mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-09-21 09:05:10 -07:00
11 commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
6823d54c1e
|
[DeckShare] Browse and open public decks with loading, error and accessibility states (#7245)
* [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" * [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. * [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. * [DeckStorage] Summarize batch publish failures when the batch drains Each rejected node stacked its own modal dialog, so publishing a ten-deck selection against a rejecting server made the user dismiss ten dialogs one at a time. Failures are now collected while the batch is in flight and shown as a single summary when the visibility refresh timer fires; a reply that lands outside an active batch still reports right away. * [PublicDecks] Time out the loading state so a dropped reply cannot wedge the tab loading only cleared in decksReceived, but the ping sweep can drop a pending command without ever emitting finished, leaving the tab stuck on 'Loading public decks...' and the refresh button permanently inert. A single-shot timer started per refresh clears the latch and reports a timeout; the latch also clears when the client disconnects. * [PublicDecks] Escape remote-crafted text in tooltips and the tab title Deck names and usernames come from other users' records and Qt renders QLabel tooltips as AutoText, so a name like '<h1><table>...' parsed as markup. Escape and bound the deck-name tooltip and escape the username interpolated into the title label. * [DeckStorage] Distinguish an inherited public state in the visibility column The column reported the effective state while publishing toggles the node's own bit, so a private deck inside a public folder already read 'Public' and toggling appeared to do nothing (and toggling again silently unpublished it). The cell now shows 'Public (inherited)' for that case and the tooltip explains why. * [PublicDecks] Run retranslateUi at construction and name the refresh button retranslateUi was never called from the constructor, so the tooltips set there were absent until a language change. Call it before the first refresh, and give the icon-only refresh button an accessible name for screen readers. * [PublicDecks] Keep the empty and status variants correct across language changes retranslateUi unconditionally rewrote the empty label to the 'nothing published' variant, stomping the 'no decks match your filters' choice rebuildGrid had made, and a visible loading message stayed in the old language. Let retranslateUi pick the same variant rebuildGrid does and re-show the status so it retranslates. * [VDS] Share one color-identity match rule between the two deck grids The remote public decks model verbatim-copied updateColorMatches' switch, down to the ExactMatch normalization and the fact that Includes/Excludes do not normalize case. Extract colorIdentityMatches() next to the FilterMode enum and call it from both so the subtle rule cannot drift. * [DeckStorage] Drop the unused tree widget model accessor The accessor handed the model out past the wrapper methods that exist to keep it encapsulated, and nothing in the stack called it. * [DeckShare] End the public-decks files with a trailing newline keeps the final line's diff clean and stops clang-format CI from flagging the files. * [VDS] Reuse the shared quick settings widget for the public decks tab PublicDecksQuickSettingsWidget was VisualDeckStorageQuickSettingsWidget minus the folders, banner and tooltip controls, with identical wiring for the shared keys and a version of the near-identical file to keep in sync by hand. Fold the Show Upload Time checkbox into the shared widget, give it a setPublicDecksMode() that hides the controls that do not apply, and delete the duplicate. * [PublicDecks] Drop stale deck-list replies after the loading timeout A reply that lands after its own loading timeout (the reverse of the ping sweep dropping the command) could stop the newer request's timeout timer and repaint the grid with out-of-date data. Each refresh now captures a monotonically increasing request id, and only the newest request's reply updates the grid. * [PublicDecks] Re-show a displayed failure message on language changes The status label carries both the loading and the failure message, and retranslateUi hid it whenever the model was not loading, so a language change while a server-error or timeout message was on screen swapped it for the (empty) grid. The tab now keeps the last failure text and re-shows it when not loading, clearing it once a new refresh starts. * [DeckStorage] Keep the visibility refresh armed until replies land The single-shot drain was armed with the 500 ms delay at send time, so a round trip slower than that drained before the server applied the change, re-read the old state and never re-armed, leaving the column stale until a manual refresh. The timer is now armed with the full network timeout at send time (a lost reply still costs one stale refresh) and re-armed with the short delay every time a reply lands. * [DeckShare] Close public decks tabs when the client disconnects TabSupervisor::stop() built tabsToDelete from the room and game tabs only, so a public decks tab survived a disconnect, sitting with stale contents and a refresh button that kept hitting the dead client. Its values are now folded into the same cleanup. --------- Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de> |
||
|
|
7b39cf98d5
|
[Themes] Add identity default palettes for the image themes (#7280)
* [Themes] Add identity default palettes for the image themes
The Fabric, Leather, Plasma and VelvetMarble themes shipped only zone art and no palette, so their chrome fell back to the bare OS palette. Each theme now ships light and dark curated defaults written in the palette editor's own conventions, with [AppColors] so the home-tab buttons keep the theme's identity over static backgrounds.
- Add palette-default-light.toml / palette-default-dark.toml for the four themes; scheme resolution follows the OS since the themes declare no color scheme.
- Tint the window/base/button chrome and bevels towards each theme's identity: navy cloth (Fabric), black-brown with brass accents (Leather), electric violet with cyan sparks (Plasma), charcoal velvet with slate marble (VelvetMarble).
- Fill [AppColors] AccentStrong / AccentSoft per theme so the home-tab button gradient matches instead of falling back to the default greens.
- Derive Disabled and Inactive groups with the same conventions as PaletteGenerator::fromAccent.
* [Themes] Add home backgrounds for the image themes
* [Themes] Ship Fusion style + scheme backgrounds for the image themes
Address PR review:
- Add theme.cfg ([Style] Name = Fusion, ColorScheme = System) to Fabric,
Leather, Plasma and VelvetMarble so their curated palettes actually apply.
Without it the native style paints button chrome from the OS (windowsvista
on Windows has no dark mode), making the dark palettes' light ButtonText
unreadable on light buttons.
- Leverage the scheme-variant asset resolution: register home-dark.png and
home-light.png in resources and add them to the qrc so the built-in home
background also flips with the palette instead of staying static.
- Fix Leather [Palette.Inactive] Accent, which copied the Active Highlight
color instead of the theme accent (dark #4a5f8f -> #c9995a, light
#34508c -> #a5712f) in both palette files.
* [Themes] Align light plasma home background with the dark variant
Recolored the Plasma light home background to mirror the dark one:
brighter violet/cyan blooms, vivid azure spark arcs, and higher accent
saturation against the same pale-lavender key. Brightness is unchanged
so it still reads as a light scheme.
* [Home] Add option to disable the home tab background dim
Adds a 'Dim the home tab background' checkbox to the Home tab settings
page (Appearance). When unchecked, HomeWidget skips the translucent
black overlay it paints over the whole background. Default is on,
preserving current behavior; the home tab repaints live on change.
* Update leather backgrounds
* Update velvet marble backgrounds
* Update light plasma background
* Update light fabric background
* WIP [UI] Theme-aware onboarding banner with frosted light mode
Banner colours now derive from palette tokens at ~60fps (tick-driven,
equality-guarded setters) so scheme switches and live accent-picker
previews apply instantly:
- dark stages: byte-for-byte the original treatment (near-black stage
from window hue, Highlight accent, white centre halo, vignette 0.62)
- light stages: pastel accent-hue wash instead of a neutral grey copy,
brightness-lifted accent for additive glow legibility, deep-Highlight
halo (uGlowColor) instead of white blowout, gentler vignette
(uVignetteMin 0.88) so corners don't go muddy
- black logo silhouette variant selected on light stages
- theme picker preseeded with brand green (brand_colors.h single source)
WIP notes for next session:
- real-pixel wizard screenshot check still pending (headless capture
exists: Xvfb :77 + isolated XDG_DATA_HOME; shader vs fallback pixel
analysis not finished)
- user plans separately: promote Fusion to default theme, Default -> system
* [Themes] Align Fusion accent tokens with the SVG brand gradient
Align AccentStrong (#139740) and AccentSoft (#c9fd62) and the linked
Link/Accent roles with cockatrice.svg's linearGradient4265-7-8 stops so the
identity gradient used by the logo emulation matches the static art the icon
shipped.
* [Onboarding] Draw the banner logo as a static gradient plate
Replace the black/white logo tint switch with a ShaderEffect plate that
repaints the SVG's brand gradient (light AccentSoft -> dark AccentStrong
along the baked-in userSpaceOnUse axis) clipped to the full-color logo's
alpha silhouette, with the white highlight path overlaid on top — matching
the home widget's QPainter composite. The plate is static: no glow or
breathing. Brand colors flow from BannerShaderConfig's new brandStrong/
brandSoft pair instead of the removed logoDark flag, and the background
motifs get a touch more accent so the mark keeps its coloured surround.
* [Home] Draw the featured logo as a theme gradient composite
Repaint cockatrice.svg in Qt instead of showing the baked-in static art:
fill the full-color logo's alpha silhouette with the same brand gradient the
banner plate uses (light AccentSoft grading to dark AccentStrong along the
SVG's userSpaceOnUse axis), then overlay the white highlight path. Renders
an explicit QPixmap so the mark stays crisp at the 200px display size, and
re-seeds it on theme/palette/appearance changes so it never goes stale.
* [Resources] Drop the unused black logo asset
No consumer remains after the banner's logoDark toggle was replaced by the
static gradient plate (unit-tested in
|
||
|
|
1c93309952
|
[Client] Show localized card names, texts and pictures (#7294)
* [Client] Show localized card names, texts and pictures
Localization wiring now runs end to end: the oracle importer collects
foreignData for the configured language and the client renders it.
- [Oracle] Import localized names and rules texts for the selected cardLang
- single-face cards store their foreignData name and full text
- multi-face (split/adventure/aftermath/prepare) cards collect the joined
name once and join each face's translated text with the same separator
as the English merge; an incomplete translation falls back to English;
the joined text follows the same highest-priority-set policy as the
single-face path and is only collected when localization is enabled
- the wizard switching languages re-imports the card database
- [Client] Display localized card info throughout the client
- card info text/picture widgets and the game board re-render on language
change
- pictures resolve cardLang art through Scryfall's named endpoint using the
localized name, falling back to id-based art when no match exists
- deck editor keeps canonical English names as card identity (EditRole)
while showing localized names (DisplayRole), so decks and wire names
stay stable
- [Card] Add CardLocalization-backed name/text lookup and cards.xml v4
localization elements with a bounded-size translation cache
- [Tests] Cover oracle foreignData import (incl. multi-face joins, priority
and fallback paths), XML v4 localization parsing, deck model localized
display and the language-aware settings default
Existing installations need to re-run Oracle to see translations: localized
data only lands in cards.xml when the Oracle app is started with the
preferred language selected — launch the separate "Oracle" program that
ships with Cockatrice, pick the language in the wizard and let it re-import
the card database.
The client's database cache (cards.xml.cache) is invalidated by the cache
format bump and the source-hash checks, but a cache written before the
re-import can still hold English-only entries (the hash uses file size and
mtime, so a same-size/same-timestamp rewrite may be served as-is); delete
cards.xml.cache and relaunch if no localized names/texts show up after
re-importing.
* [Card] Pass localized card names and texts into CardInfo construction
Address review: instead of constructing the card and then calling
setLocalizedName/setLocalizedText (which emit a cardInfoChanged signal per
language), both constructors, both newInstance overloads and their callers
(cards.xml v4 parser and the binary cache reader) now pass the localized maps
as constructor arguments.
* [Client] Rename LocalizedCard:: helpers namespace to CardLocalization
The namespace now matches its header file name, as the review pointed out;
LocalizedCard reads more like a class or struct. Callers (card info text
widget, board card name rendering) are updated to match.
* [Client] Drop unused info member from the card info text widget
The CardInfoPtr member was only ever initialized to nullptr and never read;
remove it together with its initializer.
* [PictureLoader] Add the localized picture URL explicitly, not implicitly
Address review: silently prepending the Scryfall named-picture URL to the
download list whenever a non-English card language was active was surprising,
consumed quota per card when it failed, and could grab the wrong (canon) art on
name collisions, with no way to turn it off.
The insert is now opt-in and user-controlled: changing the card language adds
the template to the top of the download URLs once (persisted, documented in the
re-import prompt, and editable/removable in the deck editor settings), while the
picture loader no longer injects it at request time.
* [Card] Show card languages in the same native (English) format as the UI
Address review: the card text & images language dropdown listed bare native
names, some in inconsistent lowercase (e.g. "čeština", "español de España"),
which makes the languages easy to mix up for users that do not read the script
(e.g. 日本語 vs 한국어). It now mirrors the UI language dropdown and always pairs
the native name with its English name (e.g. "Deutsch (German)",
"日本語 (Japanese)"), using the same fixed casing.
---------
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
|
||
|
|
760fe88fa3
|
[Client] Add setting to ignore all private messages (#7260)
* [Client] Add setting to ignore all private messages (#1250) * Early return --------- Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de> |
||
|
|
45c7ff6f87
|
[Mods] Properly close card art rules tab on disconnect (#7227)
Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de> |
||
|
|
ed4eb1cb31
|
[Server/Client/Protocol] Reporting users + moderation queue functionality (#7091)
Some checks are pending
Build Desktop / Configure (push) Waiting to run
Build Desktop / Debian 13 (push) Blocked by required conditions
Build Desktop / Debian 12 (push) Blocked by required conditions
Build Desktop / Fedora 44 (push) Blocked by required conditions
Build Desktop / Fedora 43 (push) Blocked by required conditions
Build Desktop / Servatrice_Debian 12 (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 (push) Blocked by required conditions
Build Desktop / Ubuntu 24.04 (push) Blocked by required conditions
Build Desktop / Arch (push) Blocked by required conditions
Build Desktop / macOS 15 (push) Blocked by required conditions
Build Desktop / macOS 13 Intel (push) Blocked by required conditions
Build Desktop / macOS 14 (push) Blocked by required conditions
Build Desktop / macOS 15 Debug (push) Blocked by required conditions
Build Desktop / Windows 10 (push) Blocked by required conditions
Build Docker Image / amd64 & arm64 (push) Waiting to run
* [Server/Client/Protocol] Reporting users + moderation queue functionality Took 6 minutes Took 3 minutes Took 8 seconds Took 11 minutes Took 12 minutes Took 7 minutes Took 15 seconds Took 2 minutes Took 1 minute Took 30 seconds Took 16 seconds * CI Fix Took 6 minutes * CI Fix Took 6 minutes * [Protocol] Add moderation investigation commands Adds the protocol layer for the moderation investigation suite: - Command_GetUserSessions/GetUserAlts/GetModeratorLastLogins/ResetUserPassword/RemoveUserAvatar (1013-1017) - Response extensions 1215-1219 with ServerInfo messages for sessions, alts, and staff logins - last_login on Response_ReportUserInfo and warning_il on Response_WarnList Took 2 minutes * [Utility] Add warning categories parser with infraction levels Parses the server's 'officialwarnings' setting (comma-separated, optional '|IL' suffix) into WarningCategory structs so the client can display the infraction level of each warning category. Includes GTest coverage. * [Server] Add moderation investigation tools Implements the server side of the moderation suite: - getUserSessions/getUserAlts/getModeratorLastLogins/removeUserAvatar DB methods - Handlers for all five new commands with audit records (PASSWORD_RESET, REMOVE_USER_AVATAR); password resets return a generated temporary password - cmdGetWarnList now reports per-category infraction levels from the officialwarnings setting; cmdReportUserInfo reports last_login - Update servatrice.ini.example with the warning taxonomy - Password/avatar mutations report RespNameNotFound when the user does not exist * [Client] Add moderation tab with investigate, password reset, and avatar removal - New Moderation tab: search a user to show account info, alternate accounts, login sessions, and staff last logins; actions to reset the user's password (shows the generated temporary password) and remove the user's avatar - 'Investigate user' entry in the user context menu opens the tab pre-loaded for that user - Warning dialog shows the infraction level of each warning category - Tab wired into TabSupervisor with a moderator-gated menu action, shortcut, and tabs.ini persistence (default closed) * [Server/Client/Protocol] Address PR #7091 review: security, bug, and perf fixes Security: - Promote RESET_USER_PASSWORD to admin-only dispatch (was moderator-accessible) - Reject password reset on users with equal/higher privilege than caller - Notify affected user via Event_NotifyUser::CUSTOM when password is reset - Add server-side category whitelist for reports - Drop reporter name fallback in comment/details authorization (ID-only) - Force password change: new DB column + login enforcement + client disconnect Bugs: - XSS via QTextEdit::append() → insertPlainText() in report tab and utils - allNotified initialized to true even with empty recipients list - Warning combo box: use currentData() instead of baked-in display text - Report resolution now records who resolved (resolved_by column + audit) Performance: - IP-correlation subquery: add 6-month window + LIMIT 200 - getUserSessions: clamp limit to 500 Non-blocking: - Palette-aware colors in report_utils.cpp (dark/light mode) - Report list pagination: offset/limit fields + total_count in response - SessionCommand enum gap comment for reserved values 1201-1203 Schema: 36→37 (force_password_change), 37→38 (resolved_by) Took 12 minutes Took 16 seconds * Fix macOs pedantry Took 5 minutes --------- Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de> |
||
|
|
16b6132701
|
[Tabs] Add a setting to define startup tab on application launch (#7121)
* [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> |
||
|
|
fbe5c4ade0
|
[VDE] Add a new setting to determine initial tab (Context/Deck/Database) (#7122)
* [VDE] Add a new setting to determine initial tab (Context/Deck/Database) Took 16 minutes Took 4 seconds * Adjust tooltip Took 4 minutes --------- Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de> |
||
|
|
404b0cdf28
|
[Game] Animate Arrows (#7099)
* Add an arrow draw animation setting - New arrowDrawAnimation cards-display setting, default on - The arrow draw animation checkbox joins the animation settings group - Visual Deck Storage selection animation checkbox moves next to the other animation checkboxes, and the enable/disable-all buttons now cover it and the arrow animation Took 2 minutes Took 21 minutes Took 7 minutes Took 11 minutes Took 20 seconds * Animate arrows drawing from start to target - The arrow stroke reveals itself along the arc with an eased timing, followed by a short light sheen that sweeps down the shaft - The arrow head pops in once the reveal reaches it, then the whole arrow fades from its initial glow - Decay is driven by GameScene's shared animation timer through the IAnimatedItem interface (QElapsedTimer based), respecting the arrowDrawAnimation setting - GameScene adds the arrow item to the scene before starting its animation so the item is registered against a valid scene Took 6 minutes Took 1 minute * Defer animation start so arrows don't start halfway materialized Took 13 minutes * Don't draw tip/shaft outline Took 12 minutes --------- Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de> |
||
|
|
adf574e038
|
[Settings] Shuffle some settings around (#7084)
* [Settings] Shuffle some settings around Took 21 minutes Took 1 hour 25 minutes * [Settings] Camel case everything * Revert debug schema change * Add new classes * Fix card counters writing to global * Fix CI tests * Fix Windows CI * interface() is a protected keyword for MSVC Took 5 minutes Took 5 seconds * [Settings] Keep menu settings on the appearance settings page Leave the 'Menu settings' group box on the appearance settings page for now; relocating it to the user interface settings page will be done in a separate PR. Took 6 minutes --------- Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de> |
||
|
|
12f0f59453
|
[Settings] Split cache_settings monolith into multiple SettingsManager sub-classes (#7050)
* [Settings] Split cache_settings into multiple files Took 9 minutes Took 4 minutes * [Settings] Fwd declare settings classes in cache_settings Took 15 minutes * Fix oracle includes. Took 8 minutes * Address comments, fix windows CI Took 8 minutes * fix copy constructor visibility Took 3 minutes * lint Took 2 minutes * Fix native format tests. Took 5 minutes * Remove test header guard Took 4 seconds * Remove tests invalid in CI environ Took 24 seconds * Adjust to rebase. Took 11 minutes * Change settings file name. Took 8 minutes --------- Co-authored-by: Lukas Brübach <lukas.bruebach@bdosecurity.de> Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de> |