From ffd68f2c0675110edf72f17ee24e2feae77c9085 Mon Sep 17 00:00:00 2001 From: Tristan Yang Date: Wed, 8 Feb 2023 15:03:30 +0800 Subject: [PATCH] refactor: finished tailwind --- public/index.html | 1 - src/assets/icons/arrow.down.svg | 4 +- src/assets/icons/eye.close.svg | 1 + src/assets/icons/eye.open.svg | 1 + src/assets/icons/lock.svg | 4 +- src/assets/icons/pin.svg | 4 +- src/assets/icons/reply.svg | 2 +- src/assets/index.css | 62 +++++- .../component/FileMessage/ImageMessage.tsx | 20 +- .../component/MarkdownStyleOverride.tsx | 128 ------------ src/common/component/Message/Commands.tsx | 2 +- .../component/Message/FavoredMessage.tsx | 17 +- .../component/Message/ForwardedMessage.tsx | 16 +- .../component/Message/PreviewMessage.tsx | 19 +- src/common/component/Message/Reply.tsx | 10 +- src/common/component/Message/index.tsx | 30 +-- .../component/Message/renderContent.tsx | 2 +- src/common/component/Message/styled.tsx | 129 ------------ src/common/component/PinnedMessage.tsx | 17 +- src/common/component/Profile/index.tsx | 6 +- src/common/component/Send/Replying.tsx | 4 +- src/common/component/Send/index.tsx | 2 +- .../component/StyledSettingContainer.tsx | 4 +- src/common/component/User/index.tsx | 2 +- src/common/component/styled/Button.tsx | 2 +- src/common/component/styled/Input.tsx | 111 +++------- src/common/component/styled/Radio.tsx | 10 +- src/common/component/styled/Textarea.tsx | 4 +- src/index.tsx | 2 - src/routes/chat/ChannelChat/PinList.tsx | 25 +-- src/routes/chat/ChannelChat/index.tsx | 33 ++- src/routes/chat/ChannelList/NavItem.tsx | 196 ------------------ src/routes/chat/ChannelList/index.tsx | 33 --- src/routes/chat/ChannelList/styled.tsx | 86 -------- src/routes/chat/DMChat/index.tsx | 8 +- src/routes/chat/DMList/NavItem.tsx | 139 ------------- src/routes/chat/DMList/index.tsx | 59 ------ src/routes/chat/FavList.tsx | 31 +-- src/routes/chat/GuestBlankPlaceholder.tsx | 2 +- src/routes/chat/Layout/index.tsx | 16 +- src/routes/chat/Layout/styled.tsx | 90 -------- src/routes/chat/SessionList/Session.tsx | 8 +- src/routes/chat/index.tsx | 13 +- src/routes/chat/styled.tsx | 157 -------------- src/routes/favs/index.tsx | 6 +- src/routes/home/index.tsx | 16 +- src/routes/resources/Filter/Channel.tsx | 2 +- src/routes/resources/Filter/Date.tsx | 6 +- src/routes/resources/Filter/From.tsx | 2 +- src/routes/resources/Filter/Type.tsx | 6 +- src/routes/resources/Filter/index.tsx | 11 +- src/routes/resources/Search.tsx | 2 +- src/routes/resources/View.tsx | 6 +- src/routes/setting/MyAccount.tsx | 2 +- src/routes/users/Search.tsx | 2 +- 55 files changed, 260 insertions(+), 1313 deletions(-) create mode 100644 src/assets/icons/eye.close.svg create mode 100644 src/assets/icons/eye.open.svg delete mode 100644 src/common/component/MarkdownStyleOverride.tsx delete mode 100644 src/common/component/Message/styled.tsx delete mode 100644 src/routes/chat/ChannelList/NavItem.tsx delete mode 100644 src/routes/chat/ChannelList/index.tsx delete mode 100644 src/routes/chat/ChannelList/styled.tsx delete mode 100644 src/routes/chat/DMList/NavItem.tsx delete mode 100644 src/routes/chat/DMList/index.tsx delete mode 100644 src/routes/chat/Layout/styled.tsx delete mode 100644 src/routes/chat/styled.tsx diff --git a/public/index.html b/public/index.html index 7977ba1c..e68bdee1 100644 --- a/public/index.html +++ b/public/index.html @@ -121,7 +121,6 @@ padding: 0; margin: 0; box-sizing: border-box; - /* user-select: none; */ } body { overflow: hidden; diff --git a/src/assets/icons/arrow.down.svg b/src/assets/icons/arrow.down.svg index 3d50acd0..cd8c453f 100644 --- a/src/assets/icons/arrow.down.svg +++ b/src/assets/icons/arrow.down.svg @@ -1,3 +1,3 @@ - - + + diff --git a/src/assets/icons/eye.close.svg b/src/assets/icons/eye.close.svg new file mode 100644 index 00000000..e0978244 --- /dev/null +++ b/src/assets/icons/eye.close.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/eye.open.svg b/src/assets/icons/eye.open.svg new file mode 100644 index 00000000..484eff49 --- /dev/null +++ b/src/assets/icons/eye.open.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/lock.svg b/src/assets/icons/lock.svg index 099c5910..2331f2e7 100644 --- a/src/assets/icons/lock.svg +++ b/src/assets/icons/lock.svg @@ -1,3 +1,3 @@ - - + + diff --git a/src/assets/icons/pin.svg b/src/assets/icons/pin.svg index 1bb79fb6..91af4cc5 100644 --- a/src/assets/icons/pin.svg +++ b/src/assets/icons/pin.svg @@ -1,3 +1,3 @@ - - + + diff --git a/src/assets/icons/reply.svg b/src/assets/icons/reply.svg index b6fcfcd0..8f868966 100644 --- a/src/assets/icons/reply.svg +++ b/src/assets/icons/reply.svg @@ -1,3 +1,3 @@ - + diff --git a/src/assets/index.css b/src/assets/index.css index 3cf17a9b..c87d1456 100644 --- a/src/assets/index.css +++ b/src/assets/index.css @@ -229,10 +229,70 @@ html.dark ::-webkit-scrollbar-thumb { ---channel-text-color: #1c1c1e; ---msg-text-color: #374151; } -/* overrides */ +/* markdown overrides */ #MARKDOWN_CONTAINER .toastui-editor-contents { display: flex; flex-direction: column; align-items: flex-start; } +[class^="toastui-editor-"] .toastui-editor-md-container { + border-bottom: none; +} +[class^="toastui-editor-"] .toastui-editor-md-container .toastui-editor-md-preview { + padding-right: 0; + padding-left: 8px; +} +[class^="toastui-editor-"] .toastui-editor-md-container .toastui-editor-md-splitter { + background-color: #d0d5dd; +} +[class^="toastui-editor-"] .toastui-editor-md-container .ProseMirror { + height: 100%; +} +[class^="toastui-editor-"] .ProseMirror, +[class^="toastui-editor-"] p, +[class^="toastui-editor-"] .toastui-editor.md-mode { + font-weight: 400; + font-size: 14px; + line-height: 22px; + color: #475467; + margin: 0 0 16px; + word-break: break-all; +} +[class^="toastui-editor-"] a { + background-color: transparent; +} +[class^="toastui-editor-"] pre { + width: 100%; + width: -webkit-fill-available; +} +[class^="toastui-editor-"] img { + cursor: pointer; + max-width: 300px; + display: block; +} +[class^="toastui-editor-"] ul { + white-space: nowrap; + margin-top: 0; + margin-bottom: 10px; +} +[class^="toastui-editor-"] ul > li:before { + margin-top: 10px !important; + margin-left: -14px; + background-color: #475467; +} +[class^="toastui-editor-"] ol li { + display: flex; + flex-direction: column; +} +[class^="toastui-editor-"] li ol { + display: flex; + flex-direction: column; +} +[class^="toastui-editor-"] ul, +[class^="toastui-editor-"] ol { + font-weight: 400; + font-size: 14px; + line-height: 20px; + color: #475467; +} diff --git a/src/common/component/FileMessage/ImageMessage.tsx b/src/common/component/FileMessage/ImageMessage.tsx index 66209b0d..6ae52282 100644 --- a/src/common/component/FileMessage/ImageMessage.tsx +++ b/src/common/component/FileMessage/ImageMessage.tsx @@ -1,6 +1,6 @@ import { useState, useEffect, FC } from "react"; import { Ping } from '@uiball/loaders'; -import { getDefaultSize } from "../../utils"; +// import { getDefaultSize } from "../../utils"; type Props = { uploading: boolean; @@ -20,7 +20,7 @@ const ImageMessage: FC = ({ properties }) => { const [url, setUrl] = useState(thumbnail); - const { width = 0, height = 0 } = getDefaultSize(properties); + // const { width = 0, height = 0 } = getDefaultSize(properties); useEffect(() => { const newUrl = thumbnail; const img = new Image(); @@ -36,21 +36,21 @@ const ImageMessage: FC = ({ return (
{uploading && ( -
+
- {progress}% + {progress}%
)} p { - padding-right: 10px; - font-weight: 400; - font-size: 14px; - line-height: 20px; - margin-bottom: 0; - } - - > blockquote { - padding: 14px; - } - } - - img { - cursor: pointer; - max-width: 300px; - display: block; - } - - ul{ - white-space: nowrap; - margin-top: 0; - margin-bottom: 10px; - > li:before { - margin-top: 8px; - margin-left: -14px; - background-color: #475467; - } - } - ol li{ - display: flex; - flex-direction: column; - } - li ol{ - display: flex; - flex-direction: column; - } - ul, - ol { - font-weight: 400; - font-size: 14px; - line-height: 20px; - color: #475467; - } - - h1, - h2, - h3, [class*='heading'] { - margin-block-start: 0; - margin-block-end: 0; - padding: 0; - margin: 0; - border-bottom: none; - font-weight: 700; - color: #475467; - } - - h1, [class*='heading1'] { - margin-top: 0 !important; - font-size: 24px; - line-height: 32px; - } - - h2, [class*='heading2'] { - font-size: 20px; - line-height: 30px; - } - - h3, [class*='heading3'] { - font-size: 16px; - line-height: 24px; - } - } -`; - -export default MarkdownOverrides; diff --git a/src/common/component/Message/Commands.tsx b/src/common/component/Message/Commands.tsx index 73c8b1a6..05e35154 100644 --- a/src/common/component/Message/Commands.tsx +++ b/src/common/component/Message/Commands.tsx @@ -96,7 +96,7 @@ const Commands: FC = ({ context = "user", contextId = 0, mid = 0, toggleE <>
    + className={clsx(`bg-white dark:bg-gray-900 rounded-md z-[999] absolute right-2.5 top-0 -translate-y-1/2 flex items-center border border-solid border-black/10 invisible group-hover:visible`, tippyVisible && '!visible')}> = ({ id = "" }) => { const favorite_mids = messages.map(({ from_mid }) => +from_mid) || []; setMsgs( -
    +
    {messages.map((msg, idx) => { const { user = {}, download, content, content_type, properties, thumbnail } = msg; return ( - +
    {user && ( -
    +
    )} -
    -
    - {user?.name || "Deleted User"} +
    +
    + {user?.name || "Deleted User"}
    -
    +
    {renderContent({ download, content, @@ -43,7 +42,7 @@ const FavoredMessage: FC = ({ id = "" }) => { })}
    - +
    ); })}
    diff --git a/src/common/component/Message/ForwardedMessage.tsx b/src/common/component/Message/ForwardedMessage.tsx index b5f9f4d9..de92a922 100644 --- a/src/common/component/Message/ForwardedMessage.tsx +++ b/src/common/component/Message/ForwardedMessage.tsx @@ -26,7 +26,7 @@ const ForwardedMessage: FC = ({ context, to, from_uid, id }) => { const forward_mids = messages.map(({ from_mid }) => from_mid) || []; // console.log("fff", messages); setForwards( -
    +

    {t("action.forward")} @@ -35,17 +35,17 @@ const ForwardedMessage: FC = ({ context, to, from_uid, id }) => { {messages.map((msg, idx) => { const { user = {}, download, content, content_type, properties, thumbnail } = msg; return ( - +
    {user && ( -
    +
    )} -
    -
    - {user?.name || "Deleted User"} +
    +
    + {user?.name || "Deleted User"}
    -
    +
    {renderContent({ download, context, @@ -58,7 +58,7 @@ const ForwardedMessage: FC = ({ context, to, from_uid, id }) => { })}
    - +
    ); })}
    diff --git a/src/common/component/Message/PreviewMessage.tsx b/src/common/component/Message/PreviewMessage.tsx index 4c7ad8a1..6d1c461b 100644 --- a/src/common/component/Message/PreviewMessage.tsx +++ b/src/common/component/Message/PreviewMessage.tsx @@ -1,9 +1,7 @@ import { FC } from "react"; import clsx from "clsx"; -import dayjs from "dayjs"; import renderContent from "./renderContent"; import Avatar from "../Avatar"; -import StyledWrapper from "./styled"; import { useAppSelector } from "../../../app/store"; interface Props { @@ -16,20 +14,19 @@ const PreviewMessage: FC = ({ mid = 0, context }) => { return { msg: store.message[mid], usersData: store.users.byId }; }); if (!msg) return null; - const { from_uid = 0, created_at, content_type, content, thumbnail = "", properties } = msg; + const { from_uid = 0, content_type, content, thumbnail = "", properties } = msg; const { name, avatar } = usersData[from_uid] ?? {}; const pinMsg = context == "pin"; return ( - -
    +
    +
    -
    -
    - {name} - {dayjs(created_at).format("YYYY-MM-DD h:mm:ss A")} +
    +
    + {name}
    -
    +
    {renderContent({ content_type, content, @@ -39,7 +36,7 @@ const PreviewMessage: FC = ({ mid = 0, context }) => { })}
    - +
    ); }; diff --git a/src/common/component/Message/Reply.tsx b/src/common/component/Message/Reply.tsx index 145a754e..31a29e79 100644 --- a/src/common/component/Message/Reply.tsx +++ b/src/common/component/Message/Reply.tsx @@ -14,14 +14,14 @@ const renderContent = (data: MessagePayload) => { switch (content_type) { case ContentTypes.text: res = ( - + ); break; case ContentTypes.markdown: res = ( -
    +
    ); @@ -36,7 +36,7 @@ const renderContent = (data: MessagePayload) => { res = ( <> {icon} - {name} + {name} ); } @@ -77,7 +77,7 @@ const Reply: FC = ({ mid, interactive = true }) => {
    @@ -90,7 +90,7 @@ const Reply: FC = ({ mid, interactive = true }) => { /> {currUser.name}
    -
    {renderContent(data)}
    +
    {renderContent(data)}
    ); }; diff --git a/src/common/component/Message/index.tsx b/src/common/component/Message/index.tsx index 6831e826..b651de41 100644 --- a/src/common/component/Message/index.tsx +++ b/src/common/component/Message/index.tsx @@ -1,13 +1,13 @@ import React, { useRef, useState, useEffect, FC } from "react"; import dayjs from "dayjs"; +import Tippy from "@tippyjs/react"; +import clsx from "clsx"; import useInView from "./useInView"; -import Tippy from "@tippyjs/react"; import Reaction from "./Reaction"; import Reply from "./Reply"; import Profile from "../Profile"; import Avatar from "../Avatar"; -import StyledWrapper from "./styled"; import Commands from "./Commands"; import EditMessage from "./EditMessage"; import renderContent from "./renderContent"; @@ -91,13 +91,16 @@ const Message: FC = ({ const _key = properties?.local_id || mid; const showExpire = (expires_in ?? 0) > 0; return ( - = ({ trigger="click" content={} > -
    +
    @@ -121,26 +124,29 @@ const Message: FC = ({ hide={hideContextMenu} >
    -
    - {currUser?.name || "Deleted User"} + {pinInfo && + {`pinned by ${pinInfo.created_by ? usersData[pinInfo.created_by]?.name : ""}`} + } +
    + {currUser?.name || "Deleted User"} -
    -
    +
    {reply_mid && } {edit ? ( @@ -180,7 +186,7 @@ const Message: FC = ({ toggleEditMessage={toggleEditMessage} /> )} - +
    ); }; export default React.memo(Message, (prevs, nexts) => { diff --git a/src/common/component/Message/renderContent.tsx b/src/common/component/Message/renderContent.tsx index b83856f6..964275c6 100644 --- a/src/common/component/Message/renderContent.tsx +++ b/src/common/component/Message/renderContent.tsx @@ -39,7 +39,7 @@ const renderContent = ({ <> {edited && ( - + ({i18n.t("edited", { ns: "chat" })}) )} diff --git a/src/common/component/Message/styled.tsx b/src/common/component/Message/styled.tsx deleted file mode 100644 index 30e09e31..00000000 --- a/src/common/component/Message/styled.tsx +++ /dev/null @@ -1,129 +0,0 @@ -import styled from "styled-components"; - -const StyledMsg = styled.div` -width: 100%; - position: relative; - display: flex; - align-items: flex-start; - gap: 16px; - padding: 4px 8px; - margin: 8px 0; - border-radius: 8px; - &[data-highlight="true"] { - background: #f5f6f7; - } - &.auto_delete { - background: #f1d1ca50; - } - &.pinned { - background: #ecfdff; - } - &:hover, - &.contextVisible, - &.preview { - background: #f5f6f7; - .cmds { - visibility: visible; - } - } - &.readonly:hover { - background: none; - } - > .avatar { - flex-shrink: 0; - cursor: pointer; - width: 40px; - height: 40px; - img { - object-fit: cover; - width: 100%; - height: 100%; - border-radius: 50%; - } - } - > .details { - width: 100%; - display: flex; - flex-direction: column; - gap: 8px; - .up { - display: flex; - align-items: center; - gap: 8px; - font-weight: 500; - .name { - color: #06b6d4; - font-style: normal; - font-size: 14px; - line-height: 20px; - } - .time { - color: #bfbfbf; - font-size: 12px; - line-height: 18px; - } - } - .down { - user-select: text; - color: #374151; - font-weight: normal; - font-size: 14px; - line-height: 20px; - word-break: break-all; - white-space: pre-wrap; - .edited { - margin-left: 5px; - color: #999; - font-size: 10px; - } - &.sending { - opacity: 0.9; - } - > .link { - text-decoration: none; - border-radius: 2px; - /* background-color: #f5feff; */ - padding: 2px; - color: #1fe1f9; - } - /* 下载图标颜色 */ - .download_icon.gray{ - path{ - fill: #616161; - } - } - } - } - &.archive { - gap: 8px; - > .details { - gap: 0; - .up .name { - font-weight: 600; - color: #475467; - } - .down { - color: #475467; - } - } - } - &.pinned { - padding-top: 26px; - > .details { - position: relative; - &:before { - position: absolute; - left: 0; - top: -4px; - transform: translateY(-100%); - content: attr(data-pin-tip); - font-weight: 400; - font-size: 12px; - line-height: 18px; - color: #98a2b3; - } - } - } -`; - -export default StyledMsg; diff --git a/src/common/component/PinnedMessage.tsx b/src/common/component/PinnedMessage.tsx index 6cfd93a9..e6d2ae59 100644 --- a/src/common/component/PinnedMessage.tsx +++ b/src/common/component/PinnedMessage.tsx @@ -1,7 +1,6 @@ import dayjs from "dayjs"; import renderContent from "./Message/renderContent"; import Avatar from "./Avatar"; -import StyledWrapper from "./Message/styled"; import { useAppSelector } from "../../app/store"; import { FC } from "react"; import { PinnedMessage } from "../../types/channel"; @@ -23,16 +22,16 @@ const PinnedMessageView: FC = ({ data }) => { const { created_at, content_type, content, properties, thumbnail = "" } = { ...data, ...normalized }; const { name, avatar } = usersData[created_by] ?? {}; return ( - -
    +
    +
    -
    -
    - {name} - {dayjs(created_at).format("YYYY-MM-DD h:mm:ss A")} +
    +
    + {name} +
    -
    +
    {renderContent({ content_type, content, @@ -42,7 +41,7 @@ const PinnedMessageView: FC = ({ data }) => { })}
    - +
    ); }; diff --git a/src/common/component/Profile/index.tsx b/src/common/component/Profile/index.tsx index ebf4fbbb..308cf973 100644 --- a/src/common/component/Profile/index.tsx +++ b/src/common/component/Profile/index.tsx @@ -44,8 +44,8 @@ const Profile: FC = ({ uid, type = "embed", cid }) => { const isCard = type == 'card'; const canRemoveFromServer = !isCard && canRemove; const hasMore = email || canRemoveFromChannel || canRemoveFromServer; - const iconClass = `cursor-pointer flex flex-col items-center gap-1 rounded-lg w-32 text-primary-400 bg-slate-100 dark:bg-gray-700 text-sm pt-3.5 pb-3`; - const containerClass = clsx(`flex-center flex-col w-[432px] gap-1 z-[99] mt-20 select-none`, isCard && "p-4 w-[280px] bg-white dark:bg-gray-800 drop-shadow rounded-md"); + const iconClass = `cursor-pointer flex flex-col items-center gap-1 rounded-lg w-32 text-primary-400 bg-gray-100 dark:bg-gray-800 text-sm pt-3.5 pb-3`; + const containerClass = clsx(`flex-center flex-col gap-1 z-[99] mt-20 select-none`, isCard ? "p-4 w-[280px] bg-white dark:bg-gray-800 drop-shadow rounded-md" : "w-[432px]"); return (
    = ({ uid, type = "embed", cid }) => { {t("send_msg")} - {/* */} - {/* */} +
    - Replying to {user?.name} + Replying to {user?.name}
    {renderContent(msg)}
    )}
    @@ -52,7 +43,7 @@ const PinList: FC = ({ id }: Props) => { })}

)} - +
); }; export default PinList; diff --git a/src/routes/chat/ChannelChat/index.tsx b/src/routes/chat/ChannelChat/index.tsx index 2f530cd7..026aa07c 100644 --- a/src/routes/chat/ChannelChat/index.tsx +++ b/src/routes/chat/ChannelChat/index.tsx @@ -8,7 +8,6 @@ import FavList from "../FavList"; import { useReadMessageMutation } from "../../../app/services/message"; import { updateRememberedNavs } from "../../../app/slices/ui"; import useMessageFeed from "../../../common/hook/useMessageFeed"; -import useConfig from "../../../common/hook/useConfig"; import ChannelIcon from "../../../common/component/ChannelIcon"; import Tooltip from "../../../common/component/Tooltip"; import User from "../../../common/component/User"; @@ -18,13 +17,11 @@ import EditIcon from "../../../assets/icons/edit.svg"; import IconFav from "../../../assets/icons/bookmark.svg"; import IconPeople from "../../../assets/icons/people.svg"; import IconPin from "../../../assets/icons/pin.svg"; -import IconHeadphone from "../../../assets/icons/headphone.svg"; -import addIcon from "../../../assets/icons/add.svg?url"; +import IconAdd from "../../../assets/icons/add.svg"; import InviteModal from "../../../common/component/InviteModal"; import LoadMore from "../LoadMore"; import { useAppSelector } from "../../../app/store"; -import { AgoraConfig } from "../../../types/server"; import { useTranslation } from "react-i18next"; type Props = { cid?: number; @@ -32,7 +29,6 @@ type Props = { }; function ChannelChat({ cid = 0, dropFiles = [] }: Props) { const { t } = useTranslation("chat"); - const { values: agoraConfig } = useConfig("agora"); const { pulling, list: msgIds, @@ -86,6 +82,7 @@ function ChannelChat({ cid = 0, dropFiles = [] }: Props) { const readIndex = footprint.readChannels[cid]; const pinCount = data?.pinned_messages?.length || 0; const feeds = [...msgIds, ...appends]; + const toolClass = `relative cursor-pointer`; return ( <> {addMemberModalVisible && } @@ -94,14 +91,7 @@ function ChannelChat({ cid = 0, dropFiles = [] }: Props) { context="channel" dropFiles={dropFiles} aside={ -
    - {(agoraConfig as AgoraConfig)?.enabled && ( -
  • - - - -
  • - )} +
      } > -
    • 0 ? "badge" : ""}`} data-count={pinCount}> - +
    • + {pinCount > 0 ? {pinCount} : null} +
    • @@ -125,23 +116,23 @@ function ChannelChat({ cid = 0, dropFiles = [] }: Props) { trigger="click" content={} > -
    • - +
    • +
    • - +
    } header={ -
    +
    {name} @@ -153,7 +144,7 @@ function ChannelChat({ cid = 0, dropFiles = [] }: Props) {
    {addVisible && (
    - +
    {t("add_channel_members")}
    )} diff --git a/src/routes/chat/ChannelList/NavItem.tsx b/src/routes/chat/ChannelList/NavItem.tsx deleted file mode 100644 index 6a46676f..00000000 --- a/src/routes/chat/ChannelList/NavItem.tsx +++ /dev/null @@ -1,196 +0,0 @@ -import { useState, FC, MouseEvent } from "react"; -import { useLocation, useNavigate } from "react-router-dom"; -import { useDrop } from "react-dnd"; -import { NativeTypes } from "react-dnd-html5-backend"; -import Tippy from "@tippyjs/react"; -import useContextMenu from "../../../common/hook/useContextMenu"; -import ContextMenu from "../../../common/component/ContextMenu"; -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 { useReadMessageMutation } from "../../../app/services/message"; -import { useUpdateMuteSettingMutation } from "../../../app/services/user"; -import StyledLink from "./styled"; -import ChannelIcon from "../../../common/component/ChannelIcon"; -import { getUnreadCount } from "../utils"; -import { useAppSelector } from "../../../app/store"; -import { useTranslation } from "react-i18next"; -interface IProps { - id: number; - setFiles: (files: File[]) => void; - toggleRemoveConfirm: (id: number) => void; -} -const NavItem: FC = ({ id, setFiles, toggleRemoveConfirm }) => { - const { t } = useTranslation(); - const { pathname } = useLocation(); - const [inviteModalVisible, setInviteModalVisible] = useState(false); - const navigate = useNavigate(); - const [muteChannel] = useUpdateMuteSettingMutation(); - const [updateReadIndex] = useReadMessageMutation(); - - const { - visible: contextMenuVisible, - offset, - handleContextMenuEvent, - hideContextMenu - } = useContextMenu(); - const { - channel, - mids = [], - messageData, - readIndex, - muted, - loginUid = 0 - } = useAppSelector((store) => { - return { - channel: store.channels.byId[id], - mids: store.channelMessage[id], - messageData: store.message, - loginUid: store.authData.user?.uid, - readIndex: store.footprint.readChannels[id], - muted: store.footprint.muteChannels[id] - }; - }); - const handleChannelSetting = (evt: MouseEvent) => { - evt.preventDefault(); - evt.stopPropagation(); - const { id } = evt.currentTarget.dataset; - if (id) { - navigate(`/setting/channel/${id}?f=${pathname}`); - } - }; - - // todo: type check - const [{ isActive }, drop] = useDrop(() => ({ - accept: [NativeTypes.FILE], - drop({ dataTransfer }) { - if (dataTransfer.files.length) { - // console.log(files, rest); - setFiles([...dataTransfer.files]); - navigate(`/chat/channel/${id}`); - // 重置 - setTimeout(() => { - setFiles([]); - }, 300); - } - }, - collect: (monitor) => ({ - isActive: monitor.canDrop() && monitor.isOver() - }) - })); - const handleReadAll = () => { - const lastMid = mids[mids.length - 1]; - if (lastMid) { - const param = { groups: [{ gid: id, mid: lastMid }] }; - updateReadIndex(param); - } - }; - const toggleInviteModalVisible = (evt?: Event) => { - if (evt) { - evt.preventDefault(); - evt.stopPropagation(); - } - setInviteModalVisible((prev) => !prev); - }; - const handleMute = () => { - const data = muted ? { remove_groups: [id] } : { add_groups: [{ gid: id }] }; - muteChannel(data); - }; - if (!channel) return null; - const { is_public, name, owner } = channel; - const { unreads = 0, mentions = [] } = getUnreadCount({ - mids, - messageData, - readIndex, - loginUid - }); - const isMentions = mentions.length !== 0; - const inviteIconVisible = is_public || owner == loginUid; - return ( - <> - - } - > - -
    - - {name} -
    -
    - {inviteIconVisible && ( - - - - )} - - - - {unreads > 0 && ( - - {isMentions ? mentions.length : unreads} - - )} -
    -
    -
    - {inviteModalVisible && ( - - )} - - ); -}; - -export default NavItem; diff --git a/src/routes/chat/ChannelList/index.tsx b/src/routes/chat/ChannelList/index.tsx deleted file mode 100644 index 94430b7c..00000000 --- a/src/routes/chat/ChannelList/index.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import { useState } from "react"; -import DeleteConfirmModal from "../../settingChannel/DeleteConfirmModal"; -import NavItem from "./NavItem"; -import { useAppSelector } from "../../../app/store"; - -export default function ChannelList({ setDropFiles }: { setDropFiles: (files: File[]) => void }) { - const [currId, setCurrId] = useState(); - const { channelIds } = useAppSelector((store) => { - return { channelIds: store.channels.ids }; - }); - - const setRemoveChannel = (cid?: number) => { - setCurrId(cid); - }; - - return ( - <> - {channelIds.map((cid) => { - return ( - - ); - })} - {typeof currId !== "undefined" && ( - - )} - - ); -} diff --git a/src/routes/chat/ChannelList/styled.tsx b/src/routes/chat/ChannelList/styled.tsx deleted file mode 100644 index f002d091..00000000 --- a/src/routes/chat/ChannelList/styled.tsx +++ /dev/null @@ -1,86 +0,0 @@ -import styled from "styled-components"; -import { NavLink } from "react-router-dom"; - -const Styled = styled(NavLink)` - position: relative; - display: flex; - align-items: center; - justify-content: space-between; - padding: 8px; - border-radius: 4px; - &:hover, - &.active { - background: rgba(116, 127, 141, 0.1); - } - > .name { - display: flex; - align-items: center; - gap: 8px; - .txt { - color: #1c1c1e; - font-weight: 600; - font-size: 14px; - line-height: 20px; - width: 150px; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - &.read { - color: #616161; - } - } - } - > .icons { - display: flex; - align-items: center; - gap: 8px; - > .icon { - display: none; - width: 16px; - height: 16px; - &:hover path { - fill: #667085; - } - } - > .badge { - color: #fff; - display: flex; - align-items: center; - justify-content: center; - height: 20px; - min-width: 20px; - border-radius: 50%; - background: #22ccee; - font-weight: 900; - font-size: 10px; - line-height: 10px; - &.mention { - background: #f97066; - } - &.dot { - min-width: unset; - width: 6px; - height: 6px; - padding: 0; - } - } - } - &.muted { - .name .txt { - color: #d0d5dd; - } - .icons .badge { - background: #bfbfbf; - } - } - &:hover > .icons { - > .badge { - display: none; - } - > .icon { - display: flex; - } - } -`; - -export default Styled; diff --git a/src/routes/chat/DMChat/index.tsx b/src/routes/chat/DMChat/index.tsx index 7b740cca..86a89023 100644 --- a/src/routes/chat/DMChat/index.tsx +++ b/src/routes/chat/DMChat/index.tsx @@ -46,7 +46,7 @@ const DMChat: FC = ({ uid = 0, dropFiles }) => { context="user" dropFiles={dropFiles} aside={ -
      +
        = ({ uid = 0, dropFiles }) => { trigger="click" content={} > -
      • - +
      • +
      } header={ -
      +
      } diff --git a/src/routes/chat/DMList/NavItem.tsx b/src/routes/chat/DMList/NavItem.tsx deleted file mode 100644 index a9d2bcbc..00000000 --- a/src/routes/chat/DMList/NavItem.tsx +++ /dev/null @@ -1,139 +0,0 @@ -// @ts-nocheck -import { useEffect, useState, FC } from "react"; -import { NavLink, useNavigate, useMatch } from "react-router-dom"; -import { useDrop } from "react-dnd"; -import { useDispatch } from "react-redux"; -import { NativeTypes } from "react-dnd-html5-backend"; - -import dayjs from "dayjs"; -import Tippy from "@tippyjs/react"; -import { useReadMessageMutation } from "../../../app/services/message"; -import { removeUserSession } from "../../../app/slices/message.user"; -import useNormalizeMessage from "../../../common/hook/useNormalizeMessage"; -import useContextMenu from "../../../common/hook/useContextMenu"; -import ContextMenu from "../../../common/component/ContextMenu"; -import { renderPreviewMessage } from "../utils"; -import User from "../../../common/component/User"; -import { ContentTypes } from "../../../app/config"; -import { useAppSelector } from "../../../app/store"; -import { ArchiveMessage } from "../../../types/resource"; -import { useTranslation } from "react-i18next"; - -interface IProps { - uid: number; - mid?: number; - unreads: number; - setFiles: (files: File[]) => void; -} -const NavItem: FC = ({ uid, mid = 0, unreads, setFiles }) => { - const { t } = useTranslation(); - const [previewMsg, setPreviewMsg] = useState(); - const { messages: normalizedMessages, normalizeMessage } = useNormalizeMessage(); - const dispatch = useDispatch(); - const pathMatched = useMatch(`/chat/dm/${uid}`); - const [updateReadIndex] = useReadMessageMutation(); - const { currMsg, currUser } = useAppSelector((store) => { - return { - currUser: store.users.byId[uid], - currMsg: store.message[mid] - }; - }); - const navigate = useNavigate(); - const { visible: contextMenuVisible, handleContextMenuEvent, hideContextMenu } = useContextMenu(); - const [{ isActive }, drop] = useDrop(() => ({ - accept: [NativeTypes.FILE], - drop({ dataTransfer }) { - if (dataTransfer.files.length) { - setFiles([...dataTransfer.files]); - navigate(`/chat/dm/${uid}`); - // 重置 - setTimeout(() => { - setFiles([]); - }, 300); - } - }, - collect: (monitor) => ({ - isActive: monitor.canDrop() && monitor.isOver() - }) - })); - useEffect(() => { - if (currMsg) { - if (currMsg.content_type == ContentTypes.archive) { - normalizeMessage(currMsg.content); - } else { - setPreviewMsg(currMsg); - } - } - }, [currMsg]); - useEffect(() => { - if (normalizedMessages) { - setPreviewMsg(normalizedMessages?.pop()); - } - }, [normalizedMessages]); - - const handleReadAll = () => { - const param = { users: [{ uid, mid }] }; - updateReadIndex(param); - }; - const handleRemoveSession = () => { - dispatch(removeUserSession(uid)); - if (pathMatched) { - navigate("/chat"); - } - }; - if (!currUser) return null; - return ( - - } - > - - -
      -
      - {currUser.name} - {previewMsg && } -
      - -
      -
      {renderPreviewMessage(previewMsg)}
      - {unreads > 0 && ( - 99 ? "dot" : ""}`}> - {unreads > 99 ? null : unreads} - - )} -
      -
      -
      -
      - ); -}; - -export default NavItem; diff --git a/src/routes/chat/DMList/index.tsx b/src/routes/chat/DMList/index.tsx deleted file mode 100644 index 8691c568..00000000 --- a/src/routes/chat/DMList/index.tsx +++ /dev/null @@ -1,59 +0,0 @@ -import { FC } from "react"; -import { getUnreadCount } from "../utils"; -import NavItem from "./NavItem"; -import { useAppSelector } from "../../../app/store"; - -interface Props { - uids: number[]; - setDropFiles: (files: File[]) => void; -} - -const DMList: FC = ({ uids, setDropFiles }) => { - const { - userMessage, - messageData, - readUsers, - loginUid = 0 - } = useAppSelector((store) => { - return { - loginUid: store.authData.user?.uid, - readUsers: store.footprint.readUsers, - userData: store.users.byId, - userMessage: store.userMessage.byId, - messageData: store.message - }; - }); - const sessions = uids.map((uid) => { - const mids = userMessage[uid] || []; - if (mids.length == 0) { - return { lastMid: null, unreads: 0, uid }; - } - const lastMid = [...mids].sort().pop(); - const readIndex = readUsers[uid]; - const { unreads = 0 } = getUnreadCount({ - mids, - readIndex, - messageData, - loginUid - }); - - 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 ( - - ); - })} - - ); -}; - -export default DMList; diff --git a/src/routes/chat/FavList.tsx b/src/routes/chat/FavList.tsx index cb6ce430..ee69e5a1 100644 --- a/src/routes/chat/FavList.tsx +++ b/src/routes/chat/FavList.tsx @@ -1,23 +1,10 @@ import { MouseEvent, FC } from "react"; -import styled from "styled-components"; +import { useTranslation } from "react-i18next"; import FavoredMessage from "../../common/component/Message/FavoredMessage"; import IconSurprise from "../../assets/icons/emoji.surprise.svg"; import IconRemove from "../../assets/icons/close.svg"; import useFavMessage from "../../common/hook/useFavMessage"; -import { useTranslation } from "react-i18next"; -// 覆盖样式 -const Styled = styled.div` - .favorite { - background: none; - &:hover{ - background: #f5f6f7; - } - .down img { - width: 100% !important; - height: auto !important; - } - } -`; + type Props = { cid?: number; uid?: number }; const FavList: FC = ({ cid = null, uid = null }) => { const { t } = useTranslation("chat"); @@ -29,22 +16,22 @@ const FavList: FC = ({ cid = null, uid = null }) => { }; const noFavs = favorites.length == 0; return ( - -

      {t('fav_msg')}({favorites.length})

      +
      +

      {t('fav_msg')}({favorites.length})

      {noFavs ? (
      -
      {t("fav_empty_tip")}
      +
      {t("fav_empty_tip")}
      ) : (
        {favorites.map(({ id }) => { return ( -
      • +
      • -
        +
      • @@ -52,7 +39,7 @@ const FavList: FC = ({ cid = null, uid = null }) => { })}
      )} - +
      ); }; export default FavList; diff --git a/src/routes/chat/GuestBlankPlaceholder.tsx b/src/routes/chat/GuestBlankPlaceholder.tsx index c978d0e1..4d23c749 100644 --- a/src/routes/chat/GuestBlankPlaceholder.tsx +++ b/src/routes/chat/GuestBlankPlaceholder.tsx @@ -21,7 +21,7 @@ const GuestBlankPlaceholder = () => { }; return (
      -

      {t("welcome", { name: serverName })}

      +

      {t("welcome", { name: serverName })}

      {t("guest_login_tip")} diff --git a/src/routes/chat/Layout/index.tsx b/src/routes/chat/Layout/index.tsx index f235fc72..bb853f75 100644 --- a/src/routes/chat/Layout/index.tsx +++ b/src/routes/chat/Layout/index.tsx @@ -1,9 +1,9 @@ import { useState, useRef, useEffect, FC, ReactElement } from "react"; import { useDrop } from "react-dnd"; import { NativeTypes } from "react-dnd-html5-backend"; +import clsx from "clsx"; import ImagePreviewModal from "../../../common/component/ImagePreviewModal"; import Send from "../../../common/component/Send"; -import Styled from "./styled"; import Operations from "./Operations"; import useUploadFile from "../../../common/hook/useUploadFile"; @@ -13,7 +13,6 @@ import useLicense from "../../../common/hook/useLicense"; import LicenseUpgradeTip from "./LicenseOutdatedTip"; // import { useTranslation } from "react-i18next"; import DnDTip from "./DnDTip"; -import clsx from "clsx"; interface Props { readonly?: boolean; @@ -104,14 +103,13 @@ const Layout: FC = ({ ); }, []); const name = context == "channel" ? channelsData[to]?.name : usersData[to]?.name; - return ( <> {previewImage && } - +
      {header} -
      -
      +
      +
      {children}
      {readonly ? ( @@ -126,13 +124,13 @@ const Layout: FC = ({ {selects && }
      - {users &&
      {users}
      } - {aside &&
      {aside}
      } + {users &&
      {users}
      } + {aside && }
      {!readonly && isActive && ( )} - +
      ); }; diff --git a/src/routes/chat/Layout/styled.tsx b/src/routes/chat/Layout/styled.tsx deleted file mode 100644 index 2ec6beb6..00000000 --- a/src/routes/chat/Layout/styled.tsx +++ /dev/null @@ -1,90 +0,0 @@ -import styled from "styled-components"; -const Styled = styled.article` - position: relative; - width: 100%; - border-top-right-radius: 16px; - border-bottom-right-radius: 16px; - > .head { - box-sizing: border-box; - height: 56px; - padding: 0 20px; - border-bottom: 1px solid rgba(0, 0, 0, 0.1); - } - > .main { - height: 100%; - width: 100%; - display: flex; - align-items: flex-start; - justify-content: space-between; - position: relative; - > .chat { - border-bottom-right-radius: 16px; - width: 100%; - display: flex; - flex-direction: column; - padding: 0; - height: calc(100vh - 56px - 18px); - } - .members { - box-shadow: inset 0px 10px 2px -10px rgba(0, 0, 0, 0.1); - } - > .aside { - padding: 12px; - position: absolute; - right: 0; - top: -56px; - transform: translateX(100%); - display: flex; - flex-direction: column; - .divider { - border: none; - background-color: #d4d4d4; - width: 16px; - height: 1px; - margin: 18px auto; - } - .tools { - display: flex; - flex-direction: column; - } - .tools { - gap: 24px; - .tool { - position: relative; - cursor: pointer; - &.fav svg path { - fill: #70707b; - } - &.active svg path { - fill: #3f3f46; - } - &:not(.active):hover svg path { - fill: #51525c; - } - &.badge:after { - position: absolute; - top: -8px; - right: -8px; - content: attr(data-count); - display: flex; - justify-content: center; - align-items: center; - width: 16px; - height: 16px; - - border-radius: 50%; - background-color: #22ccee; - color: #fff; - font-weight: 900; - font-size: 10px; - line-height: 10px; - text-align: center; - color: #ffffff; - } - } - } - } - } - -`; -export default Styled; diff --git a/src/routes/chat/SessionList/Session.tsx b/src/routes/chat/SessionList/Session.tsx index 53ba11cd..3f330cd5 100644 --- a/src/routes/chat/SessionList/Session.tsx +++ b/src/routes/chat/SessionList/Session.tsx @@ -129,15 +129,15 @@ const Session: FC = ({
      - - {name} {!is_public && } + + {name} {!is_public && } - + {previewMsg.created_at ? dayjs(previewMsg.created_at).fromNow() : null}
      - {renderPreviewMessage(previewMsg)} + {renderPreviewMessage(previewMsg)} {unreads > 0 && ( 99 && 'w-1.5 h-1.5 p-0 min-w-[unset]', muted && "bg-gray-500")}> {unreads > 99 ? null : unreads} diff --git a/src/routes/chat/index.tsx b/src/routes/chat/index.tsx index 59542868..b4a27e2e 100644 --- a/src/routes/chat/index.tsx +++ b/src/routes/chat/index.tsx @@ -1,7 +1,7 @@ import { memo, useState } from "react"; import { useParams } from "react-router-dom"; import clsx from "clsx"; -import StyledWrapper from "./styled"; + import BlankPlaceholder from "../../common/component/BlankPlaceholder"; import Server from "../../common/component/Server"; import ChannelChat from "./ChannelChat"; @@ -14,7 +14,7 @@ import GuestBlankPlaceholder from "./GuestBlankPlaceholder"; import GuestChannelChat from "./GuestChannelChat"; import GuestSessionList from "./GuestSessionList"; import IconList from '../../assets/icons/list.svg'; -// import IconClose from '../../assets/icons/close.svg'; + function ChatPage() { const [sessionListVisible, setSessionListVisible] = useState(false); const [channelModalVisible, setChannelModalVisible] = useState(false); @@ -46,22 +46,23 @@ function ChatPage() { }; // console.log("temp uid", tmpUid); const placeholderVisible = channel_id == 0 && user_id == 0; + return ( <> {channelModalVisible && ( )} {usersModalVisible && } - +
      {sessionListVisible &&
      } -
      +
      {isGuest ? : } {sessionListVisible ? null : }
      -
      +
      {placeholderVisible && (isGuest ? : )} {channel_id !== 0 && (isGuest ? ( @@ -71,7 +72,7 @@ function ChatPage() { ))} {user_id !== 0 && }
      - +
      ); } diff --git a/src/routes/chat/styled.tsx b/src/routes/chat/styled.tsx deleted file mode 100644 index c775fd38..00000000 --- a/src/routes/chat/styled.tsx +++ /dev/null @@ -1,157 +0,0 @@ -import styled from "styled-components"; -const StyledWrapper = styled.div` - display: flex; - height: 100%; - padding-top: 8px; - padding-bottom: 10px; - padding-right: 4px; - > .left { - flex-direction: column; - min-width: 268px; - box-shadow: inset -1px 0px 0px rgba(0, 0, 0, 0.05); - height: 100%; - border-radius: 16px 0 0 16px; - .list { - margin: 12px 8px; - &.dms { - flex: 1; - } - .title { - padding: 0 8px; - display: flex; - align-items: center; - justify-content: space-between; - margin-bottom: 4px; - cursor: pointer; - > .txt { - user-select: none; - display: flex; - align-items: center; - gap: 5px; - font-weight: bold; - font-size: 12px; - line-height: 20px; - color: #78787c; - } - .icon { - transition: transform 0.5s ease; - transform-origin: center; - } - .add_icon { - width: 18px; - height: 18px; - } - } - > .nav { - display: flex; - flex-direction: column; - gap: 4px; - a { - text-decoration: none; - } - .session { - display: flex; - align-items: center; - justify-content: space-between; - gap: 8px; - padding: 4px 8px; - border-radius: 4px; - &:hover, - &.active { - background: rgba(116, 127, 141, 0.1); - } - .details { - display: flex; - flex-direction: column; - width: 100%; - .up { - display: flex; - justify-content: space-between; - align-items: center; - .name { - font-weight: 600; - font-size: 14px; - line-height: 20px; - color: #52525b; - max-width: 112px; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - } - time { - white-space: nowrap; - font-weight: 500; - font-size: 12px; - line-height: 18px; - color: #78787c; - } - } - .down { - display: flex; - justify-content: space-between; - .msg { - min-height: 18px; - font-weight: normal; - font-size: 12px; - line-height: 18px; - color: #78787c; - white-space: nowrap; - overflow: hidden; - width: 140px; - text-overflow: ellipsis; - } - > .badge { - color: #fff; - height: 20px; - min-width: 20px; - display: flex; - align-items: center; - justify-content: center; - border-radius: 10px; - background: #1fe1f9; - font-weight: 900; - font-size: 10px; - line-height: 10px; - &.dot { - min-width: unset; - width: 6px; - height: 6px; - padding: 0; - } - &.mute { - background: #bfbfbf; - } - } - } - } - } - /* drop files effect */ - .drop_over { - box-shadow: inset 0 0 0 2px #52edff; - } - } - &.collapse { - .title .icon { - transform: rotate(-90deg); - } - > .nav > .link:not(.active) { - display: none; - } - } - } - } - - > .right { - border-radius: 0 16px 16px 0; - width: 100%; - &.placeholder { - height: 100%; - display: flex; - align-items: center; - justify-content: center; - } - } - -`; - -export default StyledWrapper; diff --git a/src/routes/favs/index.tsx b/src/routes/favs/index.tsx index b1a74b53..0271dfb5 100644 --- a/src/routes/favs/index.tsx +++ b/src/routes/favs/index.tsx @@ -145,7 +145,7 @@ function FavsPage() { ] = messages; const tip = {gid ? <> {channelData[gid]?.name} : <> - From {userData[uid]?.name} + From {userData[uid]?.name} } ; return ( @@ -156,8 +156,8 @@ function FavsPage() {
      -
      diff --git a/src/routes/home/index.tsx b/src/routes/home/index.tsx index 47827fd7..d256c557 100644 --- a/src/routes/home/index.tsx +++ b/src/routes/home/index.tsx @@ -51,30 +51,30 @@ function HomePage() { // 有点绕 const chatNav = isChatHomePath ? "/chat" : chatPath || "/chat"; const userNav = userPath || "/users"; - const linkClass = `flex items-center gap-2.5 px-3 py-2 font-semibold text-sm text-gray-600 rounded-lg hover:bg-black/10`; + const linkClass = `flex items-center gap-2.5 px-3 py-2 font-semibold text-sm text-gray-600 rounded-lg hover:bg-gray-800/10`; return ( <> {!guest && } -
      +
      {!guest && ( -
      +
      {loginUid && }