diff --git a/lib/pleroma/formatter.ex b/lib/pleroma/formatter.ex index 01b863575c..4d3fd8eaed 100644 --- a/lib/pleroma/formatter.ex +++ b/lib/pleroma/formatter.ex @@ -67,7 +67,6 @@ def mention_from_user(%User{id: id} = user, opts \\ %{mentions_format: :full}) d end def hashtag_handler("#" <> tag = tag_text, _buffer, _opts, acc) do - tag = String.downcase(tag) url = "#{Pleroma.Web.Endpoint.url()}/tag/#{tag}" link = @@ -83,11 +82,11 @@ def hashtag_handler("#" <> tag = tag_text, _buffer, _opts, acc) do end def doublehashtag_handler("##" <> tag = tag_text, _buffer, _opts, acc) do - {tag, %{acc | tags: MapSet.put(acc.tags, {tag_text, tag |> String.downcase()})}} + {tag, %{acc | tags: MapSet.put(acc.tags, {tag_text, tag})}} end def triplehashtag_handler("###" <> tag = tag_text, _buffer, _opts, acc) do - {"", %{acc | tags: MapSet.put(acc.tags, {tag_text, tag |> String.downcase()})}} + {"", %{acc | tags: MapSet.put(acc.tags, {tag_text, tag})}} end @doc """ diff --git a/lib/pleroma/hashtag.ex b/lib/pleroma/hashtag.ex index 4179924bd1..47c66f6623 100644 --- a/lib/pleroma/hashtag.ex +++ b/lib/pleroma/hashtag.ex @@ -40,7 +40,8 @@ def get_or_create_by_name(name) do end def get_or_create_by_names(names) when is_list(names) do - names = Enum.map(names, &normalize_name/1) + lowercase_names = names |> Enum.map(&normalize_name/1) + timestamp = NaiveDateTime.truncate(NaiveDateTime.utc_now(), :second) structs = @@ -59,7 +60,7 @@ def get_or_create_by_names(names) when is_list(names) do conflict_target: :name ) |> Multi.run(:query_op, fn _repo, _changes -> - {:ok, Repo.all(from(ht in Hashtag, where: ht.name in ^names))} + {:ok, Repo.all(from(ht in Hashtag, where: ht.name in ^lowercase_names))} end) |> Repo.transaction() do {:ok, hashtags} diff --git a/lib/pleroma/object.ex b/lib/pleroma/object.ex index 97bf66cd27..e1c6000cbe 100644 --- a/lib/pleroma/object.ex +++ b/lib/pleroma/object.ex @@ -464,17 +464,28 @@ def object_data_hashtags(%{"tag" => tags}) when is_list(tags) do _ -> false end) |> Enum.map(fn - %{"name" => "#" <> hashtag} -> String.downcase(hashtag) - %{"name" => hashtag} -> String.downcase(hashtag) - hashtag when is_bitstring(hashtag) -> String.downcase(hashtag) + %{"name" => "#" <> hashtag} -> hashtag + %{"name" => hashtag} -> hashtag + hashtag when is_bitstring(hashtag) -> hashtag end) - |> Enum.uniq() + |> uniq_case_insensitive() # Note: "" elements (plain text) might occur in `data.tag` for incoming objects |> Enum.filter(&(&1 not in [nil, ""])) end def object_data_hashtags(_), do: [] + defp uniq_case_insensitive(strings) do + strings + |> Enum.map(&String.downcase/1) + |> Enum.uniq() + |> Enum.map(&find_original_case(&1, strings)) + end + + defp find_original_case(string, strings) do + Enum.find(strings, &String.downcase(&1) == string) + end + def get_emoji_reactions(object) do reactions = object.data["reactions"]