From 382b2a506a14cef96ed57d4c120b4b9e11eae4b5 Mon Sep 17 00:00:00 2001 From: fusagiko / takayamaki <24884114+takayamaki@users.noreply.github.com> Date: Thu, 25 May 2023 22:42:37 +0900 Subject: [PATCH] [Glitch] Rewrite actions/modal and reducers/modal with typescript Port 38c6216082e67581e83d04b3096cdb020ad0edea to glitch-soc Signed-off-by: Claire --- .../flavours/glitch/actions/blocks.js | 2 +- .../flavours/glitch/actions/boosts.js | 5 +- .../flavours/glitch/actions/compose.js | 5 +- .../flavours/glitch/actions/filters.js | 9 +- .../flavours/glitch/actions/local_settings.js | 9 +- .../flavours/glitch/actions/modal.js | 18 ---- .../flavours/glitch/actions/modal.ts | 17 ++++ .../flavours/glitch/actions/mutes.js | 2 +- .../flavours/glitch/actions/onboarding.js | 4 +- .../flavours/glitch/actions/reports.js | 9 +- .../components/edited_timestamp/index.jsx | 5 +- .../glitch/containers/account_container.jsx | 11 ++- .../glitch/containers/domain_container.jsx | 11 ++- .../containers/dropdown_menu_container.js | 11 ++- .../notification_purge_buttons_container.js | 11 ++- .../glitch/containers/status_container.js | 73 +++++++++----- .../glitch/features/account_gallery/index.jsx | 15 ++- .../containers/header_container.jsx | 67 ++++++++----- .../containers/compose_form_container.js | 28 +++--- .../compose/containers/dropdown_container.js | 2 +- .../compose/containers/header_container.js | 15 +-- .../containers/navigation_container.js | 13 ++- .../compose/containers/options_container.js | 5 +- .../containers/privacy_dropdown_container.js | 10 +- .../containers/conversation_container.js | 11 ++- .../directory/components/account_card.jsx | 35 ++++--- .../glitch/features/getting_started/index.jsx | 5 +- .../features/getting_started_misc/index.jsx | 8 +- .../features/interaction_modal/index.jsx | 7 +- .../glitch/features/list_timeline/index.jsx | 30 +++--- .../containers/column_settings_container.js | 11 ++- .../picture_in_picture/components/footer.jsx | 44 +++++---- .../containers/detailed_status_container.js | 41 +++++--- .../flavours/glitch/features/status/index.jsx | 80 +++++++++++----- .../features/ui/components/block_modal.jsx | 5 +- .../ui/components/compare_history_modal.jsx | 5 +- .../ui/components/disabled_account_banner.jsx | 13 ++- .../glitch/features/ui/components/header.jsx | 2 +- .../features/ui/components/link_footer.jsx | 13 ++- .../features/ui/components/modal_root.jsx | 2 +- .../features/ui/components/mute_modal.jsx | 5 +- .../features/ui/components/sign_in_banner.jsx | 2 +- .../ui/containers/columns_area_container.js | 5 +- .../features/ui/containers/modal_container.js | 20 ++-- .../flavours/glitch/reducers/index.ts | 4 +- .../flavours/glitch/reducers/modal.js | 40 -------- .../flavours/glitch/reducers/modal.ts | 94 +++++++++++++++++++ 47 files changed, 556 insertions(+), 283 deletions(-) delete mode 100644 app/javascript/flavours/glitch/actions/modal.js create mode 100644 app/javascript/flavours/glitch/actions/modal.ts delete mode 100644 app/javascript/flavours/glitch/reducers/modal.js create mode 100644 app/javascript/flavours/glitch/reducers/modal.ts diff --git a/app/javascript/flavours/glitch/actions/blocks.js b/app/javascript/flavours/glitch/actions/blocks.js index 66421ed455..e293657ad3 100644 --- a/app/javascript/flavours/glitch/actions/blocks.js +++ b/app/javascript/flavours/glitch/actions/blocks.js @@ -95,6 +95,6 @@ export function initBlockModal(account) { account, }); - dispatch(openModal('BLOCK')); + dispatch(openModal({ modalType: 'BLOCK' })); }; } diff --git a/app/javascript/flavours/glitch/actions/boosts.js b/app/javascript/flavours/glitch/actions/boosts.js index c0f0f3acc5..1fc2e391e2 100644 --- a/app/javascript/flavours/glitch/actions/boosts.js +++ b/app/javascript/flavours/glitch/actions/boosts.js @@ -14,7 +14,10 @@ export function initBoostModal(props) { privacy, }); - dispatch(openModal('BOOST', props)); + dispatch(openModal({ + modalType: 'BOOST', + modalProps: props, + })); }; } diff --git a/app/javascript/flavours/glitch/actions/compose.js b/app/javascript/flavours/glitch/actions/compose.js index c34a5e8991..9e0b123704 100644 --- a/app/javascript/flavours/glitch/actions/compose.js +++ b/app/javascript/flavours/glitch/actions/compose.js @@ -416,7 +416,10 @@ export function initMediaEditModal(id) { id, }); - dispatch(openModal('FOCAL_POINT', { id })); + dispatch(openModal({ + modalType: 'FOCAL_POINT', + modalProps: { id }, + })); }; } diff --git a/app/javascript/flavours/glitch/actions/filters.js b/app/javascript/flavours/glitch/actions/filters.js index 3774ee042a..a11956ac56 100644 --- a/app/javascript/flavours/glitch/actions/filters.js +++ b/app/javascript/flavours/glitch/actions/filters.js @@ -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) => { diff --git a/app/javascript/flavours/glitch/actions/local_settings.js b/app/javascript/flavours/glitch/actions/local_settings.js index a48669b6aa..f2878daa50 100644 --- a/app/javascript/flavours/glitch/actions/local_settings.js +++ b/app/javascript/flavours/glitch/actions/local_settings.js @@ -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()), + }, })); } }; diff --git a/app/javascript/flavours/glitch/actions/modal.js b/app/javascript/flavours/glitch/actions/modal.js deleted file mode 100644 index ef2ae0e4c7..0000000000 --- a/app/javascript/flavours/glitch/actions/modal.js +++ /dev/null @@ -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, - }; -} diff --git a/app/javascript/flavours/glitch/actions/modal.ts b/app/javascript/flavours/glitch/actions/modal.ts new file mode 100644 index 0000000000..af34f5d6af --- /dev/null +++ b/app/javascript/flavours/glitch/actions/modal.ts @@ -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('MODAL_OPEN'); + +interface CloseModalPayload { + modalType: ModalType | undefined; + ignoreFocus: boolean; +} +export const closeModal = createAction('MODAL_CLOSE'); diff --git a/app/javascript/flavours/glitch/actions/mutes.js b/app/javascript/flavours/glitch/actions/mutes.js index 2ff4d27c80..4af927d932 100644 --- a/app/javascript/flavours/glitch/actions/mutes.js +++ b/app/javascript/flavours/glitch/actions/mutes.js @@ -98,7 +98,7 @@ export function initMuteModal(account) { account, }); - dispatch(openModal('MUTE')); + dispatch(openModal({ modalType: 'MUTE' })); }; } diff --git a/app/javascript/flavours/glitch/actions/onboarding.js b/app/javascript/flavours/glitch/actions/onboarding.js index 5038b7eb67..a4a525c427 100644 --- a/app/javascript/flavours/glitch/actions/onboarding.js +++ b/app/javascript/flavours/glitch/actions/onboarding.js @@ -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()); } diff --git a/app/javascript/flavours/glitch/actions/reports.js b/app/javascript/flavours/glitch/actions/reports.js index b3f9bf1ac3..756b8cd05e 100644 --- a/app/javascript/flavours/glitch/actions/reports.js +++ b/app/javascript/flavours/glitch/actions/reports.js @@ -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) => { diff --git a/app/javascript/flavours/glitch/components/edited_timestamp/index.jsx b/app/javascript/flavours/glitch/components/edited_timestamp/index.jsx index 5189f80510..3dbac58b54 100644 --- a/app/javascript/flavours/glitch/components/edited_timestamp/index.jsx +++ b/app/javascript/flavours/glitch/components/edited_timestamp/index.jsx @@ -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 }, + })); }, }); diff --git a/app/javascript/flavours/glitch/containers/account_container.jsx b/app/javascript/flavours/glitch/containers/account_container.jsx index 537c63f3f1..f204545852 100644 --- a/app/javascript/flavours/glitch/containers/account_container.jsx +++ b/app/javascript/flavours/glitch/containers/account_container.jsx @@ -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: @{account.get('acct')} }} />, - confirm: intl.formatMessage(messages.unfollowConfirm), - onConfirm: () => dispatch(unfollowAccount(account.get('id'))), + dispatch(openModal({ + modalType: 'CONFIRM', + modalProps: { + message: @{account.get('acct')} }} />, + confirm: intl.formatMessage(messages.unfollowConfirm), + onConfirm: () => dispatch(unfollowAccount(account.get('id'))), + }, })); } else { dispatch(unfollowAccount(account.get('id'))); diff --git a/app/javascript/flavours/glitch/containers/domain_container.jsx b/app/javascript/flavours/glitch/containers/domain_container.jsx index 9a55b72cc3..c719a5775c 100644 --- a/app/javascript/flavours/glitch/containers/domain_container.jsx +++ b/app/javascript/flavours/glitch/containers/domain_container.jsx @@ -18,10 +18,13 @@ const makeMapStateToProps = () => { const mapDispatchToProps = (dispatch, { intl }) => ({ onBlockDomain (domain) { - dispatch(openModal('CONFIRM', { - message: {domain} }} />, - confirm: intl.formatMessage(messages.blockDomainConfirm), - onConfirm: () => dispatch(blockDomain(domain)), + dispatch(openModal({ + modalType: 'CONFIRM', + modalProps: { + message: {domain} }} />, + confirm: intl.formatMessage(messages.blockDomainConfirm), + onConfirm: () => dispatch(blockDomain(domain)), + }, })); }, diff --git a/app/javascript/flavours/glitch/containers/dropdown_menu_container.js b/app/javascript/flavours/glitch/containers/dropdown_menu_container.js index 5ad13e5554..36aa4c4ea0 100644 --- a/app/javascript/flavours/glitch/containers/dropdown_menu_container.js +++ b/app/javascript/flavours/glitch/containers/dropdown_menu_container.js @@ -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)); }, diff --git a/app/javascript/flavours/glitch/containers/notification_purge_buttons_container.js b/app/javascript/flavours/glitch/containers/notification_purge_buttons_container.js index 58075b1c48..144d77f135 100644 --- a/app/javascript/flavours/glitch/containers/notification_purge_buttons_container.js +++ b/app/javascript/flavours/glitch/containers/notification_purge_buttons_container.js @@ -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()), + }, })); }, diff --git a/app/javascript/flavours/glitch/containers/status_container.js b/app/javascript/flavours/glitch/containers/status_container.js index 6ae58aa3d5..5af818c8f5 100644 --- a/app/javascript/flavours/glitch/containers/status_container.js +++ b/app/javascript/flavours/glitch/containers/status_container.js @@ -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'), + }, })); }, diff --git a/app/javascript/flavours/glitch/features/account_gallery/index.jsx b/app/javascript/flavours/glitch/features/account_gallery/index.jsx index c8567a1010..170b2ca3b7 100644 --- a/app/javascript/flavours/glitch/features/account_gallery/index.jsx +++ b/app/javascript/flavours/glitch/features/account_gallery/index.jsx @@ -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 }, + })); } }; diff --git a/app/javascript/flavours/glitch/features/account_timeline/containers/header_container.jsx b/app/javascript/flavours/glitch/features/account_timeline/containers/header_container.jsx index d37c52b3bb..6ee5aba5fc 100644 --- a/app/javascript/flavours/glitch/features/account_timeline/containers/header_container.jsx +++ b/app/javascript/flavours/glitch/features/account_timeline/containers/header_container.jsx @@ -48,20 +48,26 @@ const mapDispatchToProps = (dispatch, { intl }) => ({ onFollow (account) { if (account.getIn(['relationship', 'following'])) { if (unfollowModal) { - dispatch(openModal('CONFIRM', { - message: @{account.get('acct')} }} />, - confirm: intl.formatMessage(messages.unfollowConfirm), - onConfirm: () => dispatch(unfollowAccount(account.get('id'))), + dispatch(openModal({ + modalType: 'CONFIRM', + modalProps: { + message: @{account.get('acct')} }} />, + 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: @{account.get('acct')} }} />, - confirm: intl.formatMessage(messages.cancelFollowRequestConfirm), - onConfirm: () => dispatch(unfollowAccount(account.get('id'))), + dispatch(openModal({ + modalType: 'CONFIRM', + modalProps: { + message: @{account.get('acct')} }} />, + 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: {domain} }} />, - confirm: intl.formatMessage(messages.blockDomainConfirm), - onConfirm: () => dispatch(blockDomain(domain)), + dispatch(openModal({ + modalType: 'CONFIRM', + modalProps: { + message: {domain} }} />, + 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'), + }, })); }, diff --git a/app/javascript/flavours/glitch/features/compose/containers/compose_form_container.js b/app/javascript/flavours/glitch/features/compose/containers/compose_form_container.js index e01ea3497f..e9724568cd 100644 --- a/app/javascript/flavours/glitch/features/compose/containers/compose_form_container.js +++ b/app/javascript/flavours/glitch/features/compose/containers/compose_form_container.js @@ -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)), })); }, diff --git a/app/javascript/flavours/glitch/features/compose/containers/dropdown_container.js b/app/javascript/flavours/glitch/features/compose/containers/dropdown_container.js index e7fca2a651..1f39edbffc 100644 --- a/app/javascript/flavours/glitch/features/compose/containers/dropdown_container.js +++ b/app/javascript/flavours/glitch/features/compose/containers/dropdown_container.js @@ -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()), }); diff --git a/app/javascript/flavours/glitch/features/compose/containers/header_container.js b/app/javascript/flavours/glitch/features/compose/containers/header_container.js index 500dbaedd5..5b78c8b9cd 100644 --- a/app/javascript/flavours/glitch/features/compose/containers/header_container.js +++ b/app/javascript/flavours/glitch/features/compose/containers/header_container.js @@ -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(), + }, })); }, }); diff --git a/app/javascript/flavours/glitch/features/compose/containers/navigation_container.js b/app/javascript/flavours/glitch/features/compose/containers/navigation_container.js index ed0fc42c22..541365aa99 100644 --- a/app/javascript/flavours/glitch/features/compose/containers/navigation_container.js +++ b/app/javascript/flavours/glitch/features/compose/containers/navigation_container.js @@ -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(), + }, })); }, }); diff --git a/app/javascript/flavours/glitch/features/compose/containers/options_container.js b/app/javascript/flavours/glitch/features/compose/containers/options_container.js index 7494595346..c44d3ce305 100644 --- a/app/javascript/flavours/glitch/features/compose/containers/options_container.js +++ b/app/javascript/flavours/glitch/features/compose/containers/options_container.js @@ -46,7 +46,10 @@ const mapDispatchToProps = (dispatch) => ({ }, onDoodleOpen() { - dispatch(openModal('DOODLE', { noEsc: true, noClose: true })); + dispatch(openModal({ + modalType: 'DOODLE', + modalProps: { noEsc: true, noClose: true }, + })); }, }); diff --git a/app/javascript/flavours/glitch/features/compose/containers/privacy_dropdown_container.js b/app/javascript/flavours/glitch/features/compose/containers/privacy_dropdown_container.js index 3e9ad63a07..dcbd977dae 100644 --- a/app/javascript/flavours/glitch/features/compose/containers/privacy_dropdown_container.js +++ b/app/javascript/flavours/glitch/features/compose/containers/privacy_dropdown_container.js @@ -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, + })), }); diff --git a/app/javascript/flavours/glitch/features/direct_timeline/containers/conversation_container.js b/app/javascript/flavours/glitch/features/direct_timeline/containers/conversation_container.js index c87a08df12..207d3ebb65 100644 --- a/app/javascript/flavours/glitch/features/direct_timeline/containers/conversation_container.js +++ b/app/javascript/flavours/glitch/features/direct_timeline/containers/conversation_container.js @@ -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)); diff --git a/app/javascript/flavours/glitch/features/directory/components/account_card.jsx b/app/javascript/flavours/glitch/features/directory/components/account_card.jsx index 989569f45b..655714beec 100644 --- a/app/javascript/flavours/glitch/features/directory/components/account_card.jsx +++ b/app/javascript/flavours/glitch/features/directory/components/account_card.jsx @@ -53,27 +53,32 @@ const mapDispatchToProps = (dispatch, { intl }) => ({ if (account.getIn(['relationship', 'following'])) { if (unfollowModal) { dispatch( - openModal('CONFIRM', { - message: ( - @{account.get('acct')} }} - /> - ), - confirm: intl.formatMessage(messages.unfollowConfirm), - onConfirm: () => dispatch(unfollowAccount(account.get('id'))), - }), + openModal({ + modalType: 'CONFIRM', + modalProps: { + message: ( + @{account.get('acct')} }} + /> + ), + 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: @{account.get('acct')} }} />, - confirm: intl.formatMessage(messages.cancelFollowRequestConfirm), - onConfirm: () => dispatch(unfollowAccount(account.get('id'))), + dispatch(openModal({ + modalType: 'CONFIRM', + modalProps: { + message: @{account.get('acct')} }} />, + confirm: intl.formatMessage(messages.cancelFollowRequestConfirm), + onConfirm: () => dispatch(unfollowAccount(account.get('id'))), + }, })); } else { dispatch(unfollowAccount(account.get('id'))); diff --git a/app/javascript/flavours/glitch/features/getting_started/index.jsx b/app/javascript/flavours/glitch/features/getting_started/index.jsx index 26cfca0cbf..0f6f3330e8 100644 --- a/app/javascript/flavours/glitch/features/getting_started/index.jsx +++ b/app/javascript/flavours/glitch/features/getting_started/index.jsx @@ -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) => { diff --git a/app/javascript/flavours/glitch/features/getting_started_misc/index.jsx b/app/javascript/flavours/glitch/features/getting_started_misc/index.jsx index ed93ba370d..20dfe80b47 100644 --- a/app/javascript/flavours/glitch/features/getting_started_misc/index.jsx +++ b/app/javascript/flavours/glitch/features/getting_started_misc/index.jsx @@ -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 () { diff --git a/app/javascript/flavours/glitch/features/interaction_modal/index.jsx b/app/javascript/flavours/glitch/features/interaction_modal/index.jsx index 557f760a1a..db28876476 100644 --- a/app/javascript/flavours/glitch/features/interaction_modal/index.jsx +++ b/app/javascript/flavours/glitch/features/interaction_modal/index.jsx @@ -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' })); }, }); diff --git a/app/javascript/flavours/glitch/features/list_timeline/index.jsx b/app/javascript/flavours/glitch/features/list_timeline/index.jsx index 7e37a4afeb..554a3a0e89 100644 --- a/app/javascript/flavours/glitch/features/list_timeline/index.jsx +++ b/app/javascript/flavours/glitch/features/list_timeline/index.jsx @@ -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)); - - if (columnId) { - dispatch(removeColumn(columnId)); - } else { - this.context.router.history.push('/lists'); - } + 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'); + } + }, }, })); }; diff --git a/app/javascript/flavours/glitch/features/notifications/containers/column_settings_container.js b/app/javascript/flavours/glitch/features/notifications/containers/column_settings_container.js index a0a22192ac..024f4daabb 100644 --- a/app/javascript/flavours/glitch/features/notifications/containers/column_settings_container.js +++ b/app/javascript/flavours/glitch/features/notifications/containers/column_settings_container.js @@ -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()), + }, })); }, diff --git a/app/javascript/flavours/glitch/features/picture_in_picture/components/footer.jsx b/app/javascript/flavours/glitch/features/picture_in_picture/components/footer.jsx index ab7de65328..7d5c4adb6f 100644 --- a/app/javascript/flavours/glitch/features/picture_in_picture/components/footer.jsx +++ b/app/javascript/flavours/glitch/features/picture_in_picture/components/footer.jsx @@ -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'), + }, })); } }; diff --git a/app/javascript/flavours/glitch/features/status/containers/detailed_status_container.js b/app/javascript/flavours/glitch/features/status/containers/detailed_status_container.js index 56757eed03..96d9090dad 100644 --- a/app/javascript/flavours/glitch/features/status/containers/detailed_status_container.js +++ b/app/javascript/flavours/glitch/features/status/containers/detailed_status_container.js @@ -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) { diff --git a/app/javascript/flavours/glitch/features/status/index.jsx b/app/javascript/flavours/glitch/features/status/index.jsx index 8efb335b6a..0c7a016644 100644 --- a/app/javascript/flavours/glitch/features/status/index.jsx +++ b/app/javascript/flavours/glitch/features/status/index.jsx @@ -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 = () => { diff --git a/app/javascript/flavours/glitch/features/ui/components/block_modal.jsx b/app/javascript/flavours/glitch/features/ui/components/block_modal.jsx index 90f262410d..c2965d6173 100644 --- a/app/javascript/flavours/glitch/features/ui/components/block_modal.jsx +++ b/app/javascript/flavours/glitch/features/ui/components/block_modal.jsx @@ -34,7 +34,10 @@ const mapDispatchToProps = dispatch => { }, onClose() { - dispatch(closeModal()); + dispatch(closeModal({ + modalType: undefined, + ignoreFocus: false, + })); }, }; }; diff --git a/app/javascript/flavours/glitch/features/ui/components/compare_history_modal.jsx b/app/javascript/flavours/glitch/features/ui/components/compare_history_modal.jsx index 9c1a9e27ee..409342bdd2 100644 --- a/app/javascript/flavours/glitch/features/ui/components/compare_history_modal.jsx +++ b/app/javascript/flavours/glitch/features/ui/components/compare_history_modal.jsx @@ -23,7 +23,10 @@ const mapStateToProps = (state, { statusId }) => ({ const mapDispatchToProps = dispatch => ({ onClose() { - dispatch(closeModal()); + dispatch(closeModal({ + modalType: undefined, + ignoreFocus: false, + })); }, }); diff --git a/app/javascript/flavours/glitch/features/ui/components/disabled_account_banner.jsx b/app/javascript/flavours/glitch/features/ui/components/disabled_account_banner.jsx index b9b68c2887..396127829b 100644 --- a/app/javascript/flavours/glitch/features/ui/components/disabled_account_banner.jsx +++ b/app/javascript/flavours/glitch/features/ui/components/disabled_account_banner.jsx @@ -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(), + }, })); }, }); diff --git a/app/javascript/flavours/glitch/features/ui/components/header.jsx b/app/javascript/flavours/glitch/features/ui/components/header.jsx index 93bac5c7e7..bbef3a5fb8 100644 --- a/app/javascript/flavours/glitch/features/ui/components/header.jsx +++ b/app/javascript/flavours/glitch/features/ui/components/header.jsx @@ -27,7 +27,7 @@ const mapStateToProps = (state) => ({ const mapDispatchToProps = (dispatch) => ({ openClosedRegistrationsModal() { - dispatch(openModal('CLOSED_REGISTRATIONS')); + dispatch(openModal({ modalType: 'CLOSED_REGISTRATIONS' })); }, }); diff --git a/app/javascript/flavours/glitch/features/ui/components/link_footer.jsx b/app/javascript/flavours/glitch/features/ui/components/link_footer.jsx index ce65c3d827..1738116c7c 100644 --- a/app/javascript/flavours/glitch/features/ui/components/link_footer.jsx +++ b/app/javascript/flavours/glitch/features/ui/components/link_footer.jsx @@ -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(), + }, })); }, }); diff --git a/app/javascript/flavours/glitch/features/ui/components/modal_root.jsx b/app/javascript/flavours/glitch/features/ui/components/modal_root.jsx index 97bf1f6ad1..03588e2768 100644 --- a/app/javascript/flavours/glitch/features/ui/components/modal_root.jsx +++ b/app/javascript/flavours/glitch/features/ui/components/modal_root.jsx @@ -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 }), diff --git a/app/javascript/flavours/glitch/features/ui/components/mute_modal.jsx b/app/javascript/flavours/glitch/features/ui/components/mute_modal.jsx index 1060a9e63d..23f842f090 100644 --- a/app/javascript/flavours/glitch/features/ui/components/mute_modal.jsx +++ b/app/javascript/flavours/glitch/features/ui/components/mute_modal.jsx @@ -34,7 +34,10 @@ const mapDispatchToProps = dispatch => { }, onClose() { - dispatch(closeModal()); + dispatch(closeModal({ + modalType: undefined, + ignoreFocus: false, + })); }, onToggleNotifications() { diff --git a/app/javascript/flavours/glitch/features/ui/components/sign_in_banner.jsx b/app/javascript/flavours/glitch/features/ui/components/sign_in_banner.jsx index 819ad87366..31d43af7b1 100644 --- a/app/javascript/flavours/glitch/features/ui/components/sign_in_banner.jsx +++ b/app/javascript/flavours/glitch/features/ui/components/sign_in_banner.jsx @@ -10,7 +10,7 @@ const SignInBanner = () => { const dispatch = useAppDispatch(); const openClosedRegistrationsModal = useCallback( - () => dispatch(openModal('CLOSED_REGISTRATIONS')), + () => dispatch(openModal({ modalType: 'CLOSED_REGISTRATIONS' })), [dispatch], ); diff --git a/app/javascript/flavours/glitch/features/ui/containers/columns_area_container.js b/app/javascript/flavours/glitch/features/ui/containers/columns_area_container.js index 9b6202af7b..a69abfb610 100644 --- a/app/javascript/flavours/glitch/features/ui/containers/columns_area_container.js +++ b/app/javascript/flavours/glitch/features/ui/containers/columns_area_container.js @@ -12,7 +12,10 @@ const mapDispatchToProps = dispatch => ({ openSettings (e) { e.preventDefault(); e.stopPropagation(); - dispatch(openModal('SETTINGS', {})); + dispatch(openModal({ + modalType: 'SETTINGS', + modalProps: {}, + })); }, }); diff --git a/app/javascript/flavours/glitch/features/ui/containers/modal_container.js b/app/javascript/flavours/glitch/features/ui/containers/modal_container.js index 55b87485e2..0d07d68a5d 100644 --- a/app/javascript/flavours/glitch/features/ui/containers/modal_container.js +++ b/app/javascript/flavours/glitch/features/ui/containers/modal_container.js @@ -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 }, + })); } }, }); diff --git a/app/javascript/flavours/glitch/reducers/index.ts b/app/javascript/flavours/glitch/reducers/index.ts index eaef569f09..fdfa4104f6 100644 --- a/app/javascript/flavours/glitch/reducers/index.ts +++ b/app/javascript/flavours/glitch/reducers/index.ts @@ -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, diff --git a/app/javascript/flavours/glitch/reducers/modal.js b/app/javascript/flavours/glitch/reducers/modal.js deleted file mode 100644 index e8cea5032a..0000000000 --- a/app/javascript/flavours/glitch/reducers/modal.js +++ /dev/null @@ -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; - } -} diff --git a/app/javascript/flavours/glitch/reducers/modal.ts b/app/javascript/flavours/glitch/reducers/modal.ts new file mode 100644 index 0000000000..6afbcc367c --- /dev/null +++ b/app/javascript/flavours/glitch/reducers/modal.ts @@ -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; +interface Modal { + modalType: ModalType; + modalProps: ModalProps; +} + +const Modal = ImmutableRecord({ + modalType: 'ACTIONS', + modalProps: ImmutableRecord({})(), +}); + +interface ModalState { + ignoreFocus: boolean; + stack: Stack>; +} + +const initialState = ImmutableRecord({ + 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; + }> +) { + 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; + } +}