refactor: more TS code

This commit is contained in:
Tristan Yang
2022-07-25 23:14:27 +08:00
parent 17984a385e
commit 396a296c0b
21 changed files with 73 additions and 95 deletions
+2 -2
View File
@@ -1,9 +1,9 @@
import { FC, MouseEvent } from "react";
import { FC, MouseEvent, ReactElement } from "react";
import StyledMenu from "./styled/Menu";
export interface Item {
title: string;
icon?: string;
icon?: string | ReactElement;
handler: (e: MouseEvent) => void;
underline?: boolean;
danger?: boolean;
@@ -97,12 +97,12 @@ interface Props {
closeModal: () => void;
}
const AddMembers: FC<Props> = ({ cid, closeModal }) => {
const AddMembers: FC<Props> = ({ cid = 0, closeModal }) => {
const [addMembers, { isLoading: isAdding, isSuccess }] = useAddMembersMutation();
const [selects, setSelects] = useState<number[]>([]);
const { channel, userData } = useAppSelector((store) => {
return {
channel: cid ? store.channels.byId[cid] : null,
channel: store.channels.byId[cid],
userData: store.users.byId
};
});
@@ -29,8 +29,6 @@ const Styled = styled.div`
}
`;
// type: server,channel
interface Props {
type?: "server" | "channel";
cid?: number;
+12 -5
View File
@@ -1,4 +1,4 @@
import { useRef, useEffect } from "react";
import { useRef, useEffect, FC } from "react";
import "@toast-ui/editor/dist/toastui-editor.css";
import { Editor } from "@toast-ui/react-editor";
import "prismjs/themes/prism.css";
@@ -9,15 +9,22 @@ import StyledWrapper from "./styled";
import useUploadFile from "../../hook/useUploadFile";
import Button from "../styled/Button";
function MarkdownEditor({
type Props = {
updateDraft?: (draft: string) => void;
initialValue: string;
height: string;
placeholder: string;
sendMarkdown: (md: string) => void;
setEditorInstance: () => void;
};
const MarkdownEditor: FC<Props> = ({
updateDraft = null,
initialValue = "",
height = "50vh",
placeholder,
sendMarkdown,
setEditorInstance
}) {
}) => {
const editorRef = useRef<Editor | undefined>(undefined);
const { uploadFile } = useUploadFile();
// const [pHolder, setPHolder] = useState(placeholder);
@@ -73,5 +80,5 @@ function MarkdownEditor({
</Button>
</StyledWrapper>
);
}
};
export default MarkdownEditor;
+13 -9
View File
@@ -1,4 +1,4 @@
import { useState, useRef } from "react";
import { useState, useRef, FC } from "react";
import { useDispatch } from "react-redux";
import styled from "styled-components";
import Tippy from "@tippyjs/react";
@@ -61,8 +61,13 @@ const StyledCmds = styled.ul`
transform: translateX(-100%);
}
`;
export default function Commands({ context = "user", contextId = 0, mid = 0, toggleEditMessage }) {
type Props = {
context: "user" | "channel";
contextId: number;
mid: number;
toggleEditMessage: () => void;
};
const Commands: FC<Props> = ({ context = "user", contextId = 0, mid = 0, toggleEditMessage }) => {
const {
canDelete,
canReply,
@@ -84,19 +89,17 @@ export default function Commands({ context = "user", contextId = 0, mid = 0, tog
const dispatch = useDispatch();
const [tippyVisible, setTippyVisible] = useState(false);
const cmdsRef = useRef(null);
const handleReply = (fromMenu) => {
const handleReply = () => {
if (contextId) {
setReplying(mid);
}
if (fromMenu) {
hideAll();
}
hideAll();
};
const handleTippyVisible = (visible = true) => {
setTippyVisible(visible);
};
const handleSelect = (mid) => {
const handleSelect = (mid: number) => {
dispatch(updateSelectMessages({ context, id: contextId, data: mid }));
hideAll();
};
@@ -202,4 +205,5 @@ export default function Commands({ context = "user", contextId = 0, mid = 0, tog
{DeleteModal}
</>
);
}
};
export default Commands;
-7
View File
@@ -8,11 +8,6 @@ const StyledMsg = styled.div`
padding: 4px 8px;
margin: 8px 0;
border-radius: 8px;
/* content-visibility: auto;
contain-intrinsic-size: auto 150px; */
/* &.in_view {
content-visibility: visible;
} */
&[data-highlight="true"] {
background: #f5f6f7;
}
@@ -22,8 +17,6 @@ const StyledMsg = styled.div`
&:hover,
&.contextVisible,
&.preview {
/* content-visibility: inherit;
contain-intrinsic-size: inherit; */
background: #f5f6f7;
.cmds {
visibility: visible;
+4 -5
View File
@@ -4,6 +4,7 @@ import { useOutsideClick } from "rooks";
import Tooltip from "../Tooltip";
import Picker from "../EmojiPicker";
import SmileIcon from "../../../assets/icons/emoji.smile.svg";
import { BaseEmoji, EmojiData } from "emoji-mart";
const Styled = styled.div`
position: relative;
@@ -29,7 +30,7 @@ const Styled = styled.div`
}
`;
export default function EmojiPicker({ selectEmoji }) {
export default function EmojiPicker({ selectEmoji }: { selectEmoji: (e: string) => void }) {
const ref = useRef<HTMLDivElement>(null);
const [visible, setVisible] = useState(false);
@@ -37,9 +38,9 @@ export default function EmojiPicker({ selectEmoji }) {
setVisible((prev) => !prev);
};
const handleSelect = (emoji) => {
const handleSelect = (emoji: EmojiData) => {
console.log("semojii", emoji);
selectEmoji(emoji.native);
selectEmoji((emoji as BaseEmoji).native);
};
useOutsideClick(
@@ -49,9 +50,7 @@ export default function EmojiPicker({ selectEmoji }) {
const ignore =
(clickEle.nodeName == "svg" && clickEle.dataset.emoji == "toggler") ||
(clickEle.nodeName == "path" && clickEle.parentElement.dataset.emoji == "toggler");
// console.log("outside click", clickEle, clickEle.parentElement, ignore);
if (ignore) return;
// if(clickEle)
setVisible(false);
},
visible
+1 -1
View File
@@ -64,7 +64,7 @@ const Send: FC<IProps> = ({
}
}, [replying_mid]);
const insertEmoji = (emoji) => {
const insertEmoji = (emoji: string) => {
if (mode == Modes.markdown && markdownEditor) {
// markdown insert emoji
markdownEditor.insertText(emoji);
+1 -1
View File
@@ -12,7 +12,7 @@ import { useAppSelector } from "../../../app/store";
interface Props {
uid: number;
cid?: number;
owner?: number;
owner?: boolean;
dm?: boolean;
interactive?: boolean;
popover?: boolean;
+7 -1
View File
@@ -2,7 +2,13 @@ import { useState, useEffect } from "react";
import { useLazyRemoveFavoriteQuery, useFavoriteMessageMutation } from "../../app/services/message";
import { useAppSelector } from "../../app/store";
export default function useFavMessage({ cid = null, uid = null }) {
export default function useFavMessage({
cid = null,
uid = null
}: {
cid?: number | null;
uid?: number | null;
}) {
const [removeFav] = useLazyRemoveFavoriteQuery();
const [addFav] = useFavoriteMessageMutation();
const [favorites, setFavorites] = useState([]);
+2 -2
View File
@@ -7,7 +7,7 @@ import { useAppDispatch, useAppSelector } from "../../app/store";
interface Props {
context: "user" | "channel";
from: number;
from?: number;
to: number;
}
@@ -25,7 +25,7 @@ interface SendMessageDTO {
}
const useSendMessage = (props?: Props) => {
const { context = "user", from, to = null } = props || {};
const { context = "user", from = 0, to = null } = props || {};
const dispatch = useAppDispatch();
const stageFiles = useAppSelector((store) => store.ui.uploadFiles[`${context}_${to}`] || []);
const [replyMessage, { isError: replyErr, isLoading: replying, isSuccess: replySuccess }] =
+3 -3
View File
@@ -4,13 +4,14 @@ import { updateUploadFiles } from "../../app/slices/ui";
import BASE_URL, { FILE_SLICE_SIZE } from "../../app/config";
import { usePrepareUploadFileMutation, useUploadFileMutation } from "../../app/services/message";
import { useAppDispatch, useAppSelector } from "../../app/store";
import { Message } from "../../types/channel";
// todo: check props type
interface IProps {
context: "channel" | "user";
id: number;
}
const useUploadFile = (props: IProps) => {
const useUploadFile = (props?: IProps) => {
const { context, id } = props ? props : { context: "channel", id: 0 };
const dispatch = useAppDispatch();
const { stageFiles, replying } = useAppSelector((store) => {
@@ -19,8 +20,7 @@ const useUploadFile = (props: IProps) => {
replying: store.message.replying[`${context}_${id}`]
};
});
const [data, setData] = useState(null);
// const [uploadingFile, setUploadingFile] = useState(false);
const [data, setData] = useState<Message | null>(null);
const canceledRef = useRef(false);
const sliceUploadedCountRef = useRef(0);
const totalSliceCountRef = useRef(1);
+2 -1
View File
@@ -8,6 +8,7 @@ import { useLazyDeleteUserQuery } from "../../app/services/user";
import useConfig from "./useConfig";
import useCopy from "./useCopy";
import { useAppSelector } from "../../app/store";
import { AgoraConfig } from "../../types/server";
interface IProps {
uid?: number;
cid?: number;
@@ -79,7 +80,7 @@ const useUserOperation = ({ uid, cid }: IProps) => {
const canDeleteChannel = cid && !channel?.is_public && isAdmin;
const canRemoveFromChannel =
cid && !channel?.is_public && (isAdmin || channel?.owner == loginUid) && uid != channel?.owner;
const canCall: boolean = agoraConfig.enabled && loginUid != uid;
const canCall: boolean = (agoraConfig as AgoraConfig)?.enabled && loginUid != uid;
const canRemove: boolean = isAdmin && loginUid != uid && !cid;
return {
+2 -8
View File
@@ -9,7 +9,8 @@ const Styled = styled.div`
background: #f9fafb;
filter: drop-shadow(0px 25px 50px rgba(31, 41, 55, 0.25));
border-radius: 12px;
min-width: 406px;
min-width: 486px;
/* width: fit-content; */
> .head {
font-weight: 600;
font-size: 16px;
@@ -106,13 +107,6 @@ const PinList: FC<Props> = ({ id }: Props) => {
<li key={mid} className="pin">
<PreviewMessage mid={mid} />
<div className="opts">
{/* <button
className="btn"
data-mid={mid}
// onClick={handleUnpin}
>
<IconForward />
</button> */}
{canPin && (
<button className="btn" data-mid={mid} onClick={handleUnpin}>
<IconClose />
+9 -29
View File
@@ -27,6 +27,7 @@ import { StyledUsers, StyledChannelChat, StyledHeader } from "./styled";
import InviteModal from "../../../common/component/InviteModal";
import LoadMore from "../LoadMore";
import { useAppSelector } from "../../../app/store";
import { AgoraConfig } from "../../../types/server";
type Props = {
cid?: number;
dropFiles?: File[];
@@ -42,7 +43,6 @@ export default function ChannelChat({ cid = 0, dropFiles = [] }: Props) {
context: "channel",
id: cid
});
const [toolVisible, setToolVisible] = useState("");
const { pathname } = useLocation();
const dispatch = useDispatch();
const [updateReadIndex] = useReadMessageMutation();
@@ -99,57 +99,37 @@ export default function ChannelChat({ cid = 0, dropFiles = [] }: Props) {
aside={
<>
<ul className="tools">
{agoraConfig.enabled && (
{(agoraConfig as AgoraConfig)?.enabled && (
<li className="tool">
<Tooltip tip="Voice/Video Chat" placement="left">
<IconHeadphone />
</Tooltip>
</li>
)}
<Tooltip tip="Pin" placement="left" disabled={toolVisible == "pin"}>
<Tooltip tip="Pin" placement="left">
<Tippy
onShow={() => {
setToolVisible("pin");
}}
onHide={() => {
setToolVisible("");
}}
placement="left-start"
popperOptions={{ strategy: "fixed" }}
offset={[0, 80]}
offset={[0, 150]}
interactive
trigger="click"
content={<PinList id={cid} />}
>
<li
className={`tool ${pinCount > 0 ? "badge" : ""} ${
toolVisible == "pin" ? "active" : ""
} `}
data-count={pinCount}
>
<li className={`tool ${pinCount > 0 ? "badge" : ""}`} data-count={pinCount}>
<IconPin />
</li>
</Tippy>
</Tooltip>
<Tooltip tip="Favorite" placement="left" disabled={toolVisible == "favorite"}>
<Tooltip tip="Favorite" placement="left">
<Tippy
onShow={() => {
setToolVisible("favorite");
}}
onHide={() => {
setToolVisible("");
}}
placement="left-start"
popperOptions={{ strategy: "fixed" }}
offset={[0, 180]}
offset={[0, 162]}
interactive
trigger="click"
content={<FavList cid={cid} />}
>
<li
className={`tool fav ${toolVisible == "favorite" ? "active" : ""} `}
data-count={pinCount}
>
<li className={`tool fav`} data-count={pinCount}>
<IconFav />
</li>
</Tippy>
@@ -184,7 +164,7 @@ export default function ChannelChat({ cid = 0, dropFiles = [] }: Props) {
<div className="txt">Add members</div>
</div>
)}
{memberIds.map((uid) => {
{memberIds.map((uid: number) => {
return (
<User
enableContextMenu={true}
+1 -1
View File
@@ -17,7 +17,7 @@ import useMessageFeed from "../../../common/hook/useMessageFeed";
import { useAppSelector } from "../../../app/store";
type Props = {
uid: number;
dropFiles: [File];
dropFiles?: [File];
};
const DMChat: FC<Props> = ({ uid = 0, dropFiles }) => {
const {
+5 -11
View File
@@ -1,4 +1,4 @@
import { MouseEvent } from "react";
import { MouseEvent, FC } from "react";
import styled from "styled-components";
import FavoredMessage from "../../common/component/Message/FavoredMessage";
import IconSurprise from "../../assets/icons/emoji.surprise.svg";
@@ -82,8 +82,8 @@ const Styled = styled.div`
}
}
`;
export default function FavList({ cid = null, uid = null }) {
type Props = { cid?: number; uid?: number };
const FavList: FC<Props> = ({ cid = null, uid = null }) => {
const { favorites, removeFavorite } = useFavMessage({ cid, uid });
const handleRemove = (evt: MouseEvent<HTMLButtonElement>) => {
const { id } = evt.currentTarget.dataset;
@@ -106,13 +106,6 @@ export default function FavList({ cid = null, uid = null }) {
<li key={id} className="fav">
<FavoredMessage id={id} />
<div className="opts">
{/* <button
className="btn"
data-mid={mid}
// onClick={handleRemove}
>
<IconForward />
</button> */}
<button className="btn" data-id={id} onClick={handleRemove}>
<IconRemove />
</button>
@@ -124,4 +117,5 @@ export default function FavList({ cid = null, uid = null }) {
)}
</Styled>
);
}
};
export default FavList;
+1 -1
View File
@@ -14,7 +14,7 @@ interface Props {
header: ReactElement;
aside: ReactElement | null;
users?: ReactElement;
dropFiles: File[];
dropFiles?: File[];
context: "channel" | "user";
to: number;
}
+2 -2
View File
@@ -15,7 +15,7 @@ import { useAppSelector } from "../../app/store";
export default function ChatPage() {
const [channelModalVisible, setChannelModalVisible] = useState(false);
const [usersModalVisible, setUsersModalVisible] = useState(false);
const { channel_id, user_id } = useParams();
const { channel_id = 0, user_id = 0 } = useParams();
const { sessionUids } = useAppSelector((store) => {
return {
sessionUids: store.userMessage.ids
@@ -47,7 +47,7 @@ export default function ChatPage() {
</div>
<div className={`right ${placeholderVisible ? "placeholder" : ""}`}>
{placeholderVisible && <BlankPlaceholder />}
{channel_id && <ChannelChat cid={channel_id} />}
{channel_id && <ChannelChat cid={+channel_id} />}
{user_id && <DMChat uid={+user_id} />}
</div>
</StyledWrapper>
+2 -1
View File
@@ -9,6 +9,7 @@ import Tooltip from "./Tooltip";
import IssuerList from "./IssuerList";
import useGoogleAuthConfig from "../../../common/hook/useGoogleAuthConfig";
import useGithubAuthConfig from "../../../common/hook/useGithubAuthConfig";
import { LoginConfig } from "../../../types/server";
export default function Logins() {
const {
@@ -25,7 +26,7 @@ export default function Logins() {
} = useGithubAuthConfig();
const { values, updateConfig, setValues, reset, changed } = useConfig("login");
const handleUpdate = async () => {
const { google } = values;
const { google } = values as LoginConfig;
if (changed) {
updateConfig(values);
}
+2 -1
View File
@@ -16,6 +16,7 @@ import Toggle from "../../../common/component/styled/Toggle";
import Label from "../../../common/component/styled/Label";
import SaveTip from "../../../common/component/SaveTip";
import toast from "react-hot-toast";
import { SMTPConfig } from "../../../types/server";
export default function ConfigSMTP() {
const [testEmail, setTestEmail] = useState("");
@@ -24,7 +25,7 @@ export default function ConfigSMTP() {
const handleUpdate = () => {
// const { token_url, description } = values;
updateConfig({ ...values, port: Number(values.port ?? 0) });
updateConfig({ ...values, port: Number((values as SMTPConfig)?.port ?? 0) });
};
const handleChange = (evt) => {
const newValue = evt.target.value;