Skip to content

feat: Offline Post Reader for MAUI App (#155)#162

Open
fboucher wants to merge 7 commits into
mainfrom
feat/155-offline-post-reader
Open

feat: Offline Post Reader for MAUI App (#155)#162
fboucher wants to merge 7 commits into
mainfrom
feat/155-offline-post-reader

Conversation

@fboucher

Copy link
Copy Markdown
Owner

Closes #155

Implements issues #156, #157, #158, #159, #160.

Changes

  • \GET /api/posts/{postId}/html\ endpoint that serves cleaned HTML from Azure Blob Storage
  • SharedUI \PostReader.razor\ page with FluentUI layout and back navigation
  • \IDataService.GetPostHtmlAsync\ contract + HTTP implementation
  • MAUI local HTML file cache service (\ILocalHtmlStorageService)
  • Sync integration downloads HTML for unread posts, prunes stale cached HTML
  • Read button in Posts grid (visible only when HTML is cached in MAUI, always in Blazor)

Testing

  • All existing tests pass (296 non-MAUI + 20 MAUI tests)
  • SyncServiceTests updated for new ILocalHtmlStorageService constructor param
  • PostsTests updated to register AlwaysAvailableHtmlCache for ILocalHtmlCache

fboucher and others added 7 commits July 10, 2026 20:46
Add tony-stark agent with charter, history, and full squad scaffolding.
Update team.md, routing.md, casting registry, and history.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add lyra-morn and elias-ward agents for the Offline Post Reader feature
(issues #156-#160). Update team.md, routing.md, casting registry and history.

Coverage:
- Lyra Morn: issues #157 (reader page) and #160 (Read button)
- Elias Ward: issue #159 (sync integration, graceful degradation)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- New endpoint fetches blob '{postId}.html' from 'cleanedposts' container
- Returns 200 text/html when blob exists, 404 with error message when not found
- Follows existing static method + BlobServiceClient injection pattern
- Added ErrorMessage record for structured 404 responses

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
)

- Added Task<string?> GetPostHtmlAsync(string postId) to IDataService interface
- Implemented in PostNoteClient: fetches from api/posts/{postId}/html, returns null on 404
- Created PostReader.razor page at route /postreader/{PostId}
- Shows post title, author, published date header with back navigation
- Renders cleaned HTML via MarkupString, shows 'Content not available' when null
- FluentUI layout with max-width 700px, line-height 1.7, respects theme
- Requires authorization via [Authorize] attribute

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- New ILocalHtmlStorageService interface with Save/Get/IsPostHtmlCached/Remove/GetCachedPostIds
- LocalHtmlStorageService implementation using injected baseDirectory for testability
  (pass FileSystem.AppDataDirectory in production, temp dir in tests)
- LocalHtmlStorageService also implements ILocalHtmlCache from SharedUI
- OfflineDataService constructor updated to accept ILocalHtmlStorageService
- GetPostHtmlAsync in OfflineDataService reads from local HTML cache
- MauiProgram.cs registers LocalHtmlStorageService as singleton for both interfaces
- ILocalHtmlCache interface added to SharedUI to decouple cache visibility from MAUI

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Added GetPostHtmlAsync to ISyncApiClient and SyncApiClient (delegates to PostNoteClient)
- SyncService constructor extended with ILocalHtmlStorageService parameter
- SyncAsync() now calls SyncHtmlAsync() after PullAsync()
- SyncHtmlAsync() prunes cached HTML for read/deleted posts, downloads for uncached unread
- Per-post download errors are logged as warnings and do not abort sync
- SyncServiceTests updated: added ILocalHtmlStorageService mock, GetCachedPostIds setup
- ILocalHtmlStorageService.cs added to MauiApp.Tests.csproj compile items

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Added ILocalHtmlCache interface to SharedUI for cache-visibility abstraction
- Posts.razor injects ILocalHtmlCache and shows Read button only when IsHtmlCached
- ReadPost() navigates to /postreader/{postId}
- AlwaysAvailableHtmlCache stub in BlazorApp always returns true (always show button)
- BlazorApp Program.cs registers AlwaysAvailableHtmlCache as ILocalHtmlCache
- MauiApp already registers LocalHtmlStorageService as ILocalHtmlCache (done in #158)
- PostsTests updated to register AlwaysAvailableHtmlCache for ILocalHtmlCache

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions

Copy link
Copy Markdown

Code Coverage

Package Line Rate Branch Rate Health
NoteBookmark.AIServices 97% 64%
NoteBookmark.Api 89% 79%
NoteBookmark.BlazorApp 5% 10%
NoteBookmark.Domain 86% 75%
NoteBookmark.ServiceDefaults 96% 75%
NoteBookmark.SharedUI 10% 10%
Summary 52% (898 / 1714) 41% (215 / 523)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: Offline Post Reader for MAUI App

1 participant