feat: new message tip
This commit is contained in:
@@ -35,5 +35,8 @@
|
||||
"delete_msg_title": "Delete Message",
|
||||
"delete_msg_desc": "Are you sure want to delete {{msg}}?",
|
||||
"delete_msg_this": "this message",
|
||||
"delete_msg_these": "these messages"
|
||||
"delete_msg_these": "these messages",
|
||||
|
||||
"new_msg": "{{num}} new messages",
|
||||
"mark_read": "Mark As Read"
|
||||
}
|
||||
|
||||
@@ -36,5 +36,8 @@
|
||||
"delete_msg_title": "删除消息",
|
||||
"delete_msg_desc": "确定删除{{msg}}?",
|
||||
"delete_msg_this": "此消息",
|
||||
"delete_msg_these": "这些消息"
|
||||
"delete_msg_these": "这些消息",
|
||||
|
||||
"new_msg": "{{num}} 条新消息",
|
||||
"mark_read": "设为已读"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
import clsx from 'clsx';
|
||||
import { useState, useEffect } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useAppSelector } from '../../../app/store';
|
||||
import getUnreadCount from '../utils';
|
||||
import { triggerScrollHeight } from './MessageFeed';
|
||||
|
||||
type Props = {
|
||||
context: "channel" | "user",
|
||||
id: number
|
||||
}
|
||||
// linear-gradient(135deg,_#3C8CE7_0%,_#00EAFF_100%)
|
||||
const NewMessageBottomTip = ({ context, id }: Props) => {
|
||||
const [visible, setVisible] = useState(false);
|
||||
const { t } = useTranslation("chat");
|
||||
const {
|
||||
readIndex,
|
||||
mids,
|
||||
messageData,
|
||||
loginUid,
|
||||
} = useAppSelector((store) => {
|
||||
return {
|
||||
readIndex: context == "channel" ? store.footprint.readChannels[id] : store.footprint.readUsers[id],
|
||||
mids: context == "user" ? 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,
|
||||
messageData: store.message || {}
|
||||
};
|
||||
});
|
||||
const { unreads = 0 } = getUnreadCount({
|
||||
mids,
|
||||
readIndex,
|
||||
messageData,
|
||||
loginUid
|
||||
});
|
||||
useEffect(() => {
|
||||
const container = document.querySelector(`#VOCECHAT_FEED_${context}_${id}`) as HTMLElement;
|
||||
if (container) {
|
||||
const { scrollHeight, scrollTop, offsetHeight } = container;
|
||||
const deltaNum = scrollHeight - scrollTop - offsetHeight;
|
||||
const showTheTip = deltaNum > triggerScrollHeight && unreads > 0;
|
||||
console.log("show the tip", showTheTip);
|
||||
setVisible(showTheTip);
|
||||
}
|
||||
}, [context, id, unreads]);
|
||||
const handleMarkRead = () => {
|
||||
const container = document.querySelector(`#VOCECHAT_FEED_${context}_${id}`) as HTMLElement;
|
||||
if (container) {
|
||||
// scroll to bottom
|
||||
container.classList.add("scroll-smooth");
|
||||
container.scrollTop = container.scrollHeight;
|
||||
container.classList.remove("scroll-smooth");
|
||||
setVisible(false);
|
||||
}
|
||||
};
|
||||
return (
|
||||
<aside className={clsx(`absolute -top-2 right-4 -translate-y-full
|
||||
justify-between text-xs
|
||||
rounded-full py-1 px-3 text-white z-10
|
||||
bg-gradient-to-tl from-[#3C8CE7] to-[#00EAFF]`,
|
||||
visible ? "flex" : "hidden")}>
|
||||
<button onClick={handleMarkRead}>{t("new_msg", { num: unreads })}</button>
|
||||
<span className='absolute -left-1 -translate-x-full'>👇</span>
|
||||
</aside>
|
||||
);
|
||||
};
|
||||
|
||||
export default NewMessageBottomTip;
|
||||
@@ -0,0 +1,46 @@
|
||||
import clsx from 'clsx';
|
||||
import { useState, useEffect } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { triggerScrollHeight } from './MessageFeed';
|
||||
|
||||
type Props = {
|
||||
count: number,
|
||||
queryKey: string
|
||||
}
|
||||
// linear-gradient(135deg,_#3C8CE7_0%,_#00EAFF_100%)
|
||||
const NewMessageBottomTip = ({ count, queryKey }: Props) => {
|
||||
const [visible, setVisible] = useState(false);
|
||||
const { t } = useTranslation("chat");
|
||||
useEffect(() => {
|
||||
const container = document.querySelector(queryKey) as HTMLElement;
|
||||
if (container) {
|
||||
const { scrollHeight, scrollTop, offsetHeight } = container;
|
||||
const deltaNum = scrollHeight - scrollTop - offsetHeight;
|
||||
const showTheTip = deltaNum > triggerScrollHeight && count > 0;
|
||||
console.log("show the tip", showTheTip);
|
||||
setVisible(showTheTip);
|
||||
}
|
||||
}, [queryKey, count]);
|
||||
const handleMarkRead = () => {
|
||||
const container = document.querySelector(queryKey) as HTMLElement;
|
||||
if (container) {
|
||||
// scroll to bottom
|
||||
container.scrollTop = container.scrollHeight;
|
||||
setVisible(false);
|
||||
}
|
||||
};
|
||||
return (
|
||||
<aside className={clsx(`sticky top-0
|
||||
justify-between text-xs
|
||||
w-[95%] rounded-b-lg px-3 py-1 text-white z-10
|
||||
bg-gradient-to-tl from-[#3C8CE7] to-[#00EAFF]`,
|
||||
visible ? "flex" : "hidden")}>
|
||||
<span> {t("new_msg", { num: count })}</span>
|
||||
<button onClick={handleMarkRead}>
|
||||
{t("mark_read")}
|
||||
</button>
|
||||
</aside>
|
||||
);
|
||||
};
|
||||
|
||||
export default NewMessageBottomTip;
|
||||
Reference in New Issue
Block a user