@sency/react-native-smkit-ui 2.0.5 → 2.0.6

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.
@@ -95,7 +95,7 @@ dependencies {
95
95
  implementation "com.facebook.react:react-android"
96
96
  implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
97
97
 
98
- implementation("com.sency.smkitui:smkitui:1.4.5") {
98
+ implementation("com.sency.smkitui:smkitui:1.4.7") {
99
99
  exclude group: 'com.facebook.fbjni', module: 'fbjni-java-only'
100
100
  // // Don't exclude native libraries
101
101
  // exclude group: 'com.facebook.react', module: 'react-native'
@@ -111,4 +111,3 @@ dependencies {
111
111
  implementation "com.squareup.moshi:moshi-kotlin:$moshi"
112
112
  kapt "com.squareup.moshi:moshi-kotlin-codegen:$moshi"
113
113
  }
114
-
@@ -1,5 +1,7 @@
1
1
  package com.smkituilibrary
2
2
 
3
+ import android.os.Handler
4
+ import android.os.Looper
3
5
  import android.util.Log
4
6
  import com.facebook.react.bridge.Arguments
5
7
  import com.facebook.react.bridge.Promise
@@ -30,6 +32,7 @@ import com.sency.smkitui.model.workoutConfig.EndExercisePreference
30
32
  import com.sency.smkitui.model.workoutConfig.SMLanguage
31
33
  import com.sency.smkitui.model.workoutConfig.WorkoutConfigModel
32
34
  import com.smkituilibrary.mapper.toSMWorkout
35
+ import com.smkituilibrary.mapper.toSMWorkoutWithoutScoringParams
33
36
  import com.smkituilibrary.mapper.toWFPSummary
34
37
  import com.smkituilibrary.mapper.toWorkoutConfig
35
38
  import com.smkituilibrary.model.SMKitWorkout
@@ -91,6 +94,14 @@ class SmkitUiLibraryModule(reactContext: ReactApplicationContext) :
91
94
  }
92
95
  resultPromise?.resolve(result)
93
96
  sendEvent(reactApplicationContext, "workoutDidFinish", params)
97
+ // Dismiss the SDK UI on the main thread
98
+ Handler(Looper.getMainLooper()).post {
99
+ try {
100
+ smKitUI?.exitSDK()
101
+ } catch (e: Exception) {
102
+ Log.e(TAG, "Error exiting SDK: ${e.message}", e)
103
+ }
104
+ }
94
105
  }
95
106
 
96
107
  override fun didExitWorkout(summary: WorkoutSummaryData) {
@@ -113,6 +124,14 @@ class SmkitUiLibraryModule(reactContext: ReactApplicationContext) :
113
124
  }
114
125
  resultPromise?.resolve(result)
115
126
  sendEvent(reactApplicationContext, "didExitWorkout", params)
127
+ // Dismiss the SDK UI on the main thread
128
+ Handler(Looper.getMainLooper()).post {
129
+ try {
130
+ smKitUI?.exitSDK()
131
+ } catch (e: Exception) {
132
+ Log.e(TAG, "Error exiting SDK: ${e.message}", e)
133
+ }
134
+ }
116
135
  }
117
136
 
118
137
 
@@ -265,7 +284,16 @@ class SmkitUiLibraryModule(reactContext: ReactApplicationContext) :
265
284
  val assessmentType = when (type) {
266
285
  "fitness" -> Fitness
267
286
  "body360" -> Body360
268
- else -> Custom(customAssessmentId)
287
+ else -> {
288
+ // Validate customAssessmentId is not empty for custom assessments
289
+ if (customAssessmentId.isNullOrBlank()) {
290
+ Log.e(TAG, "Custom assessment ID is empty or blank")
291
+ promise.reject("Starting Assessment Failed", "Custom assessment ID is required for custom assessment type")
292
+ return
293
+ }
294
+ Log.d(TAG, "Creating Custom assessment with ID: $customAssessmentId")
295
+ Custom(customAssessmentId)
296
+ }
269
297
  }
