Commit graph

6347 commits

Author SHA1 Message Date
Lukas Brübach
e3a3ce0521
[DeckStorage] Refresh the visibility column with a guarded timer instead of a latch counter
A dropped visibility reply used to leave the pendingVisibilityChanges
counter permanently positive, so the Public/Private column never refreshed
again and nothing reset it on disconnect. A restartable single-shot timer
with a boolean guard re-reads the tree whenever publishes quiet down and is
stopped on disconnect, so a lost reply costs one stale refresh instead of
killing the column for the session.
2026-09-20 20:17:43 +02:00
Lukas Brübach
d7cd414750
[DeckShare] Adapt deck upload to the server-derived banner and tag protocol
The server now derives the banner card and tags from the uploaded deck
list itself, so Command_DeckUpload only carries the client-computed color
identity. Drop the reserved banner/tag setters from the editor and storage
uploads, send the color identity on remote saves, and read tags from the
now-repeated ServerInfo_DeckStorage_TreeItem field.
2026-09-20 20:17:43 +02:00
Lukas Brübach
da1fafeed8
[DeckShare] Browse and open public decks with loading, error and accessibility states
Add a public-decks tab that lists decks published by other users using the
server's deck visibility feature, previewing each deck's banner card, color
identity, tags and upload time without downloading the deck list until the
user opens it.

- Add a public-decks tab with a shared-settings widget and a remote model
  that fetches the target user's decks and refreshes both automatically and
  on user request, with a loading indicator and a server-error message
  instead of a blank tab when the fetch fails or the connection drops
- Render each deck as a focusable preview tile whose banner, color identity,
  tags and upload time follow the existing Preview settings, with the deck
  name announced as the tile's accessible name and Space/Enter opening the
  deck, mirroring the shared-deck preview tile
- Show a message box when opening a public deck fails or arrives corrupted
- Publish and unpublish decks from the server storage toolbar and context
  menu, toggling the deck's own visibility bit (what the server persists)
  rather than the inherited effective state, and batch the visibility
  refresh until the last in-flight change is acknowledged
- Add the Show Upload Time setting so the tile's upload stamp can be hidden
  like the other preview details
- Update the retranslateUi wiring for the new public-decks tab and rename
  the share action tooltip from "Deck share" to "Share link"
