[Glitch] Rewrite actions/modal and reducers/modal with typescript
Port 38c6216082 to glitch-soc
Signed-off-by: Claire <claire.github-309c@sitedethib.com>
			
			
This commit is contained in:
		
				
					committed by
					
						 Claire
						Claire
					
				
			
			
				
	
			
			
			
						parent
						
							6a592083f1
						
					
				
				
					commit
					382b2a506a
				
			| @@ -95,6 +95,6 @@ export function initBlockModal(account) { | ||||
|       account, | ||||
|     }); | ||||
|  | ||||
|     dispatch(openModal('BLOCK')); | ||||
|     dispatch(openModal({ modalType: 'BLOCK' })); | ||||
|   }; | ||||
| } | ||||
|   | ||||
| @@ -14,7 +14,10 @@ export function initBoostModal(props) { | ||||
|       privacy, | ||||
|     }); | ||||
|  | ||||
|     dispatch(openModal('BOOST', props)); | ||||
|     dispatch(openModal({ | ||||
|       modalType: 'BOOST', | ||||
|       modalProps: props, | ||||
|     })); | ||||
|   }; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -416,7 +416,10 @@ export function initMediaEditModal(id) { | ||||
|       id, | ||||
|     }); | ||||
|  | ||||
|     dispatch(openModal('FOCAL_POINT', { id })); | ||||
|     dispatch(openModal({ | ||||
|       modalType: 'FOCAL_POINT', | ||||
|       modalProps: { id }, | ||||
|     })); | ||||
|   }; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -15,9 +15,12 @@ export const FILTERS_CREATE_SUCCESS = 'FILTERS_CREATE_SUCCESS'; | ||||
| export const FILTERS_CREATE_FAIL    = 'FILTERS_CREATE_FAIL'; | ||||
|  | ||||
| export const initAddFilter = (status, { contextType }) => dispatch => | ||||
|   dispatch(openModal('FILTER', { | ||||
|     statusId: status?.get('id'), | ||||
|     contextType: contextType, | ||||
|   dispatch(openModal({ | ||||
|     modalType: 'FILTER', | ||||
|     modalProps: { | ||||
|       statusId: status?.get('id'), | ||||
|       contextType: contextType, | ||||
|     }, | ||||
|   })); | ||||
|  | ||||
| export const fetchFilters = () => (dispatch, getState) => { | ||||
|   | ||||
| @@ -28,9 +28,12 @@ export function checkDeprecatedLocalSettings() { | ||||
|     } | ||||
|  | ||||
|     if (changed_settings.length > 0) { | ||||
|       dispatch(openModal('DEPRECATED_SETTINGS', { | ||||
|         settings: changed_settings, | ||||
|         onConfirm: () => dispatch(clearDeprecatedLocalSettings()), | ||||
|       dispatch(openModal({ | ||||
|         modalType: 'DEPRECATED_SETTINGS', | ||||
|         modalProps: { | ||||
|           settings: changed_settings, | ||||
|           onConfirm: () => dispatch(clearDeprecatedLocalSettings()), | ||||
|         }, | ||||
|       })); | ||||
|     } | ||||
|   }; | ||||
|   | ||||
| @@ -1,18 +0,0 @@ | ||||
| export const MODAL_OPEN  = 'MODAL_OPEN'; | ||||
| export const MODAL_CLOSE = 'MODAL_CLOSE'; | ||||
|  | ||||
| export function openModal(type, props) { | ||||
|   return { | ||||
|     type: MODAL_OPEN, | ||||
|     modalType: type, | ||||
|     modalProps: props, | ||||
|   }; | ||||
| } | ||||
|  | ||||
| export function closeModal(type, options = { ignoreFocus: false }) { | ||||
|   return { | ||||
|     type: MODAL_CLOSE, | ||||
|     modalType: type, | ||||
|     ignoreFocus: options.ignoreFocus, | ||||
|   }; | ||||
| } | ||||
							
								
								
									
										17
									
								
								app/javascript/flavours/glitch/actions/modal.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								app/javascript/flavours/glitch/actions/modal.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | ||||
| import { createAction } from '@reduxjs/toolkit'; | ||||
|  | ||||
| import type { MODAL_COMPONENTS } from '../features/ui/components/modal_root'; | ||||
|  | ||||
| export type ModalType = keyof typeof MODAL_COMPONENTS; | ||||
|  | ||||
| interface OpenModalPayload { | ||||
|   modalType: ModalType; | ||||
|   modalProps: unknown; | ||||
| } | ||||
| export const openModal = createAction<OpenModalPayload>('MODAL_OPEN'); | ||||
|  | ||||
| interface CloseModalPayload { | ||||
|   modalType: ModalType | undefined; | ||||
|   ignoreFocus: boolean; | ||||
| } | ||||
| export const closeModal = createAction<CloseModalPayload>('MODAL_CLOSE'); | ||||
| @@ -98,7 +98,7 @@ export function initMuteModal(account) { | ||||
|       account, | ||||
|     }); | ||||
|  | ||||
|     dispatch(openModal('MUTE')); | ||||
|     dispatch(openModal({ modalType: 'MUTE' })); | ||||
|   }; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -6,7 +6,9 @@ export function showOnboardingOnce() { | ||||
|     const alreadySeen = getState().getIn(['settings', 'onboarded']); | ||||
|  | ||||
|     if (!alreadySeen) { | ||||
|       dispatch(openModal('ONBOARDING')); | ||||
|       dispatch(openModal({ | ||||
|         modalType: 'ONBOARDING', | ||||
|       })); | ||||
|       dispatch(changeSetting(['onboarded'], true)); | ||||
|       dispatch(saveSettings()); | ||||
|     } | ||||
|   | ||||
| @@ -7,9 +7,12 @@ export const REPORT_SUBMIT_SUCCESS = 'REPORT_SUBMIT_SUCCESS'; | ||||
| export const REPORT_SUBMIT_FAIL    = 'REPORT_SUBMIT_FAIL'; | ||||
|  | ||||
| export const initReport = (account, status) => dispatch => | ||||
|   dispatch(openModal('REPORT', { | ||||
|     accountId: account.get('id'), | ||||
|     statusId: status?.get('id'), | ||||
|   dispatch(openModal({ | ||||
|     modalType: 'REPORT', | ||||
|     modalProps: { | ||||
|       accountId: account.get('id'), | ||||
|       statusId: status?.get('id'), | ||||
|     }, | ||||
|   })); | ||||
|  | ||||
| export const submitReport = (params, onSuccess, onFail) => (dispatch, getState) => { | ||||
|   | ||||
| @@ -15,7 +15,10 @@ import DropdownMenu from './containers/dropdown_menu_container'; | ||||
| const mapDispatchToProps = (dispatch, { statusId }) => ({ | ||||
|  | ||||
|   onItemClick (index) { | ||||
|     dispatch(openModal('COMPARE_HISTORY', { index, statusId })); | ||||
|     dispatch(openModal({ | ||||
|       modalType: 'COMPARE_HISTORY', | ||||
|       modalProps: { index, statusId }, | ||||
|     })); | ||||
|   }, | ||||
|  | ||||
| }); | ||||
|   | ||||
| @@ -35,10 +35,13 @@ const mapDispatchToProps = (dispatch, { intl }) => ({ | ||||
|   onFollow (account) { | ||||
|     if (account.getIn(['relationship', 'following']) || account.getIn(['relationship', 'requested'])) { | ||||
|       if (unfollowModal) { | ||||
|         dispatch(openModal('CONFIRM', { | ||||
|           message: <FormattedMessage id='confirmations.unfollow.message' defaultMessage='Are you sure you want to unfollow {name}?' values={{ name: <strong>@{account.get('acct')}</strong> }} />, | ||||
|           confirm: intl.formatMessage(messages.unfollowConfirm), | ||||
|           onConfirm: () => dispatch(unfollowAccount(account.get('id'))), | ||||
|         dispatch(openModal({ | ||||
|           modalType: 'CONFIRM', | ||||
|           modalProps: { | ||||
|             message: <FormattedMessage id='confirmations.unfollow.message' defaultMessage='Are you sure you want to unfollow {name}?' values={{ name: <strong>@{account.get('acct')}</strong> }} />, | ||||
|             confirm: intl.formatMessage(messages.unfollowConfirm), | ||||
|             onConfirm: () => dispatch(unfollowAccount(account.get('id'))), | ||||
|           }, | ||||
|         })); | ||||
|       } else { | ||||
|         dispatch(unfollowAccount(account.get('id'))); | ||||
|   | ||||
| @@ -18,10 +18,13 @@ const makeMapStateToProps = () => { | ||||
|  | ||||
| const mapDispatchToProps = (dispatch, { intl }) => ({ | ||||
|   onBlockDomain (domain) { | ||||
|     dispatch(openModal('CONFIRM', { | ||||
|       message: <FormattedMessage id='confirmations.domain_block.message' defaultMessage='Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable. You will not see content from that domain in any public timelines or your notifications. Your followers from that domain will be removed.' values={{ domain: <strong>{domain}</strong> }} />, | ||||
|       confirm: intl.formatMessage(messages.blockDomainConfirm), | ||||
|       onConfirm: () => dispatch(blockDomain(domain)), | ||||
|     dispatch(openModal({ | ||||
|       modalType: 'CONFIRM', | ||||
|       modalProps: { | ||||
|         message: <FormattedMessage id='confirmations.domain_block.message' defaultMessage='Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable. You will not see content from that domain in any public timelines or your notifications. Your followers from that domain will be removed.' values={{ domain: <strong>{domain}</strong> }} />, | ||||
|         confirm: intl.formatMessage(messages.blockDomainConfirm), | ||||
|         onConfirm: () => dispatch(blockDomain(domain)), | ||||
|       }, | ||||
|     })); | ||||
|   }, | ||||
|  | ||||
|   | ||||
| @@ -13,10 +13,13 @@ const mapStateToProps = state => ({ | ||||
|  | ||||
| const mapDispatchToProps = (dispatch, { status, items, scrollKey }) => ({ | ||||
|   onOpen(id, onItemClick, keyboard) { | ||||
|     dispatch(isUserTouching() ? openModal('ACTIONS', { | ||||
|       status, | ||||
|       actions: items, | ||||
|       onClick: onItemClick, | ||||
|     dispatch(isUserTouching() ? openModal({ | ||||
|       modalType: 'ACTIONS', | ||||
|       modalProps: { | ||||
|         status, | ||||
|         actions: items, | ||||
|         onClick: onItemClick, | ||||
|       }, | ||||
|     }) : openDropdownMenu(id, keyboard, scrollKey)); | ||||
|   }, | ||||
|  | ||||
|   | ||||
| @@ -23,10 +23,13 @@ const mapDispatchToProps = (dispatch, { intl }) => ({ | ||||
|   }, | ||||
|  | ||||
|   onDeleteMarked() { | ||||
|     dispatch(openModal('CONFIRM', { | ||||
|       message: intl.formatMessage(messages.clearMessage), | ||||
|       confirm: intl.formatMessage(messages.clearConfirm), | ||||
|       onConfirm: () => dispatch(deleteMarkedNotifications()), | ||||
|     dispatch(openModal({ | ||||
|       modalType: 'CONFIRM', | ||||
|       modalProps: { | ||||
|         message: intl.formatMessage(messages.clearMessage), | ||||
|         confirm: intl.formatMessage(messages.clearConfirm), | ||||
|         onConfirm: () => dispatch(deleteMarkedNotifications()), | ||||
|       }, | ||||
|     })); | ||||
|   }, | ||||
|  | ||||
|   | ||||
| @@ -99,11 +99,14 @@ const mapDispatchToProps = (dispatch, { intl, contextType }) => ({ | ||||
|       let state = getState(); | ||||
|  | ||||
|       if (state.getIn(['local_settings', 'confirm_before_clearing_draft']) && state.getIn(['compose', 'text']).trim().length !== 0) { | ||||
|         dispatch(openModal('CONFIRM', { | ||||
|           message: intl.formatMessage(messages.replyMessage), | ||||
|           confirm: intl.formatMessage(messages.replyConfirm), | ||||
|           onDoNotAsk: () => dispatch(changeLocalSetting(['confirm_before_clearing_draft'], false)), | ||||
|           onConfirm: () => dispatch(replyCompose(status, router)), | ||||
|         dispatch(openModal({ | ||||
|           modalType: 'CONFIRM', | ||||
|           modalProps: { | ||||
|             message: intl.formatMessage(messages.replyMessage), | ||||
|             confirm: intl.formatMessage(messages.replyConfirm), | ||||
|             onDoNotAsk: () => dispatch(changeLocalSetting(['confirm_before_clearing_draft'], false)), | ||||
|             onConfirm: () => dispatch(replyCompose(status, router)), | ||||
|           }, | ||||
|         })); | ||||
|       } else { | ||||
|         dispatch(replyCompose(status, router)); | ||||
| @@ -151,7 +154,13 @@ const mapDispatchToProps = (dispatch, { intl, contextType }) => ({ | ||||
|       if (e.shiftKey || !favouriteModal) { | ||||
|         this.onModalFavourite(status); | ||||
|       } else { | ||||
|         dispatch(openModal('FAVOURITE', { status, onFavourite: this.onModalFavourite })); | ||||
|         dispatch(openModal({ | ||||
|           modalType: 'FAVOURITE', | ||||
|           modalProps: { | ||||
|             status, | ||||
|             onFavourite: this.onModalFavourite, | ||||
|           }, | ||||
|         })); | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
| @@ -165,9 +174,12 @@ const mapDispatchToProps = (dispatch, { intl, contextType }) => ({ | ||||
|   }, | ||||
|  | ||||
|   onEmbed (status) { | ||||
|     dispatch(openModal('EMBED', { | ||||
|       url: status.get('url'), | ||||
|       onError: error => dispatch(showAlertForError(error)), | ||||
|     dispatch(openModal({ | ||||
|       modalType: 'EMBED', | ||||
|       modalProps: { | ||||
|         url: status.get('url'), | ||||
|         onError: error => dispatch(showAlertForError(error)), | ||||
|       }, | ||||
|     })); | ||||
|   }, | ||||
|  | ||||
| @@ -175,10 +187,13 @@ const mapDispatchToProps = (dispatch, { intl, contextType }) => ({ | ||||
|     if (!deleteModal) { | ||||
|       dispatch(deleteStatus(status.get('id'), history, withRedraft)); | ||||
|     } else { | ||||
|       dispatch(openModal('CONFIRM', { | ||||
|         message: intl.formatMessage(withRedraft ? messages.redraftMessage : messages.deleteMessage), | ||||
|         confirm: intl.formatMessage(withRedraft ? messages.redraftConfirm : messages.deleteConfirm), | ||||
|         onConfirm: () => dispatch(deleteStatus(status.get('id'), history, withRedraft)), | ||||
|       dispatch(openModal({ | ||||
|         modalType: 'CONFIRM', | ||||
|         modalProps: { | ||||
|           message: intl.formatMessage(withRedraft ? messages.redraftMessage : messages.deleteMessage), | ||||
|           confirm: intl.formatMessage(withRedraft ? messages.redraftConfirm : messages.deleteConfirm), | ||||
|           onConfirm: () => dispatch(deleteStatus(status.get('id'), history, withRedraft)), | ||||
|         }, | ||||
|       })); | ||||
|     } | ||||
|   }, | ||||
| @@ -187,10 +202,13 @@ const mapDispatchToProps = (dispatch, { intl, contextType }) => ({ | ||||
|     dispatch((_, getState) => { | ||||
|       let state = getState(); | ||||
|       if (state.getIn(['compose', 'text']).trim().length !== 0) { | ||||
|         dispatch(openModal('CONFIRM', { | ||||
|           message: intl.formatMessage(messages.editMessage), | ||||
|           confirm: intl.formatMessage(messages.editConfirm), | ||||
|           onConfirm: () => dispatch(editStatus(status.get('id'), history)), | ||||
|         dispatch(openModal({ | ||||
|           modalType: 'CONFIRM', | ||||
|           modalProps: { | ||||
|             message: intl.formatMessage(messages.editMessage), | ||||
|             confirm: intl.formatMessage(messages.editConfirm), | ||||
|             onConfirm: () => dispatch(editStatus(status.get('id'), history)), | ||||
|           }, | ||||
|         })); | ||||
|       } else { | ||||
|         dispatch(editStatus(status.get('id'), history)); | ||||
| @@ -215,11 +233,17 @@ const mapDispatchToProps = (dispatch, { intl, contextType }) => ({ | ||||
|   }, | ||||
|  | ||||
|   onOpenMedia (statusId, media, index, lang) { | ||||
|     dispatch(openModal('MEDIA', { statusId, media, index, lang })); | ||||
|     dispatch(openModal({ | ||||
|       modalType: 'MEDIA', | ||||
|       modalProps: { statusId, media, index, lang }, | ||||
|     })); | ||||
|   }, | ||||
|  | ||||
|   onOpenVideo (statusId, media, lang, options) { | ||||
|     dispatch(openModal('VIDEO', { statusId, media, lang, options })); | ||||
|     dispatch(openModal({ | ||||
|       modalType: 'VIDEO', | ||||
|       modalProps: { statusId, media, lang, options }, | ||||
|     })); | ||||
|   }, | ||||
|  | ||||
|   onBlock (status) { | ||||
| @@ -264,10 +288,13 @@ const mapDispatchToProps = (dispatch, { intl, contextType }) => ({ | ||||
|   }, | ||||
|  | ||||
|   onInteractionModal (type, status) { | ||||
|     dispatch(openModal('INTERACTION', { | ||||
|       type, | ||||
|       accountId: status.getIn(['account', 'id']), | ||||
|       url: status.get('url'), | ||||
|     dispatch(openModal({ | ||||
|       modalType: 'INTERACTION', | ||||
|       modalProps: { | ||||
|         type, | ||||
|         accountId: status.getIn(['account', 'id']), | ||||
|         url: status.get('url'), | ||||
|       }, | ||||
|     })); | ||||
|   }, | ||||
|  | ||||
|   | ||||
| @@ -149,14 +149,23 @@ class AccountGallery extends ImmutablePureComponent { | ||||
|     const lang = attachment.getIn(['status', 'language']); | ||||
|  | ||||
|     if (attachment.get('type') === 'video') { | ||||
|       dispatch(openModal('VIDEO', { media: attachment, statusId, lang, options: { autoPlay: true } })); | ||||
|       dispatch(openModal({ | ||||
|         modalType: 'VIDEO', | ||||
|         modalProps: { media: attachment, statusId, lang, options: { autoPlay: true } }, | ||||
|       })); | ||||
|     } else if (attachment.get('type') === 'audio') { | ||||
|       dispatch(openModal('AUDIO', { media: attachment, statusId, lang, options: { autoPlay: true } })); | ||||
|       dispatch(openModal({ | ||||
|         modalType: 'AUDIO', | ||||
|         modalProps: { media: attachment, statusId, lang, options: { autoPlay: true } }, | ||||
|       })); | ||||
|     } else { | ||||
|       const media = attachment.getIn(['status', 'media_attachments']); | ||||
|       const index = media.findIndex(x => x.get('id') === attachment.get('id')); | ||||
|  | ||||
|       dispatch(openModal('MEDIA', { media, index, statusId, lang })); | ||||
|       dispatch(openModal({ | ||||
|         modalType: 'MEDIA', | ||||
|         modalProps: { media, index, statusId, lang }, | ||||
|       })); | ||||
|     } | ||||
|   }; | ||||
|  | ||||
|   | ||||
| @@ -48,20 +48,26 @@ const mapDispatchToProps = (dispatch, { intl }) => ({ | ||||
|   onFollow (account) { | ||||
|     if (account.getIn(['relationship', 'following'])) { | ||||
|       if (unfollowModal) { | ||||
|         dispatch(openModal('CONFIRM', { | ||||
|           message: <FormattedMessage id='confirmations.unfollow.message' defaultMessage='Are you sure you want to unfollow {name}?' values={{ name: <strong>@{account.get('acct')}</strong> }} />, | ||||
|           confirm: intl.formatMessage(messages.unfollowConfirm), | ||||
|           onConfirm: () => dispatch(unfollowAccount(account.get('id'))), | ||||
|         dispatch(openModal({ | ||||
|           modalType: 'CONFIRM', | ||||
|           modalProps: { | ||||
|             message: <FormattedMessage id='confirmations.unfollow.message' defaultMessage='Are you sure you want to unfollow {name}?' values={{ name: <strong>@{account.get('acct')}</strong> }} />, | ||||
|             confirm: intl.formatMessage(messages.unfollowConfirm), | ||||
|             onConfirm: () => dispatch(unfollowAccount(account.get('id'))), | ||||
|           }, | ||||
|         })); | ||||
|       } else { | ||||
|         dispatch(unfollowAccount(account.get('id'))); | ||||
|       } | ||||
|     } else if (account.getIn(['relationship', 'requested'])) { | ||||
|       if (unfollowModal) { | ||||
|         dispatch(openModal('CONFIRM', { | ||||
|           message: <FormattedMessage id='confirmations.cancel_follow_request.message' defaultMessage='Are you sure you want to withdraw your request to follow {name}?' values={{ name: <strong>@{account.get('acct')}</strong> }} />, | ||||
|           confirm: intl.formatMessage(messages.cancelFollowRequestConfirm), | ||||
|           onConfirm: () => dispatch(unfollowAccount(account.get('id'))), | ||||
|         dispatch(openModal({ | ||||
|           modalType: 'CONFIRM', | ||||
|           modalProps: { | ||||
|             message: <FormattedMessage id='confirmations.cancel_follow_request.message' defaultMessage='Are you sure you want to withdraw your request to follow {name}?' values={{ name: <strong>@{account.get('acct')}</strong> }} />, | ||||
|             confirm: intl.formatMessage(messages.cancelFollowRequestConfirm), | ||||
|             onConfirm: () => dispatch(unfollowAccount(account.get('id'))), | ||||
|           }, | ||||
|         })); | ||||
|       } else { | ||||
|         dispatch(unfollowAccount(account.get('id'))); | ||||
| @@ -72,10 +78,13 @@ const mapDispatchToProps = (dispatch, { intl }) => ({ | ||||
|   }, | ||||
|  | ||||
|   onInteractionModal (account) { | ||||
|     dispatch(openModal('INTERACTION', { | ||||
|       type: 'follow', | ||||
|       accountId: account.get('id'), | ||||
|       url: account.get('url'), | ||||
|     dispatch(openModal({ | ||||
|       modalType: 'INTERACTION', | ||||
|       modalProps: { | ||||
|         type: 'follow', | ||||
|         accountId: account.get('id'), | ||||
|         url: account.get('url'), | ||||
|       }, | ||||
|     })); | ||||
|   }, | ||||
|  | ||||
| @@ -136,10 +145,13 @@ const mapDispatchToProps = (dispatch, { intl }) => ({ | ||||
|   }, | ||||
|  | ||||
|   onBlockDomain (domain) { | ||||
|     dispatch(openModal('CONFIRM', { | ||||
|       message: <FormattedMessage id='confirmations.domain_block.message' defaultMessage='Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable.' values={{ domain: <strong>{domain}</strong> }} />, | ||||
|       confirm: intl.formatMessage(messages.blockDomainConfirm), | ||||
|       onConfirm: () => dispatch(blockDomain(domain)), | ||||
|     dispatch(openModal({ | ||||
|       modalType: 'CONFIRM', | ||||
|       modalProps: { | ||||
|         message: <FormattedMessage id='confirmations.domain_block.message' defaultMessage='Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable.' values={{ domain: <strong>{domain}</strong> }} />, | ||||
|         confirm: intl.formatMessage(messages.blockDomainConfirm), | ||||
|         onConfirm: () => dispatch(blockDomain(domain)), | ||||
|       }, | ||||
|     })); | ||||
|   }, | ||||
|  | ||||
| @@ -148,21 +160,30 @@ const mapDispatchToProps = (dispatch, { intl }) => ({ | ||||
|   }, | ||||
|  | ||||
|   onAddToList (account) { | ||||
|     dispatch(openModal('LIST_ADDER', { | ||||
|       accountId: account.get('id'), | ||||
|     dispatch(openModal({ | ||||
|       modalType: 'LIST_ADDER', | ||||
|       modalProps: { | ||||
|         accountId: account.get('id'), | ||||
|       }, | ||||
|     })); | ||||
|   }, | ||||
|  | ||||
|   onChangeLanguages (account) { | ||||
|     dispatch(openModal('SUBSCRIBED_LANGUAGES', { | ||||
|       accountId: account.get('id'), | ||||
|     dispatch(openModal({ | ||||
|       modalType: 'SUBSCRIBED_LANGUAGES', | ||||
|       modalProps: { | ||||
|         accountId: account.get('id'), | ||||
|       }, | ||||
|     })); | ||||
|   }, | ||||
|  | ||||
|   onOpenAvatar (account) { | ||||
|     dispatch(openModal('IMAGE', { | ||||
|       src: account.get('avatar'), | ||||
|       alt: account.get('acct'), | ||||
|     dispatch(openModal({ | ||||
|       modalType: 'IMAGE', | ||||
|       modalProps: { | ||||
|         src: account.get('avatar'), | ||||
|         alt: account.get('acct'), | ||||
|       }, | ||||
|     })); | ||||
|   }, | ||||
|  | ||||
|   | ||||
| @@ -126,18 +126,24 @@ const mapDispatchToProps = (dispatch, { intl }) => ({ | ||||
|   }, | ||||
|  | ||||
|   onMediaDescriptionConfirm(routerHistory, mediaId, overriddenVisibility = null) { | ||||
|     dispatch(openModal('CONFIRM', { | ||||
|       message: intl.formatMessage(messages.missingDescriptionMessage), | ||||
|       confirm: intl.formatMessage(messages.missingDescriptionConfirm), | ||||
|       onConfirm: () => { | ||||
|         if (overriddenVisibility) { | ||||
|           dispatch(changeComposeVisibility(overriddenVisibility)); | ||||
|         } | ||||
|         dispatch(submitCompose(routerHistory)); | ||||
|     dispatch(openModal({ | ||||
|       modalType: 'CONFIRM', | ||||
|       modalProps: { | ||||
|         message: intl.formatMessage(messages.missingDescriptionMessage), | ||||
|         confirm: intl.formatMessage(messages.missingDescriptionConfirm), | ||||
|         onConfirm: () => { | ||||
|           if (overriddenVisibility) { | ||||
|             dispatch(changeComposeVisibility(overriddenVisibility)); | ||||
|           } | ||||
|           dispatch(submitCompose(routerHistory)); | ||||
|         }, | ||||
|         secondary: intl.formatMessage(messages.missingDescriptionEdit), | ||||
|         onSecondary: () => dispatch(openModal({ | ||||
|           modalType: 'FOCAL_POINT', | ||||
|           modalProps: { id: mediaId }, | ||||
|         })), | ||||
|         onDoNotAsk: () => dispatch(changeLocalSetting(['confirm_missing_media_description'], false)), | ||||
|       }, | ||||
|       secondary: intl.formatMessage(messages.missingDescriptionEdit), | ||||
|       onSecondary: () => dispatch(openModal('FOCAL_POINT', { id: mediaId })), | ||||
|       onDoNotAsk: () => dispatch(changeLocalSetting(['confirm_missing_media_description'], false)), | ||||
|     })); | ||||
|   }, | ||||
|  | ||||
|   | ||||
| @@ -7,7 +7,7 @@ import Dropdown from '../components/dropdown'; | ||||
|  | ||||
| const mapDispatchToProps = dispatch => ({ | ||||
|   isUserTouching, | ||||
|   onModalOpen: props => dispatch(openModal('ACTIONS', props)), | ||||
|   onModalOpen: props => dispatch(openModal({ modalType: 'ACTIONS', modalProps: props })), | ||||
|   onModalClose: () => dispatch(closeModal()), | ||||
| }); | ||||
|  | ||||
|   | ||||
| @@ -24,14 +24,17 @@ const mapDispatchToProps = (dispatch, { intl }) => ({ | ||||
|   onSettingsClick (e) { | ||||
|     e.preventDefault(); | ||||
|     e.stopPropagation(); | ||||
|     dispatch(openModal('SETTINGS', {})); | ||||
|     dispatch(openModal({ modalType: 'SETTINGS', modalProps: {} })); | ||||
|   }, | ||||
|   onLogout () { | ||||
|     dispatch(openModal('CONFIRM', { | ||||
|       message: intl.formatMessage(messages.logoutMessage), | ||||
|       confirm: intl.formatMessage(messages.logoutConfirm), | ||||
|       closeWhenConfirm: false, | ||||
|       onConfirm: () => logOut(), | ||||
|     dispatch(openModal({ | ||||
|       modalType: 'CONFIRM', | ||||
|       modalProps: { | ||||
|         message: intl.formatMessage(messages.logoutMessage), | ||||
|         confirm: intl.formatMessage(messages.logoutConfirm), | ||||
|         closeWhenConfirm: false, | ||||
|         onConfirm: () => logOut(), | ||||
|       }, | ||||
|     })); | ||||
|   }, | ||||
| }); | ||||
|   | ||||
| @@ -21,11 +21,14 @@ const mapStateToProps = state => { | ||||
|  | ||||
| const mapDispatchToProps = (dispatch, { intl }) => ({ | ||||
|   onLogout () { | ||||
|     dispatch(openModal('CONFIRM', { | ||||
|       message: intl.formatMessage(messages.logoutMessage), | ||||
|       confirm: intl.formatMessage(messages.logoutConfirm), | ||||
|       closeWhenConfirm: false, | ||||
|       onConfirm: () => logOut(), | ||||
|     dispatch(openModal({ | ||||
|       modalType: 'CONFIRM', | ||||
|       modalProps: { | ||||
|         message: intl.formatMessage(messages.logoutMessage), | ||||
|         confirm: intl.formatMessage(messages.logoutConfirm), | ||||
|         closeWhenConfirm: false, | ||||
|         onConfirm: () => logOut(), | ||||
|       }, | ||||
|     })); | ||||
|   }, | ||||
| }); | ||||
|   | ||||
| @@ -46,7 +46,10 @@ const mapDispatchToProps = (dispatch) => ({ | ||||
|   }, | ||||
|  | ||||
|   onDoodleOpen() { | ||||
|     dispatch(openModal('DOODLE', { noEsc: true, noClose: true })); | ||||
|     dispatch(openModal({ | ||||
|       modalType: 'DOODLE', | ||||
|       modalProps: { noEsc: true, noClose: true }, | ||||
|     })); | ||||
|   }, | ||||
| }); | ||||
|  | ||||
|   | ||||
| @@ -17,8 +17,14 @@ const mapDispatchToProps = dispatch => ({ | ||||
|   }, | ||||
|  | ||||
|   isUserTouching, | ||||
|   onModalOpen: props => dispatch(openModal('ACTIONS', props)), | ||||
|   onModalClose: () => dispatch(closeModal()), | ||||
|   onModalOpen: props => dispatch(openModal({ | ||||
|     modalType: 'ACTIONS', | ||||
|     modalProps: props, | ||||
|   })), | ||||
|   onModalClose: () => dispatch(closeModal({ | ||||
|     modalType: undefined, | ||||
|     ignoreFocus: false, | ||||
|   })), | ||||
|  | ||||
| }); | ||||
|  | ||||
|   | ||||
| @@ -42,10 +42,13 @@ const mapDispatchToProps = (dispatch, { intl, conversationId }) => ({ | ||||
|       let state = getState(); | ||||
|  | ||||
|       if (state.getIn(['compose', 'text']).trim().length !== 0) { | ||||
|         dispatch(openModal('CONFIRM', { | ||||
|           message: intl.formatMessage(messages.replyMessage), | ||||
|           confirm: intl.formatMessage(messages.replyConfirm), | ||||
|           onConfirm: () => dispatch(replyCompose(status, router)), | ||||
|         dispatch(openModal({ | ||||
|           modalType: 'CONFIRM', | ||||
|           modalProps: { | ||||
|             message: intl.formatMessage(messages.replyMessage), | ||||
|             confirm: intl.formatMessage(messages.replyConfirm), | ||||
|             onConfirm: () => dispatch(replyCompose(status, router)), | ||||
|           }, | ||||
|         })); | ||||
|       } else { | ||||
|         dispatch(replyCompose(status, router)); | ||||
|   | ||||
| @@ -53,27 +53,32 @@ const mapDispatchToProps = (dispatch, { intl }) => ({ | ||||
|     if (account.getIn(['relationship', 'following'])) { | ||||
|       if (unfollowModal) { | ||||
|         dispatch( | ||||
|           openModal('CONFIRM', { | ||||
|             message: ( | ||||
|               <FormattedMessage | ||||
|                 id='confirmations.unfollow.message' | ||||
|                 defaultMessage='Are you sure you want to unfollow {name}?' | ||||
|                 values={{ name: <strong>@{account.get('acct')}</strong> }} | ||||
|               /> | ||||
|             ), | ||||
|             confirm: intl.formatMessage(messages.unfollowConfirm), | ||||
|             onConfirm: () => dispatch(unfollowAccount(account.get('id'))), | ||||
|           }), | ||||
|           openModal({ | ||||
|             modalType: 'CONFIRM', | ||||
|             modalProps: { | ||||
|               message: ( | ||||
|                 <FormattedMessage | ||||
|                   id='confirmations.unfollow.message' | ||||
|                   defaultMessage='Are you sure you want to unfollow {name}?' | ||||
|                   values={{ name: <strong>@{account.get('acct')}</strong> }} | ||||
|                 /> | ||||
|               ), | ||||
|               confirm: intl.formatMessage(messages.unfollowConfirm), | ||||
|               onConfirm: () => dispatch(unfollowAccount(account.get('id'))), | ||||
|             } }), | ||||
|         ); | ||||
|       } else { | ||||
|         dispatch(unfollowAccount(account.get('id'))); | ||||
|       } | ||||
|     } else if (account.getIn(['relationship', 'requested'])) { | ||||
|       if (unfollowModal) { | ||||
|         dispatch(openModal('CONFIRM', { | ||||
|           message: <FormattedMessage id='confirmations.cancel_follow_request.message' defaultMessage='Are you sure you want to withdraw your request to follow {name}?' values={{ name: <strong>@{account.get('acct')}</strong> }} />, | ||||
|           confirm: intl.formatMessage(messages.cancelFollowRequestConfirm), | ||||
|           onConfirm: () => dispatch(unfollowAccount(account.get('id'))), | ||||
|         dispatch(openModal({ | ||||
|           modalType: 'CONFIRM', | ||||
|           modalProps: { | ||||
|             message: <FormattedMessage id='confirmations.cancel_follow_request.message' defaultMessage='Are you sure you want to withdraw your request to follow {name}?' values={{ name: <strong>@{account.get('acct')}</strong> }} />, | ||||
|             confirm: intl.formatMessage(messages.cancelFollowRequestConfirm), | ||||
|             onConfirm: () => dispatch(unfollowAccount(account.get('id'))), | ||||
|           }, | ||||
|         })); | ||||
|       } else { | ||||
|         dispatch(unfollowAccount(account.get('id'))); | ||||
|   | ||||
| @@ -69,7 +69,10 @@ const makeMapStateToProps = () => { | ||||
| const mapDispatchToProps = dispatch => ({ | ||||
|   fetchFollowRequests: () => dispatch(fetchFollowRequests()), | ||||
|   fetchLists: () => dispatch(fetchLists()), | ||||
|   openSettings: () => dispatch(openModal('SETTINGS', {})), | ||||
|   openSettings: () => dispatch(openModal({ | ||||
|     modalType: 'SETTINGS', | ||||
|     modalProps: {}, | ||||
|   })), | ||||
| }); | ||||
|  | ||||
| const badgeDisplay = (number, limit) => { | ||||
|   | ||||
| @@ -38,11 +38,15 @@ class GettingStartedMisc extends ImmutablePureComponent { | ||||
|   }; | ||||
|  | ||||
|   openOnboardingModal = () => { | ||||
|     this.props.dispatch(openModal('ONBOARDING')); | ||||
|     this.props.dispatch(openModal({ | ||||
|       modalType: 'ONBOARDING', | ||||
|     })); | ||||
|   }; | ||||
|  | ||||
|   openFeaturedAccountsModal = () => { | ||||
|     this.props.dispatch(openModal('PINNED_ACCOUNTS_EDITOR')); | ||||
|     this.props.dispatch(openModal({ | ||||
|       modalType: 'PINNED_ACCOUNTS_EDITOR', | ||||
|     })); | ||||
|   }; | ||||
|  | ||||
|   render () { | ||||
|   | ||||
| @@ -18,8 +18,11 @@ const mapStateToProps = (state, { accountId }) => ({ | ||||
|  | ||||
| const mapDispatchToProps = (dispatch) => ({ | ||||
|   onSignupClick() { | ||||
|     dispatch(closeModal()); | ||||
|     dispatch(openModal('CLOSED_REGISTRATIONS')); | ||||
|     dispatch(closeModal({ | ||||
|       modalType: undefined, | ||||
|       ignoreFocus: false, | ||||
|     })); | ||||
|     dispatch(openModal({ modalType: 'CLOSED_REGISTRATIONS' })); | ||||
|   }, | ||||
| }); | ||||
|  | ||||
|   | ||||
| @@ -114,24 +114,30 @@ class ListTimeline extends PureComponent { | ||||
|   }; | ||||
|  | ||||
|   handleEditClick = () => { | ||||
|     this.props.dispatch(openModal('LIST_EDITOR', { listId: this.props.params.id })); | ||||
|     this.props.dispatch(openModal({ | ||||
|       modalType: 'LIST_EDITOR', | ||||
|       modalProps: { listId: this.props.params.id }, | ||||
|     })); | ||||
|   }; | ||||
|  | ||||
|   handleDeleteClick = () => { | ||||
|     const { dispatch, columnId, intl } = this.props; | ||||
|     const { id } = this.props.params; | ||||
|  | ||||
|     dispatch(openModal('CONFIRM', { | ||||
|       message: intl.formatMessage(messages.deleteMessage), | ||||
|       confirm: intl.formatMessage(messages.deleteConfirm), | ||||
|       onConfirm: () => { | ||||
|         dispatch(deleteList(id)); | ||||
|     dispatch(openModal({ | ||||
|       modalType: 'CONFIRM', | ||||
|       modalProps: { | ||||
|         message: intl.formatMessage(messages.deleteMessage), | ||||
|         confirm: intl.formatMessage(messages.deleteConfirm), | ||||
|         onConfirm: () => { | ||||
|           dispatch(deleteList(id)); | ||||
|  | ||||
|         if (columnId) { | ||||
|           dispatch(removeColumn(columnId)); | ||||
|         } else { | ||||
|           this.context.router.history.push('/lists'); | ||||
|         } | ||||
|           if (columnId) { | ||||
|             dispatch(removeColumn(columnId)); | ||||
|           } else { | ||||
|             this.context.router.history.push('/lists'); | ||||
|           } | ||||
|         }, | ||||
|       }, | ||||
|     })); | ||||
|   }; | ||||
|   | ||||
| @@ -61,10 +61,13 @@ const mapDispatchToProps = (dispatch, { intl }) => ({ | ||||
|   }, | ||||
|  | ||||
|   onClear () { | ||||
|     dispatch(openModal('CONFIRM', { | ||||
|       message: intl.formatMessage(messages.clearMessage), | ||||
|       confirm: intl.formatMessage(messages.clearConfirm), | ||||
|       onConfirm: () => dispatch(clearNotifications()), | ||||
|     dispatch(openModal({ | ||||
|       modalType: 'CONFIRM', | ||||
|       modalProps: { | ||||
|         message: intl.formatMessage(messages.clearMessage), | ||||
|         confirm: intl.formatMessage(messages.clearConfirm), | ||||
|         onConfirm: () => dispatch(clearNotifications()), | ||||
|       }, | ||||
|     })); | ||||
|   }, | ||||
|  | ||||
|   | ||||
| @@ -76,19 +76,25 @@ class Footer extends ImmutablePureComponent { | ||||
|  | ||||
|     if (signedIn) { | ||||
|       if (askReplyConfirmation) { | ||||
|         dispatch(openModal('CONFIRM', { | ||||
|           message: intl.formatMessage(messages.replyMessage), | ||||
|           confirm: intl.formatMessage(messages.replyConfirm), | ||||
|           onConfirm: this._performReply, | ||||
|         dispatch(openModal({ | ||||
|           modalType: 'CONFIRM', | ||||
|           modalProps: { | ||||
|             message: intl.formatMessage(messages.replyMessage), | ||||
|             confirm: intl.formatMessage(messages.replyConfirm), | ||||
|             onConfirm: this._performReply, | ||||
|           }, | ||||
|         })); | ||||
|       } else { | ||||
|         this._performReply(); | ||||
|       } | ||||
|     } else { | ||||
|       dispatch(openModal('INTERACTION', { | ||||
|         type: 'reply', | ||||
|         accountId: status.getIn(['account', 'id']), | ||||
|         url: status.get('url'), | ||||
|       dispatch(openModal({ | ||||
|         modalType: 'INTERACTION', | ||||
|         modalProps: { | ||||
|           type: 'reply', | ||||
|           accountId: status.getIn(['account', 'id']), | ||||
|           url: status.get('url'), | ||||
|         }, | ||||
|       })); | ||||
|     } | ||||
|   }; | ||||
| @@ -104,10 +110,13 @@ class Footer extends ImmutablePureComponent { | ||||
|         dispatch(favourite(status)); | ||||
|       } | ||||
|     } else { | ||||
|       dispatch(openModal('INTERACTION', { | ||||
|         type: 'favourite', | ||||
|         accountId: status.getIn(['account', 'id']), | ||||
|         url: status.get('url'), | ||||
|       dispatch(openModal({ | ||||
|         modalType: 'INTERACTION', | ||||
|         modalProps: { | ||||
|           type: 'favourite', | ||||
|           accountId: status.getIn(['account', 'id']), | ||||
|           url: status.get('url'), | ||||
|         }, | ||||
|       })); | ||||
|     } | ||||
|   }; | ||||
| @@ -130,10 +139,13 @@ class Footer extends ImmutablePureComponent { | ||||
|         dispatch(initBoostModal({ status, onReblog: this._performReblog })); | ||||
|       } | ||||
|     } else { | ||||
|       dispatch(openModal('INTERACTION', { | ||||
|         type: 'reblog', | ||||
|         accountId: status.getIn(['account', 'id']), | ||||
|         url: status.get('url'), | ||||
|       dispatch(openModal({ | ||||
|         modalType: 'INTERACTION', | ||||
|         modalProps: { | ||||
|           type: 'reblog', | ||||
|           accountId: status.getIn(['account', 'id']), | ||||
|           url: status.get('url'), | ||||
|         }, | ||||
|       })); | ||||
|     } | ||||
|   }; | ||||
|   | ||||
| @@ -58,10 +58,13 @@ const mapDispatchToProps = (dispatch, { intl }) => ({ | ||||
|     dispatch((_, getState) => { | ||||
|       let state = getState(); | ||||
|       if (state.getIn(['compose', 'text']).trim().length !== 0) { | ||||
|         dispatch(openModal('CONFIRM', { | ||||
|           message: intl.formatMessage(messages.replyMessage), | ||||
|           confirm: intl.formatMessage(messages.replyConfirm), | ||||
|           onConfirm: () => dispatch(replyCompose(status, router)), | ||||
|         dispatch(openModal({ | ||||
|           modalType: 'CONFIRM', | ||||
|           modalProps: { | ||||
|             message: intl.formatMessage(messages.replyMessage), | ||||
|             confirm: intl.formatMessage(messages.replyConfirm), | ||||
|             onConfirm: () => dispatch(replyCompose(status, router)), | ||||
|           }, | ||||
|         })); | ||||
|       } else { | ||||
|         dispatch(replyCompose(status, router)); | ||||
| @@ -102,9 +105,12 @@ const mapDispatchToProps = (dispatch, { intl }) => ({ | ||||
|   }, | ||||
|  | ||||
|   onEmbed (status) { | ||||
|     dispatch(openModal('EMBED', { | ||||
|       url: status.get('url'), | ||||
|       onError: error => dispatch(showAlertForError(error)), | ||||
|     dispatch(openModal({ | ||||
|       modalType: 'EMBED', | ||||
|       modalProps: { | ||||
|         url: status.get('url'), | ||||
|         onError: error => dispatch(showAlertForError(error)), | ||||
|       }, | ||||
|     })); | ||||
|   }, | ||||
|  | ||||
| @@ -112,10 +118,13 @@ const mapDispatchToProps = (dispatch, { intl }) => ({ | ||||
|     if (!deleteModal) { | ||||
|       dispatch(deleteStatus(status.get('id'), history, withRedraft)); | ||||
|     } else { | ||||
|       dispatch(openModal('CONFIRM', { | ||||
|         message: intl.formatMessage(withRedraft ? messages.redraftMessage : messages.deleteMessage), | ||||
|         confirm: intl.formatMessage(withRedraft ? messages.redraftConfirm : messages.deleteConfirm), | ||||
|         onConfirm: () => dispatch(deleteStatus(status.get('id'), history, withRedraft)), | ||||
|       dispatch(openModal({ | ||||
|         modalType: 'CONFIRM', | ||||
|         modalProps: { | ||||
|           message: intl.formatMessage(withRedraft ? messages.redraftMessage : messages.deleteMessage), | ||||
|           confirm: intl.formatMessage(withRedraft ? messages.redraftConfirm : messages.deleteConfirm), | ||||
|           onConfirm: () => dispatch(deleteStatus(status.get('id'), history, withRedraft)), | ||||
|         }, | ||||
|       })); | ||||
|     } | ||||
|   }, | ||||
| @@ -129,11 +138,17 @@ const mapDispatchToProps = (dispatch, { intl }) => ({ | ||||
|   }, | ||||
|  | ||||
|   onOpenMedia (media, index, lang) { | ||||
|     dispatch(openModal('MEDIA', { media, index, lang })); | ||||
|     dispatch(openModal({ | ||||
|       modalType: 'MEDIA', | ||||
|       modalProps: { media, index, lang }, | ||||
|     })); | ||||
|   }, | ||||
|  | ||||
|   onOpenVideo (media, lang, options) { | ||||
|     dispatch(openModal('VIDEO', { media, lang, options })); | ||||
|     dispatch(openModal({ | ||||
|       modalType: 'VIDEO', | ||||
|       modalProps: { media, lang, options }, | ||||
|     })); | ||||
|   }, | ||||
|  | ||||
|   onBlock (status) { | ||||
|   | ||||
| @@ -289,14 +289,23 @@ class Status extends ImmutablePureComponent { | ||||
|         if ((e && e.shiftKey) || !favouriteModal) { | ||||
|           this.handleModalFavourite(status); | ||||
|         } else { | ||||
|           dispatch(openModal('FAVOURITE', { status, onFavourite: this.handleModalFavourite })); | ||||
|           dispatch(openModal({ | ||||
|             modalType: 'FAVOURITE', | ||||
|             modalProps: { | ||||
|               status, | ||||
|               onFavourite: this.handleModalFavourite, | ||||
|             }, | ||||
|           })); | ||||
|         } | ||||
|       } | ||||
|     } else { | ||||
|       dispatch(openModal('INTERACTION', { | ||||
|         type: 'favourite', | ||||
|         accountId: status.getIn(['account', 'id']), | ||||
|         url: status.get('url'), | ||||
|       dispatch(openModal({ | ||||
|         modalType: 'INTERACTION', | ||||
|         modalProps: { | ||||
|           type: 'favourite', | ||||
|           accountId: status.getIn(['account', 'id']), | ||||
|           url: status.get('url'), | ||||
|         }, | ||||
|       })); | ||||
|     } | ||||
|   }; | ||||
| @@ -315,20 +324,26 @@ class Status extends ImmutablePureComponent { | ||||
|  | ||||
|     if (signedIn) { | ||||
|       if (askReplyConfirmation) { | ||||
|         dispatch(openModal('CONFIRM', { | ||||
|           message: intl.formatMessage(messages.replyMessage), | ||||
|           confirm: intl.formatMessage(messages.replyConfirm), | ||||
|           onDoNotAsk: () => dispatch(changeLocalSetting(['confirm_before_clearing_draft'], false)), | ||||
|           onConfirm: () => dispatch(replyCompose(status, this.context.router.history)), | ||||
|         dispatch(openModal({ | ||||
|           modalType: 'CONFIRM', | ||||
|           modalProps: { | ||||
|             message: intl.formatMessage(messages.replyMessage), | ||||
|             confirm: intl.formatMessage(messages.replyConfirm), | ||||
|             onDoNotAsk: () => dispatch(changeLocalSetting(['confirm_before_clearing_draft'], false)), | ||||
|             onConfirm: () => dispatch(replyCompose(status, this.context.router.history)), | ||||
|           }, | ||||
|         })); | ||||
|       } else { | ||||
|         dispatch(replyCompose(status, this.context.router.history)); | ||||
|       } | ||||
|     } else { | ||||
|       dispatch(openModal('INTERACTION', { | ||||
|         type: 'reply', | ||||
|         accountId: status.getIn(['account', 'id']), | ||||
|         url: status.get('url'), | ||||
|       dispatch(openModal({ | ||||
|         modalType: 'INTERACTION', | ||||
|         modalProps: { | ||||
|           type: 'reply', | ||||
|           accountId: status.getIn(['account', 'id']), | ||||
|           url: status.get('url'), | ||||
|         }, | ||||
|       })); | ||||
|     } | ||||
|   }; | ||||
| @@ -356,10 +371,13 @@ class Status extends ImmutablePureComponent { | ||||
|         dispatch(initBoostModal({ status, onReblog: this.handleModalReblog })); | ||||
|       } | ||||
|     } else { | ||||
|       dispatch(openModal('INTERACTION', { | ||||
|         type: 'reblog', | ||||
|         accountId: status.getIn(['account', 'id']), | ||||
|         url: status.get('url'), | ||||
|       dispatch(openModal({ | ||||
|         modalType: 'INTERACTION', | ||||
|         modalProps: { | ||||
|           type: 'reblog', | ||||
|           accountId: status.getIn(['account', 'id']), | ||||
|           url: status.get('url'), | ||||
|         }, | ||||
|       })); | ||||
|     } | ||||
|   }; | ||||
| @@ -378,10 +396,13 @@ class Status extends ImmutablePureComponent { | ||||
|     if (!deleteModal) { | ||||
|       dispatch(deleteStatus(status.get('id'), history, withRedraft)); | ||||
|     } else { | ||||
|       dispatch(openModal('CONFIRM', { | ||||
|         message: intl.formatMessage(withRedraft ? messages.redraftMessage : messages.deleteMessage), | ||||
|         confirm: intl.formatMessage(withRedraft ? messages.redraftConfirm : messages.deleteConfirm), | ||||
|         onConfirm: () => dispatch(deleteStatus(status.get('id'), history, withRedraft)), | ||||
|       dispatch(openModal({ | ||||
|         modalType: 'CONFIRM', | ||||
|         modalProps: { | ||||
|           message: intl.formatMessage(withRedraft ? messages.redraftMessage : messages.deleteMessage), | ||||
|           confirm: intl.formatMessage(withRedraft ? messages.redraftConfirm : messages.deleteConfirm), | ||||
|           onConfirm: () => dispatch(deleteStatus(status.get('id'), history, withRedraft)), | ||||
|         }, | ||||
|       })); | ||||
|     } | ||||
|   }; | ||||
| @@ -399,11 +420,17 @@ class Status extends ImmutablePureComponent { | ||||
|   }; | ||||
|  | ||||
|   handleOpenMedia = (media, index, lang) => { | ||||
|     this.props.dispatch(openModal('MEDIA', { statusId: this.props.status.get('id'), media, index, lang })); | ||||
|     this.props.dispatch(openModal({ | ||||
|       modalType: 'MEDIA', | ||||
|       modalProps: { statusId: this.props.status.get('id'), media, index, lang }, | ||||
|     })); | ||||
|   }; | ||||
|  | ||||
|   handleOpenVideo = (media, lang, options) => { | ||||
|     this.props.dispatch(openModal('VIDEO', { statusId: this.props.status.get('id'), media, lang, options })); | ||||
|     this.props.dispatch(openModal({ | ||||
|       modalType: 'VIDEO', | ||||
|       modalProps: { statusId: this.props.status.get('id'), media, lang, options }, | ||||
|     })); | ||||
|   }; | ||||
|  | ||||
|   handleHotkeyOpenMedia = e => { | ||||
| @@ -470,7 +497,10 @@ class Status extends ImmutablePureComponent { | ||||
|   }; | ||||
|  | ||||
|   handleEmbed = (status) => { | ||||
|     this.props.dispatch(openModal('EMBED', { url: status.get('url') })); | ||||
|     this.props.dispatch(openModal({ | ||||
|       modalType: 'EMBED', | ||||
|       modalProps: { url: status.get('url') }, | ||||
|     })); | ||||
|   }; | ||||
|  | ||||
|   handleHotkeyToggleSensitive = () => { | ||||
|   | ||||
| @@ -34,7 +34,10 @@ const mapDispatchToProps = dispatch => { | ||||
|     }, | ||||
|  | ||||
|     onClose() { | ||||
|       dispatch(closeModal()); | ||||
|       dispatch(closeModal({ | ||||
|         modalType: undefined, | ||||
|         ignoreFocus: false, | ||||
|       })); | ||||
|     }, | ||||
|   }; | ||||
| }; | ||||
|   | ||||
| @@ -23,7 +23,10 @@ const mapStateToProps = (state, { statusId }) => ({ | ||||
| const mapDispatchToProps = dispatch => ({ | ||||
|  | ||||
|   onClose() { | ||||
|     dispatch(closeModal()); | ||||
|     dispatch(closeModal({ | ||||
|       modalType: undefined, | ||||
|       ignoreFocus: false, | ||||
|     })); | ||||
|   }, | ||||
|  | ||||
| }); | ||||
|   | ||||
| @@ -23,11 +23,14 @@ const mapStateToProps = (state) => ({ | ||||
|  | ||||
| const mapDispatchToProps = (dispatch, { intl }) => ({ | ||||
|   onLogout () { | ||||
|     dispatch(openModal('CONFIRM', { | ||||
|       message: intl.formatMessage(messages.logoutMessage), | ||||
|       confirm: intl.formatMessage(messages.logoutConfirm), | ||||
|       closeWhenConfirm: false, | ||||
|       onConfirm: () => logOut(), | ||||
|     dispatch(openModal({ | ||||
|       modalType: 'CONFIRM', | ||||
|       modalProps: { | ||||
|         message: intl.formatMessage(messages.logoutMessage), | ||||
|         confirm: intl.formatMessage(messages.logoutConfirm), | ||||
|         closeWhenConfirm: false, | ||||
|         onConfirm: () => logOut(), | ||||
|       }, | ||||
|     })); | ||||
|   }, | ||||
| }); | ||||
|   | ||||
| @@ -27,7 +27,7 @@ const mapStateToProps = (state) => ({ | ||||
|  | ||||
| const mapDispatchToProps = (dispatch) => ({ | ||||
|   openClosedRegistrationsModal() { | ||||
|     dispatch(openModal('CLOSED_REGISTRATIONS')); | ||||
|     dispatch(openModal({ modalType: 'CLOSED_REGISTRATIONS' })); | ||||
|   }, | ||||
| }); | ||||
|  | ||||
|   | ||||
| @@ -19,11 +19,14 @@ const messages = defineMessages({ | ||||
|  | ||||
| const mapDispatchToProps = (dispatch, { intl }) => ({ | ||||
|   onLogout () { | ||||
|     dispatch(openModal('CONFIRM', { | ||||
|       message: intl.formatMessage(messages.logoutMessage), | ||||
|       confirm: intl.formatMessage(messages.logoutConfirm), | ||||
|       closeWhenConfirm: false, | ||||
|       onConfirm: () => logOut(), | ||||
|     dispatch(openModal({ | ||||
|       modalType: 'CONFIRM', | ||||
|       modalProps: { | ||||
|         message: intl.formatMessage(messages.logoutMessage), | ||||
|         confirm: intl.formatMessage(messages.logoutConfirm), | ||||
|         closeWhenConfirm: false, | ||||
|         onConfirm: () => logOut(), | ||||
|       }, | ||||
|     })); | ||||
|   }, | ||||
| }); | ||||
|   | ||||
| @@ -40,7 +40,7 @@ import VideoModal from './video_modal'; | ||||
|  | ||||
|  | ||||
|  | ||||
| const MODAL_COMPONENTS = { | ||||
| export const MODAL_COMPONENTS = { | ||||
|   'MEDIA': () => Promise.resolve({ default: MediaModal }), | ||||
|   'ONBOARDING': OnboardingModal, | ||||
|   'VIDEO': () => Promise.resolve({ default: VideoModal }), | ||||
|   | ||||
| @@ -34,7 +34,10 @@ const mapDispatchToProps = dispatch => { | ||||
|     }, | ||||
|  | ||||
|     onClose() { | ||||
|       dispatch(closeModal()); | ||||
|       dispatch(closeModal({ | ||||
|         modalType: undefined, | ||||
|         ignoreFocus: false, | ||||
|       })); | ||||
|     }, | ||||
|  | ||||
|     onToggleNotifications() { | ||||
|   | ||||
| @@ -10,7 +10,7 @@ const SignInBanner = () => { | ||||
|   const dispatch = useAppDispatch(); | ||||
|  | ||||
|   const openClosedRegistrationsModal = useCallback( | ||||
|     () => dispatch(openModal('CLOSED_REGISTRATIONS')), | ||||
|     () => dispatch(openModal({ modalType: 'CLOSED_REGISTRATIONS' })), | ||||
|     [dispatch], | ||||
|   ); | ||||
|  | ||||
|   | ||||
| @@ -12,7 +12,10 @@ const mapDispatchToProps = dispatch => ({ | ||||
|   openSettings (e) { | ||||
|     e.preventDefault(); | ||||
|     e.stopPropagation(); | ||||
|     dispatch(openModal('SETTINGS', {})); | ||||
|     dispatch(openModal({ | ||||
|       modalType: 'SETTINGS', | ||||
|       modalProps: {}, | ||||
|     })); | ||||
|   }, | ||||
| }); | ||||
|  | ||||
|   | ||||
| @@ -14,14 +14,22 @@ const mapDispatchToProps = dispatch => ({ | ||||
|   onClose (confirmationMessage, ignoreFocus = false) { | ||||
|     if (confirmationMessage) { | ||||
|       dispatch( | ||||
|         openModal('CONFIRM', { | ||||
|           message: confirmationMessage.message, | ||||
|           confirm: confirmationMessage.confirm, | ||||
|           onConfirm: () => dispatch(closeModal(undefined, { ignoreFocus })), | ||||
|         }), | ||||
|         openModal({ | ||||
|           modalType: 'CONFIRM', | ||||
|           modalProps: { | ||||
|             message: confirmationMessage.message, | ||||
|             confirm: confirmationMessage.confirm, | ||||
|             onConfirm: () => dispatch(closeModal({ | ||||
|               modalType: undefined, | ||||
|               ignoreFocus: { ignoreFocus }, | ||||
|             })), | ||||
|           } }), | ||||
|       ); | ||||
|     } else { | ||||
|       dispatch(closeModal(undefined, { ignoreFocus })); | ||||
|       dispatch(closeModal({ | ||||
|         modalType: undefined, | ||||
|         ignoreFocus: { ignoreFocus }, | ||||
|       })); | ||||
|     } | ||||
|   }, | ||||
| }); | ||||
|   | ||||
| @@ -26,7 +26,7 @@ import local_settings from './local_settings'; | ||||
| import markers from './markers'; | ||||
| import media_attachments from './media_attachments'; | ||||
| import meta from './meta'; | ||||
| import modal from './modal'; | ||||
| import { modalReducer } from './modal'; | ||||
| import mutes from './mutes'; | ||||
| import notifications from './notifications'; | ||||
| import picture_in_picture from './picture_in_picture'; | ||||
| @@ -52,7 +52,7 @@ const reducers = { | ||||
|   meta, | ||||
|   alerts, | ||||
|   loadingBar: loadingBarReducer, | ||||
|   modal, | ||||
|   modal: modalReducer, | ||||
|   user_lists, | ||||
|   domain_lists, | ||||
|   status_lists, | ||||
|   | ||||
| @@ -1,40 +0,0 @@ | ||||
| import { Stack as ImmutableStack, Map as ImmutableMap } from 'immutable'; | ||||
|  | ||||
| import { COMPOSE_UPLOAD_CHANGE_SUCCESS } from 'flavours/glitch/actions/compose'; | ||||
| import { MODAL_OPEN, MODAL_CLOSE } from 'flavours/glitch/actions/modal'; | ||||
| import { TIMELINE_DELETE } from 'flavours/glitch/actions/timelines'; | ||||
|  | ||||
| const initialState = ImmutableMap({ | ||||
|   ignoreFocus: false, | ||||
|   stack: ImmutableStack(), | ||||
| }); | ||||
|  | ||||
| const popModal = (state, { modalType, ignoreFocus }) => { | ||||
|   if (modalType === undefined || modalType === state.getIn(['stack', 0, 'modalType'])) { | ||||
|     return state.set('ignoreFocus', !!ignoreFocus).update('stack', stack => stack.shift()); | ||||
|   } else { | ||||
|     return state; | ||||
|   } | ||||
| }; | ||||
|  | ||||
| const pushModal = (state, modalType, modalProps) => { | ||||
|   return state.withMutations(map => { | ||||
|     map.set('ignoreFocus', false); | ||||
|     map.update('stack', stack => stack.unshift(ImmutableMap({ modalType, modalProps }))); | ||||
|   }); | ||||
| }; | ||||
|  | ||||
| export default function modal(state = initialState, action) { | ||||
|   switch(action.type) { | ||||
|   case MODAL_OPEN: | ||||
|     return pushModal(state, action.modalType, action.modalProps); | ||||
|   case MODAL_CLOSE: | ||||
|     return popModal(state, action); | ||||
|   case COMPOSE_UPLOAD_CHANGE_SUCCESS: | ||||
|     return popModal(state, { modalType: 'FOCAL_POINT', ignoreFocus: false }); | ||||
|   case TIMELINE_DELETE: | ||||
|     return state.update('stack', stack => stack.filterNot((modal) => modal.get('modalProps').statusId === action.id)); | ||||
|   default: | ||||
|     return state; | ||||
|   } | ||||
| } | ||||
							
								
								
									
										94
									
								
								app/javascript/flavours/glitch/reducers/modal.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								app/javascript/flavours/glitch/reducers/modal.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,94 @@ | ||||
| import { Record as ImmutableRecord, Stack } from 'immutable'; | ||||
|  | ||||
| import type { PayloadAction } from '@reduxjs/toolkit'; | ||||
|  | ||||
| import { COMPOSE_UPLOAD_CHANGE_SUCCESS } from '../actions/compose'; | ||||
| import type { ModalType } from '../actions/modal'; | ||||
| import { openModal, closeModal } from '../actions/modal'; | ||||
| import { TIMELINE_DELETE } from '../actions/timelines'; | ||||
|  | ||||
| type ModalProps = Record<string, unknown>; | ||||
| interface Modal { | ||||
|   modalType: ModalType; | ||||
|   modalProps: ModalProps; | ||||
| } | ||||
|  | ||||
| const Modal = ImmutableRecord<Modal>({ | ||||
|   modalType: 'ACTIONS', | ||||
|   modalProps: ImmutableRecord({})(), | ||||
| }); | ||||
|  | ||||
| interface ModalState { | ||||
|   ignoreFocus: boolean; | ||||
|   stack: Stack<ImmutableRecord<Modal>>; | ||||
| } | ||||
|  | ||||
| const initialState = ImmutableRecord<ModalState>({ | ||||
|   ignoreFocus: false, | ||||
|   stack: Stack(), | ||||
| })(); | ||||
| type State = typeof initialState; | ||||
|  | ||||
| interface PopModalOption { | ||||
|   modalType: ModalType | undefined; | ||||
|   ignoreFocus: boolean; | ||||
| } | ||||
| const popModal = ( | ||||
|   state: State, | ||||
|   { modalType, ignoreFocus }: PopModalOption | ||||
| ): State => { | ||||
|   if ( | ||||
|     modalType === undefined || | ||||
|     modalType === state.get('stack').get(0)?.get('modalType') | ||||
|   ) { | ||||
|     return state | ||||
|       .set('ignoreFocus', !!ignoreFocus) | ||||
|       .update('stack', (stack) => stack.shift()); | ||||
|   } else { | ||||
|     return state; | ||||
|   } | ||||
| }; | ||||
|  | ||||
| const pushModal = ( | ||||
|   state: State, | ||||
|   modalType: ModalType, | ||||
|   modalProps: ModalProps | ||||
| ): State => { | ||||
|   return state.withMutations((record) => { | ||||
|     record.set('ignoreFocus', false); | ||||
|     record.update('stack', (stack) => | ||||
|       stack.unshift(Modal({ modalType, modalProps })) | ||||
|     ); | ||||
|   }); | ||||
| }; | ||||
|  | ||||
| export function modalReducer( | ||||
|   state: State = initialState, | ||||
|   action: PayloadAction<{ | ||||
|     modalType: ModalType; | ||||
|     ignoreFocus: boolean; | ||||
|     modalProps: Record<string, unknown>; | ||||
|   }> | ||||
| ) { | ||||
|   switch (action.type) { | ||||
|     case openModal.type: | ||||
|       return pushModal( | ||||
|         state, | ||||
|         action.payload.modalType, | ||||
|         action.payload.modalProps | ||||
|       ); | ||||
|     case closeModal.type: | ||||
|       return popModal(state, action.payload); | ||||
|     case COMPOSE_UPLOAD_CHANGE_SUCCESS: | ||||
|       return popModal(state, { modalType: 'FOCAL_POINT', ignoreFocus: false }); | ||||
|     case TIMELINE_DELETE: | ||||
|       return state.update('stack', (stack) => | ||||
|         stack.filterNot( | ||||
|           // @ts-expect-error TIMELINE_DELETE action is not typed yet. | ||||
|           (modal) => modal.get('modalProps').statusId === action.id | ||||
|         ) | ||||
|       ); | ||||
|     default: | ||||
|       return state; | ||||
|   } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user