@octopus-community/react-native 1.0.0 → 1.0.3

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.
Files changed (27) hide show
  1. package/README.md +308 -3
  2. package/android/src/main/java/com/octopuscommunity/octopusreactnativesdk/OctopusReactNativeSdkModule.kt +82 -0
  3. package/android/src/main/java/com/octopuscommunity/octopusreactnativesdk/OctopusSDKInitializer.kt +149 -1
  4. package/android/src/main/java/com/octopuscommunity/octopusreactnativesdk/OctopusThemeConfig.kt +22 -0
  5. package/android/src/main/java/com/octopuscommunity/octopusreactnativesdk/OctopusThemeManager.kt +11 -0
  6. package/android/src/main/java/com/octopuscommunity/octopusreactnativesdk/OctopusUIActivity.kt +234 -38
  7. package/ios/OctopusColorUtility.swift +44 -0
  8. package/ios/OctopusReactNativeSdk.mm +8 -0
  9. package/ios/OctopusReactNativeSdk.swift +52 -28
  10. package/ios/OctopusSDKInitializer.swift +136 -6
  11. package/ios/OctopusUIManager.swift +138 -7
  12. package/lib/module/initialize.js +54 -1
  13. package/lib/module/initialize.js.map +1 -1
  14. package/lib/module/internals/colorSchemeManager.js +105 -0
  15. package/lib/module/internals/colorSchemeManager.js.map +1 -0
  16. package/lib/module/internals/fontParser.js +48 -0
  17. package/lib/module/internals/fontParser.js.map +1 -0
  18. package/lib/typescript/src/initialize.d.ts +92 -0
  19. package/lib/typescript/src/initialize.d.ts.map +1 -1
  20. package/lib/typescript/src/internals/colorSchemeManager.d.ts +39 -0
  21. package/lib/typescript/src/internals/colorSchemeManager.d.ts.map +1 -0
  22. package/lib/typescript/src/internals/fontParser.d.ts +18 -0
  23. package/lib/typescript/src/internals/fontParser.d.ts.map +1 -0
  24. package/package.json +1 -1
  25. package/src/initialize.ts +131 -1
  26. package/src/internals/colorSchemeManager.ts +113 -0
  27. package/src/internals/fontParser.ts +64 -0
@@ -1,4 +1,94 @@
1
1
  import type { UserProfileField } from './types/userProfileField';
2
+ import type { ImageResolvedAssetSource } from 'react-native';
3
+ import { type ParsedFontConfig } from './internals/fontParser';
4
+ /**
5
+ * Color set for a specific appearance mode (light or dark).
6
+ */
7
+ export interface OctopusColorSet {
8
+ /** Primary color set for branding (hex format: #FF6B35 or FF6B35) */
9
+ primary?: string;
10
+ /** Primary low contrast color (lighter variation of primary) (hex format: #FF6B35 or FF6B35) */
11
+ primaryLowContrast?: string;
12
+ /** High contrast variation of primary color (hex format: #FF6B35 or FF6B35) */
13
+ primaryHighContrast?: string;
14
+ /** Color for content displayed over the primary color (hex format: #FF6B35 or FF6B35) */
15
+ onPrimary?: string;
16
+ }
17
+ /**
18
+ * Font type options for unified cross-platform font configuration.
19
+ */
20
+ export type OctopusFontType = 'serif' | 'monospace' | 'default';
21
+ /**
22
+ * Font size configuration for different text types.
23
+ */
24
+ export interface OctopusFontSize {
25
+ /** Font size in points (will be converted to platform-specific units) */
26
+ size?: number;
27
+ }
28
+ /**
29
+ * Font configuration for a specific text type.
30
+ */
31
+ export interface OctopusTextStyle {
32
+ /** Font type: serif, monospace, or default (uses system default) */
33
+ fontType?: OctopusFontType;
34
+ /** Font size configuration */
35
+ fontSize?: OctopusFontSize;
36
+ }
37
+ /**
38
+ * Font configuration for customizing the Octopus UI typography.
39
+ */
40
+ export interface OctopusFonts {
41
+ /**
42
+ * Unified font configuration for different text types.
43
+ */
44
+ textStyles?: {
45
+ /** Configuration for title1 text */
46
+ title1?: OctopusTextStyle;
47
+ /** Configuration for title2 text */
48
+ title2?: OctopusTextStyle;
49
+ /** Configuration for body1 text */
50
+ body1?: OctopusTextStyle;
51
+ /** Configuration for body2 text */
52
+ body2?: OctopusTextStyle;
53
+ /** Configuration for caption1 text */
54
+ caption1?: OctopusTextStyle;
55
+ /** Configuration for caption2 text */
56
+ caption2?: OctopusTextStyle;
57
+ };
58
+ /**
59
+ * Pre-processed font configuration for native platforms.
60
+ * This is automatically generated and should not be set manually.
61
+ */
62
+ parsedConfig?: ParsedFontConfig | null;
63
+ }
64
+ /**
65
+ * Theme configuration for customizing the Octopus UI appearance.
66
+ *
67
+ * Supports two approaches:
68
+ * 1. Single color set (backward compatible) - colors are applied to both light and dark modes
69
+ * 2. Dual mode colors - separate color sets for light and dark modes
70
+ */
71
+ export interface OctopusTheme {
72
+ /**
73
+ * Color customization options.
74
+ *
75
+ * For backward compatibility, you can pass a single color set that will be used for both light and dark modes.
76
+ * For enhanced theming, you can pass separate color sets for light and dark modes.
77
+ */
78
+ colors?: OctopusColorSet | {
79
+ /** Colors for light mode */
80
+ light: OctopusColorSet;
81
+ /** Colors for dark mode */
82
+ dark: OctopusColorSet;
83
+ };
84
+ /** Font customization options */
85
+ fonts?: OctopusFonts;
86
+ /** Logo customization */
87
+ logo?: {
88
+ /** Local image resource - use Image.resolveAssetSource(require('./path/to/image.png')) */
89
+ image?: ImageResolvedAssetSource;
90
+ };
91
+ }
2
92
  /**
3
93
  * Configuration params for initializing the Octopus SDK.
4
94
  */
