@oxyhq/services 5.21.5 → 5.21.6

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 (49) hide show
  1. package/lib/commonjs/ui/components/BottomSheetRouter.js +100 -286
  2. package/lib/commonjs/ui/components/BottomSheetRouter.js.map +1 -1
  3. package/lib/commonjs/ui/components/GroupedItem.js +0 -3
  4. package/lib/commonjs/ui/components/GroupedItem.js.map +1 -1
  5. package/lib/commonjs/ui/components/OxyProvider.js +14 -19
  6. package/lib/commonjs/ui/components/OxyProvider.js.map +1 -1
  7. package/lib/commonjs/ui/navigation/bottomSheetManager.js +43 -145
  8. package/lib/commonjs/ui/navigation/bottomSheetManager.js.map +1 -1
  9. package/lib/commonjs/ui/screens/AccountSettingsScreen.js +0 -2
  10. package/lib/commonjs/ui/screens/AccountSettingsScreen.js.map +1 -1
  11. package/lib/module/ui/components/BottomSheetRouter.js +102 -284
  12. package/lib/module/ui/components/BottomSheetRouter.js.map +1 -1
  13. package/lib/module/ui/components/GroupedItem.js +0 -3
  14. package/lib/module/ui/components/GroupedItem.js.map +1 -1
  15. package/lib/module/ui/components/OxyProvider.js +14 -19
  16. package/lib/module/ui/components/OxyProvider.js.map +1 -1
  17. package/lib/module/ui/navigation/bottomSheetManager.js +37 -135
  18. package/lib/module/ui/navigation/bottomSheetManager.js.map +1 -1
  19. package/lib/module/ui/screens/AccountSettingsScreen.js +0 -2
  20. package/lib/module/ui/screens/AccountSettingsScreen.js.map +1 -1
  21. package/lib/typescript/commonjs/ui/components/BottomSheetRouter.d.ts +2 -7
  22. package/lib/typescript/commonjs/ui/components/BottomSheetRouter.d.ts.map +1 -1
  23. package/lib/typescript/commonjs/ui/components/GroupedItem.d.ts.map +1 -1
  24. package/lib/typescript/commonjs/ui/components/OxyProvider.d.ts.map +1 -1
  25. package/lib/typescript/commonjs/ui/navigation/bottomSheetManager.d.ts +11 -60
  26. package/lib/typescript/commonjs/ui/navigation/bottomSheetManager.d.ts.map +1 -1
  27. package/lib/typescript/commonjs/ui/screens/AccountSettingsScreen.d.ts.map +1 -1
  28. package/lib/typescript/module/ui/components/BottomSheetRouter.d.ts +2 -7
  29. package/lib/typescript/module/ui/components/BottomSheetRouter.d.ts.map +1 -1
  30. package/lib/typescript/module/ui/components/GroupedItem.d.ts.map +1 -1
  31. package/lib/typescript/module/ui/components/OxyProvider.d.ts.map +1 -1
  32. package/lib/typescript/module/ui/navigation/bottomSheetManager.d.ts +11 -60
  33. package/lib/typescript/module/ui/navigation/bottomSheetManager.d.ts.map +1 -1
  34. package/lib/typescript/module/ui/screens/AccountSettingsScreen.d.ts.map +1 -1
  35. package/package.json +2 -2
  36. package/src/ui/components/BottomSheetRouter.tsx +97 -319
  37. package/src/ui/components/GroupedItem.tsx +0 -4
  38. package/src/ui/components/OxyProvider.tsx +13 -18
  39. package/src/ui/navigation/bottomSheetManager.ts +43 -150
  40. package/src/ui/screens/AccountSettingsScreen.tsx +0 -2
  41. package/lib/commonjs/ui/hooks/use-haptic-press.js +0 -21
  42. package/lib/commonjs/ui/hooks/use-haptic-press.js.map +0 -1
  43. package/lib/module/ui/hooks/use-haptic-press.js +0 -17
  44. package/lib/module/ui/hooks/use-haptic-press.js.map +0 -1
  45. package/lib/typescript/commonjs/ui/hooks/use-haptic-press.d.ts +0 -8
  46. package/lib/typescript/commonjs/ui/hooks/use-haptic-press.d.ts.map +0 -1
  47. package/lib/typescript/module/ui/hooks/use-haptic-press.d.ts +0 -8
  48. package/lib/typescript/module/ui/hooks/use-haptic-press.d.ts.map +0 -1
  49. package/src/ui/hooks/use-haptic-press.ts +0 -15
