@octopus-community/react-native 1.0.6 → 1.0.7
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 +4 -4
- package/android/src/main/java/com/octopuscommunity/octopusreactnativesdk/OctopusReactNativeSdkModule.kt +11 -11
- package/android/src/main/java/com/octopuscommunity/octopusreactnativesdk/OctopusSDKInitializer.kt +21 -21
- package/android/src/main/java/com/octopuscommunity/octopusreactnativesdk/OctopusSSOAuthenticator.kt +20 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -115,7 +115,7 @@ await initialize({
|
|
|
115
115
|
onPrimary: '#FFFFFF', // Text color on primary background
|
|
116
116
|
},
|
|
117
117
|
logo: {
|
|
118
|
-
image: Image.resolveAssetSource(require('./assets/logo.png')), // Your custom logo
|
|
118
|
+
image: Image.resolveAssetSource(require('./assets/images/logo.png')), // Your custom logo
|
|
119
119
|
},
|
|
120
120
|
}
|
|
121
121
|
});
|
|
@@ -186,7 +186,7 @@ await initialize({
|
|
|
186
186
|
onPrimary: '#FFFFFF', // Text color on primary background
|
|
187
187
|
},
|
|
188
188
|
logo: {
|
|
189
|
-
image: Image.resolveAssetSource(require('./assets/logo.png')),
|
|
189
|
+
image: Image.resolveAssetSource(require('./assets/images/logo.png')),
|
|
190
190
|
},
|
|
191
191
|
}
|
|
192
192
|
});
|
|
@@ -351,7 +351,7 @@ await initialize({
|
|
|
351
351
|
},
|
|
352
352
|
// Custom logo
|
|
353
353
|
logo: {
|
|
354
|
-
image: Image.resolveAssetSource(require('./assets/logo.png')),
|
|
354
|
+
image: Image.resolveAssetSource(require('./assets/images/logo.png')),
|
|
355
355
|
},
|
|
356
356
|
}
|
|
357
357
|
});
|
|
@@ -408,7 +408,7 @@ const switchToGreenTheme = async () => {
|
|
|
408
408
|
- `caption1`: Small captions (default: 12pt)
|
|
409
409
|
- `caption2`: Extra small captions (default: 10pt)
|
|
410
410
|
|
|
411
|
-
|
|
411
|
+
|
|
412
412
|
|
|
413
413
|
**Supported Formats:**
|
|
414
414
|
- **Colors**: 3-digit (`#F63`), 6-digit (`#FF6633`), 8-digit (`#FF6633FF`) hex codes
|
|
@@ -12,7 +12,7 @@ class OctopusReactNativeSdkModule(reactContext: ReactApplicationContext) :
|
|
|
12
12
|
private val sdkInitializer = OctopusSDKInitializer()
|
|
13
13
|
private val eventEmitter = OctopusEventEmitter(reactContext)
|
|
14
14
|
private val uiController = OctopusUIController(reactContext)
|
|
15
|
-
private val ssoAuthenticator = OctopusSSOAuthenticator(eventEmitter)
|
|
15
|
+
private val ssoAuthenticator = OctopusSSOAuthenticator(reactContext, eventEmitter)
|
|
16
16
|
|
|
17
17
|
override fun getName(): String = NAME
|
|
18
18
|
|
|
@@ -85,10 +85,10 @@ class OctopusReactNativeSdkModule(reactContext: ReactApplicationContext) :
|
|
|
85
85
|
promise.reject("UPDATE_THEME_ERROR", "Failed to update theme", e)
|
|
86
86
|
}
|
|
87
87
|
}
|
|
88
|
-
|
|
88
|
+
|
|
89
89
|
private fun parseColor(colorString: String?): String? {
|
|
90
90
|
if (colorString == null) return null
|
|
91
|
-
|
|
91
|
+
|
|
92
92
|
return try {
|
|
93
93
|
// Validate that the color string is a valid hex color
|
|
94
94
|
android.graphics.Color.parseColor(colorString)
|
|
@@ -99,31 +99,31 @@ class OctopusReactNativeSdkModule(reactContext: ReactApplicationContext) :
|
|
|
99
99
|
null
|
|
100
100
|
}
|
|
101
101
|
}
|
|
102
|
-
|
|
102
|
+
|
|
103
103
|
private fun parseFontsConfig(fontsMap: ReadableMap): OctopusFontsConfig? {
|
|
104
104
|
// Use pre-processed configuration from TypeScript layer
|
|
105
105
|
val parsedConfig = fontsMap.getMap("parsedConfig")
|
|
106
106
|
if (parsedConfig != null) {
|
|
107
107
|
return parsePreProcessedFontsConfig(parsedConfig)
|
|
108
108
|
}
|
|
109
|
-
|
|
109
|
+
|
|
110
110
|
return null
|
|
111
111
|
}
|
|
112
|
-
|
|
112
|
+
|
|
113
113
|
private fun parsePreProcessedFontsConfig(parsedConfig: ReadableMap): OctopusFontsConfig? {
|
|
114
114
|
val textStylesMap = parsedConfig.getMap("textStyles")
|
|
115
115
|
val textStyles = mutableMapOf<String, OctopusTextStyleConfig>()
|
|
116
|
-
|
|
116
|
+
|
|
117
117
|
// Parse pre-processed font configuration from TypeScript layer
|
|
118
118
|
textStylesMap?.let { textStylesMap ->
|
|
119
119
|
val textStyleKeys = arrayOf("title1", "title2", "body1", "body2", "caption1", "caption2")
|
|
120
|
-
|
|
120
|
+
|
|
121
121
|
textStyleKeys.forEach { key ->
|
|
122
122
|
val textStyleMap = textStylesMap.getMap(key)
|
|
123
123
|
textStyleMap?.let { style ->
|
|
124
124
|
val fontType = style.getString("fontType")
|
|
125
125
|
val fontSize = if (style.hasKey("fontSize")) style.getDouble("fontSize") else Double.NaN
|
|
126
|
-
|
|
126
|
+
|
|
127
127
|
if (fontType != null || (!fontSize.isNaN() && fontSize > 0)) {
|
|
128
128
|
textStyles[key] = OctopusTextStyleConfig(
|
|
129
129
|
fontType = fontType,
|
|
@@ -133,14 +133,14 @@ class OctopusReactNativeSdkModule(reactContext: ReactApplicationContext) :
|
|
|
133
133
|
}
|
|
134
134
|
}
|
|
135
135
|
}
|
|
136
|
-
|
|
136
|
+
|
|
137
137
|
// Only create fonts config if we have text styles
|
|
138
138
|
if (textStyles.isNotEmpty()) {
|
|
139
139
|
return OctopusFontsConfig(
|
|
140
140
|
textStyles = textStyles
|
|
141
141
|
)
|
|
142
142
|
}
|
|
143
|
-
|
|
143
|
+
|
|
144
144
|
return null
|
|
145
145
|
}
|
|
146
146
|
|
package/android/src/main/java/com/octopuscommunity/octopusreactnativesdk/OctopusSDKInitializer.kt
CHANGED
|
@@ -18,11 +18,11 @@ class OctopusSDKInitializer {
|
|
|
18
18
|
|
|
19
19
|
try {
|
|
20
20
|
val connectionMode = parseConnectionMode(options)
|
|
21
|
-
|
|
21
|
+
|
|
22
22
|
// Store theme configuration for later use in UI
|
|
23
23
|
val themeConfig = parseThemeConfig(options)
|
|
24
24
|
OctopusThemeManager.setThemeConfig(themeConfig)
|
|
25
|
-
|
|
25
|
+
|
|
26
26
|
OctopusSDK.initialize(
|
|
27
27
|
context = context,
|
|
28
28
|
apiKey = apiKey,
|
|
@@ -35,19 +35,19 @@ class OctopusSDKInitializer {
|
|
|
35
35
|
promise.reject("INITIALIZE_ERROR", "Failed to initialize Octopus SDK", e)
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
|
-
|
|
38
|
+
|
|
39
39
|
fun parseThemeConfig(options: ReadableMap): OctopusThemeConfig? {
|
|
40
|
-
|
|
40
|
+
|
|
41
41
|
val themeMap = options.getMap("theme")
|
|
42
42
|
val colorScheme = options.getString("colorScheme") // Get colorScheme from React Native
|
|
43
|
-
|
|
43
|
+
|
|
44
44
|
var primaryColor: String? = null
|
|
45
45
|
var primaryLowContrastColor: String? = null
|
|
46
46
|
var primaryHighContrastColor: String? = null
|
|
47
47
|
var onPrimaryColor: String? = null
|
|
48
48
|
var logoSource: ReadableMap? = null
|
|
49
49
|
var fontsConfig: OctopusFontsConfig? = null
|
|
50
|
-
|
|
50
|
+
|
|
51
51
|
// Parse colors from theme if available
|
|
52
52
|
themeMap?.let { theme ->
|
|
53
53
|
val colorsMap = theme.getMap("colors")
|
|
@@ -55,7 +55,7 @@ class OctopusSDKInitializer {
|
|
|
55
55
|
// Check if this is a dual-mode theme (has light and dark properties)
|
|
56
56
|
val lightColors = colors.getMap("light")
|
|
57
57
|
val darkColors = colors.getMap("dark")
|
|
58
|
-
|
|
58
|
+
|
|
59
59
|
if (lightColors != null && darkColors != null) {
|
|
60
60
|
// Dual-mode theme - select colors based on current color scheme
|
|
61
61
|
val selectedColors = if (colorScheme == "dark") darkColors else lightColors
|
|
@@ -71,7 +71,7 @@ class OctopusSDKInitializer {
|
|
|
71
71
|
onPrimaryColor = parseColor(if (colors.hasKey("onPrimary")) colors.getString("onPrimary") else null)
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
|
-
|
|
74
|
+
|
|
75
75
|
// Handle logo from theme
|
|
76
76
|
val logoMap = theme.getMap("logo")
|
|
77
77
|
logoMap?.let { logo ->
|
|
@@ -80,7 +80,7 @@ class OctopusSDKInitializer {
|
|
|
80
80
|
logoSource = imageSource
|
|
81
81
|
}
|
|
82
82
|
}
|
|
83
|
-
|
|
83
|
+
|
|
84
84
|
// Handle fonts from theme - use pre-processed configuration from TypeScript layer
|
|
85
85
|
val fontsMap = theme.getMap("fonts")
|
|
86
86
|
fontsMap?.let { fonts ->
|
|
@@ -90,7 +90,7 @@ class OctopusSDKInitializer {
|
|
|
90
90
|
}
|
|
91
91
|
}
|
|
92
92
|
}
|
|
93
|
-
|
|
93
|
+
|
|
94
94
|
// Handle logo at root level (for backward compatibility)
|
|
95
95
|
if (logoSource == null) {
|
|
96
96
|
val rootLogoMap = options.getMap("logo")
|
|
@@ -101,7 +101,7 @@ class OctopusSDKInitializer {
|
|
|
101
101
|
}
|
|
102
102
|
}
|
|
103
103
|
}
|
|
104
|
-
|
|
104
|
+
|
|
105
105
|
// Only create theme config if we have at least one customization
|
|
106
106
|
if (primaryColor != null || logoSource != null || colorScheme != null || fontsConfig != null) {
|
|
107
107
|
return OctopusThemeConfig(
|
|
@@ -114,24 +114,24 @@ class OctopusSDKInitializer {
|
|
|
114
114
|
fonts = fontsConfig
|
|
115
115
|
)
|
|
116
116
|
}
|
|
117
|
-
|
|
117
|
+
|
|
118
118
|
return null
|
|
119
119
|
}
|
|
120
|
-
|
|
120
|
+
|
|
121
121
|
private fun parsePreProcessedFontsConfig(parsedConfig: ReadableMap): OctopusFontsConfig? {
|
|
122
122
|
val textStylesMap = parsedConfig.getMap("textStyles")
|
|
123
123
|
val textStyles = mutableMapOf<String, OctopusTextStyleConfig>()
|
|
124
|
-
|
|
124
|
+
|
|
125
125
|
// Parse pre-processed font configuration from TypeScript layer
|
|
126
126
|
textStylesMap?.let { textStylesMap ->
|
|
127
127
|
val textStyleKeys = arrayOf("title1", "title2", "body1", "body2", "caption1", "caption2")
|
|
128
|
-
|
|
128
|
+
|
|
129
129
|
textStyleKeys.forEach { key ->
|
|
130
130
|
val textStyleMap = textStylesMap.getMap(key)
|
|
131
131
|
textStyleMap?.let { style ->
|
|
132
132
|
val fontType = style.getString("fontType")
|
|
133
133
|
val fontSize = if (style.hasKey("fontSize")) style.getDouble("fontSize") else Double.NaN
|
|
134
|
-
|
|
134
|
+
|
|
135
135
|
if (fontType != null || (!fontSize.isNaN() && fontSize > 0)) {
|
|
136
136
|
textStyles[key] = OctopusTextStyleConfig(
|
|
137
137
|
fontType = fontType,
|
|
@@ -141,18 +141,18 @@ class OctopusSDKInitializer {
|
|
|
141
141
|
}
|
|
142
142
|
}
|
|
143
143
|
}
|
|
144
|
-
|
|
144
|
+
|
|
145
145
|
// Only create fonts config if we have text styles
|
|
146
146
|
if (textStyles.isNotEmpty()) {
|
|
147
147
|
return OctopusFontsConfig(
|
|
148
148
|
textStyles = textStyles
|
|
149
149
|
)
|
|
150
150
|
}
|
|
151
|
-
|
|
151
|
+
|
|
152
152
|
return null
|
|
153
153
|
}
|
|
154
154
|
|
|
155
|
-
|
|
155
|
+
|
|
156
156
|
private fun extractResourceNameFromUri(uri: String): String? {
|
|
157
157
|
// Extract resource name from React Native image URI
|
|
158
158
|
// Examples: "logo.png" -> "logo", "images/logo.png" -> "logo"
|
|
@@ -163,10 +163,10 @@ class OctopusSDKInitializer {
|
|
|
163
163
|
null
|
|
164
164
|
}
|
|
165
165
|
}
|
|
166
|
-
|
|
166
|
+
|
|
167
167
|
private fun parseColor(colorString: String?): String? {
|
|
168
168
|
if (colorString == null) return null
|
|
169
|
-
|
|
169
|
+
|
|
170
170
|
return try {
|
|
171
171
|
// Validate that the color string is a valid hex color
|
|
172
172
|
Color.parseColor(colorString)
|
package/android/src/main/java/com/octopuscommunity/octopusreactnativesdk/OctopusSSOAuthenticator.kt
CHANGED
|
@@ -15,8 +15,13 @@ import java.util.UUID
|
|
|
15
15
|
import java.util.concurrent.ConcurrentHashMap
|
|
16
16
|
import kotlin.coroutines.resume
|
|
17
17
|
import kotlin.coroutines.resumeWithException
|
|
18
|
+
import android.content.Context
|
|
18
19
|
|
|
19
|
-
|
|
20
|
+
|
|
21
|
+
class OctopusSSOAuthenticator(
|
|
22
|
+
private val context: Context,
|
|
23
|
+
private val eventEmitter: OctopusEventEmitter
|
|
24
|
+
) {
|
|
20
25
|
|
|
21
26
|
private val coroutineScope = CoroutineScope(Dispatchers.Main)
|
|
22
27
|
private val pendingTokenRequests =
|
|
@@ -107,10 +112,22 @@ class OctopusSSOAuthenticator(private val eventEmitter: OctopusEventEmitter) {
|
|
|
107
112
|
} else null
|
|
108
113
|
|
|
109
114
|
val profilePicture = profileParams.getString("profilePicture")?.let { pictureUrl ->
|
|
110
|
-
if (pictureUrl.
|
|
115
|
+
if (pictureUrl.startsWith("http://") || pictureUrl.startsWith("https://")) {
|
|
111
116
|
Image.Remote(pictureUrl)
|
|
112
|
-
} else if (pictureUrl.
|
|
117
|
+
} else if (pictureUrl.startsWith("file") || pictureUrl.startsWith("android.resource")) {
|
|
113
118
|
Image.Local(pictureUrl)
|
|
119
|
+
} else if(pictureUrl.isNotBlank()) {
|
|
120
|
+
// Asset names like "assets_images_logo" need conversion
|
|
121
|
+
// Convert to drawable resource URI
|
|
122
|
+
val resourceId = context.resources.getIdentifier(pictureUrl, "drawable", context.packageName)
|
|
123
|
+
Image.Local(
|
|
124
|
+
if (resourceId != 0) {
|
|
125
|
+
"android.resource://${context.packageName}/$resourceId"
|
|
126
|
+
} else {
|
|
127
|
+
// Fallback: try assets folder
|
|
128
|
+
"file:///android_asset/$pictureUrl"
|
|
129
|
+
}
|
|
130
|
+
)
|
|
114
131
|
} else {
|
|
115
132
|
null
|
|
116
133
|
}
|