Prevent replies/reactions on messages with errors
This commit is contained in:
		
					parent
					
						
							
								f37e73c723
							
						
					
				
			
			
				commit
				
					
						101070bf42
					
				
			
		
					 5 changed files with 68 additions and 31 deletions
				
			
		|  | @ -534,6 +534,7 @@ | ||||||
|         timestamp: this.get('sent_at'), |         timestamp: this.get('sent_at'), | ||||||
|         status: this.getMessagePropStatus(), |         status: this.getMessagePropStatus(), | ||||||
|         contact: this.getPropsForEmbeddedContact(), |         contact: this.getPropsForEmbeddedContact(), | ||||||
|  |         canReply: this.canReply(), | ||||||
|         authorColor, |         authorColor, | ||||||
|         authorName: contact.name, |         authorName: contact.name, | ||||||
|         authorProfileName: contact.profileName, |         authorProfileName: contact.profileName, | ||||||
|  | @ -1305,6 +1306,24 @@ | ||||||
|         e.name === 'OutgoingIdentityKeyError' |         e.name === 'OutgoingIdentityKeyError' | ||||||
|       ); |       ); | ||||||
|     }, |     }, | ||||||
|  |     canReply() { | ||||||
|  |       const errors = this.get('errors'); | ||||||
|  |       const isOutgoing = this.get('type') === 'outgoing'; | ||||||
|  |       const numDelivered = this.get('delivered'); | ||||||
|  | 
 | ||||||
|  |       // Case 1: We can reply if this is outgoing and delievered to at least one recipient
 | ||||||
|  |       if (isOutgoing && numDelivered > 0) { | ||||||
|  |         return true; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       // Case 2: We can reply if there are no errors
 | ||||||
|  |       if (errors && errors.length === 0) { | ||||||
|  |         return true; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       // Otherwise we cannot reply
 | ||||||
|  |       return false; | ||||||
|  |     }, | ||||||
| 
 | 
 | ||||||
|     // Called when the user ran into an error with a specific user, wants to send to them
 |     // Called when the user ran into an error with a specific user, wants to send to them
 | ||||||
|     //   One caller today: ConversationView.forceSend()
 |     //   One caller today: ConversationView.forceSend()
 | ||||||
|  |  | ||||||
|  | @ -2528,6 +2528,10 @@ | ||||||
|           }) |           }) | ||||||
|         : null; |         : null; | ||||||
| 
 | 
 | ||||||
