refactor: add more TS constraints
This commit is contained in:
@@ -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";
|
||||
|
||||
@@ -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%;
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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`}
|
||||
|
||||
@@ -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 (
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
Reference in New Issue
Block a user