diff --git a/packages/react-chat/src/components/ActivityCenter/ActivityButton.tsx b/packages/react-chat/src/components/ActivityCenter/ActivityButton.tsx index 82c04488..939b7ee2 100644 --- a/packages/react-chat/src/components/ActivityCenter/ActivityButton.tsx +++ b/packages/react-chat/src/components/ActivityCenter/ActivityButton.tsx @@ -1,8 +1,8 @@ import React, { useMemo, useRef, useState } from "react"; import styled from "styled-components"; -import { useActivities } from "../../contexts/activityProvider"; import { useIdentity } from "../../contexts/identityProvider"; +import { useActivities } from "../../hooks/useActivities"; import { useClickOutside } from "../../hooks/useClickOutside"; import { TopBtn } from "../Chat/ChatTopbar"; import { ActivityIcon } from "../Icons/ActivityIcon"; @@ -14,13 +14,17 @@ interface ActivityButtonProps { } export function ActivityButton({ className }: ActivityButtonProps) { - const { activities } = useActivities(); + const { activities, activityDispatch } = useActivities(); const identity = useIdentity(); const disabled = useMemo(() => !identity, [identity]); const ref = useRef(null); useClickOutside(ref, () => setShowActivityCenter(false)); const [showActivityCenter, setShowActivityCenter] = useState(false); + const badgeAmount = useMemo( + () => activities.filter((activity) => !activity.isRead).length, + [activities] + ); return ( @@ -29,22 +33,26 @@ export function ActivityButton({ className }: ActivityButtonProps) { disabled={disabled} > - {activities.length > 0 && ( + {badgeAmount > 0 && ( 99 + badgeAmount > 99 ? "countless" - : activities.length > 9 + : badgeAmount > 9 ? "wide" : undefined } > - {activities.length < 100 ? activities.length : "∞"} + {badgeAmount < 100 ? badgeAmount : "∞"} )} {showActivityCenter && ( - + )} ); diff --git a/packages/react-chat/src/components/ActivityCenter/ActivityCenter.tsx b/packages/react-chat/src/components/ActivityCenter/ActivityCenter.tsx index 1e24d1a0..d35f724f 100644 --- a/packages/react-chat/src/components/ActivityCenter/ActivityCenter.tsx +++ b/packages/react-chat/src/components/ActivityCenter/ActivityCenter.tsx @@ -1,8 +1,9 @@ import React, { useMemo, useState } from "react"; import styled from "styled-components"; -import { useActivities } from "../../contexts/activityProvider"; import { useMessengerContext } from "../../contexts/messengerProvider"; +import { ActivityAction } from "../../hooks/useActivities"; +import { Activity } from "../../models/Activity"; import { buttonTransparentStyles } from "../Buttons/buttonStyle"; import { Tooltip } from "../Form/Tooltip"; import { HideIcon } from "../Icons/HideIcon"; @@ -12,11 +13,16 @@ import { ShowIcon } from "../Icons/ShowIcon"; import { ActivityMessage } from "./ActivityMessage"; interface ActivityCenterProps { + activities: Activity[]; setShowActivityCenter: (val: boolean) => void; + activityDispatch: React.Dispatch; } -export function ActivityCenter({ setShowActivityCenter }: ActivityCenterProps) { - const { activities } = useActivities(); +export function ActivityCenter({ + activities, + setShowActivityCenter, + activityDispatch, +}: ActivityCenterProps) { const { contacts } = useMessengerContext(); const shownActivities = useMemo( @@ -53,9 +59,7 @@ export function ActivityCenter({ setShowActivityCenter }: ActivityCenterProps) { { - shownActivities.map((activity) => (activity.isRead = true)); - }} + onClick={() => activityDispatch({ type: "setAllAsRead" })} > @@ -76,6 +80,7 @@ export function ActivityCenter({ setShowActivityCenter }: ActivityCenterProps) { key={activity.id} activity={activity} setShowActivityCenter={setShowActivityCenter} + activityDispatch={activityDispatch} /> ))} diff --git a/packages/react-chat/src/components/ActivityCenter/ActivityMessage.tsx b/packages/react-chat/src/components/ActivityCenter/ActivityMessage.tsx index 666cc64e..0d26fbc3 100644 --- a/packages/react-chat/src/components/ActivityCenter/ActivityMessage.tsx +++ b/packages/react-chat/src/components/ActivityCenter/ActivityMessage.tsx @@ -3,7 +3,9 @@ import styled from "styled-components"; import { useMessengerContext } from "../../contexts/messengerProvider"; import { useModal } from "../../contexts/modalProvider"; +import { ActivityAction } from "../../hooks/useActivities"; import { useClickOutside } from "../../hooks/useClickOutside"; +import { useScrollToMessage } from "../../hooks/useScrollToMessage"; import { Activity } from "../../models/Activity"; import { equalDate } from "../../utils/equalDate"; import { DownloadButton } from "../Buttons/DownloadButton"; @@ -41,16 +43,19 @@ const today = new Date(); type ActivityMessageProps = { activity: Activity; setShowActivityCenter: (val: boolean) => void; + activityDispatch: React.Dispatch; }; export function ActivityMessage({ activity, setShowActivityCenter, + activityDispatch, }: ActivityMessageProps) { const { contacts, channelsDispatch } = useMessengerContext(); + const scroll = useScrollToMessage(); const { setModal } = useModal(ProfileModalName); const showChannel = () => { - activity.channel && + "channel" in activity && channelsDispatch({ type: "ChangeActive", payload: activity.channel.id }), setShowActivityCenter(false); }; @@ -66,10 +71,10 @@ export function ActivityMessage({ const [elements, setElements] = useState< (string | React.ReactElement | undefined)[] - >([activity.message?.content]); + >(["message" in activity ? activity.message?.content : undefined]); useEffect(() => { - if (activity.message) { + if ("message" in activity) { const split = activity.message?.content.split(" "); const newSplit = split.flatMap((element, idx) => { if (element.startsWith("@")) { @@ -88,7 +93,7 @@ export function ActivityMessage({ newSplit.pop(); setElements(newSplit); } - }, [activity.message?.content]); + }, [activity]); const ref = useRef(null); useClickOutside(ref, () => setShowMenu(false)); @@ -162,10 +167,16 @@ export function ActivityMessage({ )} - {activity.message?.content && ( -
{elements.map((el) => el)}
+ {"message" in activity && activity.message?.content && ( +
scroll(activity.message, activity.channel.id)} + > + {elements.map((el) => el)} +
)} - {activity.requestType === "income" && activity.request} + {activity.type === "request" && + activity.requestType === "income" && + activity.request}
{type === "mention" && activity.channel && @@ -199,8 +210,10 @@ export function ActivityMessage({ <> { - activity.isRead = true; - activity.status = "accepted"; + activityDispatch({ + type: "setStatus", + payload: { id: activity.id, status: "accepted" }, + }); }} className="accept" > @@ -208,8 +221,10 @@ export function ActivityMessage({ { - activity.isRead = true; - activity.status = "declined"; + activityDispatch({ + type: "setStatus", + payload: { id: activity.id, status: "declined" }, + }); }} className="decline" > @@ -240,9 +255,9 @@ export function ActivityMessage({ {(type === "mention" || type === "reply") && ( { - activity.isRead = true; - }} + onClick={() => + activityDispatch({ type: "setAsRead", payload: activity.id }) + } className={`${activity.isRead && "read"}`} > diff --git a/packages/react-chat/src/components/DappConnectCommunityChat.tsx b/packages/react-chat/src/components/DappConnectCommunityChat.tsx index a80bf4ea..161050e8 100644 --- a/packages/react-chat/src/components/DappConnectCommunityChat.tsx +++ b/packages/react-chat/src/components/DappConnectCommunityChat.tsx @@ -3,7 +3,6 @@ import { ThemeProvider } from "styled-components"; import styled from "styled-components"; import { ConfigType } from ".."; -import { ActivityProvider } from "../contexts/activityProvider"; import { ChatStateProvider } from "../contexts/chatStateProvider"; import { ConfigProvider } from "../contexts/configProvider"; import { FetchMetadataProvider } from "../contexts/fetchMetadataProvider"; @@ -38,21 +37,19 @@ export function DappConnectCommunityChat({ - - - - - - - - -