feat: implement support for Subscribe event

This commit is contained in:
Paul Makles
2024-06-19 17:40:59 +01:00
parent 2722d0a854
commit 61304f18c2
4 changed files with 80 additions and 7 deletions

4
.env
View File

@@ -1,5 +1,5 @@
# VITE_API_URL=https://api.revolt.chat # VITE_API_URL=https://api.revolt.chat
VITE_API_URL=https://app.revolt.chat/api # VITE_API_URL=https://app.revolt.chat/api
# VITE_API_URL=http://local.revolt.chat:8000 # VITE_API_URL=http://local.revolt.chat:8000
# VITE_API_URL=https://revolt.chat/api VITE_API_URL=https://revolt.chat/api
VITE_THEMES_URL=https://themes.revolt.chat VITE_THEMES_URL=https://themes.revolt.chat

View File

@@ -163,6 +163,7 @@ const TextChannel = observer(({ channel }: { channel: ChannelI }) => {
const checkUnread = () => const checkUnread = () =>
channel.unread && channel.unread &&
document.hasFocus() &&
channel.client.unreads!.markRead( channel.client.unreads!.markRead(
channel._id, channel._id,
channel.last_message_id!, channel.last_message_id!,
@@ -176,6 +177,45 @@ const TextChannel = observer(({ channel }: { channel: ChannelI }) => {
); );
}, [channel]); }, [channel]);
useEffect(() => {
let lastSubscribed: number | undefined;
function subscribe() {
if (document.hasFocus()) {
const tenMinutesAgo = new Date();
tenMinutesAgo.setMinutes(tenMinutesAgo.getMinutes() - 10);
if (!lastSubscribed || +tenMinutesAgo > lastSubscribed) {
channel.server?.subscribe();
lastSubscribed = +tenMinutesAgo;
}
}
}
// Trigger logic every minute
const subTimer = setInterval(subscribe, 60e3);
function onFocus() {
// Mark channel as read if it's unread
if (channel.unread) {
channel.client.unreads!.markRead(
channel._id,
channel.last_message_id!,
true,
);
}
// Subscribe to channel if expired
subscribe();
}
addEventListener("focus", onFocus);
return () => {
removeEventListener("focus", onFocus);
clearInterval(subTimer);
};
}, [channel]);
return ( return (
<AgeGate <AgeGate
type="channel" type="channel"

View File

@@ -103,10 +103,43 @@ export const Members = ({ server }: Props) => {
const [query, setQuery] = useState(""); const [query, setQuery] = useState("");
useEffect(() => { useEffect(() => {
function fetch() {
server server
.fetchMembers() .fetchMembers()
.then((data) => data.members) .then((data) => data.members)
.then(setData); .then(setData);
}
fetch();
// Members may be invalidated if we stop receiving events
// This is not very accurate, this should be tracked within
// revolt.js so we know the true validity.
let valid = true,
invalidationTimer: number;
function waitToInvalidate() {
invalidationTimer = setTimeout(() => {
valid = false;
}, 15 * 60e3) as never; // 15 minutes
}
function cancelInvalidation() {
if (!valid) {
fetch();
valid = true;
}
clearTimeout(invalidationTimer);
}
addEventListener("blur", waitToInvalidate);
addEventListener("focus", cancelInvalidation);
return () => {
removeEventListener("blur", waitToInvalidate);
removeEventListener("focus", cancelInvalidation);
};
}, [server, setData]); }, [server, setData]);
const members = useMemo( const members = useMemo(