@@ -17,6 +17,9 @@ struct CustomCommandFeature: ReducerProtocol {
1717 case editCommand( CustomCommand )
1818 case editCustomCommand( EditCustomCommand . Action )
1919 case deleteCommand( CustomCommand )
20+ case exportCommand( CustomCommand )
21+ case importCommand( at: URL )
22+ case importCommandClicked
2023 }
2124
2225 @Dependency ( \. toast) var toast
@@ -49,6 +52,68 @@ struct CustomCommandFeature: ReducerProtocol {
4952 return . none
5053 case . editCustomCommand:
5154 return . none
55+ case let . exportCommand( command) :
56+ return . run { _ in
57+ do {
58+ let data = try JSONEncoder ( ) . encode ( command)
59+ let filename = " CustomCommand- \( command. name) .json "
60+
61+ let url = await withCheckedContinuation { continuation in
62+ Task { @MainActor in
63+ let panel = NSSavePanel ( )
64+ panel. canCreateDirectories = true
65+ panel. nameFieldStringValue = filename
66+ let result = await panel. begin ( )
67+ switch result {
68+ case . OK:
69+ continuation. resume ( returning: panel. url)
70+ default :
71+ continuation. resume ( returning: nil )
72+ }
73+ }
74+ }
75+
76+ if let url {
77+ try data. write ( to: url)
78+ toast ( " Saved! " , . info)
79+ }
80+
81+ } catch {
82+ toast ( error. localizedDescription, . error)
83+ }
84+ }
85+
86+ case let . importCommand( url) :
87+ do {
88+ let data = try Data ( contentsOf: url)
89+ var command = try JSONDecoder ( ) . decode ( CustomCommand . self, from: data)
90+ command. commandId = UUID ( ) . uuidString
91+ settings. customCommands. append ( command)
92+ toast ( " Imported custom command \( command. name) ! " , . info)
93+ } catch {
94+ toast ( " Failed to import command: \( error. localizedDescription) " , . error)
95+ }
96+ return . none
97+
98+ case . importCommandClicked:
99+ return . run { send in
100+ let url = await withCheckedContinuation { continuation in
101+ Task { @MainActor in
102+ let panel = NSOpenPanel ( )
103+ panel. allowedContentTypes = [ . json]
104+ let result = await panel. begin ( )
105+ if result == . OK {
106+ continuation. resume ( returning: panel. url)
107+ } else {
108+ continuation. resume ( returning: nil )
109+ }
110+ }
111+ }
112+
113+ if let url {
114+ await send ( . importCommand( at: url) )
115+ }
116+ }
52117 }
53118 } . ifLet ( \. editCustomCommand, action: / Action. editCustomCommand) {
54119 EditCustomCommand ( settings: settings)
0 commit comments