atom/ics link copy to clipboard: using in "GroupView" + "EditIdentity" + "NotificationsView" + "AboutInstanceView" - refactoring to use same mecanizem (Issue #1496)
This commit is contained in:
@@ -1,3 +1,5 @@
|
|||||||
|
import { reactive } from "vue";
|
||||||
|
|
||||||
export const twitterShareUrl = (
|
export const twitterShareUrl = (
|
||||||
url: string | undefined,
|
url: string | undefined,
|
||||||
text: 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 => {
|
const basicTextToEncode = (url: string, text: string): string => {
|
||||||
return `${text}\r\n${url}`;
|
return `${text}\r\n${url}`;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -86,20 +86,36 @@
|
|||||||
<tr class="bg-white border-b dark:bg-gray-800 dark:border-gray-700">
|
<tr class="bg-white border-b dark:bg-gray-800 dark:border-gray-700">
|
||||||
<td>{{ t("Instance feeds") }}</td>
|
<td>{{ t("Instance feeds") }}</td>
|
||||||
<td v-if="config.instanceFeeds.enabled" class="flex gap-2">
|
<td v-if="config.instanceFeeds.enabled" class="flex gap-2">
|
||||||
|
<o-tooltip
|
||||||
|
:label="t('URL copied to clipboard')"
|
||||||
|
:active="showCopiedTooltip.atom"
|
||||||
|
variant="success"
|
||||||
|
position="left"
|
||||||
|
/>
|
||||||
<o-button
|
<o-button
|
||||||
tag="a"
|
tag="a"
|
||||||
size="small"
|
|
||||||
icon-left="rss"
|
icon-left="rss"
|
||||||
href="/feed/instance/atom"
|
@click="
|
||||||
|
(e: Event) =>
|
||||||
|
copyURL(e, tokenToURL('feed/instance/atom'), 'atom')
|
||||||
|
"
|
||||||
|
:href="tokenToURL('feed/instance/atom')"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>{{ t("RSS/Atom Feed") }}</o-button
|
>{{ t("RSS/Atom Feed") }}</o-button
|
||||||
>
|
>
|
||||||
|
<o-tooltip
|
||||||
|
:label="t('URL copied to clipboard')"
|
||||||
|
:active="showCopiedTooltip.ics"
|
||||||
|
variant="success"
|
||||||
|
position="left"
|
||||||
|
/>
|
||||||
<o-button
|
<o-button
|
||||||
tag="a"
|
tag="a"
|
||||||
size="small"
|
@click="
|
||||||
|
(e: Event) => copyURL(e, tokenToURL('feed/instance/ics'), 'ics')
|
||||||
|
"
|
||||||
icon-left="calendar-sync"
|
icon-left="calendar-sync"
|
||||||
href="/feed/instance/ics"
|
:href="tokenToURL('feed/instance/ics')"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>{{ t("ICS/WebCal Feed") }}</o-button
|
>{{ t("ICS/WebCal Feed") }}</o-button
|
||||||
>
|
>
|
||||||
@@ -124,6 +140,14 @@ import { useQuery } from "@vue/apollo-composable";
|
|||||||
import { computed } from "vue";
|
import { computed } from "vue";
|
||||||
import { useI18n } from "vue-i18n";
|
import { useI18n } from "vue-i18n";
|
||||||
import { useHead } from "@/utils/head";
|
import { useHead } from "@/utils/head";
|
||||||
|
import {
|
||||||
|
showCopiedTooltip,
|
||||||
|
initCopiedTooltipShow,
|
||||||
|
copyURL,
|
||||||
|
tokenToURL,
|
||||||
|
} from "@/utils/share";
|
||||||
|
|
||||||
|
initCopiedTooltipShow();
|
||||||
|
|
||||||
const { result: configResult } = useQuery<{ config: IConfig }>(ABOUT);
|
const { result: configResult } = useQuery<{ config: IConfig }>(ABOUT);
|
||||||
|
|
||||||
|
|||||||
@@ -133,9 +133,13 @@
|
|||||||
icon-left="rss"
|
icon-left="rss"
|
||||||
@click="
|
@click="
|
||||||
(e: Event) =>
|
(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"
|
target="_blank"
|
||||||
>{{ t("RSS/Atom Feed") }}</o-button
|
>{{ t("RSS/Atom Feed") }}</o-button
|
||||||
>
|
>
|
||||||
@@ -149,10 +153,14 @@
|
|||||||
tag="a"
|
tag="a"
|
||||||
@click="
|
@click="
|
||||||
(e: Event) =>
|
(e: Event) =>
|
||||||
copyURL(e, tokenToURL(feedToken.token, 'ics'), 'ics')
|
copyURL(
|
||||||
|
e,
|
||||||
|
tokenToURL('events/going/' + feedToken.token + '/ics'),
|
||||||
|
'ics'
|
||||||
|
)
|
||||||
"
|
"
|
||||||
icon-left="calendar-sync"
|
icon-left="calendar-sync"
|
||||||
:href="tokenToURL(feedToken.token, 'ics')"
|
:href="tokenToURL('events/going/' + feedToken.token + '/ics')"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>{{ t("ICS/WebCal Feed") }}</o-button
|
>{{ t("ICS/WebCal Feed") }}</o-button
|
||||||
>
|
>
|
||||||
@@ -225,7 +233,7 @@ import {
|
|||||||
} from "@/composition/apollo/actor";
|
} from "@/composition/apollo/actor";
|
||||||
import { useMutation, useQuery, useApolloClient } from "@vue/apollo-composable";
|
import { useMutation, useQuery, useApolloClient } from "@vue/apollo-composable";
|
||||||
import { useAvatarMaxSize } from "@/composition/config";
|
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 { useI18n } from "vue-i18n";
|
||||||
import { convertToUsername } from "@/utils/username";
|
import { convertToUsername } from "@/utils/username";
|
||||||
import { Dialog } from "@/plugins/dialog";
|
import { Dialog } from "@/plugins/dialog";
|
||||||
@@ -233,6 +241,14 @@ import { Notifier } from "@/plugins/notifier";
|
|||||||
import { AbsintheGraphQLErrors } from "@/types/errors.model";
|
import { AbsintheGraphQLErrors } from "@/types/errors.model";
|
||||||
import { ICurrentUser } from "@/types/current-user.model";
|
import { ICurrentUser } from "@/types/current-user.model";
|
||||||
import { useHead } from "@/utils/head";
|
import { useHead } from "@/utils/head";
|
||||||
|
import {
|
||||||
|
showCopiedTooltip,
|
||||||
|
initCopiedTooltipShow,
|
||||||
|
copyURL,
|
||||||
|
tokenToURL,
|
||||||
|
} from "@/utils/share";
|
||||||
|
|
||||||
|
initCopiedTooltipShow();
|
||||||
|
|
||||||
const { t } = useI18n({ useScope: "global" });
|
const { t } = useI18n({ useScope: "global" });
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@@ -301,7 +317,6 @@ const avatarMaxSize = useAvatarMaxSize();
|
|||||||
|
|
||||||
const errors = ref<string[]>([]);
|
const errors = ref<string[]>([]);
|
||||||
const avatarFile = ref<File | null>(null);
|
const avatarFile = ref<File | null>(null);
|
||||||
const showCopiedTooltip = reactive({ ics: false, atom: false });
|
|
||||||
|
|
||||||
const isUpdate = computed(() => props.isUpdate);
|
const isUpdate = computed(() => props.isUpdate);
|
||||||
const identityName = computed(() => props.identityName);
|
const identityName = computed(() => props.identityName);
|
||||||
@@ -518,21 +533,6 @@ const getInstanceHost = computed((): string => {
|
|||||||
return MOBILIZON_INSTANCE_HOST;
|
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<void> => {
|
const generateFeedTokens = async (): Promise<void> => {
|
||||||
await createNewFeedToken({ actor_id: identity.value?.id });
|
await createNewFeedToken({ actor_id: identity.value?.id });
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -244,6 +244,12 @@
|
|||||||
>
|
>
|
||||||
{{ t("Share") }}
|
{{ t("Share") }}
|
||||||
</o-button>
|
</o-button>
|
||||||
|
<o-tooltip
|
||||||
|
:label="t('URL copied to clipboard')"
|
||||||
|
:active="showCopiedTooltip.atom || showCopiedTooltip.ics"
|
||||||
|
variant="success"
|
||||||
|
position="right"
|
||||||
|
/>
|
||||||
<o-dropdown aria-role="list">
|
<o-dropdown aria-role="list">
|
||||||
<template #trigger>
|
<template #trigger>
|
||||||
<o-button
|
<o-button
|
||||||
@@ -278,8 +284,16 @@
|
|||||||
/>
|
/>
|
||||||
<o-dropdown-item has-link aria-role="menuitem">
|
<o-dropdown-item has-link aria-role="menuitem">
|
||||||
<a
|
<a
|
||||||
:href="`@${preferredUsername}/feed/atom`"
|
:href="tokenToURL('@' + preferredUsername + '/feed/atom')"
|
||||||
:title="t('Atom feed for events and posts')"
|
:title="t('Atom feed for events and posts')"
|
||||||
|
@click="
|
||||||
|
(e: Event) =>
|
||||||
|
copyURL(
|
||||||
|
e,
|
||||||
|
tokenToURL('@' + preferredUsername + '/feed/atom'),
|
||||||
|
'atom'
|
||||||
|
)
|
||||||
|
"
|
||||||
class="inline-flex gap-1"
|
class="inline-flex gap-1"
|
||||||
>
|
>
|
||||||
<RSS />
|
<RSS />
|
||||||
@@ -288,8 +302,16 @@
|
|||||||
</o-dropdown-item>
|
</o-dropdown-item>
|
||||||
<o-dropdown-item has-link aria-role="menuitem">
|
<o-dropdown-item has-link aria-role="menuitem">
|
||||||
<a
|
<a
|
||||||
:href="`@${preferredUsername}/feed/ics`"
|
:href="tokenToURL('@' + preferredUsername + '/feed/ics')"
|
||||||
:title="t('ICS feed for events')"
|
:title="t('ICS feed for events')"
|
||||||
|
@click="
|
||||||
|
(e: Event) =>
|
||||||
|
copyURL(
|
||||||
|
e,
|
||||||
|
tokenToURL('@' + preferredUsername + '/feed/ics'),
|
||||||
|
'ics'
|
||||||
|
)
|
||||||
|
"
|
||||||
class="inline-flex gap-1"
|
class="inline-flex gap-1"
|
||||||
>
|
>
|
||||||
<CalendarSync />
|
<CalendarSync />
|
||||||
@@ -674,6 +696,14 @@ import { useGroupResourcesList } from "@/composition/apollo/resources";
|
|||||||
import { useGroupMembers } from "@/composition/apollo/members";
|
import { useGroupMembers } from "@/composition/apollo/members";
|
||||||
import GroupSection from "@/components/Group/GroupSection.vue";
|
import GroupSection from "@/components/Group/GroupSection.vue";
|
||||||
import { useIsLongEvents } from "@/composition/apollo/config";
|
import { useIsLongEvents } from "@/composition/apollo/config";
|
||||||
|
import {
|
||||||
|
showCopiedTooltip,
|
||||||
|
initCopiedTooltipShow,
|
||||||
|
copyURL,
|
||||||
|
tokenToURL,
|
||||||
|
} from "@/utils/share";
|
||||||
|
|
||||||
|
initCopiedTooltipShow();
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
preferredUsername: string;
|
preferredUsername: string;
|
||||||
|
|||||||
@@ -248,13 +248,21 @@
|
|||||||
icon-left="rss"
|
icon-left="rss"
|
||||||
@click="
|
@click="
|
||||||
(e: Event) =>
|
(e: Event) =>
|
||||||
copyURL(e, tokenToURL(feedToken.token, 'atom'), 'atom')
|
copyURL(
|
||||||
|
e,
|
||||||
|
tokenToURL('events/going/' + feedToken.token + 'atom'),
|
||||||
|
'atom'
|
||||||
|
)
|
||||||
"
|
"
|
||||||
@keyup.enter="
|
@keyup.enter="
|
||||||
(e: Event) =>
|
(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"
|
target="_blank"
|
||||||
>{{ $t("RSS/Atom Feed") }}</o-button
|
>{{ $t("RSS/Atom Feed") }}</o-button
|
||||||
>
|
>
|
||||||
@@ -269,14 +277,22 @@
|
|||||||
tag="a"
|
tag="a"
|
||||||
@click="
|
@click="
|
||||||
(e: Event) =>
|
(e: Event) =>
|
||||||
copyURL(e, tokenToURL(feedToken.token, 'ics'), 'ics')
|
copyURL(
|
||||||
|
e,
|
||||||
|
tokenToURL('events/going/' + feedToken.token + 'ics'),
|
||||||
|
'ics'
|
||||||
|
)
|
||||||
"
|
"
|
||||||
@keyup.enter="
|
@keyup.enter="
|
||||||
(e: Event) =>
|
(e: Event) =>
|
||||||
copyURL(e, tokenToURL(feedToken.token, 'ics'), 'ics')
|
copyURL(
|
||||||
|
e,
|
||||||
|
tokenToURL('events/going/' + feedToken.token + 'ics'),
|
||||||
|
'ics'
|
||||||
|
)
|
||||||
"
|
"
|
||||||
icon-left="calendar-sync"
|
icon-left="calendar-sync"
|
||||||
:href="tokenToURL(feedToken.token, 'ics')"
|
:href="tokenToURL('events/going/' + feedToken.token + 'ics')"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>{{ $t("ICS/WebCal Feed") }}</o-button
|
>{{ $t("ICS/WebCal Feed") }}</o-button
|
||||||
>
|
>
|
||||||
@@ -328,19 +344,19 @@ import {
|
|||||||
import merge from "lodash/merge";
|
import merge from "lodash/merge";
|
||||||
import { CONFIG } from "@/graphql/config";
|
import { CONFIG } from "@/graphql/config";
|
||||||
import { useMutation, useQuery } from "@vue/apollo-composable";
|
import { useMutation, useQuery } from "@vue/apollo-composable";
|
||||||
import {
|
import { computed, inject, onBeforeMount, onMounted, ref, watch } from "vue";
|
||||||
computed,
|
|
||||||
inject,
|
|
||||||
onBeforeMount,
|
|
||||||
onMounted,
|
|
||||||
reactive,
|
|
||||||
ref,
|
|
||||||
watch,
|
|
||||||
} from "vue";
|
|
||||||
import { IConfig } from "@/types/config.model";
|
import { IConfig } from "@/types/config.model";
|
||||||
import { useI18n } from "vue-i18n";
|
import { useI18n } from "vue-i18n";
|
||||||
import { useHead } from "@/utils/head";
|
import { useHead } from "@/utils/head";
|
||||||
import { Dialog } from "@/plugins/dialog";
|
import { Dialog } from "@/plugins/dialog";
|
||||||
|
import {
|
||||||
|
showCopiedTooltip,
|
||||||
|
initCopiedTooltipShow,
|
||||||
|
copyURL,
|
||||||
|
tokenToURL,
|
||||||
|
} from "@/utils/share";
|
||||||
|
|
||||||
|
initCopiedTooltipShow();
|
||||||
|
|
||||||
type NotificationSubType = { label: string; id: string };
|
type NotificationSubType = { label: string; id: string };
|
||||||
type NotificationType = { label: string; subtypes: NotificationSubType[] };
|
type NotificationType = { label: string; subtypes: NotificationSubType[] };
|
||||||
@@ -380,7 +396,6 @@ const groupNotifications = ref<INotificationPendingEnum | undefined>(
|
|||||||
);
|
);
|
||||||
const notificationPendingParticipationValues = ref<Record<string, unknown>>({});
|
const notificationPendingParticipationValues = ref<Record<string, unknown>>({});
|
||||||
const groupNotificationsValues = ref<Record<string, unknown>>({});
|
const groupNotificationsValues = ref<Record<string, unknown>>({});
|
||||||
const showCopiedTooltip = reactive({ ics: false, atom: false });
|
|
||||||
const subscribed = ref(false);
|
const subscribed = ref(false);
|
||||||
const canShowWebPush = ref(false);
|
const canShowWebPush = ref(false);
|
||||||
|
|
||||||
@@ -635,21 +650,6 @@ const { mutate: updateSetting } = useMutation<{ setUserSettings: string }>(
|
|||||||
() => ({ refetchQueries: [{ query: USER_NOTIFICATIONS }] })
|
() => ({ refetchQueries: [{ query: USER_NOTIFICATIONS }] })
|
||||||
);
|
);
|
||||||
|
|
||||||
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 dialog = inject<Dialog>("dialog");
|
const dialog = inject<Dialog>("dialog");
|
||||||
|
|
||||||
const openRegenerateFeedTokensConfirmation = () => {
|
const openRegenerateFeedTokensConfirmation = () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user