Remerge of hashtag following #341

Merged
floatingghost merged 10 commits from follow-hashtags into develop 2022-12-05 12:58:48 +00:00
4 changed files with 56 additions and 28 deletions
Showing only changes of commit 1bc8c4c07d - Show all commits

View file

@ -27,6 +27,10 @@ def normalize_name(name) do
|> String.trim() |> String.trim()
end end
def get_by_id(id) do
Repo.get(Hashtag, id)
end
def get_or_create_by_name(name) do def get_or_create_by_name(name) do
changeset = changeset(%Hashtag{}, %{name: name}) changeset = changeset(%Hashtag{}, %{name: name})

View file

@ -2559,23 +2559,40 @@ def update_last_status_at(user) do
end end
end end
def hashtag_follows(%User{} = user) do defp maybe_load_followed_hashtags(%User{followed_hashtags: follows} = user)
HashtagFollow when is_list(follows),
|> where(user_id: ^user.id) do: user
|> Repo.all()
defp maybe_load_followed_hashtags(%User{} = user) do
followed_hashtags = HashtagFollow.get_by_user(user)
%{user | followed_hashtags: followed_hashtags}
end end
def follow_hashtag(%User{} = user, %Hashtag{} = hashtag) do def follow_hashtag(%User{} = user, %Hashtag{} = hashtag) do
Logger.debug("Follow hashtag #{hashtag.name} for user #{user.nickname}") Logger.debug("Follow hashtag #{hashtag.name} for user #{user.nickname}")
user = maybe_load_followed_hashtags(user)
HashtagFollow.new(user, hashtag) with {:ok, _} <- HashtagFollow.new(user, hashtag),
follows <- HashtagFollow.get_by_user(user),
%User{} = user <- user |> Map.put(:followed_hashtags, follows) do
user
|> set_cache()
end
end end
def unfollow_hashtag(%User{} = user, %Hashtag{} = hashtag) do def unfollow_hashtag(%User{} = user, %Hashtag{} = hashtag) do
Logger.debug("Unfollow hashtag #{hashtag.name} for user #{user.nickname}") Logger.debug("Unfollow hashtag #{hashtag.name} for user #{user.nickname}")
user = maybe_load_followed_hashtags(user)
from(hf in HashtagFollow) with {_, nil} <- HashtagFollow.delete(user, hashtag),
|> where([hf], hf.user_id == ^user.id and hf.hashtag_id == ^hashtag.id) follows <- HashtagFollow.get_by_user(user),
|> Repo.delete_all() %User{} = user <- user |> Map.put(:followed_hashtags, follows) do
user
|> set_cache()
end
end
def following_hashtag?(%User{} = user, %Hashtag{} = hashtag) do
not is_nil(HashtagFollow.get(user, hashtag))
end end
end end

View file

@ -1,5 +1,6 @@
defmodule Pleroma.User.HashtagFollow do defmodule Pleroma.User.HashtagFollow do
use Ecto.Schema use Ecto.Schema
import Ecto.Query
import Ecto.Changeset import Ecto.Changeset
alias Pleroma.User alias Pleroma.User
@ -26,4 +27,20 @@ def new(%User{} = user, %Hashtag{} = hashtag) do
|> changeset(%{user_id: user.id, hashtag_id: hashtag.id}) |> changeset(%{user_id: user.id, hashtag_id: hashtag.id})
|> Repo.insert(on_conflict: :nothing) |> Repo.insert(on_conflict: :nothing)
end end
def delete(%User{} = user, %Hashtag{} = hashtag) do
get(user, hashtag)
|> Repo.delete()
end
def get(%User{} = user, %Hashtag{} = hashtag) do
from(hf in __MODULE__)
|> where([hf], hf.user_id == ^user.id and hf.hashtag_id == ^hashtag.id)
|> Repo.one()
end
def get_by_user(%User{} = user) do
Ecto.assoc(user, :followed_hashtags)
|> Repo.all()
end
end end

