refactor: more TS code

This commit is contained in:
Tristan Yang
2022-07-08 10:18:23 +08:00
parent be6822e568
commit 678b8515ca
36 changed files with 210 additions and 220 deletions
+21 -21
View File
@@ -1,15 +1,15 @@
import { useState } from "react";
import { useDispatch, batch } from "react-redux";
import { fullfillReactionMessage } from "../slices/message.reaction";
import { fullfillServer } from "../slices/server";
import { fullfillMessage } from "../slices/message";
import { fullfillChannelMsg } from "../slices/message.channel";
import { fullfillUserMsg } from "../slices/message.user";
import { fullfillChannels } from "../slices/channels";
import { fullfillUsers } from "../slices/users";
import { fullfillFootprint } from "../slices/footprint";
import { fullfillFileMessage } from "../slices/message.file";
import { fullfillUI } from "../slices/ui";
import { fillReactionMessage } from "../slices/message.reaction";
import { fillServer } from "../slices/server";
import { fillMessage } from "../slices/message";
import { fillChannelMsg } from "../slices/message.channel";
import { fillUserMsg } from "../slices/message.user";
import { fillChannels } from "../slices/channels";
import { fillUsers } from "../slices/users";
import { fillFootprint } from "../slices/footprint";
import { fillFileMessage } from "../slices/message.file";
import { fillUI } from "../slices/ui";
const useRehydrate = () => {
const [iterated, setIterated] = useState(false);
@@ -75,18 +75,18 @@ const useRehydrate = () => {
})
);
batch(() => {
dispatch(fullfillUsers(rehydrateData.users));
dispatch(fullfillServer(rehydrateData.server));
console.log("fullfill channels from indexedDB");
dispatch(fullfillChannels(rehydrateData.channels));
dispatch(fillUsers(rehydrateData.users));
dispatch(fillServer(rehydrateData.server));
console.log("fill channels from indexedDB");
dispatch(fillChannels(rehydrateData.channels));
// file message
dispatch(fullfillFileMessage(rehydrateData.fileMessage.list));
dispatch(fullfillChannelMsg(rehydrateData.channelMessage));
dispatch(fullfillUserMsg(rehydrateData.userMessage));
dispatch(fullfillMessage(rehydrateData.message));
dispatch(fullfillFootprint(rehydrateData.footprint));
dispatch(fullfillUI(rehydrateData.ui));
dispatch(fullfillReactionMessage(rehydrateData.reactionMessage));
dispatch(fillFileMessage(rehydrateData.fileMessage.list));
dispatch(fillChannelMsg(rehydrateData.channelMessage));
dispatch(fillUserMsg(rehydrateData.userMessage));
dispatch(fillMessage(rehydrateData.message));
dispatch(fillFootprint(rehydrateData.footprint));
dispatch(fillUI(rehydrateData.ui));
dispatch(fillReactionMessage(rehydrateData.reactionMessage));
});
setIterated(true);
-1
View File
@@ -23,7 +23,6 @@ export const ChatPrefixs = {
user: "@"
};
export const vapidKey = `BGXCn-5YRXSFw38Q9lUKJ5bibL212-yIQn1pCvthGhp6_KwA29FO1Ax_d_7if1vfC2a5wTSVO8AcZrc-Hm1aS0Y`;
// "840319286941-6ds7lbvk55eq8mjortf68cb2ll65lprt.apps.googleusercontent.com";
export const tokenHeader = "X-API-Key";
export const FILE_SLICE_SIZE = 1000 * 200 * 8; //200kb
export const FILE_IMAGE_SIZE = 1000 * 10000 * 8; //10mb
@@ -7,7 +7,7 @@ export default async function handler({ operation, data, payload }) {
return;
}
switch (operation) {
case "fullfillChannels":
case "fillChannels":
{
const chs = payload;
await Promise.all(
+1 -1
View File
@@ -7,7 +7,7 @@ export default async function handler({ operation, data, payload }) {
return;
}
switch (operation) {
case "fullfillUsers":
case "fillUsers":
{
const users = payload;
await Promise.all(
+2 -2
View File
@@ -99,14 +99,14 @@ export const channelApi = createApi({
const {
channelMessage,
ui: {
rememberedNavs: { chat: remeberedPath }
rememberedNavs: { chat: rememberedPath }
}
} = getState() as RootState;
try {
await queryFulfilled;
// 删掉该channel下的所有消息&reaction
const mids = channelMessage[id];
if (remeberedPath == `/chat/channel/${id}`) {
if (rememberedPath == `/chat/channel/${id}`) {
dispatch(updateRememberedNavs({ path: null }));
}
if (mids) {
+2 -7
View File
@@ -1,12 +1,7 @@
import { createApi } from "@reduxjs/toolkit/query/react";
import { ContentTypes } from "../config";
import { updateReadChannels, updateReadUsers } from "../slices/footprint";
import {
fullfillFavorites,
populateFavorite,
addFavorite,
deleteFavorite
} from "../slices/favorites";
import { fillFavorites, populateFavorite, addFavorite, deleteFavorite } from "../slices/favorites";
import { onMessageSendStarted } from "./handlers";
import { normalizeArchiveData } from "../../common/utils";
// import { updateMessage } from "../slices/message";
@@ -150,7 +145,7 @@ export const messageApi = createApi({
async onQueryStarted(data, { dispatch, queryFulfilled }) {
try {
const { data: favorites } = await queryFulfilled;
dispatch(fullfillFavorites(favorites));
dispatch(fillFavorites(favorites));
for (const fav of favorites) {
const { id } = fav;
dispatch(messageApi.endpoints.getFavoriteDetails.initiate(id));
+9 -8
View File
@@ -4,11 +4,12 @@ import { KEY_UID } from "../config";
import baseQuery from "./base.query";
import { resetAuthData } from "../slices/auth.data";
import { updateMute } from "../slices/footprint";
import { fullfillUsers } from "../slices/users";
import { fillUsers } from "../slices/users";
import BASE_URL, { ContentTypes } from "../config";
import { onMessageSendStarted } from "./handlers";
import handleChatMessage from "../../common/hook/useStreaming/chat.handler";
import { User } from "../../types/auth";
import { User, UserDTO, UserForAdmin, UserForAdminDTO } from "../../types/user";
import { ContentType, MuteDTO } from "../../types/message";
export const userApi = createApi({
reducerPath: "userApi",
@@ -28,7 +29,7 @@ export const userApi = createApi({
});
},
async onQueryStarted(data, { dispatch, queryFulfilled }) {
const local_uid = localStorage.getItem(KEY_UID);
const local_uid = Number(localStorage.getItem(KEY_UID));
try {
const { data: users } = await queryFulfilled;
const matchedUser = users.find((c) => c.uid == local_uid);
@@ -41,24 +42,24 @@ export const userApi = createApi({
const markedUsers = users.map((u) => {
return u.uid == matchedUser.uid ? { ...u, online: true } : u;
});
dispatch(fullfillUsers(markedUsers));
dispatch(fillUsers(markedUsers));
}
} catch {
console.log("get user list error");
}
}
}),
deleteUser: builder.query({
deleteUser: builder.query<void, number>({
query: (uid) => ({ url: `/admin/user/${uid}`, method: "DELETE" })
}),
updateUser: builder.mutation({
updateUser: builder.mutation<UserForAdmin, UserForAdminDTO>({
query: ({ id, ...rest }) => ({
url: `/admin/user/${id}`,
body: rest,
method: "PUT"
})
}),
updateMuteSetting: builder.mutation({
updateMuteSetting: builder.mutation<void, MuteDTO>({
query: (data) => ({
url: `/user/mute`,
method: "POST",
@@ -83,7 +84,7 @@ export const userApi = createApi({
body: data
})
}),
updateInfo: builder.mutation({
updateInfo: builder.mutation<User, UserDTO>({
query: (data) => ({
url: `user`,
method: "PUT",
+2 -2
View File
@@ -24,7 +24,7 @@ const channelsSlice = createSlice({
resetChannels() {
return initialState;
},
fullfillChannels(state, action: PayloadAction<Channel[]>) {
fillChannels(state, action: PayloadAction<Channel[]>) {
const channels = action.payload || [];
state.ids = channels.map(({ gid }) => gid);
channels.forEach((c) => {
@@ -113,7 +113,7 @@ const channelsSlice = createSlice({
export const {
updatePinMessage,
resetChannels,
fullfillChannels,
fillChannels,
addChannel,
updateChannel,
removeChannel
+3 -3
View File
@@ -1,4 +1,4 @@
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
// import BASE_URL from "../config";
// todo: check messages type
@@ -13,7 +13,7 @@ const favoritesSlice = createSlice({
name: `favorites`,
initialState,
reducers: {
fullfillFavorites(state, action: PayloadAction<Favorite[]>) {
fillFavorites(state, action: PayloadAction<Favorite[]>) {
return action.payload;
},
addFavorite(state, action: PayloadAction<Favorite>) {
@@ -36,7 +36,7 @@ const favoritesSlice = createSlice({
}
});
export const { addFavorite, deleteFavorite, fullfillFavorites, populateFavorite } =
export const { addFavorite, deleteFavorite, fillFavorites, populateFavorite } =
favoritesSlice.actions;
export default favoritesSlice.reducer;
+12 -19
View File
@@ -1,13 +1,13 @@
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
import { MuteChannel, MuteUser } from "../../types/sse";
import { MuteDTO } from "../../types/message";
export interface State {
usersVersion: number;
afterMid: number;
readUsers: { [uid: number]: number };
readChannels: { [gid: number]: number };
muteUsers: { [uid: number]: { expired_at: number } | undefined };
muteChannels: { [gid: number]: { expired_at: number } | undefined };
muteUsers: { [uid: number]: { expired_in: number } | undefined };
muteChannels: { [gid: number]: { expired_in: number } | undefined };
}
const initialState: State = {
@@ -19,13 +19,6 @@ const initialState: State = {
muteChannels: {}
};
interface UpdateMutePayload {
remove_users: number[];
remove_groups: number[];
add_users: MuteUser[];
add_groups: MuteChannel[];
}
const footprintSlice = createSlice({
name: "footprint",
initialState,
@@ -33,7 +26,7 @@ const footprintSlice = createSlice({
resetFootprint() {
return initialState;
},
fullfillFootprint(state, action) {
fillFootprint(state, action) {
const {
usersVersion = 0,
afterMid = 0,
@@ -57,35 +50,35 @@ const footprintSlice = createSlice({
updateAfterMid(state, action: PayloadAction<number>) {
state.afterMid = action.payload;
},
updateMute(state, action: PayloadAction<UpdateMutePayload>) {
updateMute(state, action: PayloadAction<MuteDTO>) {
const payload = action.payload || {};
Object.keys(payload).forEach((key) => {
switch (key) {
case "remove_users": {
const uids = payload.remove_users;
uids.forEach((id) => {
uids?.forEach((id) => {
delete state.muteUsers[id];
});
break;
}
case "remove_groups": {
const gids = payload.remove_groups;
gids.forEach((id) => {
gids?.forEach((id) => {
delete state.muteChannels[id];
});
break;
}
case "add_users": {
const mutes = payload.add_users;
mutes.forEach(({ uid, expired_at }) => {
state.muteUsers[uid] = { expired_at };
mutes?.forEach(({ uid, expired_in }) => {
state.muteUsers[uid] = { expired_in };
});
break;
}
case "add_groups": {
const mutes = payload.add_groups;
mutes.forEach(({ gid, expired_at }) => {
state.muteChannels[gid] = { expired_at };
mutes?.forEach(({ gid, expired_in }) => {
state.muteChannels[gid] = { expired_in };
});
break;
}
@@ -113,7 +106,7 @@ const footprintSlice = createSlice({
export const {
resetFootprint,
fullfillFootprint,
fillFootprint,
updateAfterMid,
updateUsersVersion,
updateReadChannels,
+2 -2
View File
@@ -13,7 +13,7 @@ const channelMsgSlice = createSlice({
resetChannelMsg() {
return initialState;
},
fullfillChannelMsg(state, action: PayloadAction<State>) {
fillChannelMsg(state, action: PayloadAction<State>) {
return action.payload;
},
addChannelMsg(state, action: PayloadAction<{ id: number; mid: number; local_id?: any }>) {
@@ -59,7 +59,7 @@ const channelMsgSlice = createSlice({
export const {
removeChannelSession,
resetChannelMsg,
fullfillChannelMsg,
fillChannelMsg,
addChannelMsg,
removeChannelMsg,
replaceChannelMsg
+3 -3
View File
@@ -1,4 +1,4 @@
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
const initialState: number[] = [];
@@ -9,7 +9,7 @@ const fileMessageSlice = createSlice({
resetFileMessage() {
return initialState;
},
fullfillFileMessage(state, action: PayloadAction<number[]>) {
fillFileMessage(state, action: PayloadAction<number[]>) {
return action.payload || [];
},
addFileMessage(state, action: PayloadAction<number>) {
@@ -33,7 +33,7 @@ const fileMessageSlice = createSlice({
}
});
export const { removeFileMessage, resetFileMessage, fullfillFileMessage, addFileMessage } =
export const { removeFileMessage, resetFileMessage, fillFileMessage, addFileMessage } =
fileMessageSlice.actions;
export default fileMessageSlice.reducer;
+8 -6
View File
@@ -1,10 +1,12 @@
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
// todo: check entity type
export interface State {
[mid: number]: {
[reaction: number]: number[]
} | undefined;
[mid: number]:
| {
[reaction: number]: number[];
}
| undefined;
}
const initialState: State = {};
@@ -15,7 +17,7 @@ const reactionMessageSlice = createSlice({
resetReactionMessage() {
return initialState;
},
fullfillReactionMessage(state, action: PayloadAction<State>) {
fillReactionMessage(state, action: PayloadAction<State>) {
return action.payload;
},
removeReactionMessage(state, action: PayloadAction<number | number[]>) {
@@ -59,7 +61,7 @@ const reactionMessageSlice = createSlice({
export const {
removeReactionMessage,
resetReactionMessage,
fullfillReactionMessage,
fillReactionMessage,
toggleReactionMessage
} = reactionMessageSlice.actions;
+2 -2
View File
@@ -17,7 +17,7 @@ const messageSlice = createSlice({
resetMessage() {
return initialState;
},
fullfillMessage(state, action) {
fillMessage(state, action) {
return Object.assign({ ...initialState }, action.payload);
},
updateMessage(state, action) {
@@ -75,7 +75,7 @@ const messageSlice = createSlice({
export const {
resetMessage,
fullfillMessage,
fillMessage,
setMessage,
updateMessage,
addMessage,
+9 -13
View File
@@ -1,9 +1,9 @@
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
export interface State {
ids: string[];
ids: number[];
// todo: check object type
byId: { [id: number]: any; };
byId: { [id: number]: any };
}
const initialState: State = {
@@ -18,17 +18,16 @@ const userMsgSlice = createSlice({
resetUserMsg() {
return initialState;
},
fullfillUserMsg(state, action: PayloadAction<{ [id: string]: any; }>) {
fillUserMsg(state, action: PayloadAction<{ [id: number]: any }>) {
state.ids = Object.keys(action.payload);
state.byId = action.payload;
},
addUserMsg(state, action) {
addUserMsg(state, action: PayloadAction<{ id: number; mid: number; local_id: number }>) {
const { id, mid, local_id } = action.payload;
if (state.byId[id]) {
const midExsited = state.byId[id].findIndex((id) => id == mid) > -1;
const localMsgExsited = state.byId[id].findIndex((id) => id == local_id) > -1;
if (midExsited || localMsgExsited) return;
const midExisted = state.byId[id].findIndex((id) => id == mid) > -1;
const localMsgExisted = state.byId[id].findIndex((id) => id == local_id) > -1;
if (midExisted || localMsgExisted) return;
state.byId[id].push(+mid);
// 只要有新消息,就检查下
if (state.ids.findIndex((uid) => uid == id) == -1) {
@@ -62,16 +61,13 @@ const userMsgSlice = createSlice({
removeUserSession(state, action) {
const ids = Array.isArray(action.payload) ? action.payload : [action.payload];
state.ids = state.ids.filter((id) => ids.findIndex((i) => i == id) == -1);
// ids.forEach((id) => {
// delete state.byId[id];
// });
}
}
});
export const {
removeUserSession,
resetUserMsg,
fullfillUserMsg,
fillUserMsg,
addUserMsg,
removeUserMsg,
replaceUserMsg
+1 -1
View File
@@ -1,5 +1,5 @@
reset
fullfill
fill
set
add
update
+2 -2
View File
@@ -25,7 +25,7 @@ const serverSlice = createSlice({
resetServer() {
return initialState;
},
fullfillServer(state, action: PayloadAction<StoredServer>) {
fillServer(state, action: PayloadAction<StoredServer>) {
const {
inviteLink = {
link: "",
@@ -51,5 +51,5 @@ const serverSlice = createSlice({
}
});
export const { updateInfo, resetServer, fullfillServer } = serverSlice.actions;
export const { updateInfo, resetServer, fillServer } = serverSlice.actions;
export default serverSlice.reducer;
+6 -3
View File
@@ -39,7 +39,7 @@ const uiSlice = createSlice({
name: "ui",
initialState,
reducers: {
fullfillUI(state, action) {
fillUI(state, action) {
return { ...initialState, ...action.payload };
},
setReady(state) {
@@ -57,7 +57,10 @@ const uiSlice = createSlice({
updateFileListView(state, action) {
state.fileListView = action.payload;
},
updateRememberedNavs(state, action: PayloadAction<{ key?: string; path: string | null }>) {
updateRememberedNavs(
state,
action: PayloadAction<{ key?: "chat" | "user"; path: string | null } | undefined>
) {
const { key = "chat", path = null } = action.payload || {};
state.rememberedNavs[key] = path;
},
@@ -155,7 +158,7 @@ const uiSlice = createSlice({
});
export const {
fullfillUI,
fillUI,
setReady,
updateOnline,
updateInputMode,
+2 -3
View File
@@ -26,7 +26,7 @@ const usersSlice = createSlice({
resetUsers() {
return initialState;
},
fullfillUsers(state, action: PayloadAction<StoredUser[]>) {
fillUsers(state, action: PayloadAction<StoredUser[]>) {
const users = action.payload || [];
state.ids = users.map(({ uid }) => uid);
state.byId = Object.fromEntries(
@@ -99,6 +99,5 @@ const usersSlice = createSlice({
}
});
export const { resetUsers, fullfillUsers, updateUsersByLogs, updateUsersStatus } =
usersSlice.actions;
export const { resetUsers, fillUsers, updateUsersByLogs, updateUsersStatus } = usersSlice.actions;
export default usersSlice.reducer;

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

+9 -6
View File
@@ -1,7 +1,6 @@
// import React from 'react'
import Tippy from "@tippyjs/react";
import Tippy, { TippyProps } from "@tippyjs/react";
import styled from "styled-components";
import { Placement } from "tippy.js";
import { FC, ReactElement } from "react";
const StyledTip = styled.div`
@@ -40,14 +39,18 @@ const StyledTip = styled.div`
}
`;
interface Props {
interface IProps extends TippyProps {
tip: string;
placement?: Placement;
delay?: number | [number | null, number | null];
children: ReactElement;
}
const Tooltip: FC<Props> = ({ tip = "", placement = "right", delay = null, children, ...rest }) => {
const Tooltip: FC<IProps> = ({
tip = "",
placement = "right",
delay = null,
children,
...rest
}) => {
const defaultDuration: [number, number] = [300, 250];
return (
+3 -3
View File
@@ -6,7 +6,7 @@ import BASE_URL from "../../../app/config";
import { setReady } from "../../../app/slices/ui";
import { useRenewMutation } from "../../../app/services/auth";
import {
fullfillChannels,
fillChannels,
addChannel,
removeChannel,
updateChannel,
@@ -208,8 +208,8 @@ export default function useStreaming() {
}
break;
case "related_groups":
console.log("fullfill channels from streaming", data);
dispatch(fullfillChannels(data.groups));
console.log("fill channels from streaming", data);
dispatch(fillChannels(data.groups));
break;
case "joined_group":
console.log("joined group", data.group);
+11 -9
View File
@@ -1,17 +1,15 @@
// import React from "react";
// import { useSelector } from "react-redux";
import { FC, FormEvent } from "react";
import styled from "styled-components";
import usePinMessage from "../../../common/hook/usePinMessage";
import PreviewMessage from "../../../common/component/Message/PreviewMessage";
import IconSurprise from "../../../assets/icons/emoji.suprise.svg";
// import IconForward from "../../../assets/icons/forward.svg";
import IconSurprise from "../../../assets/icons/emoji.surprise.svg";
import IconClose from "../../../assets/icons/close.svg";
const Styled = styled.div`
padding: 16px;
background: #f9fafb;
filter: drop-shadow(0px 25px 50px rgba(31, 41, 55, 0.25));
border-radius: 12px;
width: 406px;
min-width: 406px;
> .head {
font-weight: 600;
font-size: 16px;
@@ -81,11 +79,14 @@ const Styled = styled.div`
}
}
`;
export default function PinList({ id }) {
type Props = {
id: number;
};
const PinList: FC<Props> = ({ id }: Props) => {
const { pins, unpinMessage, canPin } = usePinMessage(id);
const handleUnpin = (evt) => {
const handleUnpin = (evt: FormEvent<HTMLButtonElement>) => {
const { mid } = evt.currentTarget.dataset;
console.log("unpin msg", mid);
if (!mid) return;
unpinMessage(+mid);
};
const noPins = pins.length == 0;
@@ -125,4 +126,5 @@ export default function PinList({ id }) {
)}
</Styled>
);
}
};
export default PinList;
+6 -38
View File
@@ -2,7 +2,7 @@ import { useState, useEffect } from "react";
import { useDebounce } from "rooks";
import { NavLink, useLocation } from "react-router-dom";
import Tippy from "@tippyjs/react";
import { useDispatch, useSelector } from "react-redux";
import { useDispatch } from "react-redux";
import PinList from "./PinList";
import FavList from "../FavList";
import { useReadMessageMutation } from "../../../app/services/message";
@@ -23,16 +23,10 @@ import IconPin from "../../../assets/icons/pin.svg";
import IconHeadphone from "../../../assets/icons/headphone.svg";
import addIcon from "../../../assets/icons/add.svg?url";
import {
// StyledNotification,
StyledUsers,
StyledChannelChat,
StyledHeader
} from "./styled";
import { StyledUsers, StyledChannelChat, StyledHeader } from "./styled";
import InviteModal from "../../../common/component/InviteModal";
import LoadMore from "../LoadMore";
// import useChatScroll from "../../../common/hook/useChatScroll";
import { useAppSelector } from "../../../app/store";
export default function ChannelChat({ cid = "", dropFiles = [] }) {
const { values: agoraConfig } = useConfig("agora");
const {
@@ -44,7 +38,6 @@ export default function ChannelChat({ cid = "", dropFiles = [] }) {
context: "channel",
id: cid
});
// const scrollObserveRef = useChatScroll([msgIds, appends]);
const [toolVisible, setToolVisible] = useState("");
const { pathname } = useLocation();
const dispatch = useDispatch();
@@ -60,7 +53,7 @@ export default function ChannelChat({ cid = "", dropFiles = [] }) {
messageData,
loginUser,
footprint
} = useSelector((store) => {
} = useAppSelector((store) => {
return {
selects: store.ui.selectMessages[`channel_${cid}`],
footprint: store.footprint,
@@ -71,10 +64,6 @@ export default function ChannelChat({ cid = "", dropFiles = [] }) {
messageData: store.message || {}
};
});
// const ref = useChatScroll(msgIds);
// const handleClearUnreads = () => {
// dispatch(readMessage(msgIds));
// };
useEffect(() => {
dispatch(updateRememberedNavs());
return () => {
@@ -91,7 +80,7 @@ export default function ChannelChat({ cid = "", dropFiles = [] }) {
if (!data) return null;
const { name, description, is_public, members = [], owner } = data;
const memberIds = is_public ? userIds : members.slice(0).sort((n) => (n == owner ? -1 : 0));
const addVisible = loginUser?.is_admin || owner == loginUser.uid;
const addVisible = loginUser?.is_admin || owner == loginUser?.uid;
console.log("channel message list", msgIds);
const readIndex = footprint.readChannels[cid];
const pinCount = data?.pinned_messages?.length || 0;
@@ -103,7 +92,6 @@ export default function ChannelChat({ cid = "", dropFiles = [] }) {
to={cid}
context="channel"
dropFiles={dropFiles}
// ref={containerRef}
aside={
<>
<ul className="tools">
@@ -171,7 +159,6 @@ export default function ChannelChat({ cid = "", dropFiles = [] }) {
</Tooltip>
</li>
</ul>
{/* <hr className="divider" /> */}
</>
}
header={
@@ -211,11 +198,7 @@ export default function ChannelChat({ cid = "", dropFiles = [] }) {
) : null
}
>
<StyledChannelChat
// ref={scrollObserveRef}
id={`VOCECHAT_FEED_channel_${cid}`}
>
{/* <div className="anchor"></div> */}
<StyledChannelChat id={`VOCECHAT_FEED_channel_${cid}`}>
{hasMore ? (
<LoadMore pullUp={pullUp} />
) : (
@@ -246,22 +229,7 @@ export default function ChannelChat({ cid = "", dropFiles = [] }) {
context: "channel"
});
})}
{/* </div> */}
</StyledChannelChat>
{/* {unreads != 0 && (
<StyledNotification>
<div className="content">
{unreads} new messages
{msgs.lastAccess
? `since ${dayjs(msgs.lastAccess).format("YYYY-MM-DD h:mm:ss A")}`
: ""}
</div>
<button onClick={handleClearUnreads} className="clear">
Mark As Read
</button>
</StyledNotification>
)} */}
</Layout>
</>
);
+5 -3
View File
@@ -1,4 +1,4 @@
// import React from 'react'
import { FC } from "react";
import { NavLink, useLocation } from "react-router-dom";
import Tooltip from "../../common/component/Tooltip";
import settingIcon from "../../assets/icons/setting.svg?url";
@@ -31,7 +31,8 @@ const StyledMenus = styled.ul`
}
}
`;
export default function Menu() {
type Props = {};
const Menu: FC<Props> = () => {
const { pathname } = useLocation();
return (
<StyledMenus>
@@ -59,4 +60,5 @@ export default function Menu() {
</li> */}
</StyledMenus>
);
}
};
export default Menu;
+1 -3
View File
@@ -1,5 +1,4 @@
// import React from 'react';
// import { useEffect } from "react";
import { Outlet, NavLink, useLocation, useMatch } from "react-router-dom";
import StyledWrapper from "./styled";
import User from "./User";
@@ -36,7 +35,6 @@ export default function HomePage() {
};
});
const { loading } = usePreload();
// console.log("index loading", loading, ready);
if (loading || !ready) {
return <Loading reload={true} fullscreen={true} />;
}
@@ -60,7 +58,7 @@ export default function HomePage() {
<Notification />
<StyledWrapper>
<div className={`col left`}>
<User uid={loginUid} />
{loginUid && <User uid={loginUid} />}
<nav className="link_navs">
<NavLink
className={() => {
-1
View File
@@ -13,7 +13,6 @@ const StyledWrapper = styled.div`
position: relative;
background: transparent;
width: 64px;
/* box-shadow: inset -1px 0px 0px rgba(0, 0, 0, 0.1); */
transition: all 0.5s ease-in;
> .divider {
width: -webkit-fill-available;
-5
View File
@@ -5,11 +5,6 @@ import { useLazyGetUsersQuery } from "../../app/services/user";
import { useLazyGetServerQuery } from "../../app/services/server";
import useStreaming from "../../common/hook/useStreaming";
import { useAppSelector } from "../../app/store";
// pollingInterval: 0,
// const querySetting = {
// refetchOnMountOrArgChange: true,
// };
// let request = null;
export default function usePreload() {
const { rehydrate, rehydrated } = useRehydrate();
const { loginUid, token } = useAppSelector((store) => {
+1 -14
View File
@@ -1,3 +1,4 @@
import { User } from "./user";
export interface AuthToken {
// common
server_id: string;
@@ -6,20 +7,6 @@ export interface AuthToken {
expired_in: number;
}
export type Gender = 0 | 1;
export interface User {
uid: number;
email: string;
name: string;
gender: Gender;
language: string;
is_admin: boolean;
avatar_updated_at: number;
create_by: string;
avatar?: string;
}
export interface AuthData extends AuthToken {
initialized?: boolean;
user: User;
+1
View File
@@ -46,6 +46,7 @@ export interface UpdateChannelDTO {
// type = 'user_joined_group' | 'user_leaved_group'
// gid
uid?: number[];
icon?: string;
}
export interface UpdatePinnedMessageDTO {
-36
View File
@@ -1,39 +1,3 @@
export interface EntityId {
id: number;
}
export interface OG {
type: string;
title: string;
url: string;
images: [
{
type?: string;
url: string;
secure_url?: string;
width?: number;
height?: number;
alt?: string;
}
];
audios: [
{
type?: string;
url: string;
secure_url?: string;
}
];
videos: [
{
type?: string;
url: string;
secure_url?: string;
width: number;
height: number;
}
];
favicon_url?: string;
description?: string;
locale?: string;
locale_alternate?: [];
site_name?: string;
}
+13
View File
@@ -1,2 +1,15 @@
export type ContentType = "text/plain" | "text/markdown" | "vocechat/file" | "vocechat/archive";
export type ContentTypeKey = "text" | "markdown" | "file" | "archive";
export interface MuteDTO {
add_users?: {
uid: number;
expired_in: number;
}[];
add_groups?: {
gid: number;
expired_in: number;
}[];
remove_users?: number[];
remove_groups?: number[];
}
+37
View File
@@ -28,3 +28,40 @@ export interface UploadResponse {
height: number;
};
}
// Open Graph
export interface OG {
type: string;
title: string;
url: string;
images: [
{
type?: string;
url: string;
secure_url?: string;
width?: number;
height?: number;
alt?: string;
}
];
audios: [
{
type?: string;
url: string;
secure_url?: string;
}
];
videos: [
{
type?: string;
url: string;
secure_url?: string;
width: number;
height: number;
}
];
favicon_url?: string;
description?: string;
locale?: string;
locale_alternate?: [];
site_name?: string;
}
+1 -1
View File
@@ -1,5 +1,5 @@
// call `organization` in backend
import { User } from "./auth";
import { User } from "./user";
export interface Server {
name: string;
+33
View File
@@ -0,0 +1,33 @@
export type Gender = 0 | 1;
export interface User {
uid: number;
email: string;
name: string;
gender: Gender;
language: string;
is_admin: boolean;
avatar_updated_at: number;
create_by: string;
avatar?: string;
}
export type UserStatus = "normal" | "frozen";
export type UserDevice = {
device: string;
device_token?: string;
is_online: boolean;
};
export interface UserForAdmin extends User {
password: string;
in_online: boolean;
updated_at: number;
status: UserStatus;
online_devices: UserDevice[];
}
export interface UserForAdminDTO
extends Pick<
UserForAdmin,
"email" | "password" | "name" | "gender" | "is_admin" | "language" | "status"
> {}
export interface UserDTO extends Pick<User, "name" | "gender" | "language"> {}