@capgo/capacitor-updater 8.48.0 → 8.49.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +186 -8
- package/android/src/main/java/ee/forgr/capacitor_updater/CapacitorUpdaterPlugin.java +645 -111
- package/android/src/main/java/ee/forgr/capacitor_updater/ShakeMenu.java +203 -30
- package/android/src/main/java/ee/forgr/capacitor_updater/ThreeFingerPinchDetector.java +1 -1
- package/dist/docs.json +528 -17
- package/dist/esm/definitions.d.ts +228 -10
- package/dist/esm/definitions.js.map +1 -1
- package/dist/esm/web.d.ts +7 -1
- package/dist/esm/web.js +24 -0
- package/dist/esm/web.js.map +1 -1
- package/dist/plugin.cjs.js +24 -0
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js +24 -0
- package/dist/plugin.js.map +1 -1
- package/ios/Sources/CapacitorUpdaterPlugin/CapacitorUpdaterPlugin.swift +538 -77
- package/ios/Sources/CapacitorUpdaterPlugin/ShakeMenu.swift +225 -16
- package/package.json +1 -1
|
@@ -38,6 +38,12 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
38
38
|
CAPPluginMethod(name: "setChannelUrl", returnType: CAPPluginReturnPromise),
|
|
39
39
|
CAPPluginMethod(name: "set", returnType: CAPPluginReturnPromise),
|
|
40
40
|
CAPPluginMethod(name: "startPreviewSession", returnType: CAPPluginReturnPromise),
|
|
41
|
+
CAPPluginMethod(name: "listPreviews", returnType: CAPPluginReturnPromise),
|
|
42
|
+
CAPPluginMethod(name: "setPreview", returnType: CAPPluginReturnPromise),
|
|
43
|
+
CAPPluginMethod(name: "resetPreview", returnType: CAPPluginReturnPromise),
|
|
44
|
+
CAPPluginMethod(name: "deletePreview", returnType: CAPPluginReturnPromise),
|
|
45
|
+
CAPPluginMethod(name: "checkPreviewUpdate", returnType: CAPPluginReturnPromise),
|
|
46
|
+
CAPPluginMethod(name: "updatePreview", returnType: CAPPluginReturnPromise),
|
|
41
47
|
CAPPluginMethod(name: "list", returnType: CAPPluginReturnPromise),
|
|
42
48
|
CAPPluginMethod(name: "delete", returnType: CAPPluginReturnPromise),
|
|
43
49
|
CAPPluginMethod(name: "setBundleError", returnType: CAPPluginReturnPromise),
|
|
@@ -79,7 +85,7 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
79
85
|
CAPPluginMethod(name: "completeFlexibleUpdate", returnType: CAPPluginReturnPromise)
|
|
80
86
|
]
|
|
81
87
|
public var implementation = CapgoUpdater()
|
|
82
|
-
private let pluginVersion: String = "8.
|
|
88
|
+
private let pluginVersion: String = "8.49.0"
|
|
83
89
|
static let updateUrlDefault = "https://plugin.capgo.app/updates"
|
|
84
90
|
static let statsUrlDefault = "https://plugin.capgo.app/stats"
|
|
85
91
|
static let channelUrlDefault = "https://plugin.capgo.app/channel_self"
|
|
@@ -108,6 +114,9 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
108
114
|
private let previewPreviousDefaultChannelWasSetDefaultsKey = "CapacitorUpdater.previewPreviousDefaultChannelWasSet"
|
|
109
115
|
private let previewAppIdDefaultsKey = "CapacitorUpdater.previewAppId"
|
|
110
116
|
private let previewPayloadUrlDefaultsKey = "CapacitorUpdater.previewPayloadUrl"
|
|
117
|
+
private let previewNameDefaultsKey = "CapacitorUpdater.previewName"
|
|
118
|
+
private let previewSourceDefaultsKey = "CapacitorUpdater.previewSource"
|
|
119
|
+
private let previewSessionsDefaultsKey = "CapacitorUpdater.previewSessions"
|
|
111
120
|
private let previewSessionAlertPendingDefaultsKey = "CapacitorUpdater.previewSessionAlertPending"
|
|
112
121
|
private let previewDeepLinkScheme = "capgo"
|
|
113
122
|
private let previewDeepLinkRootComponent = "preview"
|
|
@@ -170,7 +179,7 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
170
179
|
public var shakeMenuEnabled = false
|
|
171
180
|
public var shakeChannelSelectorEnabled = false
|
|
172
181
|
public var shakeMenuGesture = CapacitorUpdaterPlugin.shakeMenuGestureShake
|
|
173
|
-
var shakeMenuPinchGestureRecognizer:
|
|
182
|
+
var shakeMenuPinchGestureRecognizer: ThreeFingerPinchGestureRecognizer?
|
|
174
183
|
var shakeMenuPinchGestureTriggered = false
|
|
175
184
|
public var previewSessionEnabled = false
|
|
176
185
|
private var previewSessionAlertPending = false
|
|
@@ -822,6 +831,226 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
822
831
|
let error: String?
|
|
823
832
|
}
|
|
824
833
|
|
|
834
|
+
private func normalizedPreviewMetadataValue(_ rawValue: String?) -> String? {
|
|
835
|
+
guard let rawValue else {
|
|
836
|
+
return nil
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
let value = rawValue.trimmingCharacters(in: .whitespacesAndNewlines)
|
|
840
|
+
guard !value.isEmpty else {
|
|
841
|
+
return nil
|
|
842
|
+
}
|
|
843
|
+
|
|
844
|
+
let lowercased = value.lowercased()
|
|
845
|
+
guard lowercased != "undefined", lowercased != "null" else {
|
|
846
|
+
return nil
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
return value
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
private func previewSessions() -> [String: [String: Any]] {
|
|
853
|
+
guard let rawSessions = UserDefaults.standard.dictionary(forKey: self.previewSessionsDefaultsKey) else {
|
|
854
|
+
return [:]
|
|
855
|
+
}
|
|
856
|
+
|
|
857
|
+
var sessions: [String: [String: Any]] = [:]
|
|
858
|
+
for (id, rawValue) in rawSessions {
|
|
859
|
+
if let session = rawValue as? [String: Any] {
|
|
860
|
+
sessions[id] = session
|
|
861
|
+
}
|
|
862
|
+
}
|
|
863
|
+
return sessions
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
private func savePreviewSessions(_ sessions: [String: [String: Any]]) {
|
|
867
|
+
UserDefaults.standard.set(sessions, forKey: self.previewSessionsDefaultsKey)
|
|
868
|
+
UserDefaults.standard.synchronize()
|
|
869
|
+
}
|
|
870
|
+
|
|
871
|
+
private func metadataString(_ metadata: [String: Any], _ key: String) -> String? {
|
|
872
|
+
self.normalizedPreviewMetadataValue(metadata[key] as? String)
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
private func currentPreviewMetadataValue(forKey key: String) -> String? {
|
|
876
|
+
self.normalizedPreviewMetadataValue(UserDefaults.standard.string(forKey: key))
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
private func previewInfo(
|
|
880
|
+
id: String,
|
|
881
|
+
metadata: [String: Any],
|
|
882
|
+
availableBundleIds: Set<String>,
|
|
883
|
+
currentBundleId: String
|
|
884
|
+
) -> [String: Any]? {
|
|
885
|
+
let bundle = self.implementation.getBundleInfo(id: id)
|
|
886
|
+
if !bundle.isBuiltin() && !availableBundleIds.contains(id) {
|
|
887
|
+
return nil
|
|
888
|
+
}
|
|
889
|
+
if bundle.isDeleted() || bundle.isErrorStatus() {
|
|
890
|
+
return nil
|
|
891
|
+
}
|
|
892
|
+
|
|
893
|
+
var info: [String: Any] = [
|
|
894
|
+
"id": id,
|
|
895
|
+
"bundle": bundle.toJSON(),
|
|
896
|
+
"createdAt": self.metadataString(metadata, "createdAt") ?? Date().iso8601withFractionalSeconds,
|
|
897
|
+
"updatedAt": self.metadataString(metadata, "updatedAt") ?? Date().iso8601withFractionalSeconds,
|
|
898
|
+
"lastUsedAt": self.metadataString(metadata, "lastUsedAt") ?? Date().iso8601withFractionalSeconds,
|
|
899
|
+
"isActive": self.previewSessionEnabled && currentBundleId == id
|
|
900
|
+
]
|
|
901
|
+
|
|
902
|
+
for key in ["name", "source", "appId", "payloadUrl"] {
|
|
903
|
+
if let value = self.metadataString(metadata, key) {
|
|
904
|
+
info[key] = value
|
|
905
|
+
}
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
return info
|
|
909
|
+
}
|
|
910
|
+
|
|
911
|
+
private func listPreviewInfos(cleanup: Bool = true) -> [[String: Any]] {
|
|
912
|
+
let availableBundleIds = Set(self.implementation.list().map { $0.getId() })
|
|
913
|
+
let currentBundleId = self.implementation.getCurrentBundleId()
|
|
914
|
+
var sessions = self.previewSessions()
|
|
915
|
+
var previews: [[String: Any]] = []
|
|
916
|
+
var staleIds: [String] = []
|
|
917
|
+
|
|
918
|
+
for (id, metadata) in sessions {
|
|
919
|
+
if let info = self.previewInfo(
|
|
920
|
+
id: id,
|
|
921
|
+
metadata: metadata,
|
|
922
|
+
availableBundleIds: availableBundleIds,
|
|
923
|
+
currentBundleId: currentBundleId
|
|
924
|
+
) {
|
|
925
|
+
previews.append(info)
|
|
926
|
+
} else {
|
|
927
|
+
staleIds.append(id)
|
|
928
|
+
}
|
|
929
|
+
}
|
|
930
|
+
|
|
931
|
+
if cleanup && !staleIds.isEmpty {
|
|
932
|
+
for id in staleIds {
|
|
933
|
+
sessions.removeValue(forKey: id)
|
|
934
|
+
}
|
|
935
|
+
self.savePreviewSessions(sessions)
|
|
936
|
+
}
|
|
937
|
+
|
|
938
|
+
return previews.sorted { first, second in
|
|
939
|
+
let firstUsed = first["lastUsedAt"] as? String ?? ""
|
|
940
|
+
let secondUsed = second["lastUsedAt"] as? String ?? ""
|
|
941
|
+
return firstUsed > secondUsed
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
|
|
945
|
+
private func storedPreviewInfo(id: String) -> [String: Any]? {
|
|
946
|
+
let sessions = self.previewSessions()
|
|
947
|
+
guard let metadata = sessions[id] else {
|
|
948
|
+
return nil
|
|
949
|
+
}
|
|
950
|
+
let availableBundleIds = Set(self.implementation.list().map { $0.getId() })
|
|
951
|
+
return self.previewInfo(
|
|
952
|
+
id: id,
|
|
953
|
+
metadata: metadata,
|
|
954
|
+
availableBundleIds: availableBundleIds,
|
|
955
|
+
currentBundleId: self.implementation.getCurrentBundleId()
|
|
956
|
+
)
|
|
957
|
+
}
|
|
958
|
+
|
|
959
|
+
@discardableResult
|
|
960
|
+
private func recordPreviewBundle(_ bundle: BundleInfo, replacing oldId: String? = nil) -> [String: Any] {
|
|
961
|
+
let now = Date().iso8601withFractionalSeconds
|
|
962
|
+
var sessions = self.previewSessions()
|
|
963
|
+
let id = bundle.getId()
|
|
964
|
+
let replacingPreview = oldId.map { $0 != id } ?? false
|
|
965
|
+
var metadata = sessions[id] ?? (replacingPreview ? sessions[oldId ?? ""] ?? [:] : [:])
|
|
966
|
+
|
|
967
|
+
if metadata["createdAt"] == nil {
|
|
968
|
+
metadata["createdAt"] = now
|
|
969
|
+
}
|
|
970
|
+
metadata["updatedAt"] = now
|
|
971
|
+
if metadata["lastUsedAt"] == nil || self.implementation.getCurrentBundleId() == id {
|
|
972
|
+
metadata["lastUsedAt"] = now
|
|
973
|
+
}
|
|
974
|
+
metadata["version"] = bundle.getVersionName()
|
|
975
|
+
|
|
976
|
+
if !replacingPreview {
|
|
977
|
+
if let appId = self.currentPreviewMetadataValue(forKey: self.previewAppIdDefaultsKey) {
|
|
978
|
+
metadata["appId"] = appId
|
|
979
|
+
} else {
|
|
980
|
+
metadata.removeValue(forKey: "appId")
|
|
981
|
+
}
|
|
982
|
+
|
|
983
|
+
if let payloadUrl = self.currentPreviewMetadataValue(forKey: self.previewPayloadUrlDefaultsKey) {
|
|
984
|
+
metadata["payloadUrl"] = payloadUrl
|
|
985
|
+
} else {
|
|
986
|
+
metadata.removeValue(forKey: "payloadUrl")
|
|
987
|
+
}
|
|
988
|
+
}
|
|
989
|
+
|
|
990
|
+
if !replacingPreview {
|
|
991
|
+
if let name = self.currentPreviewMetadataValue(forKey: self.previewNameDefaultsKey) {
|
|
992
|
+
metadata["name"] = name
|
|
993
|
+
} else {
|
|
994
|
+
metadata.removeValue(forKey: "name")
|
|
995
|
+
}
|
|
996
|
+
}
|
|
997
|
+
if self.metadataString(metadata, "name") == nil {
|
|
998
|
+
metadata["name"] = bundle.getVersionName()
|
|
999
|
+
}
|
|
1000
|
+
|
|
1001
|
+
if !replacingPreview {
|
|
1002
|
+
if let source = self.currentPreviewMetadataValue(forKey: self.previewSourceDefaultsKey) {
|
|
1003
|
+
metadata["source"] = source
|
|
1004
|
+
} else {
|
|
1005
|
+
metadata.removeValue(forKey: "source")
|
|
1006
|
+
}
|
|
1007
|
+
}
|
|
1008
|
+
|
|
1009
|
+
if let oldId, oldId != id {
|
|
1010
|
+
sessions.removeValue(forKey: oldId)
|
|
1011
|
+
}
|
|
1012
|
+
sessions[id] = metadata
|
|
1013
|
+
self.savePreviewSessions(sessions)
|
|
1014
|
+
|
|
1015
|
+
return self.storedPreviewInfo(id: id) ?? [
|
|
1016
|
+
"id": id,
|
|
1017
|
+
"bundle": bundle.toJSON(),
|
|
1018
|
+
"createdAt": now,
|
|
1019
|
+
"updatedAt": now,
|
|
1020
|
+
"lastUsedAt": now,
|
|
1021
|
+
"isActive": self.previewSessionEnabled && self.implementation.getCurrentBundleId() == id
|
|
1022
|
+
]
|
|
1023
|
+
}
|
|
1024
|
+
|
|
1025
|
+
private func updateCurrentPreviewSessionMetadata(from preview: [String: Any]) {
|
|
1026
|
+
if let appId = self.metadataString(preview, "appId") {
|
|
1027
|
+
self.implementation.appId = appId
|
|
1028
|
+
UserDefaults.standard.set(appId, forKey: self.previewAppIdDefaultsKey)
|
|
1029
|
+
} else {
|
|
1030
|
+
self.restorePreviewPreviousAppId()
|
|
1031
|
+
UserDefaults.standard.removeObject(forKey: self.previewAppIdDefaultsKey)
|
|
1032
|
+
}
|
|
1033
|
+
|
|
1034
|
+
if let payloadUrl = self.metadataString(preview, "payloadUrl") {
|
|
1035
|
+
UserDefaults.standard.set(payloadUrl, forKey: self.previewPayloadUrlDefaultsKey)
|
|
1036
|
+
} else {
|
|
1037
|
+
UserDefaults.standard.removeObject(forKey: self.previewPayloadUrlDefaultsKey)
|
|
1038
|
+
}
|
|
1039
|
+
|
|
1040
|
+
if let name = self.metadataString(preview, "name") {
|
|
1041
|
+
UserDefaults.standard.set(name, forKey: self.previewNameDefaultsKey)
|
|
1042
|
+
} else {
|
|
1043
|
+
UserDefaults.standard.removeObject(forKey: self.previewNameDefaultsKey)
|
|
1044
|
+
}
|
|
1045
|
+
|
|
1046
|
+
if let source = self.metadataString(preview, "source") {
|
|
1047
|
+
UserDefaults.standard.set(source, forKey: self.previewSourceDefaultsKey)
|
|
1048
|
+
} else {
|
|
1049
|
+
UserDefaults.standard.removeObject(forKey: self.previewSourceDefaultsKey)
|
|
1050
|
+
}
|
|
1051
|
+
UserDefaults.standard.synchronize()
|
|
1052
|
+
}
|
|
1053
|
+
|
|
825
1054
|
private func makePreviewError(_ message: String) -> NSError {
|
|
826
1055
|
NSError(domain: "CapacitorUpdaterPreview", code: 0, userInfo: [NSLocalizedDescriptionKey: message])
|
|
827
1056
|
}
|
|
@@ -1113,6 +1342,16 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
1113
1342
|
if !res {
|
|
1114
1343
|
logger.info("Bundle successfully set to: \(id) ")
|
|
1115
1344
|
call.reject("Update failed, id \(id) doesn't exist")
|
|
1345
|
+
} else if self.previewSessionEnabled {
|
|
1346
|
+
let bundle = self.implementation.getBundleInfo(id: id)
|
|
1347
|
+
_ = self.recordPreviewBundle(bundle)
|
|
1348
|
+
if !self.reloadWithoutWaitingForAppReady() {
|
|
1349
|
+
call.reject("Reload failed after setting preview bundle \(id)")
|
|
1350
|
+
return
|
|
1351
|
+
}
|
|
1352
|
+
self.notifyBundleSet(bundle)
|
|
1353
|
+
self.showPreviewSessionNoticeIfNeeded()
|
|
1354
|
+
call.resolve()
|
|
1116
1355
|
} else if !self._reload() {
|
|
1117
1356
|
call.reject("Reload failed after setting bundle \(id)")
|
|
1118
1357
|
} else {
|
|
@@ -1153,6 +1392,52 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
1153
1392
|
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(self.appReadyTimeout), execute: workItem)
|
|
1154
1393
|
}
|
|
1155
1394
|
|
|
1395
|
+
private func preparePreviewFallbackIfNeeded() -> Bool {
|
|
1396
|
+
if self.previewSessionEnabled {
|
|
1397
|
+
return true
|
|
1398
|
+
}
|
|
1399
|
+
|
|
1400
|
+
let current = self.implementation.getCurrentBundle()
|
|
1401
|
+
guard self.implementation.setPreviewFallbackBundle(fallback: current.getId()) else {
|
|
1402
|
+
logger.error("Could not save current bundle as preview fallback")
|
|
1403
|
+
return false
|
|
1404
|
+
}
|
|
1405
|
+
|
|
1406
|
+
if let previousNext = self.implementation.getNextBundle(),
|
|
1407
|
+
!previousNext.isDeleted(),
|
|
1408
|
+
!previousNext.isErrorStatus() {
|
|
1409
|
+
UserDefaults.standard.set(previousNext.getId(), forKey: self.previewPreviousNextBundleDefaultsKey)
|
|
1410
|
+
} else {
|
|
1411
|
+
UserDefaults.standard.removeObject(forKey: self.previewPreviousNextBundleDefaultsKey)
|
|
1412
|
+
}
|
|
1413
|
+
|
|
1414
|
+
UserDefaults.standard.set(self.implementation.appId, forKey: self.previewPreviousAppIdDefaultsKey)
|
|
1415
|
+
if let previousDefaultChannel = UserDefaults.standard.object(forKey: self.defaultChannelDefaultsKey) as? String {
|
|
1416
|
+
UserDefaults.standard.set(previousDefaultChannel, forKey: self.previewPreviousDefaultChannelDefaultsKey)
|
|
1417
|
+
UserDefaults.standard.set(true, forKey: self.previewPreviousDefaultChannelWasSetDefaultsKey)
|
|
1418
|
+
} else {
|
|
1419
|
+
UserDefaults.standard.removeObject(forKey: self.previewPreviousDefaultChannelDefaultsKey)
|
|
1420
|
+
UserDefaults.standard.set(false, forKey: self.previewPreviousDefaultChannelWasSetDefaultsKey)
|
|
1421
|
+
}
|
|
1422
|
+
UserDefaults.standard.set(self.shakeMenuEnabled, forKey: self.previewPreviousShakeMenuDefaultsKey)
|
|
1423
|
+
UserDefaults.standard.set(self.shakeChannelSelectorEnabled, forKey: self.previewPreviousShakeChannelSelectorDefaultsKey)
|
|
1424
|
+
logger.info("Preview session started with fallback bundle: \(current.toString())")
|
|
1425
|
+
return true
|
|
1426
|
+
}
|
|
1427
|
+
|
|
1428
|
+
private func activatePreviewSessionState() {
|
|
1429
|
+
self.clearIncomingPreviewTransition()
|
|
1430
|
+
self.hidePreviewTransitionLoader(reason: "preview-session-started")
|
|
1431
|
+
self.previewSessionEnabled = true
|
|
1432
|
+
self.previewSessionAlertPending = true
|
|
1433
|
+
self.implementation.previewSession = true
|
|
1434
|
+
self.shakeMenuEnabled = true
|
|
1435
|
+
self.syncShakeMenuGestureRecognizer()
|
|
1436
|
+
UserDefaults.standard.set(true, forKey: self.previewSessionDefaultsKey)
|
|
1437
|
+
UserDefaults.standard.set(true, forKey: self.previewSessionAlertPendingDefaultsKey)
|
|
1438
|
+
UserDefaults.standard.synchronize()
|
|
1439
|
+
}
|
|
1440
|
+
|
|
1156
1441
|
@objc func startPreviewSession(_ call: CAPPluginCall) {
|
|
1157
1442
|
guard self.allowPreview else {
|
|
1158
1443
|
self.hidePreviewTransitionLoader(reason: "preview-session-not-allowed")
|
|
@@ -1170,34 +1455,10 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
1170
1455
|
return
|
|
1171
1456
|
}
|
|
1172
1457
|
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
logger.error("Could not save current bundle as preview fallback")
|
|
1178
|
-
call.reject("Could not save current bundle as preview fallback")
|
|
1179
|
-
return
|
|
1180
|
-
}
|
|
1181
|
-
|
|
1182
|
-
if let previousNext = self.implementation.getNextBundle(),
|
|
1183
|
-
!previousNext.isDeleted(),
|
|
1184
|
-
!previousNext.isErrorStatus() {
|
|
1185
|
-
UserDefaults.standard.set(previousNext.getId(), forKey: self.previewPreviousNextBundleDefaultsKey)
|
|
1186
|
-
} else {
|
|
1187
|
-
UserDefaults.standard.removeObject(forKey: self.previewPreviousNextBundleDefaultsKey)
|
|
1188
|
-
}
|
|
1189
|
-
|
|
1190
|
-
UserDefaults.standard.set(self.implementation.appId, forKey: self.previewPreviousAppIdDefaultsKey)
|
|
1191
|
-
if let previousDefaultChannel = UserDefaults.standard.object(forKey: self.defaultChannelDefaultsKey) as? String {
|
|
1192
|
-
UserDefaults.standard.set(previousDefaultChannel, forKey: self.previewPreviousDefaultChannelDefaultsKey)
|
|
1193
|
-
UserDefaults.standard.set(true, forKey: self.previewPreviousDefaultChannelWasSetDefaultsKey)
|
|
1194
|
-
} else {
|
|
1195
|
-
UserDefaults.standard.removeObject(forKey: self.previewPreviousDefaultChannelDefaultsKey)
|
|
1196
|
-
UserDefaults.standard.set(false, forKey: self.previewPreviousDefaultChannelWasSetDefaultsKey)
|
|
1197
|
-
}
|
|
1198
|
-
UserDefaults.standard.set(self.shakeMenuEnabled, forKey: self.previewPreviousShakeMenuDefaultsKey)
|
|
1199
|
-
UserDefaults.standard.set(self.shakeChannelSelectorEnabled, forKey: self.previewPreviousShakeChannelSelectorDefaultsKey)
|
|
1200
|
-
logger.info("Preview session started with fallback bundle: \(current.toString())")
|
|
1458
|
+
guard self.preparePreviewFallbackIfNeeded() else {
|
|
1459
|
+
self.hidePreviewTransitionLoader(reason: "preview-session-fallback-failed")
|
|
1460
|
+
call.reject("Could not save current bundle as preview fallback")
|
|
1461
|
+
return
|
|
1201
1462
|
}
|
|
1202
1463
|
|
|
1203
1464
|
if let previewAppId = previewAppId, !previewAppId.isEmpty {
|
|
@@ -1213,22 +1474,251 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
1213
1474
|
UserDefaults.standard.removeObject(forKey: self.previewPayloadUrlDefaultsKey)
|
|
1214
1475
|
}
|
|
1215
1476
|
|
|
1216
|
-
self.
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
self.
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1477
|
+
if let previewName = self.normalizedPreviewMetadataValue(call.getString("name")) {
|
|
1478
|
+
UserDefaults.standard.set(previewName, forKey: self.previewNameDefaultsKey)
|
|
1479
|
+
} else {
|
|
1480
|
+
UserDefaults.standard.removeObject(forKey: self.previewNameDefaultsKey)
|
|
1481
|
+
}
|
|
1482
|
+
|
|
1483
|
+
if let previewSource = self.normalizedPreviewMetadataValue(call.getString("source")) {
|
|
1484
|
+
UserDefaults.standard.set(previewSource, forKey: self.previewSourceDefaultsKey)
|
|
1485
|
+
} else {
|
|
1486
|
+
UserDefaults.standard.removeObject(forKey: self.previewSourceDefaultsKey)
|
|
1487
|
+
}
|
|
1488
|
+
|
|
1489
|
+
self.activatePreviewSessionState()
|
|
1226
1490
|
call.resolve()
|
|
1227
1491
|
}
|
|
1228
1492
|
|
|
1229
|
-
func
|
|
1230
|
-
|
|
1493
|
+
@objc func listPreviews(_ call: CAPPluginCall) {
|
|
1494
|
+
guard self.allowPreview else {
|
|
1495
|
+
call.reject("listPreviews not allowed. Set allowPreview to true in your config to enable it.")
|
|
1496
|
+
return
|
|
1497
|
+
}
|
|
1498
|
+
|
|
1499
|
+
let previews = self.listPreviewInfos()
|
|
1500
|
+
var result: [String: Any] = [
|
|
1501
|
+
"previews": previews,
|
|
1502
|
+
"currentBundle": self.implementation.getCurrentBundle().toJSON()
|
|
1503
|
+
]
|
|
1504
|
+
if let currentPreview = previews.first(where: { ($0["isActive"] as? Bool) == true }) {
|
|
1505
|
+
result["current"] = currentPreview
|
|
1506
|
+
}
|
|
1507
|
+
if let liveBundle = self.implementation.getPreviewFallbackBundle() {
|
|
1508
|
+
result["liveBundle"] = liveBundle.toJSON()
|
|
1509
|
+
}
|
|
1510
|
+
call.resolve(result)
|
|
1511
|
+
}
|
|
1512
|
+
|
|
1513
|
+
@objc func setPreview(_ call: CAPPluginCall) {
|
|
1514
|
+
guard self.allowPreview else {
|
|
1515
|
+
call.reject("setPreview not allowed. Set allowPreview to true in your config to enable it.")
|
|
1516
|
+
return
|
|
1517
|
+
}
|
|
1518
|
+
guard let id = call.getString("id"), !id.isEmpty else {
|
|
1519
|
+
call.reject("setPreview called without id")
|
|
1520
|
+
return
|
|
1521
|
+
}
|
|
1522
|
+
guard let preview = self.storedPreviewInfo(id: id) else {
|
|
1523
|
+
call.reject("Preview \(id) is not available locally")
|
|
1524
|
+
return
|
|
1525
|
+
}
|
|
1526
|
+
|
|
1527
|
+
self.showPreviewTransitionLoader(reason: "set-preview")
|
|
1528
|
+
DispatchQueue.global(qos: .userInitiated).async {
|
|
1529
|
+
guard self.preparePreviewFallbackIfNeeded() else {
|
|
1530
|
+
self.hidePreviewTransitionLoader(reason: "set-preview-fallback-failed")
|
|
1531
|
+
call.reject("Could not save current bundle as preview fallback")
|
|
1532
|
+
return
|
|
1533
|
+
}
|
|
1534
|
+
|
|
1535
|
+
guard self.implementation.set(id: id) else {
|
|
1536
|
+
self.hidePreviewTransitionLoader(reason: "set-preview-failed")
|
|
1537
|
+
call.reject("Preview \(id) cannot be applied")
|
|
1538
|
+
return
|
|
1539
|
+
}
|
|
1540
|
+
|
|
1541
|
+
let bundle = self.implementation.getBundleInfo(id: id)
|
|
1542
|
+
self.updateCurrentPreviewSessionMetadata(from: preview)
|
|
1543
|
+
self.activatePreviewSessionState()
|
|
1544
|
+
_ = self.recordPreviewBundle(bundle)
|
|
1545
|
+
guard self.reloadWithoutWaitingForAppReady() else {
|
|
1546
|
+
self.hidePreviewTransitionLoader(reason: "set-preview-reload-failed")
|
|
1547
|
+
call.reject("Reload failed after setting preview \(id)")
|
|
1548
|
+
return
|
|
1549
|
+
}
|
|
1550
|
+
|
|
1551
|
+
self.notifyBundleSet(bundle)
|
|
1552
|
+
self.showPreviewSessionNoticeIfNeeded()
|
|
1553
|
+
call.resolve()
|
|
1554
|
+
}
|
|
1555
|
+
}
|
|
1556
|
+
|
|
1557
|
+
func previewMenuPreviews() -> [[String: Any]] {
|
|
1558
|
+
self.listPreviewInfos()
|
|
1559
|
+
}
|
|
1560
|
+
|
|
1561
|
+
func setPreviewFromShakeMenu(id: String) -> Bool {
|
|
1562
|
+
guard self.allowPreview, let preview = self.storedPreviewInfo(id: id) else {
|
|
1563
|
+
return false
|
|
1564
|
+
}
|
|
1565
|
+
|
|
1566
|
+
self.showPreviewTransitionLoader(reason: "set-preview-menu")
|
|
1567
|
+
guard self.preparePreviewFallbackIfNeeded() else {
|
|
1568
|
+
self.hidePreviewTransitionLoader(reason: "set-preview-menu-fallback-failed")
|
|
1569
|
+
return false
|
|
1570
|
+
}
|
|
1571
|
+
|
|
1572
|
+
guard self.implementation.set(id: id) else {
|
|
1573
|
+
self.hidePreviewTransitionLoader(reason: "set-preview-menu-failed")
|
|
1574
|
+
return false
|
|
1575
|
+
}
|
|
1576
|
+
|
|
1577
|
+
let bundle = self.implementation.getBundleInfo(id: id)
|
|
1578
|
+
self.updateCurrentPreviewSessionMetadata(from: preview)
|
|
1579
|
+
self.activatePreviewSessionState()
|
|
1580
|
+
_ = self.recordPreviewBundle(bundle)
|
|
1581
|
+
guard self.reloadWithoutWaitingForAppReady() else {
|
|
1582
|
+
self.hidePreviewTransitionLoader(reason: "set-preview-menu-reload-failed")
|
|
1583
|
+
return false
|
|
1584
|
+
}
|
|
1585
|
+
|
|
1586
|
+
self.notifyBundleSet(bundle)
|
|
1587
|
+
self.showPreviewSessionNoticeIfNeeded()
|
|
1588
|
+
return true
|
|
1589
|
+
}
|
|
1590
|
+
|
|
1591
|
+
@objc func resetPreview(_ call: CAPPluginCall) {
|
|
1592
|
+
guard self.previewSessionEnabled else {
|
|
1593
|
+
call.resolve()
|
|
1594
|
+
return
|
|
1595
|
+
}
|
|
1596
|
+
DispatchQueue.global(qos: .userInitiated).async {
|
|
1597
|
+
if self.leavePreviewSessionFromShakeMenu() {
|
|
1598
|
+
call.resolve()
|
|
1599
|
+
} else {
|
|
1600
|
+
call.reject("Could not leave preview session")
|
|
1601
|
+
}
|
|
1602
|
+
}
|
|
1603
|
+
}
|
|
1604
|
+
|
|
1605
|
+
@objc func deletePreview(_ call: CAPPluginCall) {
|
|
1606
|
+
guard self.allowPreview else {
|
|
1607
|
+
call.reject("deletePreview not allowed. Set allowPreview to true in your config to enable it.")
|
|
1608
|
+
return
|
|
1609
|
+
}
|
|
1610
|
+
guard let id = call.getString("id"), !id.isEmpty else {
|
|
1611
|
+
call.reject("deletePreview called without id")
|
|
1612
|
+
return
|
|
1613
|
+
}
|
|
1614
|
+
if self.previewSessionEnabled && self.implementation.getCurrentBundleId() == id {
|
|
1615
|
+
call.reject("Cannot delete the active preview")
|
|
1616
|
+
return
|
|
1617
|
+
}
|
|
1618
|
+
|
|
1619
|
+
var sessions = self.previewSessions()
|
|
1620
|
+
let removed = sessions.removeValue(forKey: id) != nil
|
|
1621
|
+
self.savePreviewSessions(sessions)
|
|
1622
|
+
|
|
1623
|
+
var deleted = false
|
|
1624
|
+
let fallbackId = self.implementation.getPreviewFallbackBundle()?.getId()
|
|
1625
|
+
let nextId = self.implementation.getNextBundle()?.getId()
|
|
1626
|
+
if removed, id != fallbackId, id != nextId, id != BundleInfo.ID_BUILTIN {
|
|
1627
|
+
deleted = self.implementation.delete(id: id, removeInfo: false)
|
|
1628
|
+
}
|
|
1231
1629
|
|
|
1630
|
+
call.resolve(["removed": removed, "deleted": deleted])
|
|
1631
|
+
}
|
|
1632
|
+
|
|
1633
|
+
@objc func checkPreviewUpdate(_ call: CAPPluginCall) {
|
|
1634
|
+
self.handlePreviewUpdate(call, shouldDownload: false)
|
|
1635
|
+
}
|
|
1636
|
+
|
|
1637
|
+
@objc func updatePreview(_ call: CAPPluginCall) {
|
|
1638
|
+
self.handlePreviewUpdate(call, shouldDownload: true)
|
|
1639
|
+
}
|
|
1640
|
+
|
|
1641
|
+
private func handlePreviewUpdate(_ call: CAPPluginCall, shouldDownload: Bool) {
|
|
1642
|
+
guard self.allowPreview else {
|
|
1643
|
+
call.reject("Preview updates not allowed. Set allowPreview to true in your config to enable it.")
|
|
1644
|
+
return
|
|
1645
|
+
}
|
|
1646
|
+
guard let id = call.getString("id"), !id.isEmpty else {
|
|
1647
|
+
call.reject("Preview update called without id")
|
|
1648
|
+
return
|
|
1649
|
+
}
|
|
1650
|
+
guard let preview = self.storedPreviewInfo(id: id),
|
|
1651
|
+
let payloadUrlString = preview["payloadUrl"] as? String,
|
|
1652
|
+
let payloadUrl = self.normalizedPreviewPayloadUrl(payloadUrlString) else {
|
|
1653
|
+
call.reject("Preview \(id) has no payloadUrl to update from")
|
|
1654
|
+
return
|
|
1655
|
+
}
|
|
1656
|
+
|
|
1657
|
+
DispatchQueue.global(qos: .userInitiated).async {
|
|
1658
|
+
do {
|
|
1659
|
+
let payload = try self.fetchPreviewPayload(payloadUrl)
|
|
1660
|
+
guard let version = payload.version, !version.isEmpty else {
|
|
1661
|
+
throw self.makePreviewError("Preview payload is missing a version")
|
|
1662
|
+
}
|
|
1663
|
+
|
|
1664
|
+
let currentPreviewBundle = self.implementation.getBundleInfo(id: id)
|
|
1665
|
+
let upToDate = currentPreviewBundle.getVersionName() == version
|
|
1666
|
+
if upToDate || !shouldDownload {
|
|
1667
|
+
call.resolve([
|
|
1668
|
+
"preview": preview,
|
|
1669
|
+
"latestVersion": version,
|
|
1670
|
+
"upToDate": upToDate,
|
|
1671
|
+
"updated": false,
|
|
1672
|
+
"bundle": currentPreviewBundle.toJSON()
|
|
1673
|
+
])
|
|
1674
|
+
return
|
|
1675
|
+
}
|
|
1676
|
+
|
|
1677
|
+
guard payload.url != nil || payload.manifest?.isEmpty == false else {
|
|
1678
|
+
throw self.makePreviewError("Preview payload is missing download information")
|
|
1679
|
+
}
|
|
1680
|
+
|
|
1681
|
+
let next = try self.downloadBundle(
|
|
1682
|
+
// Fallback URL is only provided when payload.url is missing; when manifestEntries is present,
|
|
1683
|
+
// downloadBundle routes through downloadManifest and ignores urlString.
|
|
1684
|
+
urlString: payload.url ?? "https://404.capgo.app/no.zip",
|
|
1685
|
+
version: version,
|
|
1686
|
+
sessionKey: payload.sessionKey ?? "",
|
|
1687
|
+
checksum: payload.checksum ?? "",
|
|
1688
|
+
manifestEntries: payload.manifest
|
|
1689
|
+
)
|
|
1690
|
+
|
|
1691
|
+
let wasActive = self.previewSessionEnabled && self.implementation.getCurrentBundleId() == id
|
|
1692
|
+
if wasActive {
|
|
1693
|
+
guard self.implementation.set(id: next.getId()) else {
|
|
1694
|
+
throw self.makePreviewError("Downloaded preview bundle cannot be applied")
|
|
1695
|
+
}
|
|
1696
|
+
}
|
|
1697
|
+
|
|
1698
|
+
let savedPreview = self.recordPreviewBundle(next, replacing: id)
|
|
1699
|
+
if wasActive {
|
|
1700
|
+
guard self.reloadWithoutWaitingForAppReady() else {
|
|
1701
|
+
throw self.makePreviewError("Reload failed after updating preview")
|
|
1702
|
+
}
|
|
1703
|
+
self.notifyBundleSet(next)
|
|
1704
|
+
self.showPreviewSessionNoticeIfNeeded()
|
|
1705
|
+
}
|
|
1706
|
+
|
|
1707
|
+
call.resolve([
|
|
1708
|
+
"preview": savedPreview,
|
|
1709
|
+
"latestVersion": version,
|
|
1710
|
+
"upToDate": false,
|
|
1711
|
+
"updated": true,
|
|
1712
|
+
"bundle": next.toJSON()
|
|
1713
|
+
])
|
|
1714
|
+
} catch {
|
|
1715
|
+
self.logger.error("Could not update preview: \(error.localizedDescription)")
|
|
1716
|
+
call.reject("Could not update preview: \(error.localizedDescription)")
|
|
1717
|
+
}
|
|
1718
|
+
}
|
|
1719
|
+
}
|
|
1720
|
+
|
|
1721
|
+
func leavePreviewSessionFromShakeMenu() -> Bool {
|
|
1232
1722
|
self.showPreviewTransitionLoader(reason: "leave-preview-session")
|
|
1233
1723
|
let didReset = self.resetToPreviewFallbackBundle()
|
|
1234
1724
|
guard didReset else {
|
|
@@ -1236,10 +1726,7 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
1236
1726
|
return false
|
|
1237
1727
|
}
|
|
1238
1728
|
|
|
1239
|
-
let previewFallbackBundle = self.implementation.getPreviewFallbackBundle()
|
|
1240
1729
|
self.endPreviewSession(keepPreviewGuard: true)
|
|
1241
|
-
let restoredNextBundle = self.implementation.getNextBundle()
|
|
1242
|
-
self.deletePreviewBundleIfUnused(previewBundle, previewFallbackBundle: previewFallbackBundle, restoredNextBundle: restoredNextBundle)
|
|
1243
1730
|
return true
|
|
1244
1731
|
}
|
|
1245
1732
|
|
|
@@ -1262,7 +1749,6 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
1262
1749
|
}
|
|
1263
1750
|
|
|
1264
1751
|
private func leavePreviewSessionWithoutReload(keepPreviewGuard: Bool = false) -> Bool {
|
|
1265
|
-
let previewBundle = self.implementation.getCurrentBundle()
|
|
1266
1752
|
guard let previewFallbackBundle = self.resolvePreviewFallbackBundle(reason: "preview deeplink launch") else {
|
|
1267
1753
|
return false
|
|
1268
1754
|
}
|
|
@@ -1272,14 +1758,11 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
1272
1758
|
}
|
|
1273
1759
|
|
|
1274
1760
|
self.endPreviewSession(keepPreviewGuard: keepPreviewGuard)
|
|
1275
|
-
let restoredNextBundle = self.implementation.getNextBundle()
|
|
1276
|
-
self.deletePreviewBundleIfUnused(previewBundle, previewFallbackBundle: previewFallbackBundle, restoredNextBundle: restoredNextBundle)
|
|
1277
1761
|
return true
|
|
1278
1762
|
}
|
|
1279
1763
|
|
|
1280
1764
|
private func leavePreviewSessionForIncomingPreviewLink() -> Bool {
|
|
1281
1765
|
self.showPreviewTransitionLoader(reason: "incoming-preview-deeplink")
|
|
1282
|
-
let previewBundle = self.implementation.getCurrentBundle()
|
|
1283
1766
|
guard let previewFallbackBundle = self.resolvePreviewFallbackBundle(reason: "incoming preview deeplink") else {
|
|
1284
1767
|
self.clearIncomingPreviewTransition()
|
|
1285
1768
|
self.hidePreviewTransitionLoader(reason: "incoming-preview-deeplink-failed")
|
|
@@ -1297,12 +1780,6 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
1297
1780
|
let didReload = self.reloadWithoutWaitingForAppReady()
|
|
1298
1781
|
if didReload {
|
|
1299
1782
|
self.endPreviewSession(keepPreviewGuard: true)
|
|
1300
|
-
let restoredNextBundle = self.implementation.getNextBundle()
|
|
1301
|
-
self.deletePreviewBundleIfUnused(
|
|
1302
|
-
previewBundle,
|
|
1303
|
-
previewFallbackBundle: previewFallbackBundle,
|
|
1304
|
-
restoredNextBundle: restoredNextBundle
|
|
1305
|
-
)
|
|
1306
1783
|
self.scheduleIncomingPreviewTransitionFallbackClear()
|
|
1307
1784
|
} else {
|
|
1308
1785
|
self.implementation.restoreResetState(previousState)
|
|
@@ -1313,18 +1790,6 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
1313
1790
|
return didReload
|
|
1314
1791
|
}
|
|
1315
1792
|
|
|
1316
|
-
private func deletePreviewBundleIfUnused(
|
|
1317
|
-
_ previewBundle: BundleInfo,
|
|
1318
|
-
previewFallbackBundle: BundleInfo?,
|
|
1319
|
-
restoredNextBundle: BundleInfo?
|
|
1320
|
-
) {
|
|
1321
|
-
if !previewBundle.isBuiltin() &&
|
|
1322
|
-
previewFallbackBundle?.getId() != previewBundle.getId() &&
|
|
1323
|
-
restoredNextBundle?.getId() != previewBundle.getId() {
|
|
1324
|
-
_ = self.implementation.delete(id: previewBundle.getId(), removeInfo: false)
|
|
1325
|
-
}
|
|
1326
|
-
}
|
|
1327
|
-
|
|
1328
1793
|
func reloadPreviewSessionFromShakeMenu() -> Bool {
|
|
1329
1794
|
self.showPreviewTransitionLoader(reason: "reload-preview-session")
|
|
1330
1795
|
let didReload: Bool
|
|
@@ -1460,6 +1925,8 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
1460
1925
|
UserDefaults.standard.removeObject(forKey: self.previewPreviousDefaultChannelWasSetDefaultsKey)
|
|
1461
1926
|
UserDefaults.standard.removeObject(forKey: self.previewAppIdDefaultsKey)
|
|
1462
1927
|
UserDefaults.standard.removeObject(forKey: self.previewPayloadUrlDefaultsKey)
|
|
1928
|
+
UserDefaults.standard.removeObject(forKey: self.previewNameDefaultsKey)
|
|
1929
|
+
UserDefaults.standard.removeObject(forKey: self.previewSourceDefaultsKey)
|
|
1463
1930
|
UserDefaults.standard.removeObject(forKey: self.previewSessionAlertPendingDefaultsKey)
|
|
1464
1931
|
UserDefaults.standard.synchronize()
|
|
1465
1932
|
}
|
|
@@ -1644,6 +2111,7 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
1644
2111
|
throw makePreviewError("Downloaded preview bundle cannot be applied")
|
|
1645
2112
|
}
|
|
1646
2113
|
|
|
2114
|
+
_ = self.recordPreviewBundle(next, replacing: current.getId())
|
|
1647
2115
|
self.notifyBundleSet(next)
|
|
1648
2116
|
return self.reloadWithoutWaitingForAppReady()
|
|
1649
2117
|
} catch {
|
|
@@ -1653,7 +2121,7 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
1653
2121
|
}
|
|
1654
2122
|
|
|
1655
2123
|
private func clearPreviewSessionForNativeBuildChange() {
|
|
1656
|
-
guard self.previewSessionEnabled || self.implementation.getPreviewFallbackBundle() != nil else {
|
|
2124
|
+
guard self.previewSessionEnabled || self.implementation.getPreviewFallbackBundle() != nil || !self.previewSessions().isEmpty else {
|
|
1657
2125
|
return
|
|
1658
2126
|
}
|
|
1659
2127
|
logger.info("Native build changed; clearing preview session state")
|
|
@@ -1670,6 +2138,8 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
1670
2138
|
_ = self.implementation.setPreviewFallbackBundle(fallback: nil)
|
|
1671
2139
|
_ = self.implementation.setNextBundle(next: Optional<String>.none)
|
|
1672
2140
|
self.clearPreviewSessionPreferences()
|
|
2141
|
+
UserDefaults.standard.removeObject(forKey: self.previewSessionsDefaultsKey)
|
|
2142
|
+
UserDefaults.standard.synchronize()
|
|
1673
2143
|
}
|
|
1674
2144
|
|
|
1675
2145
|
private func restorePreviewPreviousNextBundle() {
|
|
@@ -3520,15 +3990,6 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
3520
3990
|
return
|
|
3521
3991
|
}
|
|
3522
3992
|
|
|
3523
|
-
if let gesture = call.getString("gesture") {
|
|
3524
|
-
guard Self.isSupportedShakeMenuGesture(gesture) else {
|
|
3525
|
-
logger.error("Unsupported shake menu gesture: \(gesture)")
|
|
3526
|
-
call.reject("Unsupported shake menu gesture. Use \"shake\" or \"threeFingerPinch\".")
|
|
3527
|
-
return
|
|
3528
|
-
}
|
|
3529
|
-
self.shakeMenuGesture = Self.normalizedShakeMenuGesture(gesture)
|
|
3530
|
-
}
|
|
3531
|
-
|
|
3532
3993
|
self.shakeMenuEnabled = enabled
|
|
3533
3994
|
self.syncShakeMenuGestureRecognizer()
|
|
3534
3995
|
logger.info("Shake menu \(enabled ? "enabled" : "disabled") with \(self.shakeMenuGesture) gesture")
|