native macOS codings agent orchestrator
6
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge pull request #243 from onevcat/fix/icon-picker-repo-default-dir

Open icon image picker at the repo's working directory

authored by

Wei Wang and committed by
GitHub
ceef897a 0bf6122b

+21 -30
+21 -30
supacode/Features/RepositorySettings/Views/RepositoryAppearancePickerView.swift
··· 18 18 @Bindable var store: StoreOf<RepositorySettingsFeature> 19 19 20 20 @State private var isSymbolPickerPresented = false 21 - @State private var isImageImporterPresented = false 22 21 @State private var isHoveringIconTile = false 23 22 24 23 private let previewSize: CGFloat = 40 ··· 56 55 onCancel: { isSymbolPickerPresented = false } 57 56 ) 58 57 } 59 - // Accept any image UTType — PNG / JPEG / WebP / HEIC / TIFF / GIF 60 - // / etc. all flow through the same `NSImage(contentsOf:)` render 61 - // path. SVG is listed explicitly because it's a structured-text 62 - // format that doesn't always conform to `.image` in older 63 - // UTType conformance tables. Anything that fails to decode falls 64 - // back to the dashed placeholder at render time. 65 - .fileImporter( 66 - isPresented: $isImageImporterPresented, 67 - allowedContentTypes: [.image, .svg], 68 - allowsMultipleSelection: false 69 - ) { result in 70 - handleImageImportResult(result) 71 - } 72 58 } 73 59 74 60 // MARK: - Icon row ··· 112 98 isSymbolPickerPresented = true 113 99 } 114 100 Button("Choose Image…") { 115 - isImageImporterPresented = true 101 + presentImageImporter() 116 102 } 117 103 if store.appearance.icon != nil { 118 104 Divider() ··· 338 324 } 339 325 } 340 326 341 - private func handleImageImportResult(_ result: Result<[URL], Error>) { 342 - isImageImporterPresented = false 343 - switch result { 344 - case .success(let urls): 345 - guard let url = urls.first else { return } 346 - // `fileImporter` returns security-scoped URLs on macOS — we need 347 - // to start access before reading and stop it on the way out so 348 - // the import store can copy the bytes into the sandboxed app 349 - // support directory. 350 - let needsScope = url.startAccessingSecurityScopedResource() 351 - defer { 352 - if needsScope { url.stopAccessingSecurityScopedResource() } 353 - } 327 + // Uses `NSOpenPanel` (rather than SwiftUI's `.fileImporter`) so the 328 + // panel can open at the repo's working directory — most users keep 329 + // their icon assets next to the project. Accepts any image UTType — 330 + // PNG / JPEG / WebP / HEIC / TIFF / GIF / etc. all flow through the 331 + // same `NSImage(contentsOf:)` render path. SVG is listed explicitly 332 + // because it's a structured-text format that doesn't always conform 333 + // to `.image` in older UTType conformance tables. Anything that fails 334 + // to decode falls back to the dashed placeholder at render time. 335 + private func presentImageImporter() { 336 + let panel = NSOpenPanel() 337 + panel.directoryURL = store.rootURL 338 + panel.allowedContentTypes = [.image, .svg] 339 + panel.canChooseDirectories = false 340 + panel.canChooseFiles = true 341 + panel.allowsMultipleSelection = false 342 + panel.prompt = "Choose" 343 + panel.message = "Choose an image to use as this repository's icon." 344 + 345 + panel.begin { response in 346 + guard response == .OK, let url = panel.url else { return } 354 347 store.send(.importUserImage(url)) 355 - case .failure(let error): 356 - store.send(.userImageImportFailed(error.localizedDescription)) 357 348 } 358 349 } 359 350 }