fix(ui): readable error text on dark modal backdrops
The Material --error reds are muted by design, so error text drawn with the theme Error() color read low-contrast on the (now deeper) dark modal backdrops — the audit flagged the seed-migration warning/error lines on dark / dragonx. Add material::ReadableError(): the theme error lifted toward a legible light red on dark themes, unchanged on light themes (where it's already a dark red that reads on a light background). Apply it to the modal error-TEXT sites (lite first-run, seed backup, seed migration). This is targeted — it never touches the app-wide Error() used by toasts / badges / status dots — so nothing else shifts. Verified on the sweep: the "node too old" warning (dark) and "daemon did not respond" error (dragonx) now read clearly; light themes are unchanged. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
24
src/app.cpp
24
src/app.cpp
@@ -2471,7 +2471,7 @@ void App::renderLiteFirstRunPrompt()
|
|||||||
ImGui::PopFont();
|
ImGui::PopFont();
|
||||||
ImGui::Spacing();
|
ImGui::Spacing();
|
||||||
ImGui::PushTextWrapPos(ImGui::GetCursorPosX() + 380.0f);
|
ImGui::PushTextWrapPos(ImGui::GetCursorPosX() + 380.0f);
|
||||||
ImGui::PushStyleColor(ImGuiCol_Text, ui::material::Error());
|
ImGui::PushStyleColor(ImGuiCol_Text, ui::material::ReadableError());
|
||||||
ImGui::TextUnformatted("These 24 words are the ONLY way to restore your wallet. "
|
ImGui::TextUnformatted("These 24 words are the ONLY way to restore your wallet. "
|
||||||
"Write them down in order, store them offline, and never share "
|
"Write them down in order, store them offline, and never share "
|
||||||
"them. If you lose them, your funds are gone forever.");
|
"them. If you lose them, your funds are gone forever.");
|
||||||
@@ -2517,7 +2517,7 @@ void App::renderLiteFirstRunPrompt()
|
|||||||
if (skipConfirm) {
|
if (skipConfirm) {
|
||||||
ImGui::Spacing();
|
ImGui::Spacing();
|
||||||
ImGui::PushTextWrapPos(ImGui::GetCursorPosX() + 380.0f);
|
ImGui::PushTextWrapPos(ImGui::GetCursorPosX() + 380.0f);
|
||||||
ImGui::PushStyleColor(ImGuiCol_Text, ui::material::Error());
|
ImGui::PushStyleColor(ImGuiCol_Text, ui::material::ReadableError());
|
||||||
ImGui::TextUnformatted("You have not backed up your seed — funds could be lost. "
|
ImGui::TextUnformatted("You have not backed up your seed — funds could be lost. "
|
||||||
"Skip anyway?");
|
"Skip anyway?");
|
||||||
ImGui::PopStyleColor();
|
ImGui::PopStyleColor();
|
||||||
@@ -2537,7 +2537,7 @@ void App::renderLiteFirstRunPrompt()
|
|||||||
ImGui::TextDisabled("Progress: %d / %d", progress, (int)words.size());
|
ImGui::TextDisabled("Progress: %d / %d", progress, (int)words.size());
|
||||||
if (ImGui::GetTime() < wrongFlashUntil) {
|
if (ImGui::GetTime() < wrongFlashUntil) {
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
ImGui::PushStyleColor(ImGuiCol_Text, ui::material::Error());
|
ImGui::PushStyleColor(ImGuiCol_Text, ui::material::ReadableError());
|
||||||
ImGui::TextUnformatted(" — that's not the next word");
|
ImGui::TextUnformatted(" — that's not the next word");
|
||||||
ImGui::PopStyleColor();
|
ImGui::PopStyleColor();
|
||||||
}
|
}
|
||||||
@@ -2583,7 +2583,7 @@ void App::renderLiteFirstRunPrompt()
|
|||||||
if (skipConfirm) {
|
if (skipConfirm) {
|
||||||
ImGui::Spacing();
|
ImGui::Spacing();
|
||||||
ImGui::PushTextWrapPos(ImGui::GetCursorPosX() + 380.0f);
|
ImGui::PushTextWrapPos(ImGui::GetCursorPosX() + 380.0f);
|
||||||
ImGui::PushStyleColor(ImGuiCol_Text, ui::material::Error());
|
ImGui::PushStyleColor(ImGuiCol_Text, ui::material::ReadableError());
|
||||||
ImGui::TextUnformatted("You have not backed up your seed — funds could be lost. "
|
ImGui::TextUnformatted("You have not backed up your seed — funds could be lost. "
|
||||||
"Skip anyway?");
|
"Skip anyway?");
|
||||||
ImGui::PopStyleColor();
|
ImGui::PopStyleColor();
|
||||||
@@ -2623,7 +2623,7 @@ void App::renderLiteFirstRunPrompt()
|
|||||||
|
|
||||||
if (!restoreErr.empty()) {
|
if (!restoreErr.empty()) {
|
||||||
ImGui::Spacing();
|
ImGui::Spacing();
|
||||||
ImGui::PushStyleColor(ImGuiCol_Text, ui::material::Error());
|
ImGui::PushStyleColor(ImGuiCol_Text, ui::material::ReadableError());
|
||||||
ImGui::PushTextWrapPos(ImGui::GetCursorPosX() + 380.0f);
|
ImGui::PushTextWrapPos(ImGui::GetCursorPosX() + 380.0f);
|
||||||
ImGui::TextUnformatted(restoreErr.c_str());
|
ImGui::TextUnformatted(restoreErr.c_str());
|
||||||
ImGui::PopTextWrapPos();
|
ImGui::PopTextWrapPos();
|
||||||
@@ -3080,7 +3080,7 @@ void App::renderSeedBackupDialog()
|
|||||||
} else if (!seed_backup_phrase_.empty()) {
|
} else if (!seed_backup_phrase_.empty()) {
|
||||||
ImGui::TextWrapped("%s", TR("seed_backup_intro"));
|
ImGui::TextWrapped("%s", TR("seed_backup_intro"));
|
||||||
ImGui::Spacing();
|
ImGui::Spacing();
|
||||||
ImGui::PushStyleColor(ImGuiCol_Text, ui::material::Error());
|
ImGui::PushStyleColor(ImGuiCol_Text, ui::material::ReadableError());
|
||||||
ImGui::TextWrapped("%s", TR("seed_backup_warning"));
|
ImGui::TextWrapped("%s", TR("seed_backup_warning"));
|
||||||
ImGui::PopStyleColor();
|
ImGui::PopStyleColor();
|
||||||
ImGui::Spacing();
|
ImGui::Spacing();
|
||||||
@@ -3188,7 +3188,7 @@ void App::renderSeedMigrationDialog()
|
|||||||
if (ui::material::StyledButton(TR("close"), ImVec2(120 * dp, 0))) close();
|
if (ui::material::StyledButton(TR("close"), ImVec2(120 * dp, 0))) close();
|
||||||
break;
|
break;
|
||||||
case SeedMigrationPrecheck::DaemonTooOld:
|
case SeedMigrationPrecheck::DaemonTooOld:
|
||||||
ImGui::PushStyleColor(ImGuiCol_Text, ui::material::Error());
|
ImGui::PushStyleColor(ImGuiCol_Text, ui::material::ReadableError());
|
||||||
ImGui::TextWrapped("%s", TR("mig_daemon_too_old"));
|
ImGui::TextWrapped("%s", TR("mig_daemon_too_old"));
|
||||||
ImGui::PopStyleColor();
|
ImGui::PopStyleColor();
|
||||||
ImGui::Spacing(); ImGui::Separator();
|
ImGui::Spacing(); ImGui::Separator();
|
||||||
@@ -3223,7 +3223,7 @@ void App::renderSeedMigrationDialog()
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case SeedMigrationStep::ShowSeed: {
|
case SeedMigrationStep::ShowSeed: {
|
||||||
ImGui::PushStyleColor(ImGuiCol_Text, ui::material::Error());
|
ImGui::PushStyleColor(ImGuiCol_Text, ui::material::ReadableError());
|
||||||
ImGui::TextWrapped("%s", TR("mig_seed_warning"));
|
ImGui::TextWrapped("%s", TR("mig_seed_warning"));
|
||||||
ImGui::PopStyleColor();
|
ImGui::PopStyleColor();
|
||||||
ImGui::Spacing();
|
ImGui::Spacing();
|
||||||
@@ -3320,7 +3320,7 @@ void App::renderSeedMigrationDialog()
|
|||||||
ImGui::TextWrapped("%s%s", TR("mig_to"), seed_migration_dest_.c_str());
|
ImGui::TextWrapped("%s%s", TR("mig_to"), seed_migration_dest_.c_str());
|
||||||
if (state_.isLocked()) {
|
if (state_.isLocked()) {
|
||||||
ImGui::Spacing();
|
ImGui::Spacing();
|
||||||
ImGui::PushStyleColor(ImGuiCol_Text, ui::material::Error());
|
ImGui::PushStyleColor(ImGuiCol_Text, ui::material::ReadableError());
|
||||||
ImGui::TextWrapped("%s", TR("mig_unlock_first"));
|
ImGui::TextWrapped("%s", TR("mig_unlock_first"));
|
||||||
ImGui::PopStyleColor();
|
ImGui::PopStyleColor();
|
||||||
}
|
}
|
||||||
@@ -3369,7 +3369,7 @@ void App::renderSeedMigrationDialog()
|
|||||||
if (ui::material::StyledButton(TR("mig_adopt"), ImVec2(180 * dp, 0)))
|
if (ui::material::StyledButton(TR("mig_adopt"), ImVec2(180 * dp, 0)))
|
||||||
beginAdoptSeedWallet();
|
beginAdoptSeedWallet();
|
||||||
} else if (confirmed && !legacyEmpty) {
|
} else if (confirmed && !legacyEmpty) {
|
||||||
ImGui::PushStyleColor(ImGuiCol_Text, ui::material::Error());
|
ImGui::PushStyleColor(ImGuiCol_Text, ui::material::ReadableError());
|
||||||
ImGui::TextWrapped("%s", TR("mig_remainder"));
|
ImGui::TextWrapped("%s", TR("mig_remainder"));
|
||||||
ImGui::PopStyleColor();
|
ImGui::PopStyleColor();
|
||||||
if (ui::material::StyledButton(TR("mig_sweep_remaining"), ImVec2(180 * dp, 0)))
|
if (ui::material::StyledButton(TR("mig_sweep_remaining"), ImVec2(180 * dp, 0)))
|
||||||
@@ -3404,7 +3404,7 @@ void App::renderSeedMigrationDialog()
|
|||||||
ImGui::TextWrapped("%s", TR("mig_done_detail"));
|
ImGui::TextWrapped("%s", TR("mig_done_detail"));
|
||||||
if (!seed_migration_status_.empty()) { // a non-fatal warning (e.g. the daemon didn't restart)
|
if (!seed_migration_status_.empty()) { // a non-fatal warning (e.g. the daemon didn't restart)
|
||||||
ImGui::Spacing();
|
ImGui::Spacing();
|
||||||
ImGui::PushStyleColor(ImGuiCol_Text, ui::material::Error());
|
ImGui::PushStyleColor(ImGuiCol_Text, ui::material::ReadableError());
|
||||||
ImGui::TextWrapped("%s", seed_migration_status_.c_str());
|
ImGui::TextWrapped("%s", seed_migration_status_.c_str());
|
||||||
ImGui::PopStyleColor();
|
ImGui::PopStyleColor();
|
||||||
}
|
}
|
||||||
@@ -3415,7 +3415,7 @@ void App::renderSeedMigrationDialog()
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case SeedMigrationStep::Error:
|
case SeedMigrationStep::Error:
|
||||||
ImGui::PushStyleColor(ImGuiCol_Text, ui::material::Error());
|
ImGui::PushStyleColor(ImGuiCol_Text, ui::material::ReadableError());
|
||||||
ImGui::TextWrapped("%s", seed_migration_status_.c_str());
|
ImGui::TextWrapped("%s", seed_migration_status_.c_str());
|
||||||
ImGui::PopStyleColor();
|
ImGui::PopStyleColor();
|
||||||
ImGui::Spacing();
|
ImGui::Spacing();
|
||||||
|
|||||||
@@ -44,6 +44,19 @@ inline bool IsLightTheme() {
|
|||||||
return (0.299f * r + 0.587f * g + 0.114f * b) > 0.5f;
|
return (0.299f * r + 0.587f * g + 0.114f * b) > 0.5f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Theme error color tuned for use as TEXT. The Material --error reds are muted, so on a dark modal
|
||||||
|
// backdrop they read low-contrast; lift them toward a legible light red on dark themes. Light themes
|
||||||
|
// keep the theme error (already a dark red readable on a light background).
|
||||||
|
inline ImU32 ReadableError() {
|
||||||
|
ImU32 e = Error();
|
||||||
|
if (IsLightTheme()) return e;
|
||||||
|
const float m = 0.35f; // blend toward white
|
||||||
|
int r = (int)(((e >> IM_COL32_R_SHIFT) & 0xFF) * (1 - m) + 255 * m);
|
||||||
|
int g = (int)(((e >> IM_COL32_G_SHIFT) & 0xFF) * (1 - m) + 255 * m);
|
||||||
|
int b = (int)(((e >> IM_COL32_B_SHIFT) & 0xFF) * (1 - m) + 255 * m);
|
||||||
|
return IM_COL32(r, g, b, (e >> IM_COL32_A_SHIFT) & 0xFF);
|
||||||
|
}
|
||||||
|
|
||||||
// Animated "loading" ellipsis: "", ".", "..", "..." cycling on a ~3Hz phase.
|
// Animated "loading" ellipsis: "", ".", "..", "..." cycling on a ~3Hz phase.
|
||||||
inline const char* LoadingDots() {
|
inline const char* LoadingDots() {
|
||||||
int n = ((int)(ImGui::GetTime() * 3.0f)) % 4;
|
int n = ((int)(ImGui::GetTime() * 3.0f)) % 4;
|
||||||
|
|||||||
Reference in New Issue
Block a user