refactor: add more TS constraints

This commit is contained in:
Tristan Yang
2022-07-04 18:15:24 +08:00
parent 8330e45674
commit ff7fe05b58
18 changed files with 48 additions and 202 deletions
+2
View File
@@ -2,6 +2,8 @@ import { useState, useEffect, memo, SyntheticEvent, FC } from "react";
import { getInitials, getInitialsAvatar } from "../utils";
interface Props {
className?: string;
alt?: string;
url?: string;
name?: string;
type?: "user" | "channel";
-1
View File
@@ -15,7 +15,6 @@ const StyledWrapper = styled.div`
height: 100%;
border-radius: 50%;
background-color: #eee;
/* border: 1px solid #eee; */
img {
object-fit: cover;
width: 100%;
+2 -2
View File
@@ -63,14 +63,14 @@ const Channel: FC<Props> = ({ interactive = true, id, compact = false, avatarSiz
});
if (!channel) return null;
const { name, members = [], is_public, avatar } = channel;
const { name, members = [], is_public, icon } = channel;
return (
<StyledWrapper
size={avatarSize}
className={`${interactive ? "interactive" : ""} ${compact ? "compact" : ""}`}
>
<div className="avatar">
<Avatar type="channel" url={avatar} name={"#"} alt="avatar" />
<Avatar type="channel" url={icon} name={"#"} alt="avatar" />
</div>
{!compact && (
<div className="name">
-2
View File
@@ -70,7 +70,6 @@ export default function CurrentUser() {
if (!currUser) return null;
const { uid, name, avatar } = currUser;
return (
// <UserGuide step={1}>
<StyledWrapper>
<div className="profile">
<Avatar url={avatar} name={name} alt="user avatar" className="avatar" />
@@ -86,6 +85,5 @@ export default function CurrentUser() {
</div>
)}
</StyledWrapper>
// </UserGuide>
);
}
@@ -23,7 +23,6 @@ const DeleteMessageConfirmModal: FC<Props> = ({ closeModal, mids = [] }) => {
return (
<Modal>
<StyledModal
// className="animate__animated animate__fadeInDown animate__faster"
buttons={
<>
<Button className="cancel" onClick={closeModal.bind(null, false)}>
@@ -18,7 +18,6 @@ const StyledWrapper = styled.div`
transition: all 0.5s ease;
width: 100vw;
height: 100vh;
/* background-color: rgba(1, 1, 1, 0.9); */
animation: ${AniFadeIn} 0.3s ease-in-out forwards;
display: flex;
align-items: center;
@@ -45,9 +44,6 @@ const StyledWrapper = styled.div`
img {
max-width: 70vw;
max-height: 80vh;
/* width: 100%;
height: 100%;
object-fit: contain; */
}
}
@@ -121,7 +117,6 @@ const ImagePreviewModal: FC<Props> = ({ download = true, data, closeModal }) =>
<div className={`box ${loading ? "loading" : ""}`} ref={wrapperRef}>
<div className="image">
<img
// onLoadedMetadata={handleMetaDataLoaded}
src={url}
alt="preview"
className={`animate__animated animate__fadeIn animate__faster`}
+1 -1
View File
@@ -140,7 +140,7 @@ const ManageMembers: FC<Props> = ({ cid }) => {
if (ignore) return;
updateUser({ id: uid, is_admin: isAdmin });
};
const channel = channels.byId[cid] ?? null;
const channel = cid ? channels.byId[cid] : null;
const uids = channel ? (channel.is_public ? users.ids : channel.members) : users.ids;
return (
+11 -4
View File
@@ -1,19 +1,26 @@
import { useState, useEffect } from "react";
import React, { useState, useEffect } from "react";
import { formatBytes, isTreatAsImage, getFileIcon } from "../../utils";
export default function FileItem({ file = null }) {
const [icon, setIcon] = useState(null);
const [icon, setIcon] = useState<React.ReactElement | null>(null);
useEffect(() => {
let localUrl = "";
if (file) {
const { type, name } = file;
if (isTreatAsImage(file)) {
// todo: memory leak, use revokeObjectURL before component didMount
setIcon(<img src={URL.createObjectURL(file)} alt="thumb" className="thumb" />);
// use revokeObjectURL before component didMount
localUrl = URL.createObjectURL(file);
setIcon(<img src={localUrl} alt="thumb" className="thumb" />);
return;
}
console.log("file type", type, name);
setIcon(getFileIcon(type, name));
}
return () => {
if (localUrl) {
URL.revokeObjectURL(localUrl);
}
};
}, [file]);
console.log("current file", file);
if (!file) return null;
-2
View File
@@ -8,7 +8,6 @@ const StyledWrapper = styled.div`
padding: 8px;
border-radius: 8px;
user-select: none;
&.interactive {
&:hover,
&.active {
@@ -47,7 +46,6 @@ const StyledWrapper = styled.div`
}
}
.name {
/* user-select: text; */
font-weight: 600;
font-size: 14px;
line-height: 20px;
-116
View File
@@ -1,116 +0,0 @@
import { FC, ReactElement } from "react";
import styled, { createGlobalStyle } from "styled-components";
import Tippy from "@tippyjs/react";
import { Placement, roundArrow } from "tippy.js";
import "tippy.js/dist/svg-arrow.css";
import { updateUserGuide } from "../../../app/slices/ui";
import steps from "./steps";
import { useAppDispatch } from "../../../app/store";
const Styled = styled.div`
display: flex;
flex-direction: column;
padding: 24px;
background: #06aed4;
border-radius: var(--br);
box-shadow: 0 12px 16px -4px rgba(16, 24, 40, 0.08), 0px 4px 6px -2px rgba(16, 24, 40, 0.03);
color: #ffffff;
min-width: 362px;
.title {
font-weight: 700;
font-size: 20px;
line-height: 30px;
margin-bottom: 4px;
}
.desc {
font-weight: 400;
font-size: 14px;
line-height: 20px;
margin-bottom: 24px;
}
.btns {
display: flex;
justify-content: space-between;
width: 100%;
align-items: center;
button {
cursor: pointer;
color: inherit;
font-weight: 500;
font-size: 14px;
line-height: 20px;
border: none;
background: none;
&.skip {
font-weight: 400;
}
&.next {
background: rgba(0, 0, 0, 0.16);
padding: 8px 14px;
border-radius: var(--br);
}
}
}
`;
const OverrideTippyArrowColor = createGlobalStyle`
.user-guide-tippy .tippy-svg-arrow svg path{
fill:#06aed4 ;
}
`;
interface Props {
step?: number;
placement: Placement;
delay?: number | [number | null, number | null];
children: ReactElement;
}
const UserGuide: FC<Props> = ({ step = 1, placement = "right-start", delay, children }) => {
const dispatch = useAppDispatch();
const currStep = steps[step - 1];
const isLastStep = steps.length == step;
// if (!visible) return children;
if (!currStep) return null;
const { title, description } = currStep;
const defaultDuration: [number, number] = [300, 250];
const handleSkip = () => {
// to do
dispatch(updateUserGuide({ visible: false }));
};
const handleNext = () => {
dispatch(updateUserGuide({ step: step + 1 }));
};
return (
<>
<OverrideTippyArrowColor />
<Tippy
interactive
className="user-guide-tippy"
arrow={roundArrow}
visible={true}
offset={[0, 18]}
duration={delay ? defaultDuration : 0}
delay={delay ?? [150, 0]}
placement={placement}
content={
<Styled>
<h4 className="title">{title}</h4>
<p className="desc">{description}</p>
<div className="btns">
<button className="skip" onClick={handleSkip}>
Skip
</button>
<button className="next" onClick={handleNext}>
{isLastStep ? `Done` : `Next Step`}
</button>
</div>
</Styled>
}
>
{children}
</Tippy>
</>
);
};
export default UserGuide;
-29
View File
@@ -1,29 +0,0 @@
interface Step {
title: string;
description: string;
}
const steps: Step[] = [
{
title: "Step 1",
description: "hello world 1"
},
{
title: "Step 2",
description: "hello world 1"
},
{
title: "Step 3",
description: "hello world 1"
},
{
title: "Step 4",
description: "hello world 1"
},
{
title: "Step 5",
description: "hello world 1"
}
];
export default steps;