MainWindow::closeEvent has a static re-entrancy guard that returns early on a
second close event, leaving it in its default accepted state. DlgUpdate reached
from a nested event loop while a shutdown prompt was up could then get close()
== true with no shutdown work done (no settings flush, no tab shutdown) and tear
down the process behind an unanswered prompt.
Add MainWindow::closeForUpdate(), which reports false when a close is already in
progress or was vetoed, and gate the update-exit on it.
* [DeckShare] Open shared decks via links with a gated preview flow
- Serialized url-chain dispatcher in IntentUrlParser; queue-drained
urlChainFinished(bool) drives the startup auto-connect fallback
- Open-shared-deck intent with sequential download state machine,
15s per-item timeout, partial-success offer, livable Cancel via
ApplicationModal dlg_login_prompt interactive fallback
- Preview dialog: download progress label, share vocab sweep,
palette-highlight selection frame, Space/Enter keyboard toggle,
NoFocus checkbox, double-click tile opens immediately
- Confirm-before-server-migration with one-shot restore to the
previous server on failed/cancelled chains (statusChanged settle
deferral), hostname-only identity comparisons
- Skip credential link when already connected; arrow-key navigation
in FlowWidget; card glows use palette highlight
- Address code-review M1-M4 and UI/UX QA blockers 1-2
* [DeckShare] End the open-shared-deck files with a trailing newline
* [DeckShare] Forward a dependency's cancellation as the owner's own
* [DeckShare] Let intent chains opt into the link sign-in dialog
* [DeckShare] Track link-intent chains per-run so each can restore its own session
* [Settings] Match a server on the exact host and port when adding it
* [DeckShare] Confirm the share link's target server before opening a deck
* [DeckShare] Reformat the link sign-in intent constructor
* [DeckShare] Time the share-list round trip and backstop silently-destroyed intent chains
* [Client] Drain a single-instance payload before its handlers read the socket again
* [Client] Treat a busy single-instance primary as alive instead of stealing its socket
* [DeckShare] Keep arrow-key navigation between flow items inside a scroll area
* [Client] Skip the startup connection when a macOS URL launch owns the connection
* [Client] Redact share secrets from activation URL logs
* [Client] Make the link-connection gates port-aware and keyboard-safe
Second-pass review notes for the shared-deck link flow (Cockatrice#7244):
- FlowWidget arrow-key navigation is opt-in via addNavigableWidget, so
combo/spin controls on the analytics flows keep their own arrow keys
- isConnectedTo and the open-deck/join-game preconditions compare the
configured server port alongside the host, so a same-host/different-port
link cannot resolve its share token or game id on the wrong instance
- the link sign-in dialog reuses an existing server entry's saved name
instead of renaming it to the raw hostname
- skipStartupAutoConnect is cleared once the launch chain connects, so a
later mid-session declined link cannot fire the startup fallback
- the plain-launch path of SingleInstanceManager no longer blocks on the
primary's ACK
- link- and server-supplied text is html-escaped in the confirm prompts and
shared-deck preview so markup cannot spoof the shown messages
---------
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
* [Oracle/Client] Report card database download progress
Card database updates ran invisibly: MTGJSON parsing spun an indeterminate
bar on the UI thread and the set import blocked the window, while the
onboarding wizard spawned `oracle -b` with no progress to show at all.
- Add byte-level scan progress to `RawJson::scanSetRanges` via an optional
callback, throttled to ~100 reports per scan.
- Emit `OracleImporter::dataReadProgress` during the scan and import sets on a
worker thread, driving the wizard's progress bar per set.
- With `-b`, write machine-readable `PROGRESS <stage> <done> <total>` lines to
stdout for the download/scan/import stages; stderr keeps the log output.
- Parse the oracle stdout in `MainWindow` and forward it to the onboarding
wizard, giving the card database step a determinate bar with stage-specific
status text.
- Guard the async workers against the wizard being closed mid-run.
- Add Google Test coverage for scan progress reporting.
* [Oracle/Client] Harden oracle progress workers and quit prompt
Address review feedback on the download-progress change: decompress and read
sets files off the UI thread, cancel the load/import workers before the
wizard can tear down the importer, and show an 'Extracting file...' status
plus a clean 100% tail so the poll never looks stuck. Quitting Cockatrice
while a card database update runs now asks for confirmation.
* Show 100% for 500ms on complete.
* Disable buttons on set import until done.
* Clean up progress bar.
* Drop wrapper around lambda
---------
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
* [App] Add onboarding wizard
Took 10 minutes
Took 3 minutes
Took 7 minutes
Took 9 minutes
Took 2 minutes
Took 1 minute
Took 7 minutes
* Adjust CI
Took 14 minutes
Took 56 seconds
Took 2 seconds
Took 3 seconds
* Adjust CI again
Took 14 minutes
Took 2 seconds
* Comments and fixes
Took 9 seconds
Took 1 minute
* Rebase.
Took 5 minutes
Took 50 seconds
Took 15 seconds
* Comments.
Took 7 minutes
* CI lol
Took 3 minutes
* CI again lol
Took 4 minutes
* Drop some settings, add some new ones.
Took 19 minutes
* Resize when expanding section
Took 4 minutes
Took 3 minutes
Took 7 minutes
---------
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
* [Client] Show live connection latency in the status bar
Add a permanent status-bar label fed by ConnectionController's
pingStatsUpdated: shows the latest round-trip time, hides while
disconnected or without samples, and carries a tooltip with
Last/Median/95th percentile/Maximum over the rolling sample window
(mirrored into the accessible description). The server tab gets the
same stats as its tooltip.
Took 2 minutes
Took 2 minutes
Took 1 minute
Took 48 seconds
Took 25 seconds
Took 4 minutes
* [Client] Graph connection latency history in the status bar
Add LatencyGraphWidget, a size-agnostic bar sparkline over the rolling
sample window: heights scale to the window's own range while colors map
onto an absolute quality ramp, so a steady good ping stays green. Embed
it in the new LatencyStatusWidget together with the textual ping
readout and feed both through ConnectionController's forwarded signals;
the whole area hides while disconnected or without samples.
Took 9 minutes
Took 14 seconds
* [Client] Show latency details when clicking the ping display
Clicking the status bar ping area opens a popup with a larger instance
of the latency graph plus the numeric statistics, selectable and
mirrored into the accessible name. Qt::Popup closes it on any outside
click; contents refresh live while open.
Took 33 seconds
* Fixup from core commit
Took 6 minutes
Took 5 seconds
Took 5 minutes
* Lint.
Took 12 minutes
* Consolidate.
Took 6 minutes
---------
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
* [Client] Detect main-thread event loop stalls
LagMonitor ticks the GUI event loop every 500 ms and records gaps
beyond 2 s as stalls, warning with their duration and keeping a
bounded ring of recent records for diagnostics. Measurement uses a
monotonic QElapsedTimer so wall-clock steps and suspend do not
fabricate stalls. Recorded timestamps stay in wall time for
correlating with user reports.
Took 1 minute
Took 13 minutes
Took 2 minutes
* [Client] Rename LagMonitor constants to SCREAMING_SNAKE_CASE
Took 15 minutes
* [Client] Discard suspend-spanning gaps in LagMonitor
Windows counts sleep time in its monotonic clock, so a suspend would
fabricate one bogus stall per resume. Reset the clock on application
state changes and drop implausibly huge gaps; extract recordGap() for
testability.
Took 3 minutes
* [Client] Unit test LagMonitor stall recording
Drives recordGap() directly to cover the threshold, plausibility cap,
trim, and clear behavior without timing-dependent waits.
Took 36 seconds
---------
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
* [Client] Route cockatrice:// link clicks from chat to the intent chain
A cockatrice:// link clicked in chat is currently handed to the OS (or
does nothing in-process). Clicks now emit a cockatriceLinkActivated signal
that travels ChatView -> Tab -> TabSupervisor -> MainWindow, which feeds
the URL through the same IntentUrlParser the OS activation path uses, so
the join runs entirely in-process. card/user schemes and all other links
behave as before.
* [Client] Route cockatrice:// link clicks from the in-game chat to the intent chain
* [Client] Reuse one IntentUrlParser instance for cockatrice:// links
Took 59 seconds
---------
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
* [Tabs] Add a setting to define startup tab on application launch.
Took 29 minutes
* Naming and sizing
Took 4 minutes
---------
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
* [DeckEditor] Use CommanderSpellbook.com to estimate bracket if format is 'commander'
Took 2 minutes
Took 16 minutes
* Convert json data holder to structs, rename variables, extract widget
- Extract bracket estimation UI from DeckEditorDeckDockWidget into a
new CommanderBracketWidget
- Move CommanderSpellbook integration settings from CardsDisplaySettings
to DeckEditorSettings (matching the settings refactor on master)
- Rename CommanderSpellbook integration variables to drop the redundant
'DeckEditor' prefix
Took 4 minutes
# Commit time for manual adjustment:
# Took 6 minutes
# Commit time for manual adjustment:
# Took 8 minutes
---------
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
* [Application] Add single instance guard and mime types.
Took 2 hours 39 minutes
Took 18 minutes
Took 5 minutes
Took 12 seconds
Took 11 seconds
* Rework
Took 30 minutes
Took 50 seconds
* Only enforce single instance if launched with arguments.
Took 5 minutes
* Prototype intents
Took 53 minutes
Took 6 seconds
* Connect/disconnect and join game/room intents.
Took 3 hours 14 minutes
Took 2 seconds
Took 15 seconds
* Fix include.
Took 1 minute
Took 23 seconds
Took 2 seconds
* Mac handling.
Took 10 minutes
Took 12 seconds
Took 3 minutes
* Lint.
Took 3 minutes
* Rebase.
Took 3 minutes
Took 17 seconds
* Implement UrlSchemeEventFilter
Took 10 minutes
Took 7 seconds
* Qt Moc
Took 3 minutes
* Modern PList.
Took 21 minutes
Took 1 minute
* Debug output.
Took 6 minutes
Took 19 minutes
* Watch file:// prefix.
Took 15 minutes
Took 7 seconds
* Better handler.
Took 6 minutes
* Don't store reference in member
Took 5 minutes
* Move impl to cpp, fix lifetime issues.
Took 11 minutes
Took 2 minutes
* Better single-instance handoff, url intent harded
copy game link context-menu
Polish for installers
Took 35 minutes
Took 8 seconds
---------
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
* Pull client networking out of window_main and into remote_connection_controller
Took 2 minutes
* Things.
Took 13 minutes
---------
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
* Add local game options dialog. Introduces LocalGameOptions struct and DlgLocalGameOptions dialog to replace the previous QInputDialog for starting local games. Encapsulates game configuration with a simple interface that prevents parameter explosion as options are added. The dialog provides UI with settings persistence via SettingsCache
* integrate local game options into main window. Replaces QInputDialog with DlgLocalGameOptions in actSinglePlayer(). The startLocalGame() function now accepts LocalGameOptions, enabling configuration of starting life total and spectator visibility in addition to player count. Also adds user documentation for the local game options flow.
* Removed superfluous documentation file
* removed spectator option and moved structure definition
* Now remember settings separately and & shortcuts removed
* re-run checks
* [Cleanup] Unused #includes
Took 44 minutes
* [Cleanup] More unused #includes
Took 55 minutes
* [Cleanup] Include QSet
Took 4 minutes
* [Cleanup] Include QDebug in deck_list.cpp
Took 3 minutes
* [Cleanup] Include protocol stuff in servatrice_database_interface.h
Took 3 minutes
* [Cleanup] Include QDialogButtonBox
Took 8 minutes
* [Cleanup] Include QUrl
Took 8 minutes
* [Cleanup] Include QTextOption in header.
Took 3 minutes
* [Cleanup] Include QMap in user_list_manager.h
Took 8 minutes
* [Cleanup] Adjust qjson
Took 8 minutes
* [Cleanup] include button box.
Took 3 minutes
* [Cleanup] Redo fwd declarations.
* [Cleanup] Redo last removed fwd declarations.
---------
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
* Sort *every* file into a doxygen group.
Took 7 hours 9 minutes
Took 18 seconds
Took 2 minutes
* Lint some ingroup definitions.
Took 10 minutes
Took 2 seconds
* Just include the groups in the Doxyfile in this commit.
Took 3 minutes
* Update some group comments so they link!
Took 14 minutes
---------
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>