Manhwa.Annotations behaviour (manhwa v0.1.0)

Copy Markdown View Source

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.ReaderAnnotations

Shapes 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

chapter()

@type chapter() :: String.t()

series()

@type series() :: Manhwa.Store.series()

user()

@type user() :: term()

Callbacks

attach_comment_to_shape(user, series, chapter, shape_uuid, attrs)

@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.

create_annotation(user, series, chapter, attrs)

(optional)
@callback create_annotation(user(), series(), chapter(), attrs :: map()) ::
  {:ok, map()} | {:error, term()}

Create a standalone annotation mark item.

delete_item(user, series, chapter, item_id)

(optional)
@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_items(user, series, chapter)

(optional)
@callback list_items(user(), series(), chapter()) :: [map()]

List the user's visible mark items (typed overlay store) for a chapter.

list_shapes(viewer, series, chapter)

@callback list_shapes(viewer :: user() | nil, series(), chapter()) :: [map()]

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_shapes(user, series, chapter, annotations, opts)

(optional)
@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.