mirror of
https://github.com/ankitects/anki.git
synced 2025-11-06 12:47:11 -05:00
143 lines
3.9 KiB
Svelte
143 lines
3.9 KiB
Svelte
<!--
|
|
Copyright: Ankitects Pty Ltd and contributors
|
|
License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|
-->
|
|
<script lang="ts">
|
|
import {
|
|
Mirror,
|
|
type Options as OptionsProto,
|
|
type ChooseVersionResponse,
|
|
type GetMirrorsResponse_Pair,
|
|
} from "@generated/anki/launcher_pb";
|
|
import {
|
|
chooseVersion,
|
|
getAvailableVersions,
|
|
getExistingVersions,
|
|
} from "@generated/backend-launcher";
|
|
import Row from "$lib/components/Row.svelte";
|
|
import { tr } from "./stores";
|
|
import Warning from "./Warning.svelte";
|
|
import Action from "./Action.svelte";
|
|
import Spinner from "./Spinner.svelte";
|
|
import Options from "./Options.svelte";
|
|
import Term from "./Term.svelte";
|
|
import AnkiWillStart from "./AnkiWillStart.svelte";
|
|
import type { Terminal } from "@xterm/xterm";
|
|
import { tick } from "svelte";
|
|
|
|
let {
|
|
options,
|
|
mirrors,
|
|
uninstall,
|
|
footer = $bindable(),
|
|
}: {
|
|
options: OptionsProto;
|
|
mirrors: GetMirrorsResponse_Pair[];
|
|
uninstall: (() => void) | null;
|
|
footer: any; // https://github.com/sveltejs/svelte/issues/15182
|
|
} = $props();
|
|
|
|
footer = _footer;
|
|
|
|
let releasesPromise = $state(getAvailableVersions({}, { alertOnError: false }));
|
|
let existingPromise = $state(getExistingVersions({}, { alertOnError: false }));
|
|
let loadPromise = $derived(Promise.all([releasesPromise, existingPromise]));
|
|
|
|
let allowBetas = $state(options.allowBetas);
|
|
let downloadCaching = $state(options.downloadCaching);
|
|
let selectedMirror = $state(Mirror.DISABLED);
|
|
|
|
let choosePromise: Promise<ChooseVersionResponse | null> = $state(
|
|
Promise.resolve(null),
|
|
);
|
|
|
|
let error: Error | null = $state(null);
|
|
const setError = (e: Error) => {
|
|
tick().then(() => (error = e));
|
|
};
|
|
|
|
let term: Terminal | undefined = $state(undefined);
|
|
let termOpen = $state(false);
|
|
let chosen = $state(false);
|
|
|
|
const choose = (version: string, keepExisting: boolean, current?: string) => {
|
|
chosen = true;
|
|
term?.reset();
|
|
choosePromise = chooseVersion({
|
|
version,
|
|
keepExisting,
|
|
options: { allowBetas, downloadCaching, mirror: selectedMirror },
|
|
...(current ? { current } : {}),
|
|
});
|
|
};
|
|
</script>
|
|
|
|
{#await choosePromise}
|
|
<Row class="centre m-3">
|
|
<Spinner label={$tr.launcherSyncing()} />
|
|
</Row>
|
|
{:then res}
|
|
{#if res === null}
|
|
{#await loadPromise}
|
|
<Row class="centre m-3">
|
|
<Spinner label={$tr.launcherLoadingVersions()} />
|
|
</Row>
|
|
{:then [releases, existing]}
|
|
<Action {releases} {existing} {allowBetas} {choose} {uninstall} />
|
|
{:catch e}
|
|
{setError(e)}
|
|
<Warning
|
|
warning={$tr.lauuncherFailedToLoadVersions()}
|
|
className="alert-danger"
|
|
/>
|
|
{/await}
|
|
{:else}
|
|
<Row class="centre m-3">
|
|
<AnkiWillStart {res} />
|
|
</Row>
|
|
{/if}
|
|
{:catch e}
|
|
{setError(e)}
|
|
<Warning warning={$tr.launcherFailedToSync()} className="alert-danger" />
|
|
{/await}
|
|
|
|
{#if error != null}
|
|
<Row>
|
|
<pre>{error.message}</pre>
|
|
</Row>
|
|
{/if}
|
|
|
|
{#snippet _footer()}
|
|
<Term bind:term bind:open={termOpen} />
|
|
{#if !chosen}
|
|
<Row class="row-columns">
|
|
<Options
|
|
{mirrors}
|
|
bind:allowBetas
|
|
bind:downloadCaching
|
|
bind:selectedMirror
|
|
/>
|
|
</Row>
|
|
{/if}
|
|
{/snippet}
|
|
|
|
<style lang="scss">
|
|
:root {
|
|
font-size: 16px;
|
|
font-weight: 400;
|
|
|
|
text-rendering: optimizeLegibility;
|
|
font-synthesis: none;
|
|
-webkit-font-smoothing: antialiased;
|
|
-moz-osx-font-smoothing: grayscale;
|
|
-webkit-text-size-adjust: 100%;
|
|
}
|
|
|
|
:global(.centre) {
|
|
justify-content: center;
|
|
}
|
|
|
|
pre {
|
|
white-space: pre-wrap;
|
|
}
|
|
</style>
|