Skip to content

Releases: TheHolyOneZ/ZGameLib

ZGameLib (1.2.1)

03 Apr 23:29
878c8be

Choose a tag to compare

[1.2.1] — 2026-04-04

Added

  • Ubisoft Connect platform — added alongside Steam, Epic Games, and GOG as a built-in default platform
  • Ubisoft auto-scan — reads HKLM\SOFTWARE\WOW6432Node\Ubisoft\Launcher\Installs\{id} for install directories and HKLM\...\Uninstall\Uplay Install {id} for display names; exposed as scan_ubisoft_games command and included in scan_all_games
  • Ubisoft launchlaunch_ubisoft_game command opens ubisoft://launch/{gameId} via open::that(); playtime tracking follows the same directory-based process monitoring used by Steam and Epic
  • ubisoft_game_id column — new nullable TEXT column in the games table; live migration via ALTER TABLE applies to existing installs
  • Ubisoft platform badgeUbisoftIcon SVG added to Icons.tsx and PlatformBadge.tsx
  • Ubisoft sidebar filter — Ubisoft Connect entry with live game count in the Platforms section of the sidebar
  • Ubisoft spin wheel filter — "Ubisoft" quick-filter chip added to the Game Spin page; platform dot colored #60a5fa
  • Ubisoft stats supportubisoft field added to LibraryGrowthEntry; library growth chart, platform breakdown, and Year in Review donut all track Ubisoft games separately
  • Ubisoft filter builder — Ubisoft Connect available as a platform value in the advanced filter builder
  • Ubisoft game detail — Game ID shown in the info section of the detail panel when ubisoft_game_id is set
  • Collapsible library sections — Play Next and Recently Played rows can be collapsed by clicking their header; a chevron rotates to indicate state; collapsed state persists in localStorage across sessions

Changed

  • VALID_PLATFORMS in settings.rs extended to include "ubisoft"
  • Platform TypeScript union extended to "steam" | "epic" | "gog" | "custom" | "ubisoft"
  • useLaunchGame hook routes Ubisoft games to launch_ubisoft_game before falling back to direct exe launch

ZGameLib (1.2.0)

21 Mar 18:52
9d4aa3f

Choose a tag to compare

[1.2.0] — 2026-03-21

Added

  • Game-already-running detection — launching while another session is active shows a confirm dialog with "Stop & Launch" to switch games instantly
  • Live "Playing" indicator — play button shows a pulsing green "Playing" state while a game session is active
  • Stop & Launch — terminates the running game process (TerminateProcess) before launching the new one; all launch entry-points consolidated into a shared useLaunchGame hook

Fixed

  • ZipSlip path traversalinstall_bepinex and install_melonloader now validate each ZIP entry path component, rejecting any .. or rooted segments; canonicalize double-check against base directory
  • Scan button brokenGameGrid now calls useScan() at component level; the "Scan Steam / Epic / GOG" empty-state card correctly triggers the scan hook instead of a dead dynamic import
  • Dual game state divergencegame-session-ended listener in AppBehavior now calls qc.invalidateQueries rather than manually replacing store state; TanStack Query is the single source of truth
  • Soft-delete UNIQUE constraintsteam_app_id and epic_app_name UNIQUE column constraints replaced with partial unique indexes (WHERE deleted_at IS NULL); live migration rebuilds existing installs automatically
  • IGDB token wastefetch_igdb_metadata now caches the OAuth access token in IgdbTokenState with a 60-second expiry buffer; subsequent lookups reuse the cached token instead of requesting a new one per call
  • Unrestricted filesystem writesave_file command validates the resolved canonical target path against an allowlist of safe directories (APPDATA, LOCALAPPDATA, Documents, Desktop, Downloads, OneDrive); writes outside these directories are rejected
  • Missing transactionsreorder_games and batch_update_games now wrap their multi-statement loops in a single SQLite transaction for atomicity and a ~10× throughput improvement
  • Game tracking fallback — tracking state no longer resets instantly when a Steam/Epic game has no install directory or exe path; fallback tracker keeps the session active until manually stopped

v1.0.0 — The Milestone Release

20 Mar 13:04
df42cc9

Choose a tag to compare

v1.0.0 is focused on Polish & Discovery — making ZGameLib feel welcoming from
the very first launch. Three major features land alongside a set of smaller
quality-of-life additions.

Download and more info at https://zsync.eu/zgamelib/

─────────────────────────────────────────────────────────────────────────────

🎬 Interactive Onboarding Tour

