refactor: add typescript support to project

This commit is contained in:
HD
2022-06-18 00:54:41 +08:00
parent 7ca0099cb0
commit e67379ece4
14 changed files with 404 additions and 193 deletions
+121
View File
@@ -0,0 +1,121 @@
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
import BASE_URL from '../config';
import { getNonNullValues } from '../../common/utils';
import { Channel, UpdateChannelDTO, UpdatePinnedMessageDTO } from '../../types/channel';
interface State {
ids: number[];
byId: { [id: number]: Channel | undefined };
}
const initialState: State = {
ids: [],
byId: {}
};
const channelsSlice = createSlice({
name: `channels`,
initialState,
reducers: {
resetChannels() {
return initialState;
},
fullfillChannels(state, action: PayloadAction<Channel[]>) {
const channels = action.payload || [];
state.ids = channels.map(({ gid }) => gid);
state.byId = Object.fromEntries(
channels.map((c) => {
const { gid, avatar_updated_at } = c;
c.icon =
avatar_updated_at == 0
? ''
: `${BASE_URL}/resource/group_avatar?gid=${gid}&t=${avatar_updated_at}`;
return [gid, c];
})
);
},
addChannel(state, action: PayloadAction<Channel>) {
const ch = action.payload;
const { gid, avatar_updated_at } = ch;
if (!state.ids.includes(+gid)) {
state.ids.push(+gid);
}
state.byId[gid] = {
...ch,
icon:
avatar_updated_at == 0
? ''
: `${BASE_URL}/resource/group_avatar?gid=${gid}&t=${avatar_updated_at}`
};
},
updateChannel(state, action: PayloadAction<UpdateChannelDTO>) {
const ignoreInPublic = ['add_member', 'remove_member'];
const { gid, operation, members = [], ...rest } = action.payload;
const currChannel = state.byId[gid];
if (
!currChannel ||
(currChannel.is_public && ignoreInPublic.includes(operation))
) return;
switch (operation) {
case 'remove_member': {
state.byId[gid]!.members = state.byId[gid]!.members.filter(
(id) => members.findIndex((uid) => uid == id) == -1
);
break;
}
case 'add_member': {
const currs = state.byId[gid]!.members;
const _set = new Set([...currs, ...members]);
state.byId[gid]!.members = Array.from(_set);
break;
}
default:
state.byId[gid] = { ...state.byId[gid]!, ...getNonNullValues(rest) };
break;
}
},
updatePinMessage(state, action: PayloadAction<UpdatePinnedMessageDTO>) {
const { gid, mid, msg } = action.payload;
let pinnedMessages = state.byId[gid]?.pinned_messages;
// add
if (msg) {
if (!pinnedMessages) {
pinnedMessages = [msg];
} else {
const idx = pinnedMessages.findIndex((msg) => msg.mid == mid);
if (idx > -1) {
pinnedMessages.splice(idx, 1);
}
pinnedMessages.push(msg);
}
} else {
// remove
if (pinnedMessages) {
const idx = pinnedMessages.findIndex((m) => m.mid == mid);
if (idx > -1) {
pinnedMessages.splice(idx, 1);
}
}
}
},
removeChannel(state, action: PayloadAction<number>) {
const gid = action.payload;
const idx = state.ids.findIndex((i) => i == gid);
if (idx > -1) {
state.ids.splice(idx, 1);
delete state.byId[gid];
}
}
}
});
export const {
updatePinMessage,
resetChannels,
fullfillChannels,
addChannel,
updateChannel,
removeChannel
} = channelsSlice.actions;
export default channelsSlice.reducer;