~cytrogen/masto-fe

ref: f8dc013b0d81d5d463c086e291ce99ab1d796a9d masto-fe/app/javascript/mastodon/reducers/modal.ts -rw-r--r-- 2.1 KiB
f8dc013b — Cytrogen [feature] Add language selector to local settings 5 days ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import { Record as ImmutableRecord, Stack } from "immutable";

import  { type Reducer } 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";

export 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 const modalReducer: Reducer<State> = (state = initialState, action) => {
  if (openModal.match(action)) {
    return pushModal(
      state,
      action.payload.modalType,
      action.payload.modalProps,
    );
  } else if (closeModal.match(action)) {
    return popModal(state, action.payload);
  } else if (action.type === COMPOSE_UPLOAD_CHANGE_SUCCESS) {
    return popModal(state, { modalType: "FOCAL_POINT", ignoreFocus: false });
  } else if (action.type === TIMELINE_DELETE) {
    return state.update("stack", (stack) =>
      stack.filterNot(
        (modal) => modal.get("modalProps").statusId === action.id,
      ),
    );
  } else {
    return state;
  }
};