board.ts 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'
  2. import { getBoardById, setBoard, addBoard } from 'api'
  3. import type { BoardData } from 'api'
  4. import type { StoreState } from 'store'
  5. export * from 'api/board'
  6. export { BoardType, BoardTypeDesc } from 'api'
  7. export interface BoardState {
  8. list: BoardData[]
  9. currentIndex: number
  10. }
  11. const initialState: BoardState = {
  12. list: [{ shapes: [], id: -1, bgImage: null }],
  13. currentIndex: 0
  14. }
  15. const replaceState = (state: BoardState, { payload }: { payload: BoardData }) => {
  16. state.list = [payload]
  17. state.currentIndex = 0
  18. }
  19. const pushState = (state: BoardState, { payload }: { payload: BoardData }) => {
  20. const current = state.list[state.currentIndex]
  21. const newList = state.list.slice(0, state.currentIndex + 1)
  22. newList.push({
  23. ...payload,
  24. id: current.id,
  25. })
  26. state.list = newList
  27. state.currentIndex += 1
  28. }
  29. const boardSlice = createSlice({
  30. name: 'board',
  31. initialState,
  32. reducers: {
  33. forward(state, { payload = 1 }: { payload: number }) {
  34. let move = state.currentIndex + payload
  35. state.currentIndex = move > state.list.length - 1 ? state.list.length - 1 : move
  36. console.log('forward')
  37. },
  38. backoff(state, { payload = 1 }: { payload: number }) {
  39. let move = state.currentIndex - payload
  40. state.currentIndex = move < 0 ? 0 : move
  41. return state
  42. },
  43. push: pushState,
  44. replace: replaceState,
  45. destory(state) {
  46. replaceState(state, { payload: initialState.list[0] })
  47. }
  48. },
  49. extraReducers(builder) {
  50. builder
  51. .addCase(insertBoard.fulfilled, (state, action) => {
  52. const current = state.list[state.currentIndex]
  53. state.list = state.list.map(data => ({
  54. ...data,
  55. bgImage: data.bgImage === current.bgImage ? action.payload.bgImage : data.bgImage,
  56. id: action.payload.id
  57. }))
  58. })
  59. .addCase(fetchBoard.fulfilled, replaceState)
  60. }
  61. })
  62. export const boardName = boardSlice.name
  63. export const boardReducer = boardSlice.reducer
  64. export const currentBoard = (state: StoreState) => state.board.list[state.board.currentIndex]
  65. export const boardStatus = (state: StoreState) => {
  66. const len = state.board.list.length
  67. const index = state.board.currentIndex
  68. return {
  69. canBack: index !== 0,
  70. canForward: index < len - 1,
  71. top: index === len - 1
  72. }
  73. }
  74. export const copyBoard = (boardData: BoardData): BoardData => {
  75. return JSON.parse(JSON.stringify(boardData))
  76. }
  77. export const fetchBoard = createAsyncThunk('fetch/board', getBoardById)
  78. export const insertBoard = createAsyncThunk('insert/board', addBoard)
  79. export const updateBoard = createAsyncThunk('update/board', setBoard)