feat: new message tip

This commit is contained in:
Tristan Yang
2023-03-11 11:14:44 +08:00
parent 0cd7c1e9dd
commit 3302a87434
4 changed files with 123 additions and 2 deletions
+4 -1
View File
@@ -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"
}
+4 -1
View File
@@ -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;