Merge branch 'fixes' into 'main'
Little fixes See merge request framasoft/mobilizon!1496
This commit is contained in:
commit
f93457131a
|
@ -42,28 +42,12 @@ defmodule Mobilizon.Federation.ActivityPub.Fetcher do
|
||||||
end
|
end
|
||||||
|
|
||||||
@spec fetch_and_create(String.t(), Keyword.t()) ::
|
@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
|
def fetch_and_create(url, options \\ []) do
|
||||||
case fetch(url, options) do
|
case fetch(url, options) do
|
||||||
{:ok, data} when is_map(data) ->
|
{:ok, data} when is_map(data) ->
|
||||||
if origin_check?(url, data) do
|
if origin_check?(url, data) do
|
||||||
case Transmogrifier.handle_incoming(%{
|
pass_to_transmogrifier(data)
|
||||||
"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
|
|
||||||
else
|
else
|
||||||
Logger.warning("Object origin check failed")
|
Logger.warning("Object origin check failed")
|
||||||
{:error, :object_origin_check_failed}
|
{:error, :object_origin_check_failed}
|
||||||
|
@ -98,6 +82,34 @@ defmodule Mobilizon.Federation.ActivityPub.Fetcher do
|
||||||
end
|
end
|
||||||
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 ::
|
@type fetch_actor_errors ::
|
||||||
:json_decode_error | :actor_deleted | :http_error | :actor_not_allowed_type
|
:json_decode_error | :actor_deleted | :http_error | :actor_not_allowed_type
|
||||||
|
|
||||||
|
|
|
@ -76,12 +76,10 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier do
|
||||||
Actions.Create.create(:conversation, object_data, false)
|
Actions.Create.create(:conversation, object_data, false)
|
||||||
|
|
||||||
object_data when is_map(object_data) ->
|
object_data when is_map(object_data) ->
|
||||||
case Discussions.get_comment_from_url_with_preload(object_data.url) do
|
handle_comment_or_discussion(object_data)
|
||||||
{:error, :comment_not_found} ->
|
|
||||||
object_data
|
{:error, err} ->
|
||||||
|> transform_object_data_for_discussion()
|
{:error, err}
|
||||||
|> save_comment_or_discussion()
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
{:ok, %Comment{} = comment} ->
|
{:ok, %Comment{} = comment} ->
|
||||||
|
@ -1019,6 +1017,19 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier do
|
||||||
is_nil(object_data.title) or object_data.title == ""
|
is_nil(object_data.title) or object_data.title == ""
|
||||||
end
|
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
|
# Comment and conversations have different attributes for actor and groups
|
||||||
@spec transform_object_data_for_discussion(map()) :: map()
|
@spec transform_object_data_for_discussion(map()) :: map()
|
||||||
defp transform_object_data_for_discussion(object_data) do
|
defp transform_object_data_for_discussion(object_data) do
|
||||||
|
|
|
@ -107,11 +107,7 @@
|
||||||
{{ t("Actions") }}
|
{{ t("Actions") }}
|
||||||
</o-button>
|
</o-button>
|
||||||
</template>
|
</template>
|
||||||
<o-dropdown-item
|
<o-dropdown-item aria-role="listitem" has-link v-if="canManageEvent">
|
||||||
aria-role="listitem"
|
|
||||||
has-link
|
|
||||||
v-if="canManageEvent || !event?.draft"
|
|
||||||
>
|
|
||||||
<router-link
|
<router-link
|
||||||
class="flex gap-1"
|
class="flex gap-1"
|
||||||
:to="{
|
:to="{
|
||||||
|
@ -123,11 +119,7 @@
|
||||||
{{ t("Participations") }}
|
{{ t("Participations") }}
|
||||||
</router-link>
|
</router-link>
|
||||||
</o-dropdown-item>
|
</o-dropdown-item>
|
||||||
<o-dropdown-item
|
<o-dropdown-item aria-role="listitem" has-link v-if="canManageEvent">
|
||||||
aria-role="listitem"
|
|
||||||
has-link
|
|
||||||
v-if="canManageEvent || !event?.draft"
|
|
||||||
>
|
|
||||||
<router-link
|
<router-link
|
||||||
class="flex gap-1"
|
class="flex gap-1"
|
||||||
:to="{
|
:to="{
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<Story>
|
<Story>
|
||||||
<Variant title="new">
|
<Variant title="new">
|
||||||
<TagInput v-model="tags" :fetch-tags="fetchTags" />
|
<TagInput v-model="tags" />
|
||||||
</Variant>
|
</Variant>
|
||||||
<!-- <Variant title="small">
|
<!-- <Variant title="small">
|
||||||
<TagInput v-model="tags" />
|
<TagInput v-model="tags" />
|
||||||
|
@ -15,9 +15,4 @@ import { reactive } from "vue";
|
||||||
import TagInput from "./TagInput.vue";
|
import TagInput from "./TagInput.vue";
|
||||||
|
|
||||||
const tags = reactive<ITag[]>([{ title: "Hello", slug: "hello" }]);
|
const tags = reactive<ITag[]>([{ title: "Hello", slug: "hello" }]);
|
||||||
|
|
||||||
const fetchTags = async () =>
|
|
||||||
new Promise<ITag[]>((resolve) => {
|
|
||||||
resolve([{ title: "Welcome", slug: "welcome" }]);
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -34,10 +34,11 @@ import { ITag } from "../../types/tag.model";
|
||||||
import debounce from "lodash/debounce";
|
import debounce from "lodash/debounce";
|
||||||
import { computed, onBeforeMount, ref } from "vue";
|
import { computed, onBeforeMount, ref } from "vue";
|
||||||
import HelpCircleOutline from "vue-material-design-icons/HelpCircleOutline.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<{
|
const props = defineProps<{
|
||||||
modelValue: ITag[];
|
modelValue: ITag[];
|
||||||
fetchTags: (text: string) => Promise<ITag[]>;
|
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const emit = defineEmits(["update:modelValue"]);
|
const emit = defineEmits(["update:modelValue"]);
|
||||||
|
@ -56,9 +57,14 @@ const id = computed((): string => {
|
||||||
return `tag-input-${componentId}`;
|
return `tag-input-${componentId}`;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const { load: fetchTags } = useFetchTags();
|
||||||
|
|
||||||
const getFilteredTags = async (newText: string): Promise<void> => {
|
const getFilteredTags = async (newText: string): Promise<void> => {
|
||||||
text.value = newText;
|
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);
|
const debouncedGetFilteredTags = debounce(getFilteredTags, 200);
|
||||||
|
|
|
@ -1,24 +1,7 @@
|
||||||
import { FILTER_TAGS } from "@/graphql/tags";
|
import { FILTER_TAGS } from "@/graphql/tags";
|
||||||
import { ITag } from "@/types/tag.model";
|
import { ITag } from "@/types/tag.model";
|
||||||
import { apolloClient } from "@/vue-apollo";
|
import { useLazyQuery } from "@vue/apollo-composable";
|
||||||
import { provideApolloClient, useLazyQuery } from "@vue/apollo-composable";
|
|
||||||
|
|
||||||
export async function fetchTags(text: string): Promise<ITag[]> {
|
export function useFetchTags() {
|
||||||
try {
|
return useLazyQuery<{ tags: ITag[] }, { filter: string }>(FILTER_TAGS);
|
||||||
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 [];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,11 +56,7 @@
|
||||||
</option>
|
</option>
|
||||||
</o-select>
|
</o-select>
|
||||||
</o-field>
|
</o-field>
|
||||||
<tag-input
|
<tag-input v-model="event.tags" class="flex-1" />
|
||||||
v-model="event.tags"
|
|
||||||
class="flex-1"
|
|
||||||
:fetch-tags="fetchTags"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<o-field
|
<o-field
|
||||||
|
@ -626,7 +622,6 @@ import {
|
||||||
useTimezones,
|
useTimezones,
|
||||||
} from "@/composition/apollo/config";
|
} from "@/composition/apollo/config";
|
||||||
import { useMutation } from "@vue/apollo-composable";
|
import { useMutation } from "@vue/apollo-composable";
|
||||||
import { fetchTags } from "@/composition/apollo/tags";
|
|
||||||
import { Dialog } from "@/plugins/dialog";
|
import { Dialog } from "@/plugins/dialog";
|
||||||
import { Notifier } from "@/plugins/notifier";
|
import { Notifier } from "@/plugins/notifier";
|
||||||
import { useHead } from "@unhead/vue";
|
import { useHead } from "@unhead/vue";
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
/>
|
/>
|
||||||
</o-field>
|
</o-field>
|
||||||
|
|
||||||
<tag-input v-model="editablePost.tags" :fetch-tags="fetchTags" />
|
<tag-input v-model="editablePost.tags" />
|
||||||
|
|
||||||
<o-field :label="t('Post')">
|
<o-field :label="t('Post')">
|
||||||
<p v-if="errors.body" class="help is-danger">{{ errors.body }}</p>
|
<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 { computed, inject, onMounted, ref, watch } from "vue";
|
||||||
import { useRouter } from "vue-router";
|
import { useRouter } from "vue-router";
|
||||||
import { useMutation, useQuery } from "@vue/apollo-composable";
|
import { useMutation, useQuery } from "@vue/apollo-composable";
|
||||||
import { fetchTags } from "@/composition/apollo/tags";
|
|
||||||
import { Dialog } from "@/plugins/dialog";
|
import { Dialog } from "@/plugins/dialog";
|
||||||
|
|
||||||
const props = withDefaults(
|
const props = withDefaults(
|
||||||
|
|
Loading…
Reference in a new issue