@umituz/react-native-notifications 1.0.6 → 1.1.0

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 (67) hide show
  1. package/lib/infrastructure/hooks/actions/useNotificationActions.d.ts +4 -13
  2. package/lib/infrastructure/hooks/actions/useNotificationActions.d.ts.map +1 -1
  3. package/lib/infrastructure/hooks/actions/useNotificationActions.js +4 -70
  4. package/lib/infrastructure/hooks/actions/useNotificationActions.js.map +1 -1
  5. package/lib/infrastructure/hooks/actions/useNotificationManagementActions.d.ts +8 -0
  6. package/lib/infrastructure/hooks/actions/useNotificationManagementActions.d.ts.map +1 -0
  7. package/lib/infrastructure/hooks/actions/useNotificationManagementActions.js +78 -0
  8. package/lib/infrastructure/hooks/actions/useNotificationManagementActions.js.map +1 -0
  9. package/lib/infrastructure/hooks/state/useNotificationsState.d.ts +8 -8
  10. package/lib/infrastructure/hooks/useNotificationSettings.d.ts +2 -2
  11. package/lib/infrastructure/hooks/useNotifications.d.ts +21 -1
  12. package/lib/infrastructure/hooks/useNotifications.d.ts.map +1 -1
  13. package/lib/infrastructure/hooks/useNotifications.js +30 -9
  14. package/lib/infrastructure/hooks/useNotifications.js.map +1 -1
  15. package/lib/infrastructure/hooks/utils/useNotificationRefresh.d.ts +5 -10
  16. package/lib/infrastructure/hooks/utils/useNotificationRefresh.d.ts.map +1 -1
  17. package/lib/infrastructure/hooks/utils/useNotificationRefresh.js +32 -15
  18. package/lib/infrastructure/hooks/utils/useNotificationRefresh.js.map +1 -1
  19. package/lib/infrastructure/services/NotificationBadgeManager.d.ts +5 -0
  20. package/lib/infrastructure/services/NotificationBadgeManager.d.ts.map +1 -0
  21. package/lib/infrastructure/services/NotificationBadgeManager.js +29 -0
  22. package/lib/infrastructure/services/NotificationBadgeManager.js.map +1 -0
  23. package/lib/infrastructure/services/NotificationManager.d.ts +5 -84
  24. package/lib/infrastructure/services/NotificationManager.d.ts.map +1 -1
  25. package/lib/infrastructure/services/NotificationManager.js +36 -203
  26. package/lib/infrastructure/services/NotificationManager.js.map +1 -1
  27. package/lib/infrastructure/services/NotificationPermissions.d.ts +6 -0
  28. package/lib/infrastructure/services/NotificationPermissions.d.ts.map +1 -0
  29. package/lib/infrastructure/services/NotificationPermissions.js +75 -0
  30. package/lib/infrastructure/services/NotificationPermissions.js.map +1 -0
  31. package/lib/infrastructure/services/NotificationScheduler.d.ts +8 -0
  32. package/lib/infrastructure/services/NotificationScheduler.d.ts.map +1 -0
  33. package/lib/infrastructure/services/NotificationScheduler.js +72 -0
  34. package/lib/infrastructure/services/NotificationScheduler.js.map +1 -0
  35. package/lib/infrastructure/services/delivery/NotificationDelivery.d.ts +2 -8
  36. package/lib/infrastructure/services/delivery/NotificationDelivery.d.ts.map +1 -1
  37. package/lib/infrastructure/services/delivery/NotificationDelivery.js +27 -13
  38. package/lib/infrastructure/services/delivery/NotificationDelivery.js.map +1 -1
  39. package/lib/infrastructure/storage/NotificationsStore.d.ts +8 -1
  40. package/lib/infrastructure/storage/NotificationsStore.d.ts.map +1 -1
  41. package/lib/infrastructure/storage/NotificationsStore.js +2 -1
  42. package/lib/infrastructure/storage/NotificationsStore.js.map +1 -1
  43. package/lib/infrastructure/utils/dev.d.ts +5 -0
  44. package/lib/infrastructure/utils/dev.d.ts.map +1 -0
  45. package/lib/infrastructure/utils/dev.js +24 -0
  46. package/lib/infrastructure/utils/dev.js.map +1 -0
  47. package/lib/presentation/screens/NotificationsScreen.d.ts +14 -4
  48. package/lib/presentation/screens/NotificationsScreen.d.ts.map +1 -1
  49. package/lib/presentation/screens/NotificationsScreen.js +12 -15
  50. package/lib/presentation/screens/NotificationsScreen.js.map +1 -1
  51. package/package.json +1 -1
  52. package/src/__tests__/NotificationManager.test.ts +215 -0
  53. package/src/__tests__/useNotificationActions.test.ts +189 -0
  54. package/src/__tests__/useNotificationRefresh.test.ts +213 -0
  55. package/src/infrastructure/hooks/actions/useNotificationActions.ts +8 -110
  56. package/src/infrastructure/hooks/actions/useNotificationManagementActions.ts +131 -0
  57. package/src/infrastructure/hooks/useNotifications.ts +37 -11
  58. package/src/infrastructure/hooks/utils/useNotificationRefresh.ts +40 -16
  59. package/src/infrastructure/services/NotificationBadgeManager.ts +28 -0
  60. package/src/infrastructure/services/NotificationManager.ts +51 -217
  61. package/src/infrastructure/services/NotificationPermissions.ts +80 -0
  62. package/src/infrastructure/services/NotificationScheduler.ts +77 -0
  63. package/src/infrastructure/services/delivery/NotificationDelivery.ts +32 -14
  64. package/src/infrastructure/storage/NotificationsStore.ts +3 -2
  65. package/src/infrastructure/utils/dev.ts +25 -0
  66. package/src/presentation/screens/NotificationsScreen.tsx +31 -18
  67. package/src/types/global.d.ts +255 -0
