Merge branch 'fixes' into 'main'
Do not list drafts in upcoming / old events event if moderator Closes #466 et #1086 See merge request framasoft/mobilizon!1314
This commit is contained in:
commit
ce3fa41505
@ -266,7 +266,7 @@ button.menubar__button {
|
|||||||
@apply px-3 dark:text-black;
|
@apply px-3 dark:text-black;
|
||||||
}
|
}
|
||||||
.pagination-link-current {
|
.pagination-link-current {
|
||||||
@apply bg-primary cursor-not-allowed pointer-events-none border-primary text-white;
|
@apply bg-primary cursor-not-allowed pointer-events-none border-primary text-white dark:text-zinc-900;
|
||||||
}
|
}
|
||||||
.pagination-ellipsis {
|
.pagination-ellipsis {
|
||||||
@apply text-center m-1 text-gray-300;
|
@apply text-center m-1 text-gray-300;
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<share-modal
|
<share-modal
|
||||||
:title="t('Share this post')"
|
:title="t('Share this post')"
|
||||||
:text="post.title"
|
:text="post.title"
|
||||||
:url="postURL"
|
:url="post.url ?? ''"
|
||||||
:input-label="t('Post URL')"
|
:input-label="t('Post URL')"
|
||||||
>
|
>
|
||||||
<o-notification
|
<o-notification
|
||||||
@ -11,7 +11,7 @@
|
|||||||
:closable="false"
|
:closable="false"
|
||||||
>
|
>
|
||||||
{{
|
{{
|
||||||
$t(
|
t(
|
||||||
"This post is accessible only through it's link. Be careful where you post this link."
|
"This post is accessible only through it's link. Be careful where you post this link."
|
||||||
)
|
)
|
||||||
}}
|
}}
|
||||||
@ -22,29 +22,14 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { PostVisibility } from "@/types/enums";
|
import { PostVisibility } from "@/types/enums";
|
||||||
import { IPost } from "../../types/post.model";
|
import { IPost } from "../../types/post.model";
|
||||||
import RouteName from "@/router/name";
|
|
||||||
import { computed } from "vue";
|
|
||||||
import { useRouter } from "vue-router";
|
|
||||||
import { useI18n } from "vue-i18n";
|
import { useI18n } from "vue-i18n";
|
||||||
import ShareModal from "@/components/Share/ShareModal.vue";
|
import ShareModal from "@/components/Share/ShareModal.vue";
|
||||||
|
|
||||||
const props = defineProps<{
|
defineProps<{
|
||||||
post: IPost;
|
post: IPost;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const { t } = useI18n({ useScope: "global" });
|
const { t } = useI18n({ useScope: "global" });
|
||||||
|
|
||||||
const router = useRouter();
|
|
||||||
|
|
||||||
const postURL = computed((): string => {
|
|
||||||
if (props.post.id) {
|
|
||||||
return router.resolve({
|
|
||||||
name: RouteName.POST,
|
|
||||||
params: { id: props.post.id },
|
|
||||||
}).href;
|
|
||||||
}
|
|
||||||
return props.post.url ?? "";
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.diaspora,
|
.diaspora,
|
||||||
|
@ -44,8 +44,18 @@
|
|||||||
<button
|
<button
|
||||||
v-if="!isBasicMode"
|
v-if="!isBasicMode"
|
||||||
class="menubar__button"
|
class="menubar__button"
|
||||||
:class="{ 'is-active': editor?.isActive('heading', { level: 3 }) }"
|
:class="{
|
||||||
@click="editor?.chain().focus().toggleHeading({ level: 3 }).run()"
|
'is-active': editor?.isActive('heading', {
|
||||||
|
level: props.headingLevel[0],
|
||||||
|
}),
|
||||||
|
}"
|
||||||
|
@click="
|
||||||
|
editor
|
||||||
|
?.chain()
|
||||||
|
.focus()
|
||||||
|
.toggleHeading({ level: props.headingLevel[0] })
|
||||||
|
.run()
|
||||||
|
"
|
||||||
type="button"
|
type="button"
|
||||||
:title="t('Heading Level 1')"
|
:title="t('Heading Level 1')"
|
||||||
>
|
>
|
||||||
@ -55,8 +65,18 @@
|
|||||||
<button
|
<button
|
||||||
v-if="!isBasicMode"
|
v-if="!isBasicMode"
|
||||||
class="menubar__button"
|
class="menubar__button"
|
||||||
:class="{ 'is-active': editor?.isActive('heading', { level: 4 }) }"
|
:class="{
|
||||||
@click="editor?.chain().focus().toggleHeading({ level: 4 }).run()"
|
'is-active': editor?.isActive('heading', {
|
||||||
|
level: props.headingLevel[1],
|
||||||
|
}),
|
||||||
|
}"
|
||||||
|
@click="
|
||||||
|
editor
|
||||||
|
?.chain()
|
||||||
|
.focus()
|
||||||
|
.toggleHeading({ level: props.headingLevel[1] })
|
||||||
|
.run()
|
||||||
|
"
|
||||||
type="button"
|
type="button"
|
||||||
:title="t('Heading Level 2')"
|
:title="t('Heading Level 2')"
|
||||||
>
|
>
|
||||||
@ -66,8 +86,18 @@
|
|||||||
<button
|
<button
|
||||||
v-if="!isBasicMode"
|
v-if="!isBasicMode"
|
||||||
class="menubar__button"
|
class="menubar__button"
|
||||||
:class="{ 'is-active': editor?.isActive('heading', { level: 5 }) }"
|
:class="{
|
||||||
@click="editor?.chain().focus().toggleHeading({ level: 5 }).run()"
|
'is-active': editor?.isActive('heading', {
|
||||||
|
level: props.headingLevel[2],
|
||||||
|
}),
|
||||||
|
}"
|
||||||
|
@click="
|
||||||
|
editor
|
||||||
|
?.chain()
|
||||||
|
.focus()
|
||||||
|
.toggleHeading({ level: props.headingLevel[2] })
|
||||||
|
.run()
|
||||||
|
"
|
||||||
type="button"
|
type="button"
|
||||||
:title="t('Heading Level 3')"
|
:title="t('Heading Level 3')"
|
||||||
>
|
>
|
||||||
@ -196,7 +226,7 @@
|
|||||||
import { useEditor, EditorContent, BubbleMenu } from "@tiptap/vue-3";
|
import { useEditor, EditorContent, BubbleMenu } from "@tiptap/vue-3";
|
||||||
import Blockquote from "@tiptap/extension-blockquote";
|
import Blockquote from "@tiptap/extension-blockquote";
|
||||||
import BulletList from "@tiptap/extension-bullet-list";
|
import BulletList from "@tiptap/extension-bullet-list";
|
||||||
import Heading from "@tiptap/extension-heading";
|
import Heading, { Level } from "@tiptap/extension-heading";
|
||||||
import Document from "@tiptap/extension-document";
|
import Document from "@tiptap/extension-document";
|
||||||
import Paragraph from "@tiptap/extension-paragraph";
|
import Paragraph from "@tiptap/extension-paragraph";
|
||||||
import Bold from "@tiptap/extension-bold";
|
import Bold from "@tiptap/extension-bold";
|
||||||
@ -248,10 +278,12 @@ const props = withDefaults(
|
|||||||
ariaLabel?: string;
|
ariaLabel?: string;
|
||||||
currentActor: IPerson;
|
currentActor: IPerson;
|
||||||
placeholder?: string;
|
placeholder?: string;
|
||||||
|
headingLevel?: Level[];
|
||||||
}>(),
|
}>(),
|
||||||
{
|
{
|
||||||
mode: "description",
|
mode: "description",
|
||||||
maxSize: 100_000_000,
|
maxSize: 100_000_000,
|
||||||
|
headingLevel: () => [3, 4, 5],
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -310,7 +342,7 @@ const editor = useEditor({
|
|||||||
Blockquote,
|
Blockquote,
|
||||||
BulletList,
|
BulletList,
|
||||||
Heading.configure({
|
Heading.configure({
|
||||||
levels: [3, 4, 5],
|
levels: props.headingLevel,
|
||||||
}),
|
}),
|
||||||
Document,
|
Document,
|
||||||
Paragraph,
|
Paragraph,
|
||||||
@ -611,3 +643,12 @@ onBeforeUnmount(() => {
|
|||||||
height: 0;
|
height: 0;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
<style>
|
||||||
|
.menubar__button {
|
||||||
|
@apply mx-0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menubar__button.is-active {
|
||||||
|
@apply bg-zinc-300 dark:bg-zinc-500;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
@ -55,7 +55,10 @@ export function useGroup(
|
|||||||
name: unref(name),
|
name: unref(name),
|
||||||
...options,
|
...options,
|
||||||
}),
|
}),
|
||||||
() => ({ enabled: unref(name) !== undefined && unref(name) !== "" })
|
() => ({
|
||||||
|
enabled: unref(name) !== undefined && unref(name) !== "",
|
||||||
|
fetchPolicy: "cache-and-network",
|
||||||
|
})
|
||||||
);
|
);
|
||||||
const group = computed(() => result.value?.group);
|
const group = computed(() => result.value?.group);
|
||||||
return { group, error, loading, onResult, onError, refetch };
|
return { group, error, loading, onResult, onError, refetch };
|
||||||
|
@ -43,6 +43,7 @@
|
|||||||
:aria-label="t('Post body')"
|
:aria-label="t('Post body')"
|
||||||
:current-actor="currentActor"
|
:current-actor="currentActor"
|
||||||
:placeholder="t('Write your post')"
|
:placeholder="t('Write your post')"
|
||||||
|
:headingLevel="[2, 3, 4]"
|
||||||
/>
|
/>
|
||||||
</o-field>
|
</o-field>
|
||||||
<h2 class="mt-2">{{ t("Who can view this post") }}</h2>
|
<h2 class="mt-2">{{ t("Who can view this post") }}</h2>
|
||||||
|
@ -1,22 +1,38 @@
|
|||||||
<template>
|
<template>
|
||||||
<article class="container mx-auto post" v-if="post">
|
<article class="container mx-auto post" v-if="post">
|
||||||
|
<breadcrumbs-nav
|
||||||
|
v-if="post.attributedTo"
|
||||||
|
:links="[
|
||||||
|
{ name: RouteName.MY_GROUPS, text: t('My groups') },
|
||||||
|
{
|
||||||
|
name: RouteName.GROUP,
|
||||||
|
params: { preferredUsername: usernameWithDomain(post.attributedTo) },
|
||||||
|
text: displayName(post.attributedTo),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: RouteName.POST,
|
||||||
|
params: { slug: post.slug },
|
||||||
|
text: post.title,
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
/>
|
||||||
<header>
|
<header>
|
||||||
<div class="flex justify-center">
|
<div class="flex justify-center">
|
||||||
<lazy-image-wrapper :picture="post.picture" />
|
<lazy-image-wrapper :picture="post.picture" />
|
||||||
</div>
|
</div>
|
||||||
<div class="relative flex flex-col">
|
<div class="relative flex flex-col">
|
||||||
<div
|
<div
|
||||||
class="px-2 py-3 flex flex-wrap justify-center items-center"
|
class="px-2 py-3 flex flex-wrap gap-4 justify-center items-center"
|
||||||
dir="auto"
|
dir="auto"
|
||||||
>
|
>
|
||||||
<div class="flex-1">
|
<div class="flex-auto min-w-[300px] max-w-screen-lg">
|
||||||
<div class="inline">
|
<div class="inline">
|
||||||
<tag
|
<tag
|
||||||
class="mr-2"
|
class="mr-2"
|
||||||
variant="warning"
|
variant="warning"
|
||||||
size="medium"
|
size="medium"
|
||||||
v-if="post.draft"
|
v-if="post.draft"
|
||||||
>{{ $t("Draft") }}</tag
|
>{{ t("Draft") }}</tag
|
||||||
>
|
>
|
||||||
<h1 class="inline" :lang="post.language">
|
<h1 class="inline" :lang="post.language">
|
||||||
{{ post.title }}
|
{{ post.title }}
|
||||||
@ -52,7 +68,7 @@
|
|||||||
>
|
>
|
||||||
<Clock :size="16" />
|
<Clock :size="16" />
|
||||||
{{
|
{{
|
||||||
$t("Edited {relative_time} ago", {
|
t("Edited {relative_time} ago", {
|
||||||
relative_time: formatDistanceToNowStrict(
|
relative_time: formatDistanceToNowStrict(
|
||||||
new Date(post.updatedAt),
|
new Date(post.updatedAt),
|
||||||
{
|
{
|
||||||
@ -64,7 +80,7 @@
|
|||||||
</span>
|
</span>
|
||||||
<span v-if="post.visibility === PostVisibility.UNLISTED" class="">
|
<span v-if="post.visibility === PostVisibility.UNLISTED" class="">
|
||||||
<o-icon icon="link" size="small" />
|
<o-icon icon="link" size="small" />
|
||||||
{{ $t("Accessible only by link") }}
|
{{ t("Accessible only by link") }}
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
v-else-if="post.visibility === PostVisibility.PRIVATE"
|
v-else-if="post.visibility === PostVisibility.PRIVATE"
|
||||||
@ -72,7 +88,7 @@
|
|||||||
>
|
>
|
||||||
<Lock :size="16" />
|
<Lock :size="16" />
|
||||||
{{
|
{{
|
||||||
$t("Accessible only to members", {
|
t("Accessible only to members", {
|
||||||
group: post.attributedTo?.name,
|
group: post.attributedTo?.name,
|
||||||
})
|
})
|
||||||
}}
|
}}
|
||||||
@ -82,24 +98,28 @@
|
|||||||
<o-dropdown position="bottom-left" aria-role="list">
|
<o-dropdown position="bottom-left" aria-role="list">
|
||||||
<template #trigger>
|
<template #trigger>
|
||||||
<o-button role="button" icon-right="dots-horizontal">
|
<o-button role="button" icon-right="dots-horizontal">
|
||||||
{{ $t("Actions") }}
|
{{ t("Actions") }}
|
||||||
</o-button>
|
</o-button>
|
||||||
</template>
|
</template>
|
||||||
<o-dropdown-item
|
<o-dropdown-item
|
||||||
aria-role="listitem"
|
aria-role="listitem"
|
||||||
has-link
|
has-link
|
||||||
|
tabIndex="-1"
|
||||||
v-if="
|
v-if="
|
||||||
currentActor?.id === post?.author?.id ||
|
currentActor?.id === post?.author?.id ||
|
||||||
isCurrentActorAGroupModerator
|
isCurrentActorAGroupModerator
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
<router-link
|
<router-link
|
||||||
|
class="flex gap-1 whitespace-nowrap flex-1"
|
||||||
:to="{
|
:to="{
|
||||||
name: RouteName.POST_EDIT,
|
name: RouteName.POST_EDIT,
|
||||||
params: { slug: post.slug },
|
params: { slug: post.slug },
|
||||||
}"
|
}"
|
||||||
>{{ $t("Edit") }} <o-icon icon="pencil"
|
>
|
||||||
/></router-link>
|
<Pencil />
|
||||||
|
{{ t("Edit") }}
|
||||||
|
</router-link>
|
||||||
</o-dropdown-item>
|
</o-dropdown-item>
|
||||||
<o-dropdown-item
|
<o-dropdown-item
|
||||||
aria-role="listitem"
|
aria-role="listitem"
|
||||||
@ -107,11 +127,15 @@
|
|||||||
currentActor?.id === post?.author?.id ||
|
currentActor?.id === post?.author?.id ||
|
||||||
isCurrentActorAGroupModerator
|
isCurrentActorAGroupModerator
|
||||||
"
|
"
|
||||||
@click="openDeletePostModal"
|
tabIndex="-1"
|
||||||
@keyup.enter="openDeletePostModal"
|
|
||||||
>
|
>
|
||||||
{{ $t("Delete") }}
|
<button
|
||||||
<o-icon icon="delete" />
|
@click="openDeletePostModal"
|
||||||
|
class="flex gap-1 whitespace-nowrap"
|
||||||
|
>
|
||||||
|
<Delete />
|
||||||
|
{{ t("Delete") }}
|
||||||
|
</button>
|
||||||
</o-dropdown-item>
|
</o-dropdown-item>
|
||||||
|
|
||||||
<hr
|
<hr
|
||||||
@ -126,32 +150,36 @@
|
|||||||
<o-dropdown-item
|
<o-dropdown-item
|
||||||
aria-role="listitem"
|
aria-role="listitem"
|
||||||
v-if="!post.draft"
|
v-if="!post.draft"
|
||||||
@click="triggerShare()"
|
tabIndex="-1"
|
||||||
@keyup.enter="triggerShare()"
|
|
||||||
>
|
>
|
||||||
<span>
|
<button
|
||||||
{{ $t("Share this event") }}
|
@click="triggerShare()"
|
||||||
<o-icon icon="share" />
|
class="flex gap-1 whitespace-nowrap"
|
||||||
</span>
|
>
|
||||||
|
<Share />
|
||||||
|
{{ t("Share this event") }}
|
||||||
|
</button>
|
||||||
</o-dropdown-item>
|
</o-dropdown-item>
|
||||||
|
|
||||||
<o-dropdown-item
|
<o-dropdown-item
|
||||||
aria-role="listitem"
|
aria-role="listitem"
|
||||||
v-if="ableToReport"
|
v-if="ableToReport"
|
||||||
@click="isReportModalActive = true"
|
tabIndex="-1"
|
||||||
@keyup.enter="isReportModalActive = true"
|
|
||||||
>
|
>
|
||||||
<span>
|
<button
|
||||||
{{ $t("Report") }}
|
@click="isReportModalActive = true"
|
||||||
<o-icon icon="flag" />
|
class="flex gap-1 whitespace-nowrap"
|
||||||
</span>
|
>
|
||||||
|
<Flag />
|
||||||
|
{{ t("Report") }}
|
||||||
|
</button>
|
||||||
</o-dropdown-item>
|
</o-dropdown-item>
|
||||||
</o-dropdown>
|
</o-dropdown>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
<o-notification
|
<o-notification
|
||||||
:title="$t('Members-only post')"
|
:title="t('Members-only post')"
|
||||||
class="mx-4"
|
class="mx-4"
|
||||||
variant="warning"
|
variant="warning"
|
||||||
:closable="false"
|
:closable="false"
|
||||||
@ -164,7 +192,7 @@
|
|||||||
"
|
"
|
||||||
>
|
>
|
||||||
{{
|
{{
|
||||||
$t(
|
t(
|
||||||
"This post is accessible only for members. You have access to it for moderation purposes only because you are an instance moderator."
|
"This post is accessible only for members. You have access to it for moderation purposes only because you are an instance moderator."
|
||||||
)
|
)
|
||||||
}}
|
}}
|
||||||
@ -173,10 +201,10 @@
|
|||||||
<section
|
<section
|
||||||
v-html="post.body"
|
v-html="post.body"
|
||||||
dir="auto"
|
dir="auto"
|
||||||
class="px-1 prose lg:prose-xl prose-p:mt-6 dark:prose-invert"
|
class="px-2 md:px-4 py-4 prose lg:prose-xl prose-p:mt-6 dark:prose-invert bg-white dark:bg-zinc-700 mx-auto"
|
||||||
:lang="post.language"
|
:lang="post.language"
|
||||||
/>
|
/>
|
||||||
<section class="flex gap-2 my-6" dir="auto">
|
<section class="flex gap-2 my-6 justify-center" dir="auto">
|
||||||
<router-link
|
<router-link
|
||||||
v-for="tag in post.tags"
|
v-for="tag in post.tags"
|
||||||
:key="tag.title"
|
:key="tag.title"
|
||||||
@ -186,14 +214,14 @@
|
|||||||
</router-link>
|
</router-link>
|
||||||
</section>
|
</section>
|
||||||
<o-modal
|
<o-modal
|
||||||
:close-button-aria-label="$t('Close')"
|
:close-button-aria-label="t('Close')"
|
||||||
v-model:active="isReportModalActive"
|
v-model:active="isReportModalActive"
|
||||||
has-modal-card
|
has-modal-card
|
||||||
ref="reportModal"
|
ref="reportModal"
|
||||||
>
|
>
|
||||||
<ReportModal
|
<ReportModal
|
||||||
:on-confirm="reportPost"
|
:on-confirm="reportPost"
|
||||||
:title="$t('Report this post')"
|
:title="t('Report this post')"
|
||||||
:outside-domain="groupDomain"
|
:outside-domain="groupDomain"
|
||||||
@close="isReportModalActive = false"
|
@close="isReportModalActive = false"
|
||||||
/>
|
/>
|
||||||
@ -202,7 +230,7 @@
|
|||||||
v-model:active="isShareModalActive"
|
v-model:active="isShareModalActive"
|
||||||
has-modal-card
|
has-modal-card
|
||||||
ref="shareModal"
|
ref="shareModal"
|
||||||
:close-button-aria-label="$t('Close')"
|
:close-button-aria-label="t('Close')"
|
||||||
>
|
>
|
||||||
<share-post-modal :post="post" />
|
<share-post-modal :post="post" />
|
||||||
</o-modal>
|
</o-modal>
|
||||||
@ -241,6 +269,10 @@ import { useRouter } from "vue-router";
|
|||||||
import { useCreateReport } from "@/composition/apollo/report";
|
import { useCreateReport } from "@/composition/apollo/report";
|
||||||
import Clock from "vue-material-design-icons/Clock.vue";
|
import Clock from "vue-material-design-icons/Clock.vue";
|
||||||
import Lock from "vue-material-design-icons/Lock.vue";
|
import Lock from "vue-material-design-icons/Lock.vue";
|
||||||
|
import Pencil from "vue-material-design-icons/Pencil.vue";
|
||||||
|
import Delete from "vue-material-design-icons/Delete.vue";
|
||||||
|
import Share from "vue-material-design-icons/Share.vue";
|
||||||
|
import Flag from "vue-material-design-icons/Flag.vue";
|
||||||
import { Dialog } from "@/plugins/dialog";
|
import { Dialog } from "@/plugins/dialog";
|
||||||
import { useI18n } from "vue-i18n";
|
import { useI18n } from "vue-i18n";
|
||||||
import { Notifier } from "@/plugins/notifier";
|
import { Notifier } from "@/plugins/notifier";
|
||||||
|
@ -446,8 +446,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Group do
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
) do
|
) do
|
||||||
if Actors.is_member?(actor_id, group_id) or is_moderator(user_role) do
|
if Actors.is_member?(actor_id, group_id) do
|
||||||
# TODO : Handle public / restricted to group members events
|
|
||||||
{:ok,
|
{:ok,
|
||||||
Events.list_organized_events_for_group(
|
Events.list_organized_events_for_group(
|
||||||
group,
|
group,
|
||||||
|
@ -93,7 +93,8 @@ defmodule Mix.Tasks.Mobilizon.Actors.Delete do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
defp check_actor(%Actor{type: :Person, domain: nil} = profile, assume_yes?) do
|
defp check_actor(%Actor{type: :Person, domain: nil, user_id: user_id} = profile, assume_yes?)
|
||||||
|
when not is_nil(user_id) do
|
||||||
%User{actors: actors, email: email} = Users.get_user_with_actors!(profile.user_id)
|
%User{actors: actors, email: email} = Users.get_user_with_actors!(profile.user_id)
|
||||||
|
|
||||||
if length(actors) == 1 do
|
if length(actors) == 1 do
|
||||||
|
Loading…
Reference in New Issue
Block a user