diff --git a/src/app/config.js b/src/app/config.js index 7a900ba5..379787ba 100644 --- a/src/app/config.js +++ b/src/app/config.js @@ -1,6 +1,6 @@ // const BASE_URL = `${location.origin}/api`; const BASE_URL = `https://dev.rustchat.com/api`; -export const CACHE_VERSION = `0.2.13`; +export const CACHE_VERSION = `0.2.15`; export const ContentTypes = { text: "text/plain", markdown: "text/markdown", diff --git a/src/app/listener.middleware/handler.reaction.js b/src/app/listener.middleware/handler.reaction.js index 7165b5c3..702075c5 100644 --- a/src/app/listener.middleware/handler.reaction.js +++ b/src/app/listener.middleware/handler.reaction.js @@ -8,8 +8,9 @@ export default async function handler({ operation, data = {}, payload }) { switch (operation) { case "toggleReactionMessage": { - const { mid } = payload; + const { mid, rid } = payload; await table.setItem(mid + "", data[mid]); + await table.setItem(rid + "", data[rid]); } break; case "removeReactionMessage": diff --git a/src/app/services/handlers.js b/src/app/services/handlers.js index a7d37a83..d22b635c 100644 --- a/src/app/services/handlers.js +++ b/src/app/services/handlers.js @@ -1,8 +1,16 @@ import toast from "react-hot-toast"; import { batch } from "react-redux"; import { ContentTypes } from "../config"; -import { addChannelMsg, removeChannelMsg } from "../slices/message.channel"; -import { addUserMsg, removeUserMsg } from "../slices/message.user"; +import { + addChannelMsg, + removeChannelMsg, + replaceChannelMsg, +} from "../slices/message.channel"; +import { + addUserMsg, + removeUserMsg, + replaceUserMsg, +} from "../slices/message.user"; import { addMessage, removeMessage } from "../slices/message"; export const onMessageSendStarted = async ( { @@ -47,6 +55,8 @@ export const onMessageSendStarted = async ( const addContextMessage = from == "channel" ? addChannelMsg : addUserMsg; const removeContextMessage = from == "channel" ? removeChannelMsg : removeUserMsg; + const replaceContextMsg = + from == "channel" ? replaceChannelMsg : replaceUserMsg; if (!ignoreLocal) { batch(() => { dispatch(addMessage({ mid: ts, ...tmpMsg })); @@ -58,10 +68,9 @@ export const onMessageSendStarted = async ( const { data: server_mid } = await queryFulfilled; console.log("message server mid", server_mid); batch(() => { - dispatch(removeContextMessage({ id, mid: ts })); - dispatch(removeMessage(ts)); dispatch(addMessage({ mid: server_mid, ...tmpMsg })); - dispatch(addContextMessage({ id, mid: server_mid })); + dispatch(replaceContextMsg({ id, localMid: ts, serverMid: server_mid })); + dispatch(removeMessage(ts)); }); // dispatch(removePendingMessage({ id, mid:ts, type: from })); } catch { diff --git a/src/app/slices/message.reaction.js b/src/app/slices/message.reaction.js index 4181ae14..9482c0fd 100644 --- a/src/app/slices/message.reaction.js +++ b/src/app/slices/message.reaction.js @@ -20,11 +20,18 @@ const reactionMessageSlice = createSlice({ }); }, toggleReactionMessage(state, action) { - const { from_uid, mid, action: reaction } = action.payload; + // rid: reaction's mid, mid: which message append to + const { from_uid, mid, rid, action: reaction } = action.payload; console.log("msg reaction", mid, from_uid, reaction); + const ridExisted = state[rid] || false; + // 已经塞过了 + if (ridExisted) return; + console.log("ssss"); + // 还未塞过任何一表情 if (!state[mid]) { state[mid] = {}; } + // 存在该表情数据 if (state[mid][reaction]) { const reactionUids = state[mid][reaction]; const idx = reactionUids.findIndex((id) => id == from_uid); @@ -40,6 +47,7 @@ const reactionMessageSlice = createSlice({ } else { state[mid][reaction] = [from_uid]; } + state[rid] = true; }, }, }); diff --git a/src/common/component/Message/Reaction.js b/src/common/component/Message/Reaction.js index a41b557c..cd8cfa40 100644 --- a/src/common/component/Message/Reaction.js +++ b/src/common/component/Message/Reaction.js @@ -1,16 +1,16 @@ // import { useState } from "react"; import { useSelector } from "react-redux"; import styled from "styled-components"; +import { getEmojiDataFromNative } from "emoji-mart"; +import AppleEmojiData from "emoji-mart/data/apple.json"; import Tippy from "@tippyjs/react"; import { hideAll } from "tippy.js"; -import Emoji from "../Emoji"; +import ReactionItem from "../ReactionItem"; import ReactionPicker from "./ReactionPicker"; import Tooltip from "../Tooltip"; import { useReactMessageMutation } from "../../../app/services/message"; -// import { Emojis } from "../../../app/config"; import addEmojiIcon from "../../../assets/icons/add.emoji.svg?url"; const StyledWrapper = styled.span` - /* z-index: 99; */ position: relative; margin-top: 8px; margin-bottom: 4px; @@ -18,7 +18,6 @@ const StyledWrapper = styled.span` align-items: center; gap: 4px; width: fit-content; - /* align-items: center; */ .reaction { cursor: pointer; background-color: #ecfdff; @@ -67,6 +66,68 @@ const StyledWrapper = styled.span` visibility: visible; } `; +const StyledDetails = styled.div` + position: relative; + background: #ffffff; + border-radius: var(--br); + box-shadow: 0px 12px 16px -4px rgba(16, 24, 40, 0.08), + 0px 4px 6px -2px rgba(16, 24, 40, 0.03); + display: flex; + align-items: flex-start; + gap: 8px; + padding: 8px; + &:after { + content: ""; + display: block; + width: 12px; + height: 12px; + background-color: #fff; + border-radius: 1px; + position: absolute; + bottom: -6px; + left: calc(50% - 6px); + transform: matrix(0.71, 0.71, -0.71, 0.71, 0, 0); + } + &.first:after { + left: calc(50% - 16px); + } + .emoji { + width: 32px; + height: 32px; + } + .desc { + display: flex; + flex-direction: column; + width: 140px; + font-weight: 500; + font-size: 12px; + line-height: 18px; + color: #1d2939; + } +`; +const ReactionDetails = ({ uids = [], emoji, index }) => { + const contactsData = useSelector((store) => store.contacts.byId); + const names = uids.map((id) => { + return contactsData[id]?.name; + }); + const emojiData = getEmojiDataFromNative(emoji, "apple", AppleEmojiData); + const prefixDesc = + names.length > 3 + ? `${names.join(", ")} and ${names.length - 3} others reacted with` + : `${names.join(", ")} reacted with`; + console.log("eeee", emojiData); + return ( + +
+ +
+
+ {prefixDesc} + {emojiData?.colons} +
+
+ ); +}; export default function Reaction({ mid, reactions = null }) { const [reactWithEmoji] = useReactMessageMutation(); const { currUid } = useSelector((store) => { @@ -81,7 +142,7 @@ export default function Reaction({ mid, reactions = null }) { if (!reactions || Object.entries(reactions).length == 0) return null; return ( - {Object.entries(reactions).map(([reaction, uids]) => { + {Object.entries(reactions).map(([reaction, uids], idx) => { const reacted = uids.findIndex((id) => id == currUid) > -1; return uids.length > 0 ? ( 1 ? count : ""} key={reaction} > - - - + + } + > + + + + {uids.length > 1 ? ( {`${uids.length}`} diff --git a/src/common/component/Message/ReactionPicker.js b/src/common/component/Message/ReactionPicker.js index 84c30397..956d2b36 100644 --- a/src/common/component/Message/ReactionPicker.js +++ b/src/common/component/Message/ReactionPicker.js @@ -3,7 +3,7 @@ import { useSelector } from "react-redux"; import { useReactMessageMutation } from "../../../app/services/message"; import { Emojis } from "../../../app/config"; -import Emoji from "../Emoji"; +import Emoji from "../ReactionItem"; const StyledPicker = styled.div` background: none; z-index: 999; diff --git a/src/common/component/Emoji.js b/src/common/component/ReactionItem.js similarity index 94% rename from src/common/component/Emoji.js rename to src/common/component/ReactionItem.js index 148fd3f7..91b3034b 100644 --- a/src/common/component/Emoji.js +++ b/src/common/component/ReactionItem.js @@ -18,7 +18,7 @@ const Emojis = { "🎉": , }; -export default function EmojiItem({ native = "" }) { +export default function ReactionItem({ native = "" }) { if (!native || !Emojis[native]) return null; return Emojis[native]; diff --git a/src/common/hook/useStreaming/chat.handler.js b/src/common/hook/useStreaming/chat.handler.js index 88378bf3..36b89c02 100644 --- a/src/common/hook/useStreaming/chat.handler.js +++ b/src/common/hook/useStreaming/chat.handler.js @@ -118,8 +118,14 @@ const handler = (data, dispatch, currState) => { switch (type) { case "like": { + // rid reaction's mid dispatch( - toggleReactionMessage({ from_uid, mid: detailMid, action }) + toggleReactionMessage({ + from_uid, + mid: detailMid, + rid: mid, + action, + }) ); }