@@ -0,0 +1,80 @@
1
+ import * as Notifications from 'expo-notifications';
2
+ import * as Device from 'expo-device';
3
+ import { Platform } from 'react-native';
4
+ import { devWarn, devError, devLog } from '../utils/dev';
5
+
6
+ export class NotificationPermissions {
7
+ async requestPermissions(): Promise<boolean> {
8
+ try {
9
+ if (!Device.isDevice) {
10
+ devWarn('[NotificationPermissions] Notifications only work on physical devices');
11
+ return false;
12
+ }
13
+
14
+ const permissionsResponse = await Notifications.getPermissionsAsync();
15
+ const existingStatus = (permissionsResponse as any).status || ((permissionsResponse as any).granted ? 'granted' : 'denied');
16
+ let finalStatus = existingStatus;
17
+
18
+ if (existingStatus !== 'granted') {
19
+ const requestResponse = await Notifications.requestPermissionsAsync();
20
+ finalStatus = (requestResponse as any).status || ((requestResponse as any).granted ? 'granted' : 'denied');
21
+ }
22
+
23
+ if (Platform.OS === 'android') {
24
+ await this.createAndroidChannels();
25
+ }
26
+
27
+ return finalStatus === 'granted';
28
+ } catch (error) {
29
+ devError('[NotificationPermissions] Permission request failed:', error);
30
+ return false;
31
+ }
32
+ }
33
+
34
+ async hasPermissions(): Promise<boolean> {
35
+ try {
36
+ if (!Device.isDevice) return false;
37
+ const permissionsResponse = await Notifications.getPermissionsAsync();
38
+ return (permissionsResponse as any).status === 'granted' || (permissionsResponse as any).granted === true;
39
+ } catch (error) {
40
+ devError('[NotificationPermissions] Permission check failed:', error);
41
+ return false;
42
+ }
43
+ }
44
+
45
+ private async createAndroidChannels(): Promise<void> {
46
+ if (Platform.OS !== 'android') return;
47
+
48
+ try {
49
+ await Notifications.setNotificationChannelAsync('default', {
50
+ name: 'Default',
51
+ importance: Notifications.AndroidImportance.DEFAULT,
52
+ vibrationPattern: [0, 250, 250, 250],
53
+ sound: 'default',
54
+ lightColor: '#3B82F6',
55
+ });
56
+
57
+ await Notifications.setNotificationChannelAsync('reminders', {
58
+ name: 'Reminders',
59
+ importance: Notifications.AndroidImportance.HIGH,
60
+ vibrationPattern: [0, 250, 250, 250],
61
+ sound: 'default',
62
+ lightColor: '#3B82F6',
63
+ enableVibrate: true,
64
+ });
65
+
66
+ await Notifications.setNotificationChannelAsync('urgent', {
67
+ name: 'Urgent',
68
+ importance: Notifications.AndroidImportance.MAX,
69
+ vibrationPattern: [0, 500, 250, 500],
70
+ sound: 'default',
71
+ lightColor: '#EF4444',
72
+ enableVibrate: true,
73
+ });
74
+
75
+ devLog('[NotificationPermissions] Android channels created');
76
+ } catch (error) {
77
+ devError('[NotificationPermissions] Android channel creation failed:', error);
78
+ }
79
+ }
80
+ }
@@ -0,0 +1,77 @@
1
+ import * as Notifications from 'expo-notifications';
2
+ import type { NotificationTrigger, ScheduleNotificationOptions, ScheduledNotification } from './NotificationManager';
3
+
4
+ export class NotificationScheduler {
5
+ async scheduleNotification(options: ScheduleNotificationOptions): Promise<string> {
6
+ const { title, body, data = {}, trigger, sound = true, badge, categoryIdentifier } = options;
7
+
8
+ let notificationTrigger: any;
9
+
10
+ if (trigger.type === 'date') {
11
+ notificationTrigger = {
12
+ date: trigger.date,
13
+ channelId: categoryIdentifier || 'default',
14
+ };
15
+ } else if (trigger.type === 'daily') {
16
+ notificationTrigger = {
17
+ hour: trigger.hour,
18
+ minute: trigger.minute,
19
+ repeats: true,
20
+ channelId: categoryIdentifier || 'reminders',
21
+ };
22
+ } else if (trigger.type === 'weekly') {
23
+ notificationTrigger = {
24
+ weekday: trigger.weekday,
25
+ hour: trigger.hour,
26
+ minute: trigger.minute,
27
+ repeats: true,
28
+ channelId: categoryIdentifier || 'reminders',
29
+ };
30
+ } else if (trigger.type === 'monthly') {
31
+ notificationTrigger = {
32
+ day: trigger.day,
33
+ hour: trigger.hour,
34
+ minute: trigger.minute,
35
+ repeats: true,
36
+ channelId: categoryIdentifier || 'reminders',
37
+ };
38
+ }
39
+
40
+ const notificationId = await Notifications.scheduleNotificationAsync({
41
+ content: {
42
+ title,
43
+ body,
44
+ data,
45
+ sound: sound === true ? 'default' : sound || undefined,
46
+ badge,
47
+ categoryIdentifier,
48
+ priority: Notifications.AndroidNotificationPriority.HIGH,
49
+ vibrate: [0, 250, 250, 250],
50
+ },
51
+ trigger: notificationTrigger,
52
+ });
53
+
54
+ return notificationId;
55
+ }
56
+
57
+ async cancelNotification(notificationId: string): Promise<void> {
58
+ await Notifications.cancelScheduledNotificationAsync(notificationId);
59
+ }
60
+
61
+ async cancelAllNotifications(): Promise<void> {
62
+ await Notifications.cancelAllScheduledNotificationsAsync();
63
+ }
64
+
65
+ async getScheduledNotifications(): Promise<ScheduledNotification[]> {
66
+ const notifications = await Notifications.getAllScheduledNotificationsAsync();
67
+ return notifications.map(notification => ({
68
+ identifier: notification.identifier,
69
+ content: {
70
+ title: notification.content.title || '',
71
+ body: notification.content.body || '',
72
+ data: notification.content.data as Record<string, any>,
73
+ },
74
+ trigger: notification.trigger,
75
+ }));
76
+ }
77
+ }
@@ -1,21 +1,13 @@
1
1
  import * as Notifications from 'expo-notifications';
2
2
  import AsyncStorage from '@react-native-async-storage/async-storage';
3
3
  import type { Notification } from '../types';
4
+ import { devLog, devError } from '../../utils/dev';
4
5
 
5
- /**
6
- * NotificationDelivery - Offline Local Notification Delivery
7
- *
8
- * Uses expo-notifications for local push notifications only.
9
- * All data stored in AsyncStorage (offline-capable).
10
- *
11
- * NO backend, NO email/SMS - pure offline local notifications.
12
- */
13
6
  export class NotificationDelivery {
14
7
  private static STORAGE_KEY = '@notifications:delivered';
15
8
 
16
9
  async deliver(notification: Notification): Promise<void> {
17
10
  try {
18
- // Schedule local notification using expo-notifications
19
11
  await Notifications.scheduleNotificationAsync({
20
12
  content: {
21
13
  title: notification.title,
@@ -24,14 +16,17 @@ export class NotificationDelivery {
24
16
  },
25
17
  trigger: notification.scheduled_for
26
18
  ? { date: new Date(notification.scheduled_for) }
27
- : null, // null = immediate delivery
19
+ : null,
28
20
  });
29
21
 
30
- // Update status in AsyncStorage (offline storage)
31
22
  await this.updateStatus(notification.id, 'delivered');
23
+
24
+ devLog('[NotificationDelivery] Notification delivered:', notification.id);
32
25
  } catch (error) {
33
- // Silent failure - update status to failed
34
26
  await this.updateStatus(notification.id, 'failed');
27
+
28
+ devError('[NotificationDelivery] Delivery failed:', notification.id, error);
29
+ throw error;
35
30
  }
36
31
  }
37
32
 
@@ -49,8 +44,10 @@ export class NotificationDelivery {
49
44
  NotificationDelivery.STORAGE_KEY,
50
45
  JSON.stringify(delivered)
51
46
  );
47
+
48
+ devLog('[NotificationDelivery] Status updated:', notificationId, status);
52
49
  } catch (error) {
53
- // Silent failure
50
+ devError('[NotificationDelivery] Status update failed:', notificationId, error);
54
51
  }
55
52
  }
