diff --git a/src/common/component/Message/renderContent.js b/src/common/component/Message/renderContent.js
index cd9fb59d..da797ef9 100644
--- a/src/common/component/Message/renderContent.js
+++ b/src/common/component/Message/renderContent.js
@@ -51,7 +51,7 @@ const renderContent = ({
(match, idx) => {
console.log("match", match);
const uid = match.trim().slice(1);
- return
;
+ return
;
}
)}
{/* {content.replace(/\s{1}\@[1-9]+\s{1}/g,)} */}
diff --git a/src/common/component/Message/useMessageOperation.js b/src/common/component/Message/useMessageOperation.js
index 0a4af20b..b9ee9c7f 100644
--- a/src/common/component/Message/useMessageOperation.js
+++ b/src/common/component/Message/useMessageOperation.js
@@ -9,7 +9,7 @@ import useCopy from "../../hook/useCopy";
import usePinMessage from "../../hook/usePinMessage";
export default function useMessageOperation({ mid, context, contextId }) {
- const [copied, copy] = useCopy();
+ const { copy } = useCopy();
const { content_type, properties, currUid, from_uid, content } = useSelector(
(store) => {
return {
@@ -64,11 +64,6 @@ export default function useMessageOperation({ mid, context, contextId }) {
toast.success("Unpin Message Successfully!");
}
}, [isUnpinSuccess]);
- useEffect(() => {
- if (copied) {
- toast.success("Copied");
- }
- }, [copied]);
const enablePin = context == "channel" && canPin;
// const enableReply = currUid != from_uid;
const isImage =
@@ -83,7 +78,9 @@ export default function useMessageOperation({ mid, context, contextId }) {
[ContentTypes.text, ContentTypes.markdown].includes(content_type) ||
isImage;
return {
- copyContent: isImage ? copyContent.bind(null, true) : copyContent,
+ copyContent: isImage
+ ? copyContent.bind(null, true)
+ : copyContent.bind(null, false),
canCopy,
isImage,
isMarkdown: content_type == ContentTypes.markdown,
diff --git a/src/common/component/Profile.js b/src/common/component/Profile.js
deleted file mode 100644
index 997f309d..00000000
--- a/src/common/component/Profile.js
+++ /dev/null
@@ -1,134 +0,0 @@
-// import React from "react";
-import { useSelector } from 'react-redux';
-import { NavLink } from 'react-router-dom';
-import styled from 'styled-components';
-import IconMessage from '../../assets/icons/message.svg';
-import IconCall from '../../assets/icons/call.svg';
-import IconMore from '../../assets/icons/more.svg';
-import Avatar from '../../common/component/Avatar';
-import toast from 'react-hot-toast';
-
-const StyledWrapper = styled.div`
- display: flex;
- flex-direction: column;
- justify-content: center;
- align-items: center;
- margin-top: 80px;
- width: 432px;
- gap: 4px;
- .avatar {
- width: 80px;
- height: 80px;
- border-radius: 50%;
- }
- .name {
- user-select: text;
- font-weight: bold;
- font-size: 18px;
- line-height: 100%;
- color: #1c1c1e;
- }
- .email {
- user-select: text;
- font-weight: normal;
- font-size: 14px;
- line-height: 20px;
- color: #98a2b3;
- }
- .intro {
- color: #344054;
- font-style: normal;
- font-weight: 400;
- font-size: 14px;
- line-height: 20px;
- }
- .icons {
- margin-top: 24px;
- display: flex;
- align-items: center;
- gap: 8px;
- .icon {
- cursor: pointer;
- font-weight: 500;
- font-size: 14px;
- line-height: 20px;
- color: #22ccee;
- display: flex;
- align-items: center;
- flex-direction: column;
- gap: 4px;
- background: #f9fafb;
- border-radius: 8px;
- width: 128px;
- padding: 14px 0 12px 0;
- &:hover {
- background: #f2f4f7;
- }
- &.call,
- &.more {
- svg path {
- fill: #22ccee;
- }
- }
- }
- }
- .line {
- width: 100%;
- height: 1px;
- border: none;
- background-color: rgba(0, 0, 0, 0.1);
- }
- &.card {
- padding: 16px;
- width: 280px;
- background: #ffffff;
- box-shadow: 0px 20px 25px 20px rgba(31, 41, 55, 0.1), 0px 10px 10px rgba(31, 41, 55, 0.04);
- border-radius: 6px;
- .icons {
- padding-bottom: 2px;
- }
- }
-`;
-export default function Profile({ uid = null, type = 'embed' }) {
- const data = useSelector((store) => store.contacts.byId[uid]);
- if (!data) return null;
- // console.log("profile", data);
- const {
- name,
- email,
- avatar
- // introduction = "This guy has nothing to introduce",
- } = data;
- const handleClick = () => {
- toast.success('cooming soon...');
- };
- return (
-
-
- {name}
- {email}
- {/* {introduction}
*/}
-
-
- -
-
- Message
-
-
- {/* */}
- {type !== 'card' && (
- -
-
- Call
-
- )}
- {/* */}
- -
-
- More
-
-
- {/* {type == "embed" &&
} */}
-
- );
-}
diff --git a/src/common/component/Profile/index.js b/src/common/component/Profile/index.js
new file mode 100644
index 00000000..1e5ea694
--- /dev/null
+++ b/src/common/component/Profile/index.js
@@ -0,0 +1,116 @@
+import { useEffect } from "react";
+import { useSelector } from "react-redux";
+import { NavLink } from "react-router-dom";
+import toast from "react-hot-toast";
+import Tippy from "@tippyjs/react";
+import { hideAll } from "tippy.js";
+import IconMessage from "../../../assets/icons/message.svg";
+import IconCall from "../../../assets/icons/call.svg";
+import IconMore from "../../../assets/icons/more.svg";
+import Avatar from "../Avatar";
+import StyledWrapper from "./styled";
+import StyledMenu from "../styled/Menu";
+import useCopy from "../../hook/useCopy";
+import { useRemoveMembersMutation } from "../../../app/services/channel";
+
+export default function Profile({ uid = null, type = "embed", cid = null }) {
+ const [
+ removeFromChannel,
+ { isSuccess: removeSuccess },
+ ] = useRemoveMembersMutation();
+ const { copy } = useCopy();
+ const { data, channel, loginUid, isAdmin } = useSelector((store) => {
+ return {
+ data: store.contacts.byId[uid],
+ channel: store.channels.byId[cid],
+ loginUid: store.authData.uid,
+ isAdmin: store.contacts.byId[store.authData.uid]?.is_admin,
+ };
+ });
+ useEffect(() => {
+ if (removeSuccess) {
+ toast.success("Remove Successfully");
+ }
+ }, [removeSuccess]);
+
+ if (!data) return null;
+ // console.log("profile", data);
+ const {
+ name,
+ email,
+ avatar,
+ // introduction = "This guy has nothing to introduce",
+ } = data;
+ const handleClick = () => {
+ toast.success("cooming soon...");
+ };
+ const handlCopyEmail = () => {
+ copy(email);
+ hideAll();
+ };
+ const handleRemove = (uid) => {
+ removeFromChannel({ id: +cid, members: [+uid] });
+ hideAll();
+ };
+ const canCall = type !== "card" && loginUid != uid;
+ const canRemoveFromChannel =
+ cid &&
+ !channel?.is_public &&
+ (isAdmin || channel?.owner == loginUid) &&
+ channel?.owner != uid;
+ const hasMore = canCall || email || canRemoveFromChannel;
+ return (
+
+
+ {name}
+ {email}
+ {/* {introduction}
*/}
+
+
+ -
+
+ Message
+
+
+ {/* */}
+ {canCall && (
+ -
+
+ Call
+
+ )}
+ {/* */}
+
+ {canCall && - Call
}
+ {email && (
+ -
+ Copy Email
+
+ )}
+ {canRemoveFromChannel && (
+ -
+ Remove from Channel
+
+ )}
+
+ }
+ >
+ -
+
+ More
+
+
+
+
+ );
+}
diff --git a/src/common/component/Profile/styled.js b/src/common/component/Profile/styled.js
new file mode 100644
index 00000000..f3e69c2d
--- /dev/null
+++ b/src/common/component/Profile/styled.js
@@ -0,0 +1,96 @@
+import styled from "styled-components";
+
+const StyledWrapper = styled.div`
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ margin-top: 80px;
+ width: 432px;
+ gap: 4px;
+ .avatar {
+ width: 80px;
+ height: 80px;
+ border-radius: 50%;
+ }
+ .name {
+ user-select: text;
+ font-weight: bold;
+ font-size: 18px;
+ line-height: 100%;
+ color: #1c1c1e;
+ }
+ .email {
+ user-select: text;
+ font-weight: normal;
+ font-size: 14px;
+ line-height: 20px;
+ color: #98a2b3;
+ }
+ .intro {
+ color: #344054;
+ font-style: normal;
+ font-weight: 400;
+ font-size: 14px;
+ line-height: 20px;
+ }
+ .icons {
+ margin-top: 24px;
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ .icon {
+ cursor: pointer;
+ font-weight: 500;
+ font-size: 14px;
+ line-height: 20px;
+ color: #22ccee;
+ display: flex;
+ align-items: center;
+ flex-direction: column;
+ gap: 4px;
+ background: #f9fafb;
+ border-radius: 8px;
+ width: 128px;
+ padding: 14px 0 12px 0;
+
+ &:not(.disabled):hover {
+ background: #f2f4f7;
+ }
+ &.call,
+ &.more {
+ svg path {
+ fill: #22ccee;
+ }
+ }
+ &.disabled {
+ color: #ccc;
+ svg path {
+ fill: #ccc;
+ }
+ }
+ .txt {
+ user-select: none;
+ }
+ }
+ }
+ .line {
+ width: 100%;
+ height: 1px;
+ border: none;
+ background-color: rgba(0, 0, 0, 0.1);
+ }
+ &.card {
+ padding: 16px;
+ width: 280px;
+ background: #ffffff;
+ box-shadow: 0px 20px 25px 20px rgba(31, 41, 55, 0.1),
+ 0px 10px 10px rgba(31, 41, 55, 0.04);
+ border-radius: 6px;
+ .icons {
+ padding-bottom: 2px;
+ }
+ }
+`;
+
+export default StyledWrapper;
diff --git a/src/common/component/Send/index.js b/src/common/component/Send/index.js
index 9195c224..1fa18850 100644
--- a/src/common/component/Send/index.js
+++ b/src/common/component/Send/index.js
@@ -3,7 +3,7 @@ import { useDispatch, useSelector } from "react-redux";
import useSendMessage from "../../hook/useSendMessage";
import useAddLocalFileMessage from "../../hook/useAddLocalFileMessage";
import { updateInputMode } from "../../../app/slices/ui";
-import { ContentTypes } from "../../../app/config";
+import { ContentTypes, ChatPrefixs } from "../../../app/config";
import StyledSend from "./styled";
import UploadFileList from "./UploadFileList";
@@ -15,10 +15,7 @@ import MarkdownEditor from "../MarkdownEditor";
import MixedInput, { useMixedEditor } from "../MixedInput";
import useDraft from "../../hook/useDraft";
import useUploadFile from "../../hook/useUploadFile";
-const Types = {
- channel: "#",
- user: "@",
-};
+
const Modes = {
text: "text",
markdown: "markdown",
@@ -132,7 +129,7 @@ function Send({
};
const name =
context == "channel" ? channelsData[id]?.name : contactsData[id]?.name;
- const placeholder = `Send to ${Types[context]}${name} `;
+ const placeholder = `Send to ${ChatPrefixs[context]}${name} `;
const members =
context == "channel"
? channelsData[id]?.is_public
diff --git a/src/common/hook/useInviteLink.js b/src/common/hook/useInviteLink.js
index 0d221224..ccadf2f0 100644
--- a/src/common/hook/useInviteLink.js
+++ b/src/common/hook/useInviteLink.js
@@ -19,7 +19,7 @@ export default function useInviteLink(cid = null) {
generateServerInviteLink,
{ data: serverInviteLink, isLoading: generatingServerLink },
] = useCreateServerInviteLinkQuery();
- const [linkCopied, copy] = useCopy();
+ const { copied, copy } = useCopy({ enableToast: false });
const copyLink = () => {
copy(finalLink);
};
@@ -50,7 +50,7 @@ export default function useInviteLink(cid = null) {
? generateChannelInviteLink.bind(null, cid)
: genServerLink,
link: finalLink,
- linkCopied,
+ linkCopied: copied,
copyLink,
};
}