@umituz/react-native-notifications 1.1.2 → 1.1.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.
package/lib/index.d.ts CHANGED
@@ -11,4 +11,6 @@ export { NotificationService, notificationService } from './infrastructure/servi
11
11
  export { NotificationManager } from './infrastructure/services/NotificationManager';
12
12
  export { useNotificationSettings } from './infrastructure/hooks/useNotificationSettings';
13
13
  export { NotificationsScreen } from './presentation/screens/NotificationsScreen';
14
+ export { NotificationsSection } from './presentation/components/NotificationsSection';
15
+ export type { NotificationsSectionProps, NotificationsSectionConfig } from './presentation/components/NotificationsSection';
14
16
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH,YAAY,EACV,mBAAmB,EACnB,2BAA2B,EAC3B,qBAAqB,GACtB,MAAM,iCAAiC,CAAC;AAGzC,OAAO,EAAE,mBAAmB,EAAE,MAAM,6CAA6C,CAAC;AAClF,YAAY,EACV,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,6CAA6C,CAAC;AAGrD,OAAO,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,6CAA6C,CAAC;AAGtG,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,+CAA+C,CAAC;AACzG,OAAO,EAAE,mBAAmB,EAAE,MAAM,+CAA+C,CAAC;AAGpF,OAAO,EAAE,uBAAuB,EAAE,MAAM,gDAAgD,CAAC;AAOzF,OAAO,EAAE,mBAAmB,EAAE,MAAM,4CAA4C,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH,YAAY,EACV,mBAAmB,EACnB,2BAA2B,EAC3B,qBAAqB,GACtB,MAAM,iCAAiC,CAAC;AAGzC,OAAO,EAAE,mBAAmB,EAAE,MAAM,6CAA6C,CAAC;AAClF,YAAY,EACV,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,6CAA6C,CAAC;AAGrD,OAAO,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,6CAA6C,CAAC;AAGtG,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,+CAA+C,CAAC;AACzG,OAAO,EAAE,mBAAmB,EAAE,MAAM,+CAA+C,CAAC;AAGpF,OAAO,EAAE,uBAAuB,EAAE,MAAM,gDAAgD,CAAC;AAQzF,OAAO,EAAE,mBAAmB,EAAE,MAAM,4CAA4C,CAAC;AAGjF,OAAO,EAAE,oBAAoB,EAAE,MAAM,gDAAgD,CAAC;AACtF,YAAY,EAAE,yBAAyB,EAAE,0BAA0B,EAAE,MAAM,gDAAgD,CAAC"}
package/lib/index.js CHANGED
@@ -16,5 +16,8 @@ export { useNotificationSettings } from './infrastructure/hooks/useNotificationS
16
16
  // PRESENTATION LAYER EXPORTS
17
17
  // ============================================================================
18
18
  // Screens
19
+ // Screens
19
20
  export { NotificationsScreen } from './presentation/screens/NotificationsScreen';