56
53
 
@@ -59,7 +56,28 @@ export class NotificationDelivery {
59
56
  const data = await AsyncStorage.getItem(NotificationDelivery.STORAGE_KEY);
60
57
  return data ? JSON.parse(data) : {};
61
58
  } catch (error) {
59
+ devError('[NotificationDelivery] Failed to get delivered notifications:', error);
62
60
  return {};
63
61
  }
64
62
  }
65
- }
63
+
64
+ async getDeliveryStatus(notificationId: string): Promise<string | null> {
65
+ try {
66
+ const delivered = await this.getDelivered();
67
+ return delivered[notificationId]?.status || null;
68
+ } catch (error) {
69
+ devError('[NotificationDelivery] Failed to get delivery status:', notificationId, error);
70
+ return null;
71
+ }
72
+ }
73
+
74
+ async clearDeliveryHistory(): Promise<void> {
75
+ try {
76
+ await AsyncStorage.removeItem(NotificationDelivery.STORAGE_KEY);
77
+
78
+ devLog('[NotificationDelivery] Delivery history cleared');
79
+ } catch (error) {
80
+ devError('[NotificationDelivery] Failed to clear delivery history:', error);
81
+ }
82
+ }
83
+ }
@@ -28,7 +28,8 @@ export const useNotificationsStore = create<NotificationsStore>((set) => ({
28
28
  * Hook for accessing notifications state
29
29
  */
30
30
  export const useNotifications = () => {
31
- const { hasPermissions, isInitialized, setPermissions, setInitialized } = useNotificationsStore();
31
+ const store = useNotificationsStore();
32
+ const { hasPermissions, isInitialized, setPermissions, setInitialized } = store;
32
33
 
33
34
  return {
34
35
  hasPermissions,
@@ -36,4 +37,4 @@ export const useNotifications = () => {
36
37
  setPermissions,
37
38
  setInitialized,
38
39
  };
39
- };
40
+ };
@@ -0,0 +1,25 @@
1
+ export const isDev = () => {
2
+ try {
3
+ return typeof __DEV__ !== 'undefined' && __DEV__;
4
+ } catch {
5
+ return false;
6
+ }
7
+ };
8
+
9
+ export const devLog = (message: string, ...args: any[]) => {
10
+ if (isDev()) {
11
+ console.log(message, ...args);
12
+ }
13
+ };
14
+
15
+ export const devError = (message: string, ...args: any[]) => {
16
+ if (isDev()) {
17
+ console.error(message, ...args);
18
+ }
19
+ };
20
+
21
+ export const devWarn = (message: string, ...args: any[]) => {
22
+ if (isDev()) {
23
+ console.warn(message, ...args);
24
+ }
25
+ };
@@ -1,54 +1,67 @@
1
1
  /**
2
- * Notifications Screen - {{APP_NAME}}
2
+ * Notifications Screen - Dynamic and Reusable
3
3
  *
4
- * Simple notification toggle - enable or disable reminders
5
- * Theme: {{THEME_ID}} ({{CATEGORY}} category)
4
+ * A clean notification settings screen that accepts all text and configuration
5
+ * as props to make it completely reusable across different applications.
6
6
  */
7
7
 
8
8
  import React, { useMemo } from 'react';
9
9
  import { View, StyleSheet, ActivityIndicator } from 'react-native';
10
10
  import { AtomicIcon, AtomicSwitch, AtomicCard, AtomicText, ScreenLayout, STATIC_TOKENS } from '@umituz/react-native-design-system';
11
-
12
11
  import { useAppDesignTokens } from '@umituz/react-native-design-system-theme';
13
12
  import { useNotificationSettings } from '../../infrastructure/hooks/useNotificationSettings';
14
13
  import type { DesignTokens } from '@umituz/react-native-design-system';
15
14
 
16
- // Note: Translation function should be provided by the app using this package
17
- // This is a placeholder - apps should wrap this component with their i18n provider
18
- const t = (key: string): string => {
19
- // Return key as fallback - apps should provide translation function
20
- return key;
21
- };
15
+ export interface NotificationsScreenProps {
16
+ translations: {
17
+ title: string;
18
+ description: string;
19
+ loadingText?: string;
20
+ };
21
+ iconName?: string;
22
+ iconColor?: string;
23
+ testID?: string;
24
+ }
22
25
 
23
- export const NotificationsScreen: React.FC = () => {
24
-
26
+ export const NotificationsScreen: React.FC<NotificationsScreenProps> = ({
27
+ translations,
28
+ iconName = 'Bell',
29
+ iconColor = 'primary',
30
+ testID = 'notifications-screen',
31
+ }) => {
25
32
  const tokens = useAppDesignTokens();
26
33
  const styles = useMemo(() => getStyles(tokens), [tokens]);
27
34
  const { notificationsEnabled, setNotificationsEnabled, isLoading } = useNotificationSettings();
28
35
 
29
36
  if (isLoading) {
30
37
  return (
31
- <ScreenLayout testID="notifications-screen">
38
+ <ScreenLayout testID={testID}>
32
39
  <View style={styles.loadingContainer}>
33
40
  <ActivityIndicator size="large" color={tokens.colors.primary} />
41
+ <AtomicText
42
+ type="bodyMedium"
43
+ style={{ color: tokens.colors.textSecondary, marginTop: STATIC_TOKENS.spacing.md }}
44
+ >
45
+ {translations.loadingText || 'Loading...'}
46
+ </AtomicText>
34
47
  </View>
35
48
  </ScreenLayout>
36
49
  );
37
50
  }
38
51
 
39
52
  return (
40
- <ScreenLayout testID="notifications-screen" hideScrollIndicator>
53
+ <ScreenLayout testID={testID} hideScrollIndicator>
41
54
  <AtomicCard style={styles.card}>
42
55
  <View style={styles.settingItem}>
43
56
  <View style={styles.iconContainer}>
44
- <AtomicIcon name="Bell" size="lg" color="primary" />
57
+ <AtomicIcon name={iconName} size="lg" color={iconColor} />
45
58
  </View>
46
59
  <View style={styles.textContainer}>
47
60
  <AtomicText type="bodyLarge" style={{ color: tokens.colors.textPrimary }}>
48
- {t('settings.notifications.enableNotifications')}
61
+ {translations.title}
49
62
  </AtomicText>
50
63
  <AtomicText type="bodySmall" style={{ color: tokens.colors.textSecondary, marginTop: STATIC_TOKENS.spacing.xs }}>
51
- {t('settings.notifications.description')}
64
+ {translations.description}
52
65
  </AtomicText>
53
66
  </View>
54
67
  <AtomicSwitch
@@ -91,4 +104,4 @@ const getStyles = (tokens: DesignTokens) => StyleSheet.create({
91
104
  },
92
105
  });
93
106
 
94
- export default NotificationsScreen;
107
+ export default NotificationsScreen;
@@ -0,0 +1,255 @@
1
+ declare const __DEV__: boolean;
2
+
3
+ declare global {
4
+ namespace React {
5
+ interface ReactElement {
6
+ type: any;
7
+ props: any;
8
+ key: any;
9
+ }
10
+
11
+ interface ReactNode {
12
+ [key: string]: any;
13
+ }
14
+ }
15
+ }
16
+
17
+ declare module 'react' {
18
+ export interface FunctionComponent<P = {}> {
19
+ (props: P): React.ReactElement | null;
20
+ displayName?: string;
21
+ }
22
+
23
+ export type FC<P = {}> = FunctionComponent<P>;
24
+
25
+ export function useState<S>(initialState: S | (() => S)): [S, (value: S | ((prevState: S) => S)) => void];
26
+ export function useEffect(effect: () => void | (() => void), deps?: any[]): void;
27
+ export function useCallback<T extends (...args: any[]) => any>(callback: T, deps: any[]): T;
28
+ export function useMemo<T>(factory: () => T, deps: any[]): T;
29
+ export function useRef<T>(initialValue: T): { current: T };
30
+
31
+ export interface ReactElement {
32
+ type: any;
33
+ props: any;
34
+ key: any;
35
+ }
36
+
37
+ export interface ReactNode {
38
+ [key: string]: any;
39
+ }
40
+
41
+ const createElement: any;
42
+ const Component: any;
43
+ }
44
+
45
+ declare module '@react-native-async-storage/async-storage' {
46
+ export interface AsyncStorageStatic {
47
+ getItem(key: string): Promise<string | null>;
48
+ setItem(key: string, value: string): Promise<void>;
49
+ removeItem(key: string): Promise<void>;
50
+ clear(): Promise<void>;
51
+ getAllKeys(): Promise<string[]>;
52
+ multiGet(keys: string[]): Promise<[string, string | null][]>;
53
+ multiSet(keyValuePairs: [string, string][]): Promise<void>;
54
+ multiRemove(keys: string[]): Promise<void>;
55
+ }
56
+ const AsyncStorage: AsyncStorageStatic;
57
+ export default AsyncStorage;
58
+ }
59
+
60
+ declare module 'expo-notifications' {
61
+ export interface NotificationContentInput {
62
+ title: string;
63
+ body: string;
64
+ data?: Record<string, any>;
65
+ sound?: string | boolean;
66
+ badge?: number;
67
+ categoryIdentifier?: string;
68
+ priority?: AndroidNotificationPriority;
69
+ vibrate?: number[];
70
+ }
71
+
72
+ export interface NotificationRequestInput {
73
+ content: NotificationContentInput;
74
+ trigger?: NotificationTriggerInput | null;
75
+ }
76
+
77
+ export interface NotificationTriggerInput {
78
+ date?: Date;
79
+ repeats?: boolean;
80
+ channelId?: string;
81
+ hour?: number;
82
+ minute?: number;
83
+ weekday?: number;
84
+ day?: number;
85
+ }
86
+
87
+ export interface ScheduledNotification {
88
+ identifier: string;
89
+ content: NotificationContentInput;
90
+ trigger: NotificationTriggerInput;
91
+ }
92
+
93
+ export enum AndroidImportance {
94
+ DEFAULT = 'default',
95
+ HIGH = 'high',
96
+ MAX = 'max',
97
+ LOW = 'low',
98
+ MIN = 'min',
99
+ UNSPECIFIED = 'unspecified',
100
+ }
101
+
102
+ export enum AndroidNotificationPriority {
103
+ DEFAULT = 'default',
104
+ HIGH = 'high',
105
+ LOW = 'low',
106
+ MAX = 'max',
107
+ MIN = 'min',
108
+ }
109
+
110
+ export interface AndroidChannel {
111
+ name: string;
112
+ importance: AndroidImportance;
113
+ vibrationPattern?: number[];
114
+ sound?: string;
115
+ lightColor?: string;
116
+ enableVibrate?: boolean;
117
+ }
118
+
119
+ export interface NotificationPermissionsResponse {
120
+ status: 'granted' | 'denied' | 'undetermined';
121
+ granted?: boolean;
122
+ }
123
+
124
+ export function setNotificationHandler(handler: {
125
+ handleNotification: () => Promise<{
126
+ shouldShowAlert: boolean;
127
+ shouldPlaySound: boolean;
128
+ shouldSetBadge: boolean;
129
+ }>;
130
+ }): void;
131
+
132
+ export function scheduleNotificationAsync(request: NotificationRequestInput): Promise<string>;
133
+ export function cancelScheduledNotificationAsync(identifier: string): Promise<void>;
134
+ export function cancelAllScheduledNotificationsAsync(): Promise<void>;
135
+ export function getAllScheduledNotificationsAsync(): Promise<ScheduledNotification[]>;
136
+ export function dismissAllNotificationsAsync(): Promise<void>;
137
+ export function getPermissionsAsync(): Promise<NotificationPermissionsResponse>;
138
+ export function requestPermissionsAsync(): Promise<NotificationPermissionsResponse>;
139
+ export function setNotificationChannelAsync(id: string, channel: AndroidChannel): Promise<void>;
140
+ export function getBadgeCountAsync(): Promise<number>;
141
+ export function setBadgeCountAsync(count: number): Promise<void>;
142
+ export function getExpoPushTokenAsync(options?: any): Promise<{ data: string }>;
143
+ }
144
+
145
+ declare module 'expo-device' {
146
+ export const isDevice: boolean;
147
+ }
148
+
149
+ declare module 'react-native' {
150
+ export interface PlatformStatic {
151
+ OS: 'ios' | 'android';
152
+ Version: string | number;
153
+ isPad?: boolean;
154
+ isTVOS?: boolean;
155
+ select<T>(specifics: { ios?: T; android?: T; default?: T }): T;
156
+ }
157
+ export const Platform: PlatformStatic;
158
+
159
+ export interface StyleSheetStatic {
160
+ create<T>(styles: T): T;
161
+ }
162
+ export const StyleSheet: StyleSheetStatic;
163
+
164
+ export interface ViewStatic {
165
+ new (props: any): any;
166
+ }
167
+ export const View: ViewStatic;
168
+
169
+ export interface ActivityIndicatorStatic {
170
+ new (props: any): any;
171
+ }
172
+ export const ActivityIndicator: ActivityIndicatorStatic;
173
+ }
174
+
175
+ declare module 'zustand' {
176
+ export interface StoreApi<T> {
177
+ getState: () => T;
178
+ setState: (partial: T | Partial<T> | ((state: T) => T | Partial<T>), replace?: boolean) => void;
179
+ subscribe: (listener: (state: T, prevState: T) => void) => () => void;
180
+ destroy: () => void;
181
+ }
182
+
183
+ export function create<TState extends object>(
184
+ stateCreator: (
185
+ set: (
186
+ partial: TState | Partial<TState> | ((state: TState) => TState | Partial<TState>),
187
+ replace?: boolean,
188
+ ) => void,
189
+ get: () => TState,
190
+ api: StoreApi<TState>,
191
+ ) => TState,
192
+ ): StoreApi<TState> & ((selector?: (state: TState) => any) => any);
193
+ }
194
+
195
+ declare module '@umituz/react-native-design-system' {
196
+ export interface AtomicIconProps {
197
+ name: string;
198
+ size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';
199
+ color?: string;
200
+ }
201
+
202
+ export interface AtomicSwitchProps {
203
+ value: boolean;
204
+ onValueChange: (value: boolean) => void;
205
+ testID?: string;
206
+ }
207
+
208
+ export interface AtomicCardProps {
209
+ style?: any;
210
+ children?: React.ReactNode;
211
+ }
212
+
213
+ export interface AtomicTextProps {
214
+ type: 'bodySmall' | 'bodyMedium' | 'bodyLarge';
215
+ style?: any;
216
+ children?: React.ReactNode;
217
+ }
218
+
219
+ export interface ScreenLayoutProps {
220
+ testID?: string;
221
+ hideScrollIndicator?: boolean;
222
+ children?: React.ReactNode;
223
+ }
224
+
225
+ export const AtomicIcon: React.FC<AtomicIconProps>;
226
+ export const AtomicSwitch: React.FC<AtomicSwitchProps>;
227
+ export const AtomicCard: React.FC<AtomicCardProps>;
228
+ export const AtomicText: React.FC<AtomicTextProps>;
229
+ export const ScreenLayout: React.FC<ScreenLayoutProps>;
230
+
231
+ export const STATIC_TOKENS: {
232
+ spacing: {
233
+ xs: number;
234
+ sm: number;
235
+ md: number;
236
+ lg: number;
237
+ xl: number;
238
+ };
239
+ };
240
+
241
+ export interface DesignTokens {
242
+ colors: {
243
+ primary: string;
244
+ textPrimary: string;
245
+ textSecondary: string;
246
+ surface: string;
247
+ surfaceSecondary: string;
248
+ };
249
+ }
250
+ }
251
+
252
+ declare module '@umituz/react-native-design-system-theme' {
253
+ export function useAppDesignTokens(): import('@umituz/react-native-design-system').DesignTokens;
254
+ }
255
+