mirror of
https://github.com/versia-pub/frontend.git
synced 2025-12-06 16:38:20 +01:00
perf: ♻️ Use global instance of composable instead of an instance per component for identities, client and settings
This commit is contained in:
parent
f1ada1745d
commit
3428e4b5b6
4
app.vue
4
app.vue
|
|
@ -1,6 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<NuxtPwaAssets />
|
<NuxtPwaAssets />
|
||||||
<Loading />
|
|
||||||
<ClientOnly>
|
<ClientOnly>
|
||||||
<NuxtLayout>
|
<NuxtLayout>
|
||||||
<NuxtPage />
|
<NuxtPage />
|
||||||
|
|
@ -13,15 +12,12 @@
|
||||||
import "~/styles/theme.css";
|
import "~/styles/theme.css";
|
||||||
import { convert } from "html-to-text";
|
import { convert } from "html-to-text";
|
||||||
import "iconify-icon";
|
import "iconify-icon";
|
||||||
import Loading from "./components/loading.vue";
|
|
||||||
import NotificationsRenderer from "./components/notifications/notifications-renderer.vue";
|
import NotificationsRenderer from "./components/notifications/notifications-renderer.vue";
|
||||||
// Use SSR-safe IDs for Headless UI
|
// Use SSR-safe IDs for Headless UI
|
||||||
provideHeadlessUseId(() => useId());
|
provideHeadlessUseId(() => useId());
|
||||||
|
|
||||||
const code = useRequestURL().searchParams.get("code");
|
const code = useRequestURL().searchParams.get("code");
|
||||||
const appData = useAppData();
|
const appData = useAppData();
|
||||||
const identity = useCurrentIdentity();
|
|
||||||
const client = useClient();
|
|
||||||
const instance = useInstance();
|
const instance = useInstance();
|
||||||
const description = useExtendedDescription(client);
|
const description = useExtendedDescription(client);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,6 @@ const { Control_Enter, Command_Enter, Control_Alt } = useMagicKeys();
|
||||||
const content = ref("");
|
const content = ref("");
|
||||||
const respondingTo = ref<Status | null>(null);
|
const respondingTo = ref<Status | null>(null);
|
||||||
const respondingType = ref<"reply" | "quote" | "edit" | null>(null);
|
const respondingType = ref<"reply" | "quote" | "edit" | null>(null);
|
||||||
const identity = useCurrentIdentity();
|
|
||||||
const cw = ref(false);
|
const cw = ref(false);
|
||||||
const cwContent = ref("");
|
const cwContent = ref("");
|
||||||
const markdown = ref(true);
|
const markdown = ref(true);
|
||||||
|
|
@ -178,7 +177,6 @@ const canSubmit = computed(
|
||||||
(content.value?.trim().length > 0 || files.value.length > 0) &&
|
(content.value?.trim().length > 0 || files.value.length > 0) &&
|
||||||
content.value?.trim().length <= characterLimit.value,
|
content.value?.trim().length <= characterLimit.value,
|
||||||
);
|
);
|
||||||
const client = useClient();
|
|
||||||
|
|
||||||
const send = async () => {
|
const send = async () => {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,6 @@ defineProps<{
|
||||||
textarea: HTMLTextAreaElement | undefined;
|
textarea: HTMLTextAreaElement | undefined;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const identity = useCurrentIdentity();
|
|
||||||
const emojis = computed(
|
const emojis = computed(
|
||||||
() =>
|
() =>
|
||||||
identity.value?.emojis.map((emoji) => ({
|
identity.value?.emojis.map((emoji) => ({
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,6 @@ const files = defineModel<
|
||||||
required: true,
|
required: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
const client = useClient();
|
|
||||||
const fileInput = ref<HTMLInputElement | null>(null);
|
const fileInput = ref<HTMLInputElement | null>(null);
|
||||||
|
|
||||||
const openFilePicker = () => {
|
const openFilePicker = () => {
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@ const props = defineProps<{
|
||||||
textarea: HTMLTextAreaElement | undefined;
|
textarea: HTMLTextAreaElement | undefined;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const client = useClient();
|
|
||||||
const mentions = ref<{ key: string; value: Account }[]>([]);
|
const mentions = ref<{ key: string; value: Account }[]>([]);
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,6 @@ import { Dialog } from "@ark-ui/vue";
|
||||||
import Composer from "./composer.vue";
|
import Composer from "./composer.vue";
|
||||||
const open = ref(false);
|
const open = ref(false);
|
||||||
|
|
||||||
const identity = useCurrentIdentity();
|
|
||||||
useListen("note:reply", async (note) => {
|
useListen("note:reply", async (note) => {
|
||||||
open.value = true;
|
open.value = true;
|
||||||
await nextTick();
|
await nextTick();
|
||||||
|
|
|
||||||
|
|
@ -18,8 +18,6 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import Avatar from "../avatars/avatar.vue";
|
import Avatar from "../avatars/avatar.vue";
|
||||||
|
|
||||||
const identity = useCurrentIdentity();
|
|
||||||
const settings = useSettings();
|
|
||||||
const { display_name } = useParsedAccount(
|
const { display_name } = useParsedAccount(
|
||||||
computed(() => identity.value?.account),
|
computed(() => identity.value?.account),
|
||||||
settings,
|
settings,
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,6 @@ import type { ResponseError } from "@lysand-org/client";
|
||||||
import Button from "~/packages/ui/components/buttons/button.vue";
|
import Button from "~/packages/ui/components/buttons/button.vue";
|
||||||
import Avatar from "../avatars/avatar.vue";
|
import Avatar from "../avatars/avatar.vue";
|
||||||
|
|
||||||
const client = useClient();
|
|
||||||
const ssoConfig = useSSOConfig();
|
const ssoConfig = useSSOConfig();
|
||||||
const linkedProviders = useLinkedSSO(client);
|
const linkedProviders = useLinkedSSO(client);
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,6 @@ import RichTextboxInput from "../inputs/rich-textbox-input.vue";
|
||||||
import TextInput from "../inputs/text-input.vue";
|
import TextInput from "../inputs/text-input.vue";
|
||||||
import Oidc from "./oidc.vue";
|
import Oidc from "./oidc.vue";
|
||||||
|
|
||||||
const identity = useCurrentIdentity();
|
|
||||||
const account = computed(() => identity.value?.account);
|
const account = computed(() => identity.value?.account);
|
||||||
const note = ref(account.value?.source?.note ?? "");
|
const note = ref(account.value?.source?.note ?? "");
|
||||||
const displayName = ref(account.value?.display_name ?? "");
|
const displayName = ref(account.value?.display_name ?? "");
|
||||||
|
|
@ -61,7 +60,6 @@ const bio = computed(
|
||||||
() => identity.value?.instance.configuration.statuses.max_characters ?? 0,
|
() => identity.value?.instance.configuration.statuses.max_characters ?? 0,
|
||||||
);
|
);
|
||||||
|
|
||||||
const client = useClient();
|
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
|
|
||||||
const revert = () => {
|
const revert = () => {
|
||||||
|
|
|
||||||
|
|
@ -3,16 +3,16 @@
|
||||||
<template #button>
|
<template #button>
|
||||||
<slot>
|
<slot>
|
||||||
<div class="rounded text-left flex flex-row gap-x-2 hover:scale-[95%] duration-100"
|
<div class="rounded text-left flex flex-row gap-x-2 hover:scale-[95%] duration-100"
|
||||||
v-if="currentIdentity">
|
v-if="identity">
|
||||||
<div class="shrink-0">
|
<div class="shrink-0">
|
||||||
<Avatar class="size-12 rounded ring-1 ring-white/5" :src="currentIdentity.account.avatar"
|
<Avatar class="size-12 rounded ring-1 ring-white/5" :src="identity.account.avatar"
|
||||||
:alt="`${currentIdentity.account.acct}'s avatar'`" />
|
:alt="`${identity.account.acct}'s avatar'`" />
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-col items-start p-1 justify-around grow overflow-hidden">
|
<div class="flex flex-col items-start p-1 justify-around grow overflow-hidden">
|
||||||
<div class="flex flex-row items-center justify-between w-full">
|
<div class="flex flex-row items-center justify-between w-full">
|
||||||
<div class="font-semibold text-gray-200 text-sm line-clamp-1 break-all">
|
<div class="font-semibold text-gray-200 text-sm line-clamp-1 break-all">
|
||||||
{{
|
{{
|
||||||
currentIdentity.account.display_name }}
|
identity.account.display_name }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<span class="text-gray-400 text-xs line-clamp-1 break-all w-full">
|
<span class="text-gray-400 text-xs line-clamp-1 break-all w-full">
|
||||||
|
|
@ -59,7 +59,7 @@
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
<Menu.Item value="" v-if="currentIdentity">
|
<Menu.Item value="" v-if="identity">
|
||||||
<NuxtLink href="/settings" class="w-full">
|
<NuxtLink href="/settings" class="w-full">
|
||||||
<ButtonBase theme="outline" class="w-full !justify-start">
|
<ButtonBase theme="outline" class="w-full !justify-start">
|
||||||
<Icon icon="tabler:adjustments" class="!size-6" />
|
<Icon icon="tabler:adjustments" class="!size-6" />
|
||||||
|
|
@ -73,7 +73,7 @@
|
||||||
<span class="shrink-0 line-clamp-1">Add new account</span>
|
<span class="shrink-0 line-clamp-1">Add new account</span>
|
||||||
</ButtonBase>
|
</ButtonBase>
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
<Menu.Item value="" v-if="!currentIdentity">
|
<Menu.Item value="" v-if="!identity">
|
||||||
<NuxtLink href="/register" class="w-full">
|
<NuxtLink href="/register" class="w-full">
|
||||||
<ButtonBase theme="outline" class="w-full !justify-start">
|
<ButtonBase theme="outline" class="w-full !justify-start">
|
||||||
<Icon icon="tabler:certificate" class="!size-6" />
|
<Icon icon="tabler:certificate" class="!size-6" />
|
||||||
|
|
@ -92,9 +92,6 @@ import ButtonBase from "~/packages/ui/components/buttons/button.vue";
|
||||||
import Icon from "~/packages/ui/components/icons/icon.vue";
|
import Icon from "~/packages/ui/components/icons/icon.vue";
|
||||||
import Avatar from "../avatars/avatar.vue";
|
import Avatar from "../avatars/avatar.vue";
|
||||||
import AdaptiveDropdown from "../dropdowns/AdaptiveDropdown.vue";
|
import AdaptiveDropdown from "../dropdowns/AdaptiveDropdown.vue";
|
||||||
const identities = useIdentities();
|
|
||||||
|
|
||||||
const currentIdentity = useCurrentIdentity();
|
|
||||||
|
|
||||||
defineEmits<{
|
defineEmits<{
|
||||||
signIn: [];
|
signIn: [];
|
||||||
|
|
|
||||||
|
|
@ -139,9 +139,6 @@ const visibleTimelines = computed(() =>
|
||||||
const loadingAuth = ref(false);
|
const loadingAuth = ref(false);
|
||||||
|
|
||||||
const appData = useAppData();
|
const appData = useAppData();
|
||||||
const identity = useCurrentIdentity();
|
|
||||||
const identities = useIdentities();
|
|
||||||
const client = useClient();
|
|
||||||
const instance = useInstance();
|
const instance = useInstance();
|
||||||
|
|
||||||
const compose = () => {
|
const compose = () => {
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import SmallCard from "../users/SmallCard.vue";
|
import SmallCard from "../users/SmallCard.vue";
|
||||||
|
|
||||||
const client = useClient();
|
|
||||||
const instance = useInstance();
|
const instance = useInstance();
|
||||||
const description = useExtendedDescription(client);
|
const description = useExtendedDescription(client);
|
||||||
</script>
|
</script>
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
<template>
|
<template>
|
||||||
<a :href="`/@${account.acct}`"
|
<a :href="`/@${account.acct}`"
|
||||||
class="shrink break-all rounded bg-primary-700/80 text-primary-200 px-2 py-1 not-prose font-semibold cursor-pointer [&:not(:last-child)]:mr-1 duration-200 hover:bg-primary-600/30">
|
class="shrink break-all rounded bg-dark-200 ring-1 ring-white/5 ring-inset text-primary-200 px-2 py-1 not-prose font-semibold cursor-pointer [&:not(:last-child)]:mr-1 duration-200 hover:bg-primary-600/30">
|
||||||
<img class="size-[1em] rounded ring-1 ring-white/5 !inline align-middle mb-1 mr-1" :src="account.avatar"
|
<img class="size-[1em] rounded ring-1 ring-white/5 !inline align-middle mb-1 mr-1" :src="account.avatar"
|
||||||
:alt="`${account.acct}'s avatar'`" />
|
:alt="`${account.acct}'s avatar'`" />
|
||||||
{{ account.display_name }}
|
{{ account.display_name || account.acct }}
|
||||||
</a>
|
</a>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -176,9 +176,6 @@ useListen("composer:send-edit", (note) => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const client = useClient();
|
|
||||||
const identity = useCurrentIdentity();
|
|
||||||
const settings = useSettings();
|
|
||||||
const {
|
const {
|
||||||
loaded,
|
loaded,
|
||||||
note: outputtedNote,
|
note: outputtedNote,
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,5 @@ const props = defineProps<{
|
||||||
account_id: string | null;
|
account_id: string | null;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const client = useClient();
|
|
||||||
const account = useAccount(client, props.account_id);
|
const account = useAccount(client, props.account_id);
|
||||||
</script>
|
</script>
|
||||||
|
|
@ -39,7 +39,6 @@ const props = defineProps<{
|
||||||
element?: Notification;
|
element?: Notification;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const client = useClient();
|
|
||||||
const isWorkingOnFollowRequest = ref(false);
|
const isWorkingOnFollowRequest = ref(false);
|
||||||
const { relationship } = useRelationship(
|
const { relationship } = useRelationship(
|
||||||
client,
|
client,
|
||||||
|
|
@ -70,7 +69,6 @@ const rejectFollowRequest = async () => {
|
||||||
isWorkingOnFollowRequest.value = false;
|
isWorkingOnFollowRequest.value = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
const settings = useSettings();
|
|
||||||
const { display_name } = useParsedAccount(props.element?.account, settings);
|
const { display_name } = useParsedAccount(props.element?.account, settings);
|
||||||
|
|
||||||
const text = computed(() => {
|
const text = computed(() => {
|
||||||
|
|
|
||||||
|
|
@ -109,8 +109,6 @@ const props = defineProps<{
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const skeleton = computed(() => !props.account);
|
const skeleton = computed(() => !props.account);
|
||||||
const identity = useCurrentIdentity();
|
|
||||||
const client = useClient();
|
|
||||||
const config = useConfig();
|
const config = useConfig();
|
||||||
const accountId = computed(() => props.account?.id ?? null);
|
const accountId = computed(() => props.account?.id ?? null);
|
||||||
const { relationship, isLoading } = useRelationship(client, accountId);
|
const { relationship, isLoading } = useRelationship(client, accountId);
|
||||||
|
|
@ -155,7 +153,6 @@ const visibleRoles = computed(
|
||||||
() => props.account?.roles.filter((r) => r.visible) ?? [],
|
() => props.account?.roles.filter((r) => r.visible) ?? [],
|
||||||
);
|
);
|
||||||
|
|
||||||
const settings = useSettings();
|
|
||||||
const { display_name, fields, note } = useParsedAccount(
|
const { display_name, fields, note } = useParsedAccount(
|
||||||
computed(() => props.account),
|
computed(() => props.account),
|
||||||
settings,
|
settings,
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,6 @@
|
||||||
import type { Status } from "@lysand-org/client/types";
|
import type { Status } from "@lysand-org/client/types";
|
||||||
import Timeline from "./timeline.vue";
|
import Timeline from "./timeline.vue";
|
||||||
|
|
||||||
const client = useClient();
|
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
id: string;
|
id: string;
|
||||||
}>();
|
}>();
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@
|
||||||
import type { Status } from "@lysand-org/client/types";
|
import type { Status } from "@lysand-org/client/types";
|
||||||
import { useHomeTimeline } from "~/composables/HomeTimeline";
|
import { useHomeTimeline } from "~/composables/HomeTimeline";
|
||||||
import Timeline from "./timeline.vue";
|
import Timeline from "./timeline.vue";
|
||||||
const client = useClient();
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
error,
|
error,
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@
|
||||||
import type { Status } from "@lysand-org/client/types";
|
import type { Status } from "@lysand-org/client/types";
|
||||||
import { useLocalTimeline } from "~/composables/LocalTimeline";
|
import { useLocalTimeline } from "~/composables/LocalTimeline";
|
||||||
import Timeline from "./timeline.vue";
|
import Timeline from "./timeline.vue";
|
||||||
const client = useClient();
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
error,
|
error,
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,6 @@ import type { Notification } from "@lysand-org/client/types";
|
||||||
import { useNotificationTimeline } from "~/composables/NotificationTimeline";
|
import { useNotificationTimeline } from "~/composables/NotificationTimeline";
|
||||||
import Timeline from "./timeline.vue";
|
import Timeline from "./timeline.vue";
|
||||||
|
|
||||||
const client = useClient();
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
error,
|
error,
|
||||||
hasReachedEnd,
|
hasReachedEnd,
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@
|
||||||
import type { Status } from "@lysand-org/client/types";
|
import type { Status } from "@lysand-org/client/types";
|
||||||
import { usePublicTimeline } from "~/composables/PublicTimeline";
|
import { usePublicTimeline } from "~/composables/PublicTimeline";
|
||||||
import Timeline from "./timeline.vue";
|
import Timeline from "./timeline.vue";
|
||||||
const client = useClient();
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
error,
|
error,
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,11 @@
|
||||||
import type { LysandClient } from "@lysand-org/client";
|
import type { LysandClient } from "@lysand-org/client";
|
||||||
import type { RolePermission } from "@lysand-org/client/types";
|
import type { RolePermission } from "@lysand-org/client/types";
|
||||||
import { useCurrentIdentity } from "./Identities";
|
|
||||||
|
|
||||||
export const useCacheRefresh = (client: MaybeRef<LysandClient | null>) => {
|
export const useCacheRefresh = (client: MaybeRef<LysandClient | null>) => {
|
||||||
if (import.meta.server) {
|
if (import.meta.server) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const identity = useCurrentIdentity();
|
|
||||||
|
|
||||||
// Refresh custom emojis and instance data and me on every reload
|
// Refresh custom emojis and instance data and me on every reload
|
||||||
watchEffect(async () => {
|
watchEffect(async () => {
|
||||||
console.info("Refreshing emoji, instance and account cache");
|
console.info("Refreshing emoji, instance and account cache");
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,8 @@
|
||||||
import { LysandClient, type Token } from "@lysand-org/client";
|
import { LysandClient, type Token } from "@lysand-org/client";
|
||||||
import { useCurrentIdentity } from "./Identities";
|
|
||||||
|
|
||||||
export const useClient = (
|
export const useClient = (
|
||||||
customToken: MaybeRef<Token | null> = null,
|
customToken: MaybeRef<Token | null> = null,
|
||||||
): Ref<LysandClient> => {
|
): Ref<LysandClient> => {
|
||||||
const identity = useCurrentIdentity();
|
|
||||||
|
|
||||||
return computed(
|
return computed(
|
||||||
() =>
|
() =>
|
||||||
new LysandClient(
|
new LysandClient(
|
||||||
|
|
@ -25,3 +22,5 @@ export const useClient = (
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const client = useClient();
|
||||||
|
|
|
||||||
|
|
@ -5,72 +5,99 @@ import type {
|
||||||
Instance,
|
Instance,
|
||||||
RolePermission,
|
RolePermission,
|
||||||
} from "@lysand-org/client/types";
|
} from "@lysand-org/client/types";
|
||||||
import { StorageSerializers } from "@vueuse/core";
|
import { StorageSerializers, useLocalStorage } from "@vueuse/core";
|
||||||
|
import { ref, watch } from "vue";
|
||||||
|
|
||||||
export type Identity = {
|
/**
|
||||||
|
* Represents an identity with associated tokens, account, instance, permissions, and emojis.
|
||||||
|
*/
|
||||||
|
export interface Identity {
|
||||||
id: string;
|
id: string;
|
||||||
tokens: Token;
|
tokens: Token;
|
||||||
account: Account;
|
account: Account;
|
||||||
instance: Instance;
|
instance: Instance;
|
||||||
permissions: RolePermission[];
|
permissions: RolePermission[];
|
||||||
emojis: Emoji[];
|
emojis: Emoji[];
|
||||||
};
|
}
|
||||||
|
|
||||||
export const useIdentities = (): Ref<Identity[]> => {
|
/**
|
||||||
|
* Composable to manage multiple identities.
|
||||||
|
* @returns A reactive reference to an array of identities.
|
||||||
|
*/
|
||||||
|
function useIdentities(): Ref<Identity[]> {
|
||||||
return useLocalStorage<Identity[]>("lysand:identities", [], {
|
return useLocalStorage<Identity[]>("lysand:identities", [], {
|
||||||
serializer: StorageSerializers.object,
|
serializer: StorageSerializers.object,
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
|
export const identities = useIdentities();
|
||||||
|
|
||||||
export const useCurrentIdentity = (): Ref<Identity | null> => {
|
|
||||||
const currentId = useLocalStorage<string | null>(
|
const currentId = useLocalStorage<string | null>(
|
||||||
"lysand:identities:current",
|
"lysand:identities:current",
|
||||||
null,
|
null,
|
||||||
);
|
);
|
||||||
|
|
||||||
const identities = useIdentities();
|
const current = ref<Identity | null>(null);
|
||||||
const current = ref(
|
|
||||||
identities.value.find((i) => i.id === currentId.value) ?? null,
|
|
||||||
);
|
|
||||||
|
|
||||||
watch(identities, (ids) => {
|
/**
|
||||||
|
* Composable to manage the current identity.
|
||||||
|
* @returns A reactive reference to the current identity or null if not set.
|
||||||
|
*/
|
||||||
|
function useCurrentIdentity(): Ref<Identity | null> {
|
||||||
|
// Initialize current identity
|
||||||
|
function updateCurrentIdentity() {
|
||||||
|
current.value =
|
||||||
|
identities.value.find((i) => i.id === currentId.value) ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Watch for changes in identities
|
||||||
|
watch(
|
||||||
|
identities,
|
||||||
|
(ids) => {
|
||||||
if (ids.length === 0) {
|
if (ids.length === 0) {
|
||||||
current.value = null;
|
current.value = null;
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
watch(
|
|
||||||
current,
|
|
||||||
(newCurrent) => {
|
|
||||||
if (newCurrent) {
|
|
||||||
currentId.value = newCurrent.id;
|
|
||||||
// If the identity is updated, update the identity in the list
|
|
||||||
if (identities.value.find((i) => i.id === newCurrent.id)) {
|
|
||||||
identities.value = identities.value.map((i) =>
|
|
||||||
i.id === newCurrent.id ? newCurrent : i,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
// If the identity is not in the list, add it
|
|
||||||
else {
|
|
||||||
identities.value.push(newCurrent);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Force update the identities
|
|
||||||
identities.value = [...identities.value];
|
|
||||||
} else {
|
|
||||||
identities.value = identities.value.filter(
|
|
||||||
(i) => i.id !== currentId.value,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (identities.value.length > 0) {
|
|
||||||
currentId.value = identities.value[0]?.id;
|
|
||||||
} else {
|
|
||||||
currentId.value = null;
|
currentId.value = null;
|
||||||
}
|
} else {
|
||||||
|
updateCurrentIdentity();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ deep: true },
|
{ deep: true },
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Watch for changes in currentId
|
||||||
|
watch(currentId, updateCurrentIdentity);
|
||||||
|
|
||||||
|
// Watch for changes in current identity
|
||||||
|
watch(
|
||||||
|
current,
|
||||||
|
(newCurrent) => {
|
||||||
|
if (newCurrent) {
|
||||||
|
currentId.value = newCurrent.id;
|
||||||
|
const index = identities.value.findIndex(
|
||||||
|
(i) => i.id === newCurrent.id,
|
||||||
|
);
|
||||||
|
if (index !== -1) {
|
||||||
|
// Update existing identity
|
||||||
|
identities.value[index] = newCurrent;
|
||||||
|
} else {
|
||||||
|
// Add new identity
|
||||||
|
identities.value.push(newCurrent);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Remove current identity
|
||||||
|
identities.value = identities.value.filter(
|
||||||
|
(i) => i.id !== currentId.value,
|
||||||
|
);
|
||||||
|
currentId.value = identities.value[0]?.id ?? null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ deep: true },
|
||||||
|
);
|
||||||
|
|
||||||
|
// Initial setup
|
||||||
|
updateCurrentIdentity();
|
||||||
|
|
||||||
return current;
|
return current;
|
||||||
};
|
}
|
||||||
|
|
||||||
|
export const identity = useCurrentIdentity();
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,6 @@ import type { LysandClient } from "@lysand-org/client";
|
||||||
import type { ExtendedDescription, Instance } from "@lysand-org/client/types";
|
import type { ExtendedDescription, Instance } from "@lysand-org/client/types";
|
||||||
|
|
||||||
export const useInstance = () => {
|
export const useInstance = () => {
|
||||||
const identity = useCurrentIdentity();
|
|
||||||
|
|
||||||
return computed(() => identity.value?.instance);
|
return computed(() => identity.value?.instance);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
export const usePermissions = () => {
|
export const usePermissions = () => {
|
||||||
const identity = useCurrentIdentity();
|
|
||||||
|
|
||||||
return computed(() => identity.value?.permissions ?? []);
|
return computed(() => identity.value?.permissions ?? []);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
import type { LysandClient } from "@lysand-org/client";
|
import type { LysandClient } from "@lysand-org/client";
|
||||||
import type { Relationship } from "@lysand-org/client/types";
|
import type { Relationship } from "@lysand-org/client/types";
|
||||||
import { useCurrentIdentity } from "./Identities";
|
|
||||||
|
|
||||||
export const useRelationship = (
|
export const useRelationship = (
|
||||||
client: MaybeRef<LysandClient | null>,
|
client: MaybeRef<LysandClient | null>,
|
||||||
|
|
@ -9,7 +8,7 @@ export const useRelationship = (
|
||||||
const relationship = ref(null as Relationship | null);
|
const relationship = ref(null as Relationship | null);
|
||||||
const isLoading = ref(false);
|
const isLoading = ref(false);
|
||||||
|
|
||||||
if (!useCurrentIdentity().value) {
|
if (!identity.value) {
|
||||||
return { relationship, isLoading };
|
return { relationship, isLoading };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,14 +11,18 @@ export const useResolveMentions = (
|
||||||
|
|
||||||
const output = ref<Account[]>([]);
|
const output = ref<Account[]>([]);
|
||||||
|
|
||||||
watch(mentions, async () => {
|
watch(
|
||||||
|
mentions,
|
||||||
|
async () => {
|
||||||
output.value = await Promise.all(
|
output.value = await Promise.all(
|
||||||
toValue(mentions).map(async (mention) => {
|
toValue(mentions).map(async (mention) => {
|
||||||
const response = await client.getAccount(mention.id);
|
const response = await client.getAccount(mention.id);
|
||||||
return response.data;
|
return response.data;
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
});
|
},
|
||||||
|
{ immediate: true },
|
||||||
|
);
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,11 @@ import {
|
||||||
type SettingIds,
|
type SettingIds,
|
||||||
type Settings,
|
type Settings,
|
||||||
parseFromJson,
|
parseFromJson,
|
||||||
settings,
|
settings as settingsJson,
|
||||||
} from "~/settings";
|
} from "~/settings";
|
||||||
|
|
||||||
export const useSettings = () => {
|
const useSettings = () => {
|
||||||
return useLocalStorage<Settings>("lysand:settings", settings, {
|
return useLocalStorage<Settings>("lysand:settings", settingsJson, {
|
||||||
serializer: {
|
serializer: {
|
||||||
read(raw) {
|
read(raw) {
|
||||||
const json = StorageSerializers.object.read(raw);
|
const json = StorageSerializers.object.read(raw);
|
||||||
|
|
@ -31,9 +31,9 @@ export const useSettings = () => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useSetting = <T extends Setting = Setting>(id: SettingIds) => {
|
export const settings = useSettings();
|
||||||
const settings = useSettings();
|
|
||||||
|
|
||||||
|
export const useSetting = <T extends Setting = Setting>(id: SettingIds) => {
|
||||||
const setting: Ref<T> = ref<T>(
|
const setting: Ref<T> = ref<T>(
|
||||||
settings.value.find((s) => s.id === id) as T,
|
settings.value.find((s) => s.id === id) as T,
|
||||||
) as unknown as Ref<T>;
|
) as unknown as Ref<T>;
|
||||||
|
|
@ -52,5 +52,5 @@ export const useSetting = <T extends Setting = Setting>(id: SettingIds) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getSetting = <T extends Setting = Setting>(id: SettingIds) => {
|
export const getSetting = <T extends Setting = Setting>(id: SettingIds) => {
|
||||||
return settings.find((s) => s.id === id) as T;
|
return settingsJson.find((s) => s.id === id) as T;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,6 @@ const notUsingInput = computed(
|
||||||
activeElement.value?.tagName !== "INPUT" &&
|
activeElement.value?.tagName !== "INPUT" &&
|
||||||
activeElement.value?.tagName !== "TEXTAREA",
|
activeElement.value?.tagName !== "TEXTAREA",
|
||||||
);
|
);
|
||||||
const identity = useCurrentIdentity();
|
|
||||||
|
|
||||||
watchEffect(async () => {
|
watchEffect(async () => {
|
||||||
if (n?.value && notUsingInput.value) {
|
if (n?.value && notUsingInput.value) {
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,6 @@ definePageMeta({
|
||||||
|
|
||||||
const element = ref<HTMLElement | null>(null);
|
const element = ref<HTMLElement | null>(null);
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const client = useClient();
|
|
||||||
const uuid = route.params.uuid as string;
|
const uuid = route.params.uuid as string;
|
||||||
|
|
||||||
const note = useNote(client, uuid);
|
const note = useNote(client, uuid);
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ definePageMeta({
|
||||||
});
|
});
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const client = useClient();
|
|
||||||
const username = (route.params.username as string).startsWith("@")
|
const username = (route.params.username as string).startsWith("@")
|
||||||
? (route.params.username as string).substring(1)
|
? (route.params.username as string).substring(1)
|
||||||
: (route.params.username as string);
|
: (route.params.username as string);
|
||||||
|
|
|
||||||
|
|
@ -28,5 +28,4 @@ import TimelineScroller from "~/components/timelines/timeline-scroller.vue";
|
||||||
definePageMeta({
|
definePageMeta({
|
||||||
layout: "app",
|
layout: "app",
|
||||||
});
|
});
|
||||||
const identity = useCurrentIdentity();
|
|
||||||
</script>
|
</script>
|
||||||
|
|
@ -76,7 +76,6 @@ import Label from "~/components/inputs/label.vue";
|
||||||
import PasswordInput from "~/components/inputs/password-input.vue";
|
import PasswordInput from "~/components/inputs/password-input.vue";
|
||||||
import Button from "~/packages/ui/components/buttons/button.vue";
|
import Button from "~/packages/ui/components/buttons/button.vue";
|
||||||
|
|
||||||
const identity = useCurrentIdentity();
|
|
||||||
identity.value = null;
|
identity.value = null;
|
||||||
|
|
||||||
const schema = toTypedSchema(
|
const schema = toTypedSchema(
|
||||||
|
|
|
||||||
|
|
@ -84,7 +84,8 @@
|
||||||
cannot see your password.
|
cannot see your password.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<Button theme="primary" type="submit" class="w-full" :disabled="isLoading">{{ isLoading ? "Registering..." :
|
<Button theme="primary" type="submit" class="w-full" :disabled="isLoading">{{ isLoading ?
|
||||||
|
"Registering..." :
|
||||||
"Register" }}</Button>
|
"Register" }}</Button>
|
||||||
</VeeForm>
|
</VeeForm>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -140,7 +141,6 @@ const schema = toTypedSchema(
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
const client = useClient();
|
|
||||||
const tos = useTos(client);
|
const tos = useTos(client);
|
||||||
|
|
||||||
const errors = ref<{
|
const errors = ref<{
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,4 @@ import { SettingPages, getSettingsForPath } from "~/settings";
|
||||||
definePageMeta({
|
definePageMeta({
|
||||||
layout: "app",
|
layout: "app",
|
||||||
});
|
});
|
||||||
|
|
||||||
const settings = useSettings();
|
|
||||||
</script>
|
</script>
|
||||||
|
|
@ -2,10 +2,6 @@ import type { ApplicationData } from "@lysand-org/client/types";
|
||||||
import { nanoid } from "nanoid";
|
import { nanoid } from "nanoid";
|
||||||
|
|
||||||
export const signInWithCode = (code: string, appData: ApplicationData) => {
|
export const signInWithCode = (code: string, appData: ApplicationData) => {
|
||||||
const identity = useCurrentIdentity();
|
|
||||||
const identities = useIdentities();
|
|
||||||
const client = useClient();
|
|
||||||
|
|
||||||
client.value
|
client.value
|
||||||
?.fetchAccessToken(
|
?.fetchAccessToken(
|
||||||
appData.client_id,
|
appData.client_id,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue