@sency/react-native-smkit-ui 0.2.4 → 0.2.5

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 CHANGED
@@ -1,41 +1,113 @@
1
- # [react-native-smkit-ui demo](https://github.com/sency-ai/smkit-sdk)
1
+ # [Github:](https://github.com/sency-ai/smkit-sdk)
2
2
 
3
3
  1. [ Installation ](#inst)
4
4
  2. [ Setup ](#setup)
5
- 3. [ Configure ](#conf)
6
- 4. [ Start ](#start)
7
- 5. [ Data ](#data)
5
+ 3. [ API ](#api)
6
+ 4. [ Data ](#data)
8
7
 
9
8
  <a name="inst"></a>
9
+
10
10
  ## 1. Installation
11
- 1. run `npm install @sency/react-native-smkit-ui`
12
11
 
13
- 2. Update *Podfile* in `iOS` folder:
12
+ run `npm install @sency/react-native-smkit-ui`
13
+
14
+ ## 2. Setup <a name="setup"></a>
15
+
16
+ # iOS Setup
17
+
18
+ 1. Update _Podfile_ in `iOS` folder:
19
+
14
20
  ```
15
21
  [1] add the source to the top of your Podfile.
16
- source 'https://bitbucket.org/sency-ios/sency_ios_sdk.git'
22
+ source 'https://bitbucket.org/sencyai/ios_sdks_release.git'
17
23
  source 'https://github.com/CocoaPods/Specs.git'
18
24
 
19
25
  [2] add use_frameworks! commend to your target
20
26
  target 'YOUR_TARGET' do
21
27
  use_frameworks!
22
- ```
23
28
 
24
- 3. Run `NO_FLIPPER=1 pod install` to install the necessary pods.
29
+ [3] At the end of your code please add
30
+
31
+ post_install do |installer|
32
+ react_native_post_install(
33
+ installer,
34
+ :mac_catalyst_enabled => false
35
+ )
36
+ installer.pods_project.targets.each do |target|
37
+ target.build_configurations.each do |config|
38
+ config.build_settings['BUILD_LIBRARY_FOR_DISTRIBUTION'] = 'YES'
39
+ config.build_settings['EXCLUDED_ARCHS[sdk=iphonesimulator*]'] = 'arm64'
40
+ end
41
+ end
42
+ __apply_Xcode_12_5_M1_post_install_workaround(installer)
43
+ end
44
+ end
25
45
 
26
- ## 2. Setup <a name="setup"></a>
46
+ ```
47
+
48
+ 2. Run `NO_FLIPPER=1 pod install` to install the necessary pods.
49
+ 3. Add camera permission request to `Info.plist`
27
50
 
28
- ### iOS
29
- Add camera permission request to `Info.plist`
30
51
  ```Xml
31
52
  <key>NSCameraUsageDescription</key>
32
53
  <string>Camera access is needed</string>
33
54
  ```
34
55
 
35
- ### Android
36
- In order to integrate SMKitUI you need to import the smkitui dependency
56
+ ---
57
+
58
+ ## Known issues
59
+
60
+ 1. Dynamic/Static linking issues due to `use_frameworks`:
61
+ If you're unable to use use_frameworks you should add the following code to your Podfile:
62
+
63
+ ```ruby
64
+ # [1] Add the dynamic_frameworks array that will hold all of the dynamic frameworks names
65
+ dynamic_frameworks = ['SMKitUI', 'SMKit', 'SMBase', 'SwiftyJSON', 'SMBaseUI']
66
+
67
+ # [2] Add this pre_install function
68
+ pre_install do |installer|
69
+ installer.pod_targets.each do |pod|
70
+ if dynamic_frameworks.include?(pod.name)
71
+ def pod.build_type
72
+ Pod::BuildType.dynamic_framework
73
+ end
74
+ end
75
+ end
76
+ end
77
+
78
+ # [3] Add this post_install function
79
+ post_install do |installer|
80
+ react_native_post_install(installer, config[:reactNativePath], :mac_catalyst_enabled => false)
81
+ installer.pods_project.targets.each do |target|
82
+ if dynamic_frameworks.include?(target.name)
83
+ target.build_configurations.each do |config|
84
+ config.build_settings['BUILD_LIBRARY_FOR_DISTRIBUTION'] = 'YES'
85
+ config.build_settings['EXCLUDED_ARCHS[sdk=iphonesimulator*]'] = 'arm64'
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
91
+ ```
92
+
93
+ Now you can run pod install.
94
+
95
+ # Android Setup
96
+
97
+ In order to integrate SMKitUI you need your app to target minSdk 26
98
+ Add on project level `build.gradle`:
99
+
100
+ ```groovy
101
+ buildscript {
102
+ ext {
103
+ minSdkVersion = 26
104
+ }
105
+ }
106
+ ```
107
+
37
108
  Add on project level build.gradle:
38
- ```groovy
109
+
110
+ ```groovy
39
111
  allprojects {
40
112
  maven {
41
113
  url "https://artifacts.sency.ai/artifactory/release/"
@@ -43,29 +115,13 @@ allprojects {
43
115
  }
44
116
  ```
45
117
 
46
- #### FBJNI
47
-
48
- Both React Native and SencyMotion use **fbjni**. For example, the versions for SMKitUI that are used for
49
- development are:
50
-
51
- React Native (<= 0.64) uses fbjni **0.0.2**
52
- SMKitUI uses fbjni **0.2.2**.
53
- Therefore we need to exclude fbjbi on app level build.gradle:
54
- ```groovy
55
- dependencies {
56
- ...
57
- implementation('com.sency.smkitui:smkitui:$latest_version'){
58
- exclude group: 'com.facebook.fbjni', module: 'fbjni-java-only'
59
- }
60
- ...
61
- }
62
- ```
118
+ ## 3. API<a name="api"></a>
63
119
 
64
- ## 3. Configure <a name="conf"></a>
120
+ ### 1. Configure <a name="conf"></a>
65
121
 
66
122
  ```js
67
123
  [1] First import configure
68
- import { configure } from '@sency/react-native-smkit-ui-dev/src/index.tsx';
124
+ import { configure } from '@sency/react-native-smkit-ui/src/index.tsx';
69
125
 
70
126
  [2] then call the configure function with your auth key
71
127
  try{
@@ -79,123 +135,26 @@ To reduce wait time we recommend to call `configure` on app launch.
79
135
 
80
136
  **⚠️ smkit_ui_library will not work if you don't first call configure.**
81
137
 
82
- ## 4. Start <a name="start"></a>
138
+ ## 2. Start <a name="start"></a>
83
139
 
84
- 1. Import the sdk
85
- ```js
86
- import { startAssessment, startCustomWorkout, AssessmentTypes } from '@sency/react-native-smkit-ui-dev/src/index.tsx';
87
- import SMKitUI from '@sency/react-native-smkit-ui-dev/src/SMKitUIView.tsx';
88
- import * as SMWorkoutLibrary from '@sency/react-native-smkit-ui-dev/src/SMWorkout.tsx';
89
- ```
140
+ #### [Start Assessment](#data)
90
141
 
91
- 2. Add `SMKitUI` view:
92
- ```js
93
- return (
94
- <View style={styles.centeredView}>
95
- <SMKitUI/>
96
- </View>
97
- );
98
- ```
142
+ - [Start Assessment](https://github.com/sency-ai/smkit-ui-react-native-demo/blob/main/Assessment.md)
99
143
 
100
- #### [Start Assessment](https://github.com/sency-ai/smkit-sdk/blob/main/AI-Fitness-Assessment.md)
101
- **startAssessment** starts one of Sency's blueprint assessments.
102
- ```js
103
- async function startFitnessAssessment(){
104
- try{
105
- var result = await startAssessment(AssessmentTypes.Fitness, true); // => type: SMWorkoutLibrary.AssessmentTypes, showSummary:boolean
106
- console.log(result.summary);
107
- console.log(result.didFinish);
108
- }catch(e) {
109
- console.error(e);
110
- }
111
- }
112
- ```
113
- > Check out [this info page](https://github.com/sency-ai/smkit-sdk/blob/main/AI-Fitness-Assessment.md) if you want to learn more about **Sency's AI Fitness Assessment**
144
+ - [Start Workout](https://github.com/sency-ai/smkit-ui-react-native-demo/blob/main/Workout.md)
114
145
 
115
- ### Start Custom Workout
116
- **startWorkout** starts a custom workout.
117
- ```js
118
- async function startSMKitUICustomWorkout(){
119
- try{
120
- // list of exercies
121
- var exercises = [
122
- new SMWorkoutLibrary.SMExercise(
123
- name: "First Exercise", // => name:string | null
124
- 35, // => totalSeconds: number | null
125
- 5, // => introSeconds: number | null
126
- null, // => videoInstruction: string | null (url for a video)
127
- null, // => exerciseIntro: string | null (url for a sound)
128
- [SMWorkoutLibrary.UIElement.RepsCounter, SMWorkoutLibrary.UIElement.Timer], // => uiElements: UIElement[] | null
129
- "HighKnees", // => detector: string
130
- true, // => repBased: boolean | null
131
- null, // => exerciseClosure: string | null (url for a sound)
132
- 13, // => targetReps: number | null
133
- 20, // => targetTime: number | null
134
- 0.3 // => scoreFactor: number | null
135
- ),
136
- new SMWorkoutLibrary.SMExercise(
137
- "Second Exercise", // => name:string | null
138
- 25, // => totalSeconds: number | null
139
- 5, // => introSeconds: number | null
140
- null, // => videoInstruction: string | null (url for a video)
141
- null, // => exerciseIntro: string | null (url for a sound)
142
- [SMWorkoutLibrary.UIElement.GaugeOfMotion, SMWorkoutLibrary.UIElement.Timer], // => uiElements: UIElement[] | null
143
- "SquatRegularOverheadStatic", // => detector: string
144
- false, // => repBased: boolean | null
145
- null, // => exerciseClosure: string | null (url for a sound)
146
- null, // => targetReps: number | null
147
- 20, // => targetTime: number | null
148
- 0.3 // => scoreFactor: number | null
149
- ),
150
- ];
151
-
152
- var workout = new SMWorkoutLibrary.SMWorkout(
153
- "50", // => id: string | null
154
- "demo workout",// => name: string | null
155
- null, // => workoutIntro: string | null (url for a sound)
156
- null, // => soundtrack: string | null (url for a sound)
157
- exercises, // => exercises: SMExercise[]
158
- null, // => getInFrame: string | null (url for a sound)
159
- null, // => bodycalFinished: string | null (url for a sound)
160
- null // => workoutClosure: string | null (url for a sound)
161
- );
162
- var result = await startCustomWorkout(workout);
163
- console.log(result.summary);
164
- console.log(result.didFinish);
165
- }catch(e){
166
- console.error(e);
167
- }
168
- }
169
- ```
146
+ - [Build Your Own Assessment](https://github.com/sency-ai/smkit-ui-react-native-demo/blob/main/CustomizedAssessment.md)
170
147
 
171
- ### Start Program
172
- **startWorkoutProgram** starts a workout program according to your WorkoutConfig.
173
- ```js
174
- async function startSMKitUIProgram(){
175
- try{
176
- //WorkoutConfig
177
- var config = new SMWorkoutLibrary.WorkoutConfig(
178
- 3, // => week: number
179
- SMWorkoutLibrary.BodyZone.FullBody, // => bodyZone: BodyZone
180
- SMWorkoutLibrary.WorkoutDifficulty.HighDifficulty, // => difficultyLevel: WorkoutDifficulty
181
- SMWorkoutLibrary.WorkoutDuration.Short, // => workoutDuration: WorkoutDuration
182
- "YOUR_PROGRAM_ID" // => programID: string
183
- );
184
- var result = await startWorkoutProgram(config);
185
- console.log(result.summary);
186
- console.log(result.didFinish);
187
- }catch(e){
188
- console.error(e);
189
- }
190
- }
191
- }
192
- ```
148
+ ##Data <a name="data"></a>
149
+
150
+ ### AssessmentTypes
193
151
 
194
- ## Available Data Types <a name="data"></a>
195
- #### `AssessmentTypes`
196
- | Name |
197
- |---------------------|
198
- | Fitness |
199
- | Custom |
152
+ | Name (enum) | Description | More info |
153
+ | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------- |
154
+ | Fitness | For individuals of any activity level who seek to enhance their physical abilities, strength, and endurance through a tailored plan. | [Link](https://github.com/sency-ai/smkit-sdk/blob/main/Assessments/AI-Fitness-Assessment.md) |
155
+ | Body360 | Designed for individuals of any age and activity level, this assessment determines the need for a preventative plan or medical support. | [Link](https://github.com/sency-ai/smkit-sdk/blob/main/Assessments/360-Body-Assessment.md) |
156
+ | Strength | For individuals of any activity level who seek to assess their strength capabilities (core and endurance) \* This assessment will be available soon. Contact us for more info. | [Link](https://github.com/sency-ai/smkit-sdk/blob/main/Assessments/Strength.md) |
157
+ | Cardio | For individuals of any activity level who seek to assess their cardiovascular capabilities \* This assessment will be available soon. Contact us for more info. | [Link](https://github.com/sency-ai/smkit-sdk/blob/main/Assessments/Cardio.md) |
158
+ | Custom | If Sency created a tailored assessment for you, you probably know it, and you should use this enum. | |
200
159
 
201
160
  Having issues? [Contact us](mailto:support@sency.ai) and let us know what the problem is.
@@ -93,10 +93,13 @@ dependencies {
93
93
  implementation "com.facebook.react:react-native:+"
94
94
  implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
95
95
 
96
- implementation("com.sency.smkitui:smkitui:0.2.1") {
96
+ implementation("com.sency.smkitui:smkitui:0.2.3") {
97
97
  exclude group: 'com.facebook.fbjni', module: 'fbjni-java-only'
98
98
  }
99
99
 
100
+ // Gson
101
+ implementation 'com.google.code.gson:gson:2.9.0'
102
+
100
103
  // Moshi JSON library
101
104
  def moshi = "1.15.0"
102
105
  implementation "com.squareup.moshi:moshi:$moshi"
@@ -3,25 +3,47 @@ package com.smkituilibrary
3
3
  import android.util.Log
4
4
  import com.facebook.react.bridge.Promise
5
5
  import com.facebook.react.bridge.ReactApplicationContext
6
+ import com.facebook.react.bridge.ReactContext
6
7
  import com.facebook.react.bridge.ReactContextBaseJavaModule
7
8
  import com.facebook.react.bridge.ReactMethod
9
+ import com.facebook.react.bridge.WritableMap
10
+ import com.facebook.react.bridge.WritableNativeMap
11
+ import com.facebook.react.modules.core.DeviceEventManagerModule
12
+ import com.google.gson.Gson
13
+ import com.google.gson.GsonBuilder
14
+ import com.google.gson.Strictness
8
15
  import com.sency.smkitui.SMKitUI
9
16
  import com.sency.smkitui.listener.SMKitUIConfigurationListener
10
17
  import com.sency.smkitui.listener.SMKitUIWorkoutListener
11
18
  import com.sency.smkitui.model.ExerciseData
19
+ import com.sency.smkitui.model.ScoringParamsData
20
+ import com.sency.smkitui.model.UserData
12
21
  import com.sency.smkitui.model.WorkoutSummaryData
13
22
  import com.sency.smkitui.model.smkitui.Body360
14
23
  import com.sency.smkitui.model.smkitui.Custom
15
24
  import com.sency.smkitui.model.smkitui.Fitness
25
+ import com.sency.smkitui.model.workoutConfig.WorkoutConfigModel
16
26
  import com.smkituilibrary.mapper.toSMWorkout
27
+ import com.smkituilibrary.mapper.toWFPSummary
17
28
  import com.smkituilibrary.mapper.toWorkoutConfig
18
29
  import com.smkituilibrary.model.SMKitWorkout
19
30
  import com.smkituilibrary.model.SMKitWorkoutConfig
20
31
  import com.smkituilibrary.model.SMUserData
32
+ import com.smkituilibrary.model.WFPExerciseData
33
+ import com.smkituilibrary.model.WFPSummary
21
34
  import com.smkituilibrary.model.toUserData
35
+ import com.smkituilibrary.serializers.ExerciseDataSerializer
36
+ import com.smkituilibrary.serializers.FeedbackSerializer
37
+ import com.smkituilibrary.serializers.ScoringParamsDataSerializer
38
+ import com.smkituilibrary.serializers.UserDataSerializer
39
+ import com.smkituilibrary.serializers.WFPExerciseDataSerializer
40
+ import com.smkituilibrary.serializers.WFPSummarySerializer
41
+ import com.smkituilibrary.serializers.WorkoutConfigSerializer
42
+ import com.smkituilibrary.serializers.WorkoutSummarySerializer
22
43
  import com.squareup.moshi.Moshi
23
44
  import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
24
45
 
46
+
25
47
  class SmkitUiLibraryModule(reactContext: ReactApplicationContext) :
26
48
  ReactContextBaseJavaModule(reactContext) {
27
49
 
@@ -30,24 +52,70 @@ class SmkitUiLibraryModule(reactContext: ReactApplicationContext) :
30
52
  private var smKitUI: SMKitUI? = null
31
53
  private var resultPromise: Promise? = null
32
54
  private val moshi: Moshi by lazy { moshi() }
55
+ private val gson: Gson by lazy { gson() }
56
+ private var workoutFromProgram = false
33
57
 
34
58
  override fun getName(): String = "SMKitUIManager"
35
59
 
36
60
  private val listener = object : SMKitUIWorkoutListener {
37
61
  override fun handleWorkoutErrors(error: Error) {
38
- resultPromise?.reject("Workout Exercise Error", error)
62
+ val params: WritableMap = WritableNativeMap()
63
+ params.putString("error", error.message)
64
+
65
+ sendEvent(reactApplicationContext, "workoutError", params)
39
66
  }
40
67
 
41
68
  override fun workoutDidFinish(summary: WorkoutSummaryData) {
42
- sendResult(summary, didFinish = true)
69
+ val params: WritableMap = WritableNativeMap()
70
+ val summaryJson: String = try {
71
+ if(workoutFromProgram) {
72
+ gson.toJson(summary.toWFPSummary())
73
+ } else {
74
+ gson.toJson(summary)
75
+ }
76
+ } catch (e: Exception) {
77
+ summary.toString()
78
+ }
79
+ params.putString("summary", summaryJson)
80
+ params.putBoolean("didFinish", true)
81
+
82
+ sendEvent(reactApplicationContext, "workoutDidFinish", params)
43
83
  }
44
84
 
45
85
  override fun didExitWorkout(summary: WorkoutSummaryData) {
46
- sendResult(summary, didFinish = false)
86
+ val params: WritableMap = WritableNativeMap()
87
+ val summaryJson: String = try {
88
+ if(workoutFromProgram) {
89
+ gson.toJson(summary.toWFPSummary())
90
+ } else {
91
+ gson.toJson(summary)
92
+ }
93
+ } catch (e: Exception) {
94
+ summary.toString()
95
+ }
96
+ params.putString("summary", summaryJson)
97
+ params.putBoolean("didFinish", false)
98
+
99
+ sendEvent(reactApplicationContext, "didExitWorkout", params)
47
100
  }
48
101
 
102
+
49
103
  override fun exerciseDidFinish(data: ExerciseData) {
50
- println(data)
104
+ val params: WritableMap = WritableNativeMap()
105
+ val dataJson: String = try {
106
+ gson.toJson(data)
107
+ } catch (e: Exception) {
108
+ data.toString()
109
+ }
110
+ params.putString("data", dataJson)
111
+
112
+ sendEvent(reactApplicationContext, "exerciseDidFinish", params)
113
+ }
114
+
115
+ private fun sendEvent(reactContext: ReactContext, eventName: String, params: WritableMap) {
116
+ reactContext
117
+ .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
118
+ .emit(eventName, params)
51
119
  }
52
120
  }
53
121
 
@@ -76,7 +144,7 @@ class SmkitUiLibraryModule(reactContext: ReactApplicationContext) :
76
144
  promise: Promise,
77
145
  ) {
78
146
  this.resultPromise = promise
79
-
147
+ workoutFromProgram = false
80
148
  try {
81
149
  val assessmentType = when (type) {
82
150
  "fitness" -> Fitness
@@ -99,6 +167,8 @@ class SmkitUiLibraryModule(reactContext: ReactApplicationContext) :
99
167
 
100
168
  @ReactMethod
101
169
  fun startCustomWorkout(jsonArguments: String, promise: Promise) {
170
+ workoutFromProgram = false
171
+
102
172
  try {
103
173
  serializeWorkout(jsonArguments)?.let {
104
174
  smKitUI?.startCustomizedWorkout(workout = it, listener = listener)
@@ -116,6 +186,7 @@ class SmkitUiLibraryModule(reactContext: ReactApplicationContext) :
116
186
  showSummary: Boolean,
117
187
  promise: Promise
118
188
  ) {
189
+ workoutFromProgram = false
119
190
  try {
120
191
  serializeWorkout(assessmentJson)?.let {
121
192
  smKitUI?.startCustomizedAssessment(workout = it, showSummary = showSummary, listener = listener)
@@ -134,11 +205,13 @@ class SmkitUiLibraryModule(reactContext: ReactApplicationContext) :
134
205
 
135
206
  @ReactMethod
136
207
  fun startWorkoutProgram(jsonArguments: String, promise: Promise) {
208
+ workoutFromProgram = true
137
209
  try {
138
210
  Log.d(TAG, "startWorkoutProgram: $jsonArguments")
139
211
  val adapter = moshi.adapter(SMKitWorkoutConfig::class.java)
140
212
  val smKitWorkoutConfig = adapter.fromJson(jsonArguments) ?: return
141
213
 
214
+ resultPromise = promise
142
215
  smKitUI?.startWorkoutProgram(
143
216
  workoutConfig = smKitWorkoutConfig.toWorkoutConfig(),
144
217
  listener = listener,
@@ -148,6 +221,7 @@ class SmkitUiLibraryModule(reactContext: ReactApplicationContext) :
148
221
  }
149
222
  }
150
223
 
224
+
151
225
  private fun sendResult(summary: WorkoutSummaryData, didFinish: Boolean) {
152
226
  val promise = resultPromise ?: run {
153
227
  resultPromise?.reject("Unable to create summary", "Missing callback", null)
@@ -165,6 +239,20 @@ class SmkitUiLibraryModule(reactContext: ReactApplicationContext) :
165
239
  }
166
240
  }
167
241
 
242
+ private fun gson(): Gson {
243
+ return GsonBuilder()
244
+ .registerTypeAdapter(WorkoutSummaryData::class.java, WorkoutSummarySerializer())
245
+ .registerTypeAdapter(ExerciseData::class.java, ExerciseDataSerializer())
246
+ .registerTypeAdapter(ScoringParamsData::class.java, ScoringParamsDataSerializer())
247
+ .registerTypeAdapter(UserData::class.java, UserDataSerializer())
248
+ .registerTypeAdapter(WorkoutConfigModel::class.java, WorkoutConfigSerializer())
249
+ .registerTypeAdapter(WFPExerciseData::class.java, WFPExerciseDataSerializer())
250
+ .registerTypeAdapter(WFPSummary::class.java, WFPSummarySerializer())
251
+ .registerTypeAdapter(FeedbackSerializer::class.java, FeedbackSerializer())
252
+ .setStrictness(Strictness.LENIENT)
253
+ .create()
254
+ }
255
+
168
256
  private fun moshi(): Moshi {
169
257
  return Moshi.Builder()
170
258
  .add(KotlinJsonAdapterFactory())
@@ -1,17 +1,25 @@
1
1
  package com.smkituilibrary.mapper
2
2
 
3
3
  import com.sency.smkitui.data.entity.ScoringParams
4
+ import com.sency.smkitui.data.entity.UiElement
5
+ import com.sency.smkitui.model.ExerciseData
4
6
  import com.sency.smkitui.model.SMExercise
5
7
  import com.sency.smkitui.model.SMWorkout
8
+ import com.sency.smkitui.model.ScoringParamsData
9
+ import com.sency.smkitui.model.UserData
10
+ import com.sency.smkitui.model.WorkoutSummaryData
6
11
  import com.sency.smkitui.model.workoutConfig.BodyZone
7
12
  import com.sency.smkitui.model.workoutConfig.DifficultyLevel
8
13
  import com.sency.smkitui.model.workoutConfig.SMLanguage
9
14
  import com.sency.smkitui.model.workoutConfig.WorkoutConfig
15
+ import com.sency.smkitui.model.workoutConfig.WorkoutConfigModel
10
16
  import com.sency.smkitui.model.workoutConfig.WorkoutDuration
11
17
  import com.smkituilibrary.model.SMKitExercise
12
18
  import com.smkituilibrary.model.SMKitScoringParams
13
19
  import com.smkituilibrary.model.SMKitWorkout
14
20
  import com.smkituilibrary.model.SMKitWorkoutConfig
21
+ import com.smkituilibrary.model.WFPExerciseData
22
+ import com.smkituilibrary.model.WFPSummary
15
23
 
16
24
  internal fun SMKitWorkoutConfig.toWorkoutConfig(): WorkoutConfig = WorkoutConfig(
17
25
  programId = programID,
@@ -37,17 +45,15 @@ private fun SMKitExercise.toSMExercise(): SMExercise = SMExercise(
37
45
  prettyName = prettyName ?: "",
38
46
  exerciseIntro = exerciseIntro ?: "",
39
47
  totalSeconds = totalSeconds ?: 0,
40
- introSeconds = introSeconds ?: 0,
41
- videoInstruction = videoInstruction ?:"",
48
+ videoInstruction = videoInstruction ?: "",
42
49
  uiElements = uiElements ?: emptySet(),
43
50
  detector = detector ?: "",
44
- repBased = repBased ?: false,
45
51
  exerciseClosure = exerciseClosure ?: "",
46
52
  scoringParams = scoringParams?.toParams(),
47
53
  summaryTitle = summaryTitle ?: "",
48
54
  summarySubTitle = summarySubTitle ?: "",
49
- summaryTitleMainMetric = summaryTitleMainMetric ?: "",
50
- summarySubTitleMainMetric = summarySubTitleMainMetric ?: "",
55
+ summaryMainMetricTitle = summaryTitleMainMetric ?: "",
56
+ summaryMainMetricSubTitle = summarySubTitleMainMetric ?: "",
51
57
  side = side
52
58
  )
53
59
 
@@ -61,3 +67,44 @@ private fun SMKitScoringParams.toParams(): ScoringParams {
61
67
  passCriteria = passCriteria
62
68
  )
63
69
  }
70
+
71
+
72
+ fun WorkoutSummaryData.toWFPSummary(): WFPSummary {
73
+ return WFPSummary(
74
+ userData = userData,
75
+ sessionId = sessionId,
76
+ activityType = activityType,
77
+ startTime = startTime,
78
+ endTime = endTime,
79
+ totalTime = totalTime,
80
+ totalScore = totalScore,
81
+ exercises = exercises.map(ExerciseData::toWFPExerciseData),
82
+ workoutConfig = workoutConfig,
83
+ )
84
+ }
85
+
86
+ fun ExerciseData.toWFPExerciseData() = WFPExerciseData(
87
+ userData = userData,
88
+ activityType = activityType,
89
+ sessionId = sessionId,
90
+ startTime = startTime,
91
+ endTime = endTime,
92
+ assessmentId = assessmentId,
93
+ totalScore = totalScore,
94
+ performanceScore = performanceScore,
95
+ techniqueScore = techniqueScore,
96
+ repsPerformed = repsPerformed,
97
+ repsPerformedPerfect = repsPerformedPerfect,
98
+ timeInPosition = timeInPosition,
99
+ timeInPositionPerfect = timeInPositionPerfect,
100
+ peakRangeOfMotion = peakRangeOfMotion,
101
+ feedbacks = feedbacks,
102
+ exerciseId = exerciseId,
103
+ totalTime = totalTime,
104
+ uiElements = uiElements,
105
+ instructionVideo = instructionVideo,
106
+ voiceIntro = voiceIntro,
107
+ prettyName = prettyName,
108
+ side = side,
109
+ scoringParamsData = scoringParamsData,
110
+ )
@@ -0,0 +1,49 @@
1
+ package com.smkituilibrary.model
2
+
3
+ import androidx.annotation.Keep
4
+ import com.sency.smkitui.data.entity.UiElement
5
+ import com.sency.smkitui.model.ScoringParamsData
6
+ import com.sency.smkitui.model.UserData
7
+ import com.sency.smkitui.model.workoutConfig.WorkoutConfigModel
8
+
9
+ @Keep
10
+ data class WFPSummary(
11
+ var userData: UserData,
12
+ var sessionId: String,
13
+ var activityType: String = "",
14
+ var startTime: String = "",
15
+ var endTime: String = "",
16
+ var totalTime: Long = 0L,
17
+ var totalScore: Float = 0F,
18
+ var exercises: List<WFPExerciseData> = arrayListOf(),
19
+ var workoutConfig: WorkoutConfigModel? = null
20
+ )
21
+
22
+
23
+ @Keep
24
+ data class WFPExerciseData(
25
+ var userData: UserData,
26
+ var activityType: String,
27
+ var sessionId: String,
28
+ var startTime: String,
29
+ var endTime: String,
30
+ var assessmentId: String?,
31
+ var totalScore: Float? = 0f,
32
+ var performanceScore: Float? = 0f,
33
+ var techniqueScore: Float? = 0f,
34
+ var repsPerformed: Int? = 0,
35
+ var repsPerformedPerfect: Int? = 0,
36
+ var timeInPosition: Float? = 0f,
37
+ var timeInPositionPerfect: Float? = 0f,
38
+ var peakRangeOfMotion: Float? = 0f,
39
+ var feedbacks: Map<String, Float>?,
40
+ // Exercise Info Data
41
+ var exerciseId: String,
42
+ var totalTime: Long,
43
+ var uiElements: List<UiElement>,
44
+ var instructionVideo: String,
45
+ var voiceIntro: String,
46
+ var prettyName: String,
47
+ val side: String?,
48
+ var scoringParamsData: ScoringParamsData?
49
+ )
@@ -0,0 +1,182 @@
1
+ package com.smkituilibrary.serializers
2
+
3
+ import com.google.gson.JsonElement
4
+ import com.google.gson.JsonObject
5
+ import com.google.gson.JsonSerializationContext
6
+ import com.google.gson.JsonSerializer
7
+ import com.sency.smkitui.model.ExerciseData
8
+ import com.sency.smkitui.model.Feedback
9
+ import com.sency.smkitui.model.ScoringParamsData
10
+ import com.sency.smkitui.model.UserData
11
+ import com.sency.smkitui.model.WorkoutSummaryData
12
+ import com.sency.smkitui.model.workoutConfig.WorkoutConfig
13
+ import com.sency.smkitui.model.workoutConfig.WorkoutConfigModel
14
+ import com.smkituilibrary.model.WFPExerciseData
15
+ import com.smkituilibrary.model.WFPSummary
16
+ import java.lang.reflect.Type
17
+
18
+ class WorkoutSummarySerializer : JsonSerializer<WorkoutSummaryData> {
19
+ override fun serialize(
20
+ src: WorkoutSummaryData,
21
+ typeOfSrc: Type?,
22
+ context: JsonSerializationContext
23
+ ): JsonElement {
24
+ return JsonObject().apply {
25
+ add("workout_details", context.serialize(src.workoutConfig))
26
+ add("user_data", context.serialize(src.userData))
27
+ add("session_id", context.serialize(src.sessionId))
28
+ add("type", context.serialize(src.activityType))
29
+ add("start_time", context.serialize(src.startTime))
30
+ add("end_time", context.serialize(src.endTime))
31
+ add("total_time", context.serialize(src.totalTime.toDouble()))
32
+ add("total_score", context.serialize(src.totalScore.toInt()))
33
+ add("total_score_segmented", context.serialize(src.totalScoreSegmented.toInt()))
34
+ add("exercises", context.serialize(src.exercises))
35
+ }
36
+ }
37
+ }
38
+
39
+ class WFPSummarySerializer : JsonSerializer<WFPSummary> {
40
+ override fun serialize(
41
+ src: WFPSummary,
42
+ typeOfSrc: Type?,
43
+ context: JsonSerializationContext
44
+ ): JsonElement {
45
+ return JsonObject().apply {
46
+ add("workout_details", context.serialize(src.workoutConfig))
47
+ add("user_data", context.serialize(src.userData))
48
+ add("session_id", context.serialize(src.sessionId))
49
+ add("type", context.serialize(src.activityType))
50
+ add("start_time", context.serialize(src.startTime))
51
+ add("end_time", context.serialize(src.endTime))
52
+ add("total_time", context.serialize(src.totalTime.toDouble()))
53
+ add("total_score", context.serialize(src.totalScore.toInt()))
54
+ add("exercises", context.serialize(src.exercises))
55
+ }
56
+ }
57
+ }
58
+
59
+ class WorkoutConfigSerializer: JsonSerializer<WorkoutConfigModel> {
60
+ override fun serialize(
61
+ src: WorkoutConfigModel,
62
+ typeOfSrc: Type?,
63
+ context: JsonSerializationContext?
64
+ ): JsonElement {
65
+ return src.convertToJson()
66
+ }
67
+ }
68
+
69
+ class UserDataSerializer: JsonSerializer<UserData> {
70
+ override fun serialize(
71
+ src: UserData,
72
+ typeOfSrc: Type?,
73
+ context: JsonSerializationContext
74
+ ): JsonElement {
75
+ return JsonObject().apply {
76
+ add("age", context.serialize(src.age))
77
+ add("gender", context.serialize(src.gender))
78
+ add("email", context.serialize(src.email))
79
+ }
80
+ }
81
+
82
+ }
83
+
84
+ class ExerciseDataSerializer : JsonSerializer<ExerciseData> {
85
+ override fun serialize(
86
+ src: ExerciseData,
87
+ typeOfSrc: Type?,
88
+ context: JsonSerializationContext
89
+ ): JsonElement {
90
+ return JsonObject().apply {
91
+ add("activity_type", context.serialize(src.activityType))
92
+ src.totalScore?.let { add("total_score", context.serialize(it)) }
93
+ src.totalScoreSegmented?.let { add("total_score_segmented", context.serialize(it)) }
94
+ src.performanceScore?.let { add("performance_score", context.serialize(it)) }
95
+ src.performanceScoreSegmented?.let { add("performance_score_segmented", context.serialize(it)) }
96
+ src.techniqueScore?.let { add("technique_score", context.serialize(it)) }
97
+ src.techniqueScoreSegmented?.let { add("technique_score_segmented", context.serialize(it)) }
98
+ src.repsPerformed?.let { add("reps_performed", context.serialize(it)) }
99
+ src.repsPerformedPerfect?.let { add("reps_performed_perfect", context.serialize(it)) }
100
+ src.timeInPosition?.let { add("time_in_position", context.serialize(it)) }
101
+ src.timeInPositionPerfect?.let { add("time_in_position_perfect", context.serialize(it)) }
102
+ src.peakRangeOfMotion?.let { add("peak_range_of_motion_score", context.serialize(it)) }
103
+ add("user_data", context.serialize(src.userData))
104
+ add("session_id", context.serialize(src.sessionId))
105
+ add("start_time", context.serialize(src.startTime))
106
+ add("end_time", context.serialize(src.endTime))
107
+ add("feedback", context.serialize(src.feedbacks))
108
+ add("exercise_id", context.serialize(src.exerciseId))
109
+ add("total_time", context.serialize(src.totalTime))
110
+ val strings = src.uiElements.map { it.name }
111
+ add("ui_elements", context.serialize(strings))
112
+ add("instruction_video", context.serialize(src.instructionVideo))
113
+ add("voice_outro", context.serialize(src.voicOutro))
114
+ add("voice_intro", context.serialize(src.voiceIntro))
115
+ add("pretty_name", context.serialize(src.prettyName))
116
+ add("score_params", context.serialize(src.scoringParamsData))
117
+ }
118
+ }
119
+ }
120
+
121
+ class WFPExerciseDataSerializer : JsonSerializer<WFPExerciseData> {
122
+ override fun serialize(
123
+ src: WFPExerciseData,
124
+ typeOfSrc: Type?,
125
+ context: JsonSerializationContext
126
+ ): JsonElement {
127
+ return JsonObject().apply {
128
+ add("activity_type", context.serialize(src.activityType))
129
+ add("start_time", context.serialize(src.startTime))
130
+ add("end_time", context.serialize(src.endTime))
131
+ add("exercise_info", JsonObject().apply {
132
+ add("pretty_name", context.serialize(src.prettyName))
133
+ add("exercise_id", context.serialize(src.exerciseId))
134
+ add("total_time", context.serialize(src.totalTime))
135
+ add("score_params", context.serialize(src.scoringParamsData))
136
+ val strings = src.uiElements.map { it.name }
137
+ add("ui_elements", context.serialize(strings))
138
+ add("instruction_video", context.serialize(src.instructionVideo))
139
+ add("voice_intro", context.serialize(src.voiceIntro))
140
+
141
+ })
142
+ add("feedback", context.serialize(src.feedbacks))
143
+ src.totalScore?.let { add("total_score", context.serialize(it)) }
144
+ src.performanceScore?.let { add("performance_score", context.serialize(it)) }
145
+ src.techniqueScore?.let { add("technique_score", context.serialize(it)) }
146
+ src.repsPerformed?.let { add("reps_performed", context.serialize(it)) }
147
+ src.repsPerformedPerfect?.let { add("reps_performed_perfect", context.serialize(it)) }
148
+ src.timeInPosition?.let { add("time_in_position", context.serialize(it)) }
149
+ src.timeInPositionPerfect?.let { add("time_in_position_perfect", context.serialize(it)) }
150
+ src.peakRangeOfMotion?.let { add("peak_range_of_motion_score", context.serialize(it)) }
151
+ add("session_id", context.serialize(src.sessionId))
152
+ add("user_data", context.serialize(src.userData))
153
+ }
154
+ }
155
+ }
156
+
157
+ class ScoringParamsDataSerializer : JsonSerializer<ScoringParamsData> {
158
+ override fun serialize(
159
+ src: ScoringParamsData, typeOfSrc: Type, context: JsonSerializationContext
160
+ ): JsonElement {
161
+ return JsonObject().apply {
162
+ add("score_factor", context.serialize(src.scoreFactor))
163
+ add("type", context.serialize(src.type))
164
+ add("target_time", context.serialize(src.targetTime))
165
+ add("target_reps", context.serialize(src.targetReps))
166
+ add("pass_criteria", context.serialize(src.passCriteria))
167
+ add("target_rom", context.serialize(src.targetRom))
168
+ }
169
+ }
170
+ }
171
+
172
+ class FeedbackSerializer : JsonSerializer<Feedback> {
173
+ override fun serialize(
174
+ src: Feedback, typeOfSrc: Type, context: JsonSerializationContext
175
+ ): JsonElement {
176
+ return JsonObject().apply {
177
+ add("feedback_type", context.serialize(src.feedbackType))
178
+ add("occurrence_rate", context.serialize(src.occurrenceRate.toString()))
179
+ add("description", context.serialize(src.description))
180
+ }
181
+ }
182
+ }
@@ -4,13 +4,13 @@ import SMBase
4
4
 
5
5
  @objc(SMKitUIManager)
6
6
  class SMKitUIManager: RCTViewManager {
7
-
7
+
8
8
  var onWorkoutDidFinish:RCTPromiseResolveBlock?
9
9
  var onWorkoutFailed:RCTPromiseRejectBlock?
10
-
10
+
11
11
  var summaryData:WorkoutSummaryData?
12
12
  var didCompleteWorkout = false
13
-
13
+
14
14
  var didReciveSummary = false{
15
15
  didSet{
16
16
  if didReciveSummary && workoutDidEnd{
@@ -18,7 +18,7 @@ class SMKitUIManager: RCTViewManager {
18
18
  }
19
19
  }
20
20
  }
21
-
21
+
22
22
  var workoutDidEnd = false{
23
23
  didSet{
24
24
  if didReciveSummary && workoutDidEnd{
@@ -26,7 +26,7 @@ class SMKitUIManager: RCTViewManager {
26
26
  }
27
27
  }
28
28
  }
29
-
29
+
30
30
  var smkitUIViewController:UIViewController?{
31
31
  let keyWindow = UIApplication.shared.windows.filter {$0.isKeyWindow}.first
32
32
  if var topController = keyWindow?.rootViewController {
@@ -37,7 +37,7 @@ class SMKitUIManager: RCTViewManager {
37
37
  }
38
38
  return nil
39
39
  }
40
-
40
+
41
41
  @objc(configure:onSuccess:onFailure:)
42
42
  func configure(key:NSString, onSuccess: @escaping RCTPromiseResolveBlock,onFailure:@escaping RCTPromiseRejectBlock) -> Void {
43
43
  var isConfigDone = false
@@ -54,20 +54,20 @@ class SMKitUIManager: RCTViewManager {
54
54
  }
55
55
  }
56
56
  }
57
-
57
+
58
58
  @objc(startAssessment:showSummary:userData:forceShowUserDataScreen:customAssessmentID:onWorkoutDidFinish:onWorkoutFailed:)
59
59
  func startAssessment(type:NSString, showSummary:Bool, userData:NSString?, forceShowUserDataScreen:Bool, customAssessmentID:String?, onWorkoutDidFinish: @escaping RCTPromiseResolveBlock, onWorkoutFailed:@escaping RCTPromiseRejectBlock){
60
60
  DispatchQueue.main.async {[weak self] in
61
-
61
+
62
62
  guard let self = self,
63
63
  let smkitUIViewController = smkitUIViewController else {
64
64
  onWorkoutFailed("StartAssessment Failed", "Failed to present view", nil)
65
65
  return
66
66
  }
67
-
67
+
68
68
  self.onWorkoutDidFinish = onWorkoutDidFinish
69
69
  self.onWorkoutFailed = onWorkoutFailed
70
-
70
+
71
71
  do{
72
72
  let userData = try self.getUserData(rawJson: userData)
73
73
  if let type = AssessmentTypes(rawValue: "\(type)"){
@@ -89,11 +89,11 @@ class SMKitUIManager: RCTViewManager {
89
89
  }
90
90
  }
91
91
  }
92
-
92
+
93
93
  @objc(startCustomWorkout:onWorkoutDidFinish:onWorkoutFailed:)
94
94
  func startCustomWorkout(rawJson:String, onWorkoutDidFinish: @escaping RCTPromiseResolveBlock, onWorkoutFailed:@escaping RCTPromiseRejectBlock){
95
95
  DispatchQueue.main.async {[weak self] in
96
-
96
+
97
97
  guard let self = self,
98
98
  let smkitUIViewController = smkitUIViewController else {
99
99
  onWorkoutFailed("StartCustomWorkout Failed", "Failed to present view", nil)
@@ -110,7 +110,7 @@ class SMKitUIManager: RCTViewManager {
110
110
  }
111
111
  }
112
112
  }
113
-
113
+
114
114
  @objc(startCustomAssessment:userData:forceShowUserDataScreen:showSummary:onWorkoutDidFinish:onWorkoutFailed:)
115
115
  func startCustomAssessment(rawJson:String, userData:NSString?, forceShowUserDataScreen:Bool, showSummary:Bool, onWorkoutDidFinish: @escaping RCTPromiseResolveBlock, onWorkoutFailed:@escaping RCTPromiseRejectBlock){
116
116
  DispatchQueue.main.async { [weak self] in
@@ -121,11 +121,11 @@ class SMKitUIManager: RCTViewManager {
121
121
  }
122
122
  self.onWorkoutDidFinish = onWorkoutDidFinish
123
123
  self.onWorkoutFailed = onWorkoutFailed
124
-
124
+
125
125
  do{
126
126
  let userData = try self.getUserData(rawJson: userData)
127
127
  let json = try stringJsonToDic(stringJSON: rawJson)
128
- let assessment = try SMWorkoutAssessmet.initFromJSON(json)
128
+ let assessment = try SMWorkoutAssessment.initFromJSON(json)
129
129
  try SMKitUIModel.startCustomAssessment(viewController: smkitUIViewController, assessment: assessment, userData:userData, forceShowUserDataScreen: forceShowUserDataScreen, showSummary: showSummary, delegate: self) { error in
130
130
  onWorkoutFailed("startCustomAssessment Failed", error.localizedDescription, error)
131
131
  }
@@ -134,19 +134,19 @@ class SMKitUIManager: RCTViewManager {
134
134
  }
135
135
  }
136
136
  }
137
-
137
+
138
138
  @objc(startWorkoutProgram:onWorkoutDidFinish:onWorkoutFailed:)
139
139
  func startWorkoutProgram(rawJson:String, onWorkoutDidFinish: @escaping RCTPromiseResolveBlock, onWorkoutFailed:@escaping RCTPromiseRejectBlock){
140
140
  self.onWorkoutDidFinish = onWorkoutDidFinish
141
141
  self.onWorkoutFailed = onWorkoutFailed
142
-
142
+
143
143
  DispatchQueue.main.async { [weak self] in
144
144
  guard let self = self,
145
145
  let smkitUIViewController = smkitUIViewController else {
146
146
  onWorkoutFailed("StartWorkoutProgram Failed", "Failed to present view", nil)
147
147
  return
148
148
  }
149
-
149
+
150
150
  guard let json = try? stringJsonToDic(stringJSON: rawJson),
151
151
  let week = json["week"] as? Int,
152
152
  let zone = json["bodyZone"] as? String,
@@ -160,7 +160,7 @@ class SMKitUIManager: RCTViewManager {
160
160
  onWorkoutFailed("StartWorkoutProgram Failed", "Invalid Workout Config", nil)
161
161
  return
162
162
  }
163
-
163
+
164
164
  let config = WorkoutConfig(
165
165
  week: week,
166
166
  bodyZone: bodyZone,
@@ -168,7 +168,7 @@ class SMKitUIManager: RCTViewManager {
168
168
  workoutDuration: workoutDuration,
169
169
  programID: programID
170
170
  )
171
-
171
+
172
172
  SMKitUIModel.startWorkoutFromProgram(viewController: smkitUIViewController, workoutConfig: config, delegate: self) { error in
173
173
  onWorkoutFailed("StartWorkoutProgram Failed", error.localizedDescription, error)
174
174
  }
@@ -180,11 +180,11 @@ class SMKitUIManager: RCTViewManager {
180
180
  else { return [:] }
181
181
  return json
182
182
  }
183
-
183
+
184
184
  override class func requiresMainQueueSetup() -> Bool {
185
185
  true
186
186
  }
187
-
187
+
188
188
  func getUserData(rawJson:NSString?) throws -> UserData?{
189
189
  guard let rawJson = rawJson as? String else { return nil }
190
190
  let json = try stringJsonToDic(stringJSON: rawJson)
@@ -193,12 +193,12 @@ class SMKitUIManager: RCTViewManager {
193
193
  birthday: getBirthdayDate(from: json["age"] as? Int ?? 0) ?? Date()
194
194
  )
195
195
  }
196
-
196
+
197
197
  func getBirthdayDate(from age: Int) -> Date? {
198
198
  // Create a date components instance to subtract years
199
199
  var dateComponents = DateComponents()
200
200
  dateComponents.year = -age
201
-
201
+
202
202
  // Use the current calendar and current date to calculate the birth date
203
203
  let calendar = Calendar.current
204
204
  if let birthDate = calendar.date(byAdding: dateComponents, to: Date()) {
@@ -206,7 +206,7 @@ class SMKitUIManager: RCTViewManager {
206
206
  }
207
207
  return nil
208
208
  }
209
-
209
+
210
210
  func reset(){
211
211
  summaryData = nil
212
212
  didReciveSummary = false
@@ -219,27 +219,27 @@ extension SMKitUIManager:SMKitUIWorkoutDelegate{
219
219
  func handleWorkoutErrors(error: any Error) {
220
220
  onWorkoutFailed?("Workout Exercise Error", error.localizedDescription, error)
221
221
  }
222
-
222
+
223
223
  func workoutDidFinish() {
224
224
  didCompleteWorkout = true
225
225
  workoutDidEnd = true
226
-
226
+
227
227
  SMKitUIModel.exitSDK()
228
228
  }
229
-
229
+
230
230
  func didExitWorkout() {
231
231
  didCompleteWorkout = false
232
232
  workoutDidEnd = true
233
-
233
+
234
234
  SMKitUIModel.exitSDK()
235
235
  }
236
-
236
+
237
237
  func sendResult(){
238
238
  guard let onWorkoutDidFinish = self.onWorkoutDidFinish else {
239
239
  onWorkoutFailed?("Unable to create summary", "Missing callback" , nil)
240
240
  return
241
241
  }
242
-
242
+
243
243
  do{
244
244
  let result:[String:Any] = [
245
245
  "summary": try summaryData?.toStringJson() ?? "",
@@ -251,11 +251,11 @@ extension SMKitUIManager:SMKitUIWorkoutDelegate{
251
251
  onWorkoutFailed?("Unable to create summary", error.localizedDescription, error as NSError)
252
252
  }
253
253
  }
254
-
254
+
255
255
  func exerciseDidFinish(data: ExerciseData) {
256
-
256
+
257
257
  }
258
-
258
+
259
259
  func didReceiveSummaryData(data: WorkoutSummaryData?) {
260
260
  summaryData = data;
261
261
  didReciveSummary = true
@@ -270,17 +270,17 @@ extension WorkoutSummaryData{
270
270
  }
271
271
  }
272
272
 
273
- extension SMWorkoutAssessmet{
274
- static func initFromJSON(_ json: [String:Any]) throws -> SMWorkoutAssessmet{
273
+ extension SMWorkoutAssessment{
274
+ static func initFromJSON(_ json: [String:Any]) throws -> SMWorkoutAssessment{
275
275
  var assessmentsExercises:[SMAssessmentExercise] = []
276
-
276
+
277
277
  if let exercise = json["exercises"] as? [[String:Any]] {
278
278
  try exercise.forEach({
279
279
  try assessmentsExercises.append(SMAssessmentExercise(FromJson: $0))
280
280
  })
281
281
  }
282
-
283
- return SMWorkoutAssessmet(
282
+
283
+ return SMWorkoutAssessment(
284
284
  id: json["id"] as? String,
285
285
  name: json["name"] as? String,
286
286
  workoutIntro: json["workoutIntro"] as? String,
@@ -1 +1 @@
1
- {"version":3,"names":["_reactNative","require","LINKING_ERROR","Platform","select","ios","default","SMKitUIManager","NativeModules","Proxy","get","Error","configure","key","startAssessment","type","showSummary","userData","forceShowUserDataScreen","customAssessmentID","toJson","startCustomWorkout","workout","startCustomAssessment","assessment","startWorkoutProgram","workoutConfig"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;;;;;;;;;AAAA,IAAAA,YAAA,GAAAC,OAAA;AAGA,MAAMC,aAAa,GAChB,gFAA+E,GAChFC,qBAAQ,CAACC,MAAM,CAAC;EAAEC,GAAG,EAAE,gCAAgC;EAAEC,OAAO,EAAE;AAAG,CAAC,CAAC,GACvE,sDAAsD,GACtD,+BAA+B;AAEjC,MAAMC,cAAc,GAAGC,0BAAa,CAACD,cAAc,GAC/CC,0BAAa,CAACD,cAAc,GAC5B,IAAIE,KAAK,CACP,CAAC,CAAC,EACF;EACEC,GAAGA,CAAA,EAAG;IACJ,MAAM,IAAIC,KAAK,CAACT,aAAa,CAAC;EAChC;AACF,CACF,CAAC;;AAEL;AACA;AACA;AACA;AACO,SAASU,SAASA,CAACC,GAAW,EAAmB;EACtD,OAAON,cAAc,CAACK,SAAS,CAACC,GAAG,CAAC;AACtC;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASC,eAAeA,CAC7BC,IAAsC,EACtCC,WAAoB,GAAG,IAAI,EAC3BC,QAA0C,EAC1CC,uBAAgC,GAAG,KAAK,EACxCC,kBAA0B,EACwB;EAClD,OAAOZ,cAAc,CAACO,eAAe,CACnCC,IAAI,EACJC,WAAW,EACXC,QAAQ,EAAEG,MAAM,CAAC,CAAC,EAClBF,uBAAuB,EACvBC,kBACF,CAAC;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACO,SAASE,kBAAkBA,CAChCC,OAAmC,EACe;EAClD,OAAOf,cAAc,CAACc,kBAAkB,CAACC,OAAO,CAACF,MAAM,CAAC,CAAC,CAAC;AAC5D;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASG,qBAAqBA,CACnCC,UAAsC,EACtCP,QAA0C,EAC1CC,uBAAgC,GAAG,KAAK,EACxCF,WAAoB,GAAG,IAAI,EACuB;EAClD,OAAOT,cAAc,CAACgB,qBAAqB,CACzCC,UAAU,CAACJ,MAAM,CAAC,CAAC,EACnBH,QAAQ,EAAEG,MAAM,CAAC,CAAC,EAClBF,uBAAuB,EACvBF,WACF,CAAC;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACO,SAASS,mBAAmBA,CACjCC,aAA6C,EACK;EAClD,OAAOnB,cAAc,CAACkB,mBAAmB,CAACC,aAAa,CAACN,MAAM,CAAC,CAAC,CAAC;AACnE","ignoreList":[]}
1
+ {"version":3,"names":["_reactNative","require","LINKING_ERROR","Platform","select","ios","default","SMKitUIManager","NativeModules","Proxy","get","Error","configure","key","startAssessment","type","showSummary","userData","forceShowUserDataScreen","customAssessmentID","toJson","startCustomWorkout","workout","startCustomAssessment","assessment","startWorkoutProgram","workoutConfig"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;;;;;;;;;AAAA,IAAAA,YAAA,GAAAC,OAAA;AAGA,MAAMC,aAAa,GACjB,gFAAgF,GAChFC,qBAAQ,CAACC,MAAM,CAAC;EAAEC,GAAG,EAAE,gCAAgC;EAAEC,OAAO,EAAE;AAAG,CAAC,CAAC,GACvE,sDAAsD,GACtD,+BAA+B;AAEjC,MAAMC,cAAc,GAAGC,0BAAa,CAACD,cAAc,GAC/CC,0BAAa,CAACD,cAAc,GAC5B,IAAIE,KAAK,CACP,CAAC,CAAC,EACF;EACEC,GAAGA,CAAA,EAAG;IACJ,MAAM,IAAIC,KAAK,CAACT,aAAa,CAAC;EAChC;AACF,CACF,CAAC;;AAEL;AACA;AACA;AACA;AACO,SAASU,SAASA,CAACC,GAAW,EAAmB;EACtD,OAAON,cAAc,CAACK,SAAS,CAACC,GAAG,CAAC;AACtC;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASC,eAAeA,CAC7BC,IAAsC,EACtCC,WAAoB,GAAG,IAAI,EAC3BC,QAA0C,EAC1CC,uBAAgC,GAAG,KAAK,EACxCC,kBAA0B,EACwB;EAClD,OAAOZ,cAAc,CAACO,eAAe,CACnCC,IAAI,EACJC,WAAW,EACXC,QAAQ,EAAEG,MAAM,CAAC,CAAC,EAClBF,uBAAuB,EACvBC,kBACF,CAAC;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACO,SAASE,kBAAkBA,CAChCC,OAAmC,EACe;EAClD,OAAOf,cAAc,CAACc,kBAAkB,CAACC,OAAO,CAACF,MAAM,CAAC,CAAC,CAAC;AAC5D;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASG,qBAAqBA,CACnCC,UAAsC,EACtCP,QAA0C,EAC1CC,uBAAgC,GAAG,KAAK,EACxCF,WAAoB,GAAG,IAAI,EACuB;EAClD,OAAOT,cAAc,CAACgB,qBAAqB,CACzCC,UAAU,CAACJ,MAAM,CAAC,CAAC,EACnBH,QAAQ,EAAEG,MAAM,CAAC,CAAC,EAClBF,uBAAuB,EACvBF,WACF,CAAC;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACO,SAASS,mBAAmBA,CACjCC,aAA6C,EACK;EAClD,OAAOnB,cAAc,CAACkB,mBAAmB,CAACC,aAAa,CAACN,MAAM,CAAC,CAAC,CAAC;AACnE","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"names":["NativeModules","Platform","LINKING_ERROR","select","ios","default","SMKitUIManager","Proxy","get","Error","configure","key","startAssessment","type","showSummary","userData","forceShowUserDataScreen","customAssessmentID","toJson","startCustomWorkout","workout","startCustomAssessment","assessment","startWorkoutProgram","workoutConfig"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":"AAAA,SAASA,aAAa,EAAEC,QAAQ,QAAQ,cAAc;AAGtD,MAAMC,aAAa,GAChB,gFAA+E,GAChFD,QAAQ,CAACE,MAAM,CAAC;EAAEC,GAAG,EAAE,gCAAgC;EAAEC,OAAO,EAAE;AAAG,CAAC,CAAC,GACvE,sDAAsD,GACtD,+BAA+B;AAEjC,MAAMC,cAAc,GAAGN,aAAa,CAACM,cAAc,GAC/CN,aAAa,CAACM,cAAc,GAC5B,IAAIC,KAAK,CACP,CAAC,CAAC,EACF;EACEC,GAAGA,CAAA,EAAG;IACJ,MAAM,IAAIC,KAAK,CAACP,aAAa,CAAC;EAChC;AACF,CACF,CAAC;;AAEL;AACA;AACA;AACA;AACA,OAAO,SAASQ,SAASA,CAACC,GAAW,EAAmB;EACtD,OAAOL,cAAc,CAACI,SAAS,CAACC,GAAG,CAAC;AACtC;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,eAAeA,CAC7BC,IAAsC,EACtCC,WAAoB,GAAG,IAAI,EAC3BC,QAA0C,EAC1CC,uBAAgC,GAAG,KAAK,EACxCC,kBAA0B,EACwB;EAClD,OAAOX,cAAc,CAACM,eAAe,CACnCC,IAAI,EACJC,WAAW,EACXC,QAAQ,EAAEG,MAAM,CAAC,CAAC,EAClBF,uBAAuB,EACvBC,kBACF,CAAC;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASE,kBAAkBA,CAChCC,OAAmC,EACe;EAClD,OAAOd,cAAc,CAACa,kBAAkB,CAACC,OAAO,CAACF,MAAM,CAAC,CAAC,CAAC;AAC5D;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASG,qBAAqBA,CACnCC,UAAsC,EACtCP,QAA0C,EAC1CC,uBAAgC,GAAG,KAAK,EACxCF,WAAoB,GAAG,IAAI,EACuB;EAClD,OAAOR,cAAc,CAACe,qBAAqB,CACzCC,UAAU,CAACJ,MAAM,CAAC,CAAC,EACnBH,QAAQ,EAAEG,MAAM,CAAC,CAAC,EAClBF,uBAAuB,EACvBF,WACF,CAAC;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASS,mBAAmBA,CACjCC,aAA6C,EACK;EAClD,OAAOlB,cAAc,CAACiB,mBAAmB,CAACC,aAAa,CAACN,MAAM,CAAC,CAAC,CAAC;AACnE","ignoreList":[]}
1
+ {"version":3,"names":["NativeModules","Platform","LINKING_ERROR","select","ios","default","SMKitUIManager","Proxy","get","Error","configure","key","startAssessment","type","showSummary","userData","forceShowUserDataScreen","customAssessmentID","toJson","startCustomWorkout","workout","startCustomAssessment","assessment","startWorkoutProgram","workoutConfig"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":"AAAA,SAASA,aAAa,EAAEC,QAAQ,QAAQ,cAAc;AAGtD,MAAMC,aAAa,GACjB,gFAAgF,GAChFD,QAAQ,CAACE,MAAM,CAAC;EAAEC,GAAG,EAAE,gCAAgC;EAAEC,OAAO,EAAE;AAAG,CAAC,CAAC,GACvE,sDAAsD,GACtD,+BAA+B;AAEjC,MAAMC,cAAc,GAAGN,aAAa,CAACM,cAAc,GAC/CN,aAAa,CAACM,cAAc,GAC5B,IAAIC,KAAK,CACP,CAAC,CAAC,EACF;EACEC,GAAGA,CAAA,EAAG;IACJ,MAAM,IAAIC,KAAK,CAACP,aAAa,CAAC;EAChC;AACF,CACF,CAAC;;AAEL;AACA;AACA;AACA;AACA,OAAO,SAASQ,SAASA,CAACC,GAAW,EAAmB;EACtD,OAAOL,cAAc,CAACI,SAAS,CAACC,GAAG,CAAC;AACtC;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,eAAeA,CAC7BC,IAAsC,EACtCC,WAAoB,GAAG,IAAI,EAC3BC,QAA0C,EAC1CC,uBAAgC,GAAG,KAAK,EACxCC,kBAA0B,EACwB;EAClD,OAAOX,cAAc,CAACM,eAAe,CACnCC,IAAI,EACJC,WAAW,EACXC,QAAQ,EAAEG,MAAM,CAAC,CAAC,EAClBF,uBAAuB,EACvBC,kBACF,CAAC;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASE,kBAAkBA,CAChCC,OAAmC,EACe;EAClD,OAAOd,cAAc,CAACa,kBAAkB,CAACC,OAAO,CAACF,MAAM,CAAC,CAAC,CAAC;AAC5D;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASG,qBAAqBA,CACnCC,UAAsC,EACtCP,QAA0C,EAC1CC,uBAAgC,GAAG,KAAK,EACxCF,WAAoB,GAAG,IAAI,EACuB;EAClD,OAAOR,cAAc,CAACe,qBAAqB,CACzCC,UAAU,CAACJ,MAAM,CAAC,CAAC,EACnBH,QAAQ,EAAEG,MAAM,CAAC,CAAC,EAClBF,uBAAuB,EACvBF,WACF,CAAC;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASS,mBAAmBA,CACjCC,aAA6C,EACK;EAClD,OAAOlB,cAAc,CAACiB,mBAAmB,CAACC,aAAa,CAACN,MAAM,CAAC,CAAC,CAAC;AACnE","ignoreList":[]}
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ declare const App: () => React.JSX.Element;
3
+ export default App;
4
+ //# sourceMappingURL=App.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../../../../example/src/App.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAuBnD,QAAA,MAAM,GAAG,yBAwYN,CAAA;AA+KH,eAAe,GAAG,CAAC"}
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+ declare const EditText: ({ placeholder, value, onChangeText, editable }: {
3
+ placeholder?: string | undefined;
4
+ value?: string | undefined;
5
+ onChangeText?: ((_text: string) => void) | undefined;
6
+ editable?: boolean | undefined;
7
+ }) => React.JSX.Element;
8
+ export default EditText;
9
+ //# sourceMappingURL=EditText.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EditText.d.ts","sourceRoot":"","sources":["../../../../../example/src/components/EditText.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,QAAA,MAAM,QAAQ;;;4BAA2D,MAAM;;uBAa9E,CAAC;AAkBF,eAAe,QAAQ,CAAC"}
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ declare const ThreeCheckboxes: ({ list, onPress }: {
3
+ list?: string[] | undefined;
4
+ onPress?: ((_index: number) => void) | undefined;
5
+ }) => React.JSX.Element;
6
+ export default ThreeCheckboxes;
7
+ //# sourceMappingURL=ThreeCheckboxes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ThreeCheckboxes.d.ts","sourceRoot":"","sources":["../../../../../example/src/components/ThreeCheckboxes.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAGxC,QAAA,MAAM,eAAe;;wBAAsC,MAAM;uBAsBhE,CAAA;AA8BD,eAAe,eAAe,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,gBAAgB,MAAM,kBAAkB,CAAC;AAmBrD;;;GAGG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAEtD;AAED;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,gBAAgB,CAAC,eAAe,EACtC,WAAW,qBAAgB,EAC3B,QAAQ,EAAE,gBAAgB,CAAC,QAAQ,GAAG,IAAI,EAC1C,uBAAuB,qBAAiB,EACxC,kBAAkB,EAAE,MAAM,GACzB,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAAC,CAQlD;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,gBAAgB,CAAC,SAAS,GAClC,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAAC,CAElD;AAED;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,gBAAgB,CAAC,SAAS,EACtC,QAAQ,EAAE,gBAAgB,CAAC,QAAQ,GAAG,IAAI,EAC1C,uBAAuB,GAAE,OAAe,EACxC,WAAW,GAAE,OAAc,GAC1B,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAAC,CAOlD;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,aAAa,EAAE,gBAAgB,CAAC,aAAa,GAC5C,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAAC,CAElD"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,gBAAgB,MAAM,kBAAkB,CAAC;AAmBrD;;;GAGG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAEtD;AAED;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,gBAAgB,CAAC,eAAe,EACtC,WAAW,EAAE,OAAO,YAAO,EAC3B,QAAQ,EAAE,gBAAgB,CAAC,QAAQ,GAAG,IAAI,EAC1C,uBAAuB,EAAE,OAAO,YAAQ,EACxC,kBAAkB,EAAE,MAAM,GACzB,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAAC,CAQlD;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,gBAAgB,CAAC,SAAS,GAClC,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAAC,CAElD;AAED;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,gBAAgB,CAAC,SAAS,EACtC,QAAQ,EAAE,gBAAgB,CAAC,QAAQ,GAAG,IAAI,EAC1C,uBAAuB,GAAE,OAAe,EACxC,WAAW,GAAE,OAAc,GAC1B,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAAC,CAOlD;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,aAAa,EAAE,gBAAgB,CAAC,aAAa,GAC5C,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAAC,CAElD"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sency/react-native-smkit-ui",
3
- "version": "0.2.4",
3
+ "version": "0.2.5",
4
4
  "description": "react-native-smkit-ui",
5
5
  "main": "lib/commonjs/index.js",
6
6
  "module": "lib/module/index.js",
@@ -151,5 +151,8 @@
151
151
  "module",
152
152
  "typescript"
153
153
  ]
154
+ },
155
+ "dependencies": {
156
+ "@react-native-clipboard/clipboard": "^1.15.0"
154
157
  }
155
158
  }
@@ -15,7 +15,7 @@ Pod::Spec.new do |s|
15
15
  s.source = { :git => "https://github.com/sency-ai/smkit-ui-react-native-demo.git", :tag => "#{s.version}" }
16
16
 
17
17
  s.source_files = "ios/**/*.{h,m,mm,swift}"
18
- s.dependency "SMKitUI" ,'0.2.7'
18
+ s.dependency "SMKitUI" ,'0.3.0'
19
19
 
20
20
  # Use install_modules_dependencies helper to install the dependencies if React Native version >=0.71.0.
21
21
  # See https://github.com/facebook/react-native/blob/febf6b7f33fdb4904669f99d795eba4c0f95d7bf/scripts/cocoapods/new_architecture.rb#L79.