diff --git a/changelog.d/bookmark-folders.ignore b/changelog.d/bookmark-folders.ignore new file mode 100644 index 000000000..8705ac00b --- /dev/null +++ b/changelog.d/bookmark-folders.ignore @@ -0,0 +1 @@ +Various bookmark folders-related improvements diff --git a/docs/development/API/differences_in_mastoapi_responses.md b/docs/development/API/differences_in_mastoapi_responses.md index 052b2716b..0d6fc09c8 100644 --- a/docs/development/API/differences_in_mastoapi_responses.md +++ b/docs/development/API/differences_in_mastoapi_responses.md @@ -74,7 +74,7 @@ Pleroma does not process remote images and therefore cannot include fields such The `GET /api/v1/bookmarks` endpoint accepts optional parameter `folder_id` for bookmark folder ID. -The `POST /api/v1/statuses/:id/bookmark` endpoint accepts optional parameter `folder_id` for bookmark folder ID. +The `POST /api/v1/statuses/:id/bookmark` endpoint accepts optional parameter `folder_id` for bookmark folder ID. Bookmarking an already bookmarked post will update the folder association, or remove it if `folder_id` is omitted or `null`. ## Accounts diff --git a/lib/pleroma/bookmark.ex b/lib/pleroma/bookmark.ex index 1a2a63b82..1c78d495f 100644 --- a/lib/pleroma/bookmark.ex +++ b/lib/pleroma/bookmark.ex @@ -19,7 +19,7 @@ defmodule Pleroma.Bookmark do schema "bookmarks" do belongs_to(:user, User, type: FlakeId.Ecto.CompatType) belongs_to(:activity, Activity, type: FlakeId.Ecto.CompatType) - belongs_to(:folder, BookmarkFolder, type: FlakeId.Ecto.CompatType) + belongs_to(:folder, BookmarkFolder, type: FlakeId.Ecto.Type) timestamps() end @@ -38,7 +38,7 @@ defmodule Pleroma.Bookmark do |> validate_required([:user_id, :activity_id]) |> unique_constraint(:activity_id, name: :bookmarks_user_id_activity_id_index) |> Repo.insert( - on_conflict: [set: [folder_id: folder_id]], + on_conflict: [set: [folder_id: folder_id, updated_at: NaiveDateTime.utc_now()]], conflict_target: [:user_id, :activity_id] ) end @@ -76,11 +76,4 @@ defmodule Pleroma.Bookmark do |> Repo.one() |> Repo.delete() end - - def set_folder(bookmark, folder_id) do - bookmark - |> cast(%{folder_id: folder_id}, [:folder_id]) - |> validate_required([:folder_id]) - |> Repo.update() - end end diff --git a/lib/pleroma/bookmark_folder.ex b/lib/pleroma/bookmark_folder.ex index 14d37e197..65856bb29 100644 --- a/lib/pleroma/bookmark_folder.ex +++ b/lib/pleroma/bookmark_folder.ex @@ -14,7 +14,7 @@ defmodule Pleroma.BookmarkFolder do alias Pleroma.User @type t :: %__MODULE__{} - @primary_key {:id, FlakeId.Ecto.CompatType, autogenerate: true} + @primary_key {:id, FlakeId.Ecto.Type, autogenerate: true} schema "bookmark_folders" do field(:name, :string) diff --git a/lib/pleroma/web/api_spec/schemas/bookmark_folder.ex b/lib/pleroma/web/api_spec/schemas/bookmark_folder.ex index e8b4f43b7..f5ce9e8a1 100644 --- a/lib/pleroma/web/api_spec/schemas/bookmark_folder.ex +++ b/lib/pleroma/web/api_spec/schemas/bookmark_folder.ex @@ -15,12 +15,18 @@ defmodule Pleroma.Web.ApiSpec.Schemas.BookmarkFolder do properties: %{ id: FlakeID, name: %Schema{type: :string, description: "Folder name"}, - emoji: %Schema{type: :string, description: "Folder emoji", nullable: true} + emoji: %Schema{type: :string, description: "Folder emoji", nullable: true}, + emoji_url: %Schema{ + type: :string, + description: "URL of the folder emoji if it's a custom emoji, null otherwise", + nullable: true + } }, example: %{ "id" => "9toJCu5YZW7O7gfvH6", "name" => "Read later", - "emoji" => nil + "emoji" => nil, + "emoji_url" => nil } }) end diff --git a/lib/pleroma/web/mastodon_api/controllers/status_controller.ex b/lib/pleroma/web/mastodon_api/controllers/status_controller.ex index db2b61b3c..26e38aac8 100644 --- a/lib/pleroma/web/mastodon_api/controllers/status_controller.ex +++ b/lib/pleroma/web/mastodon_api/controllers/status_controller.ex @@ -81,10 +81,8 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do plug(OAuthScopesPlug, %{scopes: ["write:accounts"]} when action in [:pin, :unpin]) - # Note: scope not present in Mastodon: read:bookmarks plug(OAuthScopesPlug, %{scopes: ["read:bookmarks"]} when action == :bookmarks) - # Note: scope not present in Mastodon: write:bookmarks plug( OAuthScopesPlug, %{scopes: ["write:bookmarks"]} when action in [:bookmark, :unbookmark] diff --git a/lib/pleroma/web/pleroma_api/controllers/bookmark_folder_controller.ex b/lib/pleroma/web/pleroma_api/controllers/bookmark_folder_controller.ex index 6d6e2e940..55f323a16 100644 --- a/lib/pleroma/web/pleroma_api/controllers/bookmark_folder_controller.ex +++ b/lib/pleroma/web/pleroma_api/controllers/bookmark_folder_controller.ex @@ -10,10 +10,8 @@ defmodule Pleroma.Web.PleromaAPI.BookmarkFolderController do plug(Pleroma.Web.ApiSpec.CastAndValidate) - # Note: scope not present in Mastodon: read:bookmarks plug(OAuthScopesPlug, %{scopes: ["read:bookmarks"]} when action == :index) - # Note: scope not present in Mastodon: write:bookmarks plug( OAuthScopesPlug, %{scopes: ["write:bookmarks"]} when action in [:create, :update, :delete] diff --git a/lib/pleroma/web/pleroma_api/views/bookmark_folder_view.ex b/lib/pleroma/web/pleroma_api/views/bookmark_folder_view.ex index 29028781f..ddffa25d3 100644 --- a/lib/pleroma/web/pleroma_api/views/bookmark_folder_view.ex +++ b/lib/pleroma/web/pleroma_api/views/bookmark_folder_view.ex @@ -9,11 +9,13 @@ defmodule Pleroma.Web.PleromaAPI.BookmarkFolderView do alias Pleroma.Emoji def render("show.json", %{folder: %BookmarkFolder{} = folder}) do + {emoji, emoji_url} = get_emoji(folder.emoji) + %{ id: folder.id |> to_string(), name: folder.name, - emoji: folder.emoji, - emoji_url: get_emoji_url(folder.emoji) + emoji: emoji, + emoji_url: emoji_url } end @@ -21,20 +23,15 @@ defmodule Pleroma.Web.PleromaAPI.BookmarkFolderView do render_many(folders, __MODULE__, "show.json", Map.delete(opts, :folders)) end - defp get_emoji_url(nil) do - nil - end + defp get_emoji(nil), do: {nil, nil} - defp get_emoji_url(emoji) do + defp get_emoji(emoji) do if Emoji.unicode?(emoji) do - nil + {emoji, nil} else - emoji = Emoji.get(emoji) - - if emoji != nil do - Emoji.local_url(emoji.file) - else - nil + case Emoji.get(emoji) do + nil -> {nil, nil} + emoji_data -> {emoji, Emoji.local_url(emoji_data.file)} end end end