2026-09-20 20:17:43 +02:00
Lukas Brübach
20079dc471 [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
2026-09-20 19:58:09 +02:00
Lukas Brübach
d21dfccbef
[Client] Redact share secrets from activation URL logs 2026-09-20 19:42:14 +02:00
Lukas Brübach
ad08fbbe79
[Client] Skip the startup connection when a macOS URL launch owns the connection 2026-09-20 19:42:14 +02:00
Lukas Brübach
d174307bce
[DeckShare] Keep arrow-key navigation between flow items inside a scroll area 2026-09-20 19:42:14 +02:00
Lukas Brübach
5e70a769d4
[Client] Treat a busy single-instance primary as alive instead of stealing its socket 2026-09-20 19:42:14 +02:00
Lukas Brübach
040be0c1d3
[Client] Drain a single-instance payload before its handlers read the socket again 2026-09-20 19:42:14 +02:00
Lukas Brübach
d8cc5522f2
[DeckShare] Time the share-list round trip and backstop silently-destroyed intent chains 2026-09-20 19:42:14 +02:00
Lukas Brübach
65c2378a81
[DeckShare] Reformat the link sign-in intent constructor 2026-09-20 19:42:14 +02:00
Lukas Brübach
8130f124db
[DeckShare] Confirm the share link's target server before opening a deck 2026-09-20 19:42:14 +02:00
Lukas Brübach
c0d3febf72
[Settings] Match a server on the exact host and port when adding it 2026-09-20 19:42:14 +02:00
Lukas Brübach
501ec70512
[DeckShare] Track link-intent chains per-run so each can restore its own session 2026-09-20 19:42:14 +02:00
Lukas Brübach
5fa8df4b83
[DeckShare] Let intent chains opt into the link sign-in dialog 2026-09-20 19:42:14 +02:00
Lukas Brübach
34ef3c1f8b
[DeckShare] Forward a dependency's cancellation as the owner's own 2026-09-20 19:42:14 +02:00
Lukas Brübach
d4a73b6d4a
[DeckShare] End the open-shared-deck files with a trailing newline 2026-09-20 19:42:14 +02:00
Lukas Brübach
210a0fa76a
[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
2026-09-20 19:42:14 +02:00
Lukas Brübach
c4ffc789cd
[DeckShare] Resolve the stable server client in the deck editor gate
actShareDeck went through tabSupervisor->getClient(), which hands back a
LocalClient while an offline game is running. LocalClient never sets its status,
so a logged-in user could not share from the deck editor during a local game,
and got a misleading "You must be connected" message. Expose the supervisor's
stable remote client and use it for the gate and the dialog, matching the other
share tabs.
2026-09-20 19:42:12 +02:00
Lukas Brübach
64335328c3
[DeckShare] Restore the banner-text doc comment
Re-add the doc block above refreshBannerCardText() that was removed as part of
the share-selection work; it documents the coupling to refreshBannerCardToolTip.
2026-09-20 19:42:12 +02:00
Lukas Brübach
bda4aeef46
[DeckShare] Explain why a blank deck cannot be shared
A blank deck exited the share flow silently. The menu only disables the entry
via setSaveStatus(), a different predicate, so the path is reachable (e.g. add a
card and remove it again). Mirror the not-logged-in branch with a short
information dialog.
2026-09-20 19:42:12 +02:00
Lukas Brübach
26b17f8435
[DeckShare] Wire the status-changed handler after shareBar exists
handleConnectionChanged() dereferences shareBar->isVisible(), but the connection
was set up before shareBar was constructed and shareBar had no in-class
initializer. On any status change delivered before construction the slot read an
indeterminate pointer. Seed the connection (and the initial share availability)
after shareBar exists and give shareBar a = nullptr initializer.
2026-09-20 19:42:12 +02:00
Lukas Brübach
2cf03124de
[DeckShare] Abandon an in-flight tile share on cancel
exitShareMode() left shareTimeoutTimer running and did not abandon the pending
Command_DeckShareCreate, so a timer pop or a late success still reported the
share after the user cancelled. Stop the timer and ignore stale responses via a
sequence number, mirroring the tree tab.
2026-09-20 19:42:12 +02:00
Lukas Brübach
02f2f20356
[DeckShare] Abandon an in-flight tree share on cancel
Leaving share mode never stopped the timeout timer, and a late response still
ran shareFromTreeFinished, copying the link and announcing success for a share
the user backed out of. Stopping the timer and tracking the outstanding request
by sequence number means a stale reply (or a timed-out one) after cancel is
ignored, and cancelling + re-entering share mode can no longer confuse the two
requests.
2026-09-20 19:42:12 +02:00
Lukas Brübach
ffa3971e90
[DeckShare] Keep the share selection consistent with the visible decks
Filtered-out previews are hidden but kept alive, so selectedFilePaths() counted
them in the share and the selection highlight. Only decks the user can see are
now shared, and a deck that stops matching the filters is deselectd as the deck
pass runs, keeping the %n count and the highlight in sync with the screen.
2026-09-20 19:42:12 +02:00
Lukas Brübach
f74a957059
[DeckShare] Resolve the share theme icon through themePixmap
QPixmap("theme:icons/share") has no file extension, so ThemeManager::assetPath()
is bypassed and the pixmap is always null. Use themePixmap(QStringLiteral("icons/share"))
like every other toolbar action, so the .svg (and dark/light variants) resolves.
2026-09-20 19:42:12 +02:00
Lukas Brübach
9b60e8e7e1
[DeckShare] Include the network settings header used by the share timeout 2026-09-20 19:42:12 +02:00
Lukas Brübach
b7fd53768c
[DeckShare] Keep the settings include in the project include block 2026-09-20 19:42:12 +02:00
Lukas Brübach
75352a00a5
[DeckShare] End the share-related headers and sources with a trailing newline 2026-09-20 19:42:12 +02:00
Lukas Brübach
4721404e8b
[DeckShare] Let the share bar owners supply the hint text 2026-09-20 19:42:12 +02:00
Lukas Brübach
3199a4821a
[DeckShare] Forward retranslateUi to the visual deck storage widget 2026-09-20 19:42:12 +02:00
Lukas Brübach
60d1ce2b89
[DeckShare] Retranslate the share button tooltip with the storage widget 2026-09-20 19:42:12 +02:00
Lukas Brübach
29947d1429
[DeckShare] Join the selected-count label with a non-translatable separator 2026-09-20 19:42:12 +02:00
Lukas Brübach
2b9fdc054f
[DeckShare] Provide the full share hint in each plural form 2026-09-20 19:42:12 +02:00
Lukas Brübach
6fa4a2eb0c
[DeckShare] Recover the share controls when the server never answers 2026-09-20 19:42:12 +02:00
Lukas Brübach
34be334b06
[DeckShare] Replace the duplicate computeColorIdentity with the shared getDeckColorIdentity 2026-09-20 19:42:12 +02:00
Lukas Brübach
949d75b2bd
[DeckShare] Build share links with QUrl and QUrlQuery for percent-encoding 2026-09-20 19:42:12 +02:00
Lukas Brübach
9335adb1b6
[DeckShare] Format share expiry with the locale-aware short format 2026-09-20 19:42:12 +02:00
Lukas Brübach
4168d329de
[DeckShare] Drop includes left unused by the share-response extraction 2026-09-20 19:42:12 +02:00
Lukas Brübach
a5b2114296
[DeckShare] Extract the share-creation response handling into DeckShareUtils 2026-09-20 19:42:12 +02:00
Lukas Brübach
4b870fdf06
[DeckShare] Use the stable server client for the visual deck storage tab 2026-09-20 19:42:12 +02:00
Lukas Brübach
bb06de724f
[DeckShare] Fix share-link expiry build on the minimum-supported Qt
QTimeZone::UTC (the Initialization enum) only exists since Qt 6.7, so
Debian 12 and Ubuntu 24.04 (Qt 6.4) fail to compile the share-link expiry
handling in the share dialog and the two deck-storage tabs. Mirror the
existing games_model guard and fall back to Qt::UTC on older Qt.
2026-09-20 19:42:12 +02:00
Lukas Brübach
0276eb303e
[DeckShare] Address review findings and harden the share flows
Gate every share entry point on login, de-duplicate the share-link and
color-identity logic behind DeckShareUtils and an injected querier, and
replace the silent tray/status-bar notices with always-visible dialogs.

- abstract_tab_deck_editor: explain that sharing requires a connection
  instead of silently doing nothing when logged out
- tab_deck_storage: disable the share action on disconnect, reject
  folder/deck mixes and the root folder with clear warnings, re-enable
  Create on every entry/response so a dropped connection cannot leave
  the button disabled
- tab_deck_storage_visual: same login gate for the context-menu entry,
  visible success/error dialogs, and a symmetric in-flight guard
- getDeckColorIdentity now takes a CardDatabaseQuerier, dropping the
  CardDatabaseManager singleton access and enabling unit tests
2026-09-20 19:42:12 +02:00
Lukas Brübach
d91fe34d20
[DeckShare] Create temporary share links for local and server decks 2026-09-20 19:42:12 +02:00
Lukas Brübach
45fec7fc74
[VDS] Address second round of review nits 2026-09-20 19:42:11 +02:00
Lukas Brübach
8d28a393d7
[VDS] Address review: dead code, chip reparenting, filter signal and sort fast-path 2026-09-20 19:42:11 +02:00
Lukas Brübach
b38e9e4564
[VDS] Decouple tag filter and fix reordered-chips crash 2026-09-20 19:42:11 +02:00
Lukas Brübach
6fe6a75f8f
Address second round of deck share review comments 2026-09-20 19:42:11 +02:00
Lukas Brübach
02b4e8d13d
Document transaction teardown in deck share rollback paths 2026-09-20 19:42:11 +02:00
Lukas Brübach
b7e4afa399
Address server review comments for deck share links 2026-09-20 19:42:11 +02:00