@@ -19,6 +109,8 @@ export interface InitializeParams {
19
109
  /** Octopus-managed authentication mode */
20
110
  type: 'octopus';
21
111
  };
112
+ /** Optional theme customization for the Octopus UI */
113
+ theme?: OctopusTheme;
22
114
  }
23
115
  /**
24
116
  * 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;AAEjE;;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;CACP;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAElE"}
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;CACtB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CA8BlE"}
@@ -0,0 +1,39 @@
1
+ import type { OctopusTheme } from '../initialize';
2
+ /**
3
+ * Internal color scheme manager that automatically handles appearance changes
4
+ * and updates the native modules accordingly.
5
+ */
6
+ export declare class ColorSchemeManager {
7
+ private static instance;
8
+ private appearanceSubscription;
9
+ private appStateSubscription;
10
+ private constructor();
11
+ static getInstance(): ColorSchemeManager;
12
+ /**
13
+ * Set the current theme for color scheme management
14
+ * Note: This is kept for API compatibility but theme updates are not used
15
+ * when the Octopus UI is open since the React Native app is backgrounded.
16
+ */
17
+ setTheme(_theme: OctopusTheme | null): void;
18
+ /**
19
+ * Start listening to appearance changes and automatically update native modules
20
+ */
21
+ startListening(): void;
22
+ /**
23
+ * Stop listening to appearance changes
24
+ */
25
+ stopListening(): void;
26
+ /**
27
+ * Get the current color scheme
28
+ */
29
+ getCurrentColorScheme(): string | null | undefined;
30
+ /**
31
+ * Update the native modules with the current color scheme
32
+ * Note: This is only called when the app becomes active (foreground).
33
+ * When the Octopus UI is open, the React Native app is backgrounded,
34
+ * so theme updates are not possible during UI display.
35
+ */
36
+ private updateNativeColorScheme;
37
+ }
38
+ export declare const colorSchemeManager: ColorSchemeManager;
39
+ //# sourceMappingURL=colorSchemeManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"colorSchemeManager.d.ts","sourceRoot":"","sources":["../../../../src/internals/colorSchemeManager.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAKlD;;;GAGG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAqB;IAC5C,OAAO,CAAC,sBAAsB,CAAa;IAC3C,OAAO,CAAC,oBAAoB,CAAa;IAEzC,OAAO;IAEP,MAAM,CAAC,WAAW,IAAI,kBAAkB;IAOxC;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI,GAAG,IAAI;IAK3C;;OAEG;IACH,cAAc,IAAI,IAAI;IAgCtB;;OAEG;IACH,aAAa,IAAI,IAAI;IAcrB;;OAEG;IACH,qBAAqB,IAAI,MAAM,GAAG,IAAI,GAAG,SAAS;IAIlD;;;;;OAKG;IACH,OAAO,CAAC,uBAAuB;CAShC;AAGD,eAAO,MAAM,kBAAkB,oBAAmC,CAAC"}
@@ -0,0 +1,18 @@
1
+ import type { OctopusFonts } from '../initialize';
2
+ /**
3
+ * Parsed font configuration for native platforms
4
+ */
5
+ export interface ParsedFontConfig {
6
+ textStyles: Record<string, {
7
+ fontType?: string;
8
+ fontSize?: number;
9
+ }>;
10
+ }
11
+ /**
12
+ * Parse font configuration from the theme and return a simplified structure
13
+ * that can be easily consumed by native platforms.
14
+ *
15
+ * This centralizes the font parsing logic to avoid duplication across platforms.
16
+ */
17
+ export declare function parseFontConfig(fonts?: OctopusFonts): ParsedFontConfig | null;
18
+ //# sourceMappingURL=fontParser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fontParser.d.ts","sourceRoot":"","sources":["../../../../src/internals/fontParser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAElD;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,MAAM,CAChB,MAAM,EACN;QACE,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CACF,CAAC;CACH;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,KAAK,CAAC,EAAE,YAAY,GAAG,gBAAgB,GAAG,IAAI,CA0C7E"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@octopus-community/react-native",
3
- "version": "1.0.0",
3
+ "version": "1.0.3",
4
4
  "description": "React Native module for the Octopus Community SDK",
5
5
  "source": "./src/index.ts",
6
6
  "main": "./lib/module/index.js",
package/src/initialize.ts CHANGED
@@ -1,5 +1,105 @@
1
1
  import { OctopusReactNativeSdk } from './internals/nativeModule';
2
2
  import type { UserProfileField } from './types/userProfileField';
3
+ import type { ImageResolvedAssetSource } from 'react-native';
4
+ import { Appearance } from 'react-native';
5
+ import { colorSchemeManager } from './internals/colorSchemeManager';
6
+ import { parseFontConfig, type ParsedFontConfig } from './internals/fontParser';
7
+
8
+ /**
9
+ * Color set for a specific appearance mode (light or dark).
10
+ */
11
+ export interface OctopusColorSet {
12
+ /** Primary color set for branding (hex format: #FF6B35 or FF6B35) */
13
+ primary?: string;
14
+ /** Primary low contrast color (lighter variation of primary) (hex format: #FF6B35 or FF6B35) */
15
+ primaryLowContrast?: string;
16
+ /** High contrast variation of primary color (hex format: #FF6B35 or FF6B35) */
17
+ primaryHighContrast?: string;
18
+ /** Color for content displayed over the primary color (hex format: #FF6B35 or FF6B35) */
19
+ onPrimary?: string;
20
+ }
21
+
22
+ /**
23
+ * Font type options for unified cross-platform font configuration.
24
+ */
25
+ export type OctopusFontType = 'serif' | 'monospace' | 'default';
26
+
27
+ /**
28
+ * Font size configuration for different text types.
29
+ */
30
+ export interface OctopusFontSize {
31
+ /** Font size in points (will be converted to platform-specific units) */
32
+ size?: number;
33
+ }
34
+
35
+ /**
36
+ * Font configuration for a specific text type.
37
+ */
38
+ export interface OctopusTextStyle {
39
+ /** Font type: serif, monospace, or default (uses system default) */
40
+ fontType?: OctopusFontType;
41
+ /** Font size configuration */
42
+ fontSize?: OctopusFontSize;
43
+ }
44
+
45
+ /**
46
+ * Font configuration for customizing the Octopus UI typography.
47
+ */
48
+ export interface OctopusFonts {
49
+ /**
50
+ * Unified font configuration for different text types.
51
+ */
52
+ textStyles?: {
53
+ /** Configuration for title1 text */
54
+ title1?: OctopusTextStyle;
55
+ /** Configuration for title2 text */
56
+ title2?: OctopusTextStyle;
57
+ /** Configuration for body1 text */
58
+ body1?: OctopusTextStyle;
59
+ /** Configuration for body2 text */
60
+ body2?: OctopusTextStyle;
61
+ /** Configuration for caption1 text */
62
+ caption1?: OctopusTextStyle;
63
+ /** Configuration for caption2 text */
64
+ caption2?: OctopusTextStyle;
65
+ };
66
+ /**
67
+ * Pre-processed font configuration for native platforms.
68
+ * This is automatically generated and should not be set manually.
69
+ */
70
+ parsedConfig?: ParsedFontConfig | null;
71
+ }
72
+
73
+ /**
74
+ * Theme configuration for customizing the Octopus UI appearance.
75
+ *
76
+ * Supports two approaches:
77
+ * 1. Single color set (backward compatible) - colors are applied to both light and dark modes
78
+ * 2. Dual mode colors - separate color sets for light and dark modes
79
+ */
80
+ export interface OctopusTheme {
81
+ /**
82
+ * Color customization options.
83
+ *
84
+ * For backward compatibility, you can pass a single color set that will be used for both light and dark modes.
85
+ * For enhanced theming, you can pass separate color sets for light and dark modes.
86
+ */
87
+ colors?:
88
+ | OctopusColorSet
89
+ | {
90
+ /** Colors for light mode */
91
+ light: OctopusColorSet;
92
+ /** Colors for dark mode */
93
+ dark: OctopusColorSet;
94
+ };
95
+ /** Font customization options */
96
+ fonts?: OctopusFonts;
97
+ /** Logo customization */
98
+ logo?: {
99
+ /** Local image resource - use Image.resolveAssetSource(require('./path/to/image.png')) */
100
+ image?: ImageResolvedAssetSource;
101
+ };
102
+ }
3
103
 
