diff --git a/src/components/navigation/items/ConnectionStatus.tsx b/src/components/navigation/items/ConnectionStatus.tsx
index 517c5b03..46a9f6cc 100644
--- a/src/components/navigation/items/ConnectionStatus.tsx
+++ b/src/components/navigation/items/ConnectionStatus.tsx
@@ -2,7 +2,7 @@ import { observer } from "mobx-react-lite";
import { Text } from "preact-i18n";
-import { Banner } from "@revoltchat/ui";
+import { Banner, Button, Column } from "@revoltchat/ui";
import { useSession } from "../../../controllers/client/ClientController";
@@ -18,15 +18,19 @@ function ConnectionStatus() {
} else if (session.state === "Disconnected") {
return (
-
-
- session.emit({
- action: "RETRY",
- })
- }>
-
-
+
+
+
+
);
} else if (session.state === "Connecting") {
diff --git a/src/controllers/client/ClientController.tsx b/src/controllers/client/ClientController.tsx
index df3216bd..be9497ce 100644
--- a/src/controllers/client/ClientController.tsx
+++ b/src/controllers/client/ClientController.tsx
@@ -1,6 +1,8 @@
import { action, computed, makeAutoObservable, ObservableMap } from "mobx";
import { Client, Nullable } from "revolt.js";
+import { injectController } from "../../lib/window";
+
import Auth from "../../mobx/stores/Auth";
import { modalController } from "../modals/ModalController";
@@ -35,7 +37,7 @@ class ClientController {
this.logoutCurrent = this.logoutCurrent.bind(this);
// Inject globally
- (window as any).clientController = this;
+ injectController("client", this);
}
/**
@@ -53,12 +55,14 @@ class ClientController {
.emit({
action: "LOGIN",
session: entry.session,
+ apiUrl: entry.apiUrl,
})
.catch((error) => {
if (error === "Forbidden" || error === "Unauthorized") {
this.sessions.delete(user_id);
auth.removeSession(user_id);
modalController.push({ type: "signed_out" });
+ session.destroy();
}
});
}
diff --git a/src/controllers/client/Session.tsx b/src/controllers/client/Session.tsx
index b19750e5..96c203b9 100644
--- a/src/controllers/client/Session.tsx
+++ b/src/controllers/client/Session.tsx
@@ -7,6 +7,7 @@ type Transition =
| {
action: "LOGIN";
session: SessionPrivate;
+ apiUrl?: string;
}
| {
action:
@@ -70,12 +71,12 @@ export default class Session {
});
}
- private createClient() {
+ private createClient(apiUrl?: string) {
this.client = new Client({
unreads: true,
autoReconnect: false,
onPongTimeout: "EXIT",
- apiURL: import.meta.env.VITE_API_URL,
+ apiURL: apiUrl ?? import.meta.env.VITE_API_URL,
});
this.client.addListener("dropped", this.onDropped);
@@ -110,7 +111,7 @@ export default class Session {
case "LOGIN": {
this.assert("Ready");
this.state = "Connecting";
- this.createClient();
+ this.createClient(data.apiUrl);
try {
await this.client!.useExistingSession(data.session);
@@ -135,10 +136,13 @@ export default class Session {
this.state = "Disconnected";
setTimeout(() => {
- this.emit({
- action: "RETRY",
- });
- }, 1500);
+ // Check we are still disconnected before retrying.
+ if (this.state === "Disconnected") {
+ this.emit({
+ action: "RETRY",
+ });
+ }
+ }, 1000);
}
break;
diff --git a/src/controllers/modals/ModalController.tsx b/src/controllers/modals/ModalController.tsx
index 48bb810d..8102cab8 100644
--- a/src/controllers/modals/ModalController.tsx
+++ b/src/controllers/modals/ModalController.tsx
@@ -9,6 +9,7 @@ import type { Client, API } from "revolt.js";
import { ulid } from "ulid";
import { determineLink } from "../../lib/links";
+import { injectController } from "../../lib/window";
import { getApplicationState } from "../../mobx/State";
@@ -52,6 +53,9 @@ class ModalController {
rendered: computed,
isVisible: computed,
});
+
+ // Inject globally
+ injectController("modal", this);
}
/**
diff --git a/src/lib/window.ts b/src/lib/window.ts
new file mode 100644
index 00000000..f1290106
--- /dev/null
+++ b/src/lib/window.ts
@@ -0,0 +1,6 @@
+export function injectController(key: string, value: any) {
+ (window as any).controllers = {
+ ...((window as any).controllers ?? {}),
+ [key]: value,
+ };
+}
diff --git a/src/mobx/stores/Auth.ts b/src/mobx/stores/Auth.ts
index 33799f7e..12574350 100644
--- a/src/mobx/stores/Auth.ts
+++ b/src/mobx/stores/Auth.ts
@@ -8,6 +8,7 @@ import Store from "../interfaces/Store";
interface Account {
session: Session;
+ apiUrl?: string;
}
export interface Data {
@@ -70,9 +71,10 @@ export default class Auth implements Store, Persistent {
/**
* Add a new session to the auth manager.
* @param session Session
+ * @param apiUrl Custom API URL
*/
- @action setSession(session: Session) {
- this.sessions.set(session.user_id, { session });
+ @action setSession(session: Session, apiUrl?: string) {
+ this.sessions.set(session.user_id, { session, apiUrl });
}
/**