Skip to content

Commit 1afb02f

Browse files
committed
feat: export all plugins
Signed-off-by: Lessica <82flex@gmail.com>
1 parent 3a372ad commit 1afb02f

File tree

1 file changed

+71
-2
lines changed

1 file changed

+71
-2
lines changed

TrollFools/EjectListView.swift

Lines changed: 71 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,15 @@
88
import CocoaLumberjackSwift
99
import SwiftUI
1010
import SwiftUIIntrospect
11+
import ZIPFoundation
1112

1213
struct EjectListView: View {
1314
@StateObject var searchViewModel = AppListSearchModel()
1415
@StateObject var ejectList: EjectListModel
1516

1617
@State var quickLookExport: URL?
1718
@State var isDeletingAll = false
19+
@State var isExportingAll = false
1820
@State var isErrorOccurred: Bool = false
1921
@State var lastError: Error?
2022

@@ -33,6 +35,23 @@ struct EjectListView: View {
3335

3436
var body: some View {
3537
refreshableListView
38+
.toolbar {
39+
ToolbarItem(placement: .topBarTrailing) {
40+
Button {
41+
exportAll()
42+
} label: {
43+
if isExportingAll {
44+
ProgressView()
45+
.progressViewStyle(CircularProgressViewStyle())
46+
.transition(.opacity)
47+
} else {
48+
Label(NSLocalizedString("Export All", comment: ""), systemImage: "square.and.arrow.up")
49+
.transition(.opacity)
50+
}
51+
}
52+
}
53+
}
54+
.animation(.easeOut, value: isExportingAll)
3655
.quickLookPreview($quickLookExport)
3756
}
3857

@@ -256,8 +275,6 @@ struct EjectListView: View {
256275
try injector.ejectAll()
257276
} catch {
258277
DispatchQueue.main.async {
259-
isDeletingAll = false
260-
261278
DDLogError("\(error)", ddlog: InjectorV3.main.logger)
262279

263280
lastError = error
@@ -271,6 +288,58 @@ struct EjectListView: View {
271288
}
272289
}
273290

291+
private func exportAll() {
292+
let view = viewControllerHost.viewController?
293+
.navigationController?.view
294+
295+
view?.isUserInteractionEnabled = false
296+
297+
isExportingAll = true
298+
299+
DispatchQueue.global(qos: .userInteractive).async {
300+
defer {
301+
DispatchQueue.main.async {
302+
isExportingAll = false
303+
view?.isUserInteractionEnabled = true
304+
}
305+
}
306+
307+
do {
308+
try _exportAll()
309+
} catch {
310+
DispatchQueue.main.async {
311+
DDLogError("\(error)", ddlog: InjectorV3.main.logger)
312+
313+
lastError = error
314+
isErrorOccurred = true
315+
}
316+
}
317+
}
318+
}
319+
320+
private func _exportAll() throws {
321+
let exportURL = InjectorV3.temporaryRoot
322+
.appendingPathComponent("Exports_\(UUID().uuidString)", isDirectory: true)
323+
324+
let fileMgr = FileManager.default
325+
try fileMgr.createDirectory(at: exportURL, withIntermediateDirectories: true)
326+
327+
for plugin in ejectList.filteredPlugIns {
328+
let exportURL = exportURL.appendingPathComponent(plugin.url.lastPathComponent)
329+
try fileMgr.copyItem(at: plugin.url, to: exportURL)
330+
}
331+
332+
let zipURL = InjectorV3.temporaryRoot
333+
.appendingPathComponent(
334+
"\(ejectList.app.name)_\(ejectList.app.id)_\(UUID().uuidString.components(separatedBy: "-").last ?? "").zip")
335+
336+
try fileMgr.zipItem(at: exportURL, to: zipURL)
337+
338+
DispatchQueue.main.async {
339+
quickLookExport = zipURL
340+
}
341+
}
342+
274343
@ViewBuilder
275344
private func paddedHeaderFooterText(_ content: String) -> some View {
276345
if #available(iOS 15, *) {

0 commit comments

Comments
 (0)