4
104
  /**
5
105
  * Configuration params for initializing the Octopus SDK.
@@ -23,6 +123,8 @@ export interface InitializeParams {
23
123
  /** Octopus-managed authentication mode */
24
124
  type: 'octopus';
25
125
  };
126
+ /** Optional theme customization for the Octopus UI */
127
+ theme?: OctopusTheme;
26
128
  }
27
129
 
28
130
  /**
@@ -52,5 +154,33 @@ export interface InitializeParams {
52
154
  * ```
53
155
  */
54
156
  export function initialize(params: InitializeParams): Promise<void> {
55
- return OctopusReactNativeSdk.initialize(params);
157
+ // Automatically detect the current color scheme and add it to the params
158
+ const colorScheme = Appearance.getColorScheme();
159
+
160
+ // Pre-process font configuration to avoid duplication in native layers
161
+ const processedTheme = params.theme
162
+ ? {
163
+ ...params.theme,
164
+ fonts: params.theme.fonts
165
+ ? {
166
+ ...params.theme.fonts,
167
+ parsedConfig: parseFontConfig(params.theme.fonts),
168
+ }
169
+ : undefined,
170
+ }
171
+ : undefined;
172
+
173
+ const paramsWithColorScheme = {
174
+ ...params,
175
+ theme: processedTheme,
176
+ colorScheme: colorScheme || undefined,
177
+ };
178
+
179
+ // Set the theme in the color scheme manager for dual-mode support
180
+ colorSchemeManager.setTheme(processedTheme || null);
181
+
182
+ // Start listening to color scheme changes for automatic updates
183
+ colorSchemeManager.startListening();
184
+
185
+ return OctopusReactNativeSdk.initialize(paramsWithColorScheme);
56
186
  }
