Optional adapter for the annotation layer (Etcher shapes + attached comment threads). When unconfigured the reader works fully — the annotate button and composer simply don't render.
config :manhwa, annotations: MyApp.ReaderAnnotationsShapes are stored per (user, series, chapter); the reader treats
shape payloads and mark items as opaque maps that round-trip between
your store and the Etcher JS layer.
Summary
Callbacks
Attach a comment (composer post) to a drawn shape. attrs carries
title/content/visibility/giphy. Returns
%{comment_uuid:, resource_uuid:, tooltip_metadata:} on success.
Create a standalone annotation mark item.
Delete a mark item by id (adapter dispatches annotation-vs-plain-item cleanup, e.g. removing a linked comment thread).
List the user's visible mark items (typed overlay store) for a chapter.
Every shape payload visible to viewer for the chapter — the viewer's
own shapes (any visibility) plus other users' public shapes. viewer
may be nil (anonymous → public only). Hydrated into the viewer's
"etcher" extension at render time.
Replace the user's saved shapes for a chapter with annotations
(the Etcher layer's full-state save). opts may carry :author_name
to stamp tooltip metadata.
Types
Callbacks
@callback attach_comment_to_shape( user(), series(), chapter(), shape_uuid :: String.t(), attrs :: map() ) :: {:ok, map()} | {:error, term()}
Attach a comment (composer post) to a drawn shape. attrs carries
title/content/visibility/giphy. Returns
%{comment_uuid:, resource_uuid:, tooltip_metadata:} on success.
@callback create_annotation(user(), series(), chapter(), attrs :: map()) :: {:ok, map()} | {:error, term()}
Create a standalone annotation mark item.
@callback delete_item(user(), series(), chapter(), item_id :: String.t()) :: {:ok, term()} | {:error, :not_found | term()}
Delete a mark item by id (adapter dispatches annotation-vs-plain-item cleanup, e.g. removing a linked comment thread).
List the user's visible mark items (typed overlay store) for a chapter.
Every shape payload visible to viewer for the chapter — the viewer's
own shapes (any visibility) plus other users' public shapes. viewer
may be nil (anonymous → public only). Hydrated into the viewer's
"etcher" extension at render time.
@callback replace_shapes( user(), series(), chapter(), annotations :: [map()], opts :: keyword() ) :: :ok | {:ok, term()} | {:error, term()}
Replace the user's saved shapes for a chapter with annotations
(the Etcher layer's full-state save). opts may carry :author_name
to stamp tooltip metadata.