Verified Commit cda1470e authored by Haelwenn's avatar Haelwenn
Browse files

[MastoAPI][GlitchAPI] Add bookmarks

parent 872241d7
Pipeline #6671 passed with stages
in 7 minutes and 35 seconds
...@@ -39,6 +39,7 @@ defmodule Pleroma.User do ...@@ -39,6 +39,7 @@ defmodule Pleroma.User do
field(:follower_address, :string) field(:follower_address, :string)
field(:search_rank, :float, virtual: true) field(:search_rank, :float, virtual: true)
field(:tags, {:array, :string}, default: []) field(:tags, {:array, :string}, default: [])
field(:bookmarks, {:array, :string}, default: [])
field(:last_refreshed_at, :naive_datetime) field(:last_refreshed_at, :naive_datetime)
has_many(:notifications, Notification) has_many(:notifications, Notification)
embeds_one(:info, Pleroma.User.Info) embeds_one(:info, Pleroma.User.Info)
...@@ -1156,6 +1157,22 @@ defp update_tags(%User{} = user, new_tags) do ...@@ -1156,6 +1157,22 @@ defp update_tags(%User{} = user, new_tags) do
updated_user updated_user
end end
def bookmark(%User{} = user, status_id) do
bookmarks = Enum.uniq(user.bookmarks ++ [status_id])
update_bookmarks(user, bookmarks)
end
def unbookmark(%User{} = user, status_id) do
bookmarks = Enum.uniq(user.bookmarks -- [status_id])
update_bookmarks(user, bookmarks)
end
def update_bookmarks(%User{} = user, bookmarks) do
user
|> change(%{bookmarks: bookmarks})
|> update_and_set_cache
end
defp normalize_tags(tags) do defp normalize_tags(tags) do
[tags] [tags]
|> List.flatten() |> List.flatten()
......
...@@ -424,6 +424,28 @@ def unpin_status(%{assigns: %{user: user}} = conn, %{"id" => ap_id_or_id}) do ...@@ -424,6 +424,28 @@ def unpin_status(%{assigns: %{user: user}} = conn, %{"id" => ap_id_or_id}) do
end end
end end
def bookmark_status(%{assigns: %{user: user}} = conn, %{"id" => id}) do
with %Activity{} = activity <- Repo.get(Activity, id),
%User{} = user <- User.get_by_nickname(user.nickname),
true <- ActivityPub.visible_for_user?(activity, user),
{:ok, user} <- User.bookmark(user, activity.data["object"]["id"]) do
conn
|> put_view(StatusView)
|> try_render("status.json", %{activity: activity, for: user, as: :activity})
end
end
def unbookmark_status(%{assigns: %{user: user}} = conn, %{"id" => id}) do
with %Activity{} = activity <- Repo.get(Activity, id),
%User{} = user <- User.get_by_nickname(user.nickname),
true <- ActivityPub.visible_for_user?(activity, user),
{:ok, user} <- User.unbookmark(user, activity.data["object"]["id"]) do
conn
|> put_view(StatusView)
|> try_render("status.json", %{activity: activity, for: user, as: :activity})
end
end
def notifications(%{assigns: %{user: user}} = conn, params) do def notifications(%{assigns: %{user: user}} = conn, params) do
notifications = Notification.for_user(user, params) notifications = Notification.for_user(user, params)
...@@ -859,6 +881,19 @@ def favourites(%{assigns: %{user: user}} = conn, params) do ...@@ -859,6 +881,19 @@ def favourites(%{assigns: %{user: user}} = conn, params) do
|> render("index.json", %{activities: activities, for: user, as: :activity}) |> render("index.json", %{activities: activities, for: user, as: :activity})
end end
def bookmarks(%{assigns: %{user: user}} = conn, _) do
user = Repo.get(User, user.id)
activities =
user.bookmarks
|> Enum.map(fn id -> Activity.get_create_by_object_ap_id(id) end)
|> Enum.reverse()
conn
|> put_view(StatusView)
|> render("index.json", %{activities: activities, for: user, as: :activity})
end
def get_lists(%{assigns: %{user: user}} = conn, opts) do def get_lists(%{assigns: %{user: user}} = conn, opts) do
lists = Pleroma.List.for_user(user, opts) lists = Pleroma.List.for_user(user, opts)
res = ListView.render("lists.json", lists: lists) res = ListView.render("lists.json", lists: lists)
......
...@@ -88,6 +88,7 @@ def render( ...@@ -88,6 +88,7 @@ def render(
favourites_count: 0, favourites_count: 0,
reblogged: false, reblogged: false,
favourited: false, favourited: false,
bookmarked: false,
muted: false, muted: false,
pinned: pinned?(activity, user), pinned: pinned?(activity, user),
sensitive: false, sensitive: false,
...@@ -122,6 +123,7 @@ def render("status.json", %{activity: %{data: %{"object" => object}} = activity} ...@@ -122,6 +123,7 @@ def render("status.json", %{activity: %{data: %{"object" => object}} = activity}
repeated = opts[:for] && opts[:for].ap_id in (object["announcements"] || []) repeated = opts[:for] && opts[:for].ap_id in (object["announcements"] || [])
favorited = opts[:for] && opts[:for].ap_id in (object["likes"] || []) favorited = opts[:for] && opts[:for].ap_id in (object["likes"] || [])
bookmarked = opts[:for] && object["id"] in opts[:for].bookmarks
attachment_data = object["attachment"] || [] attachment_data = object["attachment"] || []
attachments = render_many(attachment_data, StatusView, "attachment.json", as: :attachment) attachments = render_many(attachment_data, StatusView, "attachment.json", as: :attachment)
...@@ -155,6 +157,7 @@ def render("status.json", %{activity: %{data: %{"object" => object}} = activity} ...@@ -155,6 +157,7 @@ def render("status.json", %{activity: %{data: %{"object" => object}} = activity}
favourites_count: like_count, favourites_count: like_count,
reblogged: present?(repeated), reblogged: present?(repeated),
favourited: present?(favorited), favourited: present?(favorited),
bookmarked: present?(bookmarked),
muted: false, muted: false,
pinned: pinned?(activity, user), pinned: pinned?(activity, user),
sensitive: sensitive, sensitive: sensitive,
......
...@@ -185,6 +185,7 @@ defmodule Pleroma.Web.Router do ...@@ -185,6 +185,7 @@ defmodule Pleroma.Web.Router do
get("/timelines/direct", MastodonAPIController, :dm_timeline) get("/timelines/direct", MastodonAPIController, :dm_timeline)
get("/favourites", MastodonAPIController, :favourites) get("/favourites", MastodonAPIController, :favourites)
get("/bookmarks", MastodonAPIController, :bookmarks)
post("/statuses", MastodonAPIController, :post_status) post("/statuses", MastodonAPIController, :post_status)
delete("/statuses/:id", MastodonAPIController, :delete_status) delete("/statuses/:id", MastodonAPIController, :delete_status)
...@@ -195,6 +196,8 @@ defmodule Pleroma.Web.Router do ...@@ -195,6 +196,8 @@ defmodule Pleroma.Web.Router do
post("/statuses/:id/unfavourite", MastodonAPIController, :unfav_status) post("/statuses/:id/unfavourite", MastodonAPIController, :unfav_status)
post("/statuses/:id/pin", MastodonAPIController, :pin_status) post("/statuses/:id/pin", MastodonAPIController, :pin_status)
post("/statuses/:id/unpin", MastodonAPIController, :unpin_status) post("/statuses/:id/unpin", MastodonAPIController, :unpin_status)
post("/statuses/:id/bookmark", MastodonAPIController, :bookmark_status)
post("/statuses/:id/unbookmark", MastodonAPIController, :unbookmark_status)
post("/notifications/clear", MastodonAPIController, :clear_notifications) post("/notifications/clear", MastodonAPIController, :clear_notifications)
post("/notifications/dismiss", MastodonAPIController, :dismiss_notification) post("/notifications/dismiss", MastodonAPIController, :dismiss_notification)
......
defmodule Pleroma.Repo.Migrations.AddBookmarksToUsers do
use Ecto.Migration
def change do
alter table(:users) do
add :bookmarks, {:array, :string}, null: false, default: []
end
end
end
...@@ -945,4 +945,31 @@ test "preserves hosts in user links text" do ...@@ -945,4 +945,31 @@ test "preserves hosts in user links text" do
assert expected_text == User.parse_bio(bio, user) assert expected_text == User.parse_bio(bio, user)
end end
end end
test "bookmarks" do
user = insert(:user)
{:ok, activity1} =
CommonAPI.post(user, %{
"status" => "heweoo!"
})
id1 = activity1.data["object"]["id"]
{:ok, activity2} =
CommonAPI.post(user, %{
"status" => "heweoo!"
})
id2 = activity2.data["object"]["id"]
assert {:ok, user_state1} = User.bookmark(user, id1)
assert user_state1.bookmarks == [id1]
assert {:ok, user_state2} = User.unbookmark(user, id1)
assert user_state2.bookmarks == []
assert {:ok, user_state3} = User.bookmark(user, id2)
assert user_state3.bookmarks == [id2]
end
end end
...@@ -1669,4 +1669,55 @@ test "Status rich-media Card", %{conn: conn, user: user} do ...@@ -1669,4 +1669,55 @@ test "Status rich-media Card", %{conn: conn, user: user} do
} }
end end
end end
test "bookmarks" do
user = insert(:user)
for_user = insert(:user)
{:ok, activity1} =
CommonAPI.post(user, %{
"status" => "heweoo?"
})
{:ok, activity2} =
CommonAPI.post(user, %{
"status" => "heweoo!"
})
response1 =
build_conn()
|> assign(:user, for_user)
|> post("/api/v1/statuses/#{activity1.id}/bookmark")
assert json_response(response1, 200)["bookmarked"] == true
response2 =
build_conn()
|> assign(:user, for_user)
|> post("/api/v1/statuses/#{activity2.id}/bookmark")
assert json_response(response2, 200)["bookmarked"] == true
bookmarks =
build_conn()
|> assign(:user, for_user)
|> get("/api/v1/bookmarks")
assert [json_response(response2, 200), json_response(response1, 200)] ==
json_response(bookmarks, 200)
response1 =
build_conn()
|> assign(:user, for_user)
|> post("/api/v1/statuses/#{activity1.id}/unbookmark")
assert json_response(response1, 200)["bookmarked"] == false
bookmarks =
build_conn()
|> assign(:user, for_user)
|> get("/api/v1/bookmarks")
assert [json_response(response2, 200)] == json_response(bookmarks, 200)
end
end end
...@@ -91,6 +91,7 @@ test "a note activity" do ...@@ -91,6 +91,7 @@ test "a note activity" do
replies_count: 0, replies_count: 0,
favourites_count: 0, favourites_count: 0,
reblogged: false, reblogged: false,
bookmarked: false,
favourited: false, favourited: false,
muted: false, muted: false,
pinned: false, pinned: false,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment