Packages

phoenix_kit

1.7.112
1.7.208 1.7.207 1.7.206 1.7.205 1.7.204 1.7.203 1.7.202 1.7.201 1.7.200 1.7.199 1.7.198 1.7.197 1.7.196 1.7.194 1.7.193 1.7.192 1.7.191 1.7.190 1.7.189 1.7.187 1.7.186 1.7.185 1.7.184 1.7.183 1.7.182 1.7.181 1.7.180 1.7.179 1.7.178 1.7.177 1.7.176 1.7.175 1.7.174 1.7.173 1.7.172 1.7.171 1.7.170 1.7.169 1.7.168 1.7.167 1.7.166 1.7.165 1.7.164 1.7.162 1.7.161 1.7.160 1.7.159 1.7.157 1.7.156 1.7.155 1.7.154 1.7.153 1.7.152 1.7.151 1.7.150 1.7.149 1.7.146 1.7.145 1.7.144 1.7.143 1.7.138 1.7.133 1.7.132 1.7.131 1.7.130 1.7.128 1.7.126 1.7.125 1.7.121 1.7.120 1.7.119 1.7.118 1.7.117 1.7.116 1.7.115 1.7.114 1.7.113 1.7.112 1.7.111 1.7.110 1.7.109 1.7.108 1.7.107 1.7.106 1.7.105 1.7.104 1.7.103 1.7.102 1.7.101 1.7.100 1.7.99 1.7.98 1.7.97 1.7.96 1.7.95 1.7.94 1.7.93 1.7.92 1.7.91 1.7.90 1.7.89 1.7.88 1.7.87 1.7.86 1.7.85 1.7.84 1.7.83 1.7.82 1.7.81 1.7.80 1.7.79 1.7.78 1.7.77 1.7.76 1.7.75 1.7.74 1.7.71 1.7.70 1.7.69 1.7.66 1.7.65 1.7.64 1.7.63 1.7.62 1.7.61 1.7.59 1.7.58 1.7.57 1.7.56 1.7.55 1.7.54 1.7.53 1.7.52 1.7.51 1.7.49 1.7.44 1.7.43 1.7.42 1.7.41 1.7.39 1.7.38 1.7.37 1.7.36 1.7.34 1.7.33 1.7.31 1.7.30 1.7.29 1.7.28 1.7.27 1.7.26 1.7.25 1.7.24 1.7.23 1.7.22 1.7.21 1.7.20 1.7.19 1.7.18 1.7.17 1.7.16 1.7.15 1.7.14 1.7.13 1.7.12 1.7.11 1.7.10 1.7.9 1.7.8 1.7.7 1.7.6 1.7.5 1.7.4 1.7.3 1.7.2 1.7.1 1.7.0 1.6.20 1.6.19 1.6.18 1.6.17 1.6.16 1.6.15 1.6.14 1.6.13 1.6.12 1.6.11 1.6.10 1.6.9 1.6.8 1.6.7 1.6.6 1.6.5 1.6.4 1.6.3 1.5.2 1.5.1 1.5.0 1.4.9 1.4.8 1.4.7 1.4.6 1.4.5 1.4.4 1.4.3 1.4.2 1.4.1 1.4.0 1.3.2 1.3.1 1.3.0 1.2.10 1.2.9 1.2.8 1.2.7 1.2.5 1.2.4 1.2.2 1.2.1 1.2.0 1.1.0 1.0.0

A foundation for building Elixir Phoenix apps — SaaS, social networks, ERP systems, marketplaces, and more

Current section

Files

Jump to
phoenix_kit lib modules storage etcher_adapter.ex
Raw

lib/modules/storage/etcher_adapter.ex

defmodule PhoenixKit.Modules.Storage.EtcherAdapter do
@moduledoc """
`Etcher.Storage` adapter that writes annotation events from the
MediaBrowser's Fresco viewer into `phoenix_kit_annotations`.
Etcher's generic API is keyed by `target_type` + `target_uuid` so the
library can annotate any kind of resource. In PhoenixKit the only
target is a media File, so this adapter requires `target_type ==
"file"` and maps `target_uuid` to `file_uuid`.
## Comment threads
An annotation's discussion thread is **not** created at draw time —
it's instantiated lazily when the user posts the first comment on the
annotation. The comments are anchored to the **file**
(`resource_type = "file"`, `resource_uuid = file_uuid`) with
`metadata.annotation_uuid` carrying the back-reference, so they
appear in the file's main thread alongside non-annotated discussion.
No `comment_uuid` column on annotations is needed.
"""
@behaviour Etcher.Storage
alias PhoenixKit.Annotations
alias PhoenixKit.Annotations.Annotation
# Whitelist of annotation schema fields the adapter accepts from event
# payloads, sourced from `Annotation.adapter_writable_fields/0` so the
# set stays in sync with the schema's `@cast_fields`. Anything else
# (Etcher routing keys, JS-side anchor coords, client-side metadata)
# is silently dropped — `String.to_existing_atom` on unknown payload
# keys used to crash the LV when Etcher's payload shape grew new
# client-side keys like `anchor_x` / `anchor_y`. Stored as strings
# here since the filter compares against `to_string(payload_key)`.
@schema_keys Enum.map(Annotation.adapter_writable_fields(), &Atom.to_string/1)
@impl Etcher.Storage
def create(attrs) do
with {:ok, file_uuid} <- target_uuid(attrs) do
attrs
|> filter_to_schema()
|> Map.put(:file_uuid, file_uuid)
|> Annotations.create()
end
end
@impl Etcher.Storage
def list_for(target_type, target_uuid)
def list_for("file", file_uuid) when is_binary(file_uuid) do
Annotations.list_for_file(file_uuid)
end
def list_for(_other, _uuid), do: []
@impl Etcher.Storage
def update(uuid, attrs) do
attrs
|> filter_to_schema()
|> then(&Annotations.update(uuid, &1))
end
@impl Etcher.Storage
def delete(uuid), do: Annotations.delete(uuid)
# ---------------------------------------------------------------------------
defp target_uuid(%{"target_type" => "file", "target_uuid" => uuid}) when is_binary(uuid),
do: {:ok, uuid}
defp target_uuid(%{target_type: "file", target_uuid: uuid}) when is_binary(uuid),
do: {:ok, uuid}
defp target_uuid(_attrs), do: {:error, :unsupported_target}
defp filter_to_schema(attrs) do
Enum.reduce(attrs, %{}, fn {k, v}, acc ->
key = to_string(k)
if key in @schema_keys, do: Map.put(acc, String.to_existing_atom(key), v), else: acc
end)
end
end