Skip to content

Commit 0e26133

Browse files
Organizer-first automation overhaul with menu bar targeting and terminology cleanup.
This ships per-automation sort selection in the menu bar, stabilizes Settings launch behavior, and aligns app/help copy around watched folders while introducing the new automation/routing service updates for the v1.3.0 release. Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 23c2a39 commit 0e26133

58 files changed

Lines changed: 6041 additions & 22367 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Binky.xcodeproj/project.pbxproj

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,13 @@
6161
XTBLD00000000000000002 /* DownloadSortClassificationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = XTREF00000000000000002 /* DownloadSortClassificationTests.swift */; };
6262
WFTSTBLD000000000000001 /* WhereFromsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = WFTSTREF000000000000001 /* WhereFromsTests.swift */; };
6363
FTTST200001BK000001 /* FinderTagCompositionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FTTST100001FR000001 /* FinderTagCompositionTests.swift */; };
64+
ATOBKB00000000000000001 /* AutomationsOverhaulTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = ATOBKF00000000000000001 /* AutomationsOverhaulTests.swift */; };
6465
SPTKR200001BK000002 /* SortProgressTracker.swift in Sources */ = {isa = PBXBuildFile; fileRef = SPTKR100001FR000001 /* SortProgressTracker.swift */; };
6566
BBAR200001BK000002 /* BinkySortProgressBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBAR100001FR000001 /* BinkySortProgressBar.swift */; };
6667
CURS200001BK000002 /* CurrentlySortingSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = CURS100001FR000001 /* CurrentlySortingSheet.swift */; };
6768
SRTVC00001BR000001 /* SortVoiceCopy.swift in Sources */ = {isa = PBXBuildFile; fileRef = SRTVC10001FR000001 /* SortVoiceCopy.swift */; };
69+
ARCHXTR200001BK000001 /* ArchiveExtractionService.swift in Sources */ = {isa = PBXBuildFile; fileRef = ARCHXTR100001FR000001 /* ArchiveExtractionService.swift */; };
70+
DMGXTR200001BK000001 /* DMGInstallerService.swift in Sources */ = {isa = PBXBuildFile; fileRef = DMGXTR100001FR000001 /* DMGInstallerService.swift */; };
6871
RVTRI00001BR000001 /* ReviewFolderTriageSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = RVTRI10001FR000001 /* ReviewFolderTriageSheet.swift */; };
6972
/* End PBXBuildFile section */
7073

