feat: implementation of step 5 of the plan - still not fully done

This commit is contained in:
2026-04-26 21:05:15 +02:00
parent 92e5c2ccfd
commit fa0a2fb2e1
22 changed files with 3992 additions and 27 deletions

View File

@@ -262,6 +262,87 @@ defmodule BDS.Media do
end
end
def list_media_translations(media_id) when is_binary(media_id) do
Repo.all(
from translation in Translation,
where: translation.translation_for == ^media_id,
order_by: [asc: translation.language]
)
end
def list_linked_posts(media_id) when is_binary(media_id) do
Repo.all(
from post in BDS.Posts.Post,
join: post_media in "post_media",
on: post_media.post_id == post.id,
where: post_media.media_id == ^media_id,
order_by: [asc: post_media.sort_order, asc: post.updated_at],
select: %{
post_id: post.id,
title: fragment("COALESCE(?, ?, ?)", post.title, post.slug, post.id),
sort_order: post_media.sort_order
}
)
end
def link_media_to_post(media_id, post_id) when is_binary(media_id) and is_binary(post_id) do
case {Repo.get(Media, media_id), Repo.get(BDS.Posts.Post, post_id)} do
{nil, _post} ->
{:error, :not_found}
{_media, nil} ->
{:error, :not_found}
{%Media{} = media, %BDS.Posts.Post{} = post} ->
project = Projects.get_project!(media.project_id)
Repo.transaction(fn ->
case Repo.query("SELECT 1 FROM post_media WHERE post_id = ? AND media_id = ? LIMIT 1", [post.id, media.id]) do
{:ok, %{rows: [[1]]}} ->
:already_linked
_other ->
sort_order = next_sort_order(media.id)
{:ok, _result} =
Repo.query(
"INSERT INTO post_media (id, project_id, post_id, media_id, sort_order, created_at) VALUES (?, ?, ?, ?, ?, ?)",
[Ecto.UUID.generate(), media.project_id, post.id, media.id, sort_order, Persistence.now_ms()]
)
:linked
end
:ok = write_sidecar(project, media)
:ok
end)
|> case do
{:ok, :ok} -> {:ok, :linked}
{:error, reason} -> {:error, reason}
end
end
end
def unlink_media_from_post(media_id, post_id) when is_binary(media_id) and is_binary(post_id) do
case Repo.get(Media, media_id) do
nil ->
{:error, :not_found}
%Media{} = media ->
project = Projects.get_project!(media.project_id)
Repo.transaction(fn ->
{:ok, _result} = Repo.query("DELETE FROM post_media WHERE media_id = ? AND post_id = ?", [media.id, post_id])
:ok = write_sidecar(project, media)
:ok
end)
|> case do
{:ok, :ok} -> {:ok, :unlinked}
{:error, reason} -> {:error, reason}
end
end
end
def thumbnail_paths(%Media{id: id}) do
prefix = String.slice(id, 0, 2)
@@ -675,6 +756,13 @@ defmodule BDS.Media do
end
end
defp next_sort_order(media_id) do
case Repo.query("SELECT COALESCE(MAX(sort_order), -1) FROM post_media WHERE media_id = ?", [media_id]) do
{:ok, %{rows: [[value]]}} when is_integer(value) -> value + 1
_other -> 0
end
end
defp blank_to_nil(nil), do: nil
defp blank_to_nil(""), do: nil
defp blank_to_nil(value), do: value