Skip to content

Effect parameter titles#69

Merged
meesoft merged 13 commits intomainfrom
features/ParamTitles
Feb 16, 2026
Merged

Effect parameter titles#69
meesoft merged 13 commits intomainfrom
features/ParamTitles

Conversation

@meesoft
Copy link
Owner

@meesoft meesoft commented Feb 1, 2026

Summary by CodeRabbit

  • New Features

    • Effects now accept parameterized inputs with descriptive labels and defaults.
    • Scale input is an editable dropdown with common presets (1280×720, 1080×1080, 1920×1080, 2560×1440, 3840×2160).
    • Time-slice directions and video format pickers show richer item templates.
    • New video output/combine/registration modes exposed in UI.
  • Tests

    • Added automated tests covering video transform scenarios.
  • Chores

    • Updated MSTest framework to 4.1.0

@meesoft meesoft marked this pull request as ready for review February 2, 2026 21:50
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 2, 2026

Walkthrough

Reworked effect parameter handling to use a three-element tuple (template, label, default), replacing EffectStrength with EffectParameter and EffectParameterText; updated UI bindings, process-arg construction, scale/zoom logic, and added helper combo-box item types and tests.

Changes

Cohort / File(s) Summary
Core Parameter Refactoring
PhotoLocator/VideoTransformCommands.cs
Replaced EffectStrength with EffectParameter and EffectParameterText; SelectedEffect now recognizes ValueTuple<string,string,string>; effects collection updated to 3-tuples (template, label, default); UpdateProcessArgs uses EffectParameter; added ShowSetupUserInterface and adjusted ProcessSelected, and refined scale/zoom/stabilize branching.
UI Layer Updates
PhotoLocator/VideoTransformWindow.xaml
Replaced Scale TextBox with editable ComboBox; Effects area now uses a ComboBox plus conditional parameter label (EffectParameterText) and input (EffectParameter); added ItemTemplates for TimeSliceDirections and VideoFormats; label text changed to “ffmpeg process arguments:”.
Helper Types
PhotoLocator/Helpers/ImageComboBoxItem.cs, PhotoLocator/Helpers/TextComboBoxItem.cs
Added ImageComboBoxItem (Image, Text, Tag) and TextComboBoxItem (required Text, Tag) for richer ComboBox items and display.
New Types
PhotoLocator/VideoTransformTypes.cs
Added enums OutputMode, CombineFramesMode, RegistrationMode and a ParameterizedFilter record struct for typed effect/configuration representations.
Tests: New & Adjusted
PhotoLocatorTest/VideoTransformCommandsTest.cs, PhotoLocatorTest/Metadata/ExifToolTest.cs, PhotoLocatorTest/Gps/GpsTraceTest.cs, PhotoLocatorTest/PictureFileFormats/JpegliEncoderTest.cs
Added VideoTransformCommandsTest with tests covering all effects, stabilization, and combine/fade; made ExifToolPath public; added Ignore reason to a test; adjusted jpegli encoder path.
Project & Config
PhotoLocatorTest/PhotoLocatorTest.csproj, .editorconfig
Updated MSTest packages from 4.0.2 → 4.1.0; silenced IDE0017 in .editorconfig.

Sequence Diagram(s)

mermaid
sequenceDiagram
participant UI as "VideoTransformWindow (UI)\nComboBoxes / Labels"
participant VM as "VideoTransformCommands\n(ViewModel/Controller)"
participant MV as "IMainViewModel\n(Settings, SelectedItems)"
participant Proc as "Process Runner\n(ffmpeg / external)"
participant FS as "FileSystem"

rect rgba(100,150,240,0.5)
UI->>VM: User selects effect (3-tuple) + enters parameter
VM->>VM: SelectedEffect sets EffectParameterText & EffectParameter
end

rect rgba(180,200,120,0.5)
UI->>VM: Requests ProcessSelected (with outFileName via ShowSetupUserInterface)
VM->>MV: Read settings (ffmpeg path, selected items)
MV-->>VM: return settings & selection
VM->>FS: resolve output directory (first selected item dir)
VM->>Proc: RunProcessWithProgressBarAsync(ffmpeg args built using EffectParameter)
Proc-->>VM: process completion
VM->>FS: save/move output file
VM->>UI: notify completion
end

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • Video effects and cropping #26 — Refactors VideoTransformCommands and VideoTransformWindow for parameterized effects and UI bindings; strong overlap with effect/tag tuple changes.
  • Log view #22 — Modifies UpdateProcessArgs/ProcessSelected in VideoTransformCommands.cs; related to parameter and ffmpeg-arg changes.
  • Reverse video effect #54 — Alters effect list and SelectedEffect handling (tuple/parameter expansion) in VideoTransformCommands.cs; directly related to this diff.
🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Merge Conflict Detection ⚠️ Warning ❌ Merge conflicts detected (11 files):