@@ -106,6 +109,8 @@
106109
SREM0010000000000000001 /* SortRoutingModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SortRoutingModels.swift; sourceTree = "<group>"; };
107110
SREV0010000000000000001 /* SortRulesEvaluator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SortRulesEvaluator.swift; sourceTree = "<group>"; };
108111
SRTVC10001FR000001 /* SortVoiceCopy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SortVoiceCopy.swift; sourceTree = "<group>"; };
112+
ARCHXTR100001FR000001 /* ArchiveExtractionService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArchiveExtractionService.swift; sourceTree = "<group>"; };
113+
DMGXTR100001FR000001 /* DMGInstallerService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DMGInstallerService.swift; sourceTree = "<group>"; };
109114
RVTRI10001FR000001 /* ReviewFolderTriageSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReviewFolderTriageSheet.swift; sourceTree = "<group>"; };
110115
SPSH0010000000000000001 /* SortPreviewSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SortPreviewSheet.swift; sourceTree = "<group>"; };
111116
E71A34AFC5CA41FDACAEE19D /* Preview Content/Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Content/Preview Assets.xcassets"; sourceTree = "<group>"; };
@@ -152,6 +157,7 @@
152157
XTREF00000000000000002 /* DownloadSortClassificationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DownloadSortClassificationTests.swift; sourceTree = "<group>"; };
153158
WFTSTREF000000000000001 /* WhereFromsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WhereFromsTests.swift; sourceTree = "<group>"; };
154159
FTTST100001FR000001 /* FinderTagCompositionTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FinderTagCompositionTests.swift; sourceTree = "<group>"; };
160+
ATOBKF00000000000000001 /* AutomationsOverhaulTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutomationsOverhaulTests.swift; sourceTree = "<group>"; };
155161
SPTKR100001FR000001 /* SortProgressTracker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SortProgressTracker.swift; sourceTree = "<group>"; };
156162
BBAR100001FR000001 /* BinkySortProgressBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BinkySortProgressBar.swift; sourceTree = "<group>"; };
157163
CURS100001FR000001 /* CurrentlySortingSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CurrentlySortingSheet.swift; sourceTree = "<group>"; };
@@ -306,6 +312,8 @@
306312
SREV0010000000000000001 /* SortRulesEvaluator.swift */,
307313
SRTVC10001FR000001 /* SortVoiceCopy.swift */,
308314
DST10009900000000000001 /* DownloadSortServices.swift */,
315+
ARCHXTR100001FR000001 /* ArchiveExtractionService.swift */,
316+
DMGXTR100001FR000001 /* DMGInstallerService.swift */,
309317
FTCMP100001FR000001 /* FinderTagComposition.swift */,
310318
DNKBRG1000010000000001 /* DinkyBridge.swift */,
311319
NTEXP102000000000000001 /* NewTagExpiry.swift */,
@@ -321,6 +329,7 @@
321329
XTREF00000000000000002 /* DownloadSortClassificationTests.swift */,
322330
WFTSTREF000000000000001 /* WhereFromsTests.swift */,
323331
FTTST100001FR000001 /* FinderTagCompositionTests.swift */,
332+
ATOBKF00000000000000001 /* AutomationsOverhaulTests.swift */,
324333
);
325334
path = BinkyTests;
326335
sourceTree = "<group>";
@@ -460,6 +469,8 @@
460469
BMBC0020000000000000001 /* BinkyMenuBarController.swift in Sources */,
461470
SPTKR200001BK000002 /* SortProgressTracker.swift in Sources */,
462471
DST00009900000000000001 /* DownloadSortServices.swift in Sources */,
472+
ARCHXTR200001BK000001 /* ArchiveExtractionService.swift in Sources */,
473+
DMGXTR200001BK000001 /* DMGInstallerService.swift in Sources */,
463474
FTCMP200001BK000001 /* FinderTagComposition.swift in Sources */,
464475
DNKBLD1000010000000001 /* DinkyBridge.swift in Sources */,
465476
SREM0020000000000000001 /* SortRoutingModels.swift in Sources */,
@@ -492,6 +503,7 @@
492503
XTBLD00000000000000002 /* DownloadSortClassificationTests.swift in Sources */,
493504
WFTSTBLD000000000000001 /* WhereFromsTests.swift in Sources */,
494505
FTTST200001BK000001 /* FinderTagCompositionTests.swift in Sources */,
506+
ATOBKB00000000000000001 /* AutomationsOverhaulTests.swift in Sources */,
495507
);
496508
runOnlyForDeploymentPostprocessing = 0;
497509
};
@@ -657,6 +669,7 @@
657669
isa = XCBuildConfiguration;
658670
buildSettings = {
659671
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
672+
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
660673
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = YES;
661674
CODE_SIGN_ENTITLEMENTS = Binky/Binky.entitlements;
662675
CODE_SIGN_STYLE = Automatic;
@@ -687,6 +700,7 @@
687700
isa = XCBuildConfiguration;
688701
buildSettings = {
689702
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
703+
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
690704
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = YES;
691705
CODE_SIGN_ENTITLEMENTS = Binky/Binky.entitlements;
692706
CODE_SIGN_STYLE = Automatic;

Binky/AppDelegate.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ final class AppDelegate: NSObject, NSApplicationDelegate {
7676
// MARK: - Helpers
7777

7878
/// Accepts files and folders. Folders are expanded into their top-level files by
79-
/// ``OrganizerViewModel/sortIncomingFiles(_:prefs:)`` and treated as their own ad-hoc inbox.
79+
/// ``OrganizerViewModel/sortIncomingFiles(_:prefs:)`` and treated as their own ad-hoc watch root.
8080
private func acceptedURLs(from urls: [URL]) -> [URL] {
8181
urls.filter { url in
8282
FileManager.default.fileExists(atPath: url.path)

Binky/BinkyApp.swift

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,13 +104,22 @@ private struct LastSortSummaryCommands: View {
104104
private struct BinkyShortcutCommands: View {
105105
@ObservedObject var prefs: BinkyPreferences
106106

107+
private var sortNowMenuTitle: String {
108+
let enabledCount = prefs.savedPresets.filter {
109+
$0.isEnabled && !$0.watchFolderPath.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty
110+
}.count
111+
return enabledCount > 1
112+
? String(localized: "Sort All", comment: "File menu: run sort across every enabled automation.")
113+
: String(localized: "Sort Now", comment: "File menu: run an immediate sort for the watched folder.")
114+
}
115+
107116
var body: some View {
108117
Button(String(localized: "Open Files…", comment: "File menu: open file picker.")) {
109118
NotificationCenter.default.post(name: .binkyOpenPanel, object: nil)
110119
}
111120
.keyboardShortcut(prefs.shortcut(for: .openFiles).swiftUIKeyboardShortcut)
112121

113-
Button(String(localized: "Sort Now", comment: "File menu: run an immediate sort for the watched folder.")) {
122+
Button(sortNowMenuTitle) {
114123
NotificationCenter.default.post(name: .binkyStartSort, object: nil)
115124
}
116125
.keyboardShortcut(prefs.shortcut(for: .sortNow).swiftUIKeyboardShortcut)

Binky/ContentView.swift

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,37 @@ struct ContentView: View {
5656
}
5757
.onReceive(NotificationCenter.default.publisher(for: .binkyStartSort)) { _ in
5858
Task {
59-
await vm.runInteractiveDownloadsSweep(prefs: prefs)
59+
let enabled = prefs.savedPresets.filter {
60+
$0.isEnabled && !$0.watchFolderPath.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty
61+
}
62+
if enabled.count > 1 {
63+
await vm.runInteractiveSweepAllAutomations(prefs: prefs)
64+
} else {
65+
await vm.runInteractiveDownloadsSweep(prefs: prefs)
66+
}
67+
}
68+
}
69+
.onReceive(NotificationCenter.default.publisher(for: .binkyStartSortForAutomation)) { note in
70+
Task {
71+
let fallback: () async -> Void = {
72+
let enabled = prefs.savedPresets.filter {
73+
$0.isEnabled && !$0.watchFolderPath.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty
74+
}
75+
if enabled.count > 1 {
76+
await vm.runInteractiveSweepAllAutomations(prefs: prefs)
77+
} else {
78+
await vm.runInteractiveDownloadsSweep(prefs: prefs)
79+
}
80+
}
81+
guard let id = note.userInfo?[BinkyNotificationUserInfoKey.sortAutomationPresetID] as? UUID else {
82+
await fallback()
83+
return
84+
}
85+
guard let preset = prefs.savedPresets.first(where: { $0.id == id }) else {
86+
await fallback()
87+
return
88+
}
89+
await vm.runInteractiveSweep(preset: preset, prefs: prefs)
6090
}
6191
}
6292
.onReceive(NotificationCenter.default.publisher(for: .binkyShowLastBatchSummary)) { _ in

Binky/Intents/SortFilesWithBinkyIntent.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import AppIntents
22
import AppKit
33
import Foundation
44

5-
/// Shortcuts / Siri integration: hand files to the running app for inbox sorting.
5+
/// Shortcuts / Siri integration: hand files to the running app for folder sorting.
66
struct SortFilesWithBinkyIntent: AppIntent {
77
static var title: LocalizedStringResource = LocalizedStringResource(
88
"Sort Files",

0 commit comments

Comments
 (0)