From 35b73eb20cad296d3565a8ec942efa9431068a04 Mon Sep 17 00:00:00 2001 From: Laurent GAY Date: Wed, 30 Jul 2025 17:29:19 +0200 Subject: [PATCH] atom/ics link copy to clipboard: using in "GroupView" + "EditIdentity" + "NotificationsView" + "AboutInstanceView" - refactoring to use same mecanizem (Issue #1496) --- src/utils/share.ts | 28 ++++++++++ src/views/About/AboutInstanceView.vue | 34 +++++++++-- src/views/Account/children/EditIdentity.vue | 42 +++++++------- src/views/Group/GroupView.vue | 34 ++++++++++- src/views/Settings/NotificationsView.vue | 62 ++++++++++----------- 5 files changed, 141 insertions(+), 59 deletions(-) diff --git a/src/utils/share.ts b/src/utils/share.ts index a549b9245..9a35ee07a 100644 --- a/src/utils/share.ts +++ b/src/utils/share.ts @@ -1,3 +1,5 @@ +import { reactive } from "vue"; + export const twitterShareUrl = ( url: string | undefined, text: string | undefined @@ -75,6 +77,32 @@ export const mastodonShareUrl = ( )}`; }; +export const showCopiedTooltip = reactive({ ics: false, atom: false }); + +export const initCopiedTooltipShow = (): void => { + showCopiedTooltip.ics = false; + showCopiedTooltip.atom = false; +}; + +export const tokenToURL = (subURL: string): string => { + return `${window.location.origin}/${subURL}`; +}; + +export const copyURL = ( + e: Event, + url: string, + format: "ics" | "atom" +): void => { + if (navigator.clipboard) { + e.preventDefault(); + navigator.clipboard.writeText(url); + showCopiedTooltip[format] = true; + setTimeout(() => { + showCopiedTooltip[format] = false; + }, 2000); + } +}; + const basicTextToEncode = (url: string, text: string): string => { return `${text}\r\n${url}`; }; diff --git a/src/views/About/AboutInstanceView.vue b/src/views/About/AboutInstanceView.vue index f57969443..cf5d876c7 100644 --- a/src/views/About/AboutInstanceView.vue +++ b/src/views/About/AboutInstanceView.vue @@ -86,20 +86,36 @@ {{ t("Instance feeds") }} + {{ t("RSS/Atom Feed") }} - + {{ t("ICS/WebCal Feed") }} @@ -124,6 +140,14 @@ import { useQuery } from "@vue/apollo-composable"; import { computed } from "vue"; import { useI18n } from "vue-i18n"; import { useHead } from "@/utils/head"; +import { + showCopiedTooltip, + initCopiedTooltipShow, + copyURL, + tokenToURL, +} from "@/utils/share"; + +initCopiedTooltipShow(); const { result: configResult } = useQuery<{ config: IConfig }>(ABOUT); diff --git a/src/views/Account/children/EditIdentity.vue b/src/views/Account/children/EditIdentity.vue index 1db9a79ef..3b3d9a5e3 100644 --- a/src/views/Account/children/EditIdentity.vue +++ b/src/views/Account/children/EditIdentity.vue @@ -133,9 +133,13 @@ icon-left="rss" @click=" (e: Event) => - copyURL(e, tokenToURL(feedToken.token, 'atom'), 'atom') + copyURL( + e, + tokenToURL('events/going/' + feedToken.token + '/atom'), + 'atom' + ) " - :href="tokenToURL(feedToken.token, 'atom')" + :href="tokenToURL('events/going/' + feedToken.token + '/atom')" target="_blank" >{{ t("RSS/Atom Feed") }} @@ -149,10 +153,14 @@ tag="a" @click=" (e: Event) => - copyURL(e, tokenToURL(feedToken.token, 'ics'), 'ics') + copyURL( + e, + tokenToURL('events/going/' + feedToken.token + '/ics'), + 'ics' + ) " icon-left="calendar-sync" - :href="tokenToURL(feedToken.token, 'ics')" + :href="tokenToURL('events/going/' + feedToken.token + '/ics')" target="_blank" >{{ t("ICS/WebCal Feed") }} @@ -225,7 +233,7 @@ import { } from "@/composition/apollo/actor"; import { useMutation, useQuery, useApolloClient } from "@vue/apollo-composable"; import { useAvatarMaxSize } from "@/composition/config"; -import { computed, inject, reactive, ref, watch } from "vue"; +import { computed, inject, ref, watch } from "vue"; import { useI18n } from "vue-i18n"; import { convertToUsername } from "@/utils/username"; import { Dialog } from "@/plugins/dialog"; @@ -233,6 +241,14 @@ import { Notifier } from "@/plugins/notifier"; import { AbsintheGraphQLErrors } from "@/types/errors.model"; import { ICurrentUser } from "@/types/current-user.model"; import { useHead } from "@/utils/head"; +import { + showCopiedTooltip, + initCopiedTooltipShow, + copyURL, + tokenToURL, +} from "@/utils/share"; + +initCopiedTooltipShow(); const { t } = useI18n({ useScope: "global" }); const router = useRouter(); @@ -301,7 +317,6 @@ const avatarMaxSize = useAvatarMaxSize(); const errors = ref([]); const avatarFile = ref(null); -const showCopiedTooltip = reactive({ ics: false, atom: false }); const isUpdate = computed(() => props.isUpdate); const identityName = computed(() => props.identityName); @@ -518,21 +533,6 @@ const getInstanceHost = computed((): string => { return MOBILIZON_INSTANCE_HOST; }); -const tokenToURL = (token: string, format: string): string => { - return `${window.location.origin}/events/going/${token}/${format}`; -}; - -const copyURL = (e: Event, url: string, format: "ics" | "atom"): void => { - if (navigator.clipboard) { - e.preventDefault(); - navigator.clipboard.writeText(url); - showCopiedTooltip[format] = true; - setTimeout(() => { - showCopiedTooltip[format] = false; - }, 2000); - } -}; - const generateFeedTokens = async (): Promise => { await createNewFeedToken({ actor_id: identity.value?.id }); }; diff --git a/src/views/Group/GroupView.vue b/src/views/Group/GroupView.vue index c9fc88923..abd643ccc 100644 --- a/src/views/Group/GroupView.vue +++ b/src/views/Group/GroupView.vue @@ -244,6 +244,12 @@ > {{ t("Share") }} +