folder import fixes

This commit is contained in:
True Zhuanjia
2026-04-28 23:52:14 +08:00
parent efc34ae1fc
commit 363b91b244
7 changed files with 178 additions and 12 deletions
+3 -1
View File
@@ -31,7 +31,7 @@ import UIKit
@objc public static var autoCompletion:Bool = false
@objc class func showAlert(
in viewController: UIViewController,
in viewController: UIViewController? = nil,
title: String?,
message: String?,
withCancel: Bool,
@@ -43,6 +43,8 @@ import UIKit
var remainingSeconds = countdown
let originalMessage = message
var isAlertDismissed = false
guard let viewController = viewController else {return}
alertController = UIAlertController(
title: title,
+5 -2
View File
@@ -3564,7 +3564,7 @@ import ObjectiveC.runtime
offshootRootFolders.remove(currentRootFolder)
for folder in offshootRootFolders {
print("offshootRootFolder \(CACurrentMediaTime()) \(folder.label.text ?? "")")
// print("offshootRootFolder \(CACurrentMediaTime()) \(folder.label.text ?? "")")
}
guard !folder.sequenceSet.isEmpty else {return}
@@ -3596,7 +3596,7 @@ import ObjectiveC.runtime
return widgetRef
}
private static func getParentFolders(of widget: OnScreenWidgetView) -> Set<OnScreenWidgetView> {
static func getParentFolders(of widget: OnScreenWidgetView) -> Set<OnScreenWidgetView> {
var parents = Set<OnScreenWidgetView>()
var current = widget
while let parent = OnScreenWidgetView.mapping[current.parentSequence] {
@@ -3637,6 +3637,9 @@ import ObjectiveC.runtime
}
widget.parentSequence = -1
if widget.isFolder {
if widget.folded {
OnScreenWidgetView.set(folded: false, for: widget)
}
for sequence in widget.sequenceSet {
guard let subWidget = OnScreenWidgetView.mapping[sequence] else {continue}
subWidget.parentSequence = -1
+104
View File
@@ -3455,6 +3455,29 @@
}
}
},
"Detailed Tutorial" : {
"extractionState" : "manual",
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "详细教程"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "詳細教程"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "詳細教程"
}
}
}
},
"Detecting..." : {
"extractionState" : "manual",
"localizations" : {
@@ -5022,6 +5045,87 @@
}
}
},
"Folder Button" : {
"extractionState" : "manual",
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "控件夹按键"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "控制項夾按鍵"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "控制項夾按鍵"
}
}
}
},
"folderTutorialTip" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "\nDrag other widgets (buttons or touchpads). Release when the touch point enters the folder’s bounding frame to complete collecting.\n\n- When the folder is unfolded, the collected widget will snap back to its original position.\n\n- When the folder is folded, the grouped widget will be hidden.\n\n- Drag a sub-widget or a folder over the trash icon (do not release) to detach it from the collection."
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "\n拖动其他控件(按键或触控板),当手指触点进入控件夹边框时松开,即可完成收纳。\n\n- 当控件夹处于展开状态时, 被收纳控件将弹回原先的位置。\n\n- 当控件夹处于折叠状态时,被收纳控件将隐藏。\n\n- 拖动子控件或控件夹划过垃圾桶图标(不要松开),即可解除收纳关系。"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "\n拖動其他螢幕控制項(按鍵或觸控板),當手指觸點進入資料夾邊框時放開,即可完成收納。\n\n- 當控制項夾處於展開狀態時,被收納的控制項會彈回原本的位置。\n\n- 當控制項夾處於折疊狀態時,被收納的控制項會隱藏。\n\n- 拖動子控制項或控制項夾按键,劃過垃圾桶圖示(不要放開),即可解除收納關係。\n"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "\n拖動其他螢幕控制項(按鍵或觸控板),當手指觸點進入資料夾邊框時放開,即可完成收納。\n\n- 當控制項夾處於展開狀態時,被收納的控制項會彈回原本的位置。\n\n- 當控制項夾處於折疊狀態時,被收納的控制項會隱藏。\n\n- 拖動子控制項或控制項夾按键,劃過垃圾桶圖示(不要放開),即可解除收納關係。\n"
}
}
}
},
"folderTutorialUrl" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "https://voidlink.yuque.com/org-wiki-voidlink-znirha/fa3tgr/it0qruyul6be8gr1"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "https://voidlink.yuque.com/org-wiki-voidlink-znirha/fa3tgr/li9ogn1rlb50fn52"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "https://voidlink.yuque.com/org-wiki-voidlink-znirha/fa3tgr/li9ogn1rlb50fn52"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "https://voidlink.yuque.com/org-wiki-voidlink-znirha/fa3tgr/li9ogn1rlb50fn52"
}
}
}
},
"Force pencil entering hovering on host" : {
"extractionState" : "manual",
"localizations" : {
+19
View File
@@ -77,6 +77,18 @@ import UIKit
return false
}
@objc static func isFirstTappingFolderInLayoutTool() -> Bool {
let key = "hasTappedFolderInLayoutTool"
let defaults = UserDefaults.standard
let launchedBefore = defaults.bool(forKey: key)
if !launchedBefore {
defaults.set(true, forKey: key)
return true
}
return false
}
@objc static func isFirstTappingInputAccessoryBar() -> Bool {
let key = "isFirstTappingInputAccessoryBar"
let defaults = UserDefaults.standard
@@ -275,6 +287,13 @@ import UIKit
@objc static func toCGFloat(_ str: String) -> CGFloat {
return CGFloat(Double(str) ?? 0)
}
@objc(openUrl:)
static func openUrl(_ urlString: String) {
guard let url = URL(string: urlString),
UIApplication.shared.canOpenURL(url) else { return }
UIApplication.shared.open(url, options: [:], completionHandler: nil)
}
@objc static func isLandscape() -> Bool {
if #available(iOS 13.0, *) {
+1 -3
View File
@@ -400,9 +400,7 @@ import StoreKit
let learnMoreAction = UIAlertAction(title: SwiftLocalizationHelper.localizedString(forKey: "Learn More"), style: .default) { _ in
NotificationCenter.default.post(name: product.purchaseAbortedNotification(), object: PurchaseInterruption.learnMore, userInfo:["interruption": PurchaseInterruption.learnMore.rawValue])
if let url = URL(string: product.productURL()) {
UIApplication.shared.open(url, options: [:], completionHandler: nil)
}
GenericUtils.openUrl(product.productURL())
return
}
@@ -368,6 +368,10 @@ final class LayoutOnScreenControlsViewController: UIViewController, OnScreenWidg
private func loadWidgets(from oscProfile: OSCProfile, to folder: OnScreenWidgetView? = nil) {
var sequence: Int16 = folder == nil ? -1 : (folder?.getAvailableSequence() ?? -1)
var importedWidgetSequenceMap: [Int16: Int16] = [:]
var independentWidgetSequencesPriorToImport: [Int16] = []
var newWidgetBatch: Set<OnScreenWidgetView> = Set()
var hasLegacyWidget = false
for case let encoded as Data in oscProfile.buttonStatesEncoded {
guard let buttonState = self.profilesManager?.unarchiveButtonStateEncoded(encoded) else { continue }
@@ -427,14 +431,31 @@ final class LayoutOnScreenControlsViewController: UIViewController, OnScreenWidg
guard let folder = folder else { continue }
if !folder.folded {
folder.sequenceSet.insert(widgetView.sequence)
widgetView.parentSequence = folder.sequence
if widgetView.parentSequence == -1 {
folder.sequenceSet.insert(widgetView.sequence)
widgetView.parentSequence = folder.sequence
independentWidgetSequencesPriorToImport.append(widgetView.sequence)
}
importedWidgetSequenceMap[buttonState.sequence] = widgetView.sequence
newWidgetBatch.insert(widgetView)
}
} else if buttonState.widgetType == 0 {
hasLegacyWidget = true
}
}
if let folder = folder {
for widget in newWidgetBatch where
widget.isFolder
&& widget.parentSequence != -1
&& widget != folder
{
widget.sequenceSet = Set(widget.sequenceSet.map {importedWidgetSequenceMap[$0] ?? -1})
if !independentWidgetSequencesPriorToImport.contains(widget.sequence) {widget.parentSequence = importedWidgetSequenceMap[widget.parentSequence] ?? -1}
// print("label: \(widget.widgetLabel) sequence: \(widget.sequence) set: \(widget.sequenceSet) parent: \(String(describing: OnScreenWidgetView.mapping[widget.parentSequence]?.widgetLabel))")
}
}
for case let widget as OnScreenWidgetView in self.onScreenWidgetViews {
widget.accessWidgetAttributes()
@@ -984,6 +1005,24 @@ final class LayoutOnScreenControlsViewController: UIViewController, OnScreenWidg
autoFitStack(widgetPanelStack)
}
private func popFolderTutorialTip() {
AlertControllerUtil.cancelButtonString = LocalizationHelper.localizedString(forKey: "Detailed Tutorial")
AlertControllerUtil.showAlert(
in: self,
title: LocalizationHelper.localizedString(forKey: "Folder Button"),
message: LocalizationHelper.localizedString(forKey: "folderTutorialTip"),
withCancel: true,
buttonTitle: SwiftLocalizationHelper.localizedString(forKey: "Got it!"),
countdown: 5,
completion: {
if AlertControllerUtil.actionCancelled {
GenericUtils.openUrl(LocalizationHelper.localizedString(forKey: "folderTutorialUrl"))
}
else {return}
}
)
}
@objc private func widgetViewTapped(_ notification: Notification) {
guard let widgetView = notification.object as? OnScreenWidgetView else { return }
selectedWidgetView = widgetView
@@ -993,6 +1032,10 @@ final class LayoutOnScreenControlsViewController: UIViewController, OnScreenWidg
return
}
refreshPanelForSelectedWidget(widgetView)
if (widgetView.isFolder && GenericUtils.isFirstTappingFolderInLayoutTool()) {
self.popFolderTutorialTip()
}
}
@objc private func legacyOscLayerTapped(_ notification: Notification) {
@@ -1788,10 +1788,7 @@ BOOL isCustomResolution(int resolutionSelected) {
UIAlertAction *readInstruction = [UIAlertAction actionWithTitle:[LocalizationHelper localizedStringForKey:@"Online Documentation"]
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action){
NSURL *url = [NSURL URLWithString:onlineDocLink];
if ([[UIApplication sharedApplication] canOpenURL:url]) {
[[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];
}
[GenericUtils openUrl:onlineDocLink];
}];