Skip to content

Commit 8d8194c

Browse files
committed
import feature and optimize all
1 parent 2ad033d commit 8d8194c

4 files changed

Lines changed: 184 additions & 36 deletions

File tree

iOS/ScriptWidget.xcodeproj/project.pbxproj

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2002,7 +2002,7 @@
20022002
CODE_SIGN_ENTITLEMENTS = ScriptWidget/ScriptWidget.entitlements;
20032003
CODE_SIGN_IDENTITY = "Apple Development";
20042004
CODE_SIGN_STYLE = Automatic;
2005-
CURRENT_PROJECT_VERSION = 6018;
2005+
CURRENT_PROJECT_VERSION = 6019;
20062006
DEVELOPMENT_ASSET_PATHS = "\"ScriptWidget/Preview Content\"";
20072007
DEVELOPMENT_TEAM = YPV49M8592;
20082008
ENABLE_PREVIEWS = YES;
@@ -2013,7 +2013,7 @@
20132013
"$(inherited)",
20142014
"@executable_path/Frameworks",
20152015
);
2016-
MARKETING_VERSION = 6.8;
2016+
MARKETING_VERSION = 6.9;
20172017
PRODUCT_BUNDLE_IDENTIFIER = com.everettjf.scriptwidget;
20182018
PRODUCT_NAME = "$(TARGET_NAME)";
20192019
PROVISIONING_PROFILE_SPECIFIER = "";
@@ -2034,7 +2034,7 @@
20342034
CODE_SIGN_ENTITLEMENTS = ScriptWidget/ScriptWidget.entitlements;
20352035
CODE_SIGN_IDENTITY = "Apple Development";
20362036
CODE_SIGN_STYLE = Automatic;
2037-
CURRENT_PROJECT_VERSION = 6018;
2037+
CURRENT_PROJECT_VERSION = 6019;
20382038
DEVELOPMENT_ASSET_PATHS = "\"ScriptWidget/Preview Content\"";
20392039
DEVELOPMENT_TEAM = YPV49M8592;
20402040
ENABLE_PREVIEWS = YES;
@@ -2045,7 +2045,7 @@
20452045
"$(inherited)",
20462046
"@executable_path/Frameworks",
20472047
);
2048-
MARKETING_VERSION = 6.8;
2048+
MARKETING_VERSION = 6.9;
20492049
PRODUCT_BUNDLE_IDENTIFIER = com.everettjf.scriptwidget;
20502050
PRODUCT_NAME = "$(TARGET_NAME)";
20512051
PROVISIONING_PROFILE_SPECIFIER = "";
@@ -2062,7 +2062,7 @@
20622062
ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground;
20632063
CODE_SIGN_ENTITLEMENTS = ScriptWidgetWidget/ScriptWidgetWidget.entitlements;
20642064
CODE_SIGN_STYLE = Automatic;
2065-
CURRENT_PROJECT_VERSION = 6018;
2065+
CURRENT_PROJECT_VERSION = 6019;
20662066
DEVELOPMENT_TEAM = YPV49M8592;
20672067
INFOPLIST_FILE = ScriptWidgetWidget/Info.plist;
20682068
IPHONEOS_DEPLOYMENT_TARGET = 17.0;
@@ -2071,7 +2071,7 @@
20712071
"@executable_path/Frameworks",
20722072
"@executable_path/../../Frameworks",
20732073
);
2074-
MARKETING_VERSION = 6.8;
2074+
MARKETING_VERSION = 6.9;
20752075
OTHER_SWIFT_FLAGS = "-D IsWidgetTarget";
20762076
PRODUCT_BUNDLE_IDENTIFIER = com.everettjf.scriptwidget.widget;
20772077
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -2088,7 +2088,7 @@
20882088
ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground;
20892089
CODE_SIGN_ENTITLEMENTS = ScriptWidgetWidget/ScriptWidgetWidget.entitlements;
20902090
CODE_SIGN_STYLE = Automatic;
2091-
CURRENT_PROJECT_VERSION = 6018;
2091+
CURRENT_PROJECT_VERSION = 6019;
20922092
DEVELOPMENT_TEAM = YPV49M8592;
20932093
INFOPLIST_FILE = ScriptWidgetWidget/Info.plist;
20942094
IPHONEOS_DEPLOYMENT_TARGET = 17.0;
@@ -2097,7 +2097,7 @@
20972097
"@executable_path/Frameworks",
20982098
"@executable_path/../../Frameworks",
20992099
);
2100-
MARKETING_VERSION = 6.8;
2100+
MARKETING_VERSION = 6.9;
21012101
OTHER_SWIFT_FLAGS = "-D IsWidgetTarget";
21022102
PRODUCT_BUNDLE_IDENTIFIER = com.everettjf.scriptwidget.widget;
21032103
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -2113,7 +2113,7 @@
21132113
CODE_SIGN_ENTITLEMENTS = ScriptWidgetShare/ScriptWidgetShare.entitlements;
21142114
CODE_SIGN_IDENTITY = "Apple Development";
21152115
CODE_SIGN_STYLE = Automatic;
2116-
CURRENT_PROJECT_VERSION = 6018;
2116+
CURRENT_PROJECT_VERSION = 6019;
21172117
DEVELOPMENT_TEAM = YPV49M8592;
21182118
INFOPLIST_FILE = ScriptWidgetShare/Info.plist;
21192119
IPHONEOS_DEPLOYMENT_TARGET = 17.0;
@@ -2122,7 +2122,7 @@
21222122
"@executable_path/Frameworks",
21232123
"@executable_path/../../Frameworks",
21242124
);
2125-
MARKETING_VERSION = 6.8;
2125+
MARKETING_VERSION = 6.9;
21262126
PRODUCT_BUNDLE_IDENTIFIER = com.everettjf.scriptwidget.share;
21272127
PRODUCT_NAME = "$(TARGET_NAME)";
21282128
SKIP_INSTALL = YES;
@@ -2137,7 +2137,7 @@
21372137
CODE_SIGN_ENTITLEMENTS = ScriptWidgetShare/ScriptWidgetShare.entitlements;
21382138
CODE_SIGN_IDENTITY = "Apple Development";
21392139
CODE_SIGN_STYLE = Automatic;
2140-
CURRENT_PROJECT_VERSION = 6018;
2140+
CURRENT_PROJECT_VERSION = 6019;
21412141
DEVELOPMENT_TEAM = YPV49M8592;
21422142
INFOPLIST_FILE = ScriptWidgetShare/Info.plist;
21432143
IPHONEOS_DEPLOYMENT_TARGET = 17.0;
@@ -2146,7 +2146,7 @@
21462146
"@executable_path/Frameworks",
21472147
"@executable_path/../../Frameworks",
21482148
);
2149-
MARKETING_VERSION = 6.8;
2149+
MARKETING_VERSION = 6.9;
21502150
PRODUCT_BUNDLE_IDENTIFIER = com.everettjf.scriptwidget.share;
21512151
PRODUCT_NAME = "$(TARGET_NAME)";
21522152
SKIP_INSTALL = YES;

iOS/ScriptWidget/App/Settings/ExportView.swift

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@ import UniformTypeIdentifiers
33

44
struct ExportView: View {
55
@State private var isExporting = false
6+
@State private var exportSucceeded = false
67
@State private var progress: Float = 0
78
@State private var statusMessage = ""
9+
@State private var logMessages: [String] = []
810
@State private var exportedFileURL: URL?
911
@State private var showShareSheet = false
1012

@@ -21,25 +23,33 @@ struct ExportView: View {
2123
.foregroundColor(.white)
2224
.frame(maxWidth: .infinity)
2325
.padding(.vertical, 16)
24-
.background(Color.blue)
26+
.background(isExporting || exportSucceeded ? Color.gray : Color.blue) // Change background color when disabled
2527
.cornerRadius(15)
2628
}
2729
.padding(.horizontal, 20)
28-
.disabled(isExporting)
30+
.disabled(isExporting || exportSucceeded)
2931

30-
if isExporting {
31-
VStack {
32-
ProgressView(value: progress)
33-
.progressViewStyle(LinearProgressViewStyle(tint: .blue))
34-
.scaleEffect(1.5)
35-
.padding(.top, 10)
36-
37-
Text(statusMessage)
38-
.font(.caption)
39-
.padding(.top, 5)
40-
}
32+
// Always show progress view
33+
ProgressView(value: progress)
34+
.progressViewStyle(LinearProgressViewStyle(tint: .blue))
35+
.scaleEffect(1.5)
36+
.padding(.top, 10)
37+
38+
Text(statusMessage)
39+
.font(.caption)
40+
.padding(.top, 5)
41+
}
42+
43+
// Move log list outside the VStack and increase its height
44+
List {
45+
ForEach(logMessages, id: \.self) { message in
46+
Text(message)
47+
.font(.caption)
4148
}
4249
}
50+
.frame(maxHeight: .infinity) // Allow the list to expand and fill available space
51+
.background(Color.gray.opacity(0.1))
52+
.cornerRadius(10)
4353
}
4454
.padding()
4555
.sheet(isPresented: $showShareSheet, content: {
@@ -51,27 +61,35 @@ struct ExportView: View {
5161

5262
private func startExport() {
5363
isExporting = true
64+
exportSucceeded = false
5465
progress = 0
5566
statusMessage = "Starting export..."
67+
logMessages.removeAll() // Clear previous log messages
5668

5769
Task {
5870
do {
5971
let zipFileURL = try await ExportManager.exportAllScripts { currentProgress, message in
6072
DispatchQueue.main.async {
6173
self.progress = currentProgress
6274
self.statusMessage = message
75+
self.logMessages.insert(message, at: 0) // Insert new message at the beginning
6376
}
6477
}
6578

6679
DispatchQueue.main.async {
6780
self.exportedFileURL = zipFileURL
6881
self.showShareSheet = true
6982
self.isExporting = false
83+
self.exportSucceeded = true
84+
self.statusMessage = "Export completed successfully"
85+
self.logMessages.insert("Export completed successfully", at: 0) // Insert final message at the beginning
7086
}
7187
} catch {
7288
DispatchQueue.main.async {
73-
self.statusMessage = "Error: \(error.localizedDescription)"
7489
self.isExporting = false
90+
self.exportSucceeded = false
91+
self.statusMessage = "Error: \(error.localizedDescription)"
92+
self.logMessages.insert("Error: \(error.localizedDescription)", at: 0) // Insert error message at the beginning
7593
}
7694
}
7795
}
@@ -94,5 +112,3 @@ struct ExportView_Previews: PreviewProvider {
94112
ExportView()
95113
}
96114
}
97-
98-
// End of file. No additional code.

iOS/ScriptWidget/App/Settings/ImportView.swift

Lines changed: 74 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,104 @@
11
import SwiftUI
2+
import UniformTypeIdentifiers
23

34
struct ImportView: View {
45
@State private var isImporting = false
6+
@State private var importSucceeded = false
7+
@State private var showFilePicker = false
8+
@State private var progress: Float = 0
9+
@State private var statusMessage = ""
10+
@State private var logMessages: [String] = []
511

612
var body: some View {
713
VStack(spacing: 20) {
814
// Import button and progress bar
915
VStack {
1016
Button(action: {
11-
isImporting.toggle()
17+
showFilePicker = true
1218
}) {
1319
Text("Import")
1420
.font(.title2)
1521
.fontWeight(.bold)
1622
.foregroundColor(.white)
1723
.frame(maxWidth: .infinity)
1824
.padding(.vertical, 16)
19-
.background(Color.green)
25+
.background(isImporting || importSucceeded ? Color.gray : Color.green)
2026
.cornerRadius(15)
2127
}
2228
.padding(.horizontal, 20)
29+
.disabled(isImporting || importSucceeded)
2330

24-
if isImporting {
25-
ProgressView()
26-
.progressViewStyle(LinearProgressViewStyle(tint: .green))
27-
.scaleEffect(1.5)
28-
.padding(.top, 10)
31+
ProgressView(value: progress)
32+
.progressViewStyle(LinearProgressViewStyle(tint: .green))
33+
.scaleEffect(1.5)
34+
.padding(.top, 10)
35+
36+
Text(statusMessage)
37+
.font(.caption)
38+
.padding(.top, 5)
39+
}
40+
41+
// Modify the log list to take up more space
42+
List {
43+
ForEach(logMessages, id: \.self) { message in
44+
Text(message)
45+
.font(.caption)
2946
}
3047
}
48+
.frame(maxHeight: .infinity)
49+
.background(Color.gray.opacity(0.1))
50+
.cornerRadius(10)
3151
}
3252
.padding()
53+
.fileImporter(
54+
isPresented: $showFilePicker,
55+
allowedContentTypes: [UTType.zip],
56+
allowsMultipleSelection: false
57+
) { result in
58+
switch result {
59+
case .success(let files):
60+
if let file = files.first {
61+
importFile(file)
62+
}
63+
case .failure(let error):
64+
print("Error selecting file: \(error.localizedDescription)")
65+
}
66+
}
3367
}
3468

35-
69+
private func importFile(_ file: URL) {
70+
isImporting = true
71+
importSucceeded = false
72+
progress = 0
73+
statusMessage = "Starting import..."
74+
logMessages.removeAll()
75+
76+
Task {
77+
do {
78+
try await ImportManager.importScripts(from: file) { currentProgress, message in
79+
DispatchQueue.main.async {
80+
self.progress = currentProgress
81+
self.statusMessage = message
82+
self.logMessages.insert(message, at: 0)
83+
}
84+
}
85+
86+
DispatchQueue.main.async {
87+
self.isImporting = false
88+
self.importSucceeded = true
89+
self.statusMessage = "Import completed successfully"
90+
self.logMessages.insert("Import completed successfully", at: 0)
91+
}
92+
} catch {
93+
DispatchQueue.main.async {
94+
self.isImporting = false
95+
self.importSucceeded = false
96+
self.statusMessage = "Error: \(error.localizedDescription)"
97+
self.logMessages.insert("Error: \(error.localizedDescription)", at: 0)
98+
}
99+
}
100+
}
101+
}
36102
}
37103

38104
struct ImportView_Previews: PreviewProvider {

iOS/ScriptWidget/Manager/ImportExportManager.swift

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,3 +59,69 @@ class ExportManager {
5959
}
6060
}
6161
}
62+
63+
class ImportManager {
64+
static func importScripts(from fileURL: URL, progressCallback: @escaping (Float, String) -> Void) async throws {
65+
let tempDir = FileManager.default.temporaryDirectory.appendingPathComponent("scriptwidget-import")
66+
67+
// Remove existing temp directory if it exists
68+
try? FileManager.default.removeItem(at: tempDir)
69+
70+
// Create the temporary directory
71+
try FileManager.default.createDirectory(at: tempDir, withIntermediateDirectories: true, attributes: nil)
72+
73+
// Extract zip file
74+
await MainActor.run {
75+
progressCallback(0.1, "Extracting zip file")
76+
}
77+
78+
// Start accessing the security-scoped resource
79+
guard fileURL.startAccessingSecurityScopedResource() else {
80+
throw NSError(domain: "ImportManager", code: 2, userInfo: [NSLocalizedDescriptionKey: "Failed to access the selected file"])
81+
}
82+
83+
// Ensure we stop accessing the resource when we're done
84+
defer {
85+
fileURL.stopAccessingSecurityScopedResource()
86+
}
87+
88+
// Copy the file to a temporary location
89+
let tempZipPath = tempDir.appendingPathComponent("temp.zip")
90+
try FileManager.default.copyItem(at: fileURL, to: tempZipPath)
91+
92+
guard SSZipArchive.unzipFile(atPath: tempZipPath.path, toDestination: tempDir.path) else {
93+
throw NSError(domain: "ImportManager", code: 1, userInfo: [NSLocalizedDescriptionKey: "Failed to extract zip file"])
94+
}
95+
96+
// Remove the temporary zip file
97+
try? FileManager.default.removeItem(at: tempZipPath)
98+
99+
// The rest of your code remains the same
100+
101+
// Get all files in the extracted directory
102+
let fileManager = FileManager.default
103+
let files = try fileManager.contentsOfDirectory(at: tempDir, includingPropertiesForKeys: nil)
104+
let totalFiles = Float(files.count)
105+
106+
// Import each script
107+
for (index, file) in files.enumerated() {
108+
let fileName = file.lastPathComponent
109+
await MainActor.run {
110+
progressCallback(0.2 + 0.7 * (Float(index) / totalFiles), "Importing: \(fileName)")
111+
}
112+
113+
// Import the script using your ScriptManager
114+
let success = await sharedScriptManager.importScript(fromPath: file)
115+
if !success {
116+
print("Failed to import script: \(fileName)")
117+
}
118+
}
119+
120+
// Clean up
121+
try? FileManager.default.removeItem(at: tempDir)
122+
123+
await MainActor.run {
124+
progressCallback(1.0, "Import completed")
125+
}
126+
}
127+
}

0 commit comments

Comments
 (0)