21
+ // Components
22
+ export { NotificationsSection } from './presentation/components/NotificationsSection';
20
23
  //# sourceMappingURL=index.js.map
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAaH,gBAAgB;AAChB,OAAO,EAAE,mBAAmB,EAAE,MAAM,6CAA6C,CAAC;AAOlF,wBAAwB;AACxB,OAAO,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,6CAA6C,CAAC;AAEtG,WAAW;AACX,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,+CAA+C,CAAC;AACzG,OAAO,EAAE,mBAAmB,EAAE,MAAM,+CAA+C,CAAC;AAEpF,QAAQ;AACR,OAAO,EAAE,uBAAuB,EAAE,MAAM,gDAAgD,CAAC;AAEzF,+EAA+E;AAC/E,6BAA6B;AAC7B,+EAA+E;AAE/E,UAAU;AACV,OAAO,EAAE,mBAAmB,EAAE,MAAM,4CAA4C,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAaH,gBAAgB;AAChB,OAAO,EAAE,mBAAmB,EAAE,MAAM,6CAA6C,CAAC;AAOlF,wBAAwB;AACxB,OAAO,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,6CAA6C,CAAC;AAEtG,WAAW;AACX,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,+CAA+C,CAAC;AACzG,OAAO,EAAE,mBAAmB,EAAE,MAAM,+CAA+C,CAAC;AAEpF,QAAQ;AACR,OAAO,EAAE,uBAAuB,EAAE,MAAM,gDAAgD,CAAC;AAEzF,+EAA+E;AAC/E,6BAA6B;AAC7B,+EAA+E;AAE/E,UAAU;AACV,UAAU;AACV,OAAO,EAAE,mBAAmB,EAAE,MAAM,4CAA4C,CAAC;AAEjF,aAAa;AACb,OAAO,EAAE,oBAAoB,EAAE,MAAM,gDAAgD,CAAC"}
@@ -0,0 +1,17 @@
1
+ import React from 'react';
2
+ import { ViewStyle } from 'react-native';
3
+ export interface NotificationsSectionConfig {
4
+ initialValue?: boolean;
5
+ onToggleChange?: (value: boolean) => void;
6
+ route?: string;
7
+ defaultRoute?: string;
8
+ title?: string;
9
+ description?: string;
10
+ showToggle?: boolean;
11
+ }
12
+ export interface NotificationsSectionProps {
13
+ config?: NotificationsSectionConfig;
14
+ containerStyle?: ViewStyle;
15
+ }
16
+ export declare const NotificationsSection: React.FC<NotificationsSectionProps>;
17
+ //# sourceMappingURL=NotificationsSection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NotificationsSection.d.ts","sourceRoot":"","sources":["../../../src/presentation/components/NotificationsSection.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA2C,MAAM,OAAO,CAAC;AAChE,OAAO,EAA6C,SAAS,EAAE,MAAM,cAAc,CAAC;AAMpF,MAAM,WAAW,0BAA0B;IACvC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IAC1C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,yBAAyB;IACtC,MAAM,CAAC,EAAE,0BAA0B,CAAC;IACpC,cAAc,CAAC,EAAE,SAAS,CAAC;CAC9B;AAED,eAAO,MAAM,oBAAoB,EAAE,KAAK,CAAC,EAAE,CAAC,yBAAyB,CAgHpE,CAAC"}
@@ -0,0 +1,132 @@
1
+ import React, { useState, useEffect, useCallback } from 'react';
2
+ import { View, Text, Pressable, StyleSheet, Switch } from 'react-native';
3
+ import { Feather } from '@expo/vector-icons';
4
+ import { useNavigation } from '@react-navigation/native';
5
+ import { useAppDesignTokens } from '@umituz/react-native-design-system-theme';
6
+ import { notificationService } from '../../infrastructure/services/NotificationService';
7
+ export const NotificationsSection = ({ config, containerStyle, }) => {
8
+ const navigation = useNavigation();
9
+ const tokens = useAppDesignTokens();
10
+ const colors = tokens.colors;
11
+ const [notificationsEnabled, setNotificationsEnabled] = useState(config?.initialValue ?? true);
12
+ useEffect(() => {
13
+ if (config?.initialValue !== undefined) {
14
+ setNotificationsEnabled(config.initialValue);
15
+ }
16
+ }, [config?.initialValue]);
17
+ const handleToggle = useCallback(async (value) => {
18
+ if (!value) {
19
+ // When turning ON (value is false -> true? Wait. onChange value is the NEW value)
20
+ // If value is true (turning on)
21
+ }
22
+ // Logic from settings:
23
+ /*
24
+ if (notificationService && !value) { // Wait, logic in settings was: if (!value) ...?
25
+ // Actually typically we request permissions when enabling.
26
+ // Settings code:
27
+ // if (notificationService && !value) { ... } -> This implies when value is FALSE?
28
+ // Ah, maybe the switch value logic was inverted or I misread.
29
+ // Let's re-read settings code.
30
+ }
31
+ */
32
+ if (value) { // Enabling
33
+ const hasPermissions = await notificationService.hasPermissions();
34
+ if (!hasPermissions) {
35
+ const granted = await notificationService.requestPermissions();
36
+ if (!granted) {
37
+ // Permission denied, maybe don't enable switch?
38
+ // For now just allow toggle and let app handle it or sync with state
39
+ }
40
+ }
41
+ }
42
+ setNotificationsEnabled(value);
43
+ config?.onToggleChange?.(value);
44
+ }, [config]);
45
+ const handlePress = useCallback(async () => {
46
+ const hasPermissions = await notificationService.hasPermissions();
47
+ if (!hasPermissions) {
48
+ await notificationService.requestPermissions();
49
+ }
50
+ navigation.navigate((config?.route || config?.defaultRoute || 'Notifications'));
51
+ }, [navigation, config?.route, config?.defaultRoute]);
52
+ const title = config?.title || 'Notifications';
53
+ const description = config?.description || 'Manage notification preferences';
54
+ const showToggle = config?.showToggle ?? true;
55
+ return (<View style={[styles.sectionContainer, { backgroundColor: colors.surface }, containerStyle]}>
56
+ <Text style={[styles.sectionTitle, { color: colors.textPrimary }]}>General</Text>
57
+
58
+ <Pressable style={({ pressed }) => [
59
+ styles.itemContainer,
60
+ {
61
+ backgroundColor: pressed && !showToggle ? `${colors.primary}08` : 'transparent',
62
+ },
63
+ ]} onPress={showToggle ? undefined : handlePress} disabled={showToggle}>
64
+ <View style={styles.content}>
65
+ <View style={[
66
+ styles.iconContainer,
67
+ { backgroundColor: `${colors.primary}15` },
68
+ ]}>
69
+ <Feather name="bell" size={24} color={colors.primary}/>
70
+ </View>
71
+ <View style={styles.textContainer}>
72
+ <Text style={[styles.title, { color: colors.textPrimary }]}>{title}</Text>
73
+ {!showToggle && (<Text style={[styles.description, { color: colors.textSecondary }]}>
74
+ {description}
75
+ </Text>)}
76
+ </View>
77
+
78
+ {showToggle ? (<Switch value={notificationsEnabled} onValueChange={handleToggle} trackColor={{
79
+ false: `${colors.textSecondary}30`,
80
+ true: colors.primary,
81
+ }} thumbColor={"#FFFFFF"} ios_backgroundColor={`${colors.textSecondary}30`}/>) : (<Feather name="chevron-right" size={20} color={colors.textSecondary}/>)}
82
+ </View>
83
+ </Pressable>
84
+ </View>);
85
+ };
86
+ const styles = StyleSheet.create({
87
+ sectionContainer: {
88
+ marginBottom: 16,
89
+ borderRadius: 12,
90
+ overflow: 'hidden',
91
+ },
92
+ sectionTitle: {
93
+ fontSize: 18,
94
+ fontWeight: '600',
95
+ paddingHorizontal: 16,
96
+ paddingTop: 16,
97
+ paddingBottom: 8,
98
+ },
99
+ itemContainer: {
100
+ flexDirection: 'row',
101
+ alignItems: 'center',
102
+ paddingHorizontal: 16,
103
+ paddingVertical: 16,
104
+ minHeight: 72,
105
+ },
106
+ content: {
107
+ flex: 1,
108
+ flexDirection: 'row',
109
+ alignItems: 'center',
110
+ },
111
+ iconContainer: {
112
+ width: 48,
113
+ height: 48,
114
+ borderRadius: 12,
115
+ justifyContent: 'center',
116
+ alignItems: 'center',
117
+ marginRight: 16,
118
+ },
119
+ textContainer: {
120
+ flex: 1,
121
+ marginRight: 8,
122
+ },
123
+ title: {
124
+ fontSize: 16,
125
+ fontWeight: '500',
126
+ marginBottom: 4,
127
+ },
128
+ description: {
129
+ fontSize: 14,
130
+ },
131
+ });
132
+ //# sourceMappingURL=NotificationsSection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NotificationsSection.js","sourceRoot":"","sources":["../../../src/presentation/components/NotificationsSection.tsx"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@umituz/react-native-notifications",
3
- "version": "1.1.2",
3
+ "version": "1.1.4",
4
4
  "description": "Offline-first local notifications system for React Native apps using expo-notifications",
