diff --git a/.env b/.env index c8b232c2..c13d0719 100644 --- a/.env +++ b/.env @@ -1,5 +1,5 @@ # 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=https://revolt.chat/api +VITE_API_URL=https://revolt.chat/api VITE_THEMES_URL=https://themes.revolt.chat diff --git a/.env.production b/.env.production new file mode 100644 index 00000000..327e0600 --- /dev/null +++ b/.env.production @@ -0,0 +1,2 @@ +# VITE_API_URL=http://local.revolt.chat:8000 +VITE_API_URL=https://app.revolt.chat/api diff --git a/src/controllers/client/jsx/legacy/FileUploads.tsx b/src/controllers/client/jsx/legacy/FileUploads.tsx index ec36bb6f..e2a44322 100644 --- a/src/controllers/client/jsx/legacy/FileUploads.tsx +++ b/src/controllers/client/jsx/legacy/FileUploads.tsx @@ -12,7 +12,7 @@ import { IconButton, Preloader } from "@revoltchat/ui"; import { determineFileSize } from "../../../../lib/fileSize"; import { modalController } from "../../../modals/ModalController"; -import { useClient } from "../../ClientController"; +import { clientController, useClient } from "../../ClientController"; import { takeError } from "../error"; type BehaviourType = @@ -67,9 +67,16 @@ export async function uploadFile( const formData = new FormData(); formData.append("file", file); + const client = clientController.getActiveSession()?.client; + const sesToken = + typeof client?.session === "string" + ? client.session + : client?.session?.token; + const res = await Axios.post(`${autumnURL}/${tag}`, formData, { headers: { "Content-Type": "multipart/form-data", + "X-Session-Token": sesToken, }, ...config, }); diff --git a/src/pages/channels/Channel.tsx b/src/pages/channels/Channel.tsx index 3545fd55..62857c79 100644 --- a/src/pages/channels/Channel.tsx +++ b/src/pages/channels/Channel.tsx @@ -1,5 +1,6 @@ import { Hash } from "@styled-icons/boxicons-regular"; import { Ghost } from "@styled-icons/boxicons-solid"; +import dayjs from "dayjs"; import { reaction } from "mobx"; import { observer } from "mobx-react-lite"; import { Redirect, useParams } from "react-router-dom"; @@ -163,6 +164,7 @@ const TextChannel = observer(({ channel }: { channel: ChannelI }) => { const checkUnread = () => channel.unread && + document.hasFocus() && channel.client.unreads!.markRead( channel._id, channel.last_message_id!, @@ -176,6 +178,46 @@ const TextChannel = observer(({ channel }: { channel: ChannelI }) => { ); }, [channel]); + useEffect(() => { + let lastSubscribed: number | undefined; + function subscribe() { + if (document.hasFocus()) { + if ( + !lastSubscribed || + dayjs().subtract(10, "minutes").isAfter(lastSubscribed) + ) { + lastSubscribed = +new Date(); + channel.server?.subscribe(); + } + } + } + + // Trigger logic every minute + const subTimer = setInterval(subscribe, 60e3); + subscribe(); + + 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 ( { const [query, setQuery] = useState(""); useEffect(() => { - server - .fetchMembers() - .then((data) => data.members) - .then(setData); + function fetch() { + server + .fetchMembers() + .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]); const members = useMemo(