The signature 1.0 feature. On first launch, pick a tour mode and ZGameLib
walks you through the entire UI automatically.

  • Three modes: Quick Start (~2 min, 10 steps), Standard (~5 min, 23 steps),
    Deep Dive (~10 min, 37 steps)
  • Animated SVG spotlight overlay with glow ring and pulse effects; auto-scrolls
    off-screen targets before measuring
  • Live demonstrations — context menu actually opens on a game card, scan
    dropdown expands and highlights its options, game detail tabs switch, settings
    page scrolls to each section
  • Full toolbar coverage: dedicated steps for Bulk IGDB, Remove Duplicates, Scan
    Log, HLTB, and IGDB buttons in the detail panel
  • Auto-scan runs when the tour starts so your library populates while you watch
  • Chapter system in Deep Dive (37 steps across 9 labeled chapters)
  • Cinematic finale: fly-through purple heart animation + "Made By TheHolyOneZ"
    credit with particle effects
  • Keyboard navigation: Enter/→ advance, ← back, Escape skip
  • Re-triggerable anytime from Settings → About
  • Onboarding reset on upgrade: users coming from 0.x get the tour automatically
    on first 1.0.0 launch

📅 Year in Review (/wrapped)

Annual gaming recap accessible from the sidebar or the W shortcut.

  • Year selector defaulting to current year; only shows years with session data
  • 9 animated stat cards: total hours, most played, top rated, new additions,
    completed, longest session, busiest month (12-bar chart), platform split
    (SVG donut), and games explored
  • Empty state shown when no session data exists for the selected year

💡 Smart Play Recommendations

"Play Next" strip on the library page surfacing backlog games you're most
likely to enjoy.

  • Frontend-only algorithm: taste profile = tags + genre of all games rated ≥ 8;
    score = matching tags ×2 + genre match ×3; tiebreak by time in library
  • Each card shows "X matching tags" so you know why it was suggested
  • Per-card dismiss (session only, no persistent blacklist)
  • Only activates when the library has ≥ 3 games rated ≥ 8 and ≥ 3 eligible
    suggestions; otherwise hidden entirely

─────────────────────────────────────────────────────────────────────────────

Also in 1.0.0

What's New Modal

  • Shown automatically on first launch after an update
  • "What's New" button in Settings → About to re-open it anytime

Contextual Empty State

  • When the library is empty and onboarding is complete: three action cards
    (Scan for Games, Add Manually, Browse Steam)
  • First-run users still see the original illustration + Take the Tour CTA

New Keyboard Shortcuts

  • S — focus the Scan Games dropdown
  • W — navigate to Year in Review
  • H — toggle visibility of hidden/duplicate games
  • 1–9, 0 — quick-rate the open game detail (0 = 10 stars)
  • Ctrl+Z — undo last game deletion
  • All new shortcuts added to the ? overlay

Changed

  • Default grid columns changed from 4 to 6

─────────────────────────────────────────────────────────────────────────────

Full Changelog (1.0.0)

Interactive Onboarding Tour (F-050)

  • Tour Mode Selector: full-screen mode picker on first launch with three
    options; skip option marks onboarding complete without running tour
  • Cinematic spotlight overlay: SVG mask-based cutout, accent glow ring, double
    pulse rings, radial gradient highlight; auto-scrolls off-screen targets
  • Live interactive demonstrations: scan dropdown expands, context menu appears
    via synthetic right-click, Add Game modal opens, game detail opens with IGDB
    and HLTB buttons highlighted, settings page scrolls to each section
  • Full toolbar coverage: dedicated steps for Bulk IGDB Metadata, Remove
    Duplicates, and Scan Log buttons
  • Auto-scan on first launch in every tour mode
  • Chapter system (Deep Dive): 37 steps across 9 labeled chapters with gradient
    indicator strip
  • Tour card: glass-morphism floating card with gradient accent header, step
    counter badge, animated position transitions, smooth content crossfade
  • Cinematic finale: fly-through purple SVG heart, "Made By TheHolyOneZ" credit,
    particle effects, phased reveal
  • Keyboard navigation: Enter/→ advance, ← back, Escape skip
  • afterRender hook system: context menu opens after spotlight is stable to
    prevent scroll-triggered dismissal
  • Persistent state: onboarding_completed and onboarding_tour_mode saved to
    settings; backend event and frontend check ensure reliable first-launch trigger
  • Onboarding reset on upgrade: users from 0.x get the tour on first 1.0.0 launch
  • Restart tour: "Take the Tour" button in Settings → About
  • data-tour attributes on all targeted elements

Year in Review / Wrapped (F-051)

  • New /wrapped page accessible from sidebar (between Spin and Settings) and W shortcut
  • Year selector: dropdown defaulting to current year; only years with sessions shown
  • Stat cards (staggered Framer Motion entry):
    Hero: total hours across total sessions
    Most Played: cover, name, platform badge, total hours
    Top Rated: highest-rated game played or added in the year
    New Additions: games added to the library this year
    Completed: games marked completed this year
    Longest Session: formatted as hours + minutes
    Busiest Month: month name with 12-bar chart
    Platform Split: SVG donut chart
    Games Explored: distinct games with at least one session
  • Empty state when no session data exists for the selected year
  • Rust backend command get_year_in_review(year) with multi-join SQLite queries

Smart Play Recommendations (F-052)

  • Recommendations strip: collapsible horizontal scroll row below Pinned, above
    grid; up to 5 personalized suggestions
  • Taste profiling: frontend-only; scores status=none/backlog games with
    playtime_mins < 30; matching tags ×2 + genre match ×3; tiebreak by time in library
  • Hint label: each card shows "X matching tags"
  • Per-card dismiss: hides for session, resets on reload
  • Threshold guard: only renders when ≥ 3 games rated ≥ 8 AND ≥ 3 eligible suggestions

What's New Modal (I-047)

  • Auto-shown on first launch after an update
  • Rust compares last_seen_version to CARGO_PKG_VERSION; emits show-whats-new event
  • "View full changelog" link opens GitHub releases
  • Manual trigger via Settings → About

Empty State Enhancement (I-048)

  • Contextual empty state: three action cards when library empty + onboarding complete
  • First-run users see original illustration-based empty state

Keyboard Shortcut Additions (I-049)

  • S: focus Scan Games dropdown
  • W: navigate to /wrapped
  • H: toggle hidden/duplicate game visibility
  • 1–9, 0: quick-rate open game detail (only when panel is open, never in fields)
  • Ctrl+Z: undo last game deletion
  • All added to ? overlay

Changed

  • Default grid columns: 4 → 6 (Rust default and frontend fallback)
  • Wrapped page added to sidebar between Spin and Settings
  • Settings → About: added "Take the Tour" and "What's New" buttons

ZGameLib (0.9.0 - Stable)

19 Mar 23:57
d0d58fa

Choose a tag to compare

[0.9.0] — 2026-03-20

Added

Uninstalled Steam Games (F-017)

  • Pull Uninstalled Steam Games — import all owned but uninstalled Steam games into the library via Steam Web API (IPlayerService/GetOwnedGames)
  • "Not Installed" badge shown on game cards (top-left, next to platform badge) and in list-view rows for any uninstalled game
  • Install via ZGameLib — clicking launch/play on a "Not Installed" Steam game opens Steam's install dialog (steam://install/{appId}) instead of running the game
  • Scan Games dropdown in the top bar — replaces the single Scan button with a split button/dropdown: "Scan Installed Games" (existing behavior) and "Pull Uninstalled Steam Games"
  • Sidebar filter — "Not Installed" section appears in the sidebar when any uninstalled games are present, with a count badge; clicking it filters the library to show only uninstalled games
  • Auto-pull on startup toggle in Settings → Behavior — "Pull uninstalled Steam games on startup"; requires Steam API Key and SteamID64 to be configured
  • Scanner auto-detects installs — when a Steam scan runs and finds a game previously marked as "Not Installed", it automatically marks it as installed and populates the exe_path and install_dir
  • Database migration — new not_installed column (INTEGER, default 0) added to games table via schema migration
  • Settings keyinclude_uninstalled_steam (default false) persisted in app settings

Library Pagination (F-042)

  • Pagination toggle in Settings → Appearance — off by default; when enabled the library splits into pages instead of one continuous scroll
  • Page size selector — choose 12, 24, 36, 48, 60, or 100 games per page; selector only visible when pagination is on
  • Pagination bar — prev/next arrows with numbered page buttons; smart ellipsis condensing for large page counts (e.g. 1 … 4 5 6 … 20); current page highlighted with accent gradient; appears below the grid in all view modes (grid, list, manual sort order)
  • Page resets to 1 automatically when search, filters, page size, or toggle change
  • New settings keys: pagination_enabled (default false), pagination_page_size (default 24, clamped 6–200)

Steam Playtime Sync (F-013)

  • Steam Playtime Sync in Settings → Integrations — enter your Steam API Key and SteamID64 to sync playtime from Steam; only increases local values, never decreases
  • Sync button shows updated/skipped count in a toast

Idle Detection (F-014)

  • Exclude idle time from playtime toggle in Settings → Behavior (default: on) — deducts time when the game isn't in focus for 5+ consecutive minutes; brief alt-tabs are ignored

Advanced Filter Builder (F-016)

  • Advanced filter section in the sidebar — under a collapsible "Advanced" toggle below the Cover Art section
  • Filter rules with field/operator/value — supports platform, status, rating, playtime, tags, date_added, is_favorite, has_cover
  • AND / OR logic toggle between rules
  • Add Rule and Clear All buttons; each rule has a remove button

Game Tracking Overhaul (I-046)

  • Directory-based process tracking — all launchers (Steam, Epic, direct exe) now watch the game's install_dir for any running process instead of tracking a single spawned PID; handles multi-process games that previously recorded 0 playtime
  • Launcher stub support — games that start via a stub launcher no longer lose their session when the stub exits; the tracker maintains a grace window between process deaths so the real game process is picked up seamlessly
  • install_dir fallbacklaunch_game now fetches install_dir from the database; if unset, derives it from the exe's parent directory; falls back to single-PID tracking only when no directory is resolvable
  • Directory-based idle detectionexclude_idle_time now checks whether the foreground window belongs to any process in the game directory, not just the originally spawned PID
  • ToolHelp process enumeration — replaced all tasklist subprocess calls with CreateToolhelp32Snapshot + QueryFullProcessImageNameW; process scans are now ~10× faster and create no console flicker
  • Steam / Epic install_dir tracking — Steam and Epic launch paths use the game's stored install_dir for directory tracking with a 300-second startup window; falls back to exe-name scanning only when install_dir is unavailable
  • Parallel process tracking prevention — direct launches now register in ActivePids alongside Steam/Epic, preventing duplicate session threads if the user clicks play twice before the tracking thread starts

Auto Grid Columns (I-042)

  • "Auto" option for grid columns in Settings → Appearance — uses repeat(auto-fill, minmax(180px, 1fr)) to fill the available space automatically

Persistent Error Log (I-045)

  • Copy Logs button in Settings → About — copies the last 200 error log lines to the clipboard; errors are written to %APPDATA%\zgamelib\logs\app.log with rotation at 1 MB (keeps last 3 files)

Changed

  • Version bumped to 0.9.0

ZGameLib (0.8.0)

19 Mar 13:15
ad504a6

Choose a tag to compare

[0.8.0] — 2026-03-19

Added

Collections (F-020)

  • Collections page — create, rename, delete, and describe collections; grid/list view toggle; search bar to filter by name
  • Collection description — click-to-edit description/notes field per collection; stored in collections.description (backwards-compatible ALTER TABLE)
  • Collection detail view — click a collection to see its games with search and grid/list toggle
  • Right-click context menu on collections — rename / delete directly from the collections page
  • Game context menu → Collections submenu — right-click any game anywhere → hover Collections → submenu shows all collections with checkmarks; click to add or remove; a game can belong to multiple collections simultaneously
  • Remove from Collection — when viewing a collection's game list, right-click a game → orange "Remove from Collection" option
  • Batch operations → Add to Collection — select multiple games → + Collection button in the BatchActionBar → pick a collection to add all selected games at once
  • Full export v3 — export now includes collections and collection_games arrays; import is fully backwards-compatible (#[serde(default)]); old v1/v2 exports still import correctly

IGDB Metadata (F-006)

  • Settings → Integrations — IGDB Client ID and Client Secret fields with a clear 6-step setup guide: create a Twitch Developer app at dev.twitch.tv/console, set OAuth Redirect URL to http://localhost, set Category to Other, copy Client ID and Client Secret
  • Fetch IGDB button in Game Detail — fetches genre, developer, publisher, and release year for the open game; populates description if empty
  • IGDB metadata card in Game Detail Info tab — shown when any IGDB field is present; modern 2×2 flex-wrap grid with custom SVG icons (gamepad · code · building · calendar) for each field; adapts to any panel width
  • (i) info button in metadata card header — hover or click reveals: "Data sourced from IGDB by game name. If another title shares a similar name, the wrong match may have been returned"
  • Clear IGDB data button (trash icon) in metadata card header — removes all IGDB fields and sets an igdb_skipped flag on the game
  • igdb_skipped flag (ALTER TABLE games ADD COLUMN igdb_skipped INTEGER) — persisted in SQLite; once set, the bulk scan silently skips the game and the individual fetch button shows a confirmation dialog before proceeding
  • Bulk IGDB scan button (sparkle icon) in library Topbar — fetches IGDB data for every game that has none and is not flagged; spins while running with a live X/Y counter badge; reloads the game list on completion; if no credentials are configured shows an error toast pointing to Settings → Integrations

Notes — Markdown Preview (I-026)

  • Notes in Game Detail now have a per-note preview/edit toggle (eye and pencil SVG icons)
  • Preview renders full Markdown using react-markdown + rehype-sanitize with prose styling

Tags — Undo Deletion (I-012)

  • Removing a tag in Game Detail now starts a 5-second countdown instead of deleting immediately — tag shows strikethrough at 45% opacity with a undo indicator
  • Click the pending tag to cancel the deletion; after 5 seconds the removal is committed

Statistics — Library Growth Chart (F-036)

  • Library Growth section on the Stats page — stacked bar chart showing how many games were added per calendar month, bars colored by platform using the existing PLATFORM_COLORS_HEX palette, legend at the bottom; data comes from the new get_library_growth backend command

Custom Theme Creator (F-041)

  • Create Theme button in Settings → General → Theme — opens an inline editor to build a fully custom theme from scratch
  • Accent color picker — native color input plus 14 preset swatches; HSL shade generation auto-derives all 8 accent levels (200–900) with a live shade strip preview
  • Background and sidebar color pickers — 10 dark preset swatches; sidebar auto-derived from background with manual override
  • Live preview — the entire app updates in real time as colors are adjusted; a miniature sidebar+content mockup is also shown in the editor
  • Save, edit, delete — custom themes appear alongside built-in themes with hover controls (pencil to edit, trash to delete); stored in the custom_themes settings key as JSON
  • Theme utility module (src/lib/theme.ts) — shared HSL math, shade generation, and CSS variable injection used by both Settings and Layout

Unsaved Settings Guard (I-029)

  • Dirty detection — Settings page tracks whether any field has changed since the last save using a JSON snapshot comparison
  • Navigation interception — Sidebar and Command Palette check the dirty flag before navigating away from Settings; if unsaved changes exist, navigation is blocked and a modal appears
  • Unsaved Changes modal — glass-morphism dialog with accent-colored info icon, spring animation, and two options: Discard (reverts to saved state and navigates) or Save & Leave (persists changes then navigates)

Fixed

  • Collections submenu click closes context menu — root cause: CollectionsSubmenu was rendered via createPortal to document.body, which placed it outside menuRef's DOM tree; the outside-click mousedown handler detected submenu clicks as "outside" and closed the menu before the button registered. Fix: restore createPortal (needed so fixed positioning works correctly outside the backdrop-filter parent), add data-ctx-submenu="true" attribute to the portaled div, and update the handler to check target.closest("[data-ctx-submenu]") before closing
  • Collections submenu not appearing on hover — root cause: CollectionsSubmenu was a fixed child of the main menu div which uses backdrop-filter (via glass-strong); backdrop-filter creates a new CSS containing block for fixed children, so the submenu's viewport coordinates were applied relative to the parent, placing it off-screen. Fix: restored createPortal so the submenu renders outside the backdrop-filter ancestor
  • IGDB metadata card swallowed / not resizing — removed overflow-hidden from the card wrapper (was clipping the tooltip and preventing content growth); replaced grid grid-cols-2 with flex flex-wrap with percentage widths so cells reflow gracefully at any panel width; added break-words to values

Changed

  • Version bumped to 0.8.0
  • Database additions (all backwards-compatible ALTER TABLE):
    • games.genre TEXT
    • games.developer TEXT
    • games.publisher TEXT
    • games.release_year INTEGER
    • games.igdb_skipped INTEGER NOT NULL DEFAULT 0
    • New table collections (id, name, created_at, description)
    • New table collection_games (collection_id, game_id) with cascade delete
    • New setting custom_themes — JSON array of user-created themes (id, name, accent, bg, sidebar)

ZGameLib

18 Mar 10:05
b757052

Choose a tag to compare

Fixed

  • Process tracking fallback for Steam/Epic — when the launched game process is never found within the polling window, the session is now properly closed with 0 minutes and the UI restores correctly; previously the background thread would silently exit leaving the app in a tracking state
  • Cover cache race condition — multiple components mounting simultaneously for the same game no longer trigger parallel fetches; a per-key in-flight deduplication guard prevents redundant requests; cache capacity raised from 200 to 500 entries
  • Input length validationname is capped at 255 characters, description at 10,000, tags limited to 100 items each ≤ 50 characters; the backend rejects out-of-range values with a descriptive error rather than storing them silently
  • No keyboard navigation on game cards — cards now have tabIndex={0}, role="button", and respond to Enter / Space, making the library navigable without a mouse
  • Focus not trapped in modals — Tab key could previously escape the Game Detail panel and Cover Search modal; a keyboard trap now constrains focus to the active overlay while it is open
  • PowerShell injection in icon extraction — icon extraction no longer interpolates file paths into the PowerShell command string; paths are now passed via ZGAMELIB_EXE_PATH and ZGAMELIB_DEST_PATH environment variables, eliminating a potential command injection vector
  • Empty catch blocks in GameListRow — launch and open-folder errors were silently swallowed; both now display an error toast with the failure message
  • Cover cache memory leak — the in-memory cover URL cache now uses LRU eviction (max 200 entries); previously it grew unboundedly for large libraries
  • Non-atomic cover downloads — cover images are now written to a .tmp file first and renamed atomically, preventing corrupt partial writes on crash or error
  • Folder scan walk limit — the custom folder scanner now hard-caps at 10,000 file system entries to prevent runaway walks on deeply nested or large drives
  • Exe icon not refreshing after game update — the icon cache key now includes the file's modification time (mtime); replacing a game's exe now shows the new icon on next launch
  • Game detail shows stale data after switching games — the detail panel now invalidates and refetches game data when selectedGameId changes, preventing stale reads between rapid game switches
  • Auto-scan not triggering on startupscan was missing from the useEffect dependency array in Layout.tsx; auto-scan now fires reliably on app start when enabled
  • Cover placeholder constant duplicatedCOVER_PLACEHOLDER was defined independently in RecentlyPlayed and PinnedRow; both now import from the shared @/lib/utils module
  • Missing aria labels on scan-related topbar buttons — scan log toggle and remove-duplicates button now have aria-label attributes for screen readers

Added

  • Drag-and-drop reordering — a new "Custom Order" sort option enables Framer Motion Reorder drag-and-drop for the game grid; dragging a card updates sort_order in the database for all affected games in a single batch transaction; order persists across sessions
  • Time-to-beat estimates (HLTB) — a clock icon button in the Game Detail panel fetches HowLongToBeat data for the game (main story and completionist hours); results are cached in the database (hltb_main_mins, hltb_extra_mins) and displayed in the stats grid
  • Custom fields — users can define arbitrary key/value metadata per game (text values); field editor in the Info tab with add/edit/delete; stored as a JSON map in the database under custom_fields
  • Global keyboard shortcuts? toggles a keyboard shortcut help overlay; N opens the Add Game modal; F toggles favorite on the currently open game; Escape closes the detail panel or any overlay; global keydown listener in Layout.tsx
  • Portable mode — if a file named portable.flag exists next to zgamelib.exe at startup, the database and settings are stored in the same directory as the exe instead of %APPDATA%\zgamelib; useful for USB drives or self-contained installs
  • Duplicate removal confirmation — clicking "Remove Duplicates" in the topbar now shows a confirm dialog listing how many games will be hidden before acting; previously it applied the change instantly with no warning
  • Cover lightbox — clicking the game cover image in the detail panel now opens a full-size lightbox overlay instead of jumping straight to the cover search modal; a separate "Change Cover" button on the hover overlay handles cover replacement
  • Quick rate from game card — a row of 10 rating buttons appears at the bottom of a game card on hover, allowing ratings to be set without opening the detail panel; the active rating is highlighted
  • Empty library illustration — the first-run / empty-library state now shows an animated gamepad SVG illustration with orbiting sparkle dots and an accent glow, replacing the previous blank panel
  • Trash bin / soft delete — deleting a game moves it to trash (deleted_at timestamp) instead of hard-deleting it; restore or permanently delete from a new Trash section in Settings → Data; "Empty Trash" purges all at once — backwards-compatible via ALTER TABLE
  • Pinned games row — right-click any game → Pin to show it in a dedicated "Pinned" strip at the top of the Library; pin state persists to the database
  • Session history — each game launch records a session row (started_at, ended_at, duration_mins) in a new sessions table; view the last 50 sessions per game in a new History tab in the Game Detail panel
  • Bulk auto-fetch missing covers — new "Fetch Missing Covers" button in Settings → Data; fetches covers for all games that have no cover art (Steam games via CDN, others via name search); reports updated/failed counts
  • Platform badge component — dedicated PlatformBadge component with platform icons (Steam / Epic / GOG / Custom) used consistently across GameCard, GameListRow, GameDetail, and Spin pages
  • Collapsible sidebar — sidebar can be collapsed to a 62 px icon-only strip; collapses with a spring animation; collapse toggle moved to the header (always visible); state persists across sessions via localStorage
  • Sort direction toggle — ascending/descending sort button added to the PageSearch bar
  • Theme hover preview — hovering a theme button in Settings instantly previews it; the previous theme restores on mouse-out if not confirmed
  • Delete option in right-click context menu — "Delete" entry with red styling and a visual divider separator added to the GameContextMenu
  • Weekly playtime goal (GoalBar) — collapsible goal widget at the top of the Library page; set a target in hours, animated progress bar shows current week's playtime; "Goal reached!" state with green color; persists via localStorage
  • Search scope toggle — small A / A+ toggle embedded inside the search input; switches between searching game name only vs. name + description
  • Cover art filter — "Has Cover" and "Missing Cover" filter buttons in the sidebar under a dedicated Cover Art section (consistent with Platform/Status styling); shows counts; replaces the old cluttered buttons in the search bar
  • Export library as CSV — new button in Settings → Data exports the full library as a .csv file with proper quoting; fields: id, name, platform, status, rating, playtime_mins, date_added, is_favorite, tags
  • Export Filtered — new button in Settings → Data exports only the currently visible/filtered games as JSON; button label shows the active count (e.g. "Export Filtered (12)")
  • "Saved ✓" flash indicator — editing a game's name, description, or rating now flashes a brief "Saved ✓" indicator in the detail panel's tab bar using AnimatePresence
  • Scroll-to-top button — a floating ↑ button appears after scrolling 400 px on the Library, Favorites, and Recently Played pages; smooth animated entrance/exit
  • Tab counts in game detail — Screenshots and History tab labels now show live counts (e.g. "Screenshots (6)", "History (3)")
  • Description expand/collapse — long game descriptions are truncated at 200 characters with a "Show more / Show less" toggle in the game detail Info tab
  • Cover search empty state — the cover search modal now shows "No covers found for 'X'" with a helpful hint ("Try a shorter name or remove subtitles") instead of a blank panel before searching

Changed

  • Version bumped to 0.6.0
  • delete_game command is now a soft delete; hard delete is permanent_delete_game
  • Sidebar collapse toggle moved from the bottom to the header row (always accessible regardless of window height)
  • About section in Settings spans full grid width (was half-width like other cards)
  • Cover art filter and search scope controls moved out of the search bar into proper locations (sidebar and inside search input respectively) for a cleaner topbar

ZGameLib (0.7.0)

18 Mar 14:10
861e26f

Choose a tag to compare

[0.7.0] — 2026-03-18

Fixed

  • Tiny settings labels — all text-[10px] instances in Settings replaced with text-xs for readable, consistent label sizing throughout the settings page
  • Invalid platform/status saved silentlyupdate_game now validates platform (must be steam, epic, gog, or custom) and status (must be none, backlog, playing, completed, dropped, or on_hold) and returns a descriptive error instead of persisting garbage values
  • Import library accepts bad dataimport_library now validates each game before inserting: skips entries with empty or >255 char names, ratings outside 0–10, and unrecognised platform strings
  • Launcher threads run forever — background process-polling threads for Steam/Epic/GOG/custom now have a hard 86 400-second (24-hour) cap; previously a game that never launched would leave a thread running indefinitely
  • Batch status dropdown invisible on dark background — the floating BatchActionBar status select now forces a dark background (bg-[#1a1825]) with matching dark option elements so the text is readable on all platforms
  • Batch rating input shows number spinners — the rating field in the batch action bar no longer renders browser-native up/down spinners; uses CSS to suppress them on all engines
  • Batch rating not clamped — entering a value outside 1–10 in the batch rating field is now rejected on every keystroke; the input clamps to [1, 10] immediately
  • Export missing sessions and notesexport_library previously only exported games; the JSON export now uses a v2 FullExport envelope ({ version, games, sessions, notes }) so all play history and notes are preserved; import_library detects v1 (plain array) vs v2 automatically and restores sessions and notes, skipping any whose game_id no longer exists
  • Playtime not recorded for short sessions — three root causes fixed: GOG/custom process polling interval reduced from 30 s to 5 s; Steam/Epic game_start timer now begins only after the target PID is found (not at launch time, which inflated playtime by up to 3 minutes); sessions ≥ 30 seconds are now saved (previous threshold was > 0 minutes, silently dropping any session under 1 minute)
  • Game card action buttons invisible on light covers — overlay buttons changed from bg-black/40 to bg-black/70 with an explicit border border-white/10 shadow-lg, ensuring they are always legible regardless of cover brightness
  • Fire icon appears squishedFireIcon completely redrawn as a proper three-layer SVG flame; size on game cards raised from 12 px to 18 px, and on list rows from 10 px to 15 px
  • Spin wheel inner hub dominates the empty wheel — removed the large dark center circle entirely; pie slices now extend from the exact center point, giving the wheel a clean look even with a single entry
  • Spin wheel empty state spinner icon — removed the decorative rotating icon from the empty state overlay; the empty state now shows text only
  • Spin winner card pushes "Spin the Wheel" button upward — the right panel is now split into a fixed top section (wheel + button, shrink-0) and a separate scrollable bottom section (winner card + history); the button never moves regardless of how much content appears below it
  • Directory traversal in cover file copyset_game_cover now rejects symlinks (via symlink_metadata), validates the file extension against an allowlist (jpg, jpeg, png, webp), and checks magic bytes before copying; previously any file path including sensitive system files could be copied into the app data directory
  • N+1 query pattern in scanner — Steam, Epic, and GOG scan loops previously fired one SELECT per discovered game to check for duplicates; each scanner now bulk-fetches all existing IDs into a HashMap/HashSet before the loop and does in-memory lookups, reducing scan overhead from O(n) queries to a single query per platform
  • Playtime chart renders as a solid block — the "Last 12 Weeks" chart used preserveAspectRatio="none" on its SVG, which stretched all bars to fill the full container width and merged them into an indistinguishable block; replaced with a div-based flexbox chart where bars grow from the bottom, labels show every other week, and a Framer Motion scaleY entrance animation staggers each bar in

Added

  • Command palette (Ctrl+K) — centered overlay with a fuzzy search that matches any game by name; results show cover thumbnail and platform badge; keyboard navigation (↑ ↓ Enter Escape); also surfaces six quick actions (Add Game, Library, Favorites, Stats, Spin, Settings); Ctrl+K again or Escape closes it
  • Batch multi-select — hold-click the checkbox that appears on any game card (top-left, visible on hover) or list row to build a selection; a floating BatchActionBar slides up from the bottom showing the selection count, a status dropdown, a rating input, an "add tag" field, and a Delete button; all changes apply to every selected game in one transaction; × clears the selection
  • Weekly playtime chart — new "Playtime — Last 12 Weeks" SVG bar chart on the Stats page; each bar represents one ISO week; bars animate in on mount; hovering a bar shows the exact playtime and week label in a tooltip; data comes from the sessions table
  • Lowest Rated section — Stats page shows a ranked list of up to 5 games rated ≤ 4 with their scores highlighted in red
  • Most Neglected section — Stats page shows up to 5 games with zero recorded playtime, sorted by how long they have been in the library, with a "Added X days ago" label
  • Screenshot lightbox navigation — left / right chevron buttons let you page through all screenshots without closing the lightbox; an "X / Y" counter in the top-right corner tracks position; ArrowLeft / ArrowRight keyboard support added; navigation wraps around at both ends
  • Playtime reminder on startup — if Playtime Reminders is enabled in settings, the app checks on launch for the game you have not played in the longest time (minimum 30-day threshold); emits a toast-style notification with the game name and number of days since last session
  • Window position and size memory — the app saves the window's last position (window_x, window_y) and size (window_width, window_height) to the database on close and restores them exactly on next launch; only restores if coordinates are on-screen (≥ 0)
  • Playtime Reminders toggle — new toggle in Settings → Behavior; persisted as playtime_reminders in the settings table; defaults to enabled
  • "Game Started" play button confirmation — after clicking Play in the game detail panel, the button transitions to a green "Game Started" state with a checkmark for 3 seconds using AnimatePresence, giving clear visual feedback that the launch command was sent

Changed

  • Sidebar active link now has a clear left-edge accent bar (border-l-2 border-accent-500) plus a subtle background fill and bold white text; previously only the text color changed on the active route
  • Fire icon on high-rated games now pulses with a Framer Motion breathing animation (scale 1 → 1.2 → 1, 2-second loop) on both game cards and list rows
  • Game card hover overlay buttons now stagger in (opacity 0→1, y 10→0) with a 50 ms per-button delay instead of appearing all at once
  • Rating buttons on game cards moved above the game title (previously rendered below the title, partially obscured by the status badge)
  • Spin wheel clock tick marks removed from the static overlay SVG; the outer ring and pointer triangle are kept; the wheel looks cleaner with no decorative minute-hand lines
  • Version bumped to 0.7.0

ZGameLib(0.5.0)

18 Mar 10:02
b1e4630

Choose a tag to compare

Update README.md