⚔️ .editorconfig (content)
⚔️ PhotoLocator/Metadata/ExifHandler.cs (content)
⚔️ PhotoLocator/Metadata/MaskBasedNaming.cs (content)
⚔️ PhotoLocator/RenameWindow.xaml (content)
⚔️ PhotoLocator/VideoTransformCommands.cs (content)
⚔️ PhotoLocator/VideoTransformWindow.xaml (content)
⚔️ PhotoLocatorTest/Gps/GpsTraceTest.cs (content)
⚔️ PhotoLocatorTest/Metadata/ExifToolTest.cs (content)
⚔️ PhotoLocatorTest/Metadata/MaskBasedNamingTest.cs (content)
⚔️ PhotoLocatorTest/PhotoLocatorTest.csproj (content)
⚔️ PhotoLocatorTest/PictureFileFormats/JpegliEncoderTest.cs (content)

These conflicts must be resolved before merging into main.
Resolve conflicts locally and push changes to this branch.
Title check ❓ Inconclusive The title 'Effect parameter titles' is related to the main changes but is vague and somewhat generic, failing to capture the core objective of the refactoring. Consider a more descriptive title such as 'Refactor effect parameters with titles and default values' or 'Add parameterized effect controls with labels' to better convey the scope of changes.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

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

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch features/ParamTitles
⚔️ Resolve merge conflicts (beta)
  • Auto-commit resolved conflicts to branch features/ParamTitles
  • Create stacked PR with resolved conflicts
  • Post resolved changes as copyable diffs in a comment

Tip

Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord.


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.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@PhotoLocatorTest/VideoTransformCommandsTest.cs`:
- Line 29: The field/local variable executeTask is declared as a non-nullable
Task and assigned null, causing a nullable warning; update its declaration to be
nullable (use Task? executeTask = null) in VideoTransformCommandsTest (the
executeTask variable in the test method) so the type matches the null assignment
and suppresses the compiler warning.
- Line 39: The mock setup for mainViewModelMoq returns null for the non-nullable
IAsyncDisposable returned by PauseFileSystemWatcher, which causes a
NullReferenceException when the production code does "await using var pause =
_mainViewModel.PauseFileSystemWatcher();"; fix by updating the Setup for
PauseFileSystemWatcher to return a valid IAsyncDisposable (use the existing
ActionDisposable helper or a simple no-op IAsyncDisposable) so the await using
has a concrete disposable instance instead of null.
🧹 Nitpick comments (2)
PhotoLocator/VideoTransformCommands.cs (1)

985-985: Directory.SetCurrentDirectory is a process-wide side effect.

This mutates the current working directory for the entire process. In a desktop app this may be acceptable, but it can cause subtle bugs if any concurrent or background operation relies on relative paths. Consider using absolute paths throughout instead of changing the CWD, or at minimum restoring the original directory afterward.

PhotoLocatorTest/VideoTransformCommandsTest.cs (1)

13-14: Unused using static directives.

These two using static imports (System.Net.Mime.MediaTypeNames and System.Windows.Forms.VisualStyles.VisualStyleElement.Tab) appear to be leftover and are not referenced in the test.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@PhotoLocator/VideoTransformCommands.cs`:
- Around line 701-709: SelectedEffect.Tag can be a ValueTuple (effectTuple)
where EffectParameter may be null/empty and produce malformed FFmpeg filters;
before calling string.Format use a validated parameter: if EffectParameter is
null or empty, substitute the tuple's default parameter (e.g.,
effectTuple.Item2) (or another appropriate default from the tuple) and then call
string.Format(CultureInfo.InvariantCulture, effectTuple.Item1, chosenParameter,
IsScaleChecked ? ScaleTo.Replace(':','x') : "1920x1080",
string.IsNullOrEmpty(FrameRate) ? "30" : FrameRate) so the formatted filter
never contains an empty parameter placeholder.
🧹 Nitpick comments (2)
PhotoLocator/VideoTransformCommands.cs (2)

237-249: Consider using a named type instead of ValueTuple<string, string, string>.

The 3-tuple (template, label, default) is used throughout but accessed as Item1, Item2, Item3 in multiple places (lines 261-265, 705-706), making it easy to mix up fields. A small record like record EffectDefinition(string Template, string Label, string Default) would improve readability and prevent accidental field transposition.


983-983: Directory.SetCurrentDirectory is process-global and not thread-safe.

