diff --git a/src/home/RegisteredView.jsx b/src/home/RegisteredView.jsx
index f25c9c9..6e43f20 100644
--- a/src/home/RegisteredView.jsx
+++ b/src/home/RegisteredView.jsx
@@ -17,6 +17,7 @@ import { Form } from "../form/Form";
export function RegisteredView({ client }) {
const [loading, setLoading] = useState(false);
const [error, setError] = useState();
+ const history = useHistory();
const onSubmit = useCallback(
(e) => {
e.preventDefault();
@@ -55,7 +56,6 @@ export function RegisteredView({ client }) {
const { modalState, modalProps } = useModalTriggerState();
const [existingRoomId, setExistingRoomId] = useState();
- const history = useHistory();
const onJoinExistingRoom = useCallback(() => {
history.push(`/${existingRoomId}`);
}, [history, existingRoomId]);
diff --git a/src/matrix-utils.js b/src/matrix-utils.js
index 977744d..184372c 100644
--- a/src/matrix-utils.js
+++ b/src/matrix-utils.js
@@ -50,6 +50,31 @@ export function roomAliasFromRoomName(roomName) {
.toLowerCase();
}
+export function roomNameFromRoomId(roomId) {
+ return roomId
+ .match(/([^:]+):.*$/)[1]
+ .substring(1)
+ .split("-")
+ .map((part) =>
+ part.length > 0 ? part.charAt(0).toUpperCase() + part.slice(1) : part
+ )
+ .join(" ");
+}
+
+export function isLocalRoomId(roomId) {
+ if (!roomId) {
+ return false;
+ }
+
+ const parts = roomId.match(/[^:]+:(.*)$/);
+
+ if (parts.length < 2) {
+ return false;
+ }
+
+ return parts[1] === defaultHomeserverHost;
+}
+
export async function createRoom(client, name) {
const { room_id, room_alias } = await client.createRoom({
visibility: "private",
diff --git a/src/room/GroupCallLoader.jsx b/src/room/GroupCallLoader.jsx
index 6fff1b7..799426f 100644
--- a/src/room/GroupCallLoader.jsx
+++ b/src/room/GroupCallLoader.jsx
@@ -2,6 +2,8 @@ import React from "react";
import { useLoadGroupCall } from "./useLoadGroupCall";
import { ErrorView, FullScreenView } from "../FullScreenView";
import { usePageTitle } from "../usePageTitle";
+import { isLocalRoomId } from "../matrix-utils";
+import { RoomNotFoundView } from "./RoomNotFoundView";
export function GroupCallLoader({ client, roomId, viaServers, children }) {
const { loading, error, groupCall } = useLoadGroupCall(
@@ -20,6 +22,10 @@ export function GroupCallLoader({ client, roomId, viaServers, children }) {
);
}
+ if (error && error.errcode === "M_UNKNOWN" && isLocalRoomId(roomId)) {
+ return ;
+ }
+
if (error) {
return ;
}
diff --git a/src/room/RoomNotFoundView.jsx b/src/room/RoomNotFoundView.jsx
new file mode 100644
index 0000000..2fc2f77
--- /dev/null
+++ b/src/room/RoomNotFoundView.jsx
@@ -0,0 +1,76 @@
+import React, { useState, useCallback } from "react";
+import { FullScreenView } from "../FullScreenView";
+import { Headline, Subtitle } from "../typography/Typography";
+import { createRoom, roomNameFromRoomId } from "../matrix-utils";
+import { FieldRow, ErrorMessage, InputField } from "../input/Input";
+import { Button } from "../button";
+import { Form } from "../form/Form";
+import { useHistory } from "react-router-dom";
+import styles from "./RoomNotFoundView.module.css";
+
+export function RoomNotFoundView({ client, roomId }) {
+ const history = useHistory();
+ const [loading, setLoading] = useState(false);
+ const [error, setError] = useState();
+ const roomName = roomNameFromRoomId(roomId);
+ const onSubmit = useCallback(
+ (e) => {
+ e.preventDefault();
+
+ async function submit() {
+ setError(undefined);
+ setLoading(true);
+
+ const roomIdOrAlias = await createRoom(client, roomName);
+
+ if (roomIdOrAlias) {
+ history.push(`/room/${roomIdOrAlias}`);
+ }
+ }
+
+ submit().catch((error) => {
+ console.error(error);
+ setLoading(false);
+ setError(error);
+ });
+ },
+ [client, roomName]
+ );
+
+ return (
+
+ Call Not Found
+ Would you like to create this call?
+
+
+ );
+}
diff --git a/src/room/RoomNotFoundView.module.css b/src/room/RoomNotFoundView.module.css
new file mode 100644
index 0000000..3270b87
--- /dev/null
+++ b/src/room/RoomNotFoundView.module.css
@@ -0,0 +1,11 @@
+.form {
+ padding: 0 24px;
+ justify-content: center;
+ max-width: 409px;
+ width: calc(100% - 48px);
+ margin-bottom: 72px;
+}
+
+.button {
+ width: 100%;
+}