@umituz/react-native-notifications 1.0.5 → 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 (72) hide show
  1. package/lib/index.d.ts +1 -0
  2. package/lib/index.d.ts.map +1 -1
  3. package/lib/index.js +5 -0
  4. package/lib/index.js.map +1 -1
  5. package/lib/infrastructure/hooks/actions/useNotificationActions.d.ts +4 -13
  6. package/lib/infrastructure/hooks/actions/useNotificationActions.d.ts.map +1 -1
  7. package/lib/infrastructure/hooks/actions/useNotificationActions.js +4 -70
  8. package/lib/infrastructure/hooks/actions/useNotificationActions.js.map +1 -1
  9. package/lib/infrastructure/hooks/actions/useNotificationManagementActions.d.ts +8 -0
  10. package/lib/infrastructure/hooks/actions/useNotificationManagementActions.d.ts.map +1 -0
  11. package/lib/infrastructure/hooks/actions/useNotificationManagementActions.js +78 -0
  12. package/lib/infrastructure/hooks/actions/useNotificationManagementActions.js.map +1 -0
  13. package/lib/infrastructure/hooks/state/useNotificationsState.d.ts +8 -8
  14. package/lib/infrastructure/hooks/useNotificationSettings.d.ts +2 -2
  15. package/lib/infrastructure/hooks/useNotifications.d.ts +21 -1
  16. package/lib/infrastructure/hooks/useNotifications.d.ts.map +1 -1
  17. package/lib/infrastructure/hooks/useNotifications.js +30 -9
  18. package/lib/infrastructure/hooks/useNotifications.js.map +1 -1
  19. package/lib/infrastructure/hooks/utils/useNotificationRefresh.d.ts +5 -10
  20. package/lib/infrastructure/hooks/utils/useNotificationRefresh.d.ts.map +1 -1
  21. package/lib/infrastructure/hooks/utils/useNotificationRefresh.js +32 -15
  22. package/lib/infrastructure/hooks/utils/useNotificationRefresh.js.map +1 -1
  23. package/lib/infrastructure/services/NotificationBadgeManager.d.ts +5 -0
  24. package/lib/infrastructure/services/NotificationBadgeManager.d.ts.map +1 -0
  25. package/lib/infrastructure/services/NotificationBadgeManager.js +29 -0
  26. package/lib/infrastructure/services/NotificationBadgeManager.js.map +1 -0
  27. package/lib/infrastructure/services/NotificationManager.d.ts +5 -84
  28. package/lib/infrastructure/services/NotificationManager.d.ts.map +1 -1
  29. package/lib/infrastructure/services/NotificationManager.js +36 -203
  30. package/lib/infrastructure/services/NotificationManager.js.map +1 -1
  31. package/lib/infrastructure/services/NotificationPermissions.d.ts +6 -0
  32. package/lib/infrastructure/services/NotificationPermissions.d.ts.map +1 -0
  33. package/lib/infrastructure/services/NotificationPermissions.js +75 -0
  34. package/lib/infrastructure/services/NotificationPermissions.js.map +1 -0
  35. package/lib/infrastructure/services/NotificationScheduler.d.ts +8 -0
  36. package/lib/infrastructure/services/NotificationScheduler.d.ts.map +1 -0
  37. package/lib/infrastructure/services/NotificationScheduler.js +72 -0
  38. package/lib/infrastructure/services/NotificationScheduler.js.map +1 -0
  39. package/lib/infrastructure/services/delivery/NotificationDelivery.d.ts +2 -8
  40. package/lib/infrastructure/services/delivery/NotificationDelivery.d.ts.map +1 -1
  41. package/lib/infrastructure/services/delivery/NotificationDelivery.js +27 -13
  42. package/lib/infrastructure/services/delivery/NotificationDelivery.js.map +1 -1
  43. package/lib/infrastructure/storage/NotificationsStore.d.ts +8 -1
  44. package/lib/infrastructure/storage/NotificationsStore.d.ts.map +1 -1
  45. package/lib/infrastructure/storage/NotificationsStore.js +2 -1
  46. package/lib/infrastructure/storage/NotificationsStore.js.map +1 -1
  47. package/lib/infrastructure/utils/dev.d.ts +5 -0
  48. package/lib/infrastructure/utils/dev.d.ts.map +1 -0
  49. package/lib/infrastructure/utils/dev.js +24 -0
  50. package/lib/infrastructure/utils/dev.js.map +1 -0
  51. package/lib/presentation/screens/NotificationsScreen.d.ts +14 -4
  52. package/lib/presentation/screens/NotificationsScreen.d.ts.map +1 -1
  53. package/lib/presentation/screens/NotificationsScreen.js +12 -15
  54. package/lib/presentation/screens/NotificationsScreen.js.map +1 -1
  55. package/package.json +2 -2
  56. package/src/__tests__/NotificationManager.test.ts +215 -0
  57. package/src/__tests__/useNotificationActions.test.ts +189 -0
  58. package/src/__tests__/useNotificationRefresh.test.ts +213 -0
  59. package/src/index.ts +7 -0
  60. package/src/infrastructure/hooks/actions/useNotificationActions.ts +8 -110
  61. package/src/infrastructure/hooks/actions/useNotificationManagementActions.ts +131 -0
  62. package/src/infrastructure/hooks/useNotifications.ts +37 -11
  63. package/src/infrastructure/hooks/utils/useNotificationRefresh.ts +40 -16
  64. package/src/infrastructure/services/NotificationBadgeManager.ts +28 -0
  65. package/src/infrastructure/services/NotificationManager.ts +51 -217
  66. package/src/infrastructure/services/NotificationPermissions.ts +80 -0
  67. package/src/infrastructure/services/NotificationScheduler.ts +77 -0
  68. package/src/infrastructure/services/delivery/NotificationDelivery.ts +32 -14
  69. package/src/infrastructure/storage/NotificationsStore.ts +3 -2
  70. package/src/infrastructure/utils/dev.ts +25 -0
  71. package/src/presentation/screens/NotificationsScreen.tsx +31 -18
  72. package/src/types/global.d.ts +255 -0
@@ -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
+