@@ -0,0 +1,113 @@
1
+ import { Appearance, AppState } from 'react-native';
2
+ import { OctopusReactNativeSdk } from './nativeModule';
3
+ import type { OctopusTheme } from '../initialize';
4
+
5
+ let isListening = false;
6
+ let currentColorScheme: string | null | undefined = null;
7
+
8
+ /**
9
+ * Internal color scheme manager that automatically handles appearance changes
10
+ * and updates the native modules accordingly.
11
+ */
12
+ export class ColorSchemeManager {
13
+ private static instance: ColorSchemeManager;
14
+ private appearanceSubscription: any = null;
15
+ private appStateSubscription: any = null;
16
+
17
+ private constructor() {}
18
+
19
+ static getInstance(): ColorSchemeManager {
20
+ if (!ColorSchemeManager.instance) {
21
+ ColorSchemeManager.instance = new ColorSchemeManager();
22
+ }
23
+ return ColorSchemeManager.instance;
24
+ }
25
+
26
+ /**
27
+ * Set the current theme for color scheme management
28
+ * Note: This is kept for API compatibility but theme updates are not used
29
+ * when the Octopus UI is open since the React Native app is backgrounded.
30
+ */
31
+ setTheme(_theme: OctopusTheme | null): void {
32
+ // Theme is set during initialization and applied when UI opens
33
+ // No need to store it here since updates can't happen while UI is open
34
+ }
35
+
36
+ /**
37
+ * Start listening to appearance changes and automatically update native modules
38
+ */
39
+ startListening(): void {
40
+ if (isListening) {
41
+ return;
42
+ }
43
+
44
+ isListening = true;
45
+ currentColorScheme = Appearance.getColorScheme();
46
+
47
+ // Listen to appearance changes
48
+ this.appearanceSubscription = Appearance.addChangeListener(
49
+ ({ colorScheme }) => {
50
+ currentColorScheme = colorScheme;
51
+ this.updateNativeColorScheme();
52
+ }
53
+ );
54
+
55
+ // Listen to app state changes to ensure we have the latest color scheme
56
+ this.appStateSubscription = AppState.addEventListener(
57
+ 'change',
58
+ (nextAppState) => {
59
+ // Only check color scheme when app becomes active (foreground)
60
+ if (nextAppState === 'active') {
61
+ const newColorScheme = Appearance.getColorScheme();
62
+ if (newColorScheme !== currentColorScheme) {
63
+ currentColorScheme = newColorScheme;
64
+ this.updateNativeColorScheme();
65
+ }
66
+ }
67
+ }
68
+ );
69
+ }
70
+
71
+ /**
72
+ * Stop listening to appearance changes
73
+ */
74
+ stopListening(): void {
75
+ if (this.appearanceSubscription) {
76
+ this.appearanceSubscription.remove();
77
+ this.appearanceSubscription = null;
78
+ }
79
+
80
+ if (this.appStateSubscription) {
81
+ this.appStateSubscription.remove();
82
+ this.appStateSubscription = null;
83
+ }
84
+
85
+ isListening = false;
86
+ }
87
+
88
+ /**
89
+ * Get the current color scheme
90
+ */
91
+ getCurrentColorScheme(): string | null | undefined {
92
+ return currentColorScheme;
93
+ }
94
+
95
+ /**
96
+ * Update the native modules with the current color scheme
97
+ * Note: This is only called when the app becomes active (foreground).
98
+ * When the Octopus UI is open, the React Native app is backgrounded,
99
+ * so theme updates are not possible during UI display.
100
+ */
101
+ private updateNativeColorScheme(): void {
102
+ // Both platforms handle theme updates when the app becomes active
103
+ // iOS uses adaptive colors, Android applies the theme when UI reopens
104
+ try {
105
+ OctopusReactNativeSdk.updateColorScheme(currentColorScheme || undefined);
106
+ } catch (error) {
107
+ this.stopListening();
108
+ }
109
+ }
110
+ }
111
+
112
+ // Export singleton instance
113
+ export const colorSchemeManager = ColorSchemeManager.getInstance();
@@ -0,0 +1,64 @@
1
+ import type { OctopusFonts } from '../initialize';
2
+
3
+ /**
4
+ * Parsed font configuration for native platforms
5
+ */
6
+ export interface ParsedFontConfig {
7
+ textStyles: Record<
8
+ string,
9
+ {
10
+ fontType?: string;
11
+ fontSize?: number;
12
+ }
13
+ >;
14
+ }
15
+
16
+ /**
17
+ * Parse font configuration from the theme and return a simplified structure
18
+ * that can be easily consumed by native platforms.
19
+ *
20
+ * This centralizes the font parsing logic to avoid duplication across platforms.
21
+ */
22
+ export function parseFontConfig(fonts?: OctopusFonts): ParsedFontConfig | null {
23
+ if (!fonts?.textStyles) {
24
+ return null;
25
+ }
26
+
27
+ const textStyles: Record<string, { fontType?: string; fontSize?: number }> =
28
+ {};
29
+
30
+ // Define the text style keys that are supported
31
+ const supportedTextStyles = [
32
+ 'title1',
33
+ 'title2',
34
+ 'body1',
35
+ 'body2',
36
+ 'caption1',
37
+ 'caption2',
38
+ ];
39
+
40
+ for (const key of supportedTextStyles) {
41
+ const textStyle = fonts.textStyles[key as keyof typeof fonts.textStyles];
42
+ if (textStyle) {
43
+ const parsedStyle: { fontType?: string; fontSize?: number } = {};
44
+
45
+ // Parse font type
46
+ if (textStyle.fontType) {
47
+ parsedStyle.fontType = textStyle.fontType;
48
+ }
49
+
50
+ // Parse font size
51
+ if (textStyle.fontSize?.size) {
52
+ parsedStyle.fontSize = textStyle.fontSize.size;
53
+ }
54
+
55
+ // Only include the style if it has at least one property
56
+ if (parsedStyle.fontType || parsedStyle.fontSize) {
57
+ textStyles[key] = parsedStyle;
58
+ }
59
+ }
60
+ }
61
+
62
+ // Return null if no text styles were parsed
63
+ return Object.keys(textStyles).length > 0 ? { textStyles } : null;
64
+ }