commit 19cae68be11aa50e6c8ad9cbac53abb3c0660e3b
parent 4a35f84694bcddd107f038405ab1037d329fdae4
Author: triesap <triesap@radroots.dev>
Date: Thu, 22 Jan 2026 16:18:02 +0000
app: scaffold setup intro screen
- replace setup placeholder with structured intro layout
- add setup step signal and basic navigation between steps
- keep setup gating redirect intact
- preserve existing init and health logic paths
Diffstat:
| M | app/src/app.rs | | | 117 | +++++++++++++++++++++++++++++++++++--------------------------------------------- |
1 file changed, 51 insertions(+), 66 deletions(-)
diff --git a/app/src/app.rs b/app/src/app.rs
@@ -29,7 +29,7 @@ use crate::{
app_datastore_read_state,
app_state_notifications_permission_value,
app_state_set_notifications_permission_value,
- app_setup_initialize,
+ app_setup_step_default,
app_health_check_all,
RadrootsAppBackends,
RadrootsAppConfig,
@@ -42,6 +42,7 @@ use crate::{
RadrootsAppLogsPage,
RadrootsAppSettingsPage,
RadrootsAppUiDemoPage,
+ RadrootsAppSetupStep,
RadrootsAppTangleClientStub,
};
@@ -154,85 +155,69 @@ fn SplashPage() -> impl IntoView {
#[component]
fn SetupPage() -> impl IntoView {
let context = app_context();
- let fallback_backends = RwSignal::new_local(None::<RadrootsAppBackends>);
let fallback_setup_required = RwSignal::new_local(None::<bool>);
- let backends = context
- .as_ref()
- .map(|value| value.backends)
- .unwrap_or(fallback_backends);
let setup_required = context
.as_ref()
.map(|value| value.setup_required)
.unwrap_or(fallback_setup_required);
- let setup_running = RwSignal::new_local(false);
- let setup_status = RwSignal::new_local(None::<String>);
let navigate = use_navigate();
let navigate_guard = navigate.clone();
+ let setup_step = RwSignal::new_local(app_setup_step_default());
Effect::new(move || {
if setup_required.get() == Some(false) {
navigate_guard("/", Default::default());
}
});
- let setup_label = move || {
- if setup_running.get() {
- "setup_running"
- } else {
- "setup_initialize"
- }
+ let advance_step = move |_| {
+ setup_step.update(|step| {
+ *step = step.next();
+ });
};
- let setup_status_label =
- move || setup_status.get().unwrap_or_else(|| "setup_idle".to_string());
view! {
- <main>
- <div>"setup"</div>
- <div style="margin-top: 12px; display: flex; align-items: center; gap: 8px;">
- <button
- on:click=move |_| {
- if setup_running.get_untracked() {
- return;
- }
- let setup_ctx = backends.with_untracked(|value| {
- value.as_ref().map(|backends| {
- (
- backends.datastore.clone(),
- backends.config.datastore.key_maps.clone(),
- backends.nostr_keystore.get_config(),
- )
- })
- });
- let Some((datastore, key_maps, keystore_config)) = setup_ctx else {
- return;
- };
- setup_running.set(true);
- setup_status.set(Some("setup_start".to_string()));
- let setup_required = setup_required.clone();
- let navigate = navigate.clone();
- spawn_local(async move {
- let keystore = radroots_app_core::keystore::RadrootsClientWebKeystoreNostr::new(
- Some(keystore_config),
- );
- match app_setup_initialize(datastore.as_ref(), &keystore, &key_maps).await {
- Ok(_) => {
- setup_status.set(Some("setup_done".to_string()));
- setup_required.set(Some(false));
- setup_running.set(false);
- navigate("/", Default::default());
- }
- Err(err) => {
- let log_datastore = logs_datastore();
- let _ = app_log_error_store(&log_datastore, &key_maps, &err).await;
- setup_status.set(Some(err.to_string()));
- setup_running.set(false);
- }
- }
- });
- }
- disabled=move || setup_running.get()
- >
- {setup_label}
- </button>
- <span>{setup_status_label}</span>
- </div>
+ <main class="min-h-[100dvh] w-full px-6 pt-10 pb-16">
+ {move || match setup_step.get() {
+ RadrootsAppSetupStep::Intro => view! {
+ <section class="flex flex-col w-full gap-6">
+ <header class="flex flex-col gap-3">
+ <p class="font-sans text-sm uppercase tracking-[0.14em] text-ly0-gl-label">
+ "Radroots"
+ </p>
+ <h1 class="font-sans font-[600] text-3xl text-ly0-gl">
+ "Welcome to Radroots"
+ </h1>
+ <p class="font-sans text-line_d_e text-ly0-gl-label">
+ "Set up your key and preferences to get started."
+ </p>
+ </header>
+ <div class="flex flex-col gap-3">
+ <button
+ type="button"
+ class="button-submit rounded-touch px-6 py-3"
+ on:click=advance_step
+ >
+ <span class="font-sans font-[600] text-ly2-gl">
+ "Get started"
+ </span>
+ </button>
+ </div>
+ </section>
+ }.into_any(),
+ RadrootsAppSetupStep::KeyChoice => view! {
+ <section class="flex flex-col w-full gap-4">
+ <header class="flex flex-col gap-2">
+ <p class="font-sans text-sm uppercase tracking-[0.14em] text-ly0-gl-label">
+ "Setup"
+ </p>
+ <h2 class="font-sans font-[600] text-2xl text-ly0-gl">
+ "Choose your key"
+ </h2>
+ <p class="font-sans text-line_d_e text-ly0-gl-label">
+ "Select how you want to add your Nostr key."
+ </p>
+ </header>
+ </section>
+ }.into_any(),
+ }}
</main>
}
}