View file

@ -2687,11 +2687,9 @@ test "should follow a hashtag" do
assert {:ok, _} = user |> User.follow_hashtag(hashtag) assert {:ok, _} = user |> User.follow_hashtag(hashtag)
user = user = User.get_cached_by_ap_id(user.ap_id)
User.get_cached_by_ap_id(user.ap_id)
|> Repo.preload(:followed_hashtags)
assert user.followed_hashtags |> length() == 1 assert user.followed_hashtags |> Enum.count() == 1
assert hashtag.name in Enum.map(user.followed_hashtags, fn %{name: name} -> name end) assert hashtag.name in Enum.map(user.followed_hashtags, fn %{name: name} -> name end)
end end
@ -2703,11 +2701,9 @@ test "should not follow a hashtag twice" do
assert {:ok, _} = user |> User.follow_hashtag(hashtag) assert {:ok, _} = user |> User.follow_hashtag(hashtag)
user = user = User.get_cached_by_ap_id(user.ap_id)
User.get_cached_by_ap_id(user.ap_id)
|> Repo.preload(:followed_hashtags)
assert user.followed_hashtags |> length() == 1 assert user.followed_hashtags |> Enum.count() == 1
assert hashtag.name in Enum.map(user.followed_hashtags, fn %{name: name} -> name end) assert hashtag.name in Enum.map(user.followed_hashtags, fn %{name: name} -> name end)
end end
@ -2719,11 +2715,9 @@ test "can follow multiple hashtags" do
assert {:ok, _} = user |> User.follow_hashtag(hashtag) assert {:ok, _} = user |> User.follow_hashtag(hashtag)
assert {:ok, _} = user |> User.follow_hashtag(other_hashtag) assert {:ok, _} = user |> User.follow_hashtag(other_hashtag)
user = user = User.get_cached_by_ap_id(user.ap_id)
User.get_cached_by_ap_id(user.ap_id)
|> Repo.preload(:followed_hashtags)
assert user.followed_hashtags |> length() == 2 assert user.followed_hashtags |> Enum.count() == 2
assert hashtag.name in Enum.map(user.followed_hashtags, fn %{name: name} -> name end) assert hashtag.name in Enum.map(user.followed_hashtags, fn %{name: name} -> name end)
assert other_hashtag.name in Enum.map(user.followed_hashtags, fn %{name: name} -> name end) assert other_hashtag.name in Enum.map(user.followed_hashtags, fn %{name: name} -> name end)
end end
@ -2737,11 +2731,9 @@ test "should unfollow a hashtag" do
assert {:ok, _} = user |> User.follow_hashtag(hashtag) assert {:ok, _} = user |> User.follow_hashtag(hashtag)
assert {1, nil} = user |> User.unfollow_hashtag(hashtag) assert {1, nil} = user |> User.unfollow_hashtag(hashtag)
user = user = User.get_cached_by_ap_id(user.ap_id)
User.get_cached_by_ap_id(user.ap_id)
|> Repo.preload(:followed_hashtags)
assert user.followed_hashtags |> length() == 0 assert user.followed_hashtags |> Enum.count() == 0
end end
test "should not error when trying to unfollow a hashtag twice" do test "should not error when trying to unfollow a hashtag twice" do
@ -2752,11 +2744,9 @@ test "should not error when trying to unfollow a hashtag twice" do
assert {1, nil} = user |> User.unfollow_hashtag(hashtag) assert {1, nil} = user |> User.unfollow_hashtag(hashtag)
assert {0, nil} = user |> User.unfollow_hashtag(hashtag) assert {0, nil} = user |> User.unfollow_hashtag(hashtag)
user = user = User.get_cached_by_ap_id(user.ap_id)
User.get_cached_by_ap_id(user.ap_id)
|> Repo.preload(:followed_hashtags)
assert user.followed_hashtags |> length() == 0 assert user.followed_hashtags |> Enum.count() == 0
end end
end end
end end