Merge branch 'features/glitch-soc-frontend' into 'develop'
Features/glitch soc frontend See merge request pleroma/pleroma!192
This commit is contained in:
commit
00d4333373
|
@ -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)
|
||||||
|
@ -1161,6 +1162,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()
|
||||||
|
|
|
@ -423,6 +423,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
|
||||||
|> 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)
|
||||||
|
|
|
@ -87,6 +87,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,
|
||||||
|
@ -121,6 +122,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)
|
||||||
|
@ -157,6 +159,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
|
||||||
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
|
||||||
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)
|
||||||
|
|
|
@ -1,23 +1,28 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang='en'>
|
<html lang='en'>
|
||||||
<head>
|
<head>
|
||||||
|
<meta charset='utf-8'>
|
||||||
|
<meta content='width=device-width, initial-scale=1' name='viewport'>
|
||||||
<title>
|
<title>
|
||||||
<%= Application.get_env(:pleroma, :instance)[:name] %>
|
<%= Application.get_env(:pleroma, :instance)[:name] %>
|
||||||
</title>
|
</title>
|
||||||
<meta charset='utf-8'>
|
|
||||||
<meta content='width=device-width, initial-scale=1' name='viewport'>
|
|
||||||
<link rel="icon" type="image/png" href="/favicon.png"/>
|
<link rel="icon" type="image/png" href="/favicon.png"/>
|
||||||
<link rel="stylesheet" media="all" href="/packs/common.css" />
|
<script crossorigin='anonymous' src="/packs/locales.js"></script>
|
||||||
<link rel="stylesheet" media="all" href="/packs/default.css" />
|
<script crossorigin='anonymous' src="/packs/locales/glitch/en.js"></script>
|
||||||
|
|
||||||
<script src="/packs/common.js"></script>
|
<link rel='preload' as='script' crossorigin='anonymous' href='/packs/features/getting_started.js'>
|
||||||
<script src="/packs/locale_en.js"></script>
|
<link rel='preload' as='script' crossorigin='anonymous' href='/packs/features/compose.js'>
|
||||||
<link as='script' crossorigin='anonymous' href='/packs/features/getting_started.js' rel='preload'>
|
<link rel='preload' as='script' crossorigin='anonymous' href='/packs/features/home_timeline.js'>
|
||||||
<link as='script' crossorigin='anonymous' href='/packs/features/compose.js' rel='preload'>
|
<link rel='preload' as='script' crossorigin='anonymous' href='/packs/features/notifications.js'>
|
||||||
<link as='script' crossorigin='anonymous' href='/packs/features/home_timeline.js' rel='preload'>
|
|
||||||
<link as='script' crossorigin='anonymous' href='/packs/features/notifications.js' rel='preload'>
|
|
||||||
<script id='initial-state' type='application/json'><%= raw @initial_state %></script>
|
<script id='initial-state' type='application/json'><%= raw @initial_state %></script>
|
||||||
<script src="/packs/application.js"></script>
|
|
||||||
|
<script src="/packs/core/common.js"></script>
|
||||||
|
<link rel="stylesheet" media="all" href="/packs/core/common.css" />
|
||||||
|
|
||||||
|
<script src="/packs/flavours/glitch/common.js"></script>
|
||||||
|
<link rel="stylesheet" media="all" href="/packs/flavours/glitch/common.css" />
|
||||||
|
|
||||||
|
<script src="/packs/flavours/glitch/home.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body class='app-body no-reduce-motion system-font'>
|
<body class='app-body no-reduce-motion system-font'>
|
||||||
<div class='app-holder' data-props='{"locale":"en"}' id='mastodon'>
|
<div class='app-holder' data-props='{"locale":"en"}' id='mastodon'>
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
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
|
|
@ -951,4 +951,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
|
||||||
|
|
|
@ -1693,4 +1693,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
|
||||||
|
|
|
@ -92,6 +92,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,
|
||||||
|
|
Loading…
Reference in New Issue