Files
Nexus.Reader/src/.documentation/cache/summaries/NexusReader.UI.Shared__Pages__Library.razor.json
T
2026-05-25 14:02:56 +02:00

1 line
7.7 KiB
JSON

{"path":"NexusReader.UI.Shared/Pages/Library.razor","purpose":"Blazor UI page that displays the user's library of e-books, loads last-read book summaries from the API, and provides UI to ingest new books or open a selected book.","classification":{"role":"ui-page","layer":"frontend","confidence":0.9,"evidence":["Integration/client pattern","Frontend path heuristic","@page \"/library\" directive at line 1","Razor markup with UI, Authorize attribute and component bindings (lines 1-24, 60-70)","Injects HttpClient and IReaderNavigationService; performs API call to \"api/library/books\" (lines 6-8, 526)"]},"className":"Library","methods":[{"name":"OnAfterRenderAsync","line":511,"endLine":517,"signature":"(firstRender: bool) -> Task","purpose":"Lifecycle override that triggers initial load of books on first render.","calls":[{"targetFile":"self","targetMethod":"LoadBooksAsync","callLine":515,"paramSummary":"none"}],"actions":[{"id":"onafterrenderasync_branch_513_0","kind":"branch","label":"Evaluates branch condition","line":513,"detail":"if (firstRender)","conditionSummary":"firstRender","outcomeLabels":["true","false"],"visibility":"secondary-visible","confidence":0.78},{"id":"guard-clause_513","kind":"guard-clause","label":"Only run initial load on first render","line":513,"detail":"if (firstRender) { await LoadBooksAsync(); }","conditionSummary":"firstRender == true","outcomeLabels":["load invoked","no-op"],"visibility":"detail-only","confidence":0.7},{"id":"onafterrenderasync_await_515_1","kind":"await","label":"Waits for async work","line":515,"detail":"await LoadBooksAsync();","visibility":"secondary-visible","confidence":0.81}]},{"name":"LoadBooksAsync","line":519,"endLine":541,"signature":"() -> Task","purpose":"Loads the list of last-read books from the backend API and updates component state with loading/success/failure handling.","calls":[],"actions":[{"id":"state-change_521","kind":"mapping","label":"Set loading indicator true","line":521,"detail":"_isLoading = true; StateHasChanged();","visibility":"detail-only","confidence":0.7},{"id":"loadbooksasync_try_524_0","kind":"try","label":"Begins protected execution","line":524,"detail":"try","visibility":"primary-visible","confidence":0.84},{"id":"try-catch-finally_524","kind":"mapping","label":"Exception handling and fallback for browser environment","line":524,"detail":"try { ... } catch (Exception ex) { Console.WriteLine(...); if (OperatingSystem.IsBrowser()) _isLoading = false; } finally { StateHasChanged(); }","visibility":"detail-only","confidence":0.7},{"id":"external-call_526","kind":"external-call","label":"Fetch books from API endpoint","line":526,"detail":"await Http.GetFromJsonAsync<List<LastReadBookDto>>(\"api/library/books\");","visibility":"detail-only","confidence":0.7},{"id":"loadbooksasync_await_526_1","kind":"await","label":"Waits for async work","line":526,"detail":"_books = await Http.GetFromJsonAsync<List<LastReadBookDto>>(\"api/library/books\");","visibility":"secondary-visible","confidence":0.81},{"id":"state-change_527","kind":"mapping","label":"Store loaded books and clear loading flag","line":527,"detail":"_books = ...; _isLoading = false;","visibility":"detail-only","confidence":0.7},{"id":"loadbooksasync_catch_529_2","kind":"catch","label":"Handles exception path","line":529,"detail":"catch (Exception ex)","conditionSummary":"Exception ex","outcomeLabels":["handled exception"],"visibility":"primary-visible","confidence":0.86},{"id":"log_531","kind":"log","label":"Log load failure to console","line":531,"detail":"Console.WriteLine(\"[Library] Failed to load books: {ex.Message}\");","visibility":"detail-only","confidence":0.7},{"id":"loadbooksasync_branch_532_3","kind":"branch","label":"Evaluates branch condition","line":532,"detail":"if (OperatingSystem.IsBrowser())","conditionSummary":"OperatingSystem.IsBrowser()","outcomeLabels":["true","false"],"visibility":"secondary-visible","confidence":0.78},{"id":"loadbooksasync_finally_537_4","kind":"finally","label":"Runs cleanup or finalization","line":537,"detail":"finally","visibility":"secondary-visible","confidence":0.84}]},{"name":"RefreshLibrary","line":543,"endLine":547,"signature":"() -> Task","purpose":"Public refresh helper invoked after the ingestion modal closes to reload the library.","calls":[{"targetFile":"self","targetMethod":"LoadBooksAsync","callLine":546,"paramSummary":"none"}],"actions":[{"id":"event-binding_23","kind":"mapping","label":"Bound to BookIngestionModal @bind-IsOpen:after (modal close)","line":23,"detail":"BookIngestionModal @bind-IsOpen:after=\"RefreshLibrary\" triggers this when modal closes or state changes.","visibility":"detail-only","confidence":0.7},{"id":"refreshlibrary_await_546_0","kind":"await","label":"Waits for async work","line":546,"detail":"await LoadBooksAsync();","visibility":"secondary-visible","confidence":0.81}]},{"name":"OpenBook","line":549,"endLine":552,"signature":"(bookId: Guid) -> void","purpose":"Navigate to the reader view for the selected book using the injected navigation service.","calls":[{"targetFile":"NexusReader.UI.Shared/Services/IReaderNavigationService","targetMethod":"NavigateToBook","callLine":551,"paramSummary":"bookId (Guid)"}],"actions":[{"id":"invoked-from-markup_77","kind":"mapping","label":"Invoked by book card click","line":77,"detail":"card @onclick=\"() => OpenBook(book.Id)\"","visibility":"detail-only","confidence":0.7}]}],"types":[],"serviceRegistrations":[],"startupActions":[],"dependencies":["NexusReader.Application.DTOs.User (LastReadBookDto)","NexusReader.UI.Shared/Services/IReaderNavigationService","BookIngestionModal component (markup bind at line 23)","NexusButton component (uses OnClick at line 17)"],"patterns":["Blazor Component (UI lifecycle + markup)","Client-side API fetch with try/catch fallback"],"domainConcepts":["Book","Library","Reading progress"],"keyDetails":"Component loads /api/library/books (line 526), shows loading/empty/collection UI with loops and conditionals in markup, binds a modal to refresh the list (line 23), and navigates to a book via IReaderNavigationService (line 551).","orchestrationMethods":[{"name":"LoadBooksAsync","line":519,"confidence":0.69,"reason":"Contains 2 architectural actions relevant to business execution.","actionKinds":["mapping","try","external-call","await","catch","log","branch","finally"],"evidencePaths":["NexusReader.UI.Shared/Pages/Library.razor"]},{"name":"OnAfterRenderAsync","line":511,"confidence":0.65,"reason":"Contains 1 architectural actions relevant to business execution.","actionKinds":["branch","guard-clause","await"],"evidencePaths":["NexusReader.UI.Shared/Pages/Library.razor","self"]}],"typedContracts":[],"persistenceInteractions":[],"externalInteractions":[{"methodName":"LoadBooksAsync","line":526,"kind":"external-call","detail":"await Http.GetFromJsonAsync<List<LastReadBookDto>>(\"api/library/books\");","evidencePaths":["NexusReader.UI.Shared/Pages/Library.razor"]}],"evidenceAnchors":[{"kind":"orchestration-method","label":"LoadBooksAsync","line":519,"summary":"Contains 2 architectural actions relevant to business execution.","confidence":0.69,"evidencePaths":["NexusReader.UI.Shared/Pages/Library.razor"]},{"kind":"orchestration-method","label":"OnAfterRenderAsync","line":511,"summary":"Contains 1 architectural actions relevant to business execution.","confidence":0.65,"evidencePaths":["NexusReader.UI.Shared/Pages/Library.razor","self"]},{"kind":"external-call","label":"LoadBooksAsync","line":526,"summary":"await Http.GetFromJsonAsync<List<LastReadBookDto>>(\"api/library/books\");","confidence":0.8,"evidencePaths":["NexusReader.UI.Shared/Pages/Library.razor"]}],"cacheMetadata":{"schemaVersion":2,"analysisVersion":"2026-05-23.cache-v1","contentChecksum":"18066ed79c8d908fa466850b07b54ce33c687b33c7a7e37c1fc808de9c75e0a1","sourceByteSize":17247,"analyzedAt":"2026-05-23T16:29:39.644Z","technology":"dotnet"}}