1
1
/* @flow strict-local */
2
- import { Clipboard , Share } from 'react-native' ;
2
+ import { Clipboard , Share , Alert } from 'react-native' ;
3
3
import type { Auth , Dispatch , GetText , Message , Narrow , Outbox , Subscription } from '../types' ;
4
4
import type { BackgroundData } from '../webview/MessageList' ;
5
5
import {
@@ -33,6 +33,11 @@ type ButtonDescription = {
33
33
_ : GetText ,
34
34
} ) : void | Promise < void > ,
35
35
title : string ,
36
+
37
+ /** The title of the alert-box that will be displayed if the callback throws. */
38
+ // Required even when the callback can't throw (e.g., "Cancel"), since we can't
39
+ // otherwise ensure that everything that _can_ throw has one.
40
+ errorMessage : string ,
36
41
} ;
37
42
38
43
const isAnOutboxMessage = ( message : Message | Outbox ) : boolean => message . isOutbox ;
@@ -45,6 +50,7 @@ const reply = ({ message, dispatch, ownEmail }) => {
45
50
dispatch ( doNarrow ( getNarrowFromMessage ( message , ownEmail ) , message . id ) ) ;
46
51
} ;
47
52
reply . title = 'Reply' ;
53
+ reply . errorMessage = 'Failed to reply' ;
48
54
49
55
const copyToClipboard = async ( { _, auth, message } ) => {
50
56
const rawMessage = isAnOutboxMessage ( message ) /* $FlowFixMe: then really type Outbox */
@@ -54,76 +60,89 @@ const copyToClipboard = async ({ _, auth, message }) => {
54
60
showToast ( _ ( 'Message copied' ) ) ;
55
61
} ;
56
62
copyToClipboard . title = 'Copy to clipboard' ;
63
+ copyToClipboard . errorMessage = 'Failed to copy message to clipboard' ;
57
64
58
65
const editMessage = async ( { message, dispatch } ) => {
59
66
dispatch ( startEditMessage ( message . id , message . subject ) ) ;
60
67
} ;
61
68
editMessage . title = 'Edit message' ;
69
+ editMessage . errorMessage = 'Failed to edit message' ;
62
70
63
71
const deleteMessage = async ( { auth, message, dispatch } ) => {
64
72
if ( isAnOutboxMessage ( message ) ) {
65
73
dispatch ( deleteOutboxMessage ( message . timestamp ) ) ;
66
74
} else {
67
- api . deleteMessage ( auth , message . id ) ;
75
+ await api . deleteMessage ( auth , message . id ) ;
68
76
}
69
77
} ;
70
78
deleteMessage . title = 'Delete message' ;
79
+ deleteMessage . errorMessage = 'Failed to delete message' ;
71
80
72
- const unmuteTopic = ( { auth, message } ) => {
73
- api . unmuteTopic ( auth , message . display_recipient , message . subject ) ;
81
+ const unmuteTopic = async ( { auth, message } ) => {
82
+ await api . unmuteTopic ( auth , message . display_recipient , message . subject ) ;
74
83
} ;
75
84
unmuteTopic . title = 'Unmute topic' ;
85
+ unmuteTopic . errorMessage = 'Failed to unmute topic' ;
76
86
77
- const muteTopic = ( { auth, message } ) => {
78
- api . muteTopic ( auth , message . display_recipient , message . subject ) ;
87
+ const muteTopic = async ( { auth, message } ) => {
88
+ await api . muteTopic ( auth , message . display_recipient , message . subject ) ;
79
89
} ;
80
90
muteTopic . title = 'Mute topic' ;
91
+ muteTopic . errorMessage = 'Failed to mute topic' ;
81
92
82
- const unmuteStream = ( { auth, message, subscriptions } ) => {
93
+ const unmuteStream = async ( { auth, message, subscriptions } ) => {
83
94
const sub = subscriptions . find ( x => x . name === message . display_recipient ) ;
84
95
if ( sub ) {
85
- api . toggleMuteStream ( auth , sub . stream_id , false ) ;
96
+ await api . toggleMuteStream ( auth , sub . stream_id , false ) ;
86
97
}
87
98
} ;
88
99
unmuteStream . title = 'Unmute stream' ;
100
+ unmuteStream . errorMessage = 'Failed to unmute stream' ;
89
101
90
- const muteStream = ( { auth, message, subscriptions } ) => {
102
+ const muteStream = async ( { auth, message, subscriptions } ) => {
91
103
const sub = subscriptions . find ( x => x . name === message . display_recipient ) ;
92
104
if ( sub ) {
93
- api . toggleMuteStream ( auth , sub . stream_id , true ) ;
105
+ await api . toggleMuteStream ( auth , sub . stream_id , true ) ;
94
106
}
95
107
} ;
96
108
muteStream . title = 'Mute stream' ;
109
+ muteStream . errorMessage = 'Failed to mute stream' ;
97
110
98
- const starMessage = ( { auth, message } ) => {
99
- api . toggleMessageStarred ( auth , [ message . id ] , true ) ;
111
+ const starMessage = async ( { auth, message } ) => {
112
+ await api . toggleMessageStarred ( auth , [ message . id ] , true ) ;
100
113
} ;
101
114
starMessage . title = 'Star message' ;
115
+ starMessage . errorMessage = 'Failed to star message' ;
102
116
103
- const unstarMessage = ( { auth, message } ) => {
104
- api . toggleMessageStarred ( auth , [ message . id ] , false ) ;
117
+ const unstarMessage = async ( { auth, message } ) => {
118
+ await api . toggleMessageStarred ( auth , [ message . id ] , false ) ;
105
119
} ;
106
120
unstarMessage . title = 'Unstar message' ;
121
+ unstarMessage . errorMessage = 'Failed to unstar message' ;
107
122
108
123
const shareMessage = ( { message } ) => {
109
124
Share . share ( {
110
125
message : message . content . replace ( / < (?: .| \n ) * ?> / gm, '' ) ,
111
126
} ) ;
112
127
} ;
113
128
shareMessage . title = 'Share' ;
129
+ shareMessage . errorMessage = 'Failed to share message' ;
114
130
115
131
const addReaction = ( { message, dispatch } ) => {
116
132
dispatch ( navigateToEmojiPicker ( message . id ) ) ;
117
133
} ;
118
134
addReaction . title = 'Add a reaction' ;
135
+ addReaction . errorMessage = 'Failed to add reaction' ;
119
136
120
137
const showReactions = ( { message, dispatch } ) => {
121
138
dispatch ( navigateToMessageReactionScreen ( message . id ) ) ;
122
139
} ;
123
140
showReactions . title = 'See who reacted' ;
141
+ showReactions . errorMessage = 'Failed to show reactions' ;
124
142
125
143
const cancel = params => { } ;
126
144
cancel . title = 'Cancel' ;
145
+ cancel . errorMessage = 'Failed to hide menu' ;
127
146
128
147
const allButtonsRaw = {
129
148
// For messages
@@ -239,14 +258,21 @@ export const showActionSheet = (
239
258
? constructHeaderActionButtons ( params )
240
259
: constructMessageActionButtons ( params ) ;
241
260
const callback = buttonIndex => {
242
- allButtons [ optionCodes [ buttonIndex ] ] ( {
243
- dispatch,
244
- subscriptions : params . backgroundData . subscriptions ,
245
- auth : params . backgroundData . auth ,
246
- ownEmail : params . backgroundData . ownEmail ,
247
- _,
248
- ...params ,
249
- } ) ;
261
+ ( async ( ) => {
262
+ const pressedButton : ButtonDescription = allButtons [ optionCodes [ buttonIndex ] ] ;
263
+ try {
264
+ await pressedButton ( {
265
+ dispatch,
266
+ subscriptions : params . backgroundData . subscriptions ,
267
+ auth : params . backgroundData . auth ,
268
+ ownEmail : params . backgroundData . ownEmail ,
269
+ _,
270
+ ...params ,
271
+ } ) ;
272
+ } catch ( err ) {
273
+ Alert . alert ( _ ( pressedButton . errorMessage ) , err . message ) ;
274
+ }
275
+ } ) ( ) ;
250
276
} ;
251
277
showActionSheetWithOptions (
252
278
{
0 commit comments