Add configurable default homeserver
This commit is contained in:
parent
34d0483c99
commit
39d28a0488
8 changed files with 71 additions and 88 deletions
3
.env
3
.env
|
@ -4,6 +4,9 @@
|
|||
# https://vitejs.dev/guide/env-and-mode.html#env-files
|
||||
####
|
||||
|
||||
# Used for determining the homeserver to use for short urls etc.
|
||||
# VITE_DEFAULT_HOMESERVER=http://localhost:8008
|
||||
|
||||
# The room id for the space to use for listing public group call rooms
|
||||
# VITE_PUBLIC_SPACE_ROOM_ID=!hjdfshkdskjdsk:myhomeserver.com
|
||||
|
||||
|
|
51
src/App.jsx
51
src/App.jsx
|
@ -28,18 +28,17 @@ import { Home } from "./Home";
|
|||
import { LoginPage } from "./LoginPage";
|
||||
import { RegisterPage } from "./RegisterPage";
|
||||
import { Room } from "./Room";
|
||||
import { ClientProvider } from "./ConferenceCallManagerHooks";
|
||||
import {
|
||||
ClientProvider,
|
||||
defaultHomeserverHost,
|
||||
} from "./ConferenceCallManagerHooks";
|
||||
import { useFocusVisible } from "@react-aria/interactions";
|
||||
import styles from "./App.module.css";
|
||||
import { ErrorView, LoadingView } from "./FullScreenView";
|
||||
import { LoadingView } from "./FullScreenView";
|
||||
|
||||
const SentryRoute = Sentry.withSentryRouting(Route);
|
||||
|
||||
const { protocol, host } = window.location;
|
||||
// Assume homeserver is hosted on same domain (proxied in development by vite)
|
||||
const homeserverUrl = `${protocol}//${host}`;
|
||||
|
||||
export default function App() {
|
||||
export default function App({ history }) {
|
||||
const { isFocusVisible } = useFocusVisible();
|
||||
|
||||
useEffect(() => {
|
||||
|
@ -58,8 +57,8 @@ export default function App() {
|
|||
}, [isFocusVisible]);
|
||||
|
||||
return (
|
||||
<Router>
|
||||
<ClientProvider homeserverUrl={homeserverUrl}>
|
||||
<Router history={history}>
|
||||
<ClientProvider>
|
||||
<OverlayProvider>
|
||||
<Switch>
|
||||
<SentryRoute exact path="/">
|
||||
|
@ -87,10 +86,8 @@ export default function App() {
|
|||
function RoomRedirect() {
|
||||
const { pathname } = useLocation();
|
||||
const history = useHistory();
|
||||
const [error, setError] = useState();
|
||||
|
||||
useEffect(() => {
|
||||
async function redirect() {
|
||||
let roomId = pathname;
|
||||
|
||||
if (pathname.startsWith("/")) {
|
||||
|
@ -98,39 +95,11 @@ function RoomRedirect() {
|
|||
}
|
||||
|
||||
if (!roomId.startsWith("#") && !roomId.startsWith("!")) {
|
||||
let loginHomeserverUrl = homeserverUrl.trim();
|
||||
|
||||
if (!loginHomeserverUrl.includes("://")) {
|
||||
loginHomeserverUrl = "https://" + loginHomeserverUrl;
|
||||
}
|
||||
|
||||
try {
|
||||
const wellKnownUrl = new URL(
|
||||
"/.well-known/matrix/client",
|
||||
window.location
|
||||
);
|
||||
const response = await fetch(wellKnownUrl);
|
||||
const config = await response.json();
|
||||
|
||||
if (config["m.homeserver"]) {
|
||||
loginHomeserverUrl = config["m.homeserver"];
|
||||
}
|
||||
} catch (error) {}
|
||||
|
||||
const { host } = new URL(loginHomeserverUrl);
|
||||
|
||||
roomId = `#${roomId}:${host}`;
|
||||
roomId = `#${roomId}:${defaultHomeserverHost}`;
|
||||
}
|
||||
|
||||
history.replace(`/room/${roomId}`);
|
||||
}
|
||||
|
||||
redirect().catch(setError);
|
||||
}, [history, pathname]);
|
||||
|
||||
if (error) {
|
||||
return <ErrorView error={error} />;
|
||||
}
|
||||
}, [pathname, history]);
|
||||
|
||||
return <LoadingView />;
|
||||
}
|
||||
|
|
|
@ -29,6 +29,12 @@ import {
|
|||
} from "matrix-js-sdk/src/browser-index";
|
||||
import { useHistory } from "react-router-dom";
|
||||
|
||||
export const defaultHomeserver =
|
||||
import.meta.env.VITE_DEFAULT_HOMESERVER ||
|
||||
`${window.location.protocol}//${window.location.host}`;
|
||||
|
||||
export const defaultHomeserverHost = new URL(defaultHomeserver).host;
|
||||
|
||||
const ClientContext = createContext();
|
||||
|
||||
function waitForSync(client) {
|
||||
|
@ -100,18 +106,10 @@ export async function fetchGroupCall(
|
|||
});
|
||||
}
|
||||
|
||||
export function ClientProvider({ homeserverUrl, children }) {
|
||||
export function ClientProvider({ children }) {
|
||||
const history = useHistory();
|
||||
const [
|
||||
{
|
||||
loading,
|
||||
isAuthenticated,
|
||||
isPasswordlessUser,
|
||||
isGuest,
|
||||
client,
|
||||
userName,
|
||||
displayName,
|
||||
},
|
||||
{ loading, isAuthenticated, isPasswordlessUser, isGuest, client, userName },
|
||||
setState,
|
||||
] = useState({
|
||||
loading: true,
|
||||
|
@ -120,7 +118,6 @@ export function ClientProvider({ homeserverUrl, children }) {
|
|||
isGuest: false,
|
||||
client: undefined,
|
||||
userName: null,
|
||||
displayName: null,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
|
@ -140,7 +137,7 @@ export function ClientProvider({ homeserverUrl, children }) {
|
|||
|
||||
const client = await initClient(
|
||||
{
|
||||
baseUrl: homeserverUrl,
|
||||
baseUrl: defaultHomeserver,
|
||||
accessToken: access_token,
|
||||
userId: user_id,
|
||||
deviceId: device_id,
|
||||
|
@ -255,14 +252,14 @@ export function ClientProvider({ homeserverUrl, children }) {
|
|||
|
||||
const registerGuest = useCallback(async () => {
|
||||
try {
|
||||
const registrationClient = matrix.createClient(homeserverUrl);
|
||||
const registrationClient = matrix.createClient(defaultHomeserver);
|
||||
|
||||
const { user_id, device_id, access_token } =
|
||||
await registrationClient.registerGuest({});
|
||||
|
||||
const client = await initClient(
|
||||
{
|
||||
baseUrl: homeserverUrl,
|
||||
baseUrl: defaultHomeserver,
|
||||
accessToken: access_token,
|
||||
userId: user_id,
|
||||
deviceId: device_id,
|
||||
|
@ -303,7 +300,7 @@ export function ClientProvider({ homeserverUrl, children }) {
|
|||
|
||||
const register = useCallback(async (username, password, passwordlessUser) => {
|
||||
try {
|
||||
const registrationClient = matrix.createClient(homeserverUrl);
|
||||
const registrationClient = matrix.createClient(defaultHomeserver);
|
||||
|
||||
const { user_id, device_id, access_token } =
|
||||
await registrationClient.register(username, password, null, {
|
||||
|
@ -311,7 +308,7 @@ export function ClientProvider({ homeserverUrl, children }) {
|
|||
});
|
||||
|
||||
const client = await initClient({
|
||||
baseUrl: homeserverUrl,
|
||||
baseUrl: defaultHomeserver,
|
||||
accessToken: access_token,
|
||||
userId: user_id,
|
||||
deviceId: device_id,
|
||||
|
@ -617,7 +614,7 @@ export function getRoomUrl(roomId) {
|
|||
if (roomId.startsWith("#")) {
|
||||
const [localPart, host] = roomId.replace("#", "").split(":");
|
||||
|
||||
if (host !== window.location.host) {
|
||||
if (host !== defaultHomeserverHost) {
|
||||
return `${window.location.host}/room/${roomId}`;
|
||||
} else {
|
||||
return `${window.location.host}/${localPart}`;
|
||||
|
|
|
@ -62,7 +62,7 @@ export function Home() {
|
|||
async function onCreateRoom() {
|
||||
let _client = client;
|
||||
|
||||
if (!_client) {
|
||||
if (!_client || isGuest) {
|
||||
_client = await register(userName, randomString(16), true);
|
||||
}
|
||||
|
||||
|
@ -88,7 +88,7 @@ export function Home() {
|
|||
setCreatingRoom(false);
|
||||
});
|
||||
},
|
||||
[client, history, register]
|
||||
[client, history, register, isGuest]
|
||||
);
|
||||
|
||||
const onJoinRoom = useCallback(
|
||||
|
|
|
@ -14,19 +14,21 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React, { useCallback, useRef, useState } from "react";
|
||||
import React, { useCallback, useRef, useState, useMemo } from "react";
|
||||
import { useHistory, useLocation, Link } from "react-router-dom";
|
||||
import { ReactComponent as Logo } from "./icons/LogoLarge.svg";
|
||||
import { FieldRow, InputField, ErrorMessage } from "./Input";
|
||||
import { Button } from "./button";
|
||||
import { useClient } from "./ConferenceCallManagerHooks";
|
||||
import {
|
||||
useClient,
|
||||
defaultHomeserver,
|
||||
defaultHomeserverHost,
|
||||
} from "./ConferenceCallManagerHooks";
|
||||
import styles from "./LoginPage.module.css";
|
||||
|
||||
export function LoginPage() {
|
||||
const { login } = useClient();
|
||||
const [homeserver, setHomeServer] = useState(
|
||||
`${window.location.protocol}//${window.location.host}`
|
||||
);
|
||||
const [homeserver, setHomeServer] = useState(defaultHomeserver);
|
||||
const usernameRef = useRef();
|
||||
const passwordRef = useRef();
|
||||
const history = useHistory();
|
||||
|
@ -57,6 +59,14 @@ export function LoginPage() {
|
|||
[login, location, history, homeserver]
|
||||
);
|
||||
|
||||
const homeserverHost = useMemo(() => {
|
||||
try {
|
||||
return new URL(homeserver).host;
|
||||
} catch (_error) {
|
||||
return defaultHomeserverHost;
|
||||
}
|
||||
}, [homeserver]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className={styles.container}>
|
||||
|
@ -76,7 +86,7 @@ export function LoginPage() {
|
|||
autoCorrect="off"
|
||||
autoCapitalize="none"
|
||||
prefix="@"
|
||||
suffix={`:${window.location.host}`}
|
||||
suffix={`:${homeserverHost}`}
|
||||
/>
|
||||
</FieldRow>
|
||||
<FieldRow>
|
||||
|
|
|
@ -18,7 +18,7 @@ import React, { useCallback, useEffect, useRef, useState } from "react";
|
|||
import { useHistory, useLocation, Link } from "react-router-dom";
|
||||
import { FieldRow, InputField, ErrorMessage } from "./Input";
|
||||
import { Button } from "./button";
|
||||
import { useClient } from "./ConferenceCallManagerHooks";
|
||||
import { useClient, defaultHomeserverHost } from "./ConferenceCallManagerHooks";
|
||||
import styles from "./LoginPage.module.css";
|
||||
import { ReactComponent as Logo } from "./icons/LogoLarge.svg";
|
||||
import { LoadingView } from "./FullScreenView";
|
||||
|
@ -126,7 +126,7 @@ export function RegisterPage() {
|
|||
autoCorrect="off"
|
||||
autoCapitalize="none"
|
||||
prefix="@"
|
||||
suffix={`:${window.location.host}`}
|
||||
suffix={`:${defaultHomeserverHost}`}
|
||||
value={
|
||||
isAuthenticated && isPasswordlessUser
|
||||
? client.getUserIdLocalpart()
|
||||
|
|
|
@ -37,6 +37,7 @@ import { useGroupCall } from "matrix-react-sdk/src/hooks/useGroupCall";
|
|||
import { useCallFeed } from "matrix-react-sdk/src/hooks/useCallFeed";
|
||||
import { useMediaStream } from "matrix-react-sdk/src/hooks/useMediaStream";
|
||||
import {
|
||||
getRoomUrl,
|
||||
useClient,
|
||||
useLoadGroupCall,
|
||||
useProfile,
|
||||
|
@ -294,7 +295,6 @@ function RoomSetupView({
|
|||
}) {
|
||||
const { stream } = useCallFeed(localCallFeed);
|
||||
const videoRef = useMediaStream(stream, true);
|
||||
const location = useLocation();
|
||||
|
||||
useEffect(() => {
|
||||
onInitLocalCallFeed();
|
||||
|
@ -354,7 +354,7 @@ function RoomSetupView({
|
|||
</div>
|
||||
<p>Or</p>
|
||||
<CopyButton
|
||||
value={window.location.href}
|
||||
value={getRoomUrl(roomId)}
|
||||
className={styles.copyButton}
|
||||
copiedMessage="Call link copied"
|
||||
>
|
||||
|
|
|
@ -14,16 +14,19 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { defineConfig } from "vite";
|
||||
import { defineConfig, loadEnv } from "vite";
|
||||
import svgrPlugin from "vite-plugin-svgr";
|
||||
import path from "path";
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
export default defineConfig(({ mode }) => {
|
||||
const env = loadEnv(mode, process.cwd());
|
||||
|
||||
return {
|
||||
plugins: [svgrPlugin()],
|
||||
server: {
|
||||
proxy: {
|
||||
"/_matrix": "http://localhost:8008",
|
||||
"/_matrix": env.VITE_DEFAULT_HOMESERVER || "http://localhost:8008",
|
||||
},
|
||||
},
|
||||
resolve: {
|
||||
|
@ -32,4 +35,5 @@ export default defineConfig({
|
|||
},
|
||||
dedupe: ["react", "react-dom", "matrix-js-sdk"],
|
||||
},
|
||||
};
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue