Skip to content

Add per-video volume and speed overrides#10

Open
Kryxzort wants to merge 10 commits into
sunwoo101:mainfrom
Kryxzort:pr/per-video-overrides
Open

Add per-video volume and speed overrides#10
Kryxzort wants to merge 10 commits into
sunwoo101:mainfrom
Kryxzort:pr/per-video-overrides

Conversation

@Kryxzort

@Kryxzort Kryxzort commented May 4, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Adds per-video volume and speed sliders in the preview modal (click any library card)
  • Overrides persist as .volume / .speed sidecar files alongside the video
  • Overrides apply at launch (baked into mpv options) and in real-time via IPC when switching in a playlist
  • Playlist observer reconnects after GUI close so overrides keep firing from the daemon
  • Adds a global speed slider to the Settings tab (complements existing volume slider)
  • Adds video scale setting (Fit / Fill) — Fill crops to fill the screen, Fit letterboxes

How overrides work

  • Per-video override set → used instead of global setting
  • No override set → falls back to global volume / speed
  • Override cleared (slider reset) → sidecar file deleted, global resumes

Test plan

  • Open preview modal for a library wallpaper → Volume and Speed sliders visible
  • Set volume override → apply wallpaper → audio at override level, not global
  • Set speed override → video plays at custom speed
  • Add two wallpapers to playlist with different overrides → play → each applies its own override on switch
  • Close GUI while playlist plays → overrides still apply on advance (daemon observer)
  • Settings tab → global Speed slider present and functional
  • Settings tab → Video Scale dropdown (Fit / Fill) changes mpv panscan behaviour

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added playback speed control (0.1x–4.0x)
    • Added video scaling options (fit/fill modes)
    • Per-wallpaper volume and speed overrides with global sync buttons
    • Support for Steam Workshop scene files
    • Wallpaper whitelist and crash-state tracking
  • Bug Fixes

    • Improved playlist daemon handling for non-timed playlists
    • Enhanced cleanup of associated sidecar files during library management

@coderabbitai

coderabbitai Bot commented May 4, 2026

Copy link
Copy Markdown

Warning

Rate limit exceeded

@Kryxzort has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 16 minutes and 59 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d0d1b1ab-cccd-4cae-b887-4b628d494a96

📥 Commits

Reviewing files that changed from the base of the PR and between 5ee8ba0 and a6ff103.

📒 Files selected for processing (13)
  • .claude/rules/library.md
  • .claude/rules/player.md
  • .claude/rules/session.md
  • .claude/rules/ui.md
  • src/livepaper/App.axaml.cs
  • src/livepaper/Helpers/LibraryService.cs
  • src/livepaper/Helpers/PlayerHelper.cs
  • src/livepaper/Models/AppSettings.cs
  • src/livepaper/Models/LibraryItem.cs
  • src/livepaper/Models/WallpaperResult.cs
  • src/livepaper/ViewModels/MainWindowViewModel.cs
  • src/livepaper/ViewModels/WallpaperCardViewModel.cs
  • src/livepaper/Views/MainWindow.axaml
📝 Walkthrough

Walkthrough

This PR extends livepaper with per-wallpaper volume and speed overrides, persistent metadata tracking, and dynamic video scaling. LibraryService now manages sidecar files (.volume, .speed, .crashed, .whitelist, .id) and discovers .scene files as distinct library entries. PlayerHelper adds a background playlist observer that applies per-video overrides as the playlist position changes. AppSettings gains Speed and VideoScale properties. UI controls are added for global Speed and VideoScale settings, plus per-wallpaper override sliders in the preview modal.

Changes

Metadata & Playback Control Expansion

Layer / File(s) Summary
Data Models
src/livepaper/Models/LibraryItem.cs, src/livepaper/Models/WallpaperResult.cs, src/livepaper/Models/AppSettings.cs
LibraryItem adds IsScene, WorkshopId, HasCrashed, IsWhitelisted, VolumeOverride, SpeedOverride, and AddedAt fields. WallpaperResult adds IsScene and WorkshopId. AppSettings introduces clamped Speed (0.1–4.0, default 1.0) and VideoScale ("fit" or "fill") properties with mpv option generation.
Library & Media Helpers
src/livepaper/Helpers/LibraryService.cs, src/livepaper/Helpers/PlayerHelper.cs
LibraryService.Delete() now removes sidecar files (.volume, .speed, .crashed, .whitelist, .id, thumbnail variants). LoadAll() enumerates only .mp4 files with rich metadata lookup (thumbnails, workshop-id parsing, override sidecars, creation timestamps) and adds .scene file discovery. Public methods MarkCrashed(), SaveVolumeOverride(), SaveSpeedOverride(), SetWhitelisted() persist state. PlayerHelper adds a background playlist-position observer that applies per-video volume/speed overrides via IPC, with new public methods SetSpeed() and SetVideoScale() and a new OnWallpaperChanged event callback.
Application Lifecycle
src/livepaper/App.axaml.cs
Timer daemon spawn logic extended: non-timed playlists now respawn the timer daemon when LastSession.IsPlaylist && IsPlaying is true, in addition to the existing timed-playlist condition.
ViewModel Wiring
src/livepaper/ViewModels/MainWindowViewModel.cs, src/livepaper/ViewModels/WallpaperCardViewModel.cs
MainWindowViewModel adds VideoScale options and observable Speed property; wires PlayerHelper.OnWallpaperChanged to update per-card IsCurrentlyPlaying status; adds OnSpeedChanged handler and conditional override logic (only apply global speed when no card-specific override exists); synchronizes volume/speed across selected cards with reentrancy guards. WallpaperCardViewModel introduces per-card metadata (IsScene, WorkshopId), whitelist/crash state, and volume/speed override sliders with computed "synced vs overridden" properties; provides UpdateGlobalVolume() and UpdateGlobalSpeed() methods and SyncToGlobal() / SyncSpeedToGlobal() relay commands; initializes from both WallpaperResult and LibraryItem models.
UI Layer
src/livepaper/Views/MainWindow.axaml
Playback settings add a global Speed slider (0.1–4.0, step 0.1, formatted as "F1x"). Rendering settings expand to include a Video scale selector ("fit"/"fill"). Image preview modal adds conditional per-wallpaper Volume and Speed sliders with "↺ Global" sync buttons when overrides are active.

Sequence Diagram

sequenceDiagram
    participant UI as UI / ViewModel
    participant PH as PlayerHelper
    participant IPC as mpv IPC Socket
    participant Wallpaper as Wallpaper Process

    UI->>PH: ApplyPlaylist(video_paths)
    PH->>PH: Start playlist observer task
    Note over PH: Persist paths to observer file

    loop Every mpv playlist-pos change
        Wallpaper->>IPC: playlist-pos event
        IPC->>PH: (IPC subscription)
        PH->>PH: ObservePathAsync()<br/>Read playlist-pos
        PH->>PH: ApplyOverridesForPath()<br/>Check .volume/.speed sidecars
        
        alt Override exists
            PH->>IPC: volume={override}
            IPC->>Wallpaper: Apply volume
            PH->>IPC: speed={override}
            IPC->>Wallpaper: Apply speed
        else Fallback to global
            PH->>IPC: volume={global}
            IPC->>Wallpaper: Apply global volume
            PH->>IPC: speed={global}
            IPC->>Wallpaper: Apply global speed
        end
    end

    UI->>PH: Stop()
    PH->>PH: StopPlaylistObserver()
    PH->>PH: ClearPlaylistObserverPaths()
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

  • PR #5: Modifies the same LibraryService.LoadAll() and PlayerHelper timer/teardown paths, directly related to sidecar handling and library metadata discovery.
  • PR #4: Introduces earlier timer daemon spawn logic in App.axaml.cs and foundational PlayerHelper playlist/timer behavior that this PR extends and builds upon.
  • PR #2: Overlaps in core areas (PlayerHelper, App.axaml.cs, AppSettings) with related playlist/timer and playback control changes.

Poem

🐰 Per-wallpaper dreams in sidecar files,
Speed and scale and volume dials,
Playlist hops with overrides neat,
Global sync makes the blend complete,
Override buttons, fresh as spring! 🎬

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 5.26% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and accurately reflects the main feature addition in this PR: per-video volume and speed overrides. It is concise, specific, and directly summarizes the primary change across multiple modified components.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (4)
src/livepaper/ViewModels/WallpaperCardViewModel.cs (1)

155-162: 💤 Low value

Slider initialization defaults differ between volume and speed.

Line 159 defaults _sliderVolume to 0 when no override exists, but line 161 correctly defaults _sliderSpeed to 1.0 (the global default). While UpdateGlobalVolume is called immediately after construction in MakeLibraryCard, initializing volume to 0 could cause brief visual inconsistency.

Consider consistent initialization

The constructor could accept global defaults as parameters, or defer slider initialization until UpdateGlobalVolume/UpdateGlobalSpeed are called. Alternatively, load settings here:

-        _sliderVolume = item.VolumeOverride ?? 0;
+        _sliderVolume = item.VolumeOverride ?? SettingsService.Load().Volume;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/livepaper/ViewModels/WallpaperCardViewModel.cs` around lines 155 - 162,
The _sliderVolume field is initialized to 0 while _sliderSpeed defaults to 1.0,
causing a brief UI inconsistency; update the constructor in
WallpaperCardViewModel so _sliderVolume uses the same sensible global default as
_sliderSpeed (pass in or read the global/default volume, or defer initialization
until UpdateGlobalVolume/UpdateGlobalSpeed is invoked). Locate the
initialization block setting _sliderVolume and _sliderSpeed (lines setting
_volumeOverride/_sliderVolume/_speedOverride/_sliderSpeed) and change
_sliderVolume to initialize from the global/default volume value (or remove its
immediate assignment and ensure MakeLibraryCard calls UpdateGlobalVolume after
construction to set it). Ensure references to MakeLibraryCard,
UpdateGlobalVolume, and UpdateGlobalSpeed are preserved and used to guarantee
consistent initial slider state.
src/livepaper/Helpers/LibraryService.cs (1)

115-115: 💤 Low value

CreationTime may be unreliable on Linux filesystems.

On ext4 and other Linux filesystems, FileInfo.CreationTime may return the epoch (1970-01-01) if birth time isn't tracked. Consider using LastWriteTime as a fallback when CreationTime equals DateTime.MinValue or Unix epoch.

Proposed fallback
-            var fi = new FileInfo(mp4);
+            var fi = new FileInfo(mp4);
+            var addedAt = fi.CreationTime;
+            if (addedAt.Year <= 1970) addedAt = fi.LastWriteTime;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/livepaper/Helpers/LibraryService.cs` at line 115, Replace the direct use
of fi.CreationTime for setting AddedAt with a robust fallback: check if
fi.CreationTime is DateTime.MinValue or equals the Unix epoch (new
DateTime(1970,1,1)) and if so use fi.LastWriteTime instead; update the
assignment where AddedAt = fi.CreationTime (in LibraryService.cs, inside the
code that processes FileInfo fi) to perform this conditional selection so
AddedAt always gets a reliable timestamp.
src/livepaper/Helpers/PlayerHelper.cs (1)

996-1010: ⚡ Quick win

Duplicated sidecar read helpers.

ReadVolumeOverride and ReadSpeedOverride are identical to the private helpers in LibraryService (lines 195-209). Consider making the LibraryService versions internal/public to avoid duplication.

Suggested approach

Make LibraryService.ReadVolumeOverride and LibraryService.ReadSpeedOverride public, then call them from PlayerHelper:

-    private static int? ReadVolumeOverride(string path)
-    {
-        var sidecar = Path.ChangeExtension(path, ".volume");
-        if (!File.Exists(sidecar)) return null;
-        try { return int.TryParse(File.ReadAllText(sidecar).Trim(), out int v) ? v : null; }
-        catch { return null; }
-    }
+    private static int? ReadVolumeOverride(string path) => LibraryService.ReadVolumeOverride(path);

And in LibraryService.cs:

-    private static int? ReadVolumeOverride(string mediaPath)
+    public static int? ReadVolumeOverride(string mediaPath)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/livepaper/Helpers/PlayerHelper.cs` around lines 996 - 1010, PlayerHelper
contains duplicated sidecar readers (ReadVolumeOverride and ReadSpeedOverride)
that are identical to helpers in LibraryService; remove these duplicates and
reuse the LibraryService implementations by changing the LibraryService methods
to an appropriate non-private visibility (make ReadVolumeOverride and
ReadSpeedOverride internal or public), then replace the local calls in
PlayerHelper with calls to LibraryService.ReadVolumeOverride(...) and
LibraryService.ReadSpeedOverride(...), ensuring the namespace/using and static
access are adjusted and the original parsing/exception behavior is preserved.
src/livepaper/Views/MainWindow.axaml (1)

1036-1044: Consider renaming SyncToGlobalCommand to SyncVolumeToGlobalCommand for naming consistency.

The SyncToGlobalCommand is correctly scoped to volume only and does not affect speed overrides. However, the asymmetric naming relative to SyncSpeedToGlobalCommand creates an unnecessary inconsistency. Renaming to SyncVolumeToGlobalCommand would make the pattern explicit and match the speed command's convention.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/livepaper/Views/MainWindow.axaml` around lines 1036 - 1044, Rename the
command currently named SyncToGlobalCommand to SyncVolumeToGlobalCommand to
match the existing SyncSpeedToGlobalCommand naming pattern: update the binding
on the button in MainWindow.axaml (PreviewCard.SyncToGlobalCommand) and rename
the corresponding property/command declaration and any references in the
PreviewCard viewmodel/class to PreviewCard.SyncVolumeToGlobalCommand so the
intent (volume-only) is explicit and consistent with SyncSpeedToGlobalCommand.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/livepaper/Helpers/LibraryService.cs`:
- Line 115: Replace the direct use of fi.CreationTime for setting AddedAt with a
robust fallback: check if fi.CreationTime is DateTime.MinValue or equals the
Unix epoch (new DateTime(1970,1,1)) and if so use fi.LastWriteTime instead;
update the assignment where AddedAt = fi.CreationTime (in LibraryService.cs,
inside the code that processes FileInfo fi) to perform this conditional
selection so AddedAt always gets a reliable timestamp.

In `@src/livepaper/Helpers/PlayerHelper.cs`:
- Around line 996-1010: PlayerHelper contains duplicated sidecar readers
(ReadVolumeOverride and ReadSpeedOverride) that are identical to helpers in
LibraryService; remove these duplicates and reuse the LibraryService
implementations by changing the LibraryService methods to an appropriate
non-private visibility (make ReadVolumeOverride and ReadSpeedOverride internal
or public), then replace the local calls in PlayerHelper with calls to
LibraryService.ReadVolumeOverride(...) and
LibraryService.ReadSpeedOverride(...), ensuring the namespace/using and static
access are adjusted and the original parsing/exception behavior is preserved.

In `@src/livepaper/ViewModels/WallpaperCardViewModel.cs`:
- Around line 155-162: The _sliderVolume field is initialized to 0 while
_sliderSpeed defaults to 1.0, causing a brief UI inconsistency; update the
constructor in WallpaperCardViewModel so _sliderVolume uses the same sensible
global default as _sliderSpeed (pass in or read the global/default volume, or
defer initialization until UpdateGlobalVolume/UpdateGlobalSpeed is invoked).
Locate the initialization block setting _sliderVolume and _sliderSpeed (lines
setting _volumeOverride/_sliderVolume/_speedOverride/_sliderSpeed) and change
_sliderVolume to initialize from the global/default volume value (or remove its
immediate assignment and ensure MakeLibraryCard calls UpdateGlobalVolume after
construction to set it). Ensure references to MakeLibraryCard,
UpdateGlobalVolume, and UpdateGlobalSpeed are preserved and used to guarantee
consistent initial slider state.

In `@src/livepaper/Views/MainWindow.axaml`:
- Around line 1036-1044: Rename the command currently named SyncToGlobalCommand
to SyncVolumeToGlobalCommand to match the existing SyncSpeedToGlobalCommand
naming pattern: update the binding on the button in MainWindow.axaml
(PreviewCard.SyncToGlobalCommand) and rename the corresponding property/command
declaration and any references in the PreviewCard viewmodel/class to
PreviewCard.SyncVolumeToGlobalCommand so the intent (volume-only) is explicit
and consistent with SyncSpeedToGlobalCommand.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 487ddce8-f0f3-464c-afd3-58f1a29c5ba8

📥 Commits

Reviewing files that changed from the base of the PR and between 84c9e01 and 5ee8ba0.

📒 Files selected for processing (9)
  • src/livepaper/App.axaml.cs
  • src/livepaper/Helpers/LibraryService.cs
  • src/livepaper/Helpers/PlayerHelper.cs
  • src/livepaper/Models/AppSettings.cs
  • src/livepaper/Models/LibraryItem.cs
  • src/livepaper/Models/WallpaperResult.cs
  • src/livepaper/ViewModels/MainWindowViewModel.cs
  • src/livepaper/ViewModels/WallpaperCardViewModel.cs
  • src/livepaper/Views/MainWindow.axaml

Kryxzort and others added 8 commits May 8, 2026 04:08
…eedOverride to LibraryService

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- LibraryItem gains VolumeOverride and SpeedOverride fields
- LibraryService.LoadAll reads .volume/.speed sidecars for mp4 and scene files
- PlayerHelper.SetSpeed added (mpv IPC)
- WallpaperCardViewModel: SliderVolume/SliderSpeed, override tracking, SyncToGlobal/SyncSpeedToGlobal commands, multi-select sync callbacks
- MainWindowViewModel: OnVolumeChanged broadcasts to all cards, SyncSelectedVolume/SyncSelectedSpeed helpers, MakeLibraryCard wires up callbacks
- Preview modal: volume slider + speed slider rows with per-wallpaper override and global reset button

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- PlayerHelper: add OnWallpaperChanged callback, ReadSpeedOverride, BakeVolumeOverride, BakeSpeedOverride
- SwitchToFile: bake overrides into mpv args on cold launch; apply via IPC on hot switch; fire OnWallpaperChanged for both video and scene paths
- MainWindowViewModel: register OnWallpaperChanged to track IsCurrentlyPlaying on library cards, enabling live IPC calls from sliders

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The playlist-pos observer ran only in the GUI process, so per-video
volume/speed overrides stopped firing when the app closed. Now the
timer daemon is also spawned for IsPlaylist sessions, and reconnects
the observer to the already-running mpvpaper socket. The post-shuffle
path order is saved to playlist_observer_paths.json so the pos→path
mapping stays correct for shuffled playlists.
Required by WallpaperCardViewModel which references these properties.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@Kryxzort Kryxzort force-pushed the pr/per-video-overrides branch from b009e35 to 8c0c047 Compare May 7, 2026 23:47
Kryxzort and others added 2 commits May 8, 2026 12:19
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Kryxzort added a commit to Kryxzort/livepaper-pro that referenced this pull request May 22, 2026
Merges sunwoo101#10. Adds per-wallpaper volume/speed overrides
with .volume/.speed sidecars, sliders in preview modal, daemon persistence
for native playlists, global speed slider, video scale setting, and real-time
IPC control.
Kryxzort added a commit to Kryxzort/livepaper-pro that referenced this pull request May 22, 2026
Both sides added documentation in the same regions. Preserved sidecar
table from PR sunwoo101#10 and soft-delete section from PR sunwoo101#11 in library.md.
Combined per-card delete description (PR sunwoo101#11) with preview modal line
(PR sunwoo101#10) in ui.md. No logic removed.
Kryxzort added a commit to Kryxzort/livepaper-pro that referenced this pull request May 22, 2026
LibraryService: adopt mediaFiles approach (mp4+png) from PR sunwoo101#12 while
preserving HasCrashed/IsWhitelisted/VolumeOverride/SpeedOverride fields
and AddedAt logic from PR sunwoo101#10.
LibraryItem: keep all fields from HEAD (IsScene, HasCrashed, IsWhitelisted,
VolumeOverride, SpeedOverride); PR sunwoo101#12 only knew WorkshopId and AddedAt.
MainWindowViewModel: merged _videoScale (PR sunwoo101#10) with card layout props
(PR sunwoo101#12); kept OnSpeedChanged handler from PR sunwoo101#10; adopted efficient
_currentlyPlayingCard tracking from PR sunwoo101#12; kept all settings change handlers.
WallpaperCardViewModel: preserved volume/speed override logic from PR sunwoo101#10
which PR sunwoo101#12 was unaware of.
Kryxzort added a commit to Kryxzort/livepaper-pro that referenced this pull request May 22, 2026
ui.md: placed GIF hover note before status bar line (both additions kept).
LibraryService: adopted PR sunwoo101#13 inline thumbnail call; preserved
ParseWorkshopId/ReadVolumeOverride/ReadSpeedOverride methods from PR sunwoo101#10
which PR sunwoo101#13 had removed.
LibraryItem: dropped PR sunwoo101#13 duplicate IsScene field (already declared);
kept HasCrashed/IsWhitelisted/VolumeOverride/SpeedOverride from PR sunwoo101#10.
MainWindowViewModel: added LoadStaticThumbnailAsync call alongside
volume/speed wiring in MakeLibraryCard.
WallpaperCardViewModel: merged imports (IO, Dispatcher from PR sunwoo101#13);
removed duplicate IsScene/WorkshopId props from HEAD; kept PR sunwoo101#10 field
init block alongside PR sunwoo101#13 GIF cache pre-population and new methods.
Kryxzort added a commit to Kryxzort/livepaper-pro that referenced this pull request May 22, 2026
ui.md: merged Browse tab — kept GIF hover note (PR sunwoo101#13) plus Auto-search
and Sort button lines (PR sunwoo101#14); merged Library tab — kept soft-delete/keyboard
shortcuts (PR sunwoo101#11) alongside workshop ID copy button (PR sunwoo101#14) in preview modal.
WallpaperResult: added AddedAt field from PR sunwoo101#14.
WallpaperEngineScraper: integrated scene detection and addedAt from PR sunwoo101#14;
added FindThumbnail sync helper (PR sunwoo101#14 had it, PR sunwoo101#13 replaced it with async);
kept AnimatedThumbnailUrl (PR sunwoo101#13) and added AddedAt to video results; added
sort cases 3-6; removed redundant post-loop query filter (already done inline).
WallpaperCardViewModel: kept all GIF animation code from PR sunwoo101#13 that PR sunwoo101#14
was unaware of; kept volume/speed fields from PR sunwoo101#10; PR sunwoo101#14 added WorkshopId
display only.
MainWindow.axaml: kept volume/speed slider rows at row 1/2 (PR sunwoo101#10) then
placed PR sunwoo101#14 title+WorkshopId header at row 3 (correct grid row offset).
Kryxzort added a commit to Kryxzort/livepaper-pro that referenced this pull request May 22, 2026
ui.md: kept soft-delete/keyboard shortcuts (PR sunwoo101#11) and added right-click
context menu lines (PR sunwoo101#15) to Library tab; kept GIF hover note (PR sunwoo101#13)
and added playlist right-click menu (PR sunwoo101#15); kept status bar line.
WallpaperCardViewModel: merged imports (System.Diagnostics from PR sunwoo101#15
alongside Avalonia.Threading from PR sunwoo101#13); kept GIF animation code (PR sunwoo101#13);
added IsLocalSource property (PR sunwoo101#15); removed ghost conflict marker.
MainWindowViewModel: kept volume/speed/GIF wiring (PR sunwoo101#10/PR sunwoo101#13) plus
added OnOpenSettings callback (PR sunwoo101#15) in MakeLibraryCard.
MainWindow.axaml: browse card and playlist card — kept PointerEntered/Exited
handlers (PR sunwoo101#13 GIF hover) AND added context menus (PR sunwoo101#15).
Kryxzort added a commit to Kryxzort/livepaper-pro that referenced this pull request May 22, 2026
session.md: kept VideoScale setting (PR sunwoo101#10) and added
AutoMuteOnlyIfMprisActive to auto-mute settings (PR sunwoo101#16).
AppSettings: kept ThumbnailAspect/CardSize/AutoPlayGifs/LibrarySortIndex
(PR sunwoo101#12/PR sunwoo101#13) and added AutoMuteOnlyIfMprisActive (PR sunwoo101#16).
Kryxzort added a commit to Kryxzort/livepaper-pro that referenced this pull request May 22, 2026
session.md: kept VideoScale and AutoMuteOnlyIfMprisActive (PR sunwoo101#10/PR sunwoo101#16);
added GlobalWaitForVideoEnd to global rotation settings (PR sunwoo101#17).
ui.md: kept GIF hover (PR sunwoo101#13), right-click menus (PR sunwoo101#15), Speed in Playback
(PR sunwoo101#10); added Wait for video to end to Playlist settings (PR sunwoo101#17).
PlayerHelper: dropped duplicate _observerCts field (ghost from previous merge);
added _waitForVideoEnd/_advanceOnVideoEnd/_waitingForVideoEnd/_waitCts (PR sunwoo101#17);
fixed ApplyPlaylist to use shuffled paths array and not double-shuffle via mpv flag;
added SetLoop and SetPlaylistShuffle IPC helpers (PR sunwoo101#17); resolved duplicate
StartPlaylistObserver/StopPlaylistObserver/ObservePathAsync/ApplyOverridesForPath
by keeping PR sunwoo101#17 insertions with HEAD's full ApplyOverridesForPath
(volume+speed overrides) and OnWallpaperChanged invoke; removed duplicate
HEAD methods.
MainWindowViewModel: kept _autoMuteOnlyIfMprisActive (PR sunwoo101#16); added
_speed=1.0 default (PR sunwoo101#17) to existing declaration; added _playlistSyncCts
(PR sunwoo101#17); dropped duplicate _currentlyPlayingCard; adopted PR sunwoo101#17 concise
OnWallpaperChanged + RefreshPlayingStatus; kept OnVolumeChanged/OnSpeedChanged
with per-card override logic (PR sunwoo101#10); kept LastSession with PR sunwoo101#17 new fields.
MainWindow.axaml: kept Appearance section (thumbnail/card/gif settings from
PR sunwoo101#12/PR sunwoo101#13) that PR sunwoo101#17 was unaware of.
Kryxzort added a commit to Kryxzort/livepaper-pro that referenced this pull request May 22, 2026
library.md: updated heading to include scene; added volume/speed sidecars
(PR sunwoo101#10) alongside scene-specific sidecars (PR sunwoo101#18); kept all sections.
session.md: merged WE settings — AllowScenes, LWE config (PR sunwoo101#18) alongside
ThumbnailAspect/CardSize/LibrarySortIndex (PR sunwoo101#12/PR sunwoo101#13).
ui.md: Browse tab kept GIF hover + auto-search + sort + SCENE badge;
Library tab kept full ItemsRepeater grid + all features + SCENE/crash badges;
Settings kept Video scale + WE scene support + Appearance section.
README: added both playerctl and linux-wallpaperengine to optional deps.
LibraryItem: added CopiedSceneDir (PR sunwoo101#18) + kept VolumeOverride/SpeedOverride.
AppSettings: kept Speed with clamping; kept PlaylistWaitForVideoEnd; dropped
duplicate LibrarySortIndex from PR sunwoo101#18.
WallpaperResult: kept AddedAt (PR sunwoo101#14).
livepaper.csproj: kept ItemsRepeater + AnimatedImage packages.
AudioMonitor: kept async IsAnyMprisPlayerActiveAsync + better playerctl args.
DownloadHelper: kept smart thumbnail extension detection.
LibraryService: merged scene-copy Trash/Restore/Delete + kept volume/speed.
WallpaperEngineScraper: merged all, kept AnimatedThumbnailUrl + AddedAt.
WallpaperEngineService: kept SortIndex/SupportsSorting.
PlayerHelper: merged 29 conflicts — kept wait/advance/playlist observer from
PR sunwoo101#17 + added full scene/LWE support from PR sunwoo101#18; removed duplicates.
MainWindowViewModel: merged 25 conflicts — kept all playlist wait/advance
proxies from PR sunwoo101#17 + added scene-aware methods from PR sunwoo101#18.
WallpaperCardViewModel: kept full GIF+volume/speed code + added scene-aware
fields and LoadDurationAsync from PR sunwoo101#18.
MainWindow.axaml: kept GIF animation, volume/speed sliders; added SCENE badge
and crash warning panel (adjusting grid row offsets).
MainWindow.axaml.cs: kept HEAD's existing TextBox guard structure.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant