folder import fixes
This commit is contained in:
1 parent
efc34ae1fc
commit
363b91b244
7 files changed
+178
-12
No files matched your search
@@ -31,7 +31,7 @@ import UIKit
|
|||||||
@objc public static var autoCompletion:Bool = false
|
@objc public static var autoCompletion:Bool = false
|
||||||
|
|
||||||
@objc class func showAlert(
|
@objc class func showAlert(
|
||||||
in viewController: UIViewController,
|
in viewController: UIViewController? = nil,
|
||||||
title: String?,
|
title: String?,
|
||||||
message: String?,
|
message: String?,
|
||||||
withCancel: Bool,
|
withCancel: Bool,
|
||||||
@@ -44,6 +44,8 @@ import UIKit
|
|||||||
let originalMessage = message
|
let originalMessage = message
|
||||||
var isAlertDismissed = false
|
var isAlertDismissed = false
|
||||||
|
|
||||||
|
guard let viewController = viewController else {return}
|
||||||
|
|
||||||
alertController = UIAlertController(
|
alertController = UIAlertController(
|
||||||
title: title,
|
title: title,
|
||||||
message: (countdown > 0 && !autoCompletion) ? makeCountdownMessage(baseMessage: originalMessage, remainingSeconds: remainingSeconds) : message,
|
message: (countdown > 0 && !autoCompletion) ? makeCountdownMessage(baseMessage: originalMessage, remainingSeconds: remainingSeconds) : message,
|
||||||
|
|||||||
@@ -3564,7 +3564,7 @@ import ObjectiveC.runtime
|
|||||||
|
|
||||||
offshootRootFolders.remove(currentRootFolder)
|
offshootRootFolders.remove(currentRootFolder)
|
||||||
for folder in offshootRootFolders {
|
for folder in offshootRootFolders {
|
||||||
print("offshootRootFolder \(CACurrentMediaTime()) \(folder.label.text ?? "")")
|
// print("offshootRootFolder \(CACurrentMediaTime()) \(folder.label.text ?? "")")
|
||||||
}
|
}
|
||||||
|
|
||||||
guard !folder.sequenceSet.isEmpty else {return}
|
guard !folder.sequenceSet.isEmpty else {return}
|
||||||
@@ -3596,7 +3596,7 @@ import ObjectiveC.runtime
|
|||||||
return widgetRef
|
return widgetRef
|
||||||
}
|
}
|
||||||
|
|
||||||
private static func getParentFolders(of widget: OnScreenWidgetView) -> Set<OnScreenWidgetView> {
|
static func getParentFolders(of widget: OnScreenWidgetView) -> Set<OnScreenWidgetView> {
|
||||||
var parents = Set<OnScreenWidgetView>()
|
var parents = Set<OnScreenWidgetView>()
|
||||||
var current = widget
|
var current = widget
|
||||||
while let parent = OnScreenWidgetView.mapping[current.parentSequence] {
|
while let parent = OnScreenWidgetView.mapping[current.parentSequence] {
|
||||||
@@ -3637,6 +3637,9 @@ import ObjectiveC.runtime
|
|||||||
}
|
}
|
||||||
widget.parentSequence = -1
|
widget.parentSequence = -1
|
||||||
if widget.isFolder {
|
if widget.isFolder {
|
||||||
|
if widget.folded {
|
||||||
|
OnScreenWidgetView.set(folded: false, for: widget)
|
||||||
|
}
|
||||||
for sequence in widget.sequenceSet {
|
for sequence in widget.sequenceSet {
|
||||||
guard let subWidget = OnScreenWidgetView.mapping[sequence] else {continue}
|
guard let subWidget = OnScreenWidgetView.mapping[sequence] else {continue}
|
||||||
subWidget.parentSequence = -1
|
subWidget.parentSequence = -1
|
||||||
|
|||||||
@@ -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..." : {
|
"Detecting..." : {
|
||||||
"extractionState" : "manual",
|
"extractionState" : "manual",
|
||||||
"localizations" : {
|
"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" : {
|
"Force pencil entering hovering on host" : {
|
||||||
"extractionState" : "manual",
|
"extractionState" : "manual",
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
|
|||||||
@@ -77,6 +77,18 @@ import UIKit
|
|||||||
return false
|
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 {
|
@objc static func isFirstTappingInputAccessoryBar() -> Bool {
|
||||||
let key = "isFirstTappingInputAccessoryBar"
|
let key = "isFirstTappingInputAccessoryBar"
|
||||||
let defaults = UserDefaults.standard
|
let defaults = UserDefaults.standard
|
||||||
@@ -276,6 +288,13 @@ import UIKit
|
|||||||
return CGFloat(Double(str) ?? 0)
|
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 {
|
@objc static func isLandscape() -> Bool {
|
||||||
if #available(iOS 13.0, *) {
|
if #available(iOS 13.0, *) {
|
||||||
guard let windowScene = UIApplication.shared.connectedScenes
|
guard let windowScene = UIApplication.shared.connectedScenes
|
||||||
|
|||||||
@@ -400,9 +400,7 @@ import StoreKit
|
|||||||
|
|
||||||
let learnMoreAction = UIAlertAction(title: SwiftLocalizationHelper.localizedString(forKey: "Learn More"), style: .default) { _ in
|
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])
|
NotificationCenter.default.post(name: product.purchaseAbortedNotification(), object: PurchaseInterruption.learnMore, userInfo:["interruption": PurchaseInterruption.learnMore.rawValue])
|
||||||
if let url = URL(string: product.productURL()) {
|
GenericUtils.openUrl(product.productURL())
|
||||||
UIApplication.shared.open(url, options: [:], completionHandler: nil)
|
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+45
-2
@@ -368,6 +368,10 @@ final class LayoutOnScreenControlsViewController: UIViewController, OnScreenWidg
|
|||||||
|
|
||||||
private func loadWidgets(from oscProfile: OSCProfile, to folder: OnScreenWidgetView? = nil) {
|
private func loadWidgets(from oscProfile: OSCProfile, to folder: OnScreenWidgetView? = nil) {
|
||||||
var sequence: Int16 = folder == nil ? -1 : (folder?.getAvailableSequence() ?? -1)
|
var sequence: Int16 = folder == nil ? -1 : (folder?.getAvailableSequence() ?? -1)
|
||||||
|
var importedWidgetSequenceMap: [Int16: Int16] = [:]
|
||||||
|
var independentWidgetSequencesPriorToImport: [Int16] = []
|
||||||
|
var newWidgetBatch: Set<OnScreenWidgetView> = Set()
|
||||||
|
|
||||||
var hasLegacyWidget = false
|
var hasLegacyWidget = false
|
||||||
for case let encoded as Data in oscProfile.buttonStatesEncoded {
|
for case let encoded as Data in oscProfile.buttonStatesEncoded {
|
||||||
guard let buttonState = self.profilesManager?.unarchiveButtonStateEncoded(encoded) else { continue }
|
guard let buttonState = self.profilesManager?.unarchiveButtonStateEncoded(encoded) else { continue }
|
||||||
@@ -427,8 +431,13 @@ final class LayoutOnScreenControlsViewController: UIViewController, OnScreenWidg
|
|||||||
|
|
||||||
guard let folder = folder else { continue }
|
guard let folder = folder else { continue }
|
||||||
if !folder.folded {
|
if !folder.folded {
|
||||||
folder.sequenceSet.insert(widgetView.sequence)
|
if widgetView.parentSequence == -1 {
|
||||||
widgetView.parentSequence = folder.sequence
|
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 {
|
} else if buttonState.widgetType == 0 {
|
||||||
@@ -436,6 +445,18 @@ final class LayoutOnScreenControlsViewController: UIViewController, OnScreenWidg
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 {
|
for case let widget as OnScreenWidgetView in self.onScreenWidgetViews {
|
||||||
widget.accessWidgetAttributes()
|
widget.accessWidgetAttributes()
|
||||||
}
|
}
|
||||||
@@ -984,6 +1005,24 @@ final class LayoutOnScreenControlsViewController: UIViewController, OnScreenWidg
|
|||||||
autoFitStack(widgetPanelStack)
|
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) {
|
@objc private func widgetViewTapped(_ notification: Notification) {
|
||||||
guard let widgetView = notification.object as? OnScreenWidgetView else { return }
|
guard let widgetView = notification.object as? OnScreenWidgetView else { return }
|
||||||
selectedWidgetView = widgetView
|
selectedWidgetView = widgetView
|
||||||
@@ -993,6 +1032,10 @@ final class LayoutOnScreenControlsViewController: UIViewController, OnScreenWidg
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
refreshPanelForSelectedWidget(widgetView)
|
refreshPanelForSelectedWidget(widgetView)
|
||||||
|
|
||||||
|
if (widgetView.isFolder && GenericUtils.isFirstTappingFolderInLayoutTool()) {
|
||||||
|
self.popFolderTutorialTip()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc private func legacyOscLayerTapped(_ notification: Notification) {
|
@objc private func legacyOscLayerTapped(_ notification: Notification) {
|
||||||
|
|||||||
@@ -1788,10 +1788,7 @@ BOOL isCustomResolution(int resolutionSelected) {
|
|||||||
UIAlertAction *readInstruction = [UIAlertAction actionWithTitle:[LocalizationHelper localizedStringForKey:@"Online Documentation"]
|
UIAlertAction *readInstruction = [UIAlertAction actionWithTitle:[LocalizationHelper localizedStringForKey:@"Online Documentation"]
|
||||||
style:UIAlertActionStyleDefault
|
style:UIAlertActionStyleDefault
|
||||||
handler:^(UIAlertAction *action){
|
handler:^(UIAlertAction *action){
|
||||||
NSURL *url = [NSURL URLWithString:onlineDocLink];
|
[GenericUtils openUrl:onlineDocLink];
|
||||||
if ([[UIApplication sharedApplication] canOpenURL:url]) {
|
|
||||||
[[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];
|
|
||||||
}
|
|
||||||
}];
|
}];
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user