Merge branch 'fixes' into 'main'

Little fixes

See merge request framasoft/mobilizon!1496
This commit is contained in:
Thomas Citharel 2023-12-05 08:06:10 +00:00
commit f93457131a
8 changed files with 63 additions and 70 deletions

View file

@ -42,28 +42,12 @@ defmodule Mobilizon.Federation.ActivityPub.Fetcher do
end
@spec fetch_and_create(String.t(), Keyword.t()) ::
{:ok, map(), struct()} | {:error, atom()} | :error
{:ok, map(), struct()} | {:error, atom()} | {:error, Ecto.Changeset.t()} | :error
def fetch_and_create(url, options \\ []) do
case fetch(url, options) do
{:ok, data} when is_map(data) ->
if origin_check?(url, data) do
case Transmogrifier.handle_incoming(%{
"type" => "Create",
"to" => data["to"],
"cc" => data["cc"],
"actor" => data["actor"] || data["attributedTo"],
"attributedTo" => data["attributedTo"] || data["actor"],
"object" => data
}) do
{:ok, entity, structure} ->
{:ok, entity, structure}
{:error, error} when is_atom(error) ->
{:error, error}
:error ->
{:error, :transmogrifier_error}
end
pass_to_transmogrifier(data)
else
Logger.warning("Object origin check failed")
{:error, :object_origin_check_failed}
@ -98,6 +82,34 @@ defmodule Mobilizon.Federation.ActivityPub.Fetcher do
end
end
@spec pass_to_transmogrifier(map()) ::
{:ok, map(), struct()}
| {:error, atom()}
| {:error, Ecto.Changeset.t()}
| {:error, :transmogrifier_error}
defp pass_to_transmogrifier(data) do
case Transmogrifier.handle_incoming(%{
"type" => "Create",
"to" => data["to"],
"cc" => data["cc"],
"actor" => data["actor"] || data["attributedTo"],
"attributedTo" => data["attributedTo"] || data["actor"],
"object" => data
}) do
{:ok, entity, structure} ->
{:ok, entity, structure}
{:error, error} when is_atom(error) ->
{:error, error}
{:error, %Ecto.Changeset{} = err} ->
{:error, err}
:error ->
{:error, :transmogrifier_error}
end
end
@type fetch_actor_errors ::
:json_decode_error | :actor_deleted | :http_error | :actor_not_allowed_type

View file

@ -76,12 +76,10 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier do
Actions.Create.create(:conversation, object_data, false)
object_data when is_map(object_data) ->
case Discussions.get_comment_from_url_with_preload(object_data.url) do
{:error, :comment_not_found} ->
object_data
|> transform_object_data_for_discussion()
|> save_comment_or_discussion()
end
handle_comment_or_discussion(object_data)
{:error, err} ->
{:error, err}
end
{:ok, %Comment{} = comment} ->
@ -1019,6 +1017,19 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier do
is_nil(object_data.title) or object_data.title == ""
end
defp handle_comment_or_discussion(object_data) do
case Discussions.get_comment_from_url_with_preload(object_data.url) do
{:error, :comment_not_found} ->
object_data
|> transform_object_data_for_discussion()
|> save_comment_or_discussion()
{:ok, %Comment{} = comment} ->
# Object already exists
{:ok, nil, comment}
end
end
# Comment and conversations have different attributes for actor and groups
@spec transform_object_data_for_discussion(map()) :: map()
defp transform_object_data_for_discussion(object_data) do

View file

@ -107,11 +107,7 @@
{{ t("Actions") }}
</o-button>
</template>
<o-dropdown-item
aria-role="listitem"
has-link
v-if="canManageEvent || !event?.draft"
>
<o-dropdown-item aria-role="listitem" has-link v-if="canManageEvent">
<router-link
class="flex gap-1"
:to="{
@ -123,11 +119,7 @@
{{ t("Participations") }}
</router-link>
</o-dropdown-item>
<o-dropdown-item
aria-role="listitem"
has-link
v-if="canManageEvent || !event?.draft"
>
<o-dropdown-item aria-role="listitem" has-link v-if="canManageEvent">
<router-link
class="flex gap-1"
:to="{

