From 02d928c4cd301ff88aa9a83aae169af6ea77ece7 Mon Sep 17 00:00:00 2001 From: zerosoul Date: Sat, 7 May 2022 12:24:01 +0800 Subject: [PATCH] refactor: invite modal --- src/common/component/BlankPlaceholder.js | 4 +- .../AddMembers.js | 0 .../InviteByEmail.js | 0 .../index.js | 14 +- .../ServerInviteModal/InviteByEmail.js | 123 ------ .../component/ServerInviteModal/index.js | 44 --- src/routes/chat/ChannelChat/index.js | 4 +- src/routes/chat/ChannelList/NavItem.js | 364 +++++++++--------- 8 files changed, 202 insertions(+), 351 deletions(-) rename src/common/component/{ChannelInviteModal => InviteModal}/AddMembers.js (100%) rename src/common/component/{ChannelInviteModal => InviteModal}/InviteByEmail.js (100%) rename src/common/component/{ChannelInviteModal => InviteModal}/index.js (76%) delete mode 100644 src/common/component/ServerInviteModal/InviteByEmail.js delete mode 100644 src/common/component/ServerInviteModal/index.js diff --git a/src/common/component/BlankPlaceholder.js b/src/common/component/BlankPlaceholder.js index 5541cf32..a4ce4947 100644 --- a/src/common/component/BlankPlaceholder.js +++ b/src/common/component/BlankPlaceholder.js @@ -1,7 +1,7 @@ import { useState } from "react"; import styled from "styled-components"; import ChannelModal from "../component/ChannelModal"; -import ServerInviteModal from "../component/ServerInviteModal"; +import InviteModal from "../component/InviteModal"; import IconChat from "../../assets/icons/placeholder.chat.svg"; import IconAsk from "../../assets/icons/placeholder.question.svg"; import IconInvite from "../../assets/icons/placeholder.invite.svg"; @@ -121,7 +121,7 @@ export default function BlankPlaceholder({ type = "chat" }) { )} {inviteModalVisible && ( - + )} ); diff --git a/src/common/component/ChannelInviteModal/AddMembers.js b/src/common/component/InviteModal/AddMembers.js similarity index 100% rename from src/common/component/ChannelInviteModal/AddMembers.js rename to src/common/component/InviteModal/AddMembers.js diff --git a/src/common/component/ChannelInviteModal/InviteByEmail.js b/src/common/component/InviteModal/InviteByEmail.js similarity index 100% rename from src/common/component/ChannelInviteModal/InviteByEmail.js rename to src/common/component/InviteModal/InviteByEmail.js diff --git a/src/common/component/ChannelInviteModal/index.js b/src/common/component/InviteModal/index.js similarity index 76% rename from src/common/component/ChannelInviteModal/index.js rename to src/common/component/InviteModal/index.js index 1971a12c..344709cd 100644 --- a/src/common/component/ChannelInviteModal/index.js +++ b/src/common/component/InviteModal/index.js @@ -27,28 +27,32 @@ const Styled = styled.div` } `; import Modal from "../Modal"; -export default function ChannelInviteModal({ +// type: server,channel +export default function InviteModal({ + type = "server", cid = null, title = "", closeModal, }) { - const { channel } = useSelector((store) => { + const { channel, server } = useSelector((store) => { return { channel: store.channels.byId[cid], + server: store.server, }; }); - if (!cid) return null; + const finalTitle = + type == "server" ? server.name : `#${title || channel?.name}`; return (

- Add friends to #{title || channel?.name}{" "} + Add friends to {finalTitle}

{!channel?.is_public && ( )} - +
); diff --git a/src/common/component/ServerInviteModal/InviteByEmail.js b/src/common/component/ServerInviteModal/InviteByEmail.js deleted file mode 100644 index 04e3ad4e..00000000 --- a/src/common/component/ServerInviteModal/InviteByEmail.js +++ /dev/null @@ -1,123 +0,0 @@ -import { useEffect } from "react"; -import toast from "react-hot-toast"; -import styled from "styled-components"; -import useInviteLink from "../../hook/useInviteLink"; -const Styled = styled.div` - padding: 16px 0; - .input { - position: relative; - display: flex; - align-items: center; - gap: 8px; - > .copy { - position: absolute; - right: 4px; - top: 50%; - transform: translateY(-50%); - padding-right: 8px; - background: none; - font-weight: 500; - font-size: 14px; - line-height: 20px; - color: #22ccee; - &:hover { - color: #088ab2; - } - } - input { - padding-right: 80px; - &.invite { - padding-right: 50px; - } - } - } - > .invite { - display: flex; - flex-direction: column; - gap: 16px; - margin-bottom: 16px; - /* position: relative; */ - } - > .link { - display: flex; - flex-direction: column; - gap: 8px; - margin-bottom: 12px; - /* position: relative; */ - } - label { - color: #6b7280; - font-style: normal; - font-weight: 500; - font-size: 14px; - line-height: 20px; - } - > .tip { - color: #344054; - font-weight: 400; - font-size: 12px; - line-height: 18px; - button { - background: none; - border: none; - color: #22ccee; - } - } -`; -import Button from "../styled/Button"; -import Input from "../styled/Input"; -export default function InviteByEmail() { - const { - enableSMTP, - linkCopied, - link, - copyLink, - generateNewLink, - generating, - } = useInviteLink(); - useEffect(() => { - if (linkCopied) { - toast.success("Invite Link Copied!"); - } - }, [linkCopied]); - - return ( - -
- -
- - -
-
-
- -
- - -
-
-
- Invite link expires in 7 days.{" "} - -
-
- ); -} diff --git a/src/common/component/ServerInviteModal/index.js b/src/common/component/ServerInviteModal/index.js deleted file mode 100644 index 8115d8f5..00000000 --- a/src/common/component/ServerInviteModal/index.js +++ /dev/null @@ -1,44 +0,0 @@ -// import React from 'react' -import styled from "styled-components"; -import { useSelector } from "react-redux"; -import InviteByEmail from "./InviteByEmail"; -import CloseIcon from "../../../assets/icons/close.svg"; -const Styled = styled.div` - display: flex; - flex-direction: column; - background: #fff; - box-shadow: 0px 25px 50px rgba(31, 41, 55, 0.25); - border-radius: var(--br); - padding: 16px; - min-width: 408px; - > .title { - display: flex; - align-items: center; - justify-content: space-between; - font-style: normal; - font-weight: 600; - font-size: 18px; - line-height: 28px; - color: #374151; - .close { - cursor: pointer; - } - } -`; -import Modal from "../Modal"; -export default function ServerInviteModal({ closeModal }) { - const server = useSelector((store) => { - return store.server; - }); - return ( - - -

- Invite friends to {server.name} - -

- -
-
- ); -} diff --git a/src/routes/chat/ChannelChat/index.js b/src/routes/chat/ChannelChat/index.js index ac9c78ba..98f27f36 100644 --- a/src/routes/chat/ChannelChat/index.js +++ b/src/routes/chat/ChannelChat/index.js @@ -26,7 +26,7 @@ import { StyledChannelChat, StyledHeader, } from "./styled"; -import ChannelInviteModal from "../../../common/component/ChannelInviteModal"; +import InviteModal from "../../../common/component/InviteModal"; import { NavLink, useLocation } from "react-router-dom"; import Tippy from "@tippyjs/react"; @@ -79,7 +79,7 @@ export default function ChannelChat({ cid = "", dropFiles = [] }) { return ( <> {addMemberModalVisible && ( - + )} { - const { pathname } = useLocation(); - const [inviteModalVisible, setInviteModalVisible] = useState(false); - const navigate = useNavigate(); - const [muteChannel] = useUpdateMuteSettingMutation(); - const [updateReadIndex] = useReadMessageMutation(); + 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, loginUser } = useSelector( - (store) => { - return { - loginUser: store.contacts.byId[store.authData.uid], - channel: store.channels.byId[id], - mids: store.channelMessage[id], - messageData: store.message, - loginUid: store.authData.uid, - readIndex: store.footprint.readChannels[id], - muted: store.footprint.muteChannels[id] - }; - } - ); - const handleChannelSetting = (evt) => { - evt.preventDefault(); - evt.stopPropagation(); - const { id } = evt.currentTarget.dataset; - if (id) { - navigate(`/setting/channel/${id}?f=${pathname}`); - } - }; - 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]; - console.log('last mid', mids, lastMid); - if (lastMid) { - const param = { groups: [{ gid: id, mid: lastMid }] }; - updateReadIndex(param); - } - }; - const toggleInviteModalVisible = (evt) => { - if (evt) { - evt.preventDefault(); - evt.stopPropagation(); - } - setInviteModalVisible((prev) => !prev); - }; - const handleMute = () => { - const data = muted ? { remove_groups: [id] } : { add_groups: [{ gid: id }] }; - muteChannel(data); - }; - const { is_public, name, owner } = channel; - const { unreads = 0, mentions = [] } = getUnreadCount({ - mids, - messageData, - readIndex, - loginUid - }); - const isMentions = mentions.length !== 0; - const inviteIconVisible = loginUser?.is_admin || owner == loginUid; - return ( - <> - + const { + visible: contextMenuVisible, + offset, + handleContextMenuEvent, + hideContextMenu, + } = useContextMenu(); + const { + channel, + mids, + messageData, + readIndex, + muted, + loginUid, + // loginUser, + } = useSelector((store) => { + return { + // loginUser: store.contacts.byId[store.authData.uid], + channel: store.channels.byId[id], + mids: store.channelMessage[id], + messageData: store.message, + loginUid: store.authData.uid, + readIndex: store.footprint.readChannels[id], + muted: store.footprint.muteChannels[id], + }; + }); + const handleChannelSetting = (evt) => { + evt.preventDefault(); + evt.stopPropagation(); + const { id } = evt.currentTarget.dataset; + if (id) { + navigate(`/setting/channel/${id}?f=${pathname}`); } - > - -
- - {name} -
-
- {inviteIconVisible && ( - - - + }; + 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]; + console.log("last mid", mids, lastMid); + if (lastMid) { + const param = { groups: [{ gid: id, mid: lastMid }] }; + updateReadIndex(param); + } + }; + const toggleInviteModalVisible = (evt) => { + if (evt) { + evt.preventDefault(); + evt.stopPropagation(); + } + setInviteModalVisible((prev) => !prev); + }; + const handleMute = () => { + const data = muted + ? { remove_groups: [id] } + : { add_groups: [{ gid: id }] }; + muteChannel(data); + }; + 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 && ( + )} - - - - {unreads > 0 && ( - - {isMentions ? mentions.length : unreads} - - )} -
-
-
- {inviteModalVisible && ( - - )} - - ); + + ); }; export default NavItem;