Skip to content

Commit f95d565

Browse files
committed
fix: skip parent when batch export plugins
Signed-off-by: 82Flex <82flex@gmail.com>
1 parent 16603a1 commit f95d565

File tree

8 files changed

+114
-21
lines changed

8 files changed

+114
-21
lines changed

TrollFools.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@
9090
CCC564EB2C4BE8320097C300 /* ldid in Resources */ = {isa = PBXBuildFile; fileRef = CCC564E82C4BE8320097C300 /* ldid */; };
9191
CCC564EC2C4BE8470097C300 /* libcrypto.3.dylib in Resources */ = {isa = PBXBuildFile; fileRef = CCC564E62C4BE8320097C300 /* libcrypto.3.dylib */; };
9292
CCECB7CE2C54DC660094C8E6 /* mv in Resources */ = {isa = PBXBuildFile; fileRef = CCECB7CD2C54DC660094C8E6 /* mv */; };
93+
CCF350A22D7DE50900826516 /* EjectListSearchModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = CCF350A12D7DE50800826516 /* EjectListSearchModel.swift */; };
9394
CCF4705A2C4A4649008D8197 /* TrollFoolsApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = CCF470592C4A4649008D8197 /* TrollFoolsApp.swift */; };
9495
CCF4705E2C4A464B008D8197 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = CCF4705D2C4A464B008D8197 /* Assets.xcassets */; };
9596
CCF470692C4A4919008D8197 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = CCF4706B2C4A4919008D8197 /* Localizable.strings */; };
@@ -183,6 +184,7 @@
183184
CCC564E62C4BE8320097C300 /* libcrypto.3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; path = libcrypto.3.dylib; sourceTree = "<group>"; };
184185
CCC564E82C4BE8320097C300 /* ldid */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.executable"; path = ldid; sourceTree = "<group>"; };
185186
CCECB7CD2C54DC660094C8E6 /* mv */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.executable"; path = mv; sourceTree = "<group>"; };
187+
CCF350A12D7DE50800826516 /* EjectListSearchModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EjectListSearchModel.swift; sourceTree = "<group>"; };
186188
CCF470562C4A4649008D8197 /* TrollFools.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TrollFools.app; sourceTree = BUILT_PRODUCTS_DIR; };
187189
CCF470592C4A4649008D8197 /* TrollFoolsApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrollFoolsApp.swift; sourceTree = "<group>"; };
188190
CCF4705D2C4A464B008D8197 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
@@ -242,6 +244,7 @@
242244
6124A06E2CD2324200C52253 /* AppListModel.swift */,
243245
614C0C672D7C72AC007E9184 /* AppListSearchModel.swift */,
244246
6124A0802CD233DA00C52253 /* EjectListModel.swift */,
247+
CCF350A12D7DE50800826516 /* EjectListSearchModel.swift */,
245248
6124A0702CD2326500C52253 /* FilterOptions.swift */,
246249
6124A07C2CD233A700C52253 /* InjectedPlugIn.swift */,
247250
6124A0752CD232C600C52253 /* Option.swift */,
@@ -597,6 +600,7 @@
597600
CCF4706E2C4A4BAB008D8197 /* AppListView.swift in Sources */,
598601
614C0C6C2D7D72D4007E9184 /* IndexableScroller.swift in Sources */,
599602
CC1548D32C4A743200A4173E /* SuccessView.swift in Sources */,
603+
CCF350A22D7DE50900826516 /* EjectListSearchModel.swift in Sources */,
600604
61EFA36D2D3027C400159442 /* InjectorV3+Command.swift in Sources */,
601605
CC1548D52C4A744300A4173E /* FailureView.swift in Sources */,
602606
61EFA3732D30347A00159442 /* InjectorV3+MachO.swift in Sources */,

