Compare commits

..

2 Commits

Author SHA1 Message Date
Savya Bikram Shah
a52a48fe32 Merge savya: thumbnail dynamic (default + latest-capture lookup)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 13:30:03 +05:45
Savya Bikram Shah
10be8fe01f docs(readme): make thumbnail dynamic — default + latest-capture lookup
- 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) <noreply@anthropic.com>
2026-05-27 13:29:31 +05:45

View File

@@ -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<ShapePieceDTO> Pieces { get; }
IReadOnlyList<ColorRegionDTO> Regions { get; }
@@ -490,7 +490,12 @@ public interface IGalleryService {
UniTask<SavedArtworkDTO> SaveAsync(byte[] png, string templateId);
UniTask<IReadOnlyList<SavedArtworkDTO>> ListAsync();
UniTask<Texture2D> LoadFullAsync(string artworkId);
UniTask<Texture2D> 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<Texture2D> 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<ShapePieceDTO> Pieces { get; } // for ShapeBuilder
IReadOnlyList<ColorRegionDTO> 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<SavedArtworkDTO> SaveAsync(byte[] png, string templateId);
UniTask<IReadOnlyList<SavedArtworkDTO>> ListAsync(); // sorted newest first
UniTask<Texture2D> LoadFullAsync(string artworkId); // for fullscreen view
UniTask<IReadOnlyList<SavedArtworkDTO>> ListAsync(); // sorted newest first
UniTask<Texture2D> LoadFullAsync(string artworkId); // fullscreen view
UniTask<Texture2D> 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<Texture2D> GetLatestThumbnailAsync(string templateId);
}
```
For v1 the latest-thumbnail lookup can list-and-filter (tens of templates max). Add an in-memory `Dictionary<templateId, latestArtworkId>` 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`.