@octopus-community/react-native 1.0.6 → 1.0.8
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 +52 -21
- package/android/src/main/java/com/octopuscommunity/octopusreactnativesdk/OctopusSSOAuthenticator.kt +20 -3
- package/android/src/main/java/com/octopuscommunity/octopusreactnativesdk/OctopusUIActivity.kt +31 -19
- package/android/src/main/java/com/octopuscommunity/octopusreactnativesdk/OctopusUIConfiguration.kt +6 -0
- package/android/src/main/java/com/octopuscommunity/octopusreactnativesdk/OctopusUIConfigurationManager.kt +12 -0
- package/ios/OctopusReactNativeSdk.swift +9 -1
- package/ios/OctopusSDKInitializer.swift +32 -0
- package/ios/OctopusUIConfiguration.swift +6 -0
- package/ios/OctopusUIManager.swift +51 -10
- package/lib/module/initialize.js +4 -0
- package/lib/module/initialize.js.map +1 -1
- package/lib/typescript/src/initialize.d.ts +13 -0
- package/lib/typescript/src/initialize.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/initialize.ts +14 -0
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,15 @@ 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
|
+
// Store UI configuration separately
|
|
27
|
+
val uiConfiguration = parseUIConfiguration(options)
|
|
28
|
+
OctopusUIConfigurationManager.setUIConfiguration(uiConfiguration)
|
|
29
|
+
|
|
26
30
|
OctopusSDK.initialize(
|
|
27
31
|
context = context,
|
|
28
32
|
apiKey = apiKey,
|
|
@@ -35,19 +39,19 @@ class OctopusSDKInitializer {
|
|
|
35
39
|
promise.reject("INITIALIZE_ERROR", "Failed to initialize Octopus SDK", e)
|
|
36
40
|
}
|
|
37
41
|
}
|
|
38
|
-
|
|
42
|
+
|
|
39
43
|
fun parseThemeConfig(options: ReadableMap): OctopusThemeConfig? {
|
|
40
|
-
|
|
44
|
+
|
|
41
45
|
val themeMap = options.getMap("theme")
|
|
42
46
|
val colorScheme = options.getString("colorScheme") // Get colorScheme from React Native
|
|
43
|
-
|
|
47
|
+
|
|
44
48
|
var primaryColor: String? = null
|
|
45
49
|
var primaryLowContrastColor: String? = null
|
|
46
50
|
var primaryHighContrastColor: String? = null
|
|
47
51
|
var onPrimaryColor: String? = null
|
|
48
52
|
var logoSource: ReadableMap? = null
|
|
49
53
|
var fontsConfig: OctopusFontsConfig? = null
|
|
50
|
-
|
|
54
|
+
|
|
51
55
|
// Parse colors from theme if available
|
|
52
56
|
themeMap?.let { theme ->
|
|
53
57
|
val colorsMap = theme.getMap("colors")
|
|
@@ -55,7 +59,7 @@ class OctopusSDKInitializer {
|
|
|
55
59
|
// Check if this is a dual-mode theme (has light and dark properties)
|
|
56
60
|
val lightColors = colors.getMap("light")
|
|
57
61
|
val darkColors = colors.getMap("dark")
|
|
58
|
-
|
|
62
|
+
|
|
59
63
|
if (lightColors != null && darkColors != null) {
|
|
60
64
|
// Dual-mode theme - select colors based on current color scheme
|
|
61
65
|
val selectedColors = if (colorScheme == "dark") darkColors else lightColors
|
|
@@ -71,7 +75,7 @@ class OctopusSDKInitializer {
|
|
|
71
75
|
onPrimaryColor = parseColor(if (colors.hasKey("onPrimary")) colors.getString("onPrimary") else null)
|
|
72
76
|
}
|
|
73
77
|
}
|
|
74
|
-
|
|
78
|
+
|
|
75
79
|
// Handle logo from theme
|
|
76
80
|
val logoMap = theme.getMap("logo")
|
|
77
81
|
logoMap?.let { logo ->
|
|
@@ -80,7 +84,7 @@ class OctopusSDKInitializer {
|
|
|
80
84
|
logoSource = imageSource
|
|
81
85
|
}
|
|
82
86
|
}
|
|
83
|
-
|
|
87
|
+
|
|
84
88
|
// Handle fonts from theme - use pre-processed configuration from TypeScript layer
|
|
85
89
|
val fontsMap = theme.getMap("fonts")
|
|
86
90
|
fontsMap?.let { fonts ->
|
|
@@ -90,7 +94,7 @@ class OctopusSDKInitializer {
|
|
|
90
94
|
}
|
|
91
95
|
}
|
|
92
96
|
}
|
|
93
|
-
|
|
97
|
+
|
|
94
98
|
// Handle logo at root level (for backward compatibility)
|
|
95
99
|
if (logoSource == null) {
|
|
96
100
|
val rootLogoMap = options.getMap("logo")
|
|
@@ -101,7 +105,7 @@ class OctopusSDKInitializer {
|
|
|
101
105
|
}
|
|
102
106
|
}
|
|
103
107
|
}
|
|
104
|
-
|
|
108
|
+
|
|
105
109
|
// Only create theme config if we have at least one customization
|
|
106
110
|
if (primaryColor != null || logoSource != null || colorScheme != null || fontsConfig != null) {
|
|
107
111
|
return OctopusThemeConfig(
|
|
@@ -114,24 +118,51 @@ class OctopusSDKInitializer {
|
|
|
114
118
|
fonts = fontsConfig
|
|
115
119
|
)
|
|
116
120
|
}
|
|
117
|
-
|
|
121
|
+
|
|
118
122
|
return null
|
|
119
123
|
}
|
|
120
|
-
|
|
124
|
+
|
|
125
|
+
fun parseUIConfiguration(options: ReadableMap): OctopusUIConfiguration? {
|
|
126
|
+
val uiMap = options.getMap("ui")
|
|
127
|
+
var bottomContentPadding: Double? = null
|
|
128
|
+
|
|
129
|
+
uiMap?.let { uiOptions ->
|
|
130
|
+
val candidateKeys = listOf("bottomSafeAreaInset", "bottomPadding", "contentPadding", "contentPaddingBottom")
|
|
131
|
+
for (key in candidateKeys) {
|
|
132
|
+
if (uiOptions.hasKey(key)) {
|
|
133
|
+
bottomContentPadding = try {
|
|
134
|
+
uiOptions.getDouble(key).coerceAtLeast(0.0)
|
|
135
|
+
} catch (e: Exception) {
|
|
136
|
+
null
|
|
137
|
+
}
|
|
138
|
+
if (bottomContentPadding != null) {
|
|
139
|
+
break
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
return if (bottomContentPadding != null) {
|
|
146
|
+
OctopusUIConfiguration(bottomContentPadding = bottomContentPadding)
|
|
147
|
+
} else {
|
|
148
|
+
null
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
121
152
|
private fun parsePreProcessedFontsConfig(parsedConfig: ReadableMap): OctopusFontsConfig? {
|
|
122
153
|
val textStylesMap = parsedConfig.getMap("textStyles")
|
|
123
154
|
val textStyles = mutableMapOf<String, OctopusTextStyleConfig>()
|
|
124
|
-
|
|
155
|
+
|
|
125
156
|
// Parse pre-processed font configuration from TypeScript layer
|
|
126
157
|
textStylesMap?.let { textStylesMap ->
|
|
127
158
|
val textStyleKeys = arrayOf("title1", "title2", "body1", "body2", "caption1", "caption2")
|
|
128
|
-
|
|
159
|
+
|
|
129
160
|
textStyleKeys.forEach { key ->
|
|
130
161
|
val textStyleMap = textStylesMap.getMap(key)
|
|
131
162
|
textStyleMap?.let { style ->
|
|
132
163
|
val fontType = style.getString("fontType")
|
|
133
164
|
val fontSize = if (style.hasKey("fontSize")) style.getDouble("fontSize") else Double.NaN
|
|
134
|
-
|
|
165
|
+
|
|
135
166
|
if (fontType != null || (!fontSize.isNaN() && fontSize > 0)) {
|
|
136
167
|
textStyles[key] = OctopusTextStyleConfig(
|
|
137
168
|
fontType = fontType,
|
|
@@ -141,18 +172,18 @@ class OctopusSDKInitializer {
|
|
|
141
172
|
}
|
|
142
173
|
}
|
|
143
174
|
}
|
|
144
|
-
|
|
175
|
+
|
|
145
176
|
// Only create fonts config if we have text styles
|
|
146
177
|
if (textStyles.isNotEmpty()) {
|
|
147
178
|
return OctopusFontsConfig(
|
|
148
179
|
textStyles = textStyles
|
|
149
180
|
)
|
|
150
181
|
}
|
|
151
|
-
|
|
182
|
+
|
|
152
183
|
return null
|
|
153
184
|
}
|
|
154
185
|
|
|
155
|
-
|
|
186
|
+
|
|
156
187
|
private fun extractResourceNameFromUri(uri: String): String? {
|
|
157
188
|
// Extract resource name from React Native image URI
|
|
158
189
|
// Examples: "logo.png" -> "logo", "images/logo.png" -> "logo"
|
|
@@ -163,10 +194,10 @@ class OctopusSDKInitializer {
|
|
|
163
194
|
null
|
|
164
195
|
}
|
|
165
196
|
}
|
|
166
|
-
|
|
197
|
+
|
|
167
198
|
private fun parseColor(colorString: String?): String? {
|
|
168
199
|
if (colorString == null) return null
|
|
169
|
-
|
|
200
|
+
|
|
170
201
|
return try {
|
|
171
202
|
// Validate that the color string is a valid hex color
|
|
172
203
|
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
|
}
|
package/android/src/main/java/com/octopuscommunity/octopusreactnativesdk/OctopusUIActivity.kt
CHANGED
|
@@ -12,7 +12,9 @@ import android.util.Log
|
|
|
12
12
|
import androidx.activity.ComponentActivity
|
|
13
13
|
import androidx.activity.compose.setContent
|
|
14
14
|
import androidx.compose.foundation.layout.Box
|
|
15
|
+
import androidx.compose.foundation.layout.PaddingValues
|
|
15
16
|
import androidx.compose.foundation.layout.fillMaxSize
|
|
17
|
+
import androidx.compose.foundation.layout.padding
|
|
16
18
|
import androidx.compose.runtime.Composable
|
|
17
19
|
import androidx.compose.runtime.LaunchedEffect
|
|
18
20
|
import androidx.compose.runtime.getValue
|
|
@@ -20,6 +22,7 @@ import androidx.compose.runtime.mutableStateOf
|
|
|
20
22
|
import androidx.compose.runtime.remember
|
|
21
23
|
import androidx.compose.runtime.setValue
|
|
22
24
|
import androidx.compose.ui.Modifier
|
|
25
|
+
import androidx.compose.ui.unit.Dp
|
|
23
26
|
import androidx.compose.ui.graphics.Color
|
|
24
27
|
import androidx.compose.ui.graphics.asImageBitmap
|
|
25
28
|
import androidx.compose.ui.graphics.painter.BitmapPainter
|
|
@@ -32,11 +35,13 @@ import com.octopuscommunity.sdk.ui.OctopusDrawablesDefaults
|
|
|
32
35
|
import com.octopuscommunity.sdk.ui.OctopusTheme
|
|
33
36
|
import com.octopuscommunity.sdk.ui.OctopusTypographyDefaults
|
|
34
37
|
import com.octopuscommunity.sdk.ui.OctopusTypography
|
|
38
|
+
import com.octopuscommunity.sdk.ui.home.OctopusHomeDefaults
|
|
35
39
|
import com.octopuscommunity.sdk.ui.components.OctopusNavigationHandler
|
|
36
40
|
import androidx.compose.ui.text.TextStyle
|
|
37
41
|
import androidx.compose.ui.text.font.FontFamily
|
|
38
42
|
import androidx.compose.ui.text.font.FontWeight
|
|
39
43
|
import androidx.compose.ui.unit.sp
|
|
44
|
+
import androidx.compose.ui.unit.dp
|
|
40
45
|
import com.octopuscommunity.sdk.ui.home.OctopusHomeScreen
|
|
41
46
|
import com.octopuscommunity.sdk.ui.octopusComposables
|
|
42
47
|
import com.octopuscommunity.sdk.ui.octopusDarkColorScheme
|
|
@@ -151,14 +156,18 @@ private fun OctopusUI(onBack: () -> Unit) {
|
|
|
151
156
|
|
|
152
157
|
// Create typography based on theme config
|
|
153
158
|
val typography = createCustomTypography(themeConfig)
|
|
159
|
+
val uiConfiguration = OctopusUIConfigurationManager.getUIConfiguration()
|
|
154
160
|
|
|
155
|
-
// Apply theme with custom colors, logo, and
|
|
161
|
+
// Apply theme with custom colors, logo, typography, and content padding
|
|
156
162
|
OctopusTheme(
|
|
157
163
|
colorScheme = finalColorScheme,
|
|
158
164
|
drawables = drawables,
|
|
159
165
|
typography = typography
|
|
160
166
|
) {
|
|
161
|
-
OctopusUIContent(
|
|
167
|
+
OctopusUIContent(
|
|
168
|
+
bottomContentPadding = uiConfiguration?.bottomContentPadding?.toFloat()?.dp,
|
|
169
|
+
onBack = onBack
|
|
170
|
+
)
|
|
162
171
|
}
|
|
163
172
|
}
|
|
164
173
|
|
|
@@ -213,7 +222,7 @@ private fun createTextStyle(textStyleConfig: OctopusTextStyleConfig?, defaultSty
|
|
|
213
222
|
|
|
214
223
|
|
|
215
224
|
@Composable
|
|
216
|
-
private fun OctopusUIContent(onBack: () -> Unit) {
|
|
225
|
+
private fun OctopusUIContent(bottomContentPadding: Dp?, onBack: () -> Unit) {
|
|
217
226
|
Box(modifier = Modifier.fillMaxSize()) {
|
|
218
227
|
val navController = rememberNavController()
|
|
219
228
|
|
|
@@ -222,23 +231,26 @@ private fun OctopusUIContent(onBack: () -> Unit) {
|
|
|
222
231
|
startDestination = "OctopusHome"
|
|
223
232
|
) {
|
|
224
233
|
composable(route = "OctopusHome") {
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
}
|
|
235
|
-
) {
|
|
236
|
-
OctopusHomeScreen(
|
|
237
|
-
navController = navController,
|
|
238
|
-
backIcon = true,
|
|
239
|
-
onBack = onBack
|
|
240
|
-
)
|
|
234
|
+
OctopusNavigationHandler(
|
|
235
|
+
navigateToLogin = {
|
|
236
|
+
OctopusEventEmitter.instance?.emitLoginRequired()
|
|
237
|
+
},
|
|
238
|
+
navigateToProfileEdit = { fieldToEdit ->
|
|
239
|
+
OctopusEventEmitter.instance?.emitEditUser(fieldToEdit)
|
|
240
|
+
},
|
|
241
|
+
navigateToClientObject = {
|
|
242
|
+
// TODO : Bridge Post react
|
|
241
243
|
}
|
|
244
|
+
) {
|
|
245
|
+
OctopusHomeScreen(
|
|
246
|
+
navController = navController,
|
|
247
|
+
backIcon = true,
|
|
248
|
+
floatingActionsPadding = OctopusHomeDefaults.floatingActionsPadding(
|
|
249
|
+
bottom = bottomContentPadding ?: 16.dp
|
|
250
|
+
),
|
|
251
|
+
onBack = onBack
|
|
252
|
+
)
|
|
253
|
+
}
|
|
242
254
|
}
|
|
243
255
|
octopusComposables(
|
|
244
256
|
navController = navController,
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
package com.octopuscommunity.octopusreactnativesdk
|
|
2
|
+
|
|
3
|
+
object OctopusUIConfigurationManager {
|
|
4
|
+
private var uiConfiguration: OctopusUIConfiguration? = null
|
|
5
|
+
|
|
6
|
+
fun setUIConfiguration(config: OctopusUIConfiguration?) {
|
|
7
|
+
uiConfiguration = config
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
fun getUIConfiguration(): OctopusUIConfiguration? = uiConfiguration
|
|
11
|
+
}
|
|
12
|
+
|
|
@@ -17,6 +17,7 @@ class OctopusReactNativeSdk: NSObject, RCTBridgeModule {
|
|
|
17
17
|
private var theme: OctopusTheme?
|
|
18
18
|
private var logoSource: [String: Any]?
|
|
19
19
|
private var fontConfiguration: [String: Any]?
|
|
20
|
+
private var uiConfiguration: OctopusUIConfiguration?
|
|
20
21
|
|
|
21
22
|
// MARK: - RCTBridgeModule
|
|
22
23
|
|
|
@@ -40,6 +41,7 @@ class OctopusReactNativeSdk: NSObject, RCTBridgeModule {
|
|
|
40
41
|
self.theme = sdkInitializer.parseTheme(from: options)
|
|
41
42
|
self.logoSource = sdkInitializer.getLogoSource(from: options)
|
|
42
43
|
self.fontConfiguration = sdkInitializer.getFontConfiguration(from: options)
|
|
44
|
+
self.uiConfiguration = sdkInitializer.parseUIConfiguration(from: options)
|
|
43
45
|
resolve(nil)
|
|
44
46
|
} catch {
|
|
45
47
|
reject("INITIALIZE_ERROR", "Failed to initialize Octopus SDK: \(error.localizedDescription)", error)
|
|
@@ -115,7 +117,13 @@ class OctopusReactNativeSdk: NSObject, RCTBridgeModule {
|
|
|
115
117
|
|
|
116
118
|
DispatchQueue.main.async {
|
|
117
119
|
do {
|
|
118
|
-
try self.uiManager.openUI(
|
|
120
|
+
try self.uiManager.openUI(
|
|
121
|
+
octopus: octopus,
|
|
122
|
+
theme: self.theme,
|
|
123
|
+
logoSource: self.logoSource,
|
|
124
|
+
fontConfiguration: self.fontConfiguration,
|
|
125
|
+
uiConfiguration: self.uiConfiguration
|
|
126
|
+
)
|
|
119
127
|
resolve(nil)
|
|
120
128
|
} catch {
|
|
121
129
|
reject("OPEN_UI_ERROR", error.localizedDescription, error)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import Octopus
|
|
2
2
|
import OctopusUI
|
|
3
3
|
import SwiftUI
|
|
4
|
+
import CoreGraphics
|
|
4
5
|
|
|
5
6
|
class OctopusSDKInitializer {
|
|
6
7
|
func initialize(options: [String: Any], eventManager: OctopusEventManager) throws -> OctopusSDK {
|
|
@@ -144,6 +145,37 @@ class OctopusSDKInitializer {
|
|
|
144
145
|
return nil
|
|
145
146
|
}
|
|
146
147
|
|
|
148
|
+
func parseUIConfiguration(from options: [String: Any]) -> OctopusUIConfiguration? {
|
|
149
|
+
guard let uiOptions = options["ui"] as? [String: Any] else {
|
|
150
|
+
return nil
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
let supportedKeys = [
|
|
154
|
+
"bottomSafeAreaInset",
|
|
155
|
+
"bottomPadding",
|
|
156
|
+
"contentPadding",
|
|
157
|
+
"contentPaddingBottom",
|
|
158
|
+
]
|
|
159
|
+
|
|
160
|
+
var bottomInset: CGFloat?
|
|
161
|
+
|
|
162
|
+
for key in supportedKeys {
|
|
163
|
+
if let value = uiOptions[key] as? NSNumber {
|
|
164
|
+
bottomInset = CGFloat(truncating: value)
|
|
165
|
+
break
|
|
166
|
+
} else if let value = uiOptions[key] as? Double {
|
|
167
|
+
bottomInset = CGFloat(value)
|
|
168
|
+
break
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
guard let finalInset = bottomInset else {
|
|
173
|
+
return nil
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
return OctopusUIConfiguration(bottomSafeAreaInset: max(0, finalInset))
|
|
177
|
+
}
|
|
178
|
+
|
|
147
179
|
private func parseConnectionMode(from connectionModeMap: [String: Any], eventManager: OctopusEventManager) throws -> ConnectionMode {
|
|
148
180
|
let connectionModeType = connectionModeMap["type"] as? String
|
|
149
181
|
|
|
@@ -7,24 +7,35 @@ import React
|
|
|
7
7
|
class OctopusUIManager {
|
|
8
8
|
private weak var presentedViewController: UIViewController?
|
|
9
9
|
|
|
10
|
-
func openUI(
|
|
10
|
+
func openUI(
|
|
11
|
+
octopus: OctopusSDK,
|
|
12
|
+
theme: OctopusUI.OctopusTheme?,
|
|
13
|
+
logoSource: [String: Any]?,
|
|
14
|
+
fontConfiguration: [String: Any]?,
|
|
15
|
+
uiConfiguration: OctopusUIConfiguration?
|
|
16
|
+
) throws {
|
|
11
17
|
guard let presentingViewController = RCTPresentedViewController() else {
|
|
12
18
|
throw NSError(domain: "OPEN_UI_ERROR", code: 0, userInfo: [NSLocalizedDescriptionKey: "Could not find presenting view controller"])
|
|
13
19
|
}
|
|
14
20
|
|
|
15
21
|
// Create custom theme with font configuration
|
|
16
22
|
let customTheme = createCustomTheme(baseTheme: theme, fontConfiguration: fontConfiguration)
|
|
17
|
-
|
|
18
|
-
let
|
|
19
|
-
.environment(\.octopusTheme, customTheme)
|
|
20
|
-
|
|
21
|
-
let hostingController = UIHostingController(rootView: AnyView(octopusHomeScreen))
|
|
22
|
-
hostingController.modalPresentationStyle = .fullScreen
|
|
23
|
+
let bottomSafeAreaInset = uiConfiguration?.bottomSafeAreaInset
|
|
24
|
+
let initialTheme = (theme != nil || fontConfiguration != nil) ? customTheme : nil
|
|
23
25
|
|
|
26
|
+
let hostingController = UIHostingController(
|
|
27
|
+
rootView: makeHomeScreenView(octopus: octopus, theme: initialTheme, bottomSafeAreaInset: bottomSafeAreaInset)
|
|
28
|
+
)
|
|
29
|
+
hostingController.modalPresentationStyle = .fullScreen
|
|
30
|
+
|
|
24
31
|
// Apply theme if provided
|
|
25
32
|
if let _ = theme {
|
|
26
33
|
// Apply theme immediately (without logo) to avoid delay
|
|
27
|
-
hostingController.rootView =
|
|
34
|
+
hostingController.rootView = makeHomeScreenView(
|
|
35
|
+
octopus: octopus,
|
|
36
|
+
theme: customTheme,
|
|
37
|
+
bottomSafeAreaInset: bottomSafeAreaInset
|
|
38
|
+
)
|
|
28
39
|
|
|
29
40
|
// Then load logo asynchronously and update theme if logo loads
|
|
30
41
|
if let logoSource = logoSource {
|
|
@@ -36,7 +47,11 @@ class OctopusUIManager {
|
|
|
36
47
|
fonts: customTheme.fonts,
|
|
37
48
|
assets: OctopusUI.OctopusTheme.Assets(logo: logoImage)
|
|
38
49
|
)
|
|
39
|
-
hostingController?.rootView =
|
|
50
|
+
hostingController?.rootView = self.makeHomeScreenView(
|
|
51
|
+
octopus: octopus,
|
|
52
|
+
theme: updatedTheme,
|
|
53
|
+
bottomSafeAreaInset: bottomSafeAreaInset
|
|
54
|
+
)
|
|
40
55
|
} else {
|
|
41
56
|
// Theme is already applied, no need to do anything
|
|
42
57
|
}
|
|
@@ -53,7 +68,11 @@ class OctopusUIManager {
|
|
|
53
68
|
fonts: OctopusUI.OctopusTheme.Fonts(),
|
|
54
69
|
assets: OctopusUI.OctopusTheme.Assets(logo: logoImage)
|
|
55
70
|
)
|
|
56
|
-
hostingController?.rootView =
|
|
71
|
+
hostingController?.rootView = self.makeHomeScreenView(
|
|
72
|
+
octopus: octopus,
|
|
73
|
+
theme: logoTheme,
|
|
74
|
+
bottomSafeAreaInset: bottomSafeAreaInset
|
|
75
|
+
)
|
|
57
76
|
}
|
|
58
77
|
}
|
|
59
78
|
}
|
|
@@ -142,6 +161,28 @@ class OctopusUIManager {
|
|
|
142
161
|
presentedViewController = nil
|
|
143
162
|
}
|
|
144
163
|
}
|
|
164
|
+
|
|
165
|
+
private func makeHomeScreenView(octopus: OctopusSDK, theme: OctopusUI.OctopusTheme?, bottomSafeAreaInset: CGFloat?) -> AnyView {
|
|
166
|
+
if let inset = bottomSafeAreaInset {
|
|
167
|
+
if let theme = theme {
|
|
168
|
+
return AnyView(
|
|
169
|
+
OctopusHomeScreen(octopus: octopus, bottomSafeAreaInset: inset)
|
|
170
|
+
.environment(\.octopusTheme, theme)
|
|
171
|
+
)
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return AnyView(OctopusHomeScreen(octopus: octopus, bottomSafeAreaInset: inset))
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
if let theme = theme {
|
|
178
|
+
return AnyView(
|
|
179
|
+
OctopusHomeScreen(octopus: octopus)
|
|
180
|
+
.environment(\.octopusTheme, theme)
|
|
181
|
+
)
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
return AnyView(OctopusHomeScreen(octopus: octopus))
|
|
185
|
+
}
|
|
145
186
|
|
|
146
187
|
private func createCustomTheme(baseTheme: OctopusUI.OctopusTheme?, fontConfiguration: [String: Any]?) -> OctopusUI.OctopusTheme {
|
|
147
188
|
// If no font configuration, return the base theme or default
|
package/lib/module/initialize.js
CHANGED
|
@@ -33,6 +33,10 @@ import { parseFontConfig } from "./internals/fontParser.js";
|
|
|
33
33
|
* 2. Dual mode colors - separate color sets for light and dark modes
|
|
34
34
|
*/
|
|
35
35
|
|
|
36
|
+
/**
|
|
37
|
+
* UI customization options for platform-specific layout adjustments.
|
|
38
|
+
*/
|
|
39
|
+
|
|
36
40
|
/**
|
|
37
41
|
* Configuration params for initializing the Octopus SDK.
|
|
38
42
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["OctopusReactNativeSdk","Appearance","colorSchemeManager","parseFontConfig","initialize","params","colorScheme","getColorScheme","processedTheme","theme","fonts","parsedConfig","undefined","paramsWithColorScheme","setTheme","startListening"],"sourceRoot":"../../src","sources":["initialize.ts"],"mappings":";;AAAA,SAASA,qBAAqB,QAAQ,6BAA0B;AAGhE,SAASC,UAAU,QAAQ,cAAc;AACzC,SAASC,kBAAkB,QAAQ,mCAAgC;AACnE,SAASC,eAAe,QAA+B,2BAAwB;;AAE/E;AACA;AACA;;AAYA;AACA;AACA;;AAGA;AACA;AACA;;AAMA;AACA;AACA;;AAQA;AACA;AACA;;AA0BA;AACA;AACA;AACA;AACA;AACA;AACA;;AAyBA;AACA;AACA;;
|
|
1
|
+
{"version":3,"names":["OctopusReactNativeSdk","Appearance","colorSchemeManager","parseFontConfig","initialize","params","colorScheme","getColorScheme","processedTheme","theme","fonts","parsedConfig","undefined","paramsWithColorScheme","setTheme","startListening"],"sourceRoot":"../../src","sources":["initialize.ts"],"mappings":";;AAAA,SAASA,qBAAqB,QAAQ,6BAA0B;AAGhE,SAASC,UAAU,QAAQ,cAAc;AACzC,SAASC,kBAAkB,QAAQ,mCAAgC;AACnE,SAASC,eAAe,QAA+B,2BAAwB;;AAE/E;AACA;AACA;;AAYA;AACA;AACA;;AAGA;AACA;AACA;;AAMA;AACA;AACA;;AAQA;AACA;AACA;;AA0BA;AACA;AACA;AACA;AACA;AACA;AACA;;AAyBA;AACA;AACA;;AAUA;AACA;AACA;;AA0BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,UAAUA,CAACC,MAAwB,EAAiB;EAClE;EACA,MAAMC,WAAW,GAAGL,UAAU,CAACM,cAAc,CAAC,CAAC;;EAE/C;EACA,MAAMC,cAAc,GAAGH,MAAM,CAACI,KAAK,GAC/B;IACE,GAAGJ,MAAM,CAACI,KAAK;IACfC,KAAK,EAAEL,MAAM,CAACI,KAAK,CAACC,KAAK,GACrB;MACE,GAAGL,MAAM,CAACI,KAAK,CAACC,KAAK;MACrBC,YAAY,EAAER,eAAe,CAACE,MAAM,CAACI,KAAK,CAACC,KAAK;IAClD,CAAC,GACDE;EACN,CAAC,GACDA,SAAS;EAEb,MAAMC,qBAAqB,GAAG;IAC5B,GAAGR,MAAM;IACTI,KAAK,EAAED,cAAc;IACrBF,WAAW,EAAEA,WAAW,IAAIM;EAC9B,CAAC;;EAED;EACAV,kBAAkB,CAACY,QAAQ,CAACN,cAAc,IAAI,IAAI,CAAC;;EAEnD;EACAN,kBAAkB,CAACa,cAAc,CAAC,CAAC;EAEnC,OAAOf,qBAAqB,CAACI,UAAU,CAACS,qBAAqB,CAAC;AAChE","ignoreList":[]}
|
|
@@ -89,6 +89,17 @@ export interface OctopusTheme {
|
|
|
89
89
|
image?: ImageResolvedAssetSource;
|
|
90
90
|
};
|
|
91
91
|
}
|
|
92
|
+
/**
|
|
93
|
+
* UI customization options for platform-specific layout adjustments.
|
|
94
|
+
*/
|
|
95
|
+
export interface OctopusUIOptions {
|
|
96
|
+
/**
|
|
97
|
+
* Additional bottom inset applied to the Octopus UI.
|
|
98
|
+
* - On iOS, mapped to `bottomSafeAreaInset` (points)
|
|
99
|
+
* - On Android, mapped to `contentPadding` bottom (dp)
|
|
100
|
+
*/
|
|
101
|
+
bottomSafeAreaInset?: number;
|
|
102
|
+
}
|
|
92
103
|
/**
|
|
93
104
|
* Configuration params for initializing the Octopus SDK.
|
|
94
105
|
*/
|
|
@@ -111,6 +122,8 @@ export interface InitializeParams {
|
|
|
111
122
|
};
|
|
112
123
|
/** Optional theme customization for the Octopus UI */
|
|
113
124
|
theme?: OctopusTheme;
|
|
125
|
+
/** Optional UI customization for layout-related tweaks */
|
|
126
|
+
ui?: OctopusUIOptions;
|
|
114
127
|
}
|
|
115
128
|
/**
|
|
116
129
|
* Initializes the Octopus SDK with the provided configuration.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"initialize.d.ts","sourceRoot":"","sources":["../../../src/initialize.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AAG7D,OAAO,EAAmB,KAAK,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAEhF;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,qEAAqE;IACrE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gGAAgG;IAChG,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,+EAA+E;IAC/E,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,yFAAyF;IACzF,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,WAAW,GAAG,SAAS,CAAC;AAEhE;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,yEAAyE;IACzE,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,oEAAoE;IACpE,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B,8BAA8B;IAC9B,QAAQ,CAAC,EAAE,eAAe,CAAC;CAC5B;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B;;OAEG;IACH,UAAU,CAAC,EAAE;QACX,oCAAoC;QACpC,MAAM,CAAC,EAAE,gBAAgB,CAAC;QAC1B,oCAAoC;QACpC,MAAM,CAAC,EAAE,gBAAgB,CAAC;QAC1B,mCAAmC;QACnC,KAAK,CAAC,EAAE,gBAAgB,CAAC;QACzB,mCAAmC;QACnC,KAAK,CAAC,EAAE,gBAAgB,CAAC;QACzB,sCAAsC;QACtC,QAAQ,CAAC,EAAE,gBAAgB,CAAC;QAC5B,sCAAsC;QACtC,QAAQ,CAAC,EAAE,gBAAgB,CAAC;KAC7B,CAAC;IACF;;;OAGG;IACH,YAAY,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAC;CACxC;AAED;;;;;;GAMG;AACH,MAAM,WAAW,YAAY;IAC3B;;;;;OAKG;IACH,MAAM,CAAC,EACH,eAAe,GACf;QACE,4BAA4B;QAC5B,KAAK,EAAE,eAAe,CAAC;QACvB,2BAA2B;QAC3B,IAAI,EAAE,eAAe,CAAC;KACvB,CAAC;IACN,iCAAiC;IACjC,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB,yBAAyB;IACzB,IAAI,CAAC,EAAE;QACL,0FAA0F;QAC1F,KAAK,CAAC,EAAE,wBAAwB,CAAC;KAClC,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,+DAA+D;IAC/D,MAAM,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,cAAc,EACV;QACE,6BAA6B;QAC7B,IAAI,EAAE,KAAK,CAAC;QACZ,iEAAiE;QACjE,gBAAgB,EAAE,gBAAgB,EAAE,CAAC;KACtC,GACD;QACE,0CAA0C;QAC1C,IAAI,EAAE,SAAS,CAAC;KACjB,CAAC;IACN,sDAAsD;IACtD,KAAK,CAAC,EAAE,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"initialize.d.ts","sourceRoot":"","sources":["../../../src/initialize.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AAG7D,OAAO,EAAmB,KAAK,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAEhF;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,qEAAqE;IACrE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gGAAgG;IAChG,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,+EAA+E;IAC/E,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,yFAAyF;IACzF,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,WAAW,GAAG,SAAS,CAAC;AAEhE;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,yEAAyE;IACzE,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,oEAAoE;IACpE,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B,8BAA8B;IAC9B,QAAQ,CAAC,EAAE,eAAe,CAAC;CAC5B;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B;;OAEG;IACH,UAAU,CAAC,EAAE;QACX,oCAAoC;QACpC,MAAM,CAAC,EAAE,gBAAgB,CAAC;QAC1B,oCAAoC;QACpC,MAAM,CAAC,EAAE,gBAAgB,CAAC;QAC1B,mCAAmC;QACnC,KAAK,CAAC,EAAE,gBAAgB,CAAC;QACzB,mCAAmC;QACnC,KAAK,CAAC,EAAE,gBAAgB,CAAC;QACzB,sCAAsC;QACtC,QAAQ,CAAC,EAAE,gBAAgB,CAAC;QAC5B,sCAAsC;QACtC,QAAQ,CAAC,EAAE,gBAAgB,CAAC;KAC7B,CAAC;IACF;;;OAGG;IACH,YAAY,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAC;CACxC;AAED;;;;;;GAMG;AACH,MAAM,WAAW,YAAY;IAC3B;;;;;OAKG;IACH,MAAM,CAAC,EACH,eAAe,GACf;QACE,4BAA4B;QAC5B,KAAK,EAAE,eAAe,CAAC;QACvB,2BAA2B;QAC3B,IAAI,EAAE,eAAe,CAAC;KACvB,CAAC;IACN,iCAAiC;IACjC,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB,yBAAyB;IACzB,IAAI,CAAC,EAAE;QACL,0FAA0F;QAC1F,KAAK,CAAC,EAAE,wBAAwB,CAAC;KAClC,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,+DAA+D;IAC/D,MAAM,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,cAAc,EACV;QACE,6BAA6B;QAC7B,IAAI,EAAE,KAAK,CAAC;QACZ,iEAAiE;QACjE,gBAAgB,EAAE,gBAAgB,EAAE,CAAC;KACtC,GACD;QACE,0CAA0C;QAC1C,IAAI,EAAE,SAAS,CAAC;KACjB,CAAC;IACN,sDAAsD;IACtD,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB,0DAA0D;IAC1D,EAAE,CAAC,EAAE,gBAAgB,CAAC;CACvB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CA8BlE"}
|
package/package.json
CHANGED
package/src/initialize.ts
CHANGED
|
@@ -101,6 +101,18 @@ export interface OctopusTheme {
|
|
|
101
101
|
};
|
|
102
102
|
}
|
|
103
103
|
|
|
104
|
+
/**
|
|
105
|
+
* UI customization options for platform-specific layout adjustments.
|
|
106
|
+
*/
|
|
107
|
+
export interface OctopusUIOptions {
|
|
108
|
+
/**
|
|
109
|
+
* Additional bottom inset applied to the Octopus UI.
|
|
110
|
+
* - On iOS, mapped to `bottomSafeAreaInset` (points)
|
|
111
|
+
* - On Android, mapped to `contentPadding` bottom (dp)
|
|
112
|
+
*/
|
|
113
|
+
bottomSafeAreaInset?: number;
|
|
114
|
+
}
|
|
115
|
+
|
|
104
116
|
/**
|
|
105
117
|
* Configuration params for initializing the Octopus SDK.
|
|
106
118
|
*/
|
|
@@ -125,6 +137,8 @@ export interface InitializeParams {
|
|
|
125
137
|
};
|
|
126
138
|
/** Optional theme customization for the Octopus UI */
|
|
127
139
|
theme?: OctopusTheme;
|
|
140
|
+
/** Optional UI customization for layout-related tweaks */
|
|
141
|
+
ui?: OctopusUIOptions;
|
|
128
142
|
}
|
|
129
143
|
|
|
130
144
|
/**
|