Port 38c6216082
to glitch-soc
Signed-off-by: Claire <claire.github-309c@sitedethib.com>
local
parent
6a592083f1
commit
382b2a506a
47 changed files with 556 additions and 283 deletions
@ -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, |
||||
}; |
||||
} |
@ -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'); |
@ -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; |
||||
} |
||||
} |
@ -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; |
||||
} |
||||
} |
Loading…
Reference in new issue