diff --git a/DynamicIsland/Localizable.xcstrings b/DynamicIsland/Localizable.xcstrings index 90e667c..d625982 100644 --- a/DynamicIsland/Localizable.xcstrings +++ b/DynamicIsland/Localizable.xcstrings @@ -5062,6 +5062,10 @@ } } }, + "Choose which service to use when sharing files from the shelf. Drag files onto the shelf or click the shelf button to pick files." : { + "comment" : "A footer description under the Quick Share section of the Shelf settings.", + "isCommentAutoGenerated" : true + }, "Choose which system controls should display custom OSD windows." : { "comment" : "A footer description for the \"Controls\" section of the Custom OSD settings view.", "isCommentAutoGenerated" : true @@ -5842,6 +5846,10 @@ "comment" : "A tooltip for a button that copies the link of a reminder event to the clipboard.", "isCommentAutoGenerated" : true }, + "Copy items on drag" : { + "comment" : "A toggle that allows users to copy items to the clipboard when dragging them.", + "isCommentAutoGenerated" : true + }, "Copy Latest Crash Report" : { "localizations" : { "fr" : { @@ -5945,6 +5953,10 @@ } } }, + "Currently selected: %@" : { + "comment" : "A label showing the currently selected quick share service. The argument is the ID of the currently selected quick share service.", + "isCommentAutoGenerated" : true + }, "Custom" : { "localizations" : { "fr" : { @@ -8578,6 +8590,10 @@ }, "Expand Notch with Animation" : { + }, + "Expanded drag detection area" : { + "comment" : "A toggle that lets users enable or disable expanded drag detection.", + "isCommentAutoGenerated" : true }, "Expanded notch width" : { "comment" : "A label describing the expanded notch width setting.", @@ -8696,6 +8712,10 @@ } } }, + "Files dropped on the shelf will be shared via this service" : { + "comment" : "A description below the currently selected quick share provider, explaining that files dropped on the shelf will be shared via that provider.", + "isCommentAutoGenerated" : true + }, "Fill Notch" : { }, @@ -15168,6 +15188,14 @@ }, "Quick Presets" : { + }, + "Quick Share" : { + "comment" : "A section header that says \"Quick Share\".", + "isCommentAutoGenerated" : true + }, + "Quick Share Service" : { + "comment" : "A picker that lets the user select a quick share service to use when sharing files from the shelf.", + "isCommentAutoGenerated" : true }, "Quick Start" : { "comment" : "A label displayed above the quick start options in the timer tab.", @@ -15677,6 +15705,9 @@ } } } + }, + "Remove from shelf after dragging" : { + }, "Replaces macOS system HUD with Dynamic Island displays for volume, brightness, and keyboard backlight." : { "comment" : "A footer description of the HUDs feature.", diff --git a/DynamicIsland/components/Settings/SettingsView.swift b/DynamicIsland/components/Settings/SettingsView.swift index cbbb5f8..90509df 100644 --- a/DynamicIsland/components/Settings/SettingsView.swift +++ b/DynamicIsland/components/Settings/SettingsView.swift @@ -4,6 +4,7 @@ // // Created by Richard Kunkli on 07/08/2024. // +import AppKit import AVFoundation import Combine import Defaults @@ -628,6 +629,10 @@ struct SettingsView: View { // Shelf SettingsSearchEntry(tab: .shelf, title: "Enable shelf", keywords: ["shelf", "dock"], highlightID: SettingsTab.shelf.highlightID(for: "Enable shelf")), SettingsSearchEntry(tab: .shelf, title: "Open shelf tab by default if items added", keywords: ["auto open", "shelf tab"], highlightID: SettingsTab.shelf.highlightID(for: "Open shelf tab by default if items added")), + SettingsSearchEntry(tab: .shelf, title: "Expanded drag detection area", keywords: ["shelf", "drag"], highlightID: SettingsTab.shelf.highlightID(for: "Expanded drag detection area")), + SettingsSearchEntry(tab: .shelf, title: "Copy items on drag", keywords: ["shelf", "drag", "copy"], highlightID: SettingsTab.shelf.highlightID(for: "Copy items on drag")), + SettingsSearchEntry(tab: .shelf, title: "Remove from shelf after dragging", keywords: ["shelf", "drag", "remove"], highlightID: SettingsTab.shelf.highlightID(for: "Remove from shelf after dragging")), + SettingsSearchEntry(tab: .shelf, title: "Quick Share Service", keywords: ["shelf", "share", "airdrop"], highlightID: SettingsTab.shelf.highlightID(for: "Quick Share Service")), // Appearance SettingsSearchEntry(tab: .appearance, title: "Settings icon in notch", keywords: ["settings button", "toolbar"], highlightID: SettingsTab.appearance.highlightID(for: "Settings icon in notch")), @@ -1900,6 +1905,20 @@ struct About: View { } struct Shelf: View { + @Default(.quickShareProvider) var quickShareProvider + @Default(.expandedDragDetection) var expandedDragDetection + @Default(.copyOnDrag) var copyOnDrag + @Default(.autoRemoveShelfItems) var autoRemoveShelfItems + @StateObject private var quickShareService = QuickShareService.shared + + private var selectedProvider: QuickShareProvider? { + quickShareService.availableProviders.first(where: { $0.id == quickShareProvider }) + } + + init() { + Task { await QuickShareService.shared.discoverAvailableProviders() } + } + private func highlightID(_ title: String) -> String { SettingsTab.shelf.highlightID(for: title) } @@ -1909,14 +1928,88 @@ struct Shelf: View { Section { Defaults.Toggle("Enable shelf", key: .dynamicShelf) .settingsHighlight(id: highlightID("Enable shelf")) + Defaults.Toggle("Open shelf tab by default if items added", key: .openShelfByDefault) .settingsHighlight(id: highlightID("Open shelf tab by default if items added")) + + Defaults.Toggle(key: .expandedDragDetection) { + Text("Expanded drag detection area") + } + .settingsHighlight(id: highlightID("Expanded drag detection area")) + + Defaults.Toggle(key: .copyOnDrag) { + Text("Copy items on drag") + } + .settingsHighlight(id: highlightID("Copy items on drag")) + + Defaults.Toggle(key: .autoRemoveShelfItems) { + Text("Remove from shelf after dragging") + } + .settingsHighlight(id: highlightID("Remove from shelf after dragging")) } header: { HStack { Text("General") } } + + Section { + Picker("Quick Share Service", selection: $quickShareProvider) { + ForEach(quickShareService.availableProviders, id: \.id) { provider in + HStack { + Group { + if let imgData = provider.imageData, let nsImg = NSImage(data: imgData) { + Image(nsImage: nsImg) + .resizable() + .aspectRatio(contentMode: .fit) + } else { + Image(systemName: "square.and.arrow.up") + } + } + .frame(width: 16, height: 16) + .foregroundColor(.accentColor) + Text(provider.id) + } + .tag(provider.id) + } + } + .pickerStyle(.menu) + .settingsHighlight(id: highlightID("Quick Share Service")) + + if let selectedProvider { + HStack { + Group { + if let imgData = selectedProvider.imageData, let nsImg = NSImage(data: imgData) { + Image(nsImage: nsImg) + .resizable() + .aspectRatio(contentMode: .fit) + } else { + Image(systemName: "square.and.arrow.up") + } + } + .frame(width: 16, height: 16) + .foregroundColor(.accentColor) + VStack(alignment: .leading, spacing: 2) { + Text("Currently selected: \(selectedProvider.id)") + .font(.caption) + .foregroundStyle(.secondary) + Text("Files dropped on the shelf will be shared via this service") + .font(.caption2) + .foregroundStyle(.secondary) + } + } + .padding(.vertical, 4) + } + } header: { + HStack { + Text("Quick Share") + } + } footer: { + Text("Choose which service to use when sharing files from the shelf. Drag files onto the shelf or click the shelf button to pick files.") + .font(.caption) + .foregroundStyle(.secondary) + } } + .accentColor(.effectiveAccent) .navigationTitle("Shelf") } } diff --git a/DynamicIsland/models/Constants.swift b/DynamicIsland/models/Constants.swift index 1e99e09..7ff6b6e 100644 --- a/DynamicIsland/models/Constants.swift +++ b/DynamicIsland/models/Constants.swift @@ -504,6 +504,7 @@ extension Defaults.Keys { static let quickShareProvider = Key("quickShareProvider", default: "AirDrop") static let copyOnDrag = Key("copyOnDrag", default: false) static let autoRemoveShelfItems = Key("autoRemoveShelfItems", default: false) + static let expandedDragDetection = Key("expandedDragDetection", default: true) // MARK: Calendar static let calendarSelectionState = Key("calendarSelectionState", default: .all)