@trycourier/courier-react-native 5.4.2 → 5.5.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 (113) hide show
  1. package/android/build.gradle +2 -2
  2. package/android/src/main/java/com/courierreactnative/CourierSharedModule.kt +41 -42
  3. package/android/src/main/java/com/courierreactnative/Utils.kt +1 -1
  4. package/courier-react-native.podspec +1 -1
  5. package/ios/CourierReactNativeDelegate.m +12 -8
  6. package/ios/CourierReactNativeEventEmitter.swift +1 -1
  7. package/ios/CourierReactNativeModule.m +3 -5
  8. package/ios/CourierSharedModule.swift +88 -112
  9. package/lib/commonjs/index.js +75 -93
  10. package/lib/commonjs/index.js.map +1 -1
  11. package/lib/commonjs/models/CourierInboxListener.js +1 -0
  12. package/lib/commonjs/models/CourierInboxListener.js.map +1 -1
  13. package/lib/commonjs/models/InboxAction.js +22 -0
  14. package/lib/commonjs/models/InboxAction.js.map +1 -1
  15. package/lib/commonjs/models/InboxMessage.js +64 -0
  16. package/lib/commonjs/models/InboxMessage.js.map +1 -1
  17. package/lib/commonjs/models/InboxMessageEvent.js +2 -0
  18. package/lib/commonjs/models/InboxMessageEvent.js.map +1 -0
  19. package/lib/commonjs/views/CourierInboxView.js +6 -4
  20. package/lib/commonjs/views/CourierInboxView.js.map +1 -1
  21. package/lib/example/src/App.js +11 -0
  22. package/lib/example/src/Emitter.js +11 -0
  23. package/lib/example/src/Env.js +6 -0
  24. package/lib/example/src/Home.js +67 -0
  25. package/lib/example/src/Poke.js +75 -0
  26. package/lib/example/src/Tabs.js +36 -0
  27. package/lib/example/src/Utils.js +71 -0
  28. package/lib/example/src/pages/Auth.js +224 -0
  29. package/lib/example/src/pages/Inbox.js +38 -0
  30. package/lib/example/src/pages/Preferences.js +13 -0
  31. package/lib/example/src/pages/PreferencesStack.js +11 -0
  32. package/lib/example/src/pages/Push.js +93 -0
  33. package/lib/example/src/pages/Styles.js +26 -0
  34. package/lib/example/src/pages/Tests.js +1068 -0
  35. package/lib/example/src/pages/inbox/InboxCustom.js +141 -0
  36. package/lib/example/src/pages/inbox/InboxDefault.js +22 -0
  37. package/lib/example/src/pages/inbox/InboxStyled.js +220 -0
  38. package/lib/example/src/pages/preferences/PreferencesCustom.js +91 -0
  39. package/lib/example/src/pages/preferences/PreferencesDefault.js +17 -0
  40. package/lib/example/src/pages/preferences/PreferencesDetail.js +127 -0
  41. package/lib/example/src/pages/preferences/PreferencesStyled.js +110 -0
  42. package/lib/module/index.js +67 -90
  43. package/lib/module/index.js.map +1 -1
  44. package/lib/module/models/CourierInboxListener.js +1 -0
  45. package/lib/module/models/CourierInboxListener.js.map +1 -1
  46. package/lib/module/models/InboxAction.js +16 -1
  47. package/lib/module/models/InboxAction.js.map +1 -1
  48. package/lib/module/models/InboxMessage.js +61 -1
  49. package/lib/module/models/InboxMessage.js.map +1 -1
  50. package/lib/module/models/InboxMessageEvent.js +2 -0
  51. package/lib/module/models/InboxMessageEvent.js.map +1 -0
  52. package/lib/module/views/CourierInboxView.js +6 -4
  53. package/lib/module/views/CourierInboxView.js.map +1 -1
  54. package/lib/package.json +171 -0
  55. package/lib/src/Broadcaster.js +24 -0
  56. package/lib/src/Modules.js +26 -0
  57. package/lib/src/client/BrandClient.js +17 -0
  58. package/lib/src/client/ClientModule.js +14 -0
  59. package/lib/src/client/CourierClient.js +31 -0
  60. package/lib/src/client/InboxClient.js +99 -0
  61. package/lib/src/client/PreferenceClient.js +63 -0
  62. package/lib/src/client/TokenClient.js +27 -0
  63. package/lib/src/client/TrackingClient.js +17 -0
  64. package/lib/src/index.js +567 -0
  65. package/lib/src/models/Android_CourierSheet.js +1 -0
  66. package/lib/src/models/CourierAuthenticationListener.js +14 -0
  67. package/lib/src/models/CourierBrand.js +1 -0
  68. package/lib/src/models/CourierButton.js +1 -0
  69. package/lib/src/models/CourierDevice.js +1 -0
  70. package/lib/src/models/CourierFont.js +1 -0
  71. package/lib/src/models/CourierInboxListener.js +20 -0
  72. package/lib/src/models/CourierInboxMessages.js +1 -0
  73. package/lib/src/models/CourierInboxTheme.js +1 -0
  74. package/lib/src/models/CourierInfoViewStyle.js +1 -0
  75. package/lib/src/models/CourierPaging.js +1 -0
  76. package/lib/src/models/CourierPreferencesTheme.js +1 -0
  77. package/lib/src/models/CourierPushListener.js +14 -0
  78. package/lib/src/models/CourierPushProvider.js +8 -0
  79. package/lib/src/models/CourierTrackingEvent.js +8 -0
  80. package/lib/src/models/CourierUserPreferences.js +51 -0
  81. package/lib/src/models/InboxAction.js +1 -0
  82. package/lib/src/models/InboxMessage.js +1 -0
  83. package/lib/src/models/InboxMessageFeed.js +1 -0
  84. package/lib/src/models/InboxMessageSet.js +1 -0
  85. package/lib/src/models/iOS_CourierCell.js +1 -0
  86. package/lib/src/models/iOS_CourierSheet.js +1 -0
  87. package/lib/src/utils.js +27 -0
  88. package/lib/src/views/CourierInboxView.js +75 -0
  89. package/lib/src/views/CourierPreferencesView.js +33 -0
  90. package/lib/typescript/src/index.d.ts +16 -20
  91. package/lib/typescript/src/index.d.ts.map +1 -1
  92. package/lib/typescript/src/models/CourierInboxListener.d.ts +4 -7
  93. package/lib/typescript/src/models/CourierInboxListener.d.ts.map +1 -1
  94. package/lib/typescript/src/models/InboxAction.d.ts +8 -4
  95. package/lib/typescript/src/models/InboxAction.d.ts.map +1 -1
  96. package/lib/typescript/src/models/InboxMessage.d.ts +28 -14
  97. package/lib/typescript/src/models/InboxMessage.d.ts.map +1 -1
  98. package/lib/typescript/src/models/InboxMessageEvent.d.ts +2 -0
  99. package/lib/typescript/src/models/InboxMessageEvent.d.ts.map +1 -0
  100. package/lib/typescript/src/models/InboxMessageFeed.d.ts +1 -1
  101. package/lib/typescript/src/models/InboxMessageFeed.d.ts.map +1 -1
  102. package/package.json +3 -2
  103. package/src/index.tsx +61 -99
  104. package/src/models/CourierInboxListener.tsx +10 -13
  105. package/src/models/InboxAction.tsx +28 -4
  106. package/src/models/InboxMessage.tsx +102 -14
  107. package/src/models/InboxMessageEvent.tsx +1 -0
  108. package/src/models/InboxMessageFeed.tsx +1 -1
  109. package/src/views/CourierInboxView.tsx +4 -4
  110. package/ios/CourierReactNative.xcodeproj/project.xcworkspace/contents.xcworkspacedata +0 -7
  111. package/ios/CourierReactNative.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +0 -8
  112. package/ios/CourierReactNative.xcodeproj/project.xcworkspace/xcuserdata/mike.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  113. package/ios/CourierReactNative.xcodeproj/xcuserdata/mike.xcuserdatad/xcschemes/xcschememanagement.plist +0 -14
@@ -0,0 +1,141 @@
1
+ import Courier from '@trycourier/courier-react-native';
2
+ import React, { useEffect, useState } from 'react';
3
+ import { View, Text, FlatList, StyleSheet, TouchableOpacity, RefreshControl, ActivityIndicator, Platform } from 'react-native';
4
+ const InboxCustom = () => {
5
+ const [isRefreshing, setIsRefreshing] = useState(false);
6
+ const [isLoading, setIsLoading] = useState(false);
7
+ const [error, setError] = useState(null);
8
+ const [messages, setMessages] = useState([]);
9
+ const [canPaginate, setCanPaginate] = useState(false);
10
+ useEffect(() => {
11
+ const initInbox = async () => {
12
+ await Courier.shared.setInboxPaginationLimit(100);
13
+ const inboxListener = await Courier.shared.addInboxListener({
14
+ onInitialLoad(isRefresh) {
15
+ if (isRefresh) {
16
+ setIsRefreshing(true);
17
+ }
18
+ else {
19
+ setIsLoading(true);
20
+ }
21
+ },
22
+ onError(error) {
23
+ setIsLoading(false);
24
+ setError(error);
25
+ },
26
+ onFeedChanged(messageSet) {
27
+ setIsLoading(false);
28
+ setError(null);
29
+ setMessages(messageSet.messages);
30
+ setCanPaginate(messageSet.canPaginate);
31
+ },
32
+ onMessageChanged(feed, index, message) {
33
+ if (feed === 'feed') {
34
+ setMessages(prevMessages => {
35
+ const newMessages = [...prevMessages];
36
+ newMessages[index] = message;
37
+ return newMessages;
38
+ });
39
+ }
40
+ },
41
+ onMessageAdded(feed, index, message) {
42
+ if (feed === 'feed') {
43
+ setMessages(prevMessages => {
44
+ const newMessages = [...prevMessages];
45
+ newMessages.splice(index, 0, message);
46
+ return newMessages;
47
+ });
48
+ }
49
+ },
50
+ onMessageRemoved(feed, index) {
51
+ if (feed === 'feed') {
52
+ setMessages(prevMessages => {
53
+ const newMessages = [...prevMessages];
54
+ newMessages.splice(index, 1);
55
+ return newMessages;
56
+ });
57
+ }
58
+ },
59
+ onPageAdded(feed, messageSet) {
60
+ if (feed === 'feed') {
61
+ setMessages(prevMessages => [...prevMessages, ...messageSet.messages]);
62
+ setCanPaginate(messageSet.canPaginate);
63
+ }
64
+ }
65
+ });
66
+ return inboxListener;
67
+ };
68
+ let inboxListener;
69
+ initInbox().then(listener => {
70
+ inboxListener = listener;
71
+ });
72
+ return () => {
73
+ if (inboxListener) {
74
+ inboxListener.remove();
75
+ }
76
+ };
77
+ }, []);
78
+ const ListItem = (props) => {
79
+ const styles = StyleSheet.create({
80
+ container: {
81
+ padding: 20,
82
+ borderBottomWidth: 1,
83
+ borderBottomColor: '#ccc',
84
+ },
85
+ unread: {
86
+ backgroundColor: 'red'
87
+ },
88
+ text: {
89
+ width: Platform.OS === 'ios' ? undefined : '100%',
90
+ fontFamily: Platform.select({
91
+ ios: 'Courier',
92
+ android: 'monospace',
93
+ default: 'monospace',
94
+ }),
95
+ fontSize: 16,
96
+ },
97
+ });
98
+ const isRead = props.message.read;
99
+ async function toggleMessage() {
100
+ const messageId = props.message.messageId;
101
+ await Courier.shared.clickMessage({ messageId: messageId });
102
+ isRead ? await Courier.shared.unreadMessage({ messageId: messageId }) : await Courier.shared.readMessage({ messageId: messageId });
103
+ console.log(props.message);
104
+ }
105
+ return (React.createElement(TouchableOpacity, { style: [styles.container, isRead ? undefined : styles.unread], onPress: toggleMessage },
106
+ React.createElement(Text, { style: styles.text }, JSON.stringify(props.message, null, 2))));
107
+ };
108
+ const PaginationItem = () => {
109
+ return (React.createElement(View, { style: { paddingVertical: 20 } },
110
+ React.createElement(ActivityIndicator, { size: "small" })));
111
+ };
112
+ const refresh = async () => {
113
+ setIsRefreshing(true);
114
+ await Courier.shared.refreshInbox();
115
+ setIsRefreshing(false);
116
+ };
117
+ function buildContent() {
118
+ if (isLoading) {
119
+ return React.createElement(Text, null, "Loading");
120
+ }
121
+ if (error) {
122
+ return React.createElement(Text, null, error);
123
+ }
124
+ return (React.createElement(FlatList, { data: messages, keyExtractor: message => message.messageId, renderItem: message => React.createElement(ListItem, { message: message.item }), refreshControl: React.createElement(RefreshControl, { refreshing: isRefreshing, onRefresh: refresh }), ListFooterComponent: () => {
125
+ return canPaginate ? React.createElement(PaginationItem, null) : null;
126
+ }, onEndReached: () => {
127
+ if (canPaginate) {
128
+ Courier.shared.fetchNextPageOfMessages({ inboxMessageFeed: 'feed' });
129
+ }
130
+ } }));
131
+ }
132
+ const styles = StyleSheet.create({
133
+ container: {
134
+ flex: 1,
135
+ justifyContent: 'center',
136
+ alignItems: 'center',
137
+ },
138
+ });
139
+ return (React.createElement(View, { style: styles.container }, buildContent()));
140
+ };
141
+ export default InboxCustom;
@@ -0,0 +1,22 @@
1
+ import Courier, { CourierInboxView } from '@trycourier/courier-react-native';
2
+ import React from 'react';
3
+ import { View, StyleSheet } from 'react-native';
4
+ const InboxDefault = () => {
5
+ const styles = StyleSheet.create({
6
+ container: {
7
+ flex: 1,
8
+ },
9
+ box: {
10
+ width: '100%',
11
+ height: '100%',
12
+ },
13
+ });
14
+ return (React.createElement(View, { style: styles.container },
15
+ React.createElement(CourierInboxView, { onClickInboxMessageAtIndex: async (message, _index) => {
16
+ console.log('onClickInboxMessageAtIndex', message.read);
17
+ message.read ? await Courier.shared.unreadMessage({ messageId: message.messageId }) : await Courier.shared.readMessage({ messageId: message.messageId });
18
+ }, onClickInboxActionForMessageAtIndex: (action, _message, _index) => {
19
+ console.log(action);
20
+ }, style: styles.box })));
21
+ };
22
+ export default InboxDefault;
@@ -0,0 +1,220 @@
1
+ import Courier, { CourierInboxView } from '@trycourier/courier-react-native';
2
+ import React from 'react';
3
+ import { View, StyleSheet, ActionSheetIOS, Platform, Alert } from 'react-native';
4
+ import { Styles } from '../Styles';
5
+ import Env from '../../Env';
6
+ const InboxStyled = () => {
7
+ function getTheme(isDark) {
8
+ const styles = Styles(isDark);
9
+ return {
10
+ brandId: Env.brandId,
11
+ tabIndicatorColor: styles.Colors.action,
12
+ tabStyle: {
13
+ selected: {
14
+ font: {
15
+ family: styles.Fonts.title,
16
+ size: styles.TextSizes.title,
17
+ color: styles.Colors.heading
18
+ },
19
+ indicator: {
20
+ font: {
21
+ family: styles.Fonts.title,
22
+ size: 14,
23
+ color: '#FFFFFF'
24
+ },
25
+ color: styles.Colors.action
26
+ }
27
+ },
28
+ unselected: {
29
+ font: {
30
+ family: styles.Fonts.title,
31
+ size: styles.TextSizes.title,
32
+ color: styles.Colors.subtitle
33
+ },
34
+ indicator: {
35
+ font: {
36
+ family: styles.Fonts.title,
37
+ size: 14,
38
+ color: '#000000'
39
+ },
40
+ color: styles.Colors.subtitle
41
+ }
42
+ }
43
+ },
44
+ readingSwipeActionStyle: {
45
+ read: {
46
+ icon: Platform.OS === 'ios' ? 'icon_undo' : 'icon_undo',
47
+ color: styles.Colors.subtitle
48
+ },
49
+ unread: {
50
+ icon: Platform.OS === 'ios' ? 'icon_check' : 'icon_check',
51
+ color: styles.Colors.action
52
+ }
53
+ },
54
+ archivingSwipeActionStyle: {
55
+ archive: {
56
+ icon: Platform.OS === 'ios' ? 'icon_archive' : 'icon_archive',
57
+ color: styles.Colors.warning
58
+ }
59
+ },
60
+ unreadIndicatorStyle: {
61
+ indicator: 'dot',
62
+ color: styles.Colors.action
63
+ },
64
+ titleStyle: {
65
+ unread: {
66
+ family: styles.Fonts.title,
67
+ size: styles.TextSizes.title,
68
+ color: styles.Colors.title
69
+ },
70
+ read: {
71
+ family: styles.Fonts.title,
72
+ size: styles.TextSizes.title,
73
+ color: styles.Colors.subtitle
74
+ }
75
+ },
76
+ timeStyle: {
77
+ unread: {
78
+ family: styles.Fonts.subtitle,
79
+ size: styles.TextSizes.subtitle,
80
+ color: styles.Colors.title
81
+ },
82
+ read: {
83
+ family: styles.Fonts.subtitle,
84
+ size: styles.TextSizes.subtitle,
85
+ color: styles.Colors.subtitle
86
+ }
87
+ },
88
+ bodyStyle: {
89
+ unread: {
90
+ family: styles.Fonts.subtitle,
91
+ size: styles.TextSizes.subtitle,
92
+ color: styles.Colors.subtitle
93
+ },
94
+ read: {
95
+ family: styles.Fonts.subtitle,
96
+ size: styles.TextSizes.subtitle,
97
+ color: styles.Colors.subtitle
98
+ }
99
+ },
100
+ buttonStyle: {
101
+ unread: {
102
+ font: {
103
+ family: styles.Fonts.subtitle,
104
+ size: styles.TextSizes.subtitle,
105
+ color: '#FFFFFF'
106
+ },
107
+ backgroundColor: styles.Colors.action,
108
+ cornerRadius: styles.Corners.button
109
+ },
110
+ read: {
111
+ font: {
112
+ family: styles.Fonts.subtitle,
113
+ size: styles.TextSizes.subtitle,
114
+ color: styles.Colors.title,
115
+ },
116
+ backgroundColor: styles.Colors.option,
117
+ cornerRadius: styles.Corners.button
118
+ }
119
+ },
120
+ infoViewStyle: {
121
+ font: {
122
+ family: styles.Fonts.title,
123
+ size: styles.TextSizes.title,
124
+ color: styles.Colors.title
125
+ },
126
+ button: {
127
+ font: {
128
+ family: styles.Fonts.subtitle,
129
+ size: styles.TextSizes.subtitle,
130
+ color: styles.Colors.action
131
+ },
132
+ backgroundColor: styles.Colors.title,
133
+ cornerRadius: styles.Corners.button
134
+ }
135
+ },
136
+ iOS: {
137
+ messageAnimationStyle: 'right',
138
+ cellStyles: {
139
+ separatorStyle: 'singleLineEtched',
140
+ separatorInsets: {
141
+ top: 0,
142
+ left: 0,
143
+ right: 0,
144
+ bottom: 0
145
+ }
146
+ }
147
+ },
148
+ android: {
149
+ dividerItemDecoration: 'vertical'
150
+ }
151
+ };
152
+ }
153
+ const styles = StyleSheet.create({
154
+ container: {
155
+ flex: 1,
156
+ },
157
+ box: {
158
+ width: '100%',
159
+ height: '100%',
160
+ },
161
+ });
162
+ const showMessageActions = (message) => {
163
+ if (Platform.OS === 'android') {
164
+ Alert.alert('Message Actions', '', [
165
+ {
166
+ text: message.read ? 'Mark as Unread' : 'Mark as Read',
167
+ onPress: () => {
168
+ message.read ? Courier.shared.unreadMessage({ messageId: message.messageId }) : Courier.shared.readMessage({ messageId: message.messageId });
169
+ },
170
+ },
171
+ {
172
+ text: message.archived ? 'Unarchive' : 'Archive',
173
+ onPress: () => {
174
+ message.archived ? null : Courier.shared.archiveMessage({ messageId: message.messageId });
175
+ },
176
+ },
177
+ {
178
+ text: 'Cancel',
179
+ style: 'cancel',
180
+ },
181
+ ]);
182
+ }
183
+ else if (Platform.OS === 'ios') {
184
+ ActionSheetIOS.showActionSheetWithOptions({
185
+ options: [message.read ? 'Mark as Unread' : 'Mark as Read', message.archived ? 'Unarchive' : 'Archive', 'Cancel'],
186
+ cancelButtonIndex: 2,
187
+ destructiveButtonIndex: 1,
188
+ }, (buttonIndex) => {
189
+ switch (buttonIndex) {
190
+ case 0:
191
+ message.read ? Courier.shared.unreadMessage({ messageId: message.messageId }) : Courier.shared.readMessage({ messageId: message.messageId });
192
+ break;
193
+ case 1:
194
+ message.archived ? null : Courier.shared.archiveMessage({ messageId: message.messageId });
195
+ break;
196
+ }
197
+ });
198
+ }
199
+ };
200
+ return (React.createElement(View, { style: styles.container },
201
+ React.createElement(CourierInboxView, { canSwipePages: false, theme: {
202
+ light: getTheme(false),
203
+ dark: getTheme(true)
204
+ }, onClickInboxMessageAtIndex: async (message, _index) => {
205
+ console.log(message);
206
+ if (message.read) {
207
+ await Courier.shared.unreadMessage({ messageId: message.messageId });
208
+ }
209
+ else {
210
+ await Courier.shared.readMessage({ messageId: message.messageId });
211
+ }
212
+ }, onLongPressInboxMessageAtIndex: (message, _index) => {
213
+ showMessageActions(message);
214
+ }, onClickInboxActionForMessageAtIndex: (action, _message, _index) => {
215
+ console.log(action);
216
+ }, onScrollInbox: (y, _x) => {
217
+ console.log(`Inbox scroll offset y: ${y}`);
218
+ }, style: styles.box })));
219
+ };
220
+ export default InboxStyled;
@@ -0,0 +1,91 @@
1
+ import Courier from "@trycourier/courier-react-native";
2
+ import { addListener } from "../../Emitter";
3
+ import React, { useEffect, useState } from "react";
4
+ import { ActivityIndicator, Dimensions, FlatList, Platform, RefreshControl, StyleSheet, Text, TouchableOpacity, View } from "react-native";
5
+ const ListItem = (props) => {
6
+ const SCREEN_WIDTH = Dimensions.get("screen").width;
7
+ const styles = StyleSheet.create({
8
+ container: {
9
+ width: SCREEN_WIDTH,
10
+ },
11
+ text: {
12
+ fontFamily: Platform.select({
13
+ ios: 'Courier',
14
+ android: 'monospace',
15
+ default: 'monospace',
16
+ }),
17
+ fontSize: 16,
18
+ }
19
+ });
20
+ return (React.createElement(TouchableOpacity, { style: styles.container, onPress: props.onClick },
21
+ React.createElement(View, { style: { padding: 16 } },
22
+ React.createElement(Text, { style: styles.text }, JSON.stringify(props.topic, null, 2)))));
23
+ };
24
+ const PreferencesCustom = ({ navigation }) => {
25
+ const [isLoading, setIsLoading] = useState(false);
26
+ const [userId, setUserId] = useState();
27
+ const [topics, setTopics] = useState([]);
28
+ const [isRefreshing, setIsRefreshing] = useState(false);
29
+ useEffect(() => {
30
+ const initUser = async () => {
31
+ const id = await Courier.shared.getUserId();
32
+ setUserId(id);
33
+ };
34
+ initUser();
35
+ const handleSaveClicked = (_) => {
36
+ if (userId) {
37
+ getPrefs();
38
+ }
39
+ };
40
+ // Add listener when component mounts
41
+ addListener('saveButtonClicked', handleSaveClicked);
42
+ }, []);
43
+ useEffect(() => {
44
+ if (userId) {
45
+ getPrefs();
46
+ }
47
+ }, [userId]);
48
+ async function getPrefs(refresh = false) {
49
+ const client = await Courier.shared.getClient();
50
+ if (!client) {
51
+ return;
52
+ }
53
+ if (refresh) {
54
+ setIsRefreshing(true);
55
+ }
56
+ else {
57
+ setIsLoading(true);
58
+ }
59
+ try {
60
+ console.log('getPrefs');
61
+ const res = await client.preferences.getUserPreferences();
62
+ setTopics(res.items);
63
+ }
64
+ catch (e) {
65
+ console.log(e);
66
+ }
67
+ if (refresh) {
68
+ setIsRefreshing(false);
69
+ }
70
+ else {
71
+ setIsLoading(false);
72
+ }
73
+ }
74
+ const onItemClick = (topic) => {
75
+ navigation.push('PreferencesDetail', { id: topic.topicId });
76
+ };
77
+ const styles = StyleSheet.create({
78
+ container: {
79
+ flex: 1,
80
+ justifyContent: 'center',
81
+ alignItems: 'center',
82
+ },
83
+ text: {
84
+ marginBottom: 10,
85
+ },
86
+ });
87
+ return (React.createElement(View, { style: styles.container },
88
+ isLoading && (React.createElement(ActivityIndicator, { size: "small" })),
89
+ !isLoading && (React.createElement(FlatList, { data: topics, renderItem: ({ item }) => React.createElement(ListItem, { topic: item, onClick: () => onItemClick(item) }), keyExtractor: (item) => item.topicId ?? 'empty', refreshControl: React.createElement(RefreshControl, { refreshing: isRefreshing, onRefresh: () => getPrefs(true) }) }))));
90
+ };
91
+ export default PreferencesCustom;
@@ -0,0 +1,17 @@
1
+ import { CourierPreferencesView } from "@trycourier/courier-react-native";
2
+ import React from "react";
3
+ import { StyleSheet, View } from "react-native";
4
+ const PreferencesDefault = () => {
5
+ const styles = StyleSheet.create({
6
+ container: {
7
+ flex: 1,
8
+ },
9
+ box: {
10
+ width: '100%',
11
+ height: '100%',
12
+ },
13
+ });
14
+ return (React.createElement(View, { style: styles.container },
15
+ React.createElement(CourierPreferencesView, { mode: { type: 'topic' }, style: styles.box })));
16
+ };
17
+ export default PreferencesDefault;
@@ -0,0 +1,127 @@
1
+ import React, { useEffect, useState } from "react";
2
+ import { ActivityIndicator, Button, Platform, ScrollView, StyleSheet, Switch, Text, View } from "react-native";
3
+ import SegmentedControl from '@react-native-segmented-control/segmented-control';
4
+ import Courier, { CourierUserPreferencesChannel, CourierUserPreferencesStatus } from "@trycourier/courier-react-native";
5
+ import { emitEvent } from "../../Emitter";
6
+ import Toast from 'react-native-toast-message';
7
+ const PreferencesDetail = ({ route, navigation }) => {
8
+ const styles = StyleSheet.create({
9
+ container: {
10
+ flex: 1,
11
+ padding: 20,
12
+ },
13
+ switchItem: {
14
+ flexDirection: 'row',
15
+ alignItems: 'center',
16
+ justifyContent: 'space-between',
17
+ borderBottomWidth: 1,
18
+ borderBottomColor: '#ccc',
19
+ },
20
+ text: {
21
+ fontFamily: Platform.select({
22
+ ios: 'Courier',
23
+ android: 'monospace',
24
+ default: 'monospace',
25
+ }),
26
+ fontSize: 16,
27
+ },
28
+ section: {
29
+ marginBottom: 20,
30
+ },
31
+ title: {
32
+ fontWeight: 'bold',
33
+ marginBottom: 8,
34
+ },
35
+ loading: {
36
+ flex: 1,
37
+ justifyContent: 'center',
38
+ alignItems: 'center',
39
+ },
40
+ });
41
+ const statuses = [
42
+ { status: CourierUserPreferencesStatus.OptedIn, name: "OPTED_IN" },
43
+ { status: CourierUserPreferencesStatus.OptedOut, name: "OPTED_OUT" },
44
+ { status: CourierUserPreferencesStatus.Required, name: "REQUIRED" }
45
+ ];
46
+ const { id } = route.params;
47
+ const [isLoading, setIsLoading] = useState(false);
48
+ const [statusIndex, setStatusIndex] = useState(0);
49
+ const [useCustomRouting, setUseCustomRouting] = useState(false);
50
+ const [routingChannels, setRoutingChannels] = useState([]);
51
+ useEffect(() => {
52
+ navigation.setOptions({
53
+ headerTitle: id,
54
+ });
55
+ getTopic(id);
56
+ }, []);
57
+ async function getTopic(topicId) {
58
+ const client = await Courier.shared.getClient();
59
+ if (!client) {
60
+ return;
61
+ }
62
+ setIsLoading(true);
63
+ try {
64
+ const topic = await client.preferences.getUserPreferenceTopic({ topicId });
65
+ setStatusIndex(statuses.findIndex(status => status.status === topic.status) || 0);
66
+ setUseCustomRouting(topic.hasCustomRouting || false);
67
+ setRoutingChannels(topic.customRouting || []);
68
+ }
69
+ catch (error) {
70
+ console.error("Error fetching topic:", error);
71
+ }
72
+ finally {
73
+ setIsLoading(false);
74
+ }
75
+ }
76
+ async function savePreferences() {
77
+ const client = await Courier.shared.getClient();
78
+ if (!client) {
79
+ return;
80
+ }
81
+ setIsLoading(true);
82
+ try {
83
+ await client.preferences.putUserPreferenceTopic({
84
+ topicId: id,
85
+ status: statuses[statusIndex]?.status || CourierUserPreferencesStatus.OptedIn,
86
+ hasCustomRouting: useCustomRouting,
87
+ customRouting: routingChannels,
88
+ });
89
+ emitEvent('saveButtonClicked', {});
90
+ navigation.goBack();
91
+ }
92
+ catch (error) {
93
+ console.error("Error saving preferences:", error);
94
+ Toast.show({
95
+ type: 'error',
96
+ text1: error.message,
97
+ });
98
+ }
99
+ finally {
100
+ setIsLoading(false);
101
+ }
102
+ }
103
+ return (React.createElement(React.Fragment, null, isLoading ? (React.createElement(View, { style: styles.loading },
104
+ React.createElement(ActivityIndicator, { size: "small" }))) : (React.createElement(ScrollView, { style: styles.container },
105
+ React.createElement(View, { style: styles.section },
106
+ React.createElement(Text, { style: styles.title }, "Status"),
107
+ React.createElement(SegmentedControl, { values: statuses.map(status => status.name), selectedIndex: statusIndex, fontStyle: styles.text, onChange: ({ nativeEvent }) => setStatusIndex(nativeEvent.selectedSegmentIndex) })),
108
+ React.createElement(View, { style: styles.section },
109
+ React.createElement(Text, { style: styles.title }, "Use Custom Routing"),
110
+ React.createElement(View, { style: styles.switchItem },
111
+ React.createElement(Text, { style: styles.text }, "Use Custom Routing"),
112
+ React.createElement(Switch, { value: useCustomRouting, onValueChange: value => {
113
+ setUseCustomRouting(value);
114
+ } }))),
115
+ React.createElement(View, { style: styles.section },
116
+ React.createElement(Text, { style: styles.title }, "Routing Channels"),
117
+ Object.values(CourierUserPreferencesChannel).map(channel => (React.createElement(View, { key: channel, style: styles.switchItem },
118
+ React.createElement(Text, { style: styles.text }, channel),
119
+ React.createElement(Switch, { value: routingChannels.includes(channel), onValueChange: value => {
120
+ setRoutingChannels(prevChannels => value
121
+ ? [...prevChannels, channel]
122
+ : prevChannels.filter(c => c !== channel));
123
+ } }))))),
124
+ React.createElement(View, { style: styles.section },
125
+ React.createElement(Button, { onPress: () => savePreferences(), title: "Save" }))))));
126
+ };
127
+ export default PreferencesDetail;