@messenger-box/platform-mobile 10.0.3-alpha.16 → 10.0.3-alpha.18

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 (31) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/lib/routes.json +14 -1
  3. package/lib/screens/inbox/components/CachedImage/consts.js +1 -1
  4. package/lib/screens/inbox/components/CachedImage/consts.js.map +1 -1
  5. package/lib/screens/inbox/components/CachedImage/index.js +125 -16
  6. package/lib/screens/inbox/components/CachedImage/index.js.map +1 -1
  7. package/lib/screens/inbox/components/SlackMessageContainer/SlackBubble.js +32 -21
  8. package/lib/screens/inbox/components/SlackMessageContainer/SlackBubble.js.map +1 -1
  9. package/lib/screens/inbox/containers/ConversationView.js +1175 -400
  10. package/lib/screens/inbox/containers/ConversationView.js.map +1 -1
  11. package/lib/screens/inbox/containers/Dialogs.js +290 -21
  12. package/lib/screens/inbox/containers/Dialogs.js.map +1 -1
  13. package/lib/screens/inbox/containers/ThreadConversationView.js +858 -351
  14. package/lib/screens/inbox/containers/ThreadConversationView.js.map +1 -1
  15. package/lib/screens/inbox/containers/workflow/conversation-xstate.js +380 -0
  16. package/lib/screens/inbox/containers/workflow/conversation-xstate.js.map +1 -0
  17. package/lib/screens/inbox/containers/workflow/dialogs-xstate.js +235 -0
  18. package/lib/screens/inbox/containers/workflow/dialogs-xstate.js.map +1 -0
  19. package/lib/screens/inbox/containers/workflow/thread-conversation-xstate.js +438 -0
  20. package/lib/screens/inbox/containers/workflow/thread-conversation-xstate.js.map +1 -0
  21. package/package.json +4 -4
  22. package/src/screens/inbox/components/CachedImage/consts.ts +4 -3
  23. package/src/screens/inbox/components/CachedImage/index.tsx +137 -17
  24. package/src/screens/inbox/components/SlackMessageContainer/SlackBubble.tsx +35 -9
  25. package/src/screens/inbox/containers/ConversationView.tsx +1510 -641
  26. package/src/screens/inbox/containers/Dialogs.tsx +415 -123
  27. package/src/screens/inbox/containers/ThreadConversationView.tsx +1053 -288
  28. package/src/screens/inbox/containers/workflow/apollo/handleResult.ts +20 -0
  29. package/src/screens/inbox/containers/workflow/conversation-xstate.ts +313 -0
  30. package/src/screens/inbox/containers/workflow/dialogs-xstate.ts +196 -0
  31. package/src/screens/inbox/containers/workflow/thread-conversation-xstate.ts +401 -0
