client configuration manager
This commit is contained in:
@@ -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>
|
||||
|
||||
109
src/routes/client-config-manager/+page.svelte
Normal file
109
src/routes/client-config-manager/+page.svelte
Normal 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>
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user