feat: automatic keychip installation, improved onboarding ux, tweak styles, bomb israel

This commit is contained in:
raymonable
2026-02-14 23:41:22 -05:00
parent 6ddb72e28e
commit ca5d33a1cc
14 changed files with 526 additions and 248 deletions

View File

@@ -7,80 +7,105 @@
import { codeToHtml } from 'shiki'
import { AQUA_CONNECTION, DISCORD_INVITE, FADE_IN, FADE_OUT } from "../../libs/config";
import { t } from "../../libs/i18n";
import DashboardTabs from "./DashboardTabs.svelte";
import { patchUserSegatools } from "../../libs/setup";
let user: AquaNetUser
let keychip: string;
let keychipCode: string;
let getStartedRequesting = false;
let exposeKeychip = false;
let automaticSetupStatus: "none" | "success" | "failure" = "none";
USER.me().then((u) => {
user = u;
});
function getStarted() {
if (getStartedRequesting) return;
getStartedRequesting = true;
USER.keychip().then(k => {
getStartedRequesting = false;
keychip = k;
keychip = `${k.slice(0, 4)}-${k.slice(4)}1337`;
codeToHtml(`
[dns]
default=${AQUA_CONNECTION}
[keychip]
enable=1
; ${t('home.setup.keychip-tips')}
id=${keychip.slice(0, 4)}-${keychip.slice(4)}1337`.trim(), {
id=${keychip}`.trim(), {
lang: 'ini',
theme: 'rose-pine',
transformers: []
}).then((html) => {
keychipCode = html;
});
});
});
async function patchSegatools() {
automaticSetupStatus = await patchUserSegatools({ keychip, dns: AQUA_CONNECTION }) ? "success" : "failure";
}
</script>
<div class="setup-instructions">
<h2>{t('home.setup')}</h2>
<p>
{t('home.setup.welcome')}
</p>
<blockquote>
{t('home.setup.blockquote')}
</blockquote>
<main class="content">
<DashboardTabs />
<div class="setup-instructions">
<h2>{t('home.setup')}</h2>
{#if user}
<div transition:slide>
{#if !keychip && !keychipCode}
<div class="no-margin" out:fade={FADE_OUT}>
<button class="emp" on:click={getStarted}>{t('home.setup.get')}</button>
{#if keychip}
<div class="setup-step">
1. <div>{@html t('setup.steps.one')}</div>
</div>
<blockquote class="info">
{t('setup.keychip-warning')}
</blockquote>
<details>
<summary>{t('setup.type.automatic')}</summary>
{@html t('setup.automatic')}
{#if automaticSetupStatus != "none"}
<blockquote class={`keychip-status ${automaticSetupStatus}`}>
{t(`setup.automatic.${automaticSetupStatus}`)}
</blockquote>
{/if}
<div class="setup-btn">
<button on:click={patchSegatools}>{t('setup.automatic.select')}</button>
</div>
{:else}
<div class="no-margin" in:fade={FADE_IN}>
<p>
{t('home.setup.edit')}:
</p>
</details>
<div class="code">
<details>
<summary>{t('setup.type.manual')}</summary>
{@html t('setup.manual')}
<div class="code-container">
<div class="code" class:revealed={exposeKeychip}>
{@html keychipCode}
</div>
<p>
{t('home.setup.test')}
</p>
<p>
{t('home.setup.ask')} <a href={DISCORD_INVITE}>Discord</a> {t('home.setup.support')}.
</p>
{#if !exposeKeychip}
<button class="reveal-btn" on:click={() => exposeKeychip = true}>
{t('setup.reveal-keychip')}
</button>
{/if}
</div>
{/if}
</div>
{:else}
<p>Loading...</p>
{/if}
</div>
</details>
<br>
<div class="setup-step">
2. <div>{@html t('setup.steps.two')}</div>
</div>
<div class="setup-step">
3. <div>{@html t('setup.steps.three')}</div>
</div>
<div class="setup-step">
4. <div>{@html t('setup.steps.four')}</div>
</div>
<p>
{@html t('setup.support-info')}
</p>
{:else}
<p>{t('loading')}</p>
{/if}
</div>
</main>
<style lang="sass">
@use "../../vars"
.code
overflow-x: auto
@@ -100,4 +125,45 @@ id=${keychip.slice(0, 4)}-${keychip.slice(4)}1337`.trim(), {
text-align: right
color: rgba(115,138,148,.4)
.setup-step
display: flex
div
margin-left: 1em
.setup-btn
margin: 0.5em
details
summary
cursor: pointer
font-weight: bold
padding: 0.25em 0
&:open
summary
margin: 0 0 1em 0
.code-container
padding: 10px
position: relative
margin: 1em
overflow: hidden
background: vars.$c-shadow
.code
filter: blur(4px)
transition: 250ms filter
&.revealed
filter: none
:global(.copy)
position: absolute
right: 2em
top: 2em
.reveal-btn
position: absolute
top: 50%
left: 50%
transform: translate(-50%, -50%)
</style>