@@ -0,0 +1,20 @@
1
+ import { ApolloError, FetchResult, SingleExecutionResult } from '@apollo/client';
2
+
3
+ // Accept any promise-like object with a data field
4
+ export const newHandleMutationResult = async (
5
+ promise: Promise<any>,
6
+ transformer: (result: any) => any,
7
+ ): Promise<any> => {
8
+ try {
9
+ const result = await promise;
10
+ if (result.errors) {
11
+ throw result.errors;
12
+ }
13
+ if (!result.data) {
14
+ throw new Error('No data returned from query');
15
+ }
16
+ return transformer(result.data);
17
+ } catch (error: any) {
18
+ throw error;
19
+ }
20
+ };
@@ -0,0 +1,313 @@
1
+ import { assign, setup } from 'xstate';
2
+ import { merge } from 'lodash-es';
3
+
4
+ export const enum Actions {
5
+ INITIAL_CONTEXT = 'INITIAL_CONTEXT',
6
+ ERROR_HANDLED = 'ERROR_HANDLED',
7
+ SEND_MESSAGE = 'SEND_MESSAGE',
8
+ SEND_MESSAGE_WITH_FILE = 'SEND_MESSAGE_WITH_FILE',
9
+ SET_CHANNEL_MESSAGES = 'SET_CHANNEL_MESSAGES',
10
+ CLEAR_MESSAGES = 'CLEAR_MESSAGES',
11
+ FETCH_MORE_MESSAGES = 'FETCH_MORE_MESSAGES',
12
+ SUBSCRIBE_TO_MESSAGES = 'SUBSCRIBE_TO_MESSAGES',
13
+ CREATE_DIRECT_CHANNEL = 'CREATE_DIRECT_CHANNEL',
14
+ START_LOADING = 'START_LOADING',
15
+ STOP_LOADING = 'STOP_LOADING',
16
+ SET_IMAGE = 'SET_IMAGE',
17
+ CLEAR_IMAGE = 'CLEAR_IMAGE',
18
+ SET_MESSAGE_TEXT = 'SET_MESSAGE_TEXT',
19
+ }
20
+
21
+ export const enum BaseState {
22
+ Idle = 'idle',
23
+ Error = 'error',
24
+ Loading = 'loading',
25
+ Done = 'done',
26
+ FetchChannels = 'fetchChannels',
27
+ FetchMessages = 'fetchMessages',
28
+ }
29
+
30
+ export const enum MainState {
31
+ SendMessage = 'sendMessage',
32
+ SendMessageWithFile = 'sendMessageWithFile',
33
+ FetchMoreMessages = 'fetchMoreMessages',
34
+ CreateDirectChannel = 'createDirectChannel',
35
+ }
36
+
37
+ export const conversationXstate = setup({
38
+ types: {
39
+ context: {} as {
40
+ channelId: string | null;
41
+ channelMessages: any[];
42
+ totalCount: number;
43
+ skip: number;
44
+ loading: boolean;
45
+ loadingOldMessages: boolean;
46
+ error: string | null;
47
+ selectedImage: string;
48
+ files: any[];
49
+ images: any[];
50
+ messageText: string;
51
+ imageLoading: boolean;
52
+ },
53
+ },
54
+ actions: {
55
+ errorState: assign(({ context, event }) => {
56
+ return {
57
+ ...context,
58
+ error: event.data?.message || 'An error occurred',
59
+ loading: false,
60
+ loadingOldMessages: false,
61
+ imageLoading: false,
62
+ };
63
+ }),
64
+ setInitialContext: assign(({ context, event }) => {
65
+ return merge({
66
+ ...context,
67
+ channelId: event.data?.channelId || null,
68
+ loading: false,
69
+ });
70
+ }),
71
+ setChannelMessages: assign(({ context, event }) => {
72
+ return {
73
+ ...context,
74
+ channelMessages: event.data?.messages || [],
75
+ totalCount: event.data?.totalCount || 0,
76
+ loading: false,
77
+ };
78
+ }),
79
+ addChannelMessages: assign(({ context, event }) => {
80
+ const messages = event.data?.messages || [];
81
+ return {
82
+ ...context,
83
+ channelMessages: [...context.channelMessages, ...messages],
84
+ loadingOldMessages: false,
85
+ };
86
+ }),
87
+ addNewMessage: assign(({ context, event }) => {
88
+ const message = event.data?.message;
89
+ if (!message) return context;
90
+
91
+ return {
92
+ ...context,
93
+ channelMessages: [...context.channelMessages, message],
94
+ totalCount: context.totalCount + 1,
95
+ loading: false,
96
+ };
97
+ }),
98
+ updateSkip: assign(({ context, event }) => {
99
+ return {
100
+ ...context,
101
+ skip: context.channelMessages.length,
102
+ loadingOldMessages: true,
103
+ };
104
+ }),
105
+ clearMessages: assign(({ context }) => {
106
+ return {
107
+ ...context,
108
+ channelMessages: [],
109
+ totalCount: 0,
110
+ skip: 0,
111
+ };
112
+ }),
113
+ setChannelId: assign(({ context, event }) => {
114
+ return {
115
+ ...context,
116
+ channelId: event.data?.channelId || null,
117
+ };
118
+ }),
119
+ startLoading: assign(({ context }) => {
120
+ return {
121
+ ...context,
122
+ loading: true,
123
+ };
124
+ }),
125
+ stopLoading: assign(({ context }) => {
126
+ return {
127
+ ...context,
128
+ loading: false,
129
+ };
130
+ }),
131
+ startImageLoading: assign(({ context }) => {
132
+ return {
133
+ ...context,
134
+ imageLoading: true,
135
+ };
136
+ }),
137
+ stopImageLoading: assign(({ context }) => {
138
+ return {
139
+ ...context,
140
+ imageLoading: false,
141
+ };
142
+ }),
143
+ setSelectedImage: assign(({ context, event }) => {
144
+ return {
145
+ ...context,
146
+ selectedImage: event.data?.image || '',
147
+ files: event.data?.files || context.files,
148
+ images: event.data?.images || context.images,
149
+ imageLoading: false,
150
+ };
151
+ }),
152
+ clearImageData: assign(({ context }) => {
153
+ return {
154
+ ...context,
155
+ selectedImage: '',
156
+ files: [],
157
+ images: [],
158
+ };
159
+ }),
160
+ setMessageText: assign(({ context, event }) => {
161
+ return {
162
+ ...context,
163
+ messageText: event.data?.messageText || '',
164
+ };
165
+ }),
166
+ },
167
+ guards: {
168
+ hasMoreMessages: ({ context }) => {
169
+ return context.totalCount > context.channelMessages.length;
170
+ },
171
+ },
172
+ }).createMachine({
173
+ id: 'conversation-view',
174
+ initial: BaseState.Idle,
175
+ context: {
176
+ channelId: null,
177
+ channelMessages: [],
178
+ totalCount: 0,
179
+ skip: 0,
180
+ loading: false,
181
+ loadingOldMessages: false,
182
+ error: null,
183
+ selectedImage: '',
184
+ files: [],
185
+ images: [],
186
+ messageText: '',
187
+ imageLoading: false,
188
+ },
189
+ states: {
190
+ [BaseState.Idle]: {
191
+ on: {
192
+ [Actions.INITIAL_CONTEXT]: {
193
+ target: BaseState.FetchMessages,
194
+ actions: ['setInitialContext'],
195
+ },
196
+ [Actions.SEND_MESSAGE]: {
197
+ target: MainState.SendMessage,
198
+ actions: ['startLoading'],
199
+ },
200
+ [Actions.SEND_MESSAGE_WITH_FILE]: {
201
+ target: MainState.SendMessageWithFile,
202
+ actions: ['startLoading'],
203
+ },
204
+ [Actions.FETCH_MORE_MESSAGES]: {
205
+ target: MainState.FetchMoreMessages,
206
+ actions: ['updateSkip'],
207
+ guard: 'hasMoreMessages',
208
+ },
209
+ [Actions.CLEAR_MESSAGES]: {
210
+ target: BaseState.Idle,
211
+ actions: ['clearMessages'],
212
+ },
213
+ [Actions.CREATE_DIRECT_CHANNEL]: {
214
+ target: MainState.CreateDirectChannel,
215
+ actions: ['startLoading'],
216
+ },
217
+ [Actions.START_LOADING]: {
218
+ target: BaseState.Idle,
219
+ actions: ['startLoading'],
220
+ },
221
+ [Actions.STOP_LOADING]: {
222
+ target: BaseState.Idle,
223
+ actions: ['stopLoading'],
224
+ },
225
+ [Actions.SET_IMAGE]: {
226
+ target: BaseState.Idle,
227
+ actions: ['setSelectedImage'],
228
+ },
229
+ [Actions.CLEAR_IMAGE]: {
230
+ target: BaseState.Idle,
231
+ actions: ['clearImageData'],
232
+ },
233
+ [Actions.SET_MESSAGE_TEXT]: {
234
+ target: BaseState.Idle,
235
+ actions: ['setMessageText'],
236
+ },
237
+ },
238
+ },
239
+ [BaseState.Error]: {
240
+ entry: ['errorState'],
241
+ on: {
242
+ [Actions.ERROR_HANDLED]: {
243
+ target: BaseState.Idle,
244
+ },
245
+ },
246
+ },
247
+ [BaseState.FetchMessages]: {
248
+ invoke: {
249
+ src: 'fetchMessages',
250
+ input: ({ context, event }) => ({ context, event }),
251
+ onDone: {
252
+ target: BaseState.Idle,
253
+ actions: ['setChannelMessages'],
254
+ },
255
+ onError: {
256
+ target: BaseState.Error,
257
+ },
258
+ },
259
+ },
260
+ [MainState.SendMessage]: {
261
+ invoke: {
262
+ src: 'sendMessage',
263
+ input: ({ context, event }) => ({ context, event }),
264
+ onDone: {
265
+ target: BaseState.Idle,
266
+ actions: ['addNewMessage', 'stopLoading'],
267
+ },
268
+ onError: {
269
+ target: BaseState.Error,
270
+ },
271
+ },
272
+ },
273
+ [MainState.SendMessageWithFile]: {
274
+ invoke: {
275
+ src: 'sendMessageWithFile',
276
+ input: ({ context, event }) => ({ context, event }),
277
+ onDone: {
278
+ target: BaseState.Idle,
279
+ actions: ['addNewMessage', 'clearImageData', 'stopLoading'],
280
+ },
281
+ onError: {
282
+ target: BaseState.Error,
283
+ },
284
+ },
285
+ },
286
+ [MainState.FetchMoreMessages]: {
287
+ invoke: {
288
+ src: 'fetchMoreMessages',
289
+ input: ({ context, event }) => ({ context, event }),
290
+ onDone: {
291
+ target: BaseState.Idle,
292
+ actions: ['addChannelMessages'],
293
+ },
294
+ onError: {
295
+ target: BaseState.Error,
296
+ },
297
+ },
298
+ },
299
+ [MainState.CreateDirectChannel]: {
300
+ invoke: {
301
+ src: 'createDirectChannel',
302
+ input: ({ context, event }) => ({ context, event }),
303
+ onDone: {
304
+ target: BaseState.Idle,
305
+ actions: ['setChannelId', 'stopLoading'],
306
+ },
307
+ onError: {
308
+ target: BaseState.Error,
309
+ },
310
+ },
311
+ },
312
+ },
313
+ } as any);
@@ -0,0 +1,196 @@
1
+ import { assign, setup } from 'xstate';
2
+ import { merge } from 'lodash-es';
3
+
4
+ export const enum Actions {
5
+ INITIAL_CONTEXT = 'INITIAL_CONTEXT',
6
+ ERROR_HANDLED = 'ERROR_HANDLED',
7
+ FETCH_CHANNELS = 'FETCH_CHANNELS',
8
+ REFRESH_CHANNELS = 'REFRESH_CHANNELS',
9
+ SELECT_CHANNEL = 'SELECT_CHANNEL',
10
+ START_LOADING = 'START_LOADING',
11
+ STOP_LOADING = 'STOP_LOADING',
12
+ SET_SEARCH_QUERY = 'SET_SEARCH_QUERY',
13
+ }
14
+
15
+ export const enum BaseState {
16
+ Idle = 'idle',
17
+ Error = 'error',
18
+ Loading = 'loading',
19
+ Done = 'done',
20
+ FetchChannels = 'fetchChannels',
21
+ }
22
+
23
+ export const enum MainState {
24
+ RefreshChannels = 'refreshChannels',
25
+ SelectChannel = 'selectChannel',
26
+ }
27
+
28
+ export const dialogsXstate = setup({
29
+ types: {
30
+ context: {} as {
31
+ channels: any[];
32
+ refreshing: boolean;
33
+ loading: boolean;
34
+ error: string | null;
35
+ searchQuery: string;
36
+ selectedChannelId: string | null;
37
+ channelRole: string | null;
38
+ channelFilters: Record<string, any>;
39
+ supportServices: boolean;
40
+ },
41
+ },
42
+ actions: {
43
+ errorState: assign(({ context, event }) => {
44
+ return {
45
+ ...context,
46
+ error: event.data?.message || 'An error occurred',
47
+ loading: false,
48
+ refreshing: false,
49
+ };
50
+ }),
51
+ setInitialContext: assign(({ context, event }) => {
52
+ return merge({
53
+ ...context,
54
+ channelRole: event.data?.channelRole || null,
55
+ channelFilters: event.data?.channelFilters || {},
56
+ supportServices: event.data?.supportServices || false,
57
+ selectedChannelId: event.data?.selectedChannelId || null,
58
+ loading: true,
59
+ });
60
+ }),
61
+ setChannels: assign(({ context, event }) => {
62
+ return {
63
+ ...context,
64
+ channels: event.data?.channels || [],
65
+ loading: false,
66
+ refreshing: false,
67
+ };
68
+ }),
69
+ startRefreshing: assign(({ context }) => {
70
+ return {
71
+ ...context,
72
+ refreshing: true,
73
+ };
74
+ }),
75
+ stopRefreshing: assign(({ context }) => {
76
+ return {
77
+ ...context,
78
+ refreshing: false,
79
+ };
80
+ }),
81
+ startLoading: assign(({ context }) => {
82
+ return {
83
+ ...context,
84
+ loading: true,
85
+ };
86
+ }),
87
+ stopLoading: assign(({ context }) => {
88
+ return {
89
+ ...context,
90
+ loading: false,
91
+ };
92
+ }),
93
+ setSearchQuery: assign(({ context, event }) => {
94
+ return {
95
+ ...context,
96
+ searchQuery: event.data?.searchQuery || '',
97
+ };
98
+ }),
99
+ selectChannel: assign(({ context, event }) => {
100
+ return {
101
+ ...context,
102
+ selectedChannelId: event.data?.channelId || null,
103
+ };
104
+ }),
105
+ },
106
+ guards: {
107
+ hasChannels: ({ context }) => {
108
+ return context.channels.length > 0;
109
+ },
110
+ },
111
+ }).createMachine({
112
+ id: 'dialogs-view',
113
+ initial: BaseState.Idle,
114
+ context: {
115
+ channels: [],
116
+ refreshing: false,
117
+ loading: false,
118
+ error: null,
119
+ searchQuery: '',
120
+ selectedChannelId: null,
121
+ channelRole: null,
122
+ channelFilters: {},
123
+ supportServices: false,
124
+ },
125
+ states: {
126
+ [BaseState.Idle]: {
127
+ on: {
128
+ [Actions.INITIAL_CONTEXT]: {
129
+ target: BaseState.FetchChannels,
130
+ actions: ['setInitialContext'],
131
+ },
132
+ [Actions.REFRESH_CHANNELS]: {
133
+ target: MainState.RefreshChannels,
134
+ actions: ['startRefreshing'],
135
+ },
136
+ [Actions.SELECT_CHANNEL]: {
137
+ target: MainState.SelectChannel,
138
+ actions: ['selectChannel'],
139
+ },
140
+ [Actions.START_LOADING]: {
141
+ target: BaseState.Idle,
142
+ actions: ['startLoading'],
143
+ },
144
+ [Actions.STOP_LOADING]: {
145
+ target: BaseState.Idle,
146
+ actions: ['stopLoading'],
147
+ },
148
+ [Actions.SET_SEARCH_QUERY]: {
149
+ target: BaseState.Idle,
150
+ actions: ['setSearchQuery'],
151
+ },
152
+ },
153
+ },
154
+ [BaseState.Error]: {
155
+ entry: ['errorState'],
156
+ on: {
157
+ [Actions.ERROR_HANDLED]: {
158
+ target: BaseState.Idle,
159
+ },
160
+ },
161
+ },
162
+ [BaseState.FetchChannels]: {
163
+ invoke: {
164
+ src: 'fetchChannels',
165
+ input: ({ context, event }) => ({ context, event }),
166
+ onDone: {
167
+ target: BaseState.Idle,
168
+ actions: ['setChannels'],
169
+ },
170
+ onError: {
171
+ target: BaseState.Error,
172
+ actions: ['errorState'],
173
+ },
174
+ },
175
+ },
176
+ [MainState.RefreshChannels]: {
177
+ invoke: {
178
+ src: 'refreshChannels',
179
+ input: ({ context, event }) => ({ context, event }),
180
+ onDone: {
181
+ target: BaseState.Idle,
182
+ actions: ['setChannels'],
183
+ },
184
+ onError: {
185
+ target: BaseState.Error,
186
+ actions: ['errorState'],
187
+ },
188
+ },
189
+ },
190
+ [MainState.SelectChannel]: {
191
+ always: {
192
+ target: BaseState.Idle,
193
+ },
194
+ },
195
+ },
196
+ } as any);