Add LocalSend support with service integration and UI updates

This commit is contained in:
AntonP29 2026-03-21 21:30:41 -07:00
commit f345ddaff8
15 changed files with 1773 additions and 29 deletions

View file

@ -16,6 +16,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import AppKit
import Defaults
import SwiftUI
import UniformTypeIdentifiers
@ -24,6 +26,10 @@ struct AirDropView: View {
@State var trigger: UUID = .init()
@State var targeting = false
@Default(.quickShareProvider) var quickShareProvider
@StateObject private var quickShareService = QuickShareService.shared
@State private var showShareSettings = false
@State private var isGearHover = false
var body: some View {
dropArea
@ -40,7 +46,97 @@ struct AirDropView: View {
.fill(.white.opacity(0.1))
.opacity(0.5)
.clipShape(RoundedRectangle(cornerRadius: 10))
.overlay { dropLabel }
.overlay {
ZStack {
dropLabel
// Gear in the bottom-right for quick-share settings
VStack {
Spacer()
HStack {
Spacer()
Button {
quickShareService.ensureDiscovered()
showShareSettings.toggle()
} label: {
Image(systemName: "gearshape")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 14, height: 14)
.padding(8)
.background(
RoundedRectangle(cornerRadius: 8)
.fill(isGearHover ? Color(.windowBackgroundColor).opacity(0.12) : Color.clear)
)
.foregroundColor(isGearHover ? .accentColor : .gray)
.contentShape(Rectangle())
.onHover { over in isGearHover = over }
.help("Quick Share settings")
}
.buttonStyle(.plain)
.popover(isPresented: $showShareSettings) {
VStack(alignment: .leading, spacing: 8) {
Text("Quick Share")
.font(.headline)
Picker("Quick Share Service", selection: $quickShareProvider) {
ForEach(quickShareService.availableProviders, id: \.id) { provider in
HStack(spacing: 8) {
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)
.lineLimit(1)
.fixedSize(horizontal: true, vertical: false)
}
.tag(provider.id)
}
}
.pickerStyle(.menu)
.frame(minWidth: 260)
if let selected = quickShareService.availableProviders.first(where: { $0.id == quickShareProvider }) {
HStack(alignment: .top, spacing: 8) {
Group {
if let imgData = selected.imageData, let nsImg = NSImage(data: imgData) {
Image(nsImage: nsImg)
.resizable()
.frame(width: 20, height: 20)
} else {
Image(systemName: "square.and.arrow.up")
}
}
.foregroundColor(.accentColor)
VStack(alignment: .leading, spacing: 2) {
Text("Currently: \(selected.id)")
.font(.caption)
.foregroundStyle(.secondary)
.lineLimit(1)
.fixedSize(horizontal: true, vertical: false)
Text("Files dropped here will be shared via this service")
.font(.caption2)
.foregroundStyle(.secondary)
}
}
}
}
.padding()
}
.padding(8)
}
}
}
}
.aspectRatio(1, contentMode: .fit)
.contentShape(Rectangle())
}