From 4b7bc1f07c712cf2375882da4f12a8af29444590 Mon Sep 17 00:00:00 2001 From: Renaud Chaput Date: Fri, 22 Sep 2023 18:18:46 +0200 Subject: [PATCH] Convert `dropdown_menu` state to Typescript (#25585) --- .../mastodon/actions/dropdown_menu.js | 10 ------ .../mastodon/actions/dropdown_menu.ts | 11 +++++++ .../containers/dropdown_menu_container.js | 13 +++++--- .../mastodon/components/scrollable_list.jsx | 7 +++- .../containers/dropdown_menu_container.js | 11 ++++--- app/javascript/mastodon/features/ui/index.jsx | 2 +- .../mastodon/reducers/dropdown_menu.js | 19 ----------- .../mastodon/reducers/dropdown_menu.ts | 33 +++++++++++++++++++ app/javascript/mastodon/reducers/index.ts | 4 +-- 9 files changed, 69 insertions(+), 41 deletions(-) delete mode 100644 app/javascript/mastodon/actions/dropdown_menu.js create mode 100644 app/javascript/mastodon/actions/dropdown_menu.ts delete mode 100644 app/javascript/mastodon/reducers/dropdown_menu.js create mode 100644 app/javascript/mastodon/reducers/dropdown_menu.ts diff --git a/app/javascript/mastodon/actions/dropdown_menu.js b/app/javascript/mastodon/actions/dropdown_menu.js deleted file mode 100644 index 023151d4b..000000000 --- a/app/javascript/mastodon/actions/dropdown_menu.js +++ /dev/null @@ -1,10 +0,0 @@ -export const DROPDOWN_MENU_OPEN = 'DROPDOWN_MENU_OPEN'; -export const DROPDOWN_MENU_CLOSE = 'DROPDOWN_MENU_CLOSE'; - -export function openDropdownMenu(id, keyboard, scroll_key) { - return { type: DROPDOWN_MENU_OPEN, id, keyboard, scroll_key }; -} - -export function closeDropdownMenu(id) { - return { type: DROPDOWN_MENU_CLOSE, id }; -} diff --git a/app/javascript/mastodon/actions/dropdown_menu.ts b/app/javascript/mastodon/actions/dropdown_menu.ts new file mode 100644 index 000000000..3694df1ae --- /dev/null +++ b/app/javascript/mastodon/actions/dropdown_menu.ts @@ -0,0 +1,11 @@ +import { createAction } from '@reduxjs/toolkit'; + +export const openDropdownMenu = createAction<{ + id: string; + keyboard: boolean; + scrollKey: string; +}>('dropdownMenu/open'); + +export const closeDropdownMenu = createAction<{ id: string }>( + 'dropdownMenu/close', +); diff --git a/app/javascript/mastodon/components/edited_timestamp/containers/dropdown_menu_container.js b/app/javascript/mastodon/components/edited_timestamp/containers/dropdown_menu_container.js index a0896d985..726fee907 100644 --- a/app/javascript/mastodon/components/edited_timestamp/containers/dropdown_menu_container.js +++ b/app/javascript/mastodon/components/edited_timestamp/containers/dropdown_menu_container.js @@ -4,9 +4,14 @@ import { openDropdownMenu, closeDropdownMenu } from 'mastodon/actions/dropdown_m import { fetchHistory } from 'mastodon/actions/history'; import DropdownMenu from 'mastodon/components/dropdown_menu'; +/** + * + * @param {import('mastodon/store').RootState} state + * @param {*} props + */ const mapStateToProps = (state, { statusId }) => ({ - openDropdownId: state.getIn(['dropdown_menu', 'openId']), - openedViaKeyboard: state.getIn(['dropdown_menu', 'keyboard']), + openDropdownId: state.dropdownMenu.openId, + openedViaKeyboard: state.dropdownMenu.keyboard, items: state.getIn(['history', statusId, 'items']), loading: state.getIn(['history', statusId, 'loading']), }); @@ -15,11 +20,11 @@ const mapDispatchToProps = (dispatch, { statusId }) => ({ onOpen (id, onItemClick, keyboard) { dispatch(fetchHistory(statusId)); - dispatch(openDropdownMenu(id, keyboard)); + dispatch(openDropdownMenu({ id, keyboard })); }, onClose (id) { - dispatch(closeDropdownMenu(id)); + dispatch(closeDropdownMenu({ id })); }, }); diff --git a/app/javascript/mastodon/components/scrollable_list.jsx b/app/javascript/mastodon/components/scrollable_list.jsx index ce0b579f5..7672a4e42 100644 --- a/app/javascript/mastodon/components/scrollable_list.jsx +++ b/app/javascript/mastodon/components/scrollable_list.jsx @@ -23,9 +23,14 @@ const MOUSE_IDLE_DELAY = 300; const listenerOptions = supportsPassiveEvents ? { passive: true } : false; +/** + * + * @param {import('mastodon/store').RootState} state + * @param {*} props + */ const mapStateToProps = (state, { scrollKey }) => { return { - preventScroll: scrollKey === state.getIn(['dropdown_menu', 'scroll_key']), + preventScroll: scrollKey === state.dropdownMenu.scrollKey, }; }; diff --git a/app/javascript/mastodon/containers/dropdown_menu_container.js b/app/javascript/mastodon/containers/dropdown_menu_container.js index 6cf180cd5..bc9124c04 100644 --- a/app/javascript/mastodon/containers/dropdown_menu_container.js +++ b/app/javascript/mastodon/containers/dropdown_menu_container.js @@ -7,9 +7,12 @@ import { openModal, closeModal } from '../actions/modal'; import DropdownMenu from '../components/dropdown_menu'; import { isUserTouching } from '../is_mobile'; +/** + * @param {import('mastodon/store').RootState} state + */ const mapStateToProps = state => ({ - openDropdownId: state.getIn(['dropdown_menu', 'openId']), - openedViaKeyboard: state.getIn(['dropdown_menu', 'keyboard']), + openDropdownId: state.dropdownMenu.openId, + openedViaKeyboard: state.dropdownMenu.keyboard, }); const mapDispatchToProps = (dispatch, { status, items, scrollKey }) => ({ @@ -25,7 +28,7 @@ const mapDispatchToProps = (dispatch, { status, items, scrollKey }) => ({ actions: items, onClick: onItemClick, }, - }) : openDropdownMenu(id, keyboard, scrollKey)); + }) : openDropdownMenu({ id, keyboard, scrollKey })); }, onClose(id) { @@ -33,7 +36,7 @@ const mapDispatchToProps = (dispatch, { status, items, scrollKey }) => ({ modalType: 'ACTIONS', ignoreFocus: false, })); - dispatch(closeDropdownMenu(id)); + dispatch(closeDropdownMenu({ id })); }, }); diff --git a/app/javascript/mastodon/features/ui/index.jsx b/app/javascript/mastodon/features/ui/index.jsx index 55ccde72f..ac5e2d936 100644 --- a/app/javascript/mastodon/features/ui/index.jsx +++ b/app/javascript/mastodon/features/ui/index.jsx @@ -79,7 +79,7 @@ const mapStateToProps = state => ({ hasComposingText: state.getIn(['compose', 'text']).trim().length !== 0, hasMediaAttachments: state.getIn(['compose', 'media_attachments']).size > 0, canUploadMore: !state.getIn(['compose', 'media_attachments']).some(x => ['audio', 'video'].includes(x.get('type'))) && state.getIn(['compose', 'media_attachments']).size < 4, - dropdownMenuIsOpen: state.getIn(['dropdown_menu', 'openId']) !== null, + dropdownMenuIsOpen: state.dropdownMenu.openId !== null, firstLaunch: state.getIn(['settings', 'introductionVersion'], 0) < INTRODUCTION_VERSION, username: state.getIn(['accounts', me, 'username']), }); diff --git a/app/javascript/mastodon/reducers/dropdown_menu.js b/app/javascript/mastodon/reducers/dropdown_menu.js deleted file mode 100644 index 6f92f1bbe..000000000 --- a/app/javascript/mastodon/reducers/dropdown_menu.js +++ /dev/null @@ -1,19 +0,0 @@ -import Immutable from 'immutable'; - -import { - DROPDOWN_MENU_OPEN, - DROPDOWN_MENU_CLOSE, -} from '../actions/dropdown_menu'; - -const initialState = Immutable.Map({ openId: null, keyboard: false, scroll_key: null }); - -export default function dropdownMenu(state = initialState, action) { - switch (action.type) { - case DROPDOWN_MENU_OPEN: - return state.merge({ openId: action.id, keyboard: action.keyboard, scroll_key: action.scroll_key }); - case DROPDOWN_MENU_CLOSE: - return state.get('openId') === action.id ? state.set('openId', null).set('scroll_key', null) : state; - default: - return state; - } -} diff --git a/app/javascript/mastodon/reducers/dropdown_menu.ts b/app/javascript/mastodon/reducers/dropdown_menu.ts new file mode 100644 index 000000000..59e19bb16 --- /dev/null +++ b/app/javascript/mastodon/reducers/dropdown_menu.ts @@ -0,0 +1,33 @@ +import { createReducer } from '@reduxjs/toolkit'; + +import { closeDropdownMenu, openDropdownMenu } from '../actions/dropdown_menu'; + +interface DropdownMenuState { + openId: string | null; + keyboard: boolean; + scrollKey: string | null; +} + +const initialState: DropdownMenuState = { + openId: null, + keyboard: false, + scrollKey: null, +}; + +export const dropdownMenuReducer = createReducer(initialState, (builder) => { + builder + .addCase( + openDropdownMenu, + (state, { payload: { id, keyboard, scrollKey } }) => { + state.openId = id; + state.keyboard = keyboard; + state.scrollKey = scrollKey; + }, + ) + .addCase(closeDropdownMenu, (state, { payload: { id } }) => { + if (state.openId === id) { + state.openId = null; + state.scrollKey = null; + } + }); +}); diff --git a/app/javascript/mastodon/reducers/index.ts b/app/javascript/mastodon/reducers/index.ts index c61c862cf..722f04f37 100644 --- a/app/javascript/mastodon/reducers/index.ts +++ b/app/javascript/mastodon/reducers/index.ts @@ -15,7 +15,7 @@ import contexts from './contexts'; import conversations from './conversations'; import custom_emojis from './custom_emojis'; import domain_lists from './domain_lists'; -import dropdown_menu from './dropdown_menu'; +import { dropdownMenuReducer } from './dropdown_menu'; import filters from './filters'; import followed_tags from './followed_tags'; import height_cache from './height_cache'; @@ -46,7 +46,7 @@ import user_lists from './user_lists'; const reducers = { announcements, - dropdown_menu, + dropdownMenu: dropdownMenuReducer, timelines, meta, alerts,