@@ -16,20 +16,26 @@ setupFonts();
16
16
  // Detect if running on web
17
17
  const isWeb = Platform.OS === 'web';
18
18
 
19
- // Conditionally import native-only components
19
+ // Conditionally import components
20
20
  let KeyboardProvider: any = ({ children }: any) => children;
21
- let BottomSheetRouter: any = () => null;
21
+ let BottomSheetRouter: any = null;
22
22
 
23
+ // KeyboardProvider only on native
23
24
  if (!isWeb) {
24
25
  try {
25
- // Only import on native platforms
26
26
  KeyboardProvider = require('react-native-keyboard-controller').KeyboardProvider;
27
- BottomSheetRouter = require('./BottomSheetRouter').default;
28
27
  } catch {
29
- // Fallback if imports fail
28
+ // KeyboardProvider not available
30
29
  }
31
30
  }
32
31
 
32
+ // BottomSheetRouter works on all platforms
33
+ try {
34
+ BottomSheetRouter = require('./BottomSheetRouter').default;
35
+ } catch {
36
+ // BottomSheetRouter not available
37
+ }
38
+
33
39
  /**
34
40
  * OxyProvider - Universal provider for Expo apps (native + web)
35
41
  *
@@ -199,24 +205,13 @@ const OxyProvider: FC<OxyProviderProps> = ({
199
205
  >
200
206
  {children}
201
207
  {/* Only render bottom sheet router on native */}
202
- {!isWeb && <BottomSheetRouter />}
208
+ {BottomSheetRouter && <BottomSheetRouter />}
203
209
  <Toaster />
204
210
  </OxyContextProvider>
205
211
  </QueryClientProvider>
206
212
  );
207
213
 
