();
+defineProps<
+ Props & {
+ loading?: boolean;
+ }
+>();
\ No newline at end of file
diff --git a/components/sidebars/navigation.vue b/components/sidebars/navigation.vue
index 8f0aa78..74c3264 100644
--- a/components/sidebars/navigation.vue
+++ b/components/sidebars/navigation.vue
@@ -21,14 +21,17 @@
Account
-
-
-
- Sign In
-
-
-
+ loadingAuth = false)" :loading="loadingAuth"
+ class="flex flex-row text-left items-center justify-start gap-3 text-lg hover:ring-1 ring-white/10 overflow-hidden h-12 w-full duration-200">
+
+ Sign Out
+
+ loadingAuth = false)" :loading="loadingAuth"
+ class="flex flex-row text-left items-center justify-start gap-3 text-lg hover:ring-1 ring-white/10 overflow-hidden h-12 w-full duration-200">
+
+ Sign In
+
+
@@ -52,4 +55,63 @@ const timelines = ref([
icon: "tabler:home",
},
]);
+
+const loadingAuth = ref(false);
+
+const appData = useAppData();
+const tokenData = useTokenData();
+const client = useMegalodon();
+
+const signIn = async () => {
+ loadingAuth.value = true;
+
+ const output = await client.value?.createApp("Lysand", {
+ scopes: ["read", "write", "follow", "push"],
+ redirect_uris: new URL("/", useRequestURL().origin).toString(),
+ website: useBaseUrl().value,
+ });
+
+ if (!output) {
+ alert("Failed to create app");
+ return;
+ }
+
+ appData.value = output;
+
+ const url = await client.value?.generateAuthUrl(
+ output.client_id,
+ output.client_secret,
+ {
+ scope: ["read", "write", "follow", "push"],
+ redirect_uri: new URL("/", useRequestURL().origin).toString(),
+ },
+ );
+
+ if (!url) {
+ alert("Failed to generate auth URL");
+ return;
+ }
+
+ window.location.href = url;
+};
+
+const signOut = async () => {
+ loadingAuth.value = true;
+
+ if (!appData.value || !tokenData.value) {
+ console.error("No app or token data to sign out");
+ return;
+ }
+
+ // Don't do anything on error, as Lysand doesn't implement the revoke endpoint yet
+ await client.value
+ ?.revokeToken(
+ appData.value.client_id,
+ tokenData.value.access_token,
+ tokenData.value.access_token,
+ )
+ .catch(() => {});
+
+ tokenData.value = null;
+};
\ No newline at end of file
diff --git a/components/social-elements/notes/header.vue b/components/social-elements/notes/header.vue
index ea19486..25908a9 100644
--- a/components/social-elements/notes/header.vue
+++ b/components/social-elements/notes/header.vue
@@ -55,7 +55,7 @@
\ No newline at end of file
diff --git a/components/social-elements/users/Account.vue b/components/social-elements/users/Account.vue
index 2646822..2603e09 100644
--- a/components/social-elements/users/Account.vue
+++ b/components/social-elements/users/Account.vue
@@ -115,29 +115,27 @@ watch(
skeleton,
async () => {
if (skeleton.value) return;
- parsedNote.value = (
+ parsedNote.value =
useParsedContent(
props.account?.note ?? "",
props.account?.emojis ?? [],
[],
- )
- ).value ?? "";
- parsedFields.value = props.account?.fields.map((field) => ({
- name: (
- useParsedContent(
- field.name,
- props.account?.emojis ?? [],
- [],
- )
- ).value ?? "",
- value: (
- useParsedContent(
- field.value,
- props.account?.emojis ?? [],
- [],
- )
- ).value ?? "",
- })) ?? [];
+ ).value ?? "";
+ parsedFields.value =
+ props.account?.fields.map((field) => ({
+ name:
+ useParsedContent(
+ field.name,
+ props.account?.emojis ?? [],
+ [],
+ ).value ?? "",
+ value:
+ useParsedContent(
+ field.value,
+ props.account?.emojis ?? [],
+ [],
+ ).value ?? "",
+ })) ?? [];
},
{
immediate: true,
diff --git a/components/timelines/Notifications.vue b/components/timelines/Notifications.vue
index 788fcae..2c94282 100644
--- a/components/timelines/Notifications.vue
+++ b/components/timelines/Notifications.vue
@@ -14,15 +14,15 @@