|  |       if (model && !model.canReply()) { | ||||||
|  |         return; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|       if (model && !model.isNormalBubble()) { |       if (model && !model.isNormalBubble()) { | ||||||
|         return; |         return; | ||||||
|       } |       } | ||||||
|  |  | ||||||
|  | @ -15,6 +15,7 @@ const book = storiesOf('Components/Conversation/Message', module); | ||||||
| const baseDataProps: Pick< | const baseDataProps: Pick< | ||||||
|   PropsData, |   PropsData, | ||||||
|   | 'id' |   | 'id' | ||||||
|  |   | 'canReply' | ||||||
|   | 'conversationId' |   | 'conversationId' | ||||||
|   | 'interactionMode' |   | 'interactionMode' | ||||||
|   | 'conversationType' |   | 'conversationType' | ||||||
|  | @ -23,6 +24,7 @@ const baseDataProps: Pick< | ||||||
|   | 'authorPhoneNumber' |   | 'authorPhoneNumber' | ||||||
| > = { | > = { | ||||||
|   id: 'asdf', |   id: 'asdf', | ||||||
|  |   canReply: true, | ||||||
|   conversationId: 'asdf', |   conversationId: 'asdf', | ||||||
|   interactionMode: 'mouse', |   interactionMode: 'mouse', | ||||||
|   conversationType: 'direct', |   conversationType: 'direct', | ||||||
|  |  | ||||||
|  | @ -105,6 +105,8 @@ export type PropsData = { | ||||||
| 
 | 
 | ||||||
|   reactions?: ReactionViewerProps['reactions']; |   reactions?: ReactionViewerProps['reactions']; | ||||||
|   selectedReaction?: string; |   selectedReaction?: string; | ||||||
|  | 
 | ||||||
|  |   canReply: boolean; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| export type PropsHousekeeping = { | export type PropsHousekeeping = { | ||||||
|  | @ -986,6 +988,7 @@ export class Message extends React.PureComponent<Props, State> { | ||||||
|     const { |     const { | ||||||
|       attachments, |       attachments, | ||||||
|       // tslint:disable-next-line max-func-body-length
 |       // tslint:disable-next-line max-func-body-length
 | ||||||
|  |       canReply, | ||||||
|       direction, |       direction, | ||||||
|       disableMenu, |       disableMenu, | ||||||
|       id, |       id, | ||||||
|  | @ -1098,9 +1101,9 @@ export class Message extends React.PureComponent<Props, State> { | ||||||
|             `module-message__buttons--${direction}` |             `module-message__buttons--${direction}` | ||||||
|           )} |           )} | ||||||
|         > |         > | ||||||
|           {reactButton} |           {canReply ? reactButton : null} | ||||||
|           {downloadButton} |           {downloadButton} | ||||||
|           {replyButton} |           {canReply ? replyButton : null} | ||||||
|           {menuButton} |           {menuButton} | ||||||
|         </div> |         </div> | ||||||
|         {reactionPickerRoot && |         {reactionPickerRoot && | ||||||
|  | @ -1132,6 +1135,7 @@ export class Message extends React.PureComponent<Props, State> { | ||||||
|   public renderContextMenu(triggerId: string) { |   public renderContextMenu(triggerId: string) { | ||||||
|     const { |     const { | ||||||
|       attachments, |       attachments, | ||||||
|  |       canReply, | ||||||
|       deleteMessage, |       deleteMessage, | ||||||
|       direction, |       direction, | ||||||
|       i18n, |       i18n, | ||||||
|  | @ -1163,6 +1167,8 @@ export class Message extends React.PureComponent<Props, State> { | ||||||
|             {i18n('downloadAttachment')} |             {i18n('downloadAttachment')} | ||||||
|           </MenuItem> |           </MenuItem> | ||||||
|         ) : null} |         ) : null} | ||||||
|  |         {canReply ? ( | ||||||
|  |           <> | ||||||
|             <MenuItem |             <MenuItem | ||||||
|               attributes={{ |               attributes={{ | ||||||
|                 className: 'module-message__context__react', |                 className: 'module-message__context__react', | ||||||
|  | @ -1189,6 +1195,8 @@ export class Message extends React.PureComponent<Props, State> { | ||||||
|             > |             > | ||||||
|               {i18n('replyToMessage')} |               {i18n('replyToMessage')} | ||||||
|             </MenuItem> |             </MenuItem> | ||||||
|  |           </> | ||||||
|  |         ) : null} | ||||||
|         <MenuItem |         <MenuItem | ||||||
|           attributes={{ |           attributes={{ | ||||||
|             className: 'module-message__context__more-info', |             className: 'module-message__context__more-info', | ||||||
|  | @ -1831,10 +1839,14 @@ export class Message extends React.PureComponent<Props, State> { | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|   public handleKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => { |   public handleKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => { | ||||||
|  |     // Do not allow reactions to error messages
 | ||||||
|  |     const { canReply } = this.props; | ||||||
|  | 
 | ||||||
|     if ( |     if ( | ||||||
|       (event.key === 'E' || event.key === 'e') && |       (event.key === 'E' || event.key === 'e') && | ||||||
|       (event.metaKey || event.ctrlKey) && |       (event.metaKey || event.ctrlKey) && | ||||||
|       event.shiftKey |       event.shiftKey && | ||||||
|  |       canReply | ||||||
|     ) { |     ) { | ||||||
|       this.toggleReactionPicker(); |       this.toggleReactionPicker(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -9250,17 +9250,17 @@ | ||||||
|     "rule": "React-createRef", |     "rule": "React-createRef", | ||||||
|     "path": "ts/components/conversation/Message.tsx", |     "path": "ts/components/conversation/Message.tsx", | ||||||
|     "line": "  public audioRef: React.RefObject<HTMLAudioElement> = React.createRef();", |     "line": "  public audioRef: React.RefObject<HTMLAudioElement> = React.createRef();", | ||||||
|     "lineNumber": 178, |     "lineNumber": 180, | ||||||
|     "reasonCategory": "usageTrusted", |     "reasonCategory": "usageTrusted", | ||||||
|     "updated": "2020-02-03T17:18:39.600Z" |     "updated": "2020-02-07T22:17:41.885Z" | ||||||
|   }, |   }, | ||||||
|   { |   { | ||||||
|     "rule": "React-createRef", |     "rule": "React-createRef", | ||||||
|     "path": "ts/components/conversation/Message.tsx", |     "path": "ts/components/conversation/Message.tsx", | ||||||
|     "line": "  > = React.createRef();", |     "line": "  > = React.createRef();", | ||||||
|     "lineNumber": 182, |     "lineNumber": 184, | ||||||
|     "reasonCategory": "usageTrusted", |     "reasonCategory": "usageTrusted", | ||||||
|     "updated": "2020-02-03T17:18:39.600Z" |     "updated": "2020-02-07T22:17:41.885Z" | ||||||
|   }, |   }, | ||||||
|   { |   { | ||||||
|     "rule": "React-createRef", |     "rule": "React-createRef", | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Ken Powers
				Ken Powers