client configuration manager

This commit is contained in:
2026-01-03 21:49:42 +08:00
parent b48d15df59
commit f85d7e773d
12 changed files with 395 additions and 72 deletions

View File

@@ -15,14 +15,27 @@
signingOut = false;
}
}
const openClientConfigManager = async () => {
try {
await invoke("open_client_config_manager");
} catch (error) {
console.error("Failed to open client config manager", error);
}
};
</script>
<div class="size-full flex flex-col justify-between">
<div class="flex flex-col gap-2">
<p>{$appData?.user?.name}'s preferences</p>
<button class="btn" class:btn-disabled={signingOut} onclick={handleSignOut}>
{signingOut ? "Signing out..." : "Sign out"}
</button>
<div class="flex flex-row gap-2">
<button class="btn" class:btn-disabled={signingOut} onclick={handleSignOut}>
{signingOut ? "Signing out..." : "Sign out"}
</button>
<button class="btn btn-outline" onclick={openClientConfigManager}>
Advanced options
</button>
</div>
</div>
<div class="w-full flex flex-row justify-between">
<div></div>

View File

@@ -0,0 +1,109 @@
<script lang="ts">
import { onMount } from "svelte";
import { invoke } from "@tauri-apps/api/core";
type AuthConfig = {
audience: string;
auth_url: string;
};
type AppConfig = {
api_base_url?: string | null;
auth: AuthConfig;
};
let form: AppConfig = {
api_base_url: "",
auth: { audience: "", auth_url: "" },
};
let saving = false;
let errorMessage = "";
let successMessage = "";
const loadConfig = async () => {
try {
const config = (await invoke("get_client_config")) as AppConfig;
form = {
api_base_url: config.api_base_url ?? "",
auth: {
audience: config.auth.audience,
auth_url: config.auth.auth_url,
},
};
} catch (err) {
errorMessage = `Failed to load config: ${err}`;
}
};
const save = async () => {
if (saving) return;
saving = true;
errorMessage = "";
successMessage = "";
try {
await invoke("save_client_config", {
config: {
api_base_url: form.api_base_url?.trim() || null,
auth: {
audience: form.auth.audience.trim(),
auth_url: form.auth.auth_url.trim(),
},
},
});
successMessage = "Configuration saved. Please restart the app.";
await invoke("restart_app");
} catch (err) {
errorMessage = `Failed to save config: ${err}`;
} finally {
saving = false;
}
};
onMount(loadConfig);
</script>
<div class="p-6 flex flex-col gap-4">
<div class="flex flex-col gap-1">
<p class="text-xl font-semibold">Client Configuration</p>
<p class="opacity-70 text-sm">Set custom API and auth endpoints.</p>
</div>
<div class="flex flex-col gap-3">
<label class="flex flex-col gap-1">
<span class="text-sm">API Base URL</span>
<input
class="input input-bordered"
bind:value={form.api_base_url}
placeholder="https://api.fdolls.adamcv.com"
/>
</label>
<label class="flex flex-col gap-1">
<span class="text-sm">Auth URL</span>
<input class="input input-bordered" bind:value={form.auth.auth_url} />
</label>
<label class="flex flex-col gap-1">
<span class="text-sm">JWT Audience</span>
<input class="input input-bordered" bind:value={form.auth.audience} />
</label>
</div>
{#if errorMessage}
<p class="text-sm text-error">{errorMessage}</p>
{/if}
{#if successMessage}
<p class="text-sm text-success">{successMessage}</p>
{/if}
<div class="flex flex-row gap-2">
<button
class="btn"
class:btn-disabled={saving}
disabled={saving}
on:click={save}
>
{saving ? "Saving..." : "Save"}
</button>
</div>
</div>

View File

@@ -34,15 +34,16 @@
<div class="size-full p-4">
<div class="flex flex-col gap-4 size-full justify-between">
<div class="flex flex-col gap-2">
<p class="text-md font-light">Something is not right...</p>
<p class="opacity-70 text-3xl font-bold">
Seems like the server is inaccessible. Check your network?
</p>
{#if errorMessage}
<p class="text-sm opacity-70 wrap-break-word">{errorMessage}</p>
{/if}
</div>
<div class="flex flex-col gap-2">
<p class="text-md font-light">Something is not right...</p>
<p class="opacity-70 text-3xl font-bold">
Seems like the server is inaccessible. Check your network?
</p>
{#if errorMessage}
<p class="text-sm opacity-70 wrap-break-word">{errorMessage}</p>
{/if}
</div>
<div class="flex flex-row gap-2">
<button
class="btn"
class:btn-disabled={isRestarting}
@@ -55,5 +56,10 @@
Try again
{/if}
</button>
<button class="btn btn-outline" onclick={async () => invoke("open_client_config_manager")}>
Advanced options
</button>
</div>
</div>
</div>

View File

@@ -17,6 +17,14 @@
isContinuing = false;
}
};
const openClientConfigManager = async () => {
try {
await invoke("open_client_config_manager");
} catch (error) {
console.error("Failed to open client config manager", error);
}
};
</script>
<div class="size-full relative bg-linear-to-br from-base-100 to-[#b7f2ff77]">
@@ -32,22 +40,26 @@
a cute passive socialization layer!
</p>
</div>
<div>
<button
class="btn btn-primary"
onclick={handleContinue}
disabled={isContinuing}
>
{#if isContinuing}
Loading...
{:else}
<div class="scale-70">
<ExternalLink />
</div>
Sign in with browser
{/if}
</button>
</div>
<div class="flex flex-col gap-2">
<button
class="btn btn-primary"
onclick={handleContinue}
disabled={isContinuing}
>
{#if isContinuing}
Loading...
{:else}
<div class="scale-70">
<ExternalLink />
</div>
Sign in with browser
{/if}
</button>
<button class="btn btn-outline" onclick={openClientConfigManager}>
Advanced options
</button>
</div>
<p class="text-xs opacity-50 max-w-60">
An account is needed to identify you for connecting with friends.
</p>