refactor: unify chat context type
This commit is contained in:
@@ -10,6 +10,7 @@ import { ChatMessage, ContentTypeKey, UploadFileResponse } from "../../types/mes
|
||||
import handleChatMessage from "../../common/hook/useStreaming/chat.handler";
|
||||
import { RootState } from "../store";
|
||||
import { upsertArchiveMessage } from "../slices/message.archive";
|
||||
import { ChatContext } from "../../types/common";
|
||||
|
||||
export const messageApi = createApi({
|
||||
reducerPath: "messageApi",
|
||||
@@ -175,7 +176,7 @@ export const messageApi = createApi({
|
||||
}
|
||||
}
|
||||
}),
|
||||
loadMoreMessages: builder.query<ChatMessage[], { context?: "channel" | "user", id: number; mid?: number; limit?: number }>({
|
||||
loadMoreMessages: builder.query<ChatMessage[], { context?: ChatContext, id: number; mid?: number; limit?: number }>({
|
||||
query: ({ context = "channel", id, mid = "", limit = 100 }) => {
|
||||
const url = context == "channel" ?
|
||||
`/group/${id}/history?limit=${limit}${mid ? `&before=${mid}` : ""}`
|
||||
|
||||
@@ -3,6 +3,7 @@ import { MuteDTO } from "../../types/message";
|
||||
import { OG } from "../../types/resource";
|
||||
import { AutoDeleteMessageSettingDTO, AutoDeleteMsgForGroup, AutoDeleteMsgForUser, AutoDeleteSettingForChannels, AutoDeleteSettingForUsers, PinChat, PinChatTarget } from "../../types/sse";
|
||||
import { resetAuthData } from "./auth.data";
|
||||
import { ChatContext } from "../../types/common";
|
||||
|
||||
type ChannelAside = "members" | "voice" | "voice_fullscreen" | null;
|
||||
type DMAside = "voice" | null;
|
||||
@@ -188,7 +189,7 @@ const footprintSlice = createSlice({
|
||||
const { key, value } = action.payload;
|
||||
state.og[key] = value;
|
||||
},
|
||||
updateHistoryMark(state, action: PayloadAction<{ type: "channel" | "user", id: number, mid: string, }>) {
|
||||
updateHistoryMark(state, action: PayloadAction<{ type: ChatContext, id: number, mid: string, }>) {
|
||||
const { type, id, mid } = action.payload;
|
||||
if (type == "channel") {
|
||||
state.historyChannels[id] = mid;
|
||||
|
||||
@@ -2,9 +2,10 @@ import { createSlice, PayloadAction } from "@reduxjs/toolkit";
|
||||
import { KEY_UID } from "../config";
|
||||
import { ConnectionState } from "agora-rtc-sdk-ng";
|
||||
import { resetAuthData } from "./auth.data";
|
||||
import { ChatContext } from "../../types/common";
|
||||
|
||||
export type VoiceBasicInfo = {
|
||||
context: "channel" | "dm",
|
||||
context: ChatContext,
|
||||
from?: number,
|
||||
id: number,// means to in dm context
|
||||
}
|
||||
|
||||
@@ -11,13 +11,14 @@ import IconClose from "../../../assets/icons/close.circle.svg";
|
||||
import VideoMessage from "./VideoMessage";
|
||||
import AudioMessage from "./AudioMessage";
|
||||
import clsx from "clsx";
|
||||
import { ChatContext } from "../../../types/common";
|
||||
|
||||
const isLocalFile = (content: string) => {
|
||||
return content.startsWith("blob:");
|
||||
};
|
||||
|
||||
interface Props {
|
||||
context: "user" | "channel";
|
||||
context: ChatContext;
|
||||
to: number;
|
||||
created_at: number;
|
||||
from_uid: number;
|
||||
|
||||
@@ -21,14 +21,15 @@ import moreIcon from "../../../assets/icons/more.svg?url";
|
||||
import useMessageOperation from "./useMessageOperation";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import clsx from "clsx";
|
||||
import { ChatContext } from "../../../types/common";
|
||||
type Props = {
|
||||
isSelf: boolean;
|
||||
context: "user" | "channel";
|
||||
context: ChatContext;
|
||||
contextId: number;
|
||||
mid: number;
|
||||
toggleEditMessage: () => void;
|
||||
};
|
||||
const Commands: FC<Props> = ({ isSelf, context = "user", contextId = 0, mid = 0, toggleEditMessage }) => {
|
||||
const Commands: FC<Props> = ({ isSelf, context = "dm", contextId = 0, mid = 0, toggleEditMessage }) => {
|
||||
const { t } = useTranslation();
|
||||
const {
|
||||
canDelete,
|
||||
|
||||
@@ -13,8 +13,9 @@ import { updateSelectMessages } from "../../../app/slices/ui";
|
||||
import useSendMessage from "../../hook/useSendMessage";
|
||||
import useMessageOperation from "./useMessageOperation";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { ChatContext } from "../../../types/common";
|
||||
type Props = {
|
||||
context: "user" | "channel";
|
||||
context: ChatContext;
|
||||
contextId: number;
|
||||
mid: number;
|
||||
visible: boolean;
|
||||
|
||||
@@ -5,8 +5,9 @@ import { removeMessage } from '../../../app/slices/message';
|
||||
import { removeChannelMsg } from '../../../app/slices/message.channel';
|
||||
import { removeUserMsg } from '../../../app/slices/message.user';
|
||||
import IconTimer from '../../../assets/icons/timer.svg';
|
||||
import { ChatContext } from '../../../types/common';
|
||||
type Props = {
|
||||
context: "user" | "channel",
|
||||
context: ChatContext,
|
||||
contextId: number,
|
||||
mid: number;
|
||||
expiresIn: number;
|
||||
@@ -18,7 +19,7 @@ const ExpireTimer: FC<Props> = ({ mid, createAt, expiresIn, context, contextId }
|
||||
const dispatch = useDispatch();
|
||||
const clearMsgFromClient = useCallback(
|
||||
() => {
|
||||
if (context == "user") {
|
||||
if (context == "dm") {
|
||||
dispatch(removeUserMsg({ mid, id: contextId }));
|
||||
} else {
|
||||
dispatch(removeChannelMsg({ mid, id: contextId }));
|
||||
|
||||
@@ -4,9 +4,10 @@ import Avatar from "../Avatar";
|
||||
import IconForward from "../../../assets/icons/forward.svg";
|
||||
import useNormalizeMessage from "../../hook/useNormalizeMessage";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { ChatContext } from "../../../types/common";
|
||||
|
||||
type Props = {
|
||||
context: "user" | "channel";
|
||||
context: ChatContext;
|
||||
to: number;
|
||||
from_uid: number;
|
||||
id: string;
|
||||
|
||||
@@ -18,11 +18,12 @@ import usePinMessage from "../../hook/usePinMessage";
|
||||
import { useAppSelector } from "../../../app/store";
|
||||
import ExpireTimer from "./ExpireTimer";
|
||||
import IconInfo from '../../../assets/icons/info.svg';
|
||||
import { ChatContext } from "../../../types/common";
|
||||
|
||||
interface IProps {
|
||||
readOnly?: boolean;
|
||||
contextId: number;
|
||||
context?: "user" | "channel";
|
||||
context?: ChatContext;
|
||||
read?: boolean;
|
||||
mid: number;
|
||||
updateReadIndex?: (param: any) => void;
|
||||
@@ -31,7 +32,7 @@ const Message: FC<IProps> = ({
|
||||
readOnly = false,
|
||||
contextId,
|
||||
mid,
|
||||
context = "user",
|
||||
context = "dm",
|
||||
updateReadIndex,
|
||||
read = true
|
||||
}) => {
|
||||
@@ -40,8 +41,9 @@ const Message: FC<IProps> = ({
|
||||
const [edit, setEdit] = useState(false);
|
||||
const avatarRef = useRef(null);
|
||||
const { getPinInfo } = usePinMessage(context == "channel" ? contextId : 0);
|
||||
const { message, reactionMessageData, usersData, loginUid } = useAppSelector((store) => {
|
||||
const { message, reactionMessageData, usersData, loginUid, enableRightLayout } = useAppSelector((store) => {
|
||||
return {
|
||||
enableRightLayout: store.server.chat_layout_mode == "SelfRight",
|
||||
reactionMessageData: store.reactionMessage,
|
||||
message: store.message[mid],
|
||||
usersData: store.users.byId,
|
||||
@@ -57,7 +59,7 @@ const Message: FC<IProps> = ({
|
||||
if (!read) {
|
||||
// 标记已读
|
||||
const data =
|
||||
context == "user"
|
||||
context == "dm"
|
||||
? { users: [{ uid: +contextId, mid }] }
|
||||
: { groups: [{ gid: +contextId, mid }] };
|
||||
if (updateReadIndex) {
|
||||
@@ -94,7 +96,7 @@ const Message: FC<IProps> = ({
|
||||
// return null;
|
||||
const _key = properties?.local_id || mid;
|
||||
const showExpire = (expires_in ?? 0) > 0;
|
||||
const isSelf = fromUid == loginUid;
|
||||
const isSelf = fromUid == loginUid && enableRightLayout;
|
||||
return (
|
||||
|
||||
<div
|
||||
@@ -116,7 +118,7 @@ const Message: FC<IProps> = ({
|
||||
interactive
|
||||
placement="right"
|
||||
trigger="click"
|
||||
content={<Profile uid={fromUid || 0} type="card" cid={context == "user" ? 0 : contextId} />}
|
||||
content={<Profile uid={fromUid || 0} type="card" cid={context == "dm" ? 0 : contextId} />}
|
||||
>
|
||||
<div className="cursor-pointer w-10 h-10 shrink-0" data-uid={fromUid} ref={avatarRef}>
|
||||
<Avatar className="w-10 h-10 rounded-full object-cover" width={40} height={40} src={currUser?.avatar} name={currUser?.name} />
|
||||
|
||||
@@ -8,9 +8,10 @@ import FileMessage from "../FileMessage";
|
||||
import { ContentType } from "../../../types/message";
|
||||
import LinkifyText from '../LinkifyText';
|
||||
import VoiceMessage from "../VoiceMessage";
|
||||
import { ChatContext } from "../../../types/common";
|
||||
|
||||
type Props = {
|
||||
context: "user" | "channel";
|
||||
context: ChatContext;
|
||||
to?: number;
|
||||
from_uid?: number;
|
||||
created_at?: number;
|
||||
|
||||
@@ -7,10 +7,11 @@ import { ContentTypes } from "../../../app/config";
|
||||
import useCopy from "../../hook/useCopy";
|
||||
import usePinMessage from "../../hook/usePinMessage";
|
||||
import { useAppSelector } from "../../../app/store";
|
||||
import { ChatContext } from "../../../types/common";
|
||||
|
||||
interface Params {
|
||||
mid: number;
|
||||
context: "user" | "channel";
|
||||
context: ChatContext;
|
||||
contextId: number;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ import { CONFIG } from "./config";
|
||||
import User from "../User";
|
||||
import { useAppSelector } from "../../../app/store";
|
||||
import { isMobile } from "../../utils";
|
||||
import { ChatContext } from "../../../types/common";
|
||||
export const TEXT_EDITOR_PREFIX = "_text_editor";
|
||||
|
||||
let components = createPlateUI({
|
||||
@@ -30,11 +31,10 @@ let components = createPlateUI({
|
||||
// customize your components by plugin key
|
||||
});
|
||||
const initials = [{ type: ELEMENT_PARAGRAPH, children: [{ text: "" }] }];
|
||||
type ctx = "channel" | "user";
|
||||
type Props = {
|
||||
updateDraft: (draft: any) => void | null;
|
||||
initialValue?: any;
|
||||
id: `${ctx}_${number}`;
|
||||
id: `${ChatContext}_${number}`;
|
||||
placeholder: string;
|
||||
sendMessages: any;
|
||||
updateMessages: any;
|
||||
@@ -51,7 +51,7 @@ const Plugins: FC<Props> = ({
|
||||
}) => {
|
||||
|
||||
// const { getMenuProps, getItemProps } = useComboboxControls();
|
||||
const [context, to] = id.split("_") as [ctx, number];
|
||||
const [context, to] = id.split("_") as [ChatContext, number];
|
||||
const { addStageFile } = useUploadFile({ context, id: to });
|
||||
const enableMentions = members.length > 0;
|
||||
const userData = useAppSelector((store) => store.users.byId);
|
||||
|
||||
@@ -7,6 +7,7 @@ import useSendMessage from "../../hook/useSendMessage";
|
||||
import { useAppSelector } from "../../../app/store";
|
||||
import { MessagePayload } from "../../../app/slices/message";
|
||||
import LinkifyText from "../LinkifyText";
|
||||
import { ChatContext } from "../../../types/common";
|
||||
|
||||
const renderContent = (data: MessagePayload) => {
|
||||
const { content_type, content, thumbnail = "", properties } = data;
|
||||
@@ -63,7 +64,7 @@ export default function Replying({
|
||||
id,
|
||||
mid
|
||||
}: {
|
||||
context: "user" | "channel";
|
||||
context: ChatContext;
|
||||
id: number;
|
||||
mid: number;
|
||||
}) {
|
||||
|
||||
@@ -7,6 +7,7 @@ import FullscreenIcon from "../../../assets/icons/fullscreen.svg";
|
||||
import ExitFullscreenIcon from "../../../assets/icons/fullscreen.exit.svg";
|
||||
import useUploadFile from "../../hook/useUploadFile";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { ChatContext } from "../../../types/common";
|
||||
|
||||
type Props = {
|
||||
sendMessages: () => void;
|
||||
@@ -15,7 +16,7 @@ type Props = {
|
||||
toggleMode: () => void;
|
||||
mode: "markdown" | "text";
|
||||
to: number;
|
||||
context: "user" | "channel";
|
||||
context: ChatContext;
|
||||
sendVisible: boolean
|
||||
};
|
||||
const Toolbar: FC<Props> = ({
|
||||
|
||||
@@ -5,6 +5,7 @@ import { getFileIcon, formatBytes } from "../../../utils";
|
||||
import useUploadFile from "../../../hook/useUploadFile";
|
||||
import EditIcon from "../../../../assets/icons/edit.svg";
|
||||
import DeleteIcon from "../../../../assets/icons/delete.svg";
|
||||
import { ChatContext } from "../../../../types/common";
|
||||
|
||||
type EditProps = {
|
||||
index: number;
|
||||
@@ -14,7 +15,7 @@ export default function UploadFileList({
|
||||
context,
|
||||
id
|
||||
}: {
|
||||
context: "user" | "channel";
|
||||
context: ChatContext;
|
||||
id: number;
|
||||
}) {
|
||||
const eidtor = useMixedEditor(`${context}_${id}`);
|
||||
|
||||
@@ -20,13 +20,14 @@ import { useAppDispatch, useAppSelector } from "../../../app/store";
|
||||
import TextInput from "../TextInput";
|
||||
import useUserOperation from "../../hook/useUserOperation";
|
||||
import StyledButton from "../styled/Button";
|
||||
import { ChatContext } from "../../../types/common";
|
||||
|
||||
const Modes = {
|
||||
text: "text",
|
||||
markdown: "markdown"
|
||||
};
|
||||
interface IProps {
|
||||
context?: "channel" | "user";
|
||||
context?: ChatContext;
|
||||
id: number;
|
||||
}
|
||||
const Send: FC<IProps> = ({
|
||||
@@ -35,7 +36,7 @@ const Send: FC<IProps> = ({
|
||||
id
|
||||
}) => {
|
||||
const { t } = useTranslation("chat");
|
||||
const { unblockThisContact, blocked } = useUserOperation({ uid: context == "user" ? id : undefined, cid: context == "channel" ? id : undefined });
|
||||
const { unblockThisContact, blocked } = useUserOperation({ uid: context == "dm" ? id : undefined, cid: context == "channel" ? id : undefined });
|
||||
const { resetStageFiles } = useUploadFile({ context, id });
|
||||
const { getDraft, getUpdateDraft } = useDraft({ context, id });
|
||||
const editor = useMixedEditor(`${context}_${id}`);
|
||||
@@ -144,7 +145,7 @@ const Send: FC<IProps> = ({
|
||||
const members =
|
||||
context == "channel" ? (channelsData[id]?.is_public ? uids : channelsData[id]?.members) : [];
|
||||
const isMarkdownMode = mode == Modes.markdown;
|
||||
if (context == "user" && blocked) {
|
||||
if (context == "dm" && blocked) {
|
||||
return <div className="p-5 bg-gray-200 rounded-lg w-full dark:bg-gray-600 text-red-300">
|
||||
{t("contact_block_tip")}
|
||||
<StyledButton className="mini ml-4" onClick={unblockThisContact}>{t("unblock")}</StyledButton>
|
||||
|
||||
@@ -9,11 +9,12 @@ import { updateChannelVisibleAside, updateDMVisibleAside } from '../../../app/sl
|
||||
import { addVoiceMember, updatePin, updateVoicingInfo, upsertVoiceList } from '../../../app/slices/voice';
|
||||
import { useAppSelector } from '../../../app/store';
|
||||
import { playAgoraVideo } from '../../utils';
|
||||
import { ChatContext } from '../../../types/common';
|
||||
|
||||
|
||||
type VoiceProps = {
|
||||
id: number,
|
||||
context?: "channel" | "dm"
|
||||
context?: ChatContext
|
||||
}
|
||||
const audioJoin = new Audio(AudioJoin);
|
||||
const useVoice = ({ id, context = "channel" }: VoiceProps) => {
|
||||
|
||||
@@ -3,9 +3,10 @@ import { useDispatch } from "react-redux";
|
||||
import { addMessage, MessagePayload } from "../../app/slices/message";
|
||||
import { addChannelMsg } from "../../app/slices/message.channel";
|
||||
import { addUserMsg } from "../../app/slices/message.user";
|
||||
import { ChatContext } from "../../types/common";
|
||||
|
||||
interface IProps {
|
||||
context: "channel" | "user";
|
||||
context: ChatContext;
|
||||
to: number;
|
||||
}
|
||||
export default function useAddLocalFileMessage({ context, to }: IProps) {
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { updateDraftMarkdown, updateDraftMixedText } from "../../app/slices/ui";
|
||||
import { useAppDispatch, useAppSelector } from "../../app/store";
|
||||
import { ChatContext } from "../../types/common";
|
||||
|
||||
const useDraft = ({ context = "user", id = 0 }: { context: "user" | "channel"; id: number }) => {
|
||||
const useDraft = ({ context = "dm", id = 0 }: { context: ChatContext; id: number }) => {
|
||||
const dispatch = useAppDispatch();
|
||||
const _key = `${context}_${id}`;
|
||||
const { draftMarkdown, draftMixedText } = useAppSelector((store) => {
|
||||
|
||||
@@ -2,14 +2,15 @@ import { removeMessage } from "../../app/slices/message";
|
||||
import { removeChannelMsg } from "../../app/slices/message.channel";
|
||||
import { removeUserMsg } from "../../app/slices/message.user";
|
||||
import { useAppDispatch } from "../../app/store";
|
||||
import { ChatContext } from "../../types/common";
|
||||
|
||||
// todo: check usage
|
||||
interface Props {
|
||||
context: "user" | "channel";
|
||||
context: ChatContext;
|
||||
id: number;
|
||||
}
|
||||
|
||||
export default function useRemoveLocalMessage({ context = "user", id = 0 }: Props) {
|
||||
export default function useRemoveLocalMessage({ context = "dm", id = 0 }: Props) {
|
||||
const dispatch = useAppDispatch();
|
||||
const removeContextMessage = context == "channel" ? removeChannelMsg : removeUserMsg;
|
||||
|
||||
|
||||
@@ -5,9 +5,10 @@ import { useSendMsgMutation } from "../../app/services/user";
|
||||
import { useReplyMessageMutation } from "../../app/services/message";
|
||||
import { useAppDispatch, useAppSelector } from "../../app/store";
|
||||
import { ContentTypeKey } from "../../types/message";
|
||||
import { ChatContext } from "../../types/common";
|
||||
|
||||
interface Props {
|
||||
context: "user" | "channel";
|
||||
context: ChatContext;
|
||||
from?: number;
|
||||
to: number;
|
||||
}
|
||||
@@ -21,7 +22,7 @@ interface SendMessagesDTO {
|
||||
|
||||
type SendMessageDTO = { type: ContentTypeKey } & Partial<MessagePayload> & { ignoreLocal?: boolean }
|
||||
const useSendMessage = (props?: Props) => {
|
||||
const { context = "user", from = 0, to = 0 } = props || {};
|
||||
const { context = "dm", from = 0, to = 0 } = props || {};
|
||||
const dispatch = useAppDispatch();
|
||||
const stageFiles = useAppSelector((store) => store.ui.uploadFiles[`${context}_${to}`] || []);
|
||||
const [replyMessage, { isError: replyErr, isLoading: replying, isSuccess: replySuccess }] =
|
||||
@@ -32,7 +33,7 @@ const useSendMessage = (props?: Props) => {
|
||||
] = useSendChannelMsgMutation();
|
||||
const [sendUserMsg, { isLoading: userSending, isSuccess: userSuccess, isError: userError }] =
|
||||
useSendMsgMutation();
|
||||
const sendFn = context == "user" ? sendUserMsg : sendChannelMsg;
|
||||
const sendFn = context == "dm" ? sendUserMsg : sendChannelMsg;
|
||||
const sendMessages = async ({
|
||||
type = "text",
|
||||
content,
|
||||
|
||||
@@ -6,9 +6,10 @@ import { usePrepareUploadFileMutation, useUploadFileMutation } from "../../app/s
|
||||
import { useAppDispatch, useAppSelector } from "../../app/store";
|
||||
import { Message } from "../../types/channel";
|
||||
import { UploadFileResponse } from "../../types/message";
|
||||
import { ChatContext } from "../../types/common";
|
||||
|
||||
interface IProps {
|
||||
context: "channel" | "user";
|
||||
context: ChatContext;
|
||||
id: number;
|
||||
}
|
||||
const useUploadFile = (props?: IProps) => {
|
||||
|
||||
@@ -31,11 +31,11 @@ const DMChat: FC<Props> = ({ uid = 0, dropFiles }) => {
|
||||
return (
|
||||
<Layout
|
||||
to={uid}
|
||||
context="user"
|
||||
context="dm"
|
||||
dropFiles={dropFiles}
|
||||
aside={
|
||||
<ul className="flex flex-col gap-6">
|
||||
<ServerVersionChecker version="0.3.6" empty={true}>
|
||||
<ServerVersionChecker version="0.3.7" empty={true}>
|
||||
<VoiceChat context={`dm`} id={uid} />
|
||||
</ServerVersionChecker>
|
||||
<Tooltip tip="Saved Items" placement="left">
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
// import { useEffect } from "react";
|
||||
import { ChatPrefixes } from "../../../app/config";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { ChatContext } from "../../../types/common";
|
||||
type Props = {
|
||||
context: "user" | "channel",
|
||||
context: ChatContext,
|
||||
name: string
|
||||
};
|
||||
const DnDTip = ({ context, name }: Props) => {
|
||||
|
||||
@@ -3,9 +3,10 @@ import clsx from 'clsx';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useAppSelector } from '../../../app/store';
|
||||
import getUnreadCount from '../utils';
|
||||
import { ChatContext } from '../../../types/common';
|
||||
|
||||
type Props = {
|
||||
context: "channel" | "user",
|
||||
context: ChatContext,
|
||||
id: number,
|
||||
scrollToBottom?: () => void
|
||||
}
|
||||
@@ -20,7 +21,7 @@ const NewMessageBottomTip = ({ context, id, scrollToBottom }: Props) => {
|
||||
} = useAppSelector((store) => {
|
||||
return {
|
||||
readIndex: context == "channel" ? store.footprint.readChannels[id] : store.footprint.readUsers[id],
|
||||
mids: context == "user" ? store.userMessage.byId[id] : store.channelMessage[id],
|
||||
mids: context == "dm" ? store.userMessage.byId[id] : store.channelMessage[id],
|
||||
selects: store.ui.selectMessages[`${context}_${id}`],
|
||||
loginUid: store.authData.user?.uid ?? 0,
|
||||
data: context == "channel" ? store.channels.byId[id] : undefined,
|
||||
|
||||
@@ -11,9 +11,10 @@ import IconClose from "../../../assets/icons/close.circle.svg";
|
||||
import ForwardModal from "../../../common/component/ForwardModal";
|
||||
import DeleteMessageConfirmModal from "../../../common/component/DeleteMessageConfirm";
|
||||
import { useAppDispatch, useAppSelector } from "../../../app/store";
|
||||
import { ChatContext } from "../../../types/common";
|
||||
|
||||
type Props = {
|
||||
context: "user" | "channel";
|
||||
context: ChatContext;
|
||||
id: number;
|
||||
};
|
||||
const Operations: FC<Props> = ({ context, id }) => {
|
||||
|
||||
@@ -12,8 +12,9 @@ import CustomList from './CustomList';
|
||||
import CustomHeader from './CustomHeader';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { updateHistoryMark } from '../../../../app/slices/footprint';
|
||||
import { ChatContext } from '../../../../types/common';
|
||||
type Props = {
|
||||
context: "user" | "channel",
|
||||
context: ChatContext,
|
||||
id: number
|
||||
}
|
||||
// const firstMsgIndex = 10000;
|
||||
@@ -36,8 +37,8 @@ const VirtualMessageFeed = ({ context, id }: Props) => {
|
||||
footprint
|
||||
} = useAppSelector((store) => {
|
||||
return {
|
||||
historyMid: context == "user" ? store.footprint.historyUsers[id] : store.footprint.historyChannels[id],
|
||||
mids: context == "user" ? store.userMessage.byId[id] : store.channelMessage[id],
|
||||
historyMid: context == "dm" ? store.footprint.historyUsers[id] : store.footprint.historyChannels[id],
|
||||
mids: context == "dm" ? store.userMessage.byId[id] : store.channelMessage[id],
|
||||
selects: store.ui.selectMessages[`${context}_${id}`],
|
||||
footprint: store.footprint,
|
||||
loginUser: store.authData.user,
|
||||
|
||||
@@ -19,6 +19,7 @@ import ImagePreview from "../../../common/component/ImagePreview";
|
||||
import VirtualMessageFeed from "./VirtualMessageFeed";
|
||||
import DMVoice from "./DMVoicing";
|
||||
import AddContactTip from "./AddContactTip";
|
||||
import { ChatContext } from "../../../types/common";
|
||||
|
||||
interface Props {
|
||||
readonly?: boolean;
|
||||
@@ -27,7 +28,7 @@ interface Props {
|
||||
users?: ReactElement | null;
|
||||
voice?: ReactElement | null;
|
||||
dropFiles?: File[];
|
||||
context: "channel" | "user";
|
||||
context: ChatContext;
|
||||
to: number;
|
||||
}
|
||||
|
||||
@@ -100,8 +101,8 @@ const Layout: FC<Props> = ({
|
||||
{header}
|
||||
<div className="w-full h-full flex items-start justify-between relative" >
|
||||
<div className="rounded-br-2xl flex flex-col absolute bottom-0 w-full h-full" ref={messagesContainer}>
|
||||
{context == "user" && <DMVoice uid={to} />}
|
||||
{context == "user" && <AddContactTip uid={to} />}
|
||||
{context == "dm" && <DMVoice uid={to} />}
|
||||
{context == "dm" && <AddContactTip uid={to} />}
|
||||
{/* 消息流 */}
|
||||
<VirtualMessageFeed key={`${context}_${to}`} context={context} id={to} />
|
||||
{/* 发送框 */}
|
||||
|
||||
@@ -10,6 +10,7 @@ import { updateSelectMessages } from "../../app/slices/ui";
|
||||
import { useAppSelector } from "../../app/store";
|
||||
import LinkifyText from "../../common/component/LinkifyText";
|
||||
import i18n from "../../i18n";
|
||||
import { ChatContext } from "../../types/common";
|
||||
|
||||
export function getUnreadCount({
|
||||
mids = [],
|
||||
@@ -122,7 +123,7 @@ type Params = {
|
||||
prev?: object | null;
|
||||
curr: object | null;
|
||||
contextId: number;
|
||||
context: "user" | "channel";
|
||||
context: ChatContext;
|
||||
};
|
||||
export const renderMessageFragment = ({
|
||||
readonly = false,
|
||||
@@ -132,7 +133,7 @@ export const renderMessageFragment = ({
|
||||
prev,
|
||||
curr = null,
|
||||
contextId = 0,
|
||||
context = "user"
|
||||
context = "dm"
|
||||
}: Params) => {
|
||||
if (!curr) return <div className="w-full h-[1px] invisible"></div>;
|
||||
let { created_at, mid } = curr;
|
||||
|
||||
@@ -19,7 +19,7 @@ const MessageInput = (props: Props) => {
|
||||
const { sendMessage } = useSendMessage({
|
||||
from,
|
||||
to,
|
||||
context: "user"
|
||||
context: "dm"
|
||||
});
|
||||
|
||||
const [content, setContent] = useState('');
|
||||
|
||||
Reference in New Issue
Block a user