@octopus-community/react-native 1.0.2 → 1.0.4

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.
@@ -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
+ }