@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.
package/android/build.gradle
CHANGED
|
@@ -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.
|
|
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 ->
|
|
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
|
-
|
|
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.
|
|
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",
|