@sency/react-native-smkit-ui 0.2.3 → 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 +105 -146
- package/android/build.gradle +4 -1
- package/android/src/main/java/com/smkituilibrary/SmkitUiLibraryModule.kt +93 -5
- package/android/src/main/java/com/smkituilibrary/mapper/SMMapper.kt +52 -5
- package/android/src/main/java/com/smkituilibrary/model/WFPSummary.kt +49 -0
- package/android/src/main/java/com/smkituilibrary/serializers/Serializers.kt +182 -0
- package/ios/SMKitUIManager.swift +265 -228
- package/lib/typescript/example/src/App.d.ts.map +1 -1
- package/lib/typescript/example/src/components/EditText.d.ts +9 -0
- package/lib/typescript/example/src/components/EditText.d.ts.map +1 -0
- package/lib/typescript/example/src/components/ThreeCheckboxes.d.ts +7 -0
- package/lib/typescript/example/src/components/ThreeCheckboxes.d.ts.map +1 -0
- package/package.json +4 -1
- package/react-native-smkit-ui.podspec +1 -1
package/README.md
CHANGED
|
@@ -1,41 +1,113 @@
|
|
|
1
|
-
# [
|
|
1
|
+
# [Github:](https://github.com/sency-ai/smkit-sdk)
|
|
2
2
|
|
|
3
3
|
1. [ Installation ](#inst)
|
|
4
4
|
2. [ Setup ](#setup)
|
|
5
|
-
3. [
|
|
6
|
-
4. [
|
|
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
|
-
|
|
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/
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
36
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
##
|
|
138
|
+
## 2. Start <a name="start"></a>
|
|
83
139
|
|
|
84
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
172
|
-
|
|
173
|
-
|
|
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
|
-
|
|
195
|
-
|
|
196
|
-
|
|
|
197
|
-
|
|
198
|
-
|
|
|
199
|
-
|
|
|
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.
|
package/android/build.gradle
CHANGED
|
@@ -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.
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
50
|
-
|
|
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
|
+
)
|