v1.2.0: UX audit — security fixes, accessibility, and polish
Security (P0): - Fix sidebar remaining interactive behind lock screen - Extend auto-lock idle detection to include active widget interactions - Distinguish missing PIN vault from wrong PIN; auto-switch to passphrase Blocking UX (P1): - Add 15s timeout for encryption state check to prevent indefinite loading - Show restart reason in loading overlay after wallet encryption - Add Force Quit button on shutdown screen after 10s - Warn user if embedded daemon fails to start during wizard completion Polish (P2): - Use configured explorer URL in Receive tab instead of hardcoded URL - Increase request memo buffer from 256 to 512 bytes to match Send tab - Extend notification duration to 5s for critical operations (tx sent, wallet encrypted, key import, backup, export) - Add Reduce Motion accessibility setting (disables page fade + balance lerp) - Show estimated remaining time during mining thread benchmark - Add staleness indicator to market price data (warning after 5 min) New i18n keys: incorrect_pin, incorrect_passphrase, pin_not_set, restarting_after_encryption, force_quit, reduce_motion, tt_reduce_motion, ago, wizard_daemon_start_failed
This commit is contained in:
@@ -237,6 +237,26 @@ void RenderMarketTab(App* app)
|
||||
ImVec2(centerX - valSz.x * 0.5f, valY), stats[i].valueCol, stats[i].value.c_str());
|
||||
}
|
||||
|
||||
// ---- STALENESS INDICATOR ----
|
||||
{
|
||||
auto fetchTime = market.last_fetch_time;
|
||||
if (fetchTime.time_since_epoch().count() > 0) {
|
||||
auto elapsed = std::chrono::steady_clock::now() - fetchTime;
|
||||
int ageSecs = (int)std::chrono::duration_cast<std::chrono::seconds>(elapsed).count();
|
||||
bool stale = ageSecs > 300; // 5 minutes
|
||||
if (ageSecs < 60)
|
||||
snprintf(buf, sizeof(buf), "%s %ds %s", stale ? ICON_MD_WARNING : "", ageSecs, TR("ago"));
|
||||
else
|
||||
snprintf(buf, sizeof(buf), "%s %dm %s", stale ? ICON_MD_WARNING : "", ageSecs / 60, TR("ago"));
|
||||
ImFont* staleFont = capFont;
|
||||
ImU32 staleCol = stale ? Warning() : WithAlpha(OnSurface(), 100);
|
||||
float staleY = statsY + ovFont->LegacySize + Layout::spacingXs() + sub1->LegacySize + Layout::spacingSm();
|
||||
ImVec2 staleSz = staleFont->CalcTextSizeA(staleFont->LegacySize, FLT_MAX, 0, buf);
|
||||
dl->AddText(staleFont, staleFont->LegacySize,
|
||||
ImVec2(cardMin.x + Layout::spacingLg(), staleY), staleCol, buf);
|
||||
}
|
||||
}
|
||||
|
||||
// ---- TRADE BUTTON (top-right of card) ----
|
||||
if (!currentExchange.pairs.empty()) {
|
||||
const char* pairName = currentExchange.pairs[s_pair_idx].displayName.c_str();
|
||||
|
||||
Reference in New Issue
Block a user