From 07ddfbf12b31bfaf9d41d070c813b63ac4201067 Mon Sep 17 00:00:00 2001 From: Tristan Yang Date: Mon, 6 Feb 2023 07:35:31 +0800 Subject: [PATCH] feat: darkmode draft version --- package.json | 22 +- public/locales/en/common.json | 4 +- public/locales/en/setting.json | 7 + public/locales/zh/common.json | 4 +- public/locales/zh/setting.json | 7 + src/assets/icons/arrow.down.mini.svg | 4 +- src/assets/icons/file.grid.svg | 4 +- src/assets/icons/file.list.svg | 4 +- src/assets/icons/list.svg | 4 +- src/assets/index.css | 40 ++ src/common/component/AutoDeleteMessages.tsx | 4 +- src/common/component/AvatarUploader.tsx | 4 +- src/common/component/BlankPlaceholder.tsx | 10 +- src/common/component/ChannelModal/index.tsx | 41 +- src/common/component/ChannelModal/styled.tsx | 136 ---- src/common/component/Divider.tsx | 4 +- src/common/component/InviteLink.tsx | 4 +- .../component/InviteModal/InviteByEmail.tsx | 6 +- src/common/component/InviteModal/index.tsx | 6 +- src/common/component/Loading.tsx | 2 +- src/common/component/ManageMembers/index.tsx | 35 +- src/common/component/ManageMembers/styled.tsx | 102 --- src/common/component/MarkdownEditor/index.tsx | 7 +- .../component/MarkdownEditor/styled.tsx | 40 -- src/common/component/Message/Commands.tsx | 76 +-- src/common/component/Message/Mention.tsx | 13 +- .../component/Message/PinMessageModal.tsx | 25 +- .../component/Message/PreviewMessage.tsx | 9 +- src/common/component/Message/index.tsx | 8 +- src/common/component/MixedInput/index.tsx | 2 +- src/common/component/Profile/index.tsx | 8 +- src/common/component/QRCode.tsx | 2 +- src/common/component/SaveTip.tsx | 6 +- .../Send/UploadFileList/EditFileDetails.tsx | 58 +- .../component/Send/UploadFileList/index.tsx | 22 +- .../component/Send/UploadFileList/styled.tsx | 72 -- src/common/component/Send/index.tsx | 2 +- src/common/component/Server.tsx | 4 +- .../component/StyledSettingContainer.tsx | 116 +--- src/common/component/Tooltip.tsx | 2 +- src/common/component/User/index.tsx | 2 +- src/common/component/Version.tsx | 2 +- src/common/component/styled/Modal.tsx | 6 +- src/routes/chat/ChannelChat/index.tsx | 8 +- src/routes/chat/ChannelChat/styled.tsx | 25 - src/routes/chat/GuestBlankPlaceholder.tsx | 6 +- src/routes/chat/GuestChannelChat/index.tsx | 16 +- src/routes/chat/GuestChannelChat/styled.tsx | 28 - src/routes/chat/GuestSessionList/Session.tsx | 22 +- src/routes/chat/GuestSessionList/index.tsx | 5 +- src/routes/chat/GuestSessionList/styled.tsx | 86 --- src/routes/chat/Layout/LoginTip.tsx | 4 +- src/routes/chat/Layout/styled.tsx | 2 - src/routes/chat/SessionList/Session.tsx | 24 +- src/routes/chat/SessionList/index.tsx | 6 +- src/routes/chat/SessionList/styled.tsx | 124 ---- src/routes/chat/index.tsx | 10 +- src/routes/chat/styled.tsx | 5 - src/routes/favs/index.tsx | 4 +- src/routes/home/Menu.tsx | 23 +- src/routes/home/index.tsx | 2 +- src/routes/invite/index.tsx | 35 +- src/routes/invite/styled.tsx | 74 --- src/routes/login/MagicLinkLogin.tsx | 2 +- src/routes/login/MetamaskLoginButton.tsx | 11 +- src/routes/login/OidcLoginButton.tsx | 37 +- src/routes/login/OidcLoginEntry.tsx | 8 +- src/routes/login/SignUpLink.tsx | 2 +- src/routes/login/index.tsx | 23 +- src/routes/login/styled.tsx | 88 --- .../onboarding/steps/who-can-sign-up.tsx | 16 +- src/routes/reg/EmailNextStepTip.tsx | 6 +- src/routes/reg/ExpiredTip.tsx | 2 +- src/routes/reg/RegWithUsername.tsx | 8 +- src/routes/reg/Register.tsx | 13 +- src/routes/reg/SignInLink.tsx | 2 +- src/routes/reg/index.tsx | 7 +- src/routes/reg/styled.tsx | 71 -- src/routes/resources/Filter/Channel.tsx | 68 +- src/routes/resources/Filter/Date.tsx | 50 +- src/routes/resources/Filter/From.tsx | 60 +- src/routes/resources/Filter/Type.tsx | 8 +- src/routes/resources/Filter/index.tsx | 53 +- src/routes/resources/View.tsx | 51 +- src/routes/resources/index.tsx | 2 +- src/routes/resources/styled.tsx | 40 -- src/routes/setting/APIConfig.tsx | 2 +- src/routes/setting/APIDocument.tsx | 14 +- src/routes/setting/BotConfig/BotAPIKeys.tsx | 6 +- src/routes/setting/BotConfig/CreateModal.tsx | 6 +- src/routes/setting/BotConfig/WebhookEdit.tsx | 2 +- src/routes/setting/BotConfig/index.tsx | 17 +- src/routes/setting/License/index.tsx | 2 +- src/routes/setting/MyAccount.tsx | 12 +- src/routes/setting/Overview/DarkMode.tsx | 43 ++ src/routes/setting/Overview/FrontendURL.tsx | 3 +- src/routes/setting/Overview/index.tsx | 6 +- src/routes/setting/Overview/language.tsx | 2 +- src/routes/setting/Overview/server.tsx | 6 +- src/routes/setting/Widget.tsx | 24 +- src/routes/setting/config/Firebase.tsx | 8 +- .../setting/config/IssuerList/index.tsx | 34 +- .../setting/config/IssuerList/styled.tsx | 52 -- src/routes/setting/config/Logins.tsx | 24 +- src/routes/setting/config/SMTP.tsx | 12 +- src/routes/setting/navs.tsx | 4 +- src/routes/users/Search.tsx | 4 +- src/routes/users/index.tsx | 4 +- src/types/common.ts | 1 + tailwind.config.js | 1 + yarn.lock | 625 ++++++++++-------- 111 files changed, 885 insertions(+), 2102 deletions(-) delete mode 100644 src/common/component/ChannelModal/styled.tsx delete mode 100644 src/common/component/ManageMembers/styled.tsx delete mode 100644 src/common/component/MarkdownEditor/styled.tsx delete mode 100644 src/common/component/Send/UploadFileList/styled.tsx delete mode 100644 src/routes/chat/GuestChannelChat/styled.tsx delete mode 100644 src/routes/chat/GuestSessionList/styled.tsx delete mode 100644 src/routes/chat/SessionList/styled.tsx delete mode 100644 src/routes/invite/styled.tsx delete mode 100644 src/routes/login/styled.tsx delete mode 100644 src/routes/reg/styled.tsx delete mode 100644 src/routes/resources/styled.tsx create mode 100644 src/routes/setting/Overview/DarkMode.tsx delete mode 100644 src/routes/setting/config/IssuerList/styled.tsx diff --git a/package.json b/package.json index 6f97367f..bf03ccfd 100644 --- a/package.json +++ b/package.json @@ -7,21 +7,21 @@ "@emoji-mart/react": "^1.1.1", "@metamask/onboarding": "^1.0.1", "@pmmmwh/react-refresh-webpack-plugin": "^0.5.10", - "@react-oauth/google": "^0.6.1", + "@react-oauth/google": "^0.7.0", "@reduxjs/toolkit": "^1.9.2", "@svgr/webpack": "^6.5.1", "@tippyjs/react": "^4.2.6", "@toast-ui/editor": "^3.2.1", "@toast-ui/editor-plugin-code-syntax-highlight": "^3.1.0", "@toast-ui/react-editor": "^3.2.2", - "@types/node": "^18.11.18", + "@types/node": "^18.11.19", "@types/react": "^18.0.27", "@types/react-dom": "^18.0.10", "@udecode/plate": "16.8", "@uiball/loaders": "^1.2.6", "bfj": "^7.0.2", "broadcast-channel": "^4.20.2", - "browserslist": "^4.21.4", + "browserslist": "^4.21.5", "clsx": "^1.2.1", "copy-image-clipboard": "^2.1.2", "css-loader": "^6.7.3", @@ -32,7 +32,7 @@ "emoji-mart": "5.5.2", "eslint": "^8.33.0", "file-loader": "^6.2.0", - "firebase": "^9.16.0", + "firebase": "^9.17.1", "fs-extra": "^11.1.0", "html-webpack-plugin": "^5.5.0", "i18next": "^22.4.9", @@ -53,7 +53,7 @@ "react-dom": "^18.2.0", "react-helmet": "^6.1.0", "react-hot-toast": "^2.4.0", - "react-i18next": "^12.1.4", + "react-i18next": "^12.1.5", "react-icons": "^4.7.1", "react-redux": "^8.0.5", "react-refresh": "0.14.0", @@ -64,15 +64,15 @@ "react-use-wizard": "^2.2.1", "resolve": "^1.22.1", "rooks": "^7.4.3", - "slate": "^0.88.1", + "slate": "^0.90.0", "slate-history": "^0.86.0", - "slate-react": "^0.88.2", + "slate-react": "^0.90.0", "source-map-loader": "^4.0.1", "style-loader": "^3.3.1", "styled-components": "^5.3.6", "terser-webpack-plugin": "^5.3.6", "tippy.js": "^6.3.7", - "typescript": "^4.9.4", + "typescript": "^4.9.5", "webpack": "^5.75.0", "webpack-dev-server": "^4.11.1", "webpack-manifest-plugin": "^5.0.0", @@ -124,8 +124,8 @@ "@types/react-helmet": "^6.1.6", "@types/react-syntax-highlighter": "^15.5.6", "@types/styled-components": "^5.1.26", - "@typescript-eslint/eslint-plugin": "^5.49.0", - "@typescript-eslint/parser": "^5.49.0", + "@typescript-eslint/eslint-plugin": "^5.50.0", + "@typescript-eslint/parser": "^5.50.0", "@welldone-software/why-did-you-render": "^7.0.1", "autoprefixer": "^10.4.13", "babel-loader": "^9.1.2", @@ -134,7 +134,7 @@ "eslint-config-prettier": "^8.6.0", "eslint-plugin-import": "^2.27.5", "eslint-plugin-prettier": "^4.2.1", - "eslint-plugin-react": "^7.32.1", + "eslint-plugin-react": "^7.32.2", "eslint-plugin-react-hooks": "^4.6.0", "gh-pages": "^5.0.0", "husky": "^8.0.3", diff --git a/public/locales/en/common.json b/public/locales/en/common.json index 0d8be948..1bf79f02 100644 --- a/public/locales/en/common.json +++ b/public/locales/en/common.json @@ -45,7 +45,8 @@ "hide_session": "Hide Session", "reload": "reload", "install": "Install", - "download_origin": "Download original" + "download_origin": "Download original", + "close": "Close" }, "status": { "uploading": "Uploading" @@ -55,6 +56,7 @@ "delete": "Delete Successfully!", "login": "Login Successfully!", "logout": "Logout Successfully!", + "pin": "Pin Message Successfully!", "pwa_install_title": "Install web app on desktop?", "pwa_install_desc": "Add to desktop for quick access to this app." }, diff --git a/public/locales/en/setting.json b/public/locales/en/setting.json index bb2dd7b3..e48a123d 100644 --- a/public/locales/en/setting.json +++ b/public/locales/en/setting.json @@ -68,6 +68,13 @@ "en": "English", "zh": "中文", "jp": "日本語" + }, + "theme": { + "title": "Theme", + "desc": "Setting the theme", + "auto": "Auto", + "dark": "Dark", + "light": "Light" } }, "license": { diff --git a/public/locales/zh/common.json b/public/locales/zh/common.json index e5227401..72f3108f 100644 --- a/public/locales/zh/common.json +++ b/public/locales/zh/common.json @@ -47,7 +47,8 @@ "hide_session": "隐藏会话", "reload": "刷新页面", "install": "安装", - "download_origin": "下载原图" + "download_origin": "下载原图", + "close": "关闭" }, "status": { "uploading": "上传中" @@ -57,6 +58,7 @@ "delete": "删除成功!", "login": "登录成功!", "logout": "退出成功!", + "pin": "消息置顶成功!", "pwa_install_title": "安装到桌面?", "pwa_install_desc": "使用桌面访问,更便捷!" }, diff --git a/public/locales/zh/setting.json b/public/locales/zh/setting.json index 0a58e2d3..0d141ff2 100644 --- a/public/locales/zh/setting.json +++ b/public/locales/zh/setting.json @@ -62,6 +62,13 @@ "lang": { "title": "语言", "desc": "设置界面语言" + }, + "theme": { + "title": "主题", + "desc": "设置主题模式", + "auto": "自动", + "dark": "黑夜模式", + "light": "白天模式" } }, "license": { diff --git a/src/assets/icons/arrow.down.mini.svg b/src/assets/icons/arrow.down.mini.svg index 8b8bda4c..200a99e5 100644 --- a/src/assets/icons/arrow.down.mini.svg +++ b/src/assets/icons/arrow.down.mini.svg @@ -1,4 +1,4 @@ - + - + diff --git a/src/assets/icons/file.grid.svg b/src/assets/icons/file.grid.svg index 1bc2c06e..e6614d84 100644 --- a/src/assets/icons/file.grid.svg +++ b/src/assets/icons/file.grid.svg @@ -1,3 +1,3 @@ - - + + diff --git a/src/assets/icons/file.list.svg b/src/assets/icons/file.list.svg index b415ec13..9dc2db52 100644 --- a/src/assets/icons/file.list.svg +++ b/src/assets/icons/file.list.svg @@ -1,3 +1,3 @@ - - + + diff --git a/src/assets/icons/list.svg b/src/assets/icons/list.svg index e08df59b..2bfe2329 100644 --- a/src/assets/icons/list.svg +++ b/src/assets/icons/list.svg @@ -1,3 +1,3 @@ - - + + diff --git a/src/assets/index.css b/src/assets/index.css index cefc2fe7..f5cb5bf5 100644 --- a/src/assets/index.css +++ b/src/assets/index.css @@ -26,6 +26,43 @@ .checkbox:checked::before { transform: scale(1); } + /* markdown editor */ + .md-editor { + position: relative; + width: 100%; + width: -webkit-fill-available; + margin-top: 16px; + } + .md-editor > div { + transition: height 0.5s ease 0s; + } + .md-editor .toastui-editor-defaultUI { + border-bottom: none; + border-radius: 0; + border-top: 1px solid #d0d5dd; + border-left: none; + border-right: none; + } + .md-editor .toastui-editor { + padding: 16px 0; + } + .md-editor .toastui-editor [contenteditable="true"] { + padding: 0; + } + .md-editor .toastui-editor-md-preview { + padding-top: 16px; + } + .md-editor .toastui-editor-md-preview .toastui-editor-contents { + padding: 0; + } + .md-editor .toastui-editor-toolbar { + display: none; + } + .md-editor .send { + position: absolute; + bottom: 15px; + right: 15px; + } } /* 全局设置滚动条 */ ::-webkit-scrollbar-thumb { @@ -37,6 +74,9 @@ width: 5px; height: 5px; } +html.dark ::-webkit-scrollbar-thumb { + background: #1c1c1e; +} :root { /* border radius */ diff --git a/src/common/component/AutoDeleteMessages.tsx b/src/common/component/AutoDeleteMessages.tsx index ece4eeed..c8d5f384 100644 --- a/src/common/component/AutoDeleteMessages.tsx +++ b/src/common/component/AutoDeleteMessages.tsx @@ -49,8 +49,8 @@ const AutoDeleteMessages = ({ id, type = "channel" }: Props) => { return (
-

{t("title")}

-

{t("desc")}

+

{t("title")}

+

{t("desc")}

= ({ {!disabled && ( <> -
+
{uploading ? t("status.uploading") : t("action.change_avatar")}
= ({ type = "chat" }) => { const { t } = useTranslation("welcome"); @@ -38,14 +38,14 @@ const BlankPlaceholder: FC = ({ type = "chat" }) => { const chatHandler = type == "chat" ? toggleChannelModalVisible : toggleUserListVisible; return ( <> -
+
-

{t("title", { name: server.name })}

+

{t("title", { name: server.name })}

{t("desc")}

-
+
{t("invite")}
diff --git a/src/common/component/ChannelModal/index.tsx b/src/common/component/ChannelModal/index.tsx index c6d9e24c..389d1593 100644 --- a/src/common/component/ChannelModal/index.tsx +++ b/src/common/component/ChannelModal/index.tsx @@ -5,7 +5,6 @@ import Modal from "../Modal"; import Button from "../styled/Button"; import ChannelIcon from "../ChannelIcon"; import User from "../User"; -import StyledWrapper from "./styled"; import StyledCheckbox from "../styled/Checkbox"; import StyledToggle from "../../component/styled/Toggle"; import useFilteredUsers from "../../hook/useFilteredUsers"; @@ -13,6 +12,7 @@ import { useCreateChannelMutation } from "../../../app/services/channel"; import { useAppSelector } from "../../../app/store"; import { CreateChannelDTO } from "../../../types/channel"; import { useTranslation } from "react-i18next"; +import clsx from "clsx"; interface Props { personal?: boolean; @@ -94,18 +94,19 @@ const ChannelModal: FC = ({ personal = false, closeModal }) => { return ( - +
{!is_public && ( -
-
+
+
{users && ( -
    +
      {users.map((u) => { const { uid } = u; const checked = members ? members.includes(uid) : false; @@ -113,7 +114,7 @@ const ChannelModal: FC = ({ personal = false, closeModal }) => {
    • = ({ personal = false, closeModal }) => { )}
)} -
-

{t("create_channel")}

-

+

+

{t("create_channel")}

+

{!is_public ? t("create_private_channel_desc") : t("create_channel_desc")}

-
- {t("channel_name")} -
- - +
+ {t("channel_name")} +
+ +
-
- {t("private_channel")} +
+ {t("private_channel")}
-
- -
- +
); }; diff --git a/src/common/component/ChannelModal/styled.tsx b/src/common/component/ChannelModal/styled.tsx deleted file mode 100644 index e47b7cf6..00000000 --- a/src/common/component/ChannelModal/styled.tsx +++ /dev/null @@ -1,136 +0,0 @@ -import styled from "styled-components"; - -const StyledWrapper = styled.div` - display: flex; - max-height: 402px; - background: #fff; - box-shadow: 0px 25px 50px rgba(31, 41, 55, 0.25); - border-radius: var(--br); - transition: all 0.5s ease; - .left { - width: 260px; - box-shadow: inset -1px 0px 0px rgba(0, 0, 0, 0.1); - .search { - position: sticky; - top: 0; - z-index: 99; - background: #fff; - border-top-left-radius: var(--br); - box-shadow: 0px 1px 0px rgba(0, 0, 0, 0.1); - padding: 8px; - width: calc(100% - 1px); - input { - outline: none; - width: -webkit-fill-available; - padding: 8px; - font-size: 14px; - line-height: 20px; - border: none; - } - } - .users { - display: flex; - flex-direction: column; - height: calc(100% - 52px - 10px); - overflow-y: scroll; - overflow-x: hidden; - .user { - cursor: pointer; - display: flex; - align-items: center; - padding: 0 16px; - width: -webkit-fill-available; - border-radius: 4px; - &:hover { - background: rgba(116, 127, 141, 0.1); - } - > div { - width: 100%; - } - } - } - } - .right { - min-width: 400px; - display: flex; - flex-direction: column; - align-items: center; - padding: 32px; - box-sizing: border-box; - &.private { - width: 344px; - justify-content: space-evenly; - .desc { - text-align: center; - } - } - > .title { - font-weight: 600; - font-size: 20px; - line-height: 30px; - color: #374151; - margin-bottom: 16px; - } - .desc { - font-weight: normal; - color: #6b7280; - margin-bottom: 48px; - } - .name { - width: 100%; - display: flex; - flex-direction: column; - justify-content: flex-start; - gap: 8px; - margin-bottom: 34px; - .label { - font-weight: 600; - color: #6b7280; - } - .input { - position: relative; - input { - width: -webkit-fill-available; - border: 1px solid #e5e7eb; - box-shadow: 0px 1px 2px rgba(31, 41, 55, 0.08); - border-radius: 4px; - padding: 8px; - color: #78787c; - padding-left: 36px; - } - .icon { - position: absolute; - left: 8px; - top: 50%; - transform: translateY(-50%); - } - } - } - .private { - width: 100%; - display: flex; - align-items: center; - justify-content: space-between; - margin-bottom: 50px; - .txt { - font-weight: 600; - color: #6b7280; - } - input { - cursor: pointer; - } - } - .btns { - width: 100%; - display: flex; - align-items: center; - justify-content: flex-end; - gap: 16px; - } - .normal { - font-size: 14px; - line-height: 20px; - } - } -`; -export default StyledWrapper; diff --git a/src/common/component/Divider.tsx b/src/common/component/Divider.tsx index 82362737..e2ece318 100644 --- a/src/common/component/Divider.tsx +++ b/src/common/component/Divider.tsx @@ -4,8 +4,8 @@ interface Props { } const Divider: FC = ({ content }) => { - return
- {content} + return
+ {content}
; }; diff --git a/src/common/component/InviteLink.tsx b/src/common/component/InviteLink.tsx index a09afc5e..e2cc97c7 100644 --- a/src/common/component/InviteLink.tsx +++ b/src/common/component/InviteLink.tsx @@ -15,14 +15,14 @@ const InviteLink: FC = () => { return (
- {t("share_invite_link")} + {t("share_invite_link")}
- {t("invite_link_expire")} + {t("invite_link_expire")}
diff --git a/src/common/component/InviteModal/InviteByEmail.tsx b/src/common/component/InviteModal/InviteByEmail.tsx index fe778b57..043ede5b 100644 --- a/src/common/component/InviteModal/InviteByEmail.tsx +++ b/src/common/component/InviteModal/InviteByEmail.tsx @@ -49,7 +49,7 @@ const InviteByEmail: FC = ({ cid }) => { return (
- +
= ({ cid }) => {
- +
- +
); }; export default MarkdownEditor; diff --git a/src/common/component/MarkdownEditor/styled.tsx b/src/common/component/MarkdownEditor/styled.tsx deleted file mode 100644 index ddca896d..00000000 --- a/src/common/component/MarkdownEditor/styled.tsx +++ /dev/null @@ -1,40 +0,0 @@ -import styled from "styled-components"; - -const StyledWrapper = styled.div` - position: relative; - width: 100%; - width: -webkit-fill-available; - margin-top: 16px; - > div { - transition: height 0.5s ease 0s; - } - .toastui-editor-defaultUI { - border-bottom: none; - border-radius: 0; - border-top: 1px solid #d0d5dd; - border-left: none; - border-right: none; - } - .toastui-editor { - padding: 16px 0; - [contenteditable="true"] { - padding: 0; - } - } - .toastui-editor-md-preview { - padding-top: 16px; - .toastui-editor-contents { - padding: 0; - } - } - .toastui-editor-toolbar { - display: none; - } - .send { - position: absolute; - bottom: 15px; - right: 15px; - } -`; - -export default StyledWrapper; diff --git a/src/common/component/Message/Commands.tsx b/src/common/component/Message/Commands.tsx index 42315d08..73c8b1a6 100644 --- a/src/common/component/Message/Commands.tsx +++ b/src/common/component/Message/Commands.tsx @@ -1,6 +1,5 @@ import { useState, useRef, FC } from "react"; import { useDispatch } from "react-redux"; -import styled from "styled-components"; import Tippy from "@tippyjs/react"; import { hideAll } from "tippy.js"; import toast from "react-hot-toast"; @@ -21,47 +20,7 @@ import IconDelete from "../../../assets/icons/delete.svg"; import moreIcon from "../../../assets/icons/more.svg?url"; import useMessageOperation from "./useMessageOperation"; import { useTranslation } from "react-i18next"; - -const StyledCmds = styled.ul` - z-index: 999; - position: absolute; - right: 10px; - top: 0; - transform: translateY(-50%); - display: flex; - align-items: center; - border: 1px solid rgba(0, 0, 0, 0.08); - border-radius: 6px; - background-color: #fff; - visibility: hidden; - &.visible { - visibility: visible; - } - .cmd { - display: flex; - cursor: pointer; - padding: 4px; - &:hover { - background-color: #f3f4f6; - } - img, - svg { - width: 24px; - height: 24px; - } - &.fav { - svg path { - fill: #667085; - } - } - } - > .picker { - position: absolute; - left: -10px; - top: 0; - transform: translateX(-100%); - } -`; +import clsx from "clsx"; type Props = { context: "user" | "channel"; contextId: number; @@ -124,9 +83,20 @@ const Commands: FC = ({ context = "user", contextId = 0, mid = 0, toggleE } }; + + // const StyledCmds = styled.ul` + // > .picker { + // position: absolute; + // left: -10px; + // top: 0; + // transform: translateX(-100%); + // } + // `; return ( <> - +
    = ({ context = "user", contextId = 0, mid = 0, toggleE trigger="click" content={} > -
  • +
  • - icon emoji + icon emoji
  • {canEdit && ( -
  • +
  • - icon edit + icon edit
  • )} {canReply && ( -
  • +
  • - icon reply + icon reply
  • )} -
  • +
  • - +
  • = ({ context = "user", contextId = 0, mid = 0, toggleE /> } > -
  • +
  • icon more
  • - +
{PinModal} {ForwardModal} {DeleteModal} diff --git a/src/common/component/Message/Mention.tsx b/src/common/component/Message/Mention.tsx index 4ff599a0..4435c4cb 100644 --- a/src/common/component/Message/Mention.tsx +++ b/src/common/component/Message/Mention.tsx @@ -1,17 +1,8 @@ // import { FC, ReactNode } from "react"; import Tippy from "@tippyjs/react"; -import styled from "styled-components"; import Profile from "../Profile"; import { useAppSelector } from "../../../app/store"; -const Styled = styled.span` - padding: 0 2px; - color: #1fe1f9; - &.clickable { - cursor: pointer; - } -`; - interface Props { uid: number; popover?: boolean; @@ -24,7 +15,7 @@ const Mention = ({ uid, popover = true, cid, textOnly = false }: Props) => { const user = usersData[uid]; if (!user) return null; if (textOnly) return <>{`@${user.name}`}; - if (!popover) return {`@${user.name}`}; + if (!popover) return {`@${user.name}`}; return ( { trigger="click" content={} > - {`@${user.name}`} + {`@${user.name}`} ); }; diff --git a/src/common/component/Message/PinMessageModal.tsx b/src/common/component/Message/PinMessageModal.tsx index 796ae684..54fdbe36 100644 --- a/src/common/component/Message/PinMessageModal.tsx +++ b/src/common/component/Message/PinMessageModal.tsx @@ -1,6 +1,5 @@ import { FC } from "react"; import { useEffect } from "react"; -import styled from "styled-components"; import toast from "react-hot-toast"; import usePinMessage from "../../hook/usePinMessage"; import StyledModal from "../styled/Modal"; @@ -9,20 +8,6 @@ import Modal from "../Modal"; import PreviewMessage from "./PreviewMessage"; import { useTranslation } from "react-i18next"; -const StyledPinModal = styled(StyledModal)` - min-width: 406px; - .title, - .desc { - text-align: left; - } - .preview { - border: 1px solid #f2f4f7; - max-height: 256px; - overflow: auto; - background: none; - overflow-x: hidden; - } -`; interface Props { closeModal: () => void; @@ -40,7 +25,7 @@ const PinMessageModal: FC = ({ closeModal, mid = 0, gid = 0 }) => { useEffect(() => { if (isSuccess) { closeModal(); - toast.success("Pin Message Successfully"); + toast.success(t("tip.pin")); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [isSuccess]); @@ -48,8 +33,8 @@ const PinMessageModal: FC = ({ closeModal, mid = 0, gid = 0 }) => { if (!mid) return null; return ( -
-
+
{reply_mid && } {edit ? ( diff --git a/src/common/component/MixedInput/index.tsx b/src/common/component/MixedInput/index.tsx index d8305622..66e2032a 100644 --- a/src/common/component/MixedInput/index.tsx +++ b/src/common/component/MixedInput/index.tsx @@ -188,7 +188,7 @@ const Plugins: FC = ({ return ( -
+
= ({ 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 text-sm pt-3.5 pb-3`; - const containerClass = clsx(`flex-center flex-col w-[432px] gap-1 z-[998] mt-20 select-none`, isCard && "p-4 w-[280px] bg-white drop-shadow rounded-md"); + 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"); return (
= ({ uid, type = "embed", cid }) => { src={avatar} name={name} /> -

{name}

- {email} +

{name}

+ {email} {/*

{introduction}

*/}
    diff --git a/src/common/component/QRCode.tsx b/src/common/component/QRCode.tsx index 96d0e69e..3e6992a4 100644 --- a/src/common/component/QRCode.tsx +++ b/src/common/component/QRCode.tsx @@ -10,7 +10,7 @@ const QRCode = ({ link }: Props) => { const logo = useAppSelector(store => store.server.logo); return ( = ({ saveHandler, resetHandler }) => { const { t } = useTranslation("setting"); // const btnClass=clsx("") return ( -
    - {t('save_tip')} +
    + {t('save_tip')}
    -
    - +
    ); } diff --git a/src/common/component/Send/UploadFileList/index.tsx b/src/common/component/Send/UploadFileList/index.tsx index fd6ebbbc..f2e39648 100644 --- a/src/common/component/Send/UploadFileList/index.tsx +++ b/src/common/component/Send/UploadFileList/index.tsx @@ -1,5 +1,4 @@ import { useState, useEffect } from "react"; -import Styled from "./styled"; import { useMixedEditor } from "../../MixedInput"; import EditFileDetailsModal from "./EditFileDetails"; import { getFileIcon, formatBytes } from "../../../utils"; @@ -43,6 +42,7 @@ export default function UploadFileList({ }, [stageFiles.length]); if (!context || !id || !stageFiles || stageFiles.length == 0) return null; + return ( <> {editInfo && ( @@ -53,21 +53,21 @@ export default function UploadFileList({ /> )} - +
      {stageFiles.map(({ name, url, size, type }, idx: number) => { return ( -
    • -
      - {type.startsWith("image") ? image : getFileIcon(type, name)} +
    • +
      + {type.startsWith("image") ? image : getFileIcon(type, name)}
      -

      {name}

      - {formatBytes(size)} -
        -
      • +

        {name}

        + {formatBytes(size)} +
          +
        • @@ -77,7 +77,7 @@ export default function UploadFileList({
        • ); })} - +
        ); } diff --git a/src/common/component/Send/UploadFileList/styled.tsx b/src/common/component/Send/UploadFileList/styled.tsx deleted file mode 100644 index 8bc86572..00000000 --- a/src/common/component/Send/UploadFileList/styled.tsx +++ /dev/null @@ -1,72 +0,0 @@ -import styled from "styled-components"; - -const Styled = styled.ul` - width: 100%; - overflow: auto; - display: flex; - justify-content: flex-start; - gap: 24px; - padding: 24px 16px 16px 16px; - background: #e5e7eb; - box-shadow: 0 1px 0 rgba(0, 0, 0, 0.05); - border-radius: 8px 8px 0 0; - .file { - position: relative; - display: flex; - flex-direction: column; - - background: #fcfcfd; - border-radius: 4px; - padding: 8px; - .preview { - display: flex; - justify-content: center; - align-items: center; - width: 160px; - height: 160px; - img { - width: 100%; - height: 100%; - object-fit: cover; - } - } - .name { - width: 160px; - margin: 16px 0 2px 0; - font-weight: 600; - font-size: 14px; - line-height: 20px; - color: #1c1c1e; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - } - .size { - font-weight: 400; - font-size: 12px; - line-height: 18px; - color: #616161; - } - .opts { - visibility: hidden; - background: inherit; - border: 1px solid rgba(0, 0, 0, 0.08); - box-sizing: border-box; - border-radius: 6px; - display: flex; - align-items: center; - position: absolute; - right: -20px; - top: -10px; - .opt { - padding: 4px; - cursor: pointer; - } - } - &:hover .opts { - visibility: visible; - } - } -`; - -export default Styled; diff --git a/src/common/component/Send/index.tsx b/src/common/component/Send/index.tsx index 1bc1f49b..e18058ef 100644 --- a/src/common/component/Send/index.tsx +++ b/src/common/component/Send/index.tsx @@ -137,7 +137,7 @@ const Send: FC = ({ context == "channel" ? (channelsData[id]?.is_public ? uids : channelsData[id]?.members) : []; return ( {replying_mid && } diff --git a/src/common/component/Server.tsx b/src/common/component/Server.tsx index 4c122cac..ff7b8e5a 100644 --- a/src/common/component/Server.tsx +++ b/src/common/component/Server.tsx @@ -28,7 +28,7 @@ export default function Server({ readonly = false }: Props) { {`${name}
    -

    +

    {name}

    {userCount} {t("members")} @@ -45,7 +45,7 @@ export default function Server({ readonly = false }: Props) { {`${name}
    -

    +

    {name}

    {userCount} {t("members")} diff --git a/src/common/component/StyledSettingContainer.tsx b/src/common/component/StyledSettingContainer.tsx index d243cbd5..7fa0c74d 100644 --- a/src/common/component/StyledSettingContainer.tsx +++ b/src/common/component/StyledSettingContainer.tsx @@ -1,96 +1,8 @@ import { FC, PropsWithChildren, ReactNode } from "react"; -import styled from "styled-components"; import { useLocation, NavLink } from "react-router-dom"; -import backIcon from "../../assets/icons/arrow.left.svg?url"; +import IconBack from "../../assets/icons/arrow.left.svg"; import { Nav } from "../../routes/settingChannel/navs"; - -const StyledWrapper = styled.div` - width: 100vw; - height: 100vh; - display: flex; - - > .left { - max-height: 100vh; - overflow: scroll; - padding: 32px 16px; - min-width: 212px; - background-color: #f5f6f7; - - > .title { - cursor: pointer; - font-weight: bold; - font-size: 16px; - line-height: 24px; - color: #1c1c1e; - margin-bottom: 32px; - padding-left: 24px; - background-size: 16px; - background: url(${backIcon}) no-repeat left; - } - - > .items { - display: flex; - flex-direction: column; - gap: 2px; - margin-bottom: 36px; - - &:before { - padding-left: 12px; - content: attr(data-title); - font-weight: bold; - font-size: 12px; - line-height: 18px; - color: #6b7280; - margin-bottom: 2px; - } - - .item { - font-weight: 500; - font-size: 14px; - line-height: 20px; - color: #44494f; - border-radius: 4px; - - &:hover, - &.curr { - background: #e7e5e4; - } - - > a { - display: block; - padding: 4px 12px; - } - } - - &.danger .item { - cursor: pointer; - padding: 4px 12px; - color: #ef4444; - - &:hover { - background: none; - } - } - } - } - - > .right { - background-color: #fff; - width: 100%; - max-height: 100%; - overflow: auto; - padding: 32px; - - > .title { - font-weight: bold; - font-size: 20px; - line-height: 30px; - color: #374151; - margin-bottom: 32px; - } - } -`; - +import clsx from "clsx"; export interface Danger { title: string; handler: () => void; @@ -114,18 +26,18 @@ const StyledSettingContainer: FC> = ({ }) => { const { pathname } = useLocation(); return ( - -
    -

    - {title} +
    +
    +

    + {title}

    {navs.map(({ title, items }) => { return ( -
      +
        {items.map(({ name, title }) => { return ( -
      • - {title} +
      • + {title}
      • ); })} @@ -133,12 +45,12 @@ const StyledSettingContainer: FC> = ({ ); })} {dangers.length ? ( -
          +
            {dangers.map((d) => { if (typeof d === "boolean" || !d) return null; const { title, handler } = d; return ( -
          • +
          • {title}
          • ); @@ -146,11 +58,11 @@ const StyledSettingContainer: FC> = ({
          ) : null}
    -
    - {nav &&

    {nav.title}

    } +
    + {nav &&

    {nav.title}

    } {children}
    - +
    ); }; diff --git a/src/common/component/Tooltip.tsx b/src/common/component/Tooltip.tsx index 967dafa2..b0a51175 100644 --- a/src/common/component/Tooltip.tsx +++ b/src/common/component/Tooltip.tsx @@ -27,7 +27,7 @@ const Tooltip: FC = ({ tip = "", placement = "right", delay = null, child duration={delay ? defaultDuration : 0} delay={delay ?? [150, 0]} placement={placement} - content={
    + content={
    {tip}
    } diff --git a/src/common/component/User/index.tsx b/src/common/component/User/index.tsx index 39f8e22f..780c22b3 100644 --- a/src/common/component/User/index.tsx +++ b/src/common/component/User/index.tsx @@ -44,7 +44,7 @@ const User: FC = ({ if (!curr) return null; const online = curr.online || curr.uid == loginUid; const containerClass = clsx(`relative flex items-center justify-start gap-2 p-2 rounded-lg select-none `, interactive && "hover:bg-gray-500/10", compact && "p-0"); - const nameClass = clsx(`text-sm text-gray-500 max-w-[190px] overflow-hidden text-ellipsis font-semibold`); + const nameClass = clsx(`text-sm text-gray-500 max-w-[190px] overflow-hidden text-ellipsis font-semibold dark:text-white`); const statusClass = clsx(`absolute -bottom-0.5 -right-1.5 w-3 h-3 box-content rounded-full border-[2px] border-solid border-white`, online ? "bg-[#22c55e]" : "bg-[#a1a1aa]", compact && "w-3.5 h-3.5"); diff --git a/src/common/component/Version.tsx b/src/common/component/Version.tsx index b3b38dca..7b5b6a16 100644 --- a/src/common/component/Version.tsx +++ b/src/common/component/Version.tsx @@ -6,7 +6,7 @@ const Version: FC = () => { const { t } = useTranslation("setting", { keyPrefix: "version" }); const { data: serverVersion } = useGetServerVersionQuery(); return ( -
    +
    {t("client_version")}: {process.env.VERSION}
    {t("server_version")}: {serverVersion}
    {t("build_time")}: {process.env.REACT_APP_BUILD_TIME}
    diff --git a/src/common/component/styled/Modal.tsx b/src/common/component/styled/Modal.tsx index 48a654d2..f6e8a7c2 100644 --- a/src/common/component/styled/Modal.tsx +++ b/src/common/component/styled/Modal.tsx @@ -12,9 +12,9 @@ interface Props { const StyledModal: FC = ({ compact = false, title = "", description = "", buttons, children, className }) => { return ( -
    - {title &&

    {title}

    } - {description &&

    {description}

    } +
    + {title &&

    {title}

    } + {description &&

    {description}

    } {children} {buttons &&
    {buttons}
    }
    diff --git a/src/routes/chat/ChannelChat/index.tsx b/src/routes/chat/ChannelChat/index.tsx index 7aa75c7c..aa34b993 100644 --- a/src/routes/chat/ChannelChat/index.tsx +++ b/src/routes/chat/ChannelChat/index.tsx @@ -145,7 +145,7 @@ function ChannelChat({ cid = 0, dropFiles = [] }: Props) {
    - {name} + {name} {description}
    @@ -155,7 +155,7 @@ function ChannelChat({ cid = 0, dropFiles = [] }: Props) { {addVisible && (
    -
    {t("add_channel_members")}
    +
    {t("add_channel_members")}
    )} {memberIds.map((uid: number) => { @@ -179,8 +179,8 @@ function ChannelChat({ cid = 0, dropFiles = [] }: Props) { ) : (
    -

    {t("welcome_channel", { name })}

    -

    {t("welcome_desc", { name })}

    +

    {t("welcome_channel", { name })}

    +

    {t("welcome_desc", { name })}

    {loginUser?.is_admin && ( diff --git a/src/routes/chat/ChannelChat/styled.tsx b/src/routes/chat/ChannelChat/styled.tsx index 000be93f..032a925f 100644 --- a/src/routes/chat/ChannelChat/styled.tsx +++ b/src/routes/chat/ChannelChat/styled.tsx @@ -1,30 +1,5 @@ import styled from "styled-components"; -export const StyledNotification = styled.div` - padding: 3px 8px; - font-style: normal; - font-weight: 600; - font-size: 12px; - line-height: 18px; - color: #fff; - position: absolute; - top: 0; - left: 10px; - width: 900px; - height: 24px; - background: linear-gradient(135deg, #3c8ce7 0%, #00eaff 100%); - border-radius: 0px 0px 8px 8px; - display: flex; - align-items: center; - justify-content: space-between; - .clear { - cursor: pointer; - color: inherit; - border: none; - background: none; - outline: none; - } -`; export const StyledUsers = styled.div` /* display: flex; */ flex-direction: column; diff --git a/src/routes/chat/GuestBlankPlaceholder.tsx b/src/routes/chat/GuestBlankPlaceholder.tsx index 1040e16b..c978d0e1 100644 --- a/src/routes/chat/GuestBlankPlaceholder.tsx +++ b/src/routes/chat/GuestBlankPlaceholder.tsx @@ -20,10 +20,10 @@ const GuestBlankPlaceholder = () => { navigateTo("/login"); }; return ( -
    -

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

    +
    +

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

    - {t("guest_login_tip")} + {t("guest_login_tip")}
    diff --git a/src/routes/chat/GuestChannelChat/index.tsx b/src/routes/chat/GuestChannelChat/index.tsx index e5ab52da..82e77de3 100644 --- a/src/routes/chat/GuestChannelChat/index.tsx +++ b/src/routes/chat/GuestChannelChat/index.tsx @@ -1,13 +1,13 @@ // import { useState, useEffect } from "react"; // import { NavLink } from "react-router-dom"; +import { useTranslation } from "react-i18next"; import useMessageFeed from "../../../common/hook/useMessageFeed"; import ChannelIcon from "../../../common/component/ChannelIcon"; import Layout from "../Layout"; import { renderMessageFragment } from "../utils"; -import { StyledChannelChat } from "./styled"; import LoadMore from "../LoadMore"; import { useAppSelector } from "../../../app/store"; -import { useTranslation } from "react-i18next"; + type Props = { cid?: number; }; @@ -43,19 +43,19 @@ export default function GuestChannelChat({ cid = 0 }: Props) {
    - {name} + {name} {description}
    } > - +
    {hasMore ? ( ) : ( -
    -

    {t("welcome_channel", { name })}

    -

    {t("welcome_desc", { name })}

    +
    +

    {t("welcome_channel", { name })}

    +

    {t("welcome_desc", { name })}

    )} {/*
    */} @@ -73,7 +73,7 @@ export default function GuestChannelChat({ cid = 0 }: Props) { context: "channel" }); })} - +
    ); diff --git a/src/routes/chat/GuestChannelChat/styled.tsx b/src/routes/chat/GuestChannelChat/styled.tsx deleted file mode 100644 index 063bc17b..00000000 --- a/src/routes/chat/GuestChannelChat/styled.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import styled from "styled-components"; -export const StyledChannelChat = styled.article` - padding: 18px 16px; - width: 100%; - height: 100%; - height: -webkit-fill-available; - overflow-x: hidden; - overflow-y: auto; - overflow-anchor: auto; - > .info { - padding-top: 62px; - display: flex; - flex-direction: column; - align-items: flex-start; - gap: 8px; - .title { - font-weight: bold; - font-size: 36px; - line-height: 44px; - } - .desc { - color: #78787c; - font-weight: 500; - font-size: 16px; - line-height: 24px; - } - } -`; diff --git a/src/routes/chat/GuestSessionList/Session.tsx b/src/routes/chat/GuestSessionList/Session.tsx index 7e9c2dd1..7fee9a3d 100644 --- a/src/routes/chat/GuestSessionList/Session.tsx +++ b/src/routes/chat/GuestSessionList/Session.tsx @@ -1,9 +1,9 @@ // @ts-nocheck import { useState, useEffect, FC } from "react"; import dayjs from "dayjs"; +import clsx from "clsx"; import { renderPreviewMessage } from "../../chat/utils"; import Avatar from "../../../common/component/Avatar"; -import IconLock from "../../../assets/icons/lock.svg"; import { NavLink } from "react-router-dom"; import { useAppSelector } from "../../../app/store"; @@ -35,25 +35,25 @@ const Session: FC = ({ id, mid }) => { }, [id, mid, userData, channelData]); if (!data) return null; const previewMsg = messageData[mid] || {}; - const { name, icon, is_public } = data; + const { name, icon } = data; return (
  • - -
    + clsx(`nav flex gap-2 rounded-lg p-2 w-full hover:bg-gray-500/20`, linkActive && "bg-gray-500/20")} to={`/chat/channel/${id}`}> +
    -
    -
    - - {name} {!is_public && } +
    +
    + + {name} - + {previewMsg.created_at ? dayjs(previewMsg.created_at).fromNow() : null}
    -
    - {renderPreviewMessage(previewMsg)} +
    + {renderPreviewMessage(previewMsg)}
    diff --git a/src/routes/chat/GuestSessionList/index.tsx b/src/routes/chat/GuestSessionList/index.tsx index c585d58f..42a11b06 100644 --- a/src/routes/chat/GuestSessionList/index.tsx +++ b/src/routes/chat/GuestSessionList/index.tsx @@ -1,6 +1,5 @@ import { FC } from "react"; import { useState, useEffect } from "react"; -import Styled from "./styled"; import Session from "./Session"; import { useAppSelector } from "../../../app/store"; export interface ChatSession { @@ -41,12 +40,12 @@ const SessionList: FC = () => { }, [channelIDs, channelMessage, readChannels, readUsers, loginUid, userMessage]); return ( - +
      {sessions.map((s) => { const { key, id, mid = 0 } = s; return ; })} - +
    ); }; export default SessionList; diff --git a/src/routes/chat/GuestSessionList/styled.tsx b/src/routes/chat/GuestSessionList/styled.tsx deleted file mode 100644 index b4b9b5f3..00000000 --- a/src/routes/chat/GuestSessionList/styled.tsx +++ /dev/null @@ -1,86 +0,0 @@ -import styled from "styled-components"; -const Styled = styled.ul` - display: flex; - flex-direction: column; - gap: 2px; - padding: 8px; - height: calc(100vh - 56px - 16px - 8px); - overflow: auto; - > .session { - > a { - display: flex; - gap: 8px; - border-radius: 8px; - padding: 8px; - width: 100%; - &.active, - &:hover { - background: rgba(116, 127, 141, 0.2); - } - .icon { - display: flex; - background-color: #eee; - border-radius: 50%; - img { - max-width: unset; - width: 40px; - height: 40px; - &.channel_default { - padding: 5px; - } - } - } - .details { - width: 100%; - display: flex; - flex-direction: column; - justify-content: space-between; - .up { - display: flex; - align-items: center; - justify-content: space-between; - .name { - font-weight: 600; - font-size: 14px; - line-height: 20px; - color: #52525b; - max-width: 112px; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - &.only_title { - max-width: 190px; - } - } - .time { - font-weight: 500; - font-size: 12px; - line-height: 18px; - color: #78787c; - white-space: nowrap; - overflow: hidden; - max-width: 80px; - text-overflow: ellipsis; - } - } - .down { - display: flex; - align-items: center; - justify-content: space-between; - > .msg { - font-weight: 400; - font-size: 12px; - line-height: 18px; - color: #78787c; - white-space: nowrap; - overflow: hidden; - width: 140px; - text-overflow: ellipsis; - } - } - } - } - } -`; - -export default Styled; diff --git a/src/routes/chat/Layout/LoginTip.tsx b/src/routes/chat/Layout/LoginTip.tsx index 3bad810b..778b5fbb 100644 --- a/src/routes/chat/Layout/LoginTip.tsx +++ b/src/routes/chat/Layout/LoginTip.tsx @@ -20,8 +20,8 @@ const LoginTip = () => { }; return ( -
    - +
    + 👋 {t("sign_in_tip")} diff --git a/src/routes/chat/Layout/styled.tsx b/src/routes/chat/Layout/styled.tsx index 0df32d43..ac77cb5b 100644 --- a/src/routes/chat/Layout/styled.tsx +++ b/src/routes/chat/Layout/styled.tsx @@ -2,7 +2,6 @@ import styled from "styled-components"; const Styled = styled.article` position: relative; width: 100%; - background: #fff; border-top-right-radius: 16px; border-bottom-right-radius: 16px; > .head { @@ -21,7 +20,6 @@ const Styled = styled.article` > .chat { border-bottom-right-radius: 16px; width: 100%; - background-color: #fff; display: flex; flex-direction: column; padding: 0; diff --git a/src/routes/chat/SessionList/Session.tsx b/src/routes/chat/SessionList/Session.tsx index b766d187..53ba11cd 100644 --- a/src/routes/chat/SessionList/Session.tsx +++ b/src/routes/chat/SessionList/Session.tsx @@ -1,15 +1,16 @@ // @ts-nocheck import { useState, useEffect, FC } from "react"; +import clsx from "clsx"; import dayjs from "dayjs"; import { useDrop } from "react-dnd"; import { NativeTypes } from "react-dnd-html5-backend"; +import { useNavigate, NavLink } from "react-router-dom"; import ContextMenu from "./ContextMenu"; import getUnreadCount, { renderPreviewMessage } from "../utils"; import User from "../../../common/component/User"; import Avatar from "../../../common/component/Avatar"; 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"; import { useAppSelector } from "../../../app/store"; @@ -95,7 +96,6 @@ const Session: FC = ({ messageData, loginUid }); - return (
  • = ({ > clsx(`nav flex gap-2 rounded-lg p-2 w-full hover:bg-gray-500/20`, isActive && "shadow-[inset_0_0_0_2px_#52edff]", linkActive && "bg-gray-500/20")} to={type == "user" ? `/chat/dm/${id}` : `/chat/channel/${id}`} onContextMenu={handleContextMenuEvent} > -
    +
    {type == "user" ? ( ) : ( @@ -127,21 +127,21 @@ const Session: FC = ({ /> )}
    -
    -
    - +
    +
    + {name} {!is_public && } - + {previewMsg.created_at ? dayjs(previewMsg.created_at).fromNow() : null}
    -
    - {renderPreviewMessage(previewMsg)} +
    + {renderPreviewMessage(previewMsg)} {unreads > 0 && ( - 99 ? "dot" : ""}`}> + 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/SessionList/index.tsx b/src/routes/chat/SessionList/index.tsx index 783b2ab8..bae217b4 100644 --- a/src/routes/chat/SessionList/index.tsx +++ b/src/routes/chat/SessionList/index.tsx @@ -1,6 +1,5 @@ import { FC } from "react"; import { useState, useEffect } from "react"; -import Styled from "./styled"; import Session from "./Session"; import DeleteChannelConfirmModal from "../../settingChannel/DeleteConfirmModal"; import InviteModal from "../../../common/component/InviteModal"; @@ -65,10 +64,9 @@ const SessionList: FC = ({ tempSession }) => { userMessage, tempSession ]); - return ( <> - +
      {sessions.map((s) => { const { key, type, id, mid = 0 } = s; return ( @@ -82,7 +80,7 @@ const SessionList: FC = ({ tempSession }) => { /> ); })} - +
    {!!deleteId && ( .session { - > a { - display: flex; - gap: 8px; - border-radius: 8px; - padding: 8px; - width: 100%; - &.active, - &:hover { - background: rgba(116, 127, 141, 0.2); - } - &.drop_over { - box-shadow: inset 0 0 0 2px #52edff; - } - .icon { - display: flex; - background-color: #eee; - border-radius: 50%; - img { - max-width: unset; - width: 40px; - height: 40px; - &.channel_default { - padding: 5px; - } - } - } - .details { - width: 100%; - display: flex; - flex-direction: column; - justify-content: space-between; - .up { - display: flex; - align-items: center; - justify-content: space-between; - .name { - display: flex; - align-items: center; - gap: 2px; - font-weight: 600; - font-size: 14px; - line-height: 20px; - color: #52525b; - max-width: 112px; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - &.only_title { - max-width: 190px; - } - } - .time { - font-weight: 500; - font-size: 12px; - line-height: 18px; - color: #78787c; - white-space: nowrap; - overflow: hidden; - max-width: 80px; - text-overflow: ellipsis; - } - } - .down { - display: flex; - align-items: center; - justify-content: space-between; - > .msg { - font-weight: 400; - 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; - } - } - } - } - &.muted { - .up .name, - .up .time, - .down .msg { - color: #d0d5dd; - } - .down .badge { - background: #bfbfbf; - } - } - } - } -`; - -export default Styled; diff --git a/src/routes/chat/index.tsx b/src/routes/chat/index.tsx index 32385a39..59542868 100644 --- a/src/routes/chat/index.tsx +++ b/src/routes/chat/index.tsx @@ -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'; +// import IconClose from '../../assets/icons/close.svg'; function ChatPage() { const [sessionListVisible, setSessionListVisible] = useState(false); const [channelModalVisible, setChannelModalVisible] = useState(false); @@ -52,16 +52,16 @@ function ChatPage() { )} {usersModalVisible && } - + {sessionListVisible &&
    } -
    +
    {isGuest ? : } {sessionListVisible ? null : }
    -
    +
    {placeholderVisible && (isGuest ? : )} {channel_id !== 0 && (isGuest ? ( diff --git a/src/routes/chat/styled.tsx b/src/routes/chat/styled.tsx index 3d116a7f..c775fd38 100644 --- a/src/routes/chat/styled.tsx +++ b/src/routes/chat/styled.tsx @@ -6,14 +6,10 @@ const StyledWrapper = styled.div` padding-bottom: 10px; padding-right: 4px; > .left { - background-color: #fff; - position: relative; - /* display: flex; */ flex-direction: column; min-width: 268px; box-shadow: inset -1px 0px 0px rgba(0, 0, 0, 0.05); height: 100%; - /* overflow: auto; */ border-radius: 16px 0 0 16px; .list { margin: 12px 8px; @@ -149,7 +145,6 @@ const StyledWrapper = styled.div` border-radius: 0 16px 16px 0; width: 100%; &.placeholder { - background-color: #fff; height: 100%; display: flex; align-items: center; diff --git a/src/routes/favs/index.tsx b/src/routes/favs/index.tsx index 0862157e..b1a74b53 100644 --- a/src/routes/favs/index.tsx +++ b/src/routes/favs/index.tsx @@ -118,7 +118,7 @@ function FavsPage() { removeFavorite(id); }; return ( -
    +
      {Filters.map(({ icon, title, filter: f }) => { @@ -129,7 +129,7 @@ function FavsPage() { onClick={handleFilter.bind(null, f as filter)} > {icon} - {title} + {title} ); })} diff --git a/src/routes/home/Menu.tsx b/src/routes/home/Menu.tsx index 23a95b7e..36cf5d3a 100644 --- a/src/routes/home/Menu.tsx +++ b/src/routes/home/Menu.tsx @@ -2,36 +2,19 @@ import { FC } from "react"; import { NavLink, useLocation } from "react-router-dom"; import Tooltip from "../../common/component/Tooltip"; import settingIcon from "../../assets/icons/setting.svg?url"; -import styled from "styled-components"; -const StyledMenus = styled.ul` - display: flex; - flex-direction: column; - position: absolute; - left: 0; - bottom: 0; - width: 100%; - padding: 8px 12px; - .menu { - cursor: pointer; - display: flex; - align-items: center; - padding: 10px; - gap: 10px; - } -`; type Props = {}; const Menu: FC = () => { const { pathname } = useLocation(); return ( - -
    • +
        +
      • setting icon
      • - +
      ); }; export default Menu; diff --git a/src/routes/home/index.tsx b/src/routes/home/index.tsx index 41d3ce5d..58447a76 100644 --- a/src/routes/home/index.tsx +++ b/src/routes/home/index.tsx @@ -57,7 +57,7 @@ function HomePage() { <> {!guest && } - + {!guest && (
      {loginUid && } diff --git a/src/routes/invite/index.tsx b/src/routes/invite/index.tsx index 0d35fce7..5545883d 100644 --- a/src/routes/invite/index.tsx +++ b/src/routes/invite/index.tsx @@ -1,11 +1,12 @@ import { useState, useEffect, FormEvent, ChangeEvent, FC } from "react"; -import StyledWrapper from "./styled"; import { Navigate } from "react-router-dom"; import toast from "react-hot-toast"; import BASE_URL from "../../app/config"; import { useRegisterMutation } from "../../app/services/auth"; import { useCheckMagicTokenValidMutation } from "../../app/services/auth"; import { useAppSelector } from "../../app/store"; +import StyledButton from "../../common/component/styled/Button"; +import Input from "../../common/component/styled/Input"; interface AuthForm { name: string; @@ -117,15 +118,16 @@ const InvitePage: FC = () => { if (!valid) return <>invite token expires or invalid; return ( - -
      -
      - logo -

      Sign Up to VoceChat

      - Please enter your details. +
      +
      +
      + logo +

      Sign Up to VoceChat

      + Please enter your details.
      - - + { data-type="name" onChange={handleInput} /> - { data-type="email" onChange={handleInput} /> - { onChange={handleInput} placeholder="Enter your password" /> - { onChange={handleSecondPwdInput} placeholder="Enter your password again" /> - +
      - +
      ); }; diff --git a/src/routes/invite/styled.tsx b/src/routes/invite/styled.tsx deleted file mode 100644 index a435f662..00000000 --- a/src/routes/invite/styled.tsx +++ /dev/null @@ -1,74 +0,0 @@ -import styled from "styled-components"; -const StyledWrapper = styled.div` - display: flex; - justify-content: center; - align-items: center; - height: 100vh; - .form { - padding: 36px 40px 32px 40px; - box-shadow: 0px 4px 8px -2px rgba(16, 24, 40, 0.1), 0px 2px 4px -2px rgba(16, 24, 40, 0.06); - border-radius: 12px; - .tips { - display: flex; - flex-direction: column; - align-items: center; - padding-bottom: 24px; - .logo { - width: 56px; - height: 56px; - margin-bottom: 28px; - } - .title { - font-weight: 600; - font-size: 24px; - line-height: 32px; - color: #101828; - margin-bottom: 8px; - } - } - .desc { - font-weight: normal; - font-size: 16px; - line-height: 24px; - color: #667085; - } - form { - display: flex; - flex-direction: column; - gap: 20px; - input { - width: 360px; - background: #ffffff; - border: 1px solid #d0d5dd; - box-shadow: 0px 1px 2px rgba(16, 24, 40, 0.05); - border-radius: 8px; - padding: 10px 14px; - font-weight: normal; - font-size: 16px; - line-height: 24px; - color: #667085; - } - } - .btn { - display: inline-block; - text-align: center; - width: 100%; - font-weight: 500; - font-size: 16px; - line-height: 24px; - color: #ffffff; - padding: 10px; - background: #1fe1f9; - border: 1px solid #1fe1f9; - box-shadow: 0px 1px 2px rgba(16, 24, 40, 0.05); - border-radius: 8px; - &.google { - color: #344054; - border-color: #d0d5dd; - background: none; - } - } - } -`; - -export default StyledWrapper; diff --git a/src/routes/login/MagicLinkLogin.tsx b/src/routes/login/MagicLinkLogin.tsx index ebf9ab04..01b75185 100644 --- a/src/routes/login/MagicLinkLogin.tsx +++ b/src/routes/login/MagicLinkLogin.tsx @@ -8,5 +8,5 @@ export default function MagicLinkLogin() { // signIn(); }; - return ; + return ; } diff --git a/src/routes/login/MetamaskLoginButton.tsx b/src/routes/login/MetamaskLoginButton.tsx index b06d0921..540903c9 100644 --- a/src/routes/login/MetamaskLoginButton.tsx +++ b/src/routes/login/MetamaskLoginButton.tsx @@ -3,11 +3,10 @@ import { useState, useEffect, useRef } from "react"; import MetaMaskOnboarding from "@metamask/onboarding"; import { useLazyGetMetamaskNonceQuery } from "../../app/services/auth"; import metamaskSvg from "../../assets/icons/metamask.svg?url"; -import { StyledSocialButton } from "./styled"; -import Onboarding from "@metamask/onboarding"; import { LoginCredential } from "../../types/auth"; import { useTranslation } from "react-i18next"; import { AuthType } from "../../types/common"; +import Button from "../../common/component/styled/Button"; // import toast from "react-hot-toast"; export default function MetamaskLoginButton({ @@ -21,7 +20,7 @@ export default function MetamaskLoginButton({ const [requesting, setRequesting] = useState(false); const [accounts, setAccounts] = useState([]); const [getNonce] = useLazyGetMetamaskNonceQuery(); - const onboarding = useRef(); + const onboarding = useRef(); useEffect(() => { if (!onboarding.current) { @@ -94,9 +93,9 @@ export default function MetamaskLoginButton({ } }; return ( - - meta mask icon + ); } diff --git a/src/routes/login/OidcLoginButton.tsx b/src/routes/login/OidcLoginButton.tsx index 19e5263f..88156dd2 100644 --- a/src/routes/login/OidcLoginButton.tsx +++ b/src/routes/login/OidcLoginButton.tsx @@ -1,68 +1,49 @@ /* eslint-disable no-undef */ import { FC, useState } from "react"; -import styled from "styled-components"; import StyledModal from "../../common/component/styled/Modal"; import Modal from "../../common/component/Modal"; -import { StyledSocialButton } from "./styled"; import StyledButton from "../../common/component/styled/Button"; import OidcLoginEntry from "./OidcLoginEntry"; import { OIDCConfig } from "../../types/auth"; import { useTranslation } from "react-i18next"; import { AuthType } from "../../types/common"; - -const StyledOidcLoginModal = styled(StyledModal)` - text-align: center; - padding: 32px 32px 16px; - - > *:first-child { - margin-bottom: 32px; - } - - > .button { - > .icon { - width: 24px; - height: 24px; - } - - &.buttonCancel { - color: #8f8f8f; - } - } -`; +import Button from "../../common/component/styled/Button"; interface IProps { issuers?: OIDCConfig[]; type?: AuthType } const OidcLoginButton: FC = ({ issuers, type = "login" }) => { const { t } = useTranslation("auth"); + const { t: ct } = useTranslation(); const [modal, setModal] = useState(false); if (!issuers) return null; return ( <> - { setModal(true); }} > {type == "login" ? t("login.oidc") : t("reg.oidc")} - + {modal && ( - + {issuers .filter((issuer) => issuer.enable) .map((issuer, index) => ( ))} { setModal(false); }} > - Close + {ct("action.close")} - + )} diff --git a/src/routes/login/OidcLoginEntry.tsx b/src/routes/login/OidcLoginEntry.tsx index 4f56a422..6a35fd93 100644 --- a/src/routes/login/OidcLoginEntry.tsx +++ b/src/routes/login/OidcLoginEntry.tsx @@ -1,7 +1,7 @@ import { useEffect, FC } from "react"; import { useGetOpenidMutation } from "../../app/services/auth"; +import Button from "../../common/component/styled/Button"; import { OIDCConfig } from "../../types/auth"; -import { StyledSocialButton } from "./styled"; const OidcLoginEntry: FC<{ issuer: OIDCConfig }> = ({ issuer }) => { const [getOpenId, { data, isLoading, isSuccess }] = useGetOpenidMutation(); @@ -21,10 +21,10 @@ const OidcLoginEntry: FC<{ issuer: OIDCConfig }> = ({ issuer }) => { }, [data, isSuccess]); return ( - - {!!issuer.favicon && icon} + ); }; export default OidcLoginEntry; diff --git a/src/routes/login/SignUpLink.tsx b/src/routes/login/SignUpLink.tsx index 9f2bf750..389d5b22 100644 --- a/src/routes/login/SignUpLink.tsx +++ b/src/routes/login/SignUpLink.tsx @@ -17,7 +17,7 @@ export default function MagicLinkLogin({ smtp = false }: Props) { }; return ( -
      +
      {t("login.no_account")} {t("sign_up")}
      diff --git a/src/routes/login/index.tsx b/src/routes/login/index.tsx index 384d81cc..324f4c0e 100644 --- a/src/routes/login/index.tsx +++ b/src/routes/login/index.tsx @@ -3,7 +3,6 @@ import { useState, useEffect, FormEvent, ChangeEvent } from "react"; import toast from "react-hot-toast"; import BASE_URL from "../../app/config"; // import web3 from "web3"; -import StyledWrapper from "./styled"; import Input from "../../common/component/styled/Input"; import Button from "../../common/component/styled/Button"; @@ -15,6 +14,7 @@ import useGoogleAuthConfig from "../../common/hook/useGoogleAuthConfig"; import { FetchBaseQueryError } from "@reduxjs/toolkit/dist/query"; import { useTranslation } from "react-i18next"; import SocialLoginButtons from "./SocialLoginButtons"; +import Divider from "../../common/component/Divider"; export default function LoginPage() { const { t } = useTranslation("auth"); @@ -122,15 +122,16 @@ export default function LoginPage() { const hasDivider = enableMagicLink || googleLogin || enableMetamaskLogin || oidc.length > 0 || enableGithubLogin; + return ( - -
      -
      - logo -

      {t("login.title")}

      - {t("login.desc")} +
      +
      +
      + logo +

      {t("login.title")}

      + {t("login.desc")}
      -
      +
      - {hasDivider &&
      } -
      + {hasDivider && } +
      {enableMagicLink && } @@ -164,6 +165,6 @@ export default function LoginPage() {
      {whoCanSignUp === "EveryOne" && }
      - +
      ); } diff --git a/src/routes/login/styled.tsx b/src/routes/login/styled.tsx deleted file mode 100644 index a88a5b4c..00000000 --- a/src/routes/login/styled.tsx +++ /dev/null @@ -1,88 +0,0 @@ -import styled from "styled-components"; -import Button from "../../common/component/styled/Button"; - -export const StyledSocialButton = styled(Button)` - width: 100%; - /* margin-bottom: 16px; */ - display: flex; - align-items: center; - justify-content: center; - gap: 12px; - color: #344054; - border: 1px solid #d0d5dd; - background: none !important; - .icon { - width: 24px; - height: 24px; - } -`; - -const StyledWrapper = styled.div` - display: flex; - justify-content: center; - align-items: center; - height: 100vh; - .form { - padding: 36px 40px 32px 40px; - box-shadow: 0px 4px 8px -2px rgba(16, 24, 40, 0.1), 0px 2px 4px -2px rgba(16, 24, 40, 0.06); - border-radius: 12px; - .tips { - display: flex; - flex-direction: column; - align-items: center; - padding-bottom: 24px; - .logo { - width: 56px; - height: 56px; - margin-bottom: 28px; - border-radius: 50%; - } - .title { - font-weight: 600; - font-size: 24px; - line-height: 32px; - color: #101828; - margin-bottom: 8px; - } - } - .desc { - font-weight: normal; - font-size: 16px; - line-height: 24px; - color: #667085; - } - form { - display: flex; - flex-direction: column; - gap: 20px; - width: 360px; - } - .or { - border: none; - position: relative; - height: 1px; - background-color: #e4e7ec; - margin: 26px 0; - overflow: visible; - &:after { - padding: 4px; - background-color: #fff; - content: "OR"; - position: absolute; - left: 50%; - top: 50%; - transform: translate3d(-50%, -50%, 0); - font-size: 14px; - line-height: 20px; - color: #667085; - } - } - >.btns{ - display: flex; - flex-direction: column; - gap: 15px; - } - } -`; - -export default StyledWrapper; diff --git a/src/routes/onboarding/steps/who-can-sign-up.tsx b/src/routes/onboarding/steps/who-can-sign-up.tsx index a56c2620..570586e2 100644 --- a/src/routes/onboarding/steps/who-can-sign-up.tsx +++ b/src/routes/onboarding/steps/who-can-sign-up.tsx @@ -1,6 +1,5 @@ import { useEffect, useState } from "react"; import toast from "react-hot-toast"; -import styled from "styled-components"; import StyledRadio from "../../../common/component/styled/Radio"; import StyledButton from "../../../common/component/styled/Button"; import { useGetLoginConfigQuery, useUpdateLoginConfigMutation } from "../../../app/services/server"; @@ -40,20 +39,9 @@ export default function SignUpSetting() { if (isSuccess) nextStep(); }, [isSuccess]); - const StyledWrapper = styled.div` - /* > form { - width: 512px; - } - - > .button { - width: 124px; - height: 44px; - margin-top: 24px; - } */ -`; return ( - +
      {t("onboarding.invite_title")} {t("onboarding.invite_desc")} {value && {t("onboarding.confirm")} - +
      ); } diff --git a/src/routes/reg/EmailNextStepTip.tsx b/src/routes/reg/EmailNextStepTip.tsx index 3caec27c..cb988704 100644 --- a/src/routes/reg/EmailNextStepTip.tsx +++ b/src/routes/reg/EmailNextStepTip.tsx @@ -2,9 +2,9 @@ export default function EmailNextTip() { return (
      -
      Magic link Sent
      -

      Login to your email client, and continue next step

      -

      You can close this window now.

      +
      Magic link Sent
      +

      Login to your email client, and continue next step

      +

      You can close this window now.

      ); } diff --git a/src/routes/reg/ExpiredTip.tsx b/src/routes/reg/ExpiredTip.tsx index 7a2d8ca7..7d595ba6 100644 --- a/src/routes/reg/ExpiredTip.tsx +++ b/src/routes/reg/ExpiredTip.tsx @@ -2,7 +2,7 @@ export default function ExpiredTip() { return (
      -
      Magic link expired
      +
      Magic link expired

      Go back to your original VoceChat tab and request a new magic link.

      You can close this window now.

      diff --git a/src/routes/reg/RegWithUsername.tsx b/src/routes/reg/RegWithUsername.tsx index fd9c5460..d1b526fc 100644 --- a/src/routes/reg/RegWithUsername.tsx +++ b/src/routes/reg/RegWithUsername.tsx @@ -98,14 +98,14 @@ const RegWithUsername: FC = () => { const isSuccess = loginSuccess || regSuccess; return ( <> -
      -

      What’s your name

      - +
      +

      What’s your name

      + Enter a name or handle so people know how you’d like to be called. Your name will only be visible to others in spaces you joined.
      -
      + -
      - logo -

      {t("reg.title")}

      - {t("reg.desc")} +
      + logo +

      {t("reg.title")}

      + {t("reg.desc")}
      - + -
      +
      diff --git a/src/routes/reg/SignInLink.tsx b/src/routes/reg/SignInLink.tsx index eb1a41ea..818b9fcf 100644 --- a/src/routes/reg/SignInLink.tsx +++ b/src/routes/reg/SignInLink.tsx @@ -17,7 +17,7 @@ export default function SignInLink({ token }: { token?: string }) { }, [token]); return ( -
      +
      {t("reg.have_account")} {t("sign_in")}
      diff --git a/src/routes/reg/index.tsx b/src/routes/reg/index.tsx index 5216c5b1..ad88225a 100644 --- a/src/routes/reg/index.tsx +++ b/src/routes/reg/index.tsx @@ -1,12 +1,11 @@ import { Outlet } from "react-router-dom"; -import StyledWrapper from "./styled"; export default function RegContainer() { return ( - -
      +
      +
      - +
      ); } diff --git a/src/routes/reg/styled.tsx b/src/routes/reg/styled.tsx deleted file mode 100644 index 0e57d0fe..00000000 --- a/src/routes/reg/styled.tsx +++ /dev/null @@ -1,71 +0,0 @@ -import styled from "styled-components"; - -const StyledWrapper = styled.div` - display: flex; - justify-content: center; - align-items: center; - height: 100vh; - .form { - max-width: 440px; - padding: 36px 40px 32px 40px; - box-shadow: 0 4px 8px -2px rgba(16, 24, 40, 0.1), 0px 2px 4px -2px rgba(16, 24, 40, 0.06); - border-radius: 12px; - .tips { - display: flex; - flex-direction: column; - align-items: center; - padding-bottom: 24px; - .logo { - width: 56px; - height: 56px; - margin-bottom: 28px; - border-radius: 50%; - } - .title { - font-weight: 600; - font-size: 24px; - line-height: 32px; - color: #101828; - margin-bottom: 8px; - &.error { - color: red; - } - } - .desc { - text-align: center; - font-weight: normal; - font-size: 16px; - line-height: 24px; - color: #667085; - } - } - form { - display: flex; - flex-direction: column; - gap: 20px; - width: 360px; - } - } - .or { - border: none; - position: relative; - height: 1px; - background-color: #e4e7ec; - margin: 26px 0; - overflow: visible; - &:after { - padding: 4px; - background-color: #fff; - content: "OR"; - position: absolute; - left: 50%; - top: 50%; - transform: translate3d(-50%, -50%, 0); - font-size: 14px; - line-height: 20px; - color: #667085; - } - } -`; - -export default StyledWrapper; diff --git a/src/routes/resources/Filter/Channel.tsx b/src/routes/resources/Filter/Channel.tsx index 9b2e6171..c1e93739 100644 --- a/src/routes/resources/Filter/Channel.tsx +++ b/src/routes/resources/Filter/Channel.tsx @@ -1,57 +1,9 @@ import { FC } from "react"; -import styled from "styled-components"; import CheckSign from "../../../assets/icons/check.sign.svg"; import ChannelIcon from "../../../common/component/ChannelIcon"; import Search from "../Search"; import useFilteredChannels from "../../../common/hook/useFilteredChannels"; -const Styled = styled.div` - padding: 0 4px 4px 4px; - background: #ffffff; - max-height: 400px; - overflow: auto; - box-shadow: 0 24px 48px -12px rgba(16, 24, 40, 0.18); - border-radius: 8px; - display: flex; - flex-direction: column; - align-items: flex-start; - position: relative; - > .search { - z-index: 1; - background-color: #fff; - position: sticky; - top: 0; - input { - z-index: 2; - } - } - > .list { - width: 100%; - display: flex; - flex-direction: column; - gap: 16px; - padding: 8px; - .channel { - position: relative; - cursor: pointer; - display: flex; - align-items: center; - gap: 8px; - .name { - color: #616161; - font-weight: 600; - font-size: 14px; - line-height: 20px; - } - .check { - position: absolute; - right: 0; - top: 50%; - transform: translateY(-50%); - } - } - } -`; type Props = { select: number; updateFilter: (param: { channel?: number }) => void; @@ -63,27 +15,27 @@ const Channel: FC = ({ select = 0, updateFilter }) => { }; return ( - -
      +
      +
      -
        -
      • +
          +
        • - Any Channel - {!select && } + Any Channel + {!select && }
        • {channels.map(({ gid, is_public, name }) => { return ( -
        • +
        • - {name} - {select == gid && } + {name} + {select == gid && }
        • ); })}
        - +
      ); }; export default Channel; diff --git a/src/routes/resources/Filter/Date.tsx b/src/routes/resources/Filter/Date.tsx index 6a0747ab..17d60167 100644 --- a/src/routes/resources/Filter/Date.tsx +++ b/src/routes/resources/Filter/Date.tsx @@ -1,42 +1,6 @@ import { FC } from "react"; -import styled from "styled-components"; import CheckSign from "../../../assets/icons/check.sign.svg"; -const Styled = styled.div` - padding: 12px; - background: #ffffff; - min-width: 200px; - overflow: auto; - box-shadow: 0px 24px 48px -12px rgba(16, 24, 40, 0.18); - border-radius: 8px; - display: flex; - flex-direction: column; - align-items: flex-start; - position: relative; - > .list { - width: 100%; - display: flex; - flex-direction: column; - gap: 16px; - .date { - position: relative; - cursor: pointer; - display: flex; - align-items: center; - gap: 16px; - color: #616161; - font-weight: 600; - font-size: 14px; - line-height: 20px; - .check { - position: absolute; - right: 0; - top: 50%; - transform: translateY(-50%); - } - } - } -`; export const Dates = { today: { @@ -66,22 +30,22 @@ const DateFilter: FC = ({ select = "", updateFilter }) => { }; return ( - -
        -
      • +
        +
          +
        • Any Time - {!select && } + {!select && }
        • {Object.entries(Dates).map(([_key, { title }]) => { return ( -
        • +
        • {title} - {select == _key && } + {select == _key && }
        • ); })}
        - +
        ); }; export default DateFilter; diff --git a/src/routes/resources/Filter/From.tsx b/src/routes/resources/Filter/From.tsx index 57909dc6..c61c2312 100644 --- a/src/routes/resources/Filter/From.tsx +++ b/src/routes/resources/Filter/From.tsx @@ -1,53 +1,9 @@ import { FC } from "react"; -import styled from "styled-components"; import Search from "../Search"; import CheckSign from "../../../assets/icons/check.sign.svg"; import User from "../../../common/component/User"; import useFilteredUsers from "../../../common/hook/useFilteredUsers"; -const Styled = styled.div` - padding: 0 4px 4px 4px; - background: #ffffff; - max-height: 300px; - overflow: auto; - box-shadow: 0 24px 48px -12px rgba(16, 24, 40, 0.18); - border-radius: 8px; - display: flex; - flex-direction: column; - align-items: flex-start; - position: relative; - > .search { - z-index: 1; - background-color: #fff; - position: sticky; - top: 0; - input { - z-index: 2; - } - } - > .list { - width: 100%; - display: flex; - flex-direction: column; - .user { - position: relative; - cursor: pointer; - &.none { - padding: 10px; - font-weight: 600; - font-size: 14px; - line-height: 20px; - color: #616161; - } - .check { - position: absolute; - right: 6px; - top: 50%; - transform: translateY(-50%); - } - } - } -`; type Props = { select: number; updateFilter: (param: { from?: number }) => void; @@ -59,25 +15,25 @@ const From: FC = ({ select = "", updateFilter }) => { }; return ( - -
        +
        +
        -
          -
        • +
            +
          • Anyone - {!select && } + {!select && }
          • {users.map(({ uid }) => { return ( -
          • +
          • - {select == uid && } + {select == uid && }
          • ); })}
          - +
        ); }; export default From; diff --git a/src/routes/resources/Filter/Type.tsx b/src/routes/resources/Filter/Type.tsx index 269337ce..a5007ac3 100644 --- a/src/routes/resources/Filter/Type.tsx +++ b/src/routes/resources/Filter/Type.tsx @@ -48,17 +48,17 @@ const Type: FC = ({ select = "", updateFilter }) => { }; return ( -
        +
          -
        • +
        • Any Type - {!select && } + {!select && }
        • {Object.entries(FileTypes).map(([type, { title, icon }]) => { return (
        • {icon} {title} - {select == type && } + {select == type && }
        • ); })} diff --git a/src/routes/resources/Filter/index.tsx b/src/routes/resources/Filter/index.tsx index 0cdd73e6..615396f3 100644 --- a/src/routes/resources/Filter/index.tsx +++ b/src/routes/resources/Filter/index.tsx @@ -1,5 +1,4 @@ import { useState } from "react"; -import styled from "styled-components"; import Tippy from "@tippyjs/react"; import Avatar from "../../../common/component/Avatar"; import FilterDate, { Dates } from "./Date"; @@ -9,41 +8,12 @@ import FilterType, { FileTypes } from "./Type"; import ArrowDown from "../../../assets/icons/arrow.down.svg"; import { useAppSelector } from "../../../app/store"; import { useTranslation } from "react-i18next"; +import clsx from "clsx"; -const Styled = styled.div` - /* padding: 20px 0; */ - display: flex; - align-items: center; - gap: 8px; - .filter { - cursor: pointer; - display: flex; - align-items: center; - gap: 8px; - border: 1px solid #d0d5dd; - box-sizing: border-box; - box-shadow: 0 1px 2px rgba(16, 24, 40, 0.05); - border-radius: var(--br); - padding: 7px 12px; - font-weight: 500; - font-size: 12px; - line-height: 18px; - &.selected { - border: none; - color: #fff; - background-color: #22ccee; - .arrow path { - stroke: #fff; - } - } - .avatar { - width: 16px; - height: 16px; - border-radius: 50%; - } - } -`; +const getClass = (selected: boolean) => { + return clsx(`cursor-pointer flex items-center gap-2 border border-solid box-border shadow rounded-lg py-2 px-3 text-xs`, selected && 'text-white bg-primary-400'); +}; export default function Filter({ filter, updateFilter }) { const { t } = useTranslation("file"); const [filtersVisible, setFiltersVisible] = useState({ @@ -79,8 +49,9 @@ export default function Filter({ filter, updateFilter }) { from: fromVisible } = filtersVisible; + return ( - +
          } >
          {from && ( @@ -115,7 +86,7 @@ export default function Filter({ filter, updateFilter }) { content={} >
          {channel ? `In ${channelMap[channel].name}` : t("channel")} @@ -130,7 +101,7 @@ export default function Filter({ filter, updateFilter }) { content={} >
          {type ? FileTypes[type].title : t("type")} @@ -145,13 +116,13 @@ export default function Filter({ filter, updateFilter }) { content={} >
          {date ? Dates[date].title : t("date")}
          - +
          ); } diff --git a/src/routes/resources/View.tsx b/src/routes/resources/View.tsx index dcfc279e..3c6351db 100644 --- a/src/routes/resources/View.tsx +++ b/src/routes/resources/View.tsx @@ -1,55 +1,30 @@ import { MouseEvent } from "react"; -import styled from "styled-components"; import { useDispatch } from "react-redux"; import { updateFileListView } from "../../app/slices/ui"; import IconList from "../../assets/icons/file.list.svg"; import IconGrid from "../../assets/icons/file.grid.svg"; +import clsx from "clsx"; -const Styled = styled.ul` - display: flex; - border: 1px solid #d0d5dd; - box-shadow: 0 1px 2px rgba(16, 24, 40, 0.05); - border-radius: 8px; - box-sizing: border-box; - - .view { - cursor: pointer; - padding: 8px; - box-sizing: border-box; - display: flex; - align-items: center; - justify-content: center; - } - &.item .item, - &.grid .grid { - border: 1px solid #52edff; - box-shadow: 0 1px 2px rgba(16, 24, 40, 0.05); - border-radius: 8px; - svg { - transition: all 0.2s ease; - path { - fill: #52edff; - } - } - } -`; - -export default function View({ view = "item" }) { +const getClass = (selected: boolean) => clsx(`cursor-pointer p-2 box-border flex-center`, selected && `border border-solid border-primary-400 shadow rounded-lg`); +type Props = { + view?: "item" | "grid" +} +export default function View({ view = "item" }: Props) { const dispatch = useDispatch(); const handleChangeView = (evt: MouseEvent) => { const { view: clickView } = evt.currentTarget.dataset; if (clickView == view) return; dispatch(updateFileListView(view == "item" ? "grid" : "item")); }; - + const isGrid = view == "grid"; return ( - -
        • - +
            +
          • +
          • -
          • - +
          • +
          • - +
          ); } diff --git a/src/routes/resources/index.tsx b/src/routes/resources/index.tsx index 209602bd..604c1767 100644 --- a/src/routes/resources/index.tsx +++ b/src/routes/resources/index.tsx @@ -82,7 +82,7 @@ function ResourceManagement({ fileMessages }) { }, [view, filter]); return ( -
          +
          diff --git a/src/routes/resources/styled.tsx b/src/routes/resources/styled.tsx deleted file mode 100644 index 4f12d58b..00000000 --- a/src/routes/resources/styled.tsx +++ /dev/null @@ -1,40 +0,0 @@ -import styled from "styled-components"; - -const Styled = styled.div` - height: 100vh; - overflow-y: scroll; - display: flex; - flex-direction: column; - align-items: flex-start; - background-color: #fff; - margin: 8px 24px 10px 0; - border-radius: 16px; - .opts { - padding: 20px 16px; - display: flex; - justify-content: space-between; - width: 100%; - } - > .list { - padding: 0 16px; - height: 100%; - overflow-y: scroll; - width: 100%; - display: flex; - &.item { - gap: 8px; - flex-direction: column; - } - &.grid { - flex-direction: row; - flex-wrap: wrap; - > .file_box { - flex-direction: column; - /* margin-right: 8px; */ - margin-bottom: 8px; - } - } - } -`; - -export default Styled; diff --git a/src/routes/setting/APIConfig.tsx b/src/routes/setting/APIConfig.tsx index 1d37afdd..800c5310 100644 --- a/src/routes/setting/APIConfig.tsx +++ b/src/routes/setting/APIConfig.tsx @@ -40,7 +40,7 @@ export default function APIConfig() { data-checked={thirdParty} />
          - +
          { }; return (
          -
          +
          {t("api_doc.desc")}
          -

          +

          {t("api_doc.use_method")}

          -

          +

          👉 {t("api_doc.step_1")}

          {/*
          */} @@ -39,8 +39,8 @@ const APIDocument = () => { {/*
          */}
          -

          - 👉 {t("api_doc.step_2")} +

          + 👉 {t("api_doc.step_2")} ({t("api_doc.step_2_desc")})

          @@ -53,7 +53,7 @@ const APIDocument = () => { step 2

          -

          +

          👉 {t("api_doc.last")}

          step 3 diff --git a/src/routes/setting/BotConfig/BotAPIKeys.tsx b/src/routes/setting/BotConfig/BotAPIKeys.tsx index f1e25709..7130d86f 100644 --- a/src/routes/setting/BotConfig/BotAPIKeys.tsx +++ b/src/routes/setting/BotConfig/BotAPIKeys.tsx @@ -21,7 +21,7 @@ type Props = { // ; // }; type DeleteAPIKeyProps = { uid: number, kid: number } -const tdClass = "p-1 whitespace-nowrap text-xs text-gray-500 align-middle px-1"; +const tdClass = "p-1 whitespace-nowrap text-xs text-gray-500 dark:text-gray-200 align-middle px-1"; const BotAPIKeys = ({ uid }: Props) => { const { t } = useTranslation("setting", { keyPrefix: "bot" }); const [currentUid, setCurrentUid] = useState(); @@ -39,11 +39,11 @@ const BotAPIKeys = ({ uid }: Props) => { const colWidths = ["w-20", "w-[166px]", "w-36", "w-15", "w-10"]; return (
          -
          +
          - {[t("col_key_name"), t('col_key_value'), t('col_key_create_time'), t('col_key_last_used'), ""].map((title, idx) => )} diff --git a/src/routes/setting/BotConfig/CreateModal.tsx b/src/routes/setting/BotConfig/CreateModal.tsx index 83c124b4..98b65b44 100644 --- a/src/routes/setting/BotConfig/CreateModal.tsx +++ b/src/routes/setting/BotConfig/CreateModal.tsx @@ -77,12 +77,12 @@ const CreateModal = ({ closeModal }: Props) => { } > - -
          + +
          -
          +
          diff --git a/src/routes/setting/BotConfig/WebhookEdit.tsx b/src/routes/setting/BotConfig/WebhookEdit.tsx index ea66e512..170dd0ac 100644 --- a/src/routes/setting/BotConfig/WebhookEdit.tsx +++ b/src/routes/setting/BotConfig/WebhookEdit.tsx @@ -72,7 +72,7 @@ const WebhookEdit = ({ uid }: Props) => { evt.preventDefault(); handleEdit(); }}> - +
          -

          +

          {t("manage")} 🔗 {t("how_to_use")}

          -

          {t("manage_desc")}

          +

          {t("manage_desc")}

          + {[t("col_key_name"), t('col_key_value'), t('col_key_create_time'), t('col_key_last_used'), ""].map((title, idx) => {title}
          - + - {[t("col_avatar"), t('col_name'), t('col_api_key'), t('col_webhook'), t('col_opt')].map(title => )} @@ -85,10 +85,9 @@ export default function BotConfig() { {bots.map(bot => { const { uid, name, avatar } = bot; - return + return
          + {[t("col_avatar"), t('col_name'), t('col_api_key'), t('col_webhook'), t('col_opt')].map(title => {title}
          -
          diff --git a/src/routes/setting/License/index.tsx b/src/routes/setting/License/index.tsx index fcf4b3d8..ba2efaf8 100644 --- a/src/routes/setting/License/index.tsx +++ b/src/routes/setting/License/index.tsx @@ -13,7 +13,7 @@ const Item = ({ label, data, foldable = false, ...rest }: ItemProps) => { const infoClass = clsx("font-bold w-full cursor-pointer", foldable ? " overflow-hidden text-ellipsis" : "whitespace-pre-wrap break-all"); if (!data) return null; return
          - {label} + {label} {Array.isArray(data) ?
            {data.map((d) => { return
          • {d}
          • ; diff --git a/src/routes/setting/MyAccount.tsx b/src/routes/setting/MyAccount.tsx index ebb42bf8..b5c2b539 100644 --- a/src/routes/setting/MyAccount.tsx +++ b/src/routes/setting/MyAccount.tsx @@ -61,16 +61,16 @@ export default function MyAccount() { return ( <>
            -
            +
            -
            +
            {name} #{uid}
            -
            +
            {t("username")} - {name} #{uid} + {name} #{uid}
            -
            +
            {t("email")} {email}
            @@ -87,7 +87,7 @@ export default function MyAccount() {
            -
            +
            {t("password")} *********
            diff --git a/src/routes/setting/Overview/DarkMode.tsx b/src/routes/setting/Overview/DarkMode.tsx new file mode 100644 index 00000000..a3630234 --- /dev/null +++ b/src/routes/setting/Overview/DarkMode.tsx @@ -0,0 +1,43 @@ +import { useState } from 'react'; +import { useTranslation } from 'react-i18next'; +import Radio from '../../../common/component/styled/Radio'; +import { Theme } from '../../../types/common'; + +// type Props = {} + +const DarkMode = () => { + const [theme, setTheme] = useState(localStorage.theme || "auto"); + const { t } = useTranslation("setting"); + const handleThemeToggle = (v: Theme) => { + setTheme(v); + localStorage.theme = v; + // reset + document.documentElement.classList.remove("dark"); + document.documentElement.classList.remove("light"); + if (v !== "auto") { + document.documentElement.classList.add(v); + } else { + const isDark = window.matchMedia('(prefers-color-scheme: dark)').matches; + document.documentElement.classList.add(isDark ? "dark" : 'light'); + + } + }; + return ( +
            +

            {t("overview.theme.title")}

            +

            + {t("overview.theme.desc")} +

            + { + handleThemeToggle(v); + }} + /> +
            + ); +}; + +export default DarkMode; \ No newline at end of file diff --git a/src/routes/setting/Overview/FrontendURL.tsx b/src/routes/setting/Overview/FrontendURL.tsx index 4a6f04a3..707b6467 100644 --- a/src/routes/setting/Overview/FrontendURL.tsx +++ b/src/routes/setting/Overview/FrontendURL.tsx @@ -33,12 +33,11 @@ const Index = () => { // if(!fetch) return (
            -

            {t("overview.url.title")}

            +

            {t("overview.url.title")}

            {t("overview.url.desc")}

            - {ct("action.update")}
            diff --git a/src/routes/setting/Overview/index.tsx b/src/routes/setting/Overview/index.tsx index b58ac397..25194828 100644 --- a/src/routes/setting/Overview/index.tsx +++ b/src/routes/setting/Overview/index.tsx @@ -7,6 +7,7 @@ import useConfig from "../../../common/hook/useConfig"; import Server from './server'; import Language from './Language'; import FrontendURL from "./FrontendURL"; +// import DarkMode from "./DarkMode"; import ServerVersionChecker from "../../../common/component/ServerVersionChecker"; export default function Overview() { @@ -33,7 +34,7 @@ export default function Overview() { {isAdmin && ( <>
            -

            {t("overview.sign_up.title")}

            +

            {t("overview.sign_up.title")}

            {t("overview.sign_up.desc")}

            -

            {t("overview.guest_mode.title")}

            +

            {t("overview.guest_mode.title")}

            {t("overview.guest_mode.desc")} @@ -66,6 +67,7 @@ export default function Overview() { )} + {/* */}

            ); } diff --git a/src/routes/setting/Overview/language.tsx b/src/routes/setting/Overview/language.tsx index fde8c6f4..8a58453f 100644 --- a/src/routes/setting/Overview/language.tsx +++ b/src/routes/setting/Overview/language.tsx @@ -11,7 +11,7 @@ const Index = () => { }; return (
            -

            {t("overview.lang.title")}

            +

            {t("overview.lang.title")}

            {t("overview.lang.desc")}

            diff --git a/src/routes/setting/Overview/server.tsx b/src/routes/setting/Overview/server.tsx index 0ca67d62..86c6b3a2 100644 --- a/src/routes/setting/Overview/server.tsx +++ b/src/routes/setting/Overview/server.tsx @@ -72,7 +72,7 @@ const Index = () => {
            {isAdmin && (
            -
            +
            {t("overview.upload_desc")}
            @@ -80,7 +80,7 @@ const Index = () => {
            - + { />
            - +