Skip to content

feat(merge): sort files by name or date before merging - #1018

Merged
KnifeLemon merged 5 commits into
KnifeLemon:mainfrom
amanvir-singh:feature/merge-sort-order
Nov 3, 2026
Merged

KnifeLemon merged 5 commits into
KnifeLemon:mainfrom
amanvir-singh:feature/merge-sort-order

Conversation

@amanvir-singh

Copy link
Copy Markdown
Contributor

What does this change?

Lets you sort files by name or date before they merge. Today the merge order window always opens in name order, so putting files in date order means moving them one row at a time. On the command line, a folder or wildcard merges in whatever order the file system lists it.

  • Merge order window: a "Sort by" list with Name (A to Z, Z to A), Date modified and Date created (oldest or newest first). Each row now shows its date and time, and moving a row by hand switches the list to "Custom order". It still opens in name order.
  • filee convert --sort: name, name-desc, modified, modified-desc, created or created-desc. Without the flag, the order is unchanged. filee watch refuses the flag rather than ignoring it.
  • Both use one new sorter, Filee.Core/Platform/FileSorter.cs. Files without a known date, such as browser drops not saved yet, come last in both directions.

The window applies to every merge it already handles (PDF, video, audio, images), so they all get the sort list.

Overlap with #928: related to #927, but it doesn't replace #928. #928 adds no sorting, but it edits the same three merge window files (MergeOrderViewModel.cs, MergeOrderWindow.axaml, MergeOrderWindow.axaml.cs), so whichever merges second will need a rebase. I'm happy to rebase this one if #928 goes first.

Type of change

  • Bug fix
  • New feature or improvement
  • New format or engine
  • Translation (the new strings, in all 19 language files)
  • Documentation
  • Build, CI or dependencies

How was it tested?

  • dotnet format --verify-no-changes
  • dotnet test: full solution run on Windows 11. Core, CLI, Setup and App pass; 7 tests in other projects fail, and the same 7 fail on unchanged main (328225c) on this machine:
    • TrashTests.Windows_recycles_and_never_deletes_for_good
    • SizeLimitTests.A_video_too_long_for_its_percentage_limit_is_refused
    • ClipTests.The_waveform_and_silences_come_from_the_first_sound_ffmpeg_can_decode
    • 4 MediaTests about sound ffmpeg cannot decode
  • Tried it in the app: not done by hand. The new MergeOrderTests case drives the real window headlessly from the donut through a real merge, then checks the page order of the merged PDF. CliTests does the same for --sort.

The new tests were checked by mutation: 7 deliberate bugs in the sorter, the view model and the CLI each made them fail.

Not tested: Linux and macOS. Linux can't set a file's creation time, so the test for that date only checks it on Windows, and what "Date created" shows there depends on the file system.

Screenshots (UI changes)

Checklist

  • New UI strings are in all src/Filee.App/Assets/i18n/*.json files (not reviewed by native speakers, so corrections are welcome)
  • New third-party code or binaries are listed in THIRD-PARTY-NOTICES.md (none added)
  • The PR does one thing (unrelated changes go in a separate PR)

@github-actions github-actions Bot added the feature New features label Nov 2, 2026
@amanvir-singh

Copy link
Copy Markdown
Contributor Author
merge-order-en merge-order-ar merge-images-de-dark

@KnifeLemon KnifeLemon left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Thanks, @amanvir-singh. This is a clean addition:

  • one FileSorter shared by the merge window and filee convert --sort;
  • the existing natural order for names (file2 before file10);
  • UTC dates, with ties broken by name, and files without a date last;
  • nothing persisted, so no settings step;
  • all 19 language files only gain lines, translated;
  • tests build their files in code.

I merged it with current main (clean), built it, and ran the FileSorter, CLI and merge-window tests. I've also approved the CI run, since it was waiting for a first-time contributor.

One thing to decide before merging: --sort name with --recursive

FileSorter compares Path.GetFileName first (FileSorter.cs:44, 55, 61). With

filee convert D:\project -r --preset merge-pdf --sort name

files from different subfolders are interleaved by their file names: sub2\a.pdf, sub1\b.pdf, c.pdf, and so on. #966 asks for the opposite, Explorer order: folder by folder. --sort name is a public CLI option, so its meaning should be settled now.

Please sort by the path relative to the input folder, naturally, so each folder's files stay together, and add a test for -r with --sort name. The merge window can keep sorting by file name, since its files usually come from one folder.

Small, optional

  • Fewer file reads: Cli.cs:74 calls FileStamp.Read in each key selector, so each file is read 3–4 times. Read the stamps once (files.Select(FileStamp.Read).ToList()), then sort.
  • Dates on the UI thread: MergeOrderViewModel reads every file's dates in its constructor. That's fine on a local disk, but slow for many files on a network share.
  • Window size: the image-merge window's height grows to 690, but its MinHeight stays 540, so the list loses room at the minimum size.
  • Linux "Date created": .NET returns the earlier of ctime and mtime when there's no birth time, so this sort quietly uses another date there. A line in the help text is enough.

Heads-up: #928

#928 (cards in the merge window) changes the same two files, MergeOrderViewModel.cs and MergeOrderWindow.axaml. Yours is smaller and nearly ready, so it can go first, and #928 will adapt to it.

@amanvir-singh

Copy link
Copy Markdown
Contributor Author

Thanks for the review. --sort in the CLI now sorts by path, naturally, one folder level at a time, so each folder's files stay together, with a test for -r. The merge window still sorts by file name.

Two choices to check:

Also done: file stamps are read once, the image window's MinHeight is 590, and the help text covers the Linux created date. The CI failure was our test: on Linux SetCreationTimeUtc changes the modified date, so I fixed the order and made the merge window's creation-date checks Windows-only. I left the date reads on the UI thread, since it only matters for many files on a network share.

@KnifeLemon KnifeLemon left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Thanks, @amanvir-singh. --sort name now keeps each folder's files together, with sub folders first as in Explorer, and the -r test shows it (sub2 before sub10, deep before its folder's files). The stamps are read once, the window's minimum height is fixed, and the help explains Linux creation dates. Comparing full paths is fine: for one input folder it's the same as relative paths.

CI is green. Merging.

@KnifeLemon
KnifeLemon merged commit c187f1a into KnifeLemon:main Nov 3, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature New features

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants