@sency/react-native-smkit-ui 2.2.0 → 2.2.2
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 +218 -65
- package/android/build.gradle +3 -1
- package/android/src/main/java/com/smkituilibrary/SmkitUiLibraryModule.kt +237 -3
- package/android/src/main/java/com/smkituilibrary/mapper/SMMapper.kt +70 -10
- package/android/src/main/java/com/smkituilibrary/model/SMKitExercise.kt +40 -0
- package/android/src/main/java/com/smkituilibrary/model/SMKitWorkout.kt +8 -0
- package/android/src/main/java/com/smkituilibrary/model/SMKitWorkoutConfig.kt +2 -0
- package/android/src/main/java/com/smkituilibrary/model/SMUserData.kt +5 -1
- package/ios/SMKitUIManager.mm +33 -11
- package/ios/SMKitUIManager.swift +243 -26
- package/lib/commonjs/SMWorkout.js +239 -177
- package/lib/commonjs/SMWorkout.js.map +1 -1
- package/lib/commonjs/index.js +187 -5
- package/lib/commonjs/index.js.map +1 -1
- package/lib/module/SMWorkout.js +232 -181
- package/lib/module/SMWorkout.js.map +1 -1
- package/lib/module/index.js +165 -5
- package/lib/module/index.js.map +1 -1
- package/package.json +2 -2
- package/react-native-smkit-ui.podspec +2 -2
- package/src/SMWorkout.tsx +353 -176
- package/src/index.tsx +167 -8
- package/android/build/intermediates/compile_r_class_jar/debug/generateDebugRFile/R.jar +0 -0
- package/android/build/intermediates/compile_symbol_list/debug/generateDebugRFile/R.txt +0 -0
- package/android/build/intermediates/incremental/debug/packageDebugResources/compile-file-map.properties +0 -1
- package/android/build/intermediates/incremental/debug/packageDebugResources/merger.xml +0 -2
- package/android/build/intermediates/incremental/mergeDebugJniLibFolders/merger.xml +0 -2
- package/android/build/intermediates/local_only_symbol_list/debug/parseDebugLocalResources/R-def.txt +0 -2
- package/android/build/intermediates/nested_resources_validation_report/debug/generateDebugResources/nestedResourcesValidationReport.txt +0 -1
- package/android/build/intermediates/symbol_list_with_package_name/debug/generateDebugRFile/package-aware-r.txt +0 -1
package/ios/SMKitUIManager.swift
CHANGED
|
@@ -18,6 +18,7 @@ class SMKitUIManager: NSObject, RCTBridgeModule {
|
|
|
18
18
|
|
|
19
19
|
var summaryData: WorkoutSummaryData?
|
|
20
20
|
var didCompleteWorkout = false
|
|
21
|
+
var startTimerOnFirstActivityOverride: Bool?
|
|
21
22
|
|
|
22
23
|
var didReciveSummary = false {
|
|
23
24
|
didSet {
|
|
@@ -65,7 +66,9 @@ class SMKitUIManager: NSObject, RCTBridgeModule {
|
|
|
65
66
|
var isConfigDone = false
|
|
66
67
|
var didFail = false
|
|
67
68
|
// RN SDK policy: do not wait for first activity before starting exercise timer.
|
|
68
|
-
SMKitUIModel.startTimerOnFirstActivity = false
|
|
69
|
+
SMKitUIModel.startTimerOnFirstActivity = self.startTimerOnFirstActivityOverride ?? false
|
|
70
|
+
// RN SDK policy: keep Jinni wake-word / orb features internal — never enabled from RN.
|
|
71
|
+
SMKitUIModel.alwaysOnJinniWakeWordDuringWorkout = false
|
|
69
72
|
SMKitUIModel.configure(authKey: "\(key)", includesHighlights: false, onSuccess: {
|
|
70
73
|
if !isConfigDone {
|
|
71
74
|
isConfigDone = true
|
|
@@ -228,7 +231,9 @@ class SMKitUIManager: NSObject, RCTBridgeModule {
|
|
|
228
231
|
difficultyLevel: difficultyLevel,
|
|
229
232
|
workoutDuration: workoutDuration,
|
|
230
233
|
language: language,
|
|
231
|
-
programID: programID
|
|
234
|
+
programID: programID,
|
|
235
|
+
phonePosition: self.resolvePhonePosition(json["phonePosition"] as? String),
|
|
236
|
+
shortIntro: json["shortIntro"] as? Bool ?? false
|
|
232
237
|
)
|
|
233
238
|
|
|
234
239
|
SMKitUIModel.startWorkoutFromProgram(viewController: smkitUIViewController, workoutConfig: config, delegate: self, onFailure: { error in
|
|
@@ -237,17 +242,19 @@ class SMKitUIManager: NSObject, RCTBridgeModule {
|
|
|
237
242
|
}
|
|
238
243
|
}
|
|
239
244
|
|
|
240
|
-
@objc(setSessionLanguage:)
|
|
241
|
-
func setSessionLanguage(language: String) {
|
|
245
|
+
@objc(setSessionLanguage:onSuccess:onFailure:)
|
|
246
|
+
func setSessionLanguage(language: String, onSuccess: @escaping RCTPromiseResolveBlock, onFailure: @escaping RCTPromiseRejectBlock) {
|
|
242
247
|
let lang = resolveLanguage(language)
|
|
243
248
|
SMKitUIModel.setSessionLanguage(language: lang)
|
|
244
249
|
// Auto-sync phone calibration language so callers don't need to set it separately
|
|
245
250
|
SMKitUIModel.setPhoneCalibrationLanguage(language: lang)
|
|
251
|
+
onSuccess(nil)
|
|
246
252
|
}
|
|
247
253
|
|
|
248
|
-
@objc(setPhoneCalibrationLanguage:)
|
|
249
|
-
func setPhoneCalibrationLanguage(language: String) {
|
|
254
|
+
@objc(setPhoneCalibrationLanguage:onSuccess:onFailure:)
|
|
255
|
+
func setPhoneCalibrationLanguage(language: String, onSuccess: @escaping RCTPromiseResolveBlock, onFailure: @escaping RCTPromiseRejectBlock) {
|
|
250
256
|
SMKitUIModel.setPhoneCalibrationLanguage(language: resolveLanguage(language))
|
|
257
|
+
onSuccess(nil)
|
|
251
258
|
}
|
|
252
259
|
|
|
253
260
|
private func resolveLanguage(_ language: String) -> SencySupportedLanguage {
|
|
@@ -258,29 +265,40 @@ class SMKitUIManager: NSObject, RCTBridgeModule {
|
|
|
258
265
|
}
|
|
259
266
|
}
|
|
260
267
|
|
|
261
|
-
|
|
262
|
-
|
|
268
|
+
private func resolvePhonePosition(_ position: String?) -> PhonePosition {
|
|
269
|
+
switch position?.lowercased() {
|
|
270
|
+
case "elevated": return .Elevated
|
|
271
|
+
default: return .Floor
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
@objc(setEndExercisePreferences:onSuccess:onFailure:)
|
|
276
|
+
func setEndExercisePreferences(preferencesString: String, onSuccess: @escaping RCTPromiseResolveBlock, onFailure: @escaping RCTPromiseRejectBlock) {
|
|
263
277
|
let target = EndExercisePreferences(rawValue: preferencesString) ?? .Default
|
|
264
278
|
SMKitUIModel.setEndExercisePreferences(endExercisePreferences: target)
|
|
279
|
+
onSuccess(nil)
|
|
265
280
|
}
|
|
266
281
|
|
|
267
|
-
@objc(setCounterPreferences:)
|
|
268
|
-
func setCounterPreferences(preferencesString: String) {
|
|
282
|
+
@objc(setCounterPreferences:onSuccess:onFailure:)
|
|
283
|
+
func setCounterPreferences(preferencesString: String, onSuccess: @escaping RCTPromiseResolveBlock, onFailure: @escaping RCTPromiseRejectBlock) {
|
|
269
284
|
let preferences = CounterPreferences(rawValue: preferencesString) ?? .Default
|
|
270
285
|
SMKitUIModel.setCounterPreferences(counterPreferences: preferences)
|
|
286
|
+
onSuccess(nil)
|
|
271
287
|
}
|
|
272
288
|
|
|
273
|
-
@objc(setIntelligenceRestEnabled:)
|
|
274
|
-
func setIntelligenceRestEnabled(_ enabled: Bool) {
|
|
289
|
+
@objc(setIntelligenceRestEnabled:onSuccess:onFailure:)
|
|
290
|
+
func setIntelligenceRestEnabled(_ enabled: Bool, onSuccess: @escaping RCTPromiseResolveBlock, onFailure: @escaping RCTPromiseRejectBlock) {
|
|
275
291
|
SMKitUIModel.enableIntelligenceRest = enabled
|
|
292
|
+
onSuccess(nil)
|
|
276
293
|
}
|
|
277
294
|
|
|
278
|
-
@objc(setSkeletonSettings:)
|
|
279
|
-
func setSkeletonSettings(_ configString: String) {
|
|
295
|
+
@objc(setSkeletonSettings:onSuccess:onFailure:)
|
|
296
|
+
func setSkeletonSettings(_ configString: String, onSuccess: @escaping RCTPromiseResolveBlock, onFailure: @escaping RCTPromiseRejectBlock) {
|
|
280
297
|
guard let data = configString.data(using: .utf8),
|
|
281
298
|
let rawConfig = try? JSONSerialization.jsonObject(with: data),
|
|
282
299
|
let config = rawConfig as? [String: Any] else {
|
|
283
300
|
print("setSkeletonSettings: invalid JSON")
|
|
301
|
+
onFailure("setSkeletonSettings Failed", "Invalid JSON", nil)
|
|
284
302
|
return
|
|
285
303
|
}
|
|
286
304
|
if let v = config["hidden"] as? Bool { SMKitUIModel.skeletonHidden = v }
|
|
@@ -299,37 +317,49 @@ class SMKitUIManager: NSObject, RCTBridgeModule {
|
|
|
299
317
|
if let v = config["dotsOuterColor"] as? String, let c = skeletonColor(from: v) { SMKitUIModel.skeletonDotsOuterColorOption = c }
|
|
300
318
|
if let v = config["connectionsInnerColor"] as? String, let c = skeletonColor(from: v) { SMKitUIModel.skeletonConnectionsInnerColorOption = c }
|
|
301
319
|
if let v = config["connectionsOuterColor"] as? String, let c = skeletonColor(from: v) { SMKitUIModel.skeletonConnectionsOuterColorOption = c }
|
|
320
|
+
onSuccess(nil)
|
|
302
321
|
}
|
|
303
322
|
|
|
304
|
-
@objc(setPauseTypes:)
|
|
305
|
-
func setPauseTypes(_ typesJson: String) {
|
|
323
|
+
@objc(setPauseTypes:onSuccess:onFailure:)
|
|
324
|
+
func setPauseTypes(_ typesJson: String, onSuccess: @escaping RCTPromiseResolveBlock, onFailure: @escaping RCTPromiseRejectBlock) {
|
|
306
325
|
guard let data = typesJson.data(using: .utf8),
|
|
307
326
|
let rawArray = try? JSONSerialization.jsonObject(with: data),
|
|
308
|
-
let arr = rawArray as? [String] else {
|
|
327
|
+
let arr = rawArray as? [String] else {
|
|
328
|
+
onFailure("setPauseTypes Failed", "Invalid JSON", nil)
|
|
329
|
+
return
|
|
330
|
+
}
|
|
309
331
|
let types = arr.compactMap { pauseAlertType(from: $0) }
|
|
310
|
-
|
|
332
|
+
do {
|
|
333
|
+
try SMKitUIModel.setAllowedPauseTypes(types: types)
|
|
334
|
+
onSuccess(nil)
|
|
335
|
+
} catch {
|
|
336
|
+
onFailure("setPauseTypes Failed", error.localizedDescription, error)
|
|
337
|
+
}
|
|
311
338
|
}
|
|
312
339
|
|
|
313
|
-
@objc(setAllowAudioMixing:)
|
|
314
|
-
func setAllowAudioMixing(_ enabled: Bool) {
|
|
340
|
+
@objc(setAllowAudioMixing:onSuccess:onFailure:)
|
|
341
|
+
func setAllowAudioMixing(_ enabled: Bool, onSuccess: @escaping RCTPromiseResolveBlock, onFailure: @escaping RCTPromiseRejectBlock) {
|
|
315
342
|
SMKitUIModel.allowAudioMixing = enabled
|
|
343
|
+
onSuccess(nil)
|
|
316
344
|
}
|
|
317
345
|
|
|
318
|
-
@objc(setShowExternalAudioControl:)
|
|
319
|
-
func setShowExternalAudioControl(_ enabled: Bool) {
|
|
346
|
+
@objc(setShowExternalAudioControl:onSuccess:onFailure:)
|
|
347
|
+
func setShowExternalAudioControl(_ enabled: Bool, onSuccess: @escaping RCTPromiseResolveBlock, onFailure: @escaping RCTPromiseRejectBlock) {
|
|
320
348
|
SMKitUIModel.showExternalAudioControl = enabled
|
|
349
|
+
onSuccess(nil)
|
|
321
350
|
}
|
|
322
351
|
|
|
323
|
-
@objc(setAccuratePoseEstimation:)
|
|
324
|
-
func setAccuratePoseEstimation(_ enabled: Bool) {
|
|
352
|
+
@objc(setAccuratePoseEstimation:onSuccess:onFailure:)
|
|
353
|
+
func setAccuratePoseEstimation(_ enabled: Bool, onSuccess: @escaping RCTPromiseResolveBlock, onFailure: @escaping RCTPromiseRejectBlock) {
|
|
325
354
|
SMKitUIModel.accuratePoseEstimation = enabled
|
|
355
|
+
onSuccess(nil)
|
|
326
356
|
}
|
|
327
357
|
|
|
328
358
|
// Instruction video config (align with ../smkit_android ConfigureViewModel).
|
|
329
359
|
// displayMode: "default" | "mediumCycle". mediumCycle: video at 75% for first N reps, then 50%.
|
|
330
360
|
// mediumSizeCycles: 1–5, only used when displayMode is mediumCycle.
|
|
331
|
-
@objc(setInstructionVideoConfig:)
|
|
332
|
-
func setInstructionVideoConfig(_ configString: String) {
|
|
361
|
+
@objc(setInstructionVideoConfig:onSuccess:onFailure:)
|
|
362
|
+
func setInstructionVideoConfig(_ configString: String, onSuccess: @escaping RCTPromiseResolveBlock, onFailure: @escaping RCTPromiseRejectBlock) {
|
|
333
363
|
do {
|
|
334
364
|
let configDict = try stringJsonToDic(stringJSON: configString)
|
|
335
365
|
|
|
@@ -344,11 +374,177 @@ class SMKitUIManager: NSObject, RCTBridgeModule {
|
|
|
344
374
|
SMKitUIModel.instructionVideoConfig = config
|
|
345
375
|
|
|
346
376
|
print("SMKitUIManager: Set InstructionVideoConfig - mode: \(displayModeStr), cycles: \(mediumSizeCycles)")
|
|
377
|
+
onSuccess(nil)
|
|
347
378
|
} catch {
|
|
348
379
|
print("SMKitUIManager: Error parsing InstructionVideoConfig - \(error.localizedDescription)")
|
|
380
|
+
onFailure("setInstructionVideoConfig Failed", error.localizedDescription, error)
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
@objc(setColorTheme:onSuccess:onFailure:)
|
|
385
|
+
func setColorTheme(_ theme: String, onSuccess: @escaping RCTPromiseResolveBlock, onFailure: @escaping RCTPromiseRejectBlock) {
|
|
386
|
+
SMKitUIModel.colorTheme = mapColorToTheme(primaryColor: theme)
|
|
387
|
+
onSuccess(nil)
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
@objc(setPlayPhoneCalibrationAudio:onSuccess:onFailure:)
|
|
391
|
+
func setPlayPhoneCalibrationAudio(_ enabled: Bool, onSuccess: @escaping RCTPromiseResolveBlock, onFailure: @escaping RCTPromiseRejectBlock) {
|
|
392
|
+
SMKitUIModel.playPhoneCalibrationAudio = enabled
|
|
393
|
+
onSuccess(nil)
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
@objc(setPlayBodyCalibrationAudio:onSuccess:onFailure:)
|
|
397
|
+
func setPlayBodyCalibrationAudio(_ enabled: Bool, onSuccess: @escaping RCTPromiseResolveBlock, onFailure: @escaping RCTPromiseRejectBlock) {
|
|
398
|
+
SMKitUIModel.playBodyCalibrationAudio = enabled
|
|
399
|
+
onSuccess(nil)
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
@objc(setStartTimerOnFirstActivity:onSuccess:onFailure:)
|
|
403
|
+
func setStartTimerOnFirstActivity(_ enabled: Bool, onSuccess: @escaping RCTPromiseResolveBlock, onFailure: @escaping RCTPromiseRejectBlock) {
|
|
404
|
+
startTimerOnFirstActivityOverride = enabled
|
|
405
|
+
SMKitUIModel.startTimerOnFirstActivity = enabled
|
|
406
|
+
onSuccess(nil)
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
@objc(setWorkoutContinuationTimerDuration:onSuccess:onFailure:)
|
|
410
|
+
func setWorkoutContinuationTimerDuration(_ seconds: NSNumber, onSuccess: @escaping RCTPromiseResolveBlock, onFailure: @escaping RCTPromiseRejectBlock) {
|
|
411
|
+
SMKitUIModel.workoutContinuationTimerDuration = max(1.0, seconds.doubleValue)
|
|
412
|
+
onSuccess(nil)
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
@objc(setPhoneMovementCountPreventionEnabled:onSuccess:onFailure:)
|
|
416
|
+
func setPhoneMovementCountPreventionEnabled(_ enabled: Bool, onSuccess: @escaping RCTPromiseResolveBlock, onFailure: @escaping RCTPromiseRejectBlock) {
|
|
417
|
+
SMKitUIModel.enablePhoneMovementCountPrevention = enabled
|
|
418
|
+
onSuccess(nil)
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
@objc(setVariationMismatchFeedbackEnabled:onSuccess:onFailure:)
|
|
422
|
+
func setVariationMismatchFeedbackEnabled(_ enabled: Bool, onSuccess: @escaping RCTPromiseResolveBlock, onFailure: @escaping RCTPromiseRejectBlock) {
|
|
423
|
+
SMKitUIModel.enableVariationMismatchFeedback = enabled
|
|
424
|
+
onSuccess(nil)
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
@objc(setUseDefaultGuidanceMode:onSuccess:onFailure:)
|
|
428
|
+
func setUseDefaultGuidanceMode(_ enabled: Bool, onSuccess: @escaping RCTPromiseResolveBlock, onFailure: @escaping RCTPromiseRejectBlock) {
|
|
429
|
+
SMKitFlowManager.useDefaultGuidanceMode = enabled
|
|
430
|
+
onSuccess(nil)
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
@objc(setGuidanceDebugLogging:onSuccess:onFailure:)
|
|
434
|
+
func setGuidanceDebugLogging(_ enabled: Bool, onSuccess: @escaping RCTPromiseResolveBlock, onFailure: @escaping RCTPromiseRejectBlock) {
|
|
435
|
+
UserDefaults.standard.set(enabled, forKey: "guidanceDebugLogging")
|
|
436
|
+
onSuccess(nil)
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
@objc(setEnableButtonTutorial:onSuccess:onFailure:)
|
|
440
|
+
func setEnableButtonTutorial(_ enabled: Bool, onSuccess: @escaping RCTPromiseResolveBlock, onFailure: @escaping RCTPromiseRejectBlock) {
|
|
441
|
+
SMKitUIModel.enableButtonTutorial = enabled
|
|
442
|
+
onSuccess(nil)
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
@objc(setButtonTutorialCompletionAudioUri:onSuccess:onFailure:)
|
|
446
|
+
func setButtonTutorialCompletionAudioUri(_ uri: NSString?, onSuccess: @escaping RCTPromiseResolveBlock, onFailure: @escaping RCTPromiseRejectBlock) {
|
|
447
|
+
guard let raw = uri as? String, !raw.isEmpty else {
|
|
448
|
+
SMKitUIModel.buttonTutorialCompletionAudioURL = nil
|
|
449
|
+
onSuccess(nil)
|
|
450
|
+
return
|
|
451
|
+
}
|
|
452
|
+
SMKitUIModel.buttonTutorialCompletionAudioURL = URL(string: raw)
|
|
453
|
+
onSuccess(nil)
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
@objc(setShowRowingPhoneCalibration:onSuccess:onFailure:)
|
|
457
|
+
func setShowRowingPhoneCalibration(_ enabled: Bool, onSuccess: @escaping RCTPromiseResolveBlock, onFailure: @escaping RCTPromiseRejectBlock) {
|
|
458
|
+
SMKitUIModel.showRowingPhoneCalibration = enabled
|
|
459
|
+
onSuccess(nil)
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
@objc(setFeedbacksUIToExclude:onSuccess:onFailure:)
|
|
463
|
+
func setFeedbacksUIToExclude(_ feedbacksJson: String, onSuccess: @escaping RCTPromiseResolveBlock, onFailure: @escaping RCTPromiseRejectBlock) {
|
|
464
|
+
do {
|
|
465
|
+
let feedbacks = try parseFeedbackTypes(feedbacksJson)
|
|
466
|
+
SMKitUIModel.setFeedbacksUIToExclude(feedbacksUIToExclude: feedbacks)
|
|
467
|
+
onSuccess(nil)
|
|
468
|
+
} catch {
|
|
469
|
+
onFailure("setFeedbacksUIToExclude Failed", error.localizedDescription, error)
|
|
349
470
|
}
|
|
350
471
|
}
|
|
351
472
|
|
|
473
|
+
@objc(setExcludedFeedbacks:onSuccess:onFailure:)
|
|
474
|
+
func setExcludedFeedbacks(_ feedbacksJson: String, onSuccess: @escaping RCTPromiseResolveBlock, onFailure: @escaping RCTPromiseRejectBlock) {
|
|
475
|
+
do {
|
|
476
|
+
let feedbacks = try parseFeedbackTypes(feedbacksJson)
|
|
477
|
+
SMKitUIModel.setExcludedFeedbacks(excludedFeedbacks: feedbacks)
|
|
478
|
+
onSuccess(nil)
|
|
479
|
+
} catch {
|
|
480
|
+
onFailure("setExcludedFeedbacks Failed", error.localizedDescription, error)
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
@objc(setConfigString:onSuccess:onFailure:)
|
|
485
|
+
func setConfigString(_ configString: NSString?, onSuccess: @escaping RCTPromiseResolveBlock, onFailure: @escaping RCTPromiseRejectBlock) {
|
|
486
|
+
// The iOS SMKitUI public surface does not expose a global config-string setter.
|
|
487
|
+
// Exercise modifications remain supported through the start* APIs.
|
|
488
|
+
onSuccess(nil)
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
@objc(clearAdaptiveRomCache:onFailure:)
|
|
492
|
+
func clearAdaptiveRomCache(onSuccess: @escaping RCTPromiseResolveBlock, onFailure: @escaping RCTPromiseRejectBlock) {
|
|
493
|
+
SMKitFlowManager.clearAdaptiveRomPilotCache()
|
|
494
|
+
onSuccess(nil)
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
@objc(quitWorkout:onFailure:)
|
|
498
|
+
func quitWorkout(onSuccess: @escaping RCTPromiseResolveBlock, onFailure: @escaping RCTPromiseRejectBlock) {
|
|
499
|
+
SMKitUIModel.exitSDK()
|
|
500
|
+
onSuccess(nil)
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
@objc(pauseSDK:onFailure:)
|
|
504
|
+
func pauseSDK(onSuccess: @escaping RCTPromiseResolveBlock, onFailure: @escaping RCTPromiseRejectBlock) {
|
|
505
|
+
do {
|
|
506
|
+
try SMKitUIModel.pauseSDK()
|
|
507
|
+
onSuccess(nil)
|
|
508
|
+
} catch {
|
|
509
|
+
onFailure("pauseSDK Failed", error.localizedDescription, error)
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
@objc(resumeSDK:onFailure:)
|
|
514
|
+
func resumeSDK(onSuccess: @escaping RCTPromiseResolveBlock, onFailure: @escaping RCTPromiseRejectBlock) {
|
|
515
|
+
do {
|
|
516
|
+
try SMKitUIModel.resumeSDK()
|
|
517
|
+
onSuccess(nil)
|
|
518
|
+
} catch {
|
|
519
|
+
onFailure("resumeSDK Failed", error.localizedDescription, error)
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
@objc(getSupportedMovements:onFailure:)
|
|
524
|
+
func getSupportedMovements(onSuccess: @escaping RCTPromiseResolveBlock, onFailure: @escaping RCTPromiseRejectBlock) {
|
|
525
|
+
onSuccess(SMKitUIModel.getSupportedMovements() ?? [])
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
@objc(getExerciseType:onSuccess:onFailure:)
|
|
529
|
+
func getExerciseType(_ detector: String, onSuccess: @escaping RCTPromiseResolveBlock, onFailure: @escaping RCTPromiseRejectBlock) {
|
|
530
|
+
do {
|
|
531
|
+
let exerciseType = try SMKitUIModel.getExerciseType(type: detector)
|
|
532
|
+
onSuccess(String(describing: exerciseType))
|
|
533
|
+
} catch {
|
|
534
|
+
onFailure("getExerciseType Failed", error.localizedDescription, error)
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
@objc(setPoseModelChoice:onSuccess:onFailure:)
|
|
539
|
+
func setPoseModelChoice(_ choice: String, onSuccess: @escaping RCTPromiseResolveBlock, onFailure: @escaping RCTPromiseRejectBlock) {
|
|
540
|
+
guard ["AdaptiveChoice", "Prime", "Pro", "Lite", "UltraLite", "Basic"].contains(choice) else {
|
|
541
|
+
onFailure("setPoseModelChoice Failed", "Invalid pose model choice: \(choice)", nil)
|
|
542
|
+
return
|
|
543
|
+
}
|
|
544
|
+
// Android-only. Resolve for API parity.
|
|
545
|
+
onSuccess(nil)
|
|
546
|
+
}
|
|
547
|
+
|
|
352
548
|
private func pauseAlertType(from s: String) -> PauseAlertType? {
|
|
353
549
|
switch s {
|
|
354
550
|
case "resume": return .Resume
|
|
@@ -455,6 +651,27 @@ class SMKitUIManager: NSObject, RCTBridgeModule {
|
|
|
455
651
|
}
|
|
456
652
|
}
|
|
457
653
|
|
|
654
|
+
private func parseFeedbackTypes(_ feedbacksJson: String) throws -> [FormFeedbackTypeBr] {
|
|
655
|
+
guard let data = feedbacksJson.data(using: .utf8),
|
|
656
|
+
let rawArray = try JSONSerialization.jsonObject(with: data) as? [String] else {
|
|
657
|
+
throw NSError(
|
|
658
|
+
domain: "SMKitUIManager",
|
|
659
|
+
code: 0,
|
|
660
|
+
userInfo: [NSLocalizedDescriptionKey: "Expected a JSON array of feedback type names"]
|
|
661
|
+
)
|
|
662
|
+
}
|
|
663
|
+
return try rawArray.map { raw in
|
|
664
|
+
guard let feedback = FormFeedbackTypeBr(rawValue: raw) else {
|
|
665
|
+
throw NSError(
|
|
666
|
+
domain: "SMKitUIManager",
|
|
667
|
+
code: 0,
|
|
668
|
+
userInfo: [NSLocalizedDescriptionKey: "Invalid feedback type: \(raw)"]
|
|
669
|
+
)
|
|
670
|
+
}
|
|
671
|
+
return feedback
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
|
|
458
675
|
private func stringJsonToDic(stringJSON: String) throws -> [String: Any] {
|
|
459
676
|
guard let data = stringJSON.data(using: .utf8),
|
|
460
677
|
let json = try JSONSerialization.jsonObject(with: data) as? [String: Any]
|