5
5
  "main": "./lib/index.js",
6
6
  "types": "./lib/index.d.ts",
@@ -41,12 +41,14 @@
41
41
  "zustand": "^5.0.2"
42
42
  },
43
43
  "devDependencies": {
44
+ "@expo/vector-icons": "^15.0.3",
44
45
  "@react-native-async-storage/async-storage": "^1.21.0",
46
+ "@react-navigation/native": "^7.1.25",
45
47
  "@types/react": "^18.2.45",
46
48
  "@types/react-native": "^0.73.0",
47
49
  "@umituz/react-native-design-system": "^1.5.28",
48
- "@umituz/react-native-design-system-theme": "latest",
49
50
  "@umituz/react-native-design-system-atoms": "*",
51
+ "@umituz/react-native-design-system-theme": "^1.8.0",
50
52
  "expo-device": "~6.0.2",
51
53
  "expo-notifications": "~0.28.0",
52
54
  "react": "^18.2.0",
@@ -65,7 +67,6 @@
65
67
  ],
66
68
  "dependencies": {
67
69
  "@react-native-community/datetimepicker": "^8.5.0",
68
- "@react-navigation/native": "^7.1.19",
69
70
  "@umituz/react-native-design-system-atoms": "*",
70
71
  "expo-linear-gradient": "^15.0.7",
71
72
  "react-native-safe-area-context": "^5.6.2"
package/src/index.ts CHANGED
@@ -37,5 +37,10 @@ export { useNotificationSettings } from './infrastructure/hooks/useNotificationS
37
37
  // PRESENTATION LAYER EXPORTS
38
38
  // ============================================================================
39
39
 
40
+ // Screens
40
41
  // Screens
41
42
  export { NotificationsScreen } from './presentation/screens/NotificationsScreen';
43
+
44
+ // Components
45
+ export { NotificationsSection } from './presentation/components/NotificationsSection';
46
+ export type { NotificationsSectionProps, NotificationsSectionConfig } from './presentation/components/NotificationsSection';
@@ -0,0 +1,182 @@
1
+ import React, { useState, useEffect, useCallback } from 'react';
2
+ import { View, Text, Pressable, StyleSheet, Switch, ViewStyle } from 'react-native';
3
+ import { Feather } from '@expo/vector-icons';
4
+ import { useNavigation } from '@react-navigation/native';
5
+ import { useAppDesignTokens } from '@umituz/react-native-design-system-theme';
6
+ import { notificationService } from '../../infrastructure/services/NotificationService';
7
+
8
+ export interface NotificationsSectionConfig {
9
+ initialValue?: boolean;
10
+ onToggleChange?: (value: boolean) => void;
11
+ route?: string;
12
+ defaultRoute?: string;
13
+ title?: string;
14
+ description?: string;
15
+ showToggle?: boolean;
16
+ }
17
+
18
+ export interface NotificationsSectionProps {
19
+ config?: NotificationsSectionConfig;
20
+ containerStyle?: ViewStyle;
21
+ }
22
+
23
+ export const NotificationsSection: React.FC<NotificationsSectionProps> = ({
24
+ config,
25
+ containerStyle,
26
+ }) => {
27
+ const navigation = useNavigation();
28
+ const tokens = useAppDesignTokens();
29
+ const colors = tokens.colors;
30
+
31
+ const [notificationsEnabled, setNotificationsEnabled] = useState(
32
+ config?.initialValue ?? true,
33
+ );
34
+
35
+ useEffect(() => {
36
+ if (config?.initialValue !== undefined) {
37
+ setNotificationsEnabled(config.initialValue);
38
+ }
39
+ }, [config?.initialValue]);
40
+
41
+ const handleToggle = useCallback(async (value: boolean) => {
42
+ if (!value) {
43
+ // When turning ON (value is false -> true? Wait. onChange value is the NEW value)
44
+ // If value is true (turning on)
45
+ }
46
+
47
+ // Logic from settings:
48
+ /*
49
+ if (notificationService && !value) { // Wait, logic in settings was: if (!value) ...?
50
+ // Actually typically we request permissions when enabling.
51
+ // Settings code:
52
+ // if (notificationService && !value) { ... } -> This implies when value is FALSE?
53
+ // Ah, maybe the switch value logic was inverted or I misread.
54
+ // Let's re-read settings code.
55
+ }
56
+ */
57
+
58
+ if (value) { // Enabling
59
+ const hasPermissions = await notificationService.hasPermissions();
60
+ if (!hasPermissions) {
61
+ const granted = await notificationService.requestPermissions();
62
+ if (!granted) {
63
+ // Permission denied, maybe don't enable switch?
64
+ // For now just allow toggle and let app handle it or sync with state
65
+ }
66
+ }
67
+ }
68
+
69
+ setNotificationsEnabled(value);
70
+ config?.onToggleChange?.(value);
71
+ }, [config]);
72
+
73
+ const handlePress = useCallback(async () => {
74
+ const hasPermissions = await notificationService.hasPermissions();
75
+ if (!hasPermissions) {
76
+ await notificationService.requestPermissions();
77
+ }
78
+ navigation.navigate((config?.route || config?.defaultRoute || 'Notifications') as never);
79
+ }, [navigation, config?.route, config?.defaultRoute]);
80
+
81
+ const title = config?.title || 'Notifications';
82
+ const description = config?.description || 'Manage notification preferences';
83
+ const showToggle = config?.showToggle ?? true;
84
+
85
+ return (
86
+ <View style={[styles.sectionContainer, { backgroundColor: colors.surface }, containerStyle]}>
87
+ <Text style={[styles.sectionTitle, { color: colors.textPrimary }]}>General</Text>
88
+
89
+ <Pressable
90
+ style={({ pressed }) => [
91
+ styles.itemContainer,
92
+ {
93
+ backgroundColor: pressed && !showToggle ? `${colors.primary}08` : 'transparent',
94
+ },
95
+ ]}
96
+ onPress={showToggle ? undefined : handlePress}
97
+ disabled={showToggle}
98
+ >
99
+ <View style={styles.content}>
100
+ <View
101
+ style={[
102
+ styles.iconContainer,
103
+ { backgroundColor: `${colors.primary}15` },
104
+ ]}
105
+ >
106
+ <Feather name="bell" size={24} color={colors.primary} />
107
+ </View>
108
+ <View style={styles.textContainer}>
109
+ <Text style={[styles.title, { color: colors.textPrimary }]}>{title}</Text>
110
+ {!showToggle && (
111
+ <Text style={[styles.description, { color: colors.textSecondary }]}>
112
+ {description}
113
+ </Text>
114
+ )}
115
+ </View>
116
+
117
+ {showToggle ? (
118
+ <Switch
119
+ value={notificationsEnabled}
120
+ onValueChange={handleToggle}
121
+ trackColor={{
122
+ false: `${colors.textSecondary}30`,
123
+ true: colors.primary,
124
+ }}
125
+ thumbColor={"#FFFFFF"}
126
+ ios_backgroundColor={`${colors.textSecondary}30`}
127
+ />
128
+ ) : (
129
+ <Feather name="chevron-right" size={20} color={colors.textSecondary} />
130
+ )}
131
+ </View>
132
+ </Pressable>
133
+ </View>
134
+ );
135
+ };
136
+
137
+ const styles = StyleSheet.create({
138
+ sectionContainer: {
139
+ marginBottom: 16,
140
+ borderRadius: 12,
141
+ overflow: 'hidden',
142
+ },
143
+ sectionTitle: {
144
+ fontSize: 18,
145
+ fontWeight: '600',
146
+ paddingHorizontal: 16,
147
+ paddingTop: 16,
148
+ paddingBottom: 8,
149
+ },
150
+ itemContainer: {
151
+ flexDirection: 'row',
152
+ alignItems: 'center',
153
+ paddingHorizontal: 16,
154
+ paddingVertical: 16,
155
+ minHeight: 72,
156
+ },
157
+ content: {
158
+ flex: 1,
159
+ flexDirection: 'row',
160
+ alignItems: 'center',
161
+ },
162
+ iconContainer: {
163
+ width: 48,
164
+ height: 48,
165
+ borderRadius: 12,
166
+ justifyContent: 'center',
167
+ alignItems: 'center',
168
+ marginRight: 16,
169
+ },
170
+ textContainer: {
171
+ flex: 1,
172
+ marginRight: 8,
173
+ },
174
+ title: {
175
+ fontSize: 16,
176
+ fontWeight: '500',
177
+ marginBottom: 4,
178
+ },
179
+ description: {
180
+ fontSize: 14,
181
+ },
182
+ });