208
- // On web, minimal wrappers (GestureHandler and SafeArea work via react-native-web)
209
- if (isWeb) {
210
- return (
211
- <SafeAreaProvider>
212
- <GestureHandlerRootView style={{ flex: 1 }}>
213
- {coreContent}
214
- </GestureHandlerRootView>
215
- </SafeAreaProvider>
216
- );
217
- }
218
-
219
- // On native, full wrappers including KeyboardProvider
214
+ // All platforms use same wrapper (KeyboardProvider is passthrough on web)
220
215
  return (
221
216
  <SafeAreaProvider>
222
217
  <GestureHandlerRootView style={{ flex: 1 }}>
@@ -3,189 +3,82 @@ import { isValidRoute } from './routes';
3
3
  import { createStore } from 'zustand/vanilla';
4
4
 
5
5
  /**
6
- * Bottom Sheet Manager - Pure state management module
7
- *
8
- * Uses Zustand (vanilla) for robust state management without React dependencies.
9
- * This ensures the manager can be imported safely anywhere.
6
+ * Bottom Sheet State Manager
10
7
  */
11
8
 
12
- export interface NavigationHistoryEntry {
13
- screen: RouteName;
14
- props: Record<string, unknown>;
15
- step?: number; // For step-based screens
16
- }
17
-
18
- export interface BottomSheetRouterState {
9
+ export interface BottomSheetState {
19
10
  currentScreen: RouteName | null;
20
11
  screenProps: Record<string, unknown>;
21
- currentStep?: number; // Current step in step-based screen
22
- navigationHistory: NavigationHistoryEntry[];
12
+ currentStep?: number;
13
+ history: Array<{ screen: RouteName; props: Record<string, unknown>; step?: number }>;
23
14
  isOpen: boolean;
24
15
  }
25
16
 
26
- // Initial state
27
- const initialState: BottomSheetRouterState = {
17
+ const initialState: BottomSheetState = {
28
18
  currentScreen: null,
29
19
  screenProps: {},
30
20
  currentStep: undefined,
31
- navigationHistory: [],
21
+ history: [],
32
22
  isOpen: false,
33
23
  };
34
24
 
35
- // Create vanilla store
36
- export const bottomSheetStore = createStore<BottomSheetRouterState>(() => initialState);
25
+ export const bottomSheetStore = createStore<BottomSheetState>(() => initialState);
37
26
 
38
- // Use a generic ref type to avoid importing React types
39
- type BottomSheetRefObject = { current: { present: () => void; dismiss: () => void } | null } | null;
40
- let bottomSheetRef: BottomSheetRefObject = null;
41
-
42
- /**
43
- * Set the bottom sheet ref so showBottomSheet can control it
44
- */
45
- export const setBottomSheetRef = (ref: BottomSheetRefObject) => {
46
- bottomSheetRef = ref;
47
- };
27
+ export const getState = () => bottomSheetStore.getState();
48
28
 
49
- /**
50
- * Update the bottom sheet state
51
- * (Kept for backward compatibility, but prefer using store directly if possible)
52
- */
53
- export const updateBottomSheetState = (updates: Partial<BottomSheetRouterState>) => {
54
- bottomSheetStore.setState((state) => ({ ...state, ...updates }));
55
- };
29
+ export const showBottomSheet = (
30
+ screenOrConfig: RouteName | { screen: RouteName; props?: Record<string, unknown> },
31
+ ): void => {
32
+ const screen = typeof screenOrConfig === 'string' ? screenOrConfig : screenOrConfig.screen;
33
+ const props = typeof screenOrConfig === 'string' ? {} : (screenOrConfig.props || {});
56
34
 
57
- /**
58
- * Subscribe to bottom sheet state changes
59
- * (Wrapper around store.subscribe for backward compatibility)
60
- */
61
- export const subscribeToBottomSheetState = (listener: (state: BottomSheetRouterState) => void) => {
62
- return bottomSheetStore.subscribe(listener);
63
- };
35
+ if (!isValidRoute(screen)) {
36
+ if (__DEV__) console.warn(`[BottomSheet] Invalid route: ${screen}`);
37
+ return;
38
+ }
64
39
 
65
- /**
66
- * Get the current bottom sheet state
67
- * (Wrapper around store.getState for backward compatibility)
68
- */
69
- export const getBottomSheetState = (): BottomSheetRouterState => {
70
- return bottomSheetStore.getState();
71
- };
40
+ const state = bottomSheetStore.getState();
72
41
 
73
- /**
74
- * Show the bottom sheet with a specific screen (internal - no route validation)
75
- */
76
- export const managerShowBottomSheet = (
77
- screen: RouteName,
78
- props?: Record<string, unknown>,
79
- options?: { addToHistory?: boolean; step?: number },
80
- ): void => {
81
- const currentState = bottomSheetStore.getState();
82
- const addToHistory = options?.addToHistory !== false; // Default to true
83
-
84
- // If adding to history and there's a current screen, push it to history
85
- if (addToHistory && currentState.currentScreen) {
86
- const historyEntry: NavigationHistoryEntry = {
87
- screen: currentState.currentScreen,
88
- props: { ...currentState.screenProps },
89
- step: currentState.currentStep,
90
- };
91
-
92
- // We need to create a new array for immutability
93
- const newHistory = [...currentState.navigationHistory, historyEntry];
94
- bottomSheetStore.setState({ navigationHistory: newHistory });
42
+ // Push current screen to history if navigating to different screen
43
+ if (state.currentScreen && state.currentScreen !== screen) {
44
+ bottomSheetStore.setState({
45
+ history: [...state.history, {
46
+ screen: state.currentScreen,
47
+ props: state.screenProps,
48
+ step: state.currentStep,
49
+ }],
50
+ });
95
51
  }
96
-
97
- // Determine the new step
98
- const newStep = options?.step ??
99
- (props?.initialStep !== undefined ? props.initialStep :
100
- (addToHistory ? undefined : currentState.currentStep));
101
-
52
+
102
53
  bottomSheetStore.setState({
103
54
  currentScreen: screen,
104
- screenProps: props || {},
105
- currentStep: newStep !== null && newStep !== undefined ? (newStep as number) : undefined,
55
+ screenProps: props,
56
+ currentStep: typeof props.initialStep === 'number' ? props.initialStep : undefined,
106
57
  isOpen: true,
107
58
  });
108
-
109
- // Present the sheet after state update
110
- if (bottomSheetRef?.current) {
111
- bottomSheetRef.current.present();
112
- }
113
59
  };
114
60
 
115
- /**
116
- * Close the bottom sheet (internal)
117
- */
118
- export const managerCloseBottomSheet = (): void => {
119
- bottomSheetStore.setState({
120
- currentScreen: null,
121
- screenProps: {},
122
- currentStep: undefined,
123
- navigationHistory: [],
124
- isOpen: false,
125
- });
126
-
127
- if (bottomSheetRef?.current) {
128
- bottomSheetRef.current.dismiss();
129
- }
61
+ export const closeBottomSheet = (): void => {
62
+ bottomSheetStore.setState(initialState);
130
63
  };
131
64
 
132
- /**
133
- * Go back in navigation history
134
- * Returns true if back navigation was successful, false if history is empty
135
- */
136
- export const managerGoBack = (): boolean => {
137
- const currentState = bottomSheetStore.getState();
65
+ export const goBack = (): boolean => {
66
+ const { history } = bottomSheetStore.getState();
138
67
 
139
- // If there's history, pop and navigate to previous screen
140
- if (currentState.navigationHistory.length > 0) {
141
- const previous = currentState.navigationHistory[currentState.navigationHistory.length - 1];
142
- const newHistory = currentState.navigationHistory.slice(0, -1);
143
-
68
+ if (history.length > 0) {
69
+ const prev = history[history.length - 1];
144
70
  bottomSheetStore.setState({
145
- currentScreen: previous.screen,
146
- screenProps: previous.props,
147
- currentStep: previous.step,
148
- navigationHistory: newHistory,
149
- isOpen: true,
71
+ currentScreen: prev.screen,
72
+ screenProps: prev.props,
73
+ currentStep: prev.step,
74
+ history: history.slice(0, -1),
150
75
  });
151
-
152
76
  return true;
153
77
  }
154
-
155
- return false;
156
- };
157
-
158
- /**
159
- * Public API for showing bottom sheets
160
- */
161
- export const showBottomSheet = (
162
- screenOrConfig: RouteName | { screen: RouteName; props?: Record<string, unknown> },
163
- ): void => {
164
- let screen: RouteName;
165
- let props: Record<string, unknown> = {};
166
-
167
- if (typeof screenOrConfig === 'string') {
168
- screen = screenOrConfig;
169
- } else {
170
- screen = screenOrConfig.screen;
171
- props = screenOrConfig.props || {};
172
- }
173
-
174
- if (!isValidRoute(screen)) {
175
- if (__DEV__) {
176
- console.warn(`[BottomSheetAPI] Invalid route: ${screen}`);
177
- }
178
- return;
179
- }
180
78
 
181
- managerShowBottomSheet(screen, props);
79
+ return false;
182
80
  };
183
81
 
184
- /**
185
- * Public API for closing bottom sheets
186
- */
187
- export const closeBottomSheet = (): void => {
188
- managerCloseBottomSheet();
82
+ export const updateState = (updates: Partial<BottomSheetState>) => {
83
+ bottomSheetStore.setState((state) => ({ ...state, ...updates }));
189
84
  };
190
-
191
-
@@ -29,7 +29,6 @@ import { useThemeStyles } from '../hooks/useThemeStyles';
29
29
  import { useColorScheme } from '../hooks/use-color-scheme';
30
30
  import { Colors } from '../constants/theme';
31
31
  import { normalizeColorScheme, normalizeTheme } from '../utils/themeUtils';
32
- import { useHapticPress } from '../hooks/use-haptic-press';
33
32
  import { EditDisplayNameModal } from '../components/profile/EditDisplayNameModal';
34
33
  import { EditUsernameModal } from '../components/profile/EditUsernameModal';
35
34
  import { EditEmailModal } from '../components/profile/EditEmailModal';
@@ -176,7 +175,6 @@ const AccountSettingsScreen: React.FC<BaseScreenProps & { initialField?: string;
176
175
  // Get theme colors using centralized hook
177
176
  const colorScheme = useColorScheme();
178
177
  const themeStyles = useThemeStyles(theme || 'light', colorScheme);
179
- const handlePressIn = useHapticPress();
180
178
 
181
179
  // Extract colors for convenience - ensure it's always defined
182
180
  // useThemeStyles always returns colors, but add safety check for edge cases
@@ -1,21 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.useHapticPress = useHapticPress;
7
- var _react = require("react");
8
- var Haptics = _interopRequireWildcard(require("expo-haptics"));
9
- function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
10
- /**
11
- * Hook that returns a memoized callback for haptic feedback on press.
12
- * Provides consistent light haptic feedback across the app.
13
- *
14
- * @returns A stable callback function that triggers haptic feedback
15
- */
16
- function useHapticPress() {
17
- return (0, _react.useCallback)(() => {
18
- Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light);
19
- }, []);
20
- }
21
- //# sourceMappingURL=use-haptic-press.js.map
@@ -1 +0,0 @@
1
- {"version":3,"names":["_react","require","Haptics","_interopRequireWildcard","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","useHapticPress","useCallback","impactAsync","ImpactFeedbackStyle","Light"],"sourceRoot":"../../../../src","sources":["ui/hooks/use-haptic-press.ts"],"mappings":";;;;;;AAAA,IAAAA,MAAA,GAAAC,OAAA;AACA,IAAAC,OAAA,GAAAC,uBAAA,CAAAF,OAAA;AAAwC,SAAAE,wBAAAC,CAAA,EAAAC,CAAA,6BAAAC,OAAA,MAAAC,CAAA,OAAAD,OAAA,IAAAE,CAAA,OAAAF,OAAA,YAAAH,uBAAA,YAAAA,CAAAC,CAAA,EAAAC,CAAA,SAAAA,CAAA,IAAAD,CAAA,IAAAA,CAAA,CAAAK,UAAA,SAAAL,CAAA,MAAAM,CAAA,EAAAC,CAAA,EAAAC,CAAA,KAAAC,SAAA,QAAAC,OAAA,EAAAV,CAAA,iBAAAA,CAAA,uBAAAA,CAAA,yBAAAA,CAAA,SAAAQ,CAAA,MAAAF,CAAA,GAAAL,CAAA,GAAAG,CAAA,GAAAD,CAAA,QAAAG,CAAA,CAAAK,GAAA,CAAAX,CAAA,UAAAM,CAAA,CAAAM,GAAA,CAAAZ,CAAA,GAAAM,CAAA,CAAAO,GAAA,CAAAb,CAAA,EAAAQ,CAAA,gBAAAP,CAAA,IAAAD,CAAA,gBAAAC,CAAA,OAAAa,cAAA,CAAAC,IAAA,CAAAf,CAAA,EAAAC,CAAA,OAAAM,CAAA,IAAAD,CAAA,GAAAU,MAAA,CAAAC,cAAA,KAAAD,MAAA,CAAAE,wBAAA,CAAAlB,CAAA,EAAAC,CAAA,OAAAM,CAAA,CAAAK,GAAA,IAAAL,CAAA,CAAAM,GAAA,IAAAP,CAAA,CAAAE,CAAA,EAAAP,CAAA,EAAAM,CAAA,IAAAC,CAAA,CAAAP,CAAA,IAAAD,CAAA,CAAAC,CAAA,WAAAO,CAAA,KAAAR,CAAA,EAAAC,CAAA;AAExC;AACA;AACA;AACA;AACA;AACA;AACO,SAASkB,cAAcA,CAAA,EAAG;EAC/B,OAAO,IAAAC,kBAAW,EAAC,MAAM;IACvBtB,OAAO,CAACuB,WAAW,CAACvB,OAAO,CAACwB,mBAAmB,CAACC,KAAK,CAAC;EACxD,CAAC,EAAE,EAAE,CAAC;AACR","ignoreList":[]}
@@ -1,17 +0,0 @@
1
- "use strict";
2
-
3
- import { useCallback } from 'react';
4
- import * as Haptics from 'expo-haptics';
5
-
6
- /**
7
- * Hook that returns a memoized callback for haptic feedback on press.
8
- * Provides consistent light haptic feedback across the app.
9
- *
10
- * @returns A stable callback function that triggers haptic feedback
11
- */
12
- export function useHapticPress() {
13
- return useCallback(() => {
14
- Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light);
15
- }, []);
16
- }
17
- //# sourceMappingURL=use-haptic-press.js.map
@@ -1 +0,0 @@
1
- {"version":3,"names":["useCallback","Haptics","useHapticPress","impactAsync","ImpactFeedbackStyle","Light"],"sourceRoot":"../../../../src","sources":["ui/hooks/use-haptic-press.ts"],"mappings":";;AAAA,SAASA,WAAW,QAAQ,OAAO;AACnC,OAAO,KAAKC,OAAO,MAAM,cAAc;;AAEvC;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,cAAcA,CAAA,EAAG;EAC/B,OAAOF,WAAW,CAAC,MAAM;IACvBC,OAAO,CAACE,WAAW,CAACF,OAAO,CAACG,mBAAmB,CAACC,KAAK,CAAC;EACxD,CAAC,EAAE,EAAE,CAAC;AACR","ignoreList":[]}
@@ -1,8 +0,0 @@
1
- /**
2
- * Hook that returns a memoized callback for haptic feedback on press.
3
- * Provides consistent light haptic feedback across the app.
4
- *
5
- * @returns A stable callback function that triggers haptic feedback
6
- */
7
- export declare function useHapticPress(): () => void;
8
- //# sourceMappingURL=use-haptic-press.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"use-haptic-press.d.ts","sourceRoot":"","sources":["../../../../../src/ui/hooks/use-haptic-press.ts"],"names":[],"mappings":"AAGA;;;;;GAKG;AACH,wBAAgB,cAAc,eAI7B"}
@@ -1,8 +0,0 @@
1
- /**
2
- * Hook that returns a memoized callback for haptic feedback on press.
3
- * Provides consistent light haptic feedback across the app.
4
- *
5
- * @returns A stable callback function that triggers haptic feedback
6
- */
7
- export declare function useHapticPress(): () => void;
8
- //# sourceMappingURL=use-haptic-press.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"use-haptic-press.d.ts","sourceRoot":"","sources":["../../../../../src/ui/hooks/use-haptic-press.ts"],"names":[],"mappings":"AAGA;;;;;GAKG;AACH,wBAAgB,cAAc,eAI7B"}
@@ -1,15 +0,0 @@
1
- import { useCallback } from 'react';
2
- import * as Haptics from 'expo-haptics';
3
-
4
- /**
5
- * Hook that returns a memoized callback for haptic feedback on press.
6
- * Provides consistent light haptic feedback across the app.
7
- *
8
- * @returns A stable callback function that triggers haptic feedback
9
- */
10
- export function useHapticPress() {
11
- return useCallback(() => {
12
- Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light);
13
- }, []);
14
- }
15
-