perf: ♻️ Use global instance of composable instead of an instance per component for identities, client and settings

This commit is contained in:
Jesse Wierzbinski 2024-07-21 15:33:32 +02:00
parent f1ada1745d
commit 3428e4b5b6
No known key found for this signature in database
38 changed files with 104 additions and 131 deletions

View file

@ -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);

View file

@ -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;

View file

@ -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) => ({

View file

@ -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 = () => {

View file

@ -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(

View file

@ -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();

View file

@ -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,

View file

@ -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);

View file

@ -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 = () => {

View file

@ -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: [];

View file

@ -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 = () => {

View file

@ -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>

View file

@ -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>

View file

@ -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,

View file

@ -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>

View file

@ -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(() => {

View file

@ -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,

View file

@ -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;
}>(); }>();

View file

@ -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,

View file

@ -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,

View file

@ -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,

View file

@ -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,

View file

@ -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");

View file

@ -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();

View file

@ -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 useCurrentIdentity = (): Ref<Identity | null> => { export const identities = useIdentities();
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();

View file

@ -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);
}; };

View file

@ -1,5 +1,3 @@
export const usePermissions = () => { export const usePermissions = () => {
const identity = useCurrentIdentity();
return computed(() => identity.value?.permissions ?? []); return computed(() => identity.value?.permissions ?? []);
}; };

View file

@ -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 };
} }

View file

@ -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;
}; };

View file

@ -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;
}; };

View file

@ -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) {

View file

@ -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);

View file

@ -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);

View file

@ -28,5 +28,4 @@ import TimelineScroller from "~/components/timelines/timeline-scroller.vue";
definePageMeta({ definePageMeta({
layout: "app", layout: "app",
}); });
const identity = useCurrentIdentity();
</script> </script>

View file

@ -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(

View file

@ -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<{

View file

@ -33,6 +33,4 @@ import { SettingPages, getSettingsForPath } from "~/settings";
definePageMeta({ definePageMeta({
layout: "app", layout: "app",
}); });
const settings = useSettings();
</script> </script>

View file

@ -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,