diff --git a/packages/react-chat/src/components/ActivityCenter.tsx b/packages/react-chat/src/components/ActivityCenter.tsx new file mode 100644 index 0000000..7d73d1e --- /dev/null +++ b/packages/react-chat/src/components/ActivityCenter.tsx @@ -0,0 +1,427 @@ +import React, { useMemo, useRef, useState } from "react"; +import styled from "styled-components"; + +import { useActivities } from "../contexts/activityProvider"; +import { useMessengerContext } from "../contexts/messengerProvider"; +import { useClickOutside } from "../hooks/useClickOutside"; +import { Activity } from "../models/Activity"; +import { equalDate } from "../utils/equalDate"; + +import { buttonStyles } from "./Buttons/buttonStyle"; +import { + ContentWrapper, + DateSeparator, + MessageHeaderWrapper, + MessageOuterWrapper, + MessageText, + TimeWrapper, + UserAddress, + UserName, + UserNameWrapper, +} from "./Chat/ChatMessages"; +import { ContactMenu } from "./Form/ContactMenu"; +import { CheckSvg } from "./Icons/CheckIcon"; +import { ClearSvg } from "./Icons/ClearIcon"; +import { GroupIcon } from "./Icons/GroupIcon"; +import { HideIcon } from "./Icons/HideIcon"; +import { Icon } from "./Icons/Icon"; +import { MoreIcon } from "./Icons/MoreIcon"; +import { ReadIcon } from "./Icons/ReadIcon"; +import { ReplyIcon } from "./Icons/ReplyActivityIcon"; +import { ShowIcon } from "./Icons/ShowIcon"; +import { UntrustworthIcon } from "./Icons/UntrustworthIcon"; +import { UserIcon } from "./Icons/UserIcon"; +import { textMediumStyles, textSmallStyles } from "./Text"; + +const today = new Date(); + +type ActivityMessageProps = { + activity: Activity; +}; + +function ActivityMessage({ activity }: ActivityMessageProps) { + const { contacts } = useMessengerContext(); + + const [showMenu, setShowMenu] = useState(false); + + const type = activity.type; + + const contact = useMemo( + () => contacts[activity.user], + [activity.user, contacts] + ); + + return ( + + + {equalDate(activity.date, today) + ? "Today" + : activity.date.toLocaleDateString()} + + + + <> + + + + + + + + + {" "} + {contact.customName ?? activity.user.slice(0, 10)} + + {contact.customName && ( + + {activity.user.slice(0, 5)}...{activity.user.slice(-3)} + + )} + {contact.isUntrustworthy && } + + + {activity.date.toLocaleString("en-US", { + hour: "numeric", + minute: "numeric", + hour12: true, + })} + + + {type === "request" && ( + + Contact request + {activity.requestType === "outcome" + ? ` to ${activity.user.slice(0, 10)}` + : ": "} + + )} + + {activity.message?.content || + (activity.requestType === "income" && activity.request)} + + {type === "mention" && + activity.channel && + activity.channel.type !== "dm" && ( + + {activity.channel.type === "group" ? : "#"}{" "} + {` ${activity.channel.name.slice(0, 10)}`} + + )} + {type === "reply" && activity.quote && ( + + {activity.quote.image && ( + Posted an image in + )} + + {activity.quote.content} + + + )} + + + {type === "request" && + !activity.status && + activity.requestType === "income" && ( + <> + { + activity.isRead = true; + activity.status = "accepted"; + }} + className="accept" + > + + + { + activity.isRead = true; + activity.status = "declined"; + }} + className="decline" + > + + + { + setShowMenu((e) => !e); + }} + > + {showMenu && } + + + + )} + {type === "request" && activity.status === "accepted" && ( + Accepted + )} + {type === "request" && activity.status === "declined" && ( + Declined + )} + {type === "request" && activity.status === "sent" && ( + Sent + )} + {type !== "request" && ( + { + activity.isRead = true; + }} + className={`${activity.isRead && "read"}`} + > + + + )} + + + ); +} + +interface ActivityCenterProps { + setShowActivityCenter: (val: boolean) => void; +} + +export function ActivityCenter({ setShowActivityCenter }: ActivityCenterProps) { + const { activities } = useActivities(); + const { contacts } = useMessengerContext(); + + const ref = useRef(null); + useClickOutside(ref, () => setShowActivityCenter(false)); + + const shownActivities = useMemo( + () => + activities.filter( + (activity) => !contacts?.[activity.user]?.blocked ?? true + ), + [contacts, activities, activities.length] + ); + + const [hideRead, setHideRead] = useState(false); + + const [filter, setFilter] = useState(""); + + const filteredActivities = shownActivities.filter((activity) => + filter + ? activity.type === filter + : hideRead + ? activity.isRead !== true + : activity + ); + + return ( + + + + setFilter("")}>All + setFilter("mention")}>Mentions + setFilter("reply")}>Replies + setFilter("request")}> + Contact requests + + + + { + shownActivities.map((activity) => (activity.isRead = true)); + }} + > + + + setHideRead(!hideRead)}> + {hideRead ? : } + + + + {filteredActivities.length > 0 ? ( + + {filteredActivities.map((activity) => ( + + ))} + + ) : ( + Notifications will appear here + )} + + ); +} + +const ActivityBlock = styled.div` + width: 600px; + height: 770px; + display: flex; + flex-direction: column; + background: ${({ theme }) => theme.bodyBackgroundColor}; + box-shadow: 0px 12px 24px rgba(0, 34, 51, 0.1); + border-radius: 8px; + position: absolute; + top: 48px; + right: 8px; + z-index: 100; +`; + +const ActivityFilter = styled.div` + display: flex; + justify-content: space-between; + padding: 13px 16px; +`; + +const Filters = styled.div` + display: flex; +`; + +const FilterBtn = styled.button` + ${buttonStyles} + ${textSmallStyles} + + padding: 10px 12px; + background: ${({ theme }) => theme.bodyBackgroundColor}; + + & + & { + margin-left: 8px; + } + + &:hover { + background: ${({ theme }) => theme.buttonBgHover}; + } + + &:focus { + background: ${({ theme }) => theme.buttonBg}; + } +`; + +const ActivityBtn = styled.button` + width: 32px; + height: 32px; + display: flex; + justify-content: center; + align-items: center; + border-radius: 8px; + align-self: center; + + &:hover { + background: ${({ theme }) => theme.buttonBgHover}; + } + + &.read { + &:hover { + background: ${({ theme }) => theme.bodyBackgroundColor}; + } + } + + &.accept { + &:hover { + background: rgba(78, 188, 96, 0.1); + } + } + + &.decline { + &:hover { + background: rgba(255, 45, 85, 0.1); + } + } + + & + & { + margin-left: 8px; + } +`; + +const Activities = styled.div` + display: flex; + flex-direction: column; + width: 100%; + overflow: auto; +`; + +const EmptyActivities = styled.div` + display: flex; + justify-content: center; + align-items: center; + flex: 1; + width: 100%; + color: ${({ theme }) => theme.secondary}; +`; + +const ActivityDate = styled(DateSeparator)` + justify-content: flex-start; + padding: 8px 16px; + margin: 0; +`; + +const MessageWrapper = styled.div` + width: 100%; + display: flex; + align-items: flex-start; + padding: 8px 16px; + + &.unread { + background: ${({ theme }) => theme.buttonBgHover}; + } +`; + +const ActivityText = styled(MessageText)` + white-space: unset; + margin-bottom: 8px; +`; + +const Tag = styled.div` + width: fit-content; + max-width: 200px; + display: flex; + align-items: center; + + border: 1px solid ${({ theme }) => theme.secondary}; + border-radius: 11px; + padding: 0 6px; + cursor: pointer; + + font-weight: 500; + color: ${({ theme }) => theme.secondary}; + ${textSmallStyles} + + & > span { + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + } +`; + +const ContextHeading = styled.p` + font-style: italic; + color: ${({ theme }) => theme.secondary}; + flex-shrink: 0; + ${textMediumStyles} +`; + +const RequestStatus = styled.p` + font-weight: 500; + align-self: center; + text-align: end; + color: ${({ theme }) => theme.secondary}; + ${textSmallStyles} + + &.accepted { + color: ${({ theme }) => theme.greenColor}; + } + + &.declined { + color: ${({ theme }) => theme.redColor}; + } +`; + +const ActivityContent = styled(ContentWrapper)` + max-width: calc(100% - 80px); + flex: 1; +`; + +const Btns = styled.div` + display: flex; + align-items: center; +`; + +const ReplyWrapper = styled.div` + max-width: 100%; + display: flex; + align-items: center; + + & > p { + margin-right: 4px; + } +`; diff --git a/packages/react-chat/src/components/Buttons/buttonStyle.tsx b/packages/react-chat/src/components/Buttons/buttonStyle.tsx index cf461a4..70a7157 100644 --- a/packages/react-chat/src/components/Buttons/buttonStyle.tsx +++ b/packages/react-chat/src/components/Buttons/buttonStyle.tsx @@ -2,6 +2,7 @@ import { css } from "styled-components"; export const buttonStyles = css` border-radius: 8px; + font-family: "Inter"; font-weight: 500; font-size: 15px; line-height: 22px; diff --git a/packages/react-chat/src/components/Channels/Channel.tsx b/packages/react-chat/src/components/Channels/Channel.tsx index 09b6ae5..4193f18 100644 --- a/packages/react-chat/src/components/Channels/Channel.tsx +++ b/packages/react-chat/src/components/Channels/Channel.tsx @@ -188,6 +188,7 @@ const NotificationBagde = styled.div` border-radius: 50%; font-size: 12px; line-height: 16px; + font-weight: 500; background-color: ${({ theme }) => theme.notificationColor}; color: ${({ theme }) => theme.bodyBackgroundColor}; display: flex; diff --git a/packages/react-chat/src/components/Chat/ChatMessageContent.tsx b/packages/react-chat/src/components/Chat/ChatMessageContent.tsx index 2937002..0dd8676 100644 --- a/packages/react-chat/src/components/Chat/ChatMessageContent.tsx +++ b/packages/react-chat/src/components/Chat/ChatMessageContent.tsx @@ -24,7 +24,10 @@ function Mention({ id, setMentioned }: MentionProps) { const identity = useIdentity(); if (!contact) return <>{id}; - if (contact.id === utils.bufToHex(identity.publicKey)) setMentioned(true); + + useEffect(() => { + if (contact.id === utils.bufToHex(identity.publicKey)) setMentioned(true); + }, [contact.id]); return ( setShowMenu(!showMenu)}> diff --git a/packages/react-chat/src/components/Chat/ChatMessages.tsx b/packages/react-chat/src/components/Chat/ChatMessages.tsx index d3ce6b6..3145300 100644 --- a/packages/react-chat/src/components/Chat/ChatMessages.tsx +++ b/packages/react-chat/src/components/Chat/ChatMessages.tsx @@ -1,14 +1,19 @@ import React, { useEffect, useMemo, useRef, useState } from "react"; +import { utils } from "status-communities/dist/cjs"; import styled from "styled-components"; +import { useActivities } from "../../contexts/activityProvider"; +import { useIdentity } from "../../contexts/identityProvider"; import { useMessengerContext } from "../../contexts/messengerProvider"; import { useModal } from "../../contexts/modalProvider"; import { useChatScrollHandle } from "../../hooks/useChatScrollHandle"; import { Reply } from "../../hooks/useReply"; +import { ChannelData } from "../../models/ChannelData"; import { ChatMessage } from "../../models/ChatMessage"; import { equalDate } from "../../utils"; import { EmptyChannel } from "../Channels/EmptyChannel"; import { ContactMenu } from "../Form/ContactMenu"; +import { Icon } from "../Icons/Icon"; import { LoadingIcon } from "../Icons/LoadingIcon"; import { QuoteSvg } from "../Icons/QuoteIcon"; import { ReactionSvg } from "../Icons/ReactionIcon"; @@ -27,6 +32,7 @@ const today = new Date(); type ChatUiMessageProps = { idx: number; message: ChatMessage; + channel: ChannelData; prevMessage: ChatMessage; setImage: (img: string) => void; setLink: (link: string) => void; @@ -36,6 +42,7 @@ type ChatUiMessageProps = { function ChatUiMessage({ message, + channel, idx, prevMessage, setImage, @@ -44,6 +51,9 @@ function ChatUiMessage({ quote, }: ChatUiMessageProps) { const { contacts } = useMessengerContext(); + const { setActivities } = useActivities(); + const identity = useIdentity(); + const contact = useMemo( () => contacts[message.sender], [message.sender, contacts] @@ -51,6 +61,34 @@ function ChatUiMessage({ const [showMenu, setShowMenu] = useState(false); const [mentioned, setMentioned] = useState(false); + useEffect(() => { + if (mentioned) + setActivities((prev) => [ + ...prev, + { + id: message.date.getTime().toString() + message.content, + type: "mention", + date: message.date, + user: message.sender, + message: message, + channel: channel, + }, + ]); + if (quote && quote.sender === utils.bufToHex(identity.publicKey)) + setActivities((prev) => [ + ...prev, + { + id: message.date.getTime().toString() + message.content, + type: "reply", + date: message.date, + user: message.sender, + message: message, + channel: channel, + quote: quote, + }, + ]); + }, [mentioned, message, quote]); + return ( {(idx === 0 || !equalDate(prevMessage.date, message.date)) && ( @@ -190,6 +228,7 @@ export function ChatMessages({ setReply }: ChatMessagesProps) { theme.tertiary}; margin-right: 4px; @@ -331,7 +356,7 @@ export const UserAddress = styled.p` } `; -const TimeWrapper = styled.div` +export const TimeWrapper = styled.div` font-size: 10px; line-height: 14px; letter-spacing: 0.2px; @@ -340,7 +365,7 @@ const TimeWrapper = styled.div` margin-left: 4px; `; -const MessageText = styled.div` +export const MessageText = styled.div` overflow-wrap: anywhere; width: 100%; white-space: pre-wrap; diff --git a/packages/react-chat/src/components/Chat/ChatTopbar.tsx b/packages/react-chat/src/components/Chat/ChatTopbar.tsx index 910110f..8f9b72b 100644 --- a/packages/react-chat/src/components/Chat/ChatTopbar.tsx +++ b/packages/react-chat/src/components/Chat/ChatTopbar.tsx @@ -1,11 +1,14 @@ import React, { useState } from "react"; import styled from "styled-components"; +import { useActivities } from "../../contexts/activityProvider"; import { useMessengerContext } from "../../contexts/messengerProvider"; import { useNarrow } from "../../contexts/narrowProvider"; +import { ActivityCenter } from "../ActivityCenter"; import { Channel } from "../Channels/Channel"; import { Community } from "../Community"; import { ChannelMenu } from "../Form/ChannelMenu"; +import { ActivityIcon } from "../Icons/ActivityIcon"; import { MembersIcon } from "../Icons/MembersIcon"; import { MoreIcon } from "../Icons/MoreIcon"; import { CommunitySkeleton } from "../Skeleton/CommunitySkeleton"; @@ -31,8 +34,10 @@ export function ChatTopbar({ setEditGroup, }: ChatTopbarProps) { const { messenger, activeChannel, communityData } = useMessengerContext(); + const { activities } = useActivities(); const narrow = useNarrow(); const [showChannelMenu, setShowChannelMenu] = useState(false); + const [showActivityCenter, setShowActivityCenter] = useState(false); return ( {!narrow && ( - + - + )} - setShowChannelMenu(!showChannelMenu)}> + setShowChannelMenu(!showChannelMenu)}> - + + + setShowActivityCenter(!showActivityCenter)} + className="activity" + > + + {activities.length > 0 && ( + {activities.length} + )} + + {!messenger && !communityData && } {showChannelMenu && ( @@ -80,10 +96,26 @@ export function ChatTopbar({ setEditGroup={setEditGroup} /> )} + {showActivityCenter && ( + + )} ); } +const Topbar = styled.div` + display: flex; + justify-content: space-between; + align-items: center; + padding: 5px 8px; + background: ${({ theme }) => theme.bodyBackgroundColor}; + position: relative; + + &.narrow { + width: 100%; + } +`; + const ChannelWrapper = styled.div` display: flex; align-items: center; @@ -98,19 +130,6 @@ const SkeletonWrapper = styled.div` padding: 8px; `; -const Topbar = styled.div` - display: flex; - justify-content: space-between; - align-items: center; - padding: 5px 8px; - background: ${({ theme }) => theme.bodyBackgroundColor}; - position: relative; - - &.narrow { - width: 100%; - } -`; - const CommunityWrap = styled.div` padding-right: 10px; margin-right: 16px; @@ -139,35 +158,61 @@ const MenuWrapper = styled.div` align-items: center; `; -const MemberBtn = styled.button` +const ActivityWrapper = styled.div` + padding-left: 10px; + margin-left: 10px; + position: relative; + + &:before { + content: ""; + position: absolute; + left: 0; + top: 50%; + width: 2px; + height: 24px; + transform: translateY(-50%); + border-radius: 1px; + background: ${({ theme }) => theme.primary}; + opacity: 0.1; + } +`; + +const TopBtn = styled.button` width: 32px; height: 32px; border-radius: 8px; padding: 0; &:hover { - background: ${({ theme }) => theme.border}; + background: ${({ theme }) => theme.sectionBackgroundColor}; } &:active, &.active { background: ${({ theme }) => theme.inputColor}; } -`; -const MoreBtn = styled.button` - width: 32px; - height: 32px; - border-radius: 8px; - padding: 0; - margin: 0 8px; - - &:hover { - background: ${({ theme }) => theme.border}; - } - - &:active, - &.active { - background: ${({ theme }) => theme.inputColor}; + &.activity { + &:hover { + background: ${({ theme }) => theme.bodyBackgroundColor}; + } } `; + +const NotificationBagde = styled.div` + width: 18px; + height: 18px; + position: absolute; + top: -2px; + right: -2px; + border-radius: 50%; + font-size: 12px; + line-height: 16px; + font-weight: 500; + background-color: ${({ theme }) => theme.notificationColor}; + color: ${({ theme }) => theme.bodyBackgroundColor}; + display: flex; + align-items: center; + justify-content: center; + flex-shrink: 0; +`; diff --git a/packages/react-chat/src/components/Icons/ActivityIcon.tsx b/packages/react-chat/src/components/Icons/ActivityIcon.tsx new file mode 100644 index 0000000..68ec4f3 --- /dev/null +++ b/packages/react-chat/src/components/Icons/ActivityIcon.tsx @@ -0,0 +1,25 @@ +import React from "react"; +import styled from "styled-components"; + +export const ActivityIcon = () => { + return ( + + + + ); +}; + +const Icon = styled.svg` + fill: ${({ theme }) => theme.primary}; +`; diff --git a/packages/react-chat/src/components/Icons/CheckIcon.tsx b/packages/react-chat/src/components/Icons/CheckIcon.tsx index 6367008..2a8fd0e 100644 --- a/packages/react-chat/src/components/Icons/CheckIcon.tsx +++ b/packages/react-chat/src/components/Icons/CheckIcon.tsx @@ -9,11 +9,10 @@ type CheckSvgProps = { export function CheckSvg({ width, height, className }: CheckSvgProps) { return ( - @@ -23,7 +22,7 @@ export function CheckSvg({ width, height, className }: CheckSvgProps) { clipRule="evenodd" d="M7.99992 14.6668C4.31802 14.6668 1.33325 11.6821 1.33325 8.00016C1.33325 4.31826 4.31802 1.3335 7.99992 1.3335C11.6818 1.3335 14.6666 4.31826 14.6666 8.00016C14.6666 11.6821 11.6818 14.6668 7.99992 14.6668ZM7.99992 13.6668C4.8703 13.6668 2.33325 11.1298 2.33325 8.00016C2.33325 4.87055 4.8703 2.3335 7.99992 2.3335C11.1295 2.3335 13.6666 4.87055 13.6666 8.00016C13.6666 11.1298 11.1295 13.6668 7.99992 13.6668Z" /> - + ); } @@ -31,12 +30,14 @@ export const CheckIcon = () => { return ; }; -const Icon = styled(CheckSvg)` - & > path { - fill: ${({ theme }) => theme.tertiary}; - } +const Icon = styled.svg` + fill: ${({ theme }) => theme.tertiary}; - &:hover > path { + &:hover { fill: ${({ theme }) => theme.bodyBackgroundColor}; } + + &.accept { + fill: ${({ theme }) => theme.greenColor}; + } `; diff --git a/packages/react-chat/src/components/Icons/ClearIcon.tsx b/packages/react-chat/src/components/Icons/ClearIcon.tsx index e31f940..c20abab 100644 --- a/packages/react-chat/src/components/Icons/ClearIcon.tsx +++ b/packages/react-chat/src/components/Icons/ClearIcon.tsx @@ -9,7 +9,7 @@ type ClearSvgProps = { export function ClearSvg({ height, width, className }: ClearSvgProps) { return ( - - + ); } @@ -30,10 +30,8 @@ export const ClearIcon = () => { return ; }; -const Icon = styled(ClearSvg)` - & > path { - fill: ${({ theme }) => theme.tertiary}; - } +const Icon = styled.svg` + fill: ${({ theme }) => theme.tertiary}; &.profile { fill: ${({ theme }) => theme.secondary}; @@ -47,7 +45,7 @@ const Icon = styled(ClearSvg)` fill: ${({ theme }) => theme.bodyBackgroundColor}; } - &:hover > path { - fill: ${({ theme }) => theme.bodyBackgroundColor}; + &.decline { + fill: ${({ theme }) => theme.redColor}; } `; diff --git a/packages/react-chat/src/components/Icons/HideIcon.tsx b/packages/react-chat/src/components/Icons/HideIcon.tsx new file mode 100644 index 0000000..967e090 --- /dev/null +++ b/packages/react-chat/src/components/Icons/HideIcon.tsx @@ -0,0 +1,24 @@ +import React from "react"; +import styled from "styled-components"; + +export const HideIcon = () => ( + + + + + +); + +const Icon = styled.svg` + fill: ${({ theme }) => theme.tertiary}; +`; diff --git a/packages/react-chat/src/components/Icons/Icon.ts b/packages/react-chat/src/components/Icons/Icon.ts new file mode 100644 index 0000000..e9ff55d --- /dev/null +++ b/packages/react-chat/src/components/Icons/Icon.ts @@ -0,0 +1,16 @@ +import styled from "styled-components"; + +export const Icon = styled.div` + width: 40px; + height: 40px; + display: flex; + justify-content: center; + align-items: end; + border-radius: 50%; + background-color: #bcbdff; + background-size: contain; + background-position: center; + flex-shrink: 0; + position: relative; + cursor: pointer; +`; diff --git a/packages/react-chat/src/components/Icons/ReadIcon.tsx b/packages/react-chat/src/components/Icons/ReadIcon.tsx new file mode 100644 index 0000000..5c18d16 --- /dev/null +++ b/packages/react-chat/src/components/Icons/ReadIcon.tsx @@ -0,0 +1,43 @@ +import React from "react"; +import styled from "styled-components"; + +interface ReadIconProps { + isRead?: boolean; +} + +export const ReadIcon = ({ isRead }: ReadIconProps) => { + return ( + + + + + + ); +}; + +const Icon = styled.svg` + fill: ${({ theme }) => theme.tertiary}; + + &.read { + fill: ${({ theme }) => theme.secondary}; + } +`; diff --git a/packages/react-chat/src/components/Icons/ReplyActivityIcon.tsx b/packages/react-chat/src/components/Icons/ReplyActivityIcon.tsx new file mode 100644 index 0000000..815d582 --- /dev/null +++ b/packages/react-chat/src/components/Icons/ReplyActivityIcon.tsx @@ -0,0 +1,19 @@ +import React from "react"; +import styled from "styled-components"; + +export const ReplyIcon = () => ( + + + +); + +const Icon = styled.svg` + fill: ${({ theme }) => theme.secondary}; + flex-shrink: 0; +`; diff --git a/packages/react-chat/src/components/Icons/ShowIcon.tsx b/packages/react-chat/src/components/Icons/ShowIcon.tsx new file mode 100644 index 0000000..22eb5ae --- /dev/null +++ b/packages/react-chat/src/components/Icons/ShowIcon.tsx @@ -0,0 +1,27 @@ +import React from "react"; +import styled from "styled-components"; + +export const ShowIcon = () => ( + + + + +); + +const Icon = styled.svg` + fill: ${({ theme }) => theme.tertiary}; +`; diff --git a/packages/react-chat/src/components/Members/Member.tsx b/packages/react-chat/src/components/Members/Member.tsx index 222848e..175e562 100644 --- a/packages/react-chat/src/components/Members/Member.tsx +++ b/packages/react-chat/src/components/Members/Member.tsx @@ -3,8 +3,8 @@ import styled from "styled-components"; import { useMessengerContext } from "../../contexts/messengerProvider"; import { Contact } from "../../models/Contact"; -import { Icon } from "../Chat/ChatMessages"; import { ContactMenu } from "../Form/ContactMenu"; +import { Icon } from "../Icons/Icon"; import { UserIcon } from "../Icons/UserIcon"; interface MemberProps { diff --git a/packages/react-chat/src/components/Modals/ProfileModal.tsx b/packages/react-chat/src/components/Modals/ProfileModal.tsx index d68544d..153c30f 100644 --- a/packages/react-chat/src/components/Modals/ProfileModal.tsx +++ b/packages/react-chat/src/components/Modals/ProfileModal.tsx @@ -2,6 +2,7 @@ import React, { useEffect, useMemo, useState } from "react"; import { bufToHex } from "status-communities/dist/cjs/utils"; import styled from "styled-components"; +import { useActivities } from "../../contexts/activityProvider"; import { useIdentity } from "../../contexts/identityProvider"; import { useModal } from "../../contexts/modalProvider"; import { useManageContact } from "../../hooks/useManageContact"; @@ -40,6 +41,8 @@ export const ProfileModal = () => { [props] ); + const { setActivities } = useActivities(); + const identity = useIdentity(); const isUser = useMemo( () => id === bufToHex(identity.publicKey), @@ -47,12 +50,14 @@ export const ProfileModal = () => { ); const [renaming, setRenaming] = useState(renamingState ?? false); + useEffect(() => { setRenaming(renamingState ?? false); }, [renamingState]); const [request, setRequest] = useState(""); const [requestCreation, setRequestCreation] = useState(requestState ?? false); + useEffect(() => { setRequestCreation(requestState ?? false); }, [requestState]); @@ -183,7 +188,19 @@ export const ProfileModal = () => { { - setIsUserFriend(true), + setActivities((prev) => [ + ...prev, + { + id: id + request, + type: "request", + isRead: true, + date: new Date(), + user: id, + request: request, + requestType: "outcome", + status: "sent", + }, + ]), setRequestCreation(false), setRequest(""); }} diff --git a/packages/react-chat/src/components/ReactChat.tsx b/packages/react-chat/src/components/ReactChat.tsx index 9482598..c1bdaa9 100644 --- a/packages/react-chat/src/components/ReactChat.tsx +++ b/packages/react-chat/src/components/ReactChat.tsx @@ -2,6 +2,7 @@ import React, { useRef } from "react"; import { ThemeProvider } from "styled-components"; import styled from "styled-components"; +import { ActivityProvider } from "../contexts/activityProvider"; import { FetchMetadataProvider } from "../contexts/fetchMetadataProvider"; import { ModalProvider } from "../contexts/modalProvider"; import { NarrowProvider } from "../contexts/narrowProvider"; @@ -28,11 +29,13 @@ export function ReactChat({ - - - -