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
No known key found for this signature in database
GPG key ID: 5059F398521BB0F6
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

2
external/revolt.js vendored

@ -1 +1 @@
Subproject commit 783c8d1a3e3ad6071d268b18077569262ea61602 Subproject commit 3fbd54281924e4778ed141de23305a8faaa31516

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(() => {
server function fetch() {
.fetchMembers() server
.then((data) => data.members) .fetchMembers()
.then(setData); .then((data) => data.members)
.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(