This mutates global process state from within an async callback. If any other async operation (or UI code) relies on or changes the current directory concurrently, this can cause subtle bugs. In a desktop app with sequential operations this is likely acceptable, but consider passing the directory explicitly to operations that need it, or saving/restoring the original directory.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@PhotoLocatorTest/VideoTransformCommandsTest.cs`:
- Line 14: The TestContext property in VideoTransformCommandsTest.cs will raise
CS8618 because MSTest injects it at runtime but the compiler thinks it may be
null; update the property declaration for TestContext to either be nullable
(TestContext?) or suppress the warning by initializing it with the
null-forgiving operator (TestContext = null!) so the compiler stops emitting the
nullable warning for the TestContext property.
🧹 Nitpick comments (4)
PhotoLocatorTest/AssemblyInfo.cs (1)

3-3: Disabling parallelization globally is a blunt fix for the Directory.SetCurrentDirectory issue.

The new VideoTransformCommandsTest calls Directory.SetCurrentDirectory(_testDir) which mutates process-global state, making parallel execution unsafe. However, disabling parallelization assembly-wide penalizes all tests. Consider using [DoNotParallelize] only on the VideoTransformCommandsTest class, or better yet, eliminating the SetCurrentDirectory calls in the tests if the underlying production code can be adjusted.

PhotoLocator/VideoTransformEnums.cs (1)

27-30: Remove the empty body from the record struct.

The positional record struct already generates all needed members. The empty braces are unnecessary.

Proposed fix
-internal record struct ParameterizedFilter(string Filter, string ParameterText, string DefaultValue)
-{
-
-}
+internal record struct ParameterizedFilter(string Filter, string ParameterText, string DefaultValue);
PhotoLocatorTest/VideoTransformCommandsTest.cs (1)

55-75: Directory.SetCurrentDirectory mutates process-global state.

Line 72 (and lines 96, 119) reset the current directory after each test. This is fragile—if the test throws before reaching SetCurrentDirectory, the directory stays changed, potentially breaking subsequent tests. This is also the root cause for needing [DoNotParallelize] at assembly level.

Consider having VideoTransformCommands accept a working directory parameter instead, or wrapping the cleanup in a finally block / [TestCleanup] method.

PhotoLocator/VideoTransformWindow.xaml (1)

60-66: The ItemTemplate with {Binding} is redundant for text-only display.

WPF's ComboBox already calls ToString() on each item by default. Since TextComboBoxItem.ToString() returns Text, this template just replicates the default behavior. The same applies to the VideoFormats ComboBox at lines 159–163. You can simplify by removing both templates, unless they're intentionally reserved for future richer rendering.

{
string _testDir;

public TestContext TestContext { get; set; }
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

TestContext will produce a nullable warning (CS8618).

MSTest injects the value at runtime, but the compiler doesn't know that. Suppress with = null! or declare as TestContext?.

Proposed fix
-    public TestContext TestContext { get; set; }
+    public TestContext TestContext { get; set; } = null!;
🤖 Prompt for AI Agents
In `@PhotoLocatorTest/VideoTransformCommandsTest.cs` at line 14, The TestContext
property in VideoTransformCommandsTest.cs will raise CS8618 because MSTest
injects it at runtime but the compiler thinks it may be null; update the
property declaration for TestContext to either be nullable (TestContext?) or
suppress the warning by initializing it with the null-forgiving operator
(TestContext = null!) so the compiler stops emitting the nullable warning for
the TestContext property.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@PhotoLocatorTest/VideoTransformCommandsTest.cs`:
- Around line 33-45: The mock for IMainViewModel in SetupMainViewModelMoq is
missing a setup for PauseFileSystemWatcher, causing null references when
VideoTransformCommands awaits using var pause =
_mainViewModel.PauseFileSystemWatcher(); update SetupMainViewModelMoq to Setup(m
=> m.PauseFileSystemWatcher()) and have it return a no-op IAsyncDisposable
(e.g., an AsyncNoOpDisposable instance) or
Task.CompletedTask.AsAsyncDisposable() so tests like
ProcessSelected_ShouldHandleAllEffects, ProcessSelected_ShouldStabilize and
CombineFade_ShouldCombineVideos receive a valid disposable.
🧹 Nitpick comments (2)
PhotoLocatorTest/VideoTransformCommandsTest.cs (2)

52-56: Consider extracting repeated mock setup into the helper.

The RunProcessWithProgressBarAsync mock setup with processTask capture is duplicated across all three tests (lines 52–56, 85–89, 108–112). Moving it into SetupMainViewModelMoq (or a second helper) would reduce boilerplate.


97-97: Nit: missing space before parenthesis in await.

await(processTask on lines 97 and 119 — add a space for consistency with line 74 which has await (processTask.

-        await(processTask ?? throw new Exception("Process task not set"));
+        await (processTask ?? throw new Exception("Process task not set"));

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
PhotoLocatorTest/VideoTransformCommandsTest.cs (2)

54-79: Test does not clean up generated output files.

Each effect iteration creates an output file that persists after the test run. Consider adding a [TestCleanup] method or wrapping deletions to avoid stale artifacts influencing subsequent runs. This is a minor hygiene concern for test reliability.


59-78: Test loop stops on first failure — consider whether that's intentional.

If any effect fails (throws during await), the remaining effects are never tested. If the goal is to verify all effects independently, consider using [DynamicData] or [DataRow] to parameterize each effect as a separate test case. If fail-fast is intentional, this is fine as-is.

@meesoft meesoft merged commit df6a649 into main Feb 16, 2026
5 checks passed
@meesoft meesoft deleted the features/ParamTitles branch February 16, 2026 19:11
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