feat(lite): first-run welcome prompt (create / restore)
Replace the bare "land on main UI with a No-wallet overlay" first-run with a
lite welcome modal, shown when no wallet file exists yet (lite_wallet_ present,
not open, walletExists() false):
- "Create new wallet" — one-click createWallet({}); on success, notifies the user
to back up their recovery phrase and navigates to Settings (Backup & keys),
where the seed can be revealed/copied via the existing backup UI.
- "Restore from seed" — navigates to Settings (Lite wallet request → Restore).
- "Later" — dismiss for the session.
Routes to the already-built + verified create/restore/backup flows rather than
re-implementing seed display in the modal (no new secret-handling surface).
Dismissed once an action is chosen; never shown again once a wallet exists.
Full-node is unaffected (renderLiteFirstRunPrompt() returns early when
lite_wallet_ is null). English i18n built-ins added.
Verified: fresh-HOME lite launch shows the prompt, clean run + shutdown, no
crash/RPC noise; tests pass.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
60
src/app.cpp
60
src/app.cpp
@@ -1394,7 +1394,10 @@ void App::render()
|
||||
if (show_about_) {
|
||||
ui::RenderAboutDialog(this, &show_about_);
|
||||
}
|
||||
|
||||
|
||||
// Lite first-run welcome: prompt to create/restore when no wallet file exists yet.
|
||||
renderLiteFirstRunPrompt();
|
||||
|
||||
if (show_import_key_) {
|
||||
renderImportKeyDialog();
|
||||
}
|
||||
@@ -1785,6 +1788,61 @@ void App::reloadThemeImages(const std::string& bgPath, const std::string& logoPa
|
||||
coin_logo_h_ = 0;
|
||||
}
|
||||
|
||||
void App::renderLiteFirstRunPrompt()
|
||||
{
|
||||
// Lite-only: a brief welcome shown when no wallet file exists yet (full-node uses the wizard,
|
||||
// which is skipped in lite). Routes to the existing create/restore + Backup flows in Settings.
|
||||
if (!lite_wallet_ || lite_firstrun_dismissed_) return;
|
||||
if (lite_wallet_->walletOpen() || lite_wallet_->walletExists()) return;
|
||||
|
||||
if (!ImGui::IsPopupOpen("##LiteFirstRun")) ImGui::OpenPopup("##LiteFirstRun");
|
||||
|
||||
ImGuiViewport* vp = ImGui::GetMainViewport();
|
||||
ImGui::SetNextWindowPos(ImVec2(vp->Pos.x + vp->Size.x * 0.5f, vp->Pos.y + vp->Size.y * 0.5f),
|
||||
ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
|
||||
if (ImGui::BeginPopupModal("##LiteFirstRun", nullptr,
|
||||
ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar)) {
|
||||
ImGui::PushFont(ui::material::Type().subtitle1());
|
||||
ImGui::TextUnformatted(TR("lite_welcome_title"));
|
||||
ImGui::PopFont();
|
||||
ImGui::Spacing();
|
||||
ImGui::PushTextWrapPos(ImGui::GetCursorPosX() + 360.0f);
|
||||
ImGui::TextUnformatted(TR("lite_welcome_msg"));
|
||||
ImGui::PopTextWrapPos();
|
||||
ImGui::Spacing();
|
||||
ImGui::Spacing();
|
||||
|
||||
const float btnW = 170.0f;
|
||||
if (ImGui::Button(TR("lite_welcome_create"), ImVec2(btnW, 0))) {
|
||||
// One-click create (unencrypted by default); the user backs up the seed next via the
|
||||
// Settings → Backup & keys flow, where the seed can be revealed and copied.
|
||||
const auto result = lite_wallet_->createWallet(wallet::LiteWalletCreateRequest{});
|
||||
if (result.walletReady) {
|
||||
ui::Notifications::instance().success(TR("lite_welcome_created"), 8.0f);
|
||||
setCurrentPage(ui::NavPage::Settings);
|
||||
} else {
|
||||
ui::Notifications::instance().warning(TR("lite_welcome_create_failed"));
|
||||
}
|
||||
lite_firstrun_dismissed_ = true;
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button(TR("lite_welcome_restore"), ImVec2(btnW, 0))) {
|
||||
ui::Notifications::instance().info(TR("lite_welcome_restore_hint"), 8.0f);
|
||||
setCurrentPage(ui::NavPage::Settings);
|
||||
lite_firstrun_dismissed_ = true;
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
ImGui::Spacing();
|
||||
if (ImGui::Button(TR("lite_welcome_later"),
|
||||
ImVec2(btnW * 2 + ImGui::GetStyle().ItemSpacing.x, 0))) {
|
||||
lite_firstrun_dismissed_ = true;
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
}
|
||||
|
||||
void App::renderAboutDialog()
|
||||
{
|
||||
auto dlg = ui::schema::UI().drawElement("inline-dialogs", "about");
|
||||
|
||||
@@ -425,6 +425,8 @@ private:
|
||||
// One-shot guard: auto-open an existing lite wallet on the first update() tick (kept off
|
||||
// init() so a slow initialize_existing network call doesn't freeze startup before the window).
|
||||
bool lite_autoopen_done_ = false;
|
||||
// Lite first-run welcome prompt: dismissed for the session once the user picks an action.
|
||||
bool lite_firstrun_dismissed_ = false;
|
||||
std::unique_ptr<daemon::DaemonController> daemon_controller_;
|
||||
std::unique_ptr<daemon::XmrigManager> xmrig_manager_;
|
||||
util::AsyncTaskManager async_tasks_;
|
||||
@@ -648,6 +650,7 @@ private:
|
||||
// Private methods - rendering
|
||||
void renderStatusBar();
|
||||
void renderAboutDialog();
|
||||
void renderLiteFirstRunPrompt(); // lite-only welcome modal when no wallet exists yet
|
||||
void renderImportKeyDialog();
|
||||
void renderExportKeyDialog();
|
||||
void renderBackupDialog();
|
||||
|
||||
@@ -579,6 +579,15 @@ void I18n::loadBuiltinEnglish()
|
||||
// strings when no wallet is open (isConnected() tracks the lite wallet in lite builds).
|
||||
strings_["lite_no_wallet"] = "No wallet open — create or open one in Settings";
|
||||
strings_["lite_no_wallet_short"] = "No wallet open";
|
||||
// Lite first-run welcome prompt (shown when no wallet file exists yet).
|
||||
strings_["lite_welcome_title"] = "Welcome to ObsidianDragon Lite";
|
||||
strings_["lite_welcome_msg"] = "You don't have a wallet yet. Create a new one or restore from a recovery phrase.";
|
||||
strings_["lite_welcome_create"] = "Create new wallet";
|
||||
strings_["lite_welcome_restore"] = "Restore from seed";
|
||||
strings_["lite_welcome_later"] = "Later";
|
||||
strings_["lite_welcome_created"] = "Wallet created — back up your recovery phrase now in Settings → Backup & keys";
|
||||
strings_["lite_welcome_restore_hint"] = "Restore your wallet under Settings → Lite wallet request";
|
||||
strings_["lite_welcome_create_failed"] = "Could not create wallet";
|
||||
|
||||
// Send Tab
|
||||
strings_["pay_from"] = "Pay From";
|
||||
|
||||
Reference in New Issue
Block a user