From 10be8fe01f1eb85a2e5ae7098fd95827a89fb243 Mon Sep 17 00:00:00 2001 From: Savya Bikram Shah Date: Wed, 27 May 2026 13:29:31 +0545 Subject: [PATCH] =?UTF-8?q?docs(readme):=20make=20thumbnail=20dynamic=20?= =?UTF-8?q?=E2=80=94=20default=20+=20latest-capture=20lookup?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Rename IDrawingTemplate.Thumbnail → DefaultThumbnail (authored fallback) - Add IGalleryService.GetLatestThumbnailAsync(templateId) for catalog grid - DrawingCatalog cells show latest user capture when available, else default; refresh on ArtworkSavedSignal so progress reflects without a reopen Co-Authored-By: Claude Opus 4.7 (1M context) --- Readme.md | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/Readme.md b/Readme.md index 8eb88c6..0f453f9 100644 --- a/Readme.md +++ b/Readme.md @@ -381,7 +381,7 @@ namespace Darkmatter.Core.Contracts.Features.Drawing; public interface IDrawingTemplate { string Id { get; } string DisplayName { get; } - Sprite Thumbnail { get; } + Sprite DefaultThumbnail { get; } // authored fallback (used when user has no captures for this template) Sprite PaperBackground { get; } IReadOnlyList Pieces { get; } IReadOnlyList Regions { get; } @@ -490,7 +490,12 @@ public interface IGalleryService { UniTask SaveAsync(byte[] png, string templateId); UniTask> ListAsync(); UniTask LoadFullAsync(string artworkId); + UniTask LoadThumbnailAsync(string artworkId); UniTask DeleteAsync(string artworkId); + + // Newest captured thumbnail for the given template, or null if none exist. + // Catalog cells fall back to IDrawingTemplate.DefaultThumbnail when this returns null. + UniTask GetLatestThumbnailAsync(string templateId); } namespace Darkmatter.Core.Contracts.Services.Capture; @@ -539,8 +544,10 @@ public readonly struct ArtworkSavedSignal { ### `DrawingCatalog` -- Loads the catalog manifest (list of available template IDs + thumbnail addresses). +- Loads the catalog manifest (list of available template IDs). - Presents a scrollable grid of thumbnails (Canvas). +- **Each cell shows the latest captured thumbnail** for that template via `IGalleryService.GetLatestThumbnailAsync(templateId)`. If the user has no captures yet for that template, falls back to `IDrawingTemplate.DefaultThumbnail` (the authored sprite). +- Subscribes to `ArtworkSavedSignal` — re-fetches the cell's thumbnail for the affected `TemplateId` so the grid reflects user progress without a reopen. - On select → fires `DrawingSelectedSignal(templateId)` and unloads the catalog UI. ### `Paper` @@ -1305,14 +1312,16 @@ Immutable view of a single drawing's authored data. public interface IDrawingTemplate { string Id { get; } // e.g. "animals/elephant" string DisplayName { get; } // user-facing - Sprite Thumbnail { get; } // 256×256 for catalog grid - Sprite PaperBackground { get; } // composited under artwork + Sprite DefaultThumbnail { get; } // 256×256 authored fallback for the catalog grid + Sprite PaperBackground { get; } // image under all paper content IReadOnlyList Pieces { get; } // for ShapeBuilder IReadOnlyList Regions { get; } // for Coloring } ``` Implemented by `DrawingTemplateSO` (ScriptableObject) loaded via Addressables. +> The catalog grid shows the latest user-captured thumbnail (via `IGalleryService.GetLatestThumbnailAsync`) when available, falling back to `DefaultThumbnail` when the user hasn't completed this template yet. The template itself stays immutable. + #### `IDrawingTemplateCatalog` *(Core/Contracts/Features/Drawing — planned)* Authority on which drawings exist, completion state, and "next" selection. ```csharp @@ -1343,12 +1352,18 @@ Persistent store of saved artwork PNGs. ```csharp public interface IGalleryService { UniTask SaveAsync(byte[] png, string templateId); - UniTask> ListAsync(); // sorted newest first - UniTask LoadFullAsync(string artworkId); // for fullscreen view + UniTask> ListAsync(); // sorted newest first + UniTask LoadFullAsync(string artworkId); // fullscreen view UniTask LoadThumbnailAsync(string artworkId); UniTask DeleteAsync(string artworkId); + + // Newest captured thumbnail for the given template, or null if the user has + // no captures for it. Used by the catalog grid; null → caller falls back to + // IDrawingTemplate.DefaultThumbnail. + UniTask GetLatestThumbnailAsync(string templateId); } ``` +For v1 the latest-thumbnail lookup can list-and-filter (tens of templates max). Add an in-memory `Dictionary` cache later if perf becomes a concern. #### `ICaptureService` *(Core/Contracts/Services/Capture — planned)* Snapshots the paper RT to a PNG blob. No arguments — dimensions and content come from `IPaperRig.Surface`.