TrollFools/EjectListSearchModel.swift

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//
2+
// EjectListSearchModel.swift
3+
// TrollFools
4+
//
5+
// Created by Rachel on 9/3/2025.
6+
//
7+
8+
import Combine
9+
import Foundation
10+
11+
final class EjectListSearchViewModel: NSObject, UISearchResultsUpdating, ObservableObject {
12+
@Published var searchKeyword: String = ""
13+
14+
weak var searchController: UISearchController?
15+
16+
func updateSearchResults(for searchController: UISearchController) {
17+
searchKeyword = searchController.searchBar.text ?? ""
18+
}
19+
}

TrollFools/EjectListView.swift

Lines changed: 57 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -37,19 +37,41 @@ struct EjectListView: View {
3737
refreshableListView
3838
.toolbar {
3939
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)
40+
if #available(iOS 16.4, *) {
41+
ShareLink(
42+
item: CompressedFileRepresentation(
43+
name: "\(ejectList.app.name)_\(ejectList.app.id)_\(UUID().uuidString.components(separatedBy: "-").last ?? "").zip",
44+
urls: ejectList.injectedPlugIns.map(\.url)
45+
),
46+
preview: SharePreview(
47+
String(format: NSLocalizedString("%ld Plug-Ins of “%@”", comment: ""), ejectList.injectedPlugIns.count, ejectList.app.name)
48+
)
49+
) {
50+
if isExportingAll {
51+
ProgressView()
52+
.progressViewStyle(CircularProgressViewStyle())
53+
.transition(.opacity)
54+
} else {
55+
Label(NSLocalizedString("Export All", comment: ""), systemImage: "square.and.arrow.up")
56+
.transition(.opacity)
57+
}
5058
}
59+
.disabled(ejectList.injectedPlugIns.isEmpty)
60+
} else {
61+
Button {
62+
exportAll()
63+
} label: {
64+
if isExportingAll {
65+
ProgressView()
66+
.progressViewStyle(CircularProgressViewStyle())
67+
.transition(.opacity)
68+
} else {
69+
Label(NSLocalizedString("Export All", comment: ""), systemImage: "square.and.arrow.up")
70+
.transition(.opacity)
71+
}
72+
}
73+
.disabled(ejectList.injectedPlugIns.isEmpty)
5174
}
52-
.disabled(ejectList.injectedPlugIns.isEmpty)
5375
}
5476
}
5577
.animation(.easeOut, value: isExportingAll)
@@ -334,7 +356,7 @@ struct EjectListView: View {
334356
.appendingPathComponent(
335357
"\(ejectList.app.name)_\(ejectList.app.id)_\(UUID().uuidString.components(separatedBy: "-").last ?? "").zip")
336358

337-
try fileMgr.zipItem(at: exportURL, to: zipURL)
359+
try fileMgr.zipItem(at: exportURL, to: zipURL, shouldKeepParent: false)
338360

339361
DispatchQueue.main.async {
340362
quickLookExport = zipURL
@@ -354,12 +376,30 @@ struct EjectListView: View {
354376
}
355377
}
356378

357-
final class EjectListSearchViewModel: NSObject, UISearchResultsUpdating, ObservableObject {
358-
@Published var searchKeyword: String = ""
379+
@available(iOS 16.0, *)
380+
private struct CompressedFileRepresentation: Transferable {
381+
let name: String
382+
let urls: [URL]
383+
384+
static var transferRepresentation: some TransferRepresentation {
385+
FileRepresentation(exportedContentType: .zip) { archive in
386+
let exportURL = InjectorV3.temporaryRoot
387+
.appendingPathComponent("Exports_\(UUID().uuidString)", isDirectory: true)
359388

360-
weak var searchController: UISearchController?
389+
let fileMgr = FileManager.default
390+
try fileMgr.createDirectory(at: exportURL, withIntermediateDirectories: true)
391+
392+
for url in archive.urls {
393+
let exportURL = exportURL.appendingPathComponent(url.lastPathComponent)
394+
try fileMgr.copyItem(at: url, to: exportURL)
395+
}
361396

362-
func updateSearchResults(for searchController: UISearchController) {
363-
searchKeyword = searchController.searchBar.text ?? ""
397+
let zipURL = InjectorV3.temporaryRoot
398+
.appendingPathComponent(archive.name)
399+
400+
try fileMgr.zipItem(at: exportURL, to: zipURL, shouldKeepParent: false)
401+
402+
return SentTransferredFile(zipURL)
403+
}
364404
}
365405
}

TrollFools/PlugInCell.swift

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,16 @@ struct PlugInCell: View {
7373
}
7474
}
7575
.contextMenu {
76-
Button {
77-
exportPlugIn()
78-
} label: {
79-
Label(NSLocalizedString("Export", comment: ""), systemImage: "square.and.arrow.up")
76+
if #available(iOS 16.4, *) {
77+
ShareLink(item: plugIn.url) {
78+
Label(NSLocalizedString("Export", comment: ""), systemImage: "square.and.arrow.up")
79+
}
80+
} else {
81+
Button {
82+
exportPlugIn()
83+
} label: {
84+
Label(NSLocalizedString("Export", comment: ""), systemImage: "square.and.arrow.up")
85+
}
8086
}
8187

8288
Button {

TrollFools/en.lproj/Localizable.strings

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
/* No comment provided by engineer. */
88
"%@ terminated with signal %d" = "%@ terminated with signal %d";
99

10+
/* No comment provided by engineer. */
11+
"%ld Plug-Ins of “%@”" = "%1$ld Plug-Ins of “%2$@”";
12+
1013
/* No comment provided by engineer. */
1114
"Advanced Settings" = "Advanced Settings";
1215

@@ -55,6 +58,9 @@
5558
/* No comment provided by engineer. */
5659
"Export" = "Export";
5760

61+
/* No comment provided by engineer. */
62+
"Export All" = "Export All";
63+
5864
/* No comment provided by engineer. */
5965
"Failed" = "Failed";
6066

TrollFools/it.lproj/Localizable.strings

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
/* No comment provided by engineer. */
88
"%@ terminated with signal %d" = "%@ terminato col segnale %d";
99

10+
/* TODO */
11+
"%ld Plug-Ins of “%@”" = "%1$ld Plug-Ins of “%2$@”";
12+
1013
/* No comment provided by engineer. */
1114
"Advanced Settings" = "Impostazioni Avanzate";
1215

@@ -55,6 +58,9 @@
5558
/* TODO */
5659
"Export" = "Export";
5760

61+
/* TODO */
62+
"Export All" = "Export All";
63+
5864
/* No comment provided by engineer. */
5965
"Failed" = "Fallito";
6066

TrollFools/vi.lproj/Localizable.strings

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
/* No comment provided by engineer. */
88
"%@ terminated with signal %d" = "%@ đã kết thúc với tín hiệu %d";
99

10+
/* TODO */
11+
"%ld Plug-Ins of “%@”" = "%1$ld Plug-Ins of “%2$@”";
12+
1013
/* No comment provided by engineer. */
1114
"Advanced Settings" = "Cài đặt nâng cao";
1215

@@ -55,6 +58,9 @@
5558
/* TODO */
5659
"Export" = "Export";
5760

61+
/* TODO */
62+
"Export All" = "Export All";
63+
5864
/* No comment provided by engineer. */
5965
"Failed" = "Thất bại";
6066

TrollFools/zh-Hans.lproj/Localizable.strings

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
/* No comment provided by engineer. */
88
"%@ terminated with signal %d" = "%@ 意外终止,未捕获的信号 %d";
99

10+
/* No comment provided by engineer. */
11+
"%ld Plug-Ins of “%@”" = "“%2$@” 的 %1$ld 个插件";
12+
1013
/* No comment provided by engineer. */
1114
"Advanced Settings" = "高级选项";
1215

@@ -55,6 +58,9 @@
5558
/* No comment provided by engineer. */
5659
"Export" = "导出";
5760

61+
/* No comment provided by engineer. */
62+
"Export All" = "全部导出";
63+
5864
/* No comment provided by engineer. */
5965
"Failed" = "失败";
6066

0 commit comments

Comments
 (0)