refactor: add typescript support to project

This commit is contained in:
HD
2022-06-21 15:08:35 +08:00
parent 88ec2b742a
commit bd799ebea8
259 changed files with 1042 additions and 458 deletions
@@ -10,10 +10,8 @@ import InviteModal from "../../../common/component/InviteModal";
import Tooltip from "../../../common/component/Tooltip";
import IconSetting from "../../../assets/icons/setting.svg";
import IconInvite from "../../../assets/icons/invite.from.channel.svg";
// import { useDebounce} from "rooks";
import { useReadMessageMutation } from "../../../app/services/message";
import { useUpdateMuteSettingMutation } from "../../../app/services/contact";
import StyledLink from "./styled";
import ChannelIcon from "../../../common/component/ChannelIcon";
import { getUnreadCount } from "../utils";
@@ -1,12 +1,11 @@
import { useState } from "react";
import { useSelector } from "react-redux";
import DeleteConfirmModal from "../../settingChannel/DeleteConfirmModal";
import NavItem from "./NavItem";
import { useAppSelector } from "../../../app/store";
export default function ChannelList({ setDropFiles }) {
const [currId, setCurrId] = useState(null);
const { channelIds } = useSelector((store) => {
const { channelIds } = useAppSelector((store) => {
return { channelIds: store.channels.ids };
});
@@ -82,4 +82,5 @@ const Styled = styled(NavLink)`
}
}
`;
export default Styled;
@@ -3,7 +3,6 @@ import { useSelector } from "react-redux";
import { useDebounce } from "rooks";
import Tippy from "@tippyjs/react";
import FavList from "../FavList";
import Tooltip from "../../../common/component/Tooltip";
import FavIcon from "../../../assets/icons/bookmark.svg";
// import searchIcon from "../../../assets/icons/search.svg?url";
@@ -16,6 +15,7 @@ import { StyledHeader, StyledDMChat } from "./styled";
import LoadMore from "../LoadMore";
import { renderMessageFragment } from "../utils";
import useMessageFeed from "../../../common/hook/useMessageFeed";
export default function DMChat({ uid = "", dropFiles = [] }) {
const {
list: msgIds,
@@ -1,11 +1,15 @@
// import React from "react";
import { useSelector } from "react-redux";
import { FC } from "react";
import { getUnreadCount } from "../utils";
import NavItem from "./NavItem";
export default function DMList({ uids, setDropFiles }) {
const { userMessage, messageData, readUsers, loginUid } = useSelector((store) => {
import { useAppSelector } from "../../../app/store";
interface Props {
uids: number[];
setDropFiles: () => void;
}
const DMList: FC<Props> = ({ uids, setDropFiles }) => {
const { userMessage, messageData, readUsers, loginUid } = useAppSelector((store) => {
return {
loginUid: store.authData.uid,
readUsers: store.footprint.readUsers,
@@ -31,14 +35,20 @@ export default function DMList({ uids, setDropFiles }) {
return { lastMid, unreads, uid };
});
// console.log("temp uids", sessions);
return sessions
.sort((s1, s2) => {
if (!s1.lastMid) return s2.lastMid - Infinity;
return s2.lastMid - s1.lastMid;
})
.map(({ lastMid, uid, unreads }) => {
return (
<NavItem key={uid} uid={uid} mid={lastMid} unreads={unreads} setFiles={setDropFiles} />
);
});
}
return (
<>
{sessions
.sort((s1, s2) => {
if (!s1.lastMid) return s2.lastMid - Infinity;
return s2.lastMid - s1.lastMid;
})
.map(({ lastMid, uid, unreads }) => {
return (
<NavItem key={uid} uid={uid} mid={lastMid} unreads={unreads} setFiles={setDropFiles} />
);
})}
</>
);
};
export default DMList;
@@ -6,6 +6,7 @@ import IconSurprise from "../../assets/icons/emoji.suprise.svg";
// import IconForward from "../../../assets/icons/forward.svg";
import IconRemove from "../../assets/icons/close.svg";
import useFavMessage from "../../common/hook/useFavMessage";
const Styled = styled.div`
padding: 16px;
background: #f9fafb;
@@ -83,6 +84,7 @@ const Styled = styled.div`
}
}
`;
export default function FavList({ cid = null, uid = null }) {
const { favorites, removeFavorite } = useFavMessage({ cid, uid });
const handleRemove = (evt) => {
@@ -1,7 +1,7 @@
import { useState } from "react";
import styled from "styled-components";
import { useDispatch, useSelector } from "react-redux";
import { useKey } from "rooks";
import toast from "react-hot-toast";
import useDeleteMessage from "../../../common/hook/useDeleteMessage";
import useFavMessage from "../../../common/hook/useFavMessage";
import { updateSelectMessages } from "../../../app/slices/ui";
@@ -10,8 +10,9 @@ import IconBookmark from "../../../assets/icons/bookmark.svg";
import IconDelete from "../../../assets/icons/delete.svg";
import IconClose from "../../../assets/icons/close.circle.svg";
import ForwardModal from "../../../common/component/ForwardModal";
import toast from "react-hot-toast";
import DeleteMessageConfirmModal from "../../../common/component/DeleteMessageConfirm";
import { useAppDispatch, useAppSelector } from "../../../app/store";
const Styled = styled.div`
position: relative;
padding: 16px;
@@ -40,16 +41,19 @@ const Styled = styled.div`
transform: translateY(-50%);
}
`;
export default function Operations({ context, id }) {
const [deleteModalVisible, setDeleteModalVisible] = useState(false);
const { canDelete } = useDeleteMessage();
const { addFavorite } = useFavMessage({});
const mids = useSelector((store) => store.ui.selectMessages[`${context}_${id}`]);
const mids = useAppSelector((store) => store.ui.selectMessages[`${context}_${id}`]);
const [forwardModalVisible, setForwardModalVisible] = useState(false);
const dispatch = useDispatch();
const dispatch = useAppDispatch();
const handleClose = () => {
dispatch(updateSelectMessages({ context, id, operation: "reset" }));
};
const handleFav = async () => {
const added = await addFavorite(mids);
if (added) {
@@ -60,6 +64,7 @@ export default function Operations({ context, id }) {
toast.error("Operation Failed!");
}
};
const toggleDeleteModal = (isSuccess = false) => {
setDeleteModalVisible((prev) => !prev);
if (isSuccess) {
@@ -67,14 +72,17 @@ export default function Operations({ context, id }) {
toast.success("Messages Deleted!");
}
};
const toggleForwardModal = () => {
setForwardModalVisible((prev) => !prev);
};
useKey("Escape", (evt) => {
console.log("Escape keypress", evt);
dispatch(updateSelectMessages({ context, id, operation: "reset" }));
});
const canDel = canDelete(mids);
return (
<>
<Styled>
@@ -1,7 +1,5 @@
import { useState, useRef, useEffect } from "react";
import { useState, useRef, useEffect, FC, ReactElement } from "react";
import { useDrop } from "react-dnd";
import { useSelector } from "react-redux";
import { NativeTypes } from "react-dnd-html5-backend";
import ImagePreviewModal from "../../../common/component/ImagePreviewModal";
import Send from "../../../common/component/Send";
@@ -9,8 +7,19 @@ import Styled from "./styled";
import Operations from "./Operations";
import useUploadFile from "../../../common/hook/useUploadFile";
import { ChatPrefixs } from "../../../app/config";
import { useAppSelector } from "../../../app/store";
export default function Layout({
interface Props {
children: ReactElement;
header: ReactElement;
aside: ReactElement | null;
contacts: ReactElement | null;
dropFiles: [];
context: string;
to: number | null;
}
const Layout: FC<Props> = ({
children,
header,
aside = null,
@@ -18,11 +27,11 @@ export default function Layout({
dropFiles = [],
context = "channel",
to = null
}) {
}) => {
const { addStageFile } = useUploadFile({ context, id: to });
const messagesContainer = useRef(undefined);
const messagesContainer = useRef<HTMLDivElement>(null);
const [previewImage, setPreviewImage] = useState(null);
const { selects, channelsData, contactsData } = useSelector((store) => {
const { selects, channelsData, contactsData } = useAppSelector((store) => {
return {
selects: store.ui.selectMessages[`${context}_${to}`],
channelsData: store.channels.byId,
@@ -49,6 +58,7 @@ export default function Layout({
}),
[context, to]
);
useEffect(() => {
if (dropFiles?.length) {
const filesData = dropFiles.map((file) => {
@@ -63,6 +73,7 @@ export default function Layout({
const closePreviewModal = () => {
setPreviewImage(null);
};
useEffect(() => {
const container = messagesContainer?.current;
if (container) {
@@ -85,6 +96,7 @@ export default function Layout({
}
}, []);
const name = context == "channel" ? channelsData[to]?.name : contactsData[to]?.name;
return (
<>
{previewImage && <ImagePreviewModal data={previewImage} closeModal={closePreviewModal} />}
@@ -112,4 +124,6 @@ export default function Layout({
</Styled>
</>
);
}
};
export default Layout;
@@ -1,4 +1,3 @@
// import React from 'react'
import Tippy from "@tippyjs/react";
import { useDispatch, useSelector } from "react-redux";
import { useNavigate, useLocation, useMatch } from "react-router-dom";
@@ -30,9 +29,11 @@ export default function SessionContextMenu({
channelMuted: context == "channel" ? store.footprint.muteChannels[id] : false
};
});
const handleChannelSetting = () => {
navigateTo(`/setting/channel/${id}?f=${pathname}`);
};
const handleReadAll = () => {
// console.log("last mid", mids, lastMid);
if (mid) {
@@ -41,16 +42,19 @@ export default function SessionContextMenu({
updateReadIndex(param);
}
};
const handleRemoveSession = () => {
dispatch(removeUserSession(id));
if (pathMatched) {
navigateTo("/chat");
}
};
const handleChannelMute = () => {
const data = channelMuted ? { remove_groups: [id] } : { add_groups: [{ gid: id }] };
muteChannel(data);
};
const items =
context == "user"
? [
@@ -13,7 +13,10 @@ import IconLock from "../../../assets/icons/lock.svg";
import useContextMenu from "../../../common/hook/useContextMenu";
import { useNavigate, NavLink } from "react-router-dom";
import useUploadFile from "../../../common/hook/useUploadFile";
// todo: move to root file
dayjs.extend(relativeTime);
export default function Session({
type = "user",
id,
@@ -23,6 +26,7 @@ export default function Session({
}) {
const navigate = useNavigate();
const { addStageFile } = useUploadFile({ context: type, id });
const [{ isActive }, drop] = useDrop(
() => ({
accept: [NativeTypes.FILE],
@@ -44,6 +48,7 @@ export default function Session({
}),
[type, id]
);
const { visible: contextMenuVisible, handleContextMenuEvent, hideContextMenu } = useContextMenu();
const [data, setData] = useState(null);
const { messageData, contactData, channelData, readIndex, loginUid, mids, muted } = useSelector(
@@ -60,10 +65,12 @@ export default function Session({
};
}
);
const handleImageError = (evt) => {
evt.target.classList.add("channel_default");
evt.target.src = iconChannel;
};
useEffect(() => {
const tmp = type == "user" ? contactData[id] : channelData[id];
if (!tmp) return;
@@ -81,6 +88,7 @@ export default function Session({
messageData,
loginUid
});
return (
<li className="session">
<ContextMenu
@@ -1,15 +1,16 @@
import { useState, useEffect } from "react";
import { useSelector } from "react-redux";
import Styled from "./styled";
import Session from "./Session";
import DeleteChannelConfirmModal from "../../settingChannel/DeleteConfirmModal";
import InviteModal from "../../../common/component/InviteModal";
import { useAppSelector } from "../../../app/store";
export default function SessionList({ tempSession = null }) {
const [deleteId, setDeleteId] = useState(null);
const [inviteChannelId, setInviteChannelId] = useState(null);
const [sessions, setSessions] = useState([]);
const { channelIDs, DMs, readChannels, readUsers, channelMessage, userMessage, loginUid } =
useSelector((store) => {
useAppSelector((store) => {
return {
loginUid: store.authData.uid,
channelIDs: store.channels.ids,
@@ -20,6 +21,7 @@ export default function SessionList({ tempSession = null }) {
readUsers: store.footprint.readUsers
};
});
useEffect(() => {
const cSessions = channelIDs.map((id) => {
const mids = channelMessage[id];
@@ -51,6 +53,7 @@ export default function SessionList({ tempSession = null }) {
userMessage,
tempSession
]);
return (
<>
<Styled>
@@ -1,14 +1,14 @@
import { useState } from "react";
import { useSelector } from "react-redux";
// import { useUpdateChannelMutation } from "../../app/services/channel";
import { useUpdateMuteSettingMutation } from "../../app/services/contact";
import { useReadMessageMutation } from "../../app/services/message";
import { useAppSelector } from "../../app/store";
export default function useSession({ type, id }) {
const [inviteModalVisible, setInviteModalVisible] = useState(false);
const [muteChannel] = useUpdateMuteSettingMutation();
const [updateReadIndex] = useReadMessageMutation();
const { messageData, contactData, channelData } = useSelector((store) => {
const { messageData, contactData, channelData } = useAppSelector((store) => {
return {
messageData: store.message,
contactData: store.contacts.byId,
@@ -1,6 +1,7 @@
import React from "react";
import dayjs from "dayjs";
import styled from "styled-components";
import reactStringReplace from "react-string-replace";
import { useDispatch, useSelector } from "react-redux";
import { isImage } from "../../common/utils";
import { ContentTypes } from "../../app/config";
@@ -9,7 +10,7 @@ import Divider from "../../common/component/Divider";
import Message from "../../common/component/Message";
import { updateSelectMessages } from "../../app/slices/ui";
import Mention from "../../common/component/Message/Mention";
import reactStringReplace from "react-string-replace";
// function debounce(callback, wait = 2000, immediate = false) {
// let timeout = null;
// return function () {
@@ -22,6 +23,7 @@ import reactStringReplace from "react-string-replace";
// }
// };
// }
export function getUnreadCount({ mids = [], messageData = {}, loginUid = 0, readIndex = 0 }) {
// console.log({ mids, loginUid, readIndex });
// 先过滤掉空信息和from自己的
@@ -124,6 +126,7 @@ const StyledWrapper = styled.div`
}
}
`;
const MessageWrapper = ({ selectMode = false, context, id, mid, children, ...rest }) => {
const dispatch = useDispatch();
@@ -142,6 +145,7 @@ const MessageWrapper = ({ selectMode = false, context, id, mid, children, ...res
</StyledWrapper>
);
};
export const renderMessageFragment = ({
selectMode = false,
isFirst = false,