Files
sync/src/routes/setup/+page.svelte
Sticks a0649911fe
Some checks failed
FanslySync Build & Test / FanslySync Test Runner (push) Failing after 24m12s
fix: make display_name an Option so parsing doesn't fail
2025-04-28 10:51:08 -04:00

199 lines
5.8 KiB
Svelte
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<script lang="ts">
import { onMount } from 'svelte';
import { invoke } from '@tauri-apps/api/core';
import { writeText } from '@tauri-apps/plugin-clipboard-manager';
import { message } from '@tauri-apps/plugin-dialog';
import { awaiter } from '$lib/utils';
// --- Types & Config ---
import type { Config, AccountInfo } from '$lib/types';
// --- State ---
let loading = true;
let errored = false;
let step = 0;
let status = 'Contacting Fansly and checking account...';
let fanslyToken = '';
let validationErrors = { fanslyToken: '' };
onMount(async () => {
const [config, configError] = await awaiter(invoke('get_config'));
if (configError) return await handleError(configError);
loading = false;
});
async function handleError(err: unknown) {
errored = true;
await message(`Something went wrong. Error: ${err}`, { title: 'Setup Error', kind: 'error' });
await writeText(String(err));
invoke('quit', { code: 1 });
}
function validateLoginForm() {
validationErrors.fanslyToken = fanslyToken ? '' : 'Please enter your Fansly token.';
if (validationErrors.fanslyToken) return;
step = 2;
loginToFanslyAndFetchData();
}
async function loginToFanslyAndFetchData() {
try {
const [config] = await awaiter(invoke('get_config') as Promise<Config>);
if (!config) {
validationErrors.fanslyToken =
'Failed to retrieve configuration -- please try restarting the app.';
step = 1;
return;
}
await invoke('fansly_set_token', { token: fanslyToken });
const [me, err] = (await awaiter(invoke('fansly_get_me'))) as [
{ success: boolean; response: AccountInfo },
unknown
];
if (err || !me?.success) {
if (err) {
console.error('Error fetching account info:', err);
}
validationErrors.fanslyToken =
'Authentication failed. Please check your token and try again.';
step = 1;
return;
}
status = 'Finishing up...';
config.fansly_token = fanslyToken;
config.is_first_run = false;
await invoke('save_config', { config });
step = 3;
} catch (e) {
validationErrors.fanslyToken = 'Unexpected error. Please try again.';
step = 1;
}
}
</script>
<div class="flex items-center justify-center min-h-screen bg-zinc-900 text-zinc-200 p-6">
<div class="w-full max-w-lg space-y-8">
{#if loading}
<div class="text-center space-y-4">
<svg class="mx-auto w-16 h-16 animate-spin text-zinc-600 fill-zinc-500" viewBox="0 0 24 24">
<circle cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4" fill="none"
></circle>
<path d="M22 12a10 10 0 00-10-10" stroke="currentFill" stroke-width="4"></path>
</svg>
<p>Loading setup...</p>
</div>
{:else if errored}
<div class="text-center space-y-4">
<svg
class="mx-auto w-12 h-12 text-red-500"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<path d="M6 18L18 6M6 6l12 12"></path>
</svg>
<h2 class="text-2xl font-bold">Oops!</h2>
<p>An error occurred during setup. Please restart the application.</p>
</div>
{:else}
<!-- Step 0: Welcome -->
{#if step === 0}
<div class="space-y-4 text-center">
<h2 class="text-2xl font-bold">Welcome to FanslySync!</h2>
<p>
Since this is your first time running FanslySync, we need to connect to your Fansly
account.
</p>
<button
on:click={() => (step = 1)}
class="mt-4 w-full bg-blue-600 text-white py-2 rounded hover:bg-blue-500 transition"
>
Begin Setup
</button>
</div>
<!-- Step 1: Token entry -->
{:else if step === 1}
<div class="space-y-4">
<h2 class="text-2xl font-bold text-center">Authenticate with Fansly</h2>
<p class="text-zinc-400">
Enter your Fansly Authentication Token. We use it only locally to fetch data.
</p>
<div class="space-y-2">
<label for="token" class="block">Fansly Token</label>
<input
id="token"
type="text"
bind:value={fanslyToken}
class="w-full bg-zinc-800 p-2 rounded placeholder-zinc-500"
placeholder="Paste your token here"
/>
{#if validationErrors.fanslyToken}
<p class="text-red-500 text-sm">{validationErrors.fanslyToken}</p>
{/if}
</div>
<button
on:click={validateLoginForm}
class="mt-4 w-full bg-blue-600 text-white py-2 rounded hover:bg-blue-500 transition"
>
Authenticate &amp; Continue
</button>
</div>
<!-- Step 2: Loading -->
{:else if step === 2}
<div class="text-center space-y-4">
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
class="mx-auto size-16 animate-spin"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M16.023 9.348h4.992v-.001M2.985 19.644v-4.992m0 0h4.992m-4.993 0 3.181 3.183a8.25 8.25 0 0 0 13.803-3.7M4.031 9.865a8.25 8.25 0 0 1 13.803-3.7l3.181 3.182m0-4.991v4.99"
/>
</svg>
<h2 class="text-2xl font-bold">Processing…</h2>
<p>{status}</p>
</div>
<!-- Step 3: Success -->
{:else if step === 3}
<div class="text-center space-y-4">
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
class="mx-auto size-16 text-green-400"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M9 12.75 11.25 15 15 9.75M21 12a9 9 0
1 1-18 0 9 9 0 0 1 18 0Z"
/>
</svg>
<h2 class="text-2xl font-bold">Setup Complete!</h2>
<p>Youre now connected. Ready to go!</p>
<button
on:click={() => (window.location.href = '/home')}
class="mt-4 w-full bg-blue-600 text-white py-2 rounded hover:bg-blue-500 transition"
>
Finish
</button>
</div>
{/if}
{/if}
</div>
</div>