270
298
  val user = if(userData == null) null else if (forceShowUserDataScreen) null else {
271
299
  serializeUserData(userData)
@@ -294,12 +322,20 @@ class SmkitUiLibraryModule(reactContext: ReactApplicationContext) :
294
322
  try {
295
323
  Log.d(TAG, "startCustomWorkout called with modifications: $modifications")
296
324
  resultPromise = promise
297
- val workout = serializeWorkout(jsonArguments)
325
+ // Use mapper without scoring params for workouts
326
+ val workout = serializeWorkoutWithoutScoringParams(jsonArguments)
298
327
  if (workout == null) {
299
328
  Log.e(TAG, "Failed to serialize workout from JSON")
300
329
  promise.reject("Starting Custom Workout Failed", "Failed to parse workout JSON")
301
330
  return
302
331
  }
332
+ // Verify no scoring params exist in the workout
333
+ val hasScoringParams = workout.exercises.any { it.scoringParams != null }
334
+ if (hasScoringParams) {
335
+ Log.w(TAG, "Warning: Workout still contains scoring params after removal attempt")
336
+ } else {
337
+ Log.d(TAG, "Verified: Workout has no scoring params")
338
+ }
303
339
  val (finalModifications, showPhoneCalibration) = processModifications(modifications)
304
340
  smKitUI?.startCustomizedWorkout(
305
341
  workout = workout,
@@ -354,6 +390,44 @@ class SmkitUiLibraryModule(reactContext: ReactApplicationContext) :
354
390
 
355
391
  private fun serializeWorkout(jsonArguments: String) =
356
392
  moshi.adapter(SMKitWorkout::class.java).fromJson(jsonArguments)?.toSMWorkout()
393
+
394
+ private fun serializeWorkoutWithoutScoringParams(jsonArguments: String): com.sency.smkitui.model.SMWorkout? {
395
+ // Remove scoring params from JSON before deserializing to ensure they're completely excluded
396
+ val jsonWithoutScoringParams = removeScoringParamsFromJson(jsonArguments)
397
+ return moshi.adapter(SMKitWorkout::class.java).fromJson(jsonWithoutScoringParams)?.toSMWorkoutWithoutScoringParams()
398
+ }
399
+
400
+ private fun removeScoringParamsFromJson(json: String): String {
401
+ return try {
402
+ val jsonObject = gson.fromJson(json, Map::class.java) as? Map<*, *> ?: return json
403
+ val mutableMap = jsonObject.toMutableMap()
404
+
405
+ // Get exercises array
406
+ val exercises = mutableMap["exercises"] as? List<*> ?: return json
407
+ val updatedExercises = exercises.mapIndexed { index, exercise ->
408
+ if (exercise is Map<*, *>) {
409
+ val exerciseMap = exercise.toMutableMap()
410
+ // Remove scoringParams field (check both camelCase and snake_case variants)
411
+ val removed = exerciseMap.remove("scoringParams")
412
+ exerciseMap.remove("scoring_params")
413
+ if (removed != null) {
414
+ Log.d(TAG, "Removed scoringParams from exercise at index $index")
415
+ }
416
+ exerciseMap
417
+ } else {
418
+ exercise
419
+ }
420
+ }
421
+
422
+ mutableMap["exercises"] = updatedExercises
423
+ val result = gson.toJson(mutableMap)
424
+ Log.d(TAG, "Removed scoring params from workout JSON")
425
+ result
426
+ } catch (e: Exception) {
427
+ Log.e(TAG, "Error removing scoring params from JSON: ${e.message}", e)
428
+ json // Return original JSON if parsing fails
429
+ }
430
+ }
357
431
 
358
432
  private fun serializeUserData(jsonArguments: String) =
359
433
  moshi.adapter(SMUserData::class.java).fromJson(jsonArguments)?.toUserData()
@@ -40,6 +40,17 @@ internal fun SMKitWorkout.toSMWorkout(): SMWorkout = SMWorkout(
40
40
  bodycalFinished = bodycalFinished ?: ""
41
41
  )
42
42
 
43
+ internal fun SMKitWorkout.toSMWorkoutWithoutScoringParams(): SMWorkout = SMWorkout(
44
+ id = id ?: "",
45
+ name = name ?: "",
46
+ workoutIntro = workoutIntro ?: "",
47
+ soundtrack = soundtrack ?: "",
48
+ exercises = exercises.map(SMKitExercise::toSMExerciseWithoutScoringParams),
49
+ workoutClosure = workoutClosure ?: "",
50
+ getInFrame = getInFrame ?: "",
51
+ bodycalFinished = bodycalFinished ?: ""
52
+ )
53
+
43
54
  private fun SMKitExercise.toSMExercise(): SMExercise = SMExercise(
44
55
  prettyName = prettyName ?: "",
45
56
  exerciseIntro = exerciseIntro ?: "",
@@ -57,6 +68,23 @@ private fun SMKitExercise.toSMExercise(): SMExercise = SMExercise(
57
68
  side = side
58
69
  )
59
70
 
71
+ private fun SMKitExercise.toSMExerciseWithoutScoringParams(): SMExercise = SMExercise(
72
+ prettyName = prettyName ?: "",
73
+ exerciseIntro = exerciseIntro ?: "",
74
+ totalSeconds = totalSeconds ?: 0,
75
+ videoInstruction = videoInstruction ?: "",
76
+ uiElements = uiElements ?: emptySet(),
77
+ detector = detector ?: "",
78
+ exerciseClosure = exerciseClosure ?: "",
79
+ closureFailedSound = closureFailedSound ?: "",
80
+ scoringParams = null, // Exclude scoring params for workouts
81
+ summaryTitle = summaryTitle ?: "",
82
+ summarySubTitle = summarySubTitle ?: "",
83
+ summaryMainMetricTitle = summaryTitleMainMetric ?: "",
84
+ summarySubTitleMainMetric = summarySubTitleMainMetric ?: "",
85
+ side = side
86
+ )
87
+
60
88
  private fun SMKitScoringParams.toParams(): ScoringParams {
61
89
  return ScoringParams(
62
90
  type = type ?: "",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sency/react-native-smkit-ui",
3
- "version": "2.0.5",
3
+ "version": "2.0.6",
4
4
  "description": "React Native library for SMKit UI - Advanced fitness assessments and workout programs with AI-powered motion detection and real-time performance tracking",
5
5
  "main": "lib/commonjs/index",
6
6
  "module": "lib/module/index",