View file

@ -1,7 +1,7 @@
<template>
<Story>
<Variant title="new">
<TagInput v-model="tags" :fetch-tags="fetchTags" />
<TagInput v-model="tags" />
</Variant>
<!-- <Variant title="small">
<TagInput v-model="tags" />
@ -15,9 +15,4 @@ import { reactive } from "vue";
import TagInput from "./TagInput.vue";
const tags = reactive<ITag[]>([{ title: "Hello", slug: "hello" }]);
const fetchTags = async () =>
new Promise<ITag[]>((resolve) => {
resolve([{ title: "Welcome", slug: "welcome" }]);
});
</script>

View file

@ -34,10 +34,11 @@ import { ITag } from "../../types/tag.model";
import debounce from "lodash/debounce";
import { computed, onBeforeMount, ref } from "vue";
import HelpCircleOutline from "vue-material-design-icons/HelpCircleOutline.vue";
import { useFetchTags } from "@/composition/apollo/tags";
import { FILTER_TAGS } from "@/graphql/tags";
const props = defineProps<{
modelValue: ITag[];
fetchTags: (text: string) => Promise<ITag[]>;
}>();
const emit = defineEmits(["update:modelValue"]);
@ -56,9 +57,14 @@ const id = computed((): string => {
return `tag-input-${componentId}`;
});
const { load: fetchTags } = useFetchTags();
const getFilteredTags = async (newText: string): Promise<void> => {
text.value = newText;
tags.value = await props.fetchTags(newText);
const res = await fetchTags(FILTER_TAGS, { filter: newText });
if (res) {
tags.value = res.tags;
}
};
const debouncedGetFilteredTags = debounce(getFilteredTags, 200);

View file

@ -1,24 +1,7 @@
import { FILTER_TAGS } from "@/graphql/tags";
import { ITag } from "@/types/tag.model";
import { apolloClient } from "@/vue-apollo";
import { provideApolloClient, useLazyQuery } from "@vue/apollo-composable";
import { useLazyQuery } from "@vue/apollo-composable";
export async function fetchTags(text: string): Promise<ITag[]> {
try {
const { load: loadFetchTagsQuery } = useLazyQuery<
{ tags: ITag[] },
{ filter: string }
>(FILTER_TAGS);
const res = await provideApolloClient(apolloClient)(() =>
loadFetchTagsQuery(FILTER_TAGS, {
filter: text,
})
);
if (!res) return [];
return res.tags;
} catch (e) {
console.error(e);
return [];
}
export function useFetchTags() {
return useLazyQuery<{ tags: ITag[] }, { filter: string }>(FILTER_TAGS);
}

View file

@ -56,11 +56,7 @@
</option>
</o-select>
</o-field>
<tag-input
v-model="event.tags"
class="flex-1"
:fetch-tags="fetchTags"
/>
<tag-input v-model="event.tags" class="flex-1" />
</div>
<o-field
@ -626,7 +622,6 @@ import {
useTimezones,
} from "@/composition/apollo/config";
import { useMutation } from "@vue/apollo-composable";
import { fetchTags } from "@/composition/apollo/tags";
import { Dialog } from "@/plugins/dialog";
import { Notifier } from "@/plugins/notifier";
import { useHead } from "@unhead/vue";

View file

@ -32,7 +32,7 @@
/>
</o-field>
<tag-input v-model="editablePost.tags" :fetch-tags="fetchTags" />
<tag-input v-model="editablePost.tags" />
<o-field :label="t('Post')">
<p v-if="errors.body" class="help is-danger">{{ errors.body }}</p>
@ -158,7 +158,6 @@ import { useI18n } from "vue-i18n";
import { computed, inject, onMounted, ref, watch } from "vue";
import { useRouter } from "vue-router";
import { useMutation, useQuery } from "@vue/apollo-composable";
import { fetchTags } from "@/composition/apollo/tags";
import { Dialog } from "@/plugins/dialog";
const props = withDefaults(