add option to use hash router in config and remove appVersion

This commit is contained in:
Ajay Bura 2024-01-20 20:58:22 +05:30
parent fdf2521192
commit 845eebe98a
11 changed files with 78 additions and 63 deletions

3
build.config.ts Normal file
View file

@ -0,0 +1,3 @@
export default {
base: '/',
};

View file

@ -1,6 +1,4 @@
{
"appVersion": "3.2.0",
"basename": "/",
"defaultHomeserver": 2,
"homeserverList": [
"converser.eu",
@ -10,5 +8,10 @@
"mozilla.org",
"xmr.se"
],
"allowCustomHomeservers": true
"allowCustomHomeservers": true,
"hashRouter": {
"enabled": false,
"basename": "/"
}
}

View file

@ -1,9 +1,11 @@
import { ReactNode, useEffect } from 'react';
import { AsyncStatus, useAsyncCallback } from '../hooks/useAsyncCallback';
import { ClientConfig } from '../hooks/useClientConfig';
import { trimTrailingSlash } from '../utils/common';
const getClientConfig = async (): Promise<ClientConfig> => {
const config = await fetch('/config.json', { method: 'GET' });
const url = `${trimTrailingSlash(import.meta.env.BASE_URL)}/config.json`;
const config = await fetch(url, { method: 'GET' });
return config.json();
};

View file

@ -1,11 +1,14 @@
import { createContext, useContext } from 'react';
export type ClientConfig = {
appVersion?: string;
basename?: string;
defaultHomeserver?: number;
homeserverList?: string[];
allowCustomHomeservers?: boolean;
hashRouter?: {
enabled?: boolean;
basename?: string;
};
};
const ClientConfigContext = createContext<ClientConfig | null>(null);

View file

@ -1,27 +1,26 @@
import { useMemo } from 'react';
import { useClientConfig } from './useClientConfig';
const START_SLASHES_REG = /^\/+/g;
const END_SLASHES_REG = /\/+$/g;
const trimStartSlash = (str: string): string => str.replace(START_SLASHES_REG, '');
const trimEndSlash = (str: string): string => str.replace(END_SLASHES_REG, '');
const trimSlash = (str: string): string => trimStartSlash(trimEndSlash(str));
import { trimLeadingSlash, trimSlash, trimTrailingSlash } from '../utils/common';
export const usePathWithOrigin = (path: string): string => {
const clientConfig = useClientConfig();
const basename = clientConfig.basename ?? '';
const { hashRouter } = useClientConfig();
const { origin } = window.location;
const pathWithOrigin = useMemo(() => {
let url: string = trimSlash(origin);
url += `/${trimSlash(basename)}`;
url = trimEndSlash(url);
url += `/${trimStartSlash(path)}`;
url += `/${trimSlash(import.meta.env.BASE_URL ?? '')}`;
url = trimTrailingSlash(url);
if (hashRouter?.enabled) {
url += `/#/${trimSlash(hashRouter.basename ?? '')}`;
url = trimTrailingSlash(url);
}
url += `/${trimLeadingSlash(path)}`;
return url;
}, [path, basename, origin]);
}, [path, hashRouter, origin]);
return pathWithOrigin;
};

View file

@ -4,6 +4,7 @@ import {
Route,
RouterProvider,
createBrowserRouter,
createHashRouter,
createRoutesFromElements,
redirect,
} from 'react-router-dom';
@ -17,40 +18,44 @@ import Client from '../templates/client/Client';
import { getLoginPath } from './pathUtils';
const createRouter = (clientConfig: ClientConfig) => {
const { basename } = clientConfig;
const router = createBrowserRouter(
createRoutesFromElements(
<Route>
<Route
path={ROOT_PATH}
loader={() => {
if (isAuthenticated()) return redirect('/home');
return redirect(getLoginPath());
}}
/>
<Route loader={authLayoutLoader} element={<AuthLayout />}>
<Route path={LOGIN_PATH} element={<Login />} />
<Route path={REGISTER_PATH} element={<Register />} />
<Route path={RESET_PASSWORD_PATH} element={<ResetPassword />} />
</Route>
const { hashRouter } = clientConfig;
<Route
loader={() => {
if (!isAuthenticated()) return redirect(getLoginPath());
return null;
}}
>
<Route path="/home" element={<Client />} />
<Route path="/direct" element={<p>direct</p>} />
<Route path="/:spaceIdOrAlias" element={<p>:spaceIdOrAlias</p>} />
<Route path="/explore" element={<p>explore</p>} />
</Route>
<Route path="/*" element={<p>Page not found</p>} />
const routes = createRoutesFromElements(
<Route>
<Route
path={ROOT_PATH}
loader={() => {
if (isAuthenticated()) return redirect('/home');
return redirect(getLoginPath());
}}
/>
<Route loader={authLayoutLoader} element={<AuthLayout />}>
<Route path={LOGIN_PATH} element={<Login />} />
<Route path={REGISTER_PATH} element={<Register />} />
<Route path={RESET_PASSWORD_PATH} element={<ResetPassword />} />
</Route>
),
{ basename }
<Route
loader={() => {
if (!isAuthenticated()) return redirect(getLoginPath());
return null;
}}
>
<Route path="/home" element={<Client />} />
<Route path="/direct" element={<p>direct</p>} />
<Route path="/:spaceIdOrAlias" element={<p>:spaceIdOrAlias</p>} />
<Route path="/explore" element={<p>explore</p>} />
</Route>
<Route path="/*" element={<p>Page not found</p>} />
</Route>
);
return router;
if (hashRouter?.enabled) {
return createHashRouter(routes, { basename: hashRouter.basename });
}
return createBrowserRouter(routes, {
basename: import.meta.env.BASE_URL,
});
};
// TODO: app crash boundary

View file

@ -1,11 +1,8 @@
import React from 'react';
import { Box, Text } from 'folds';
import * as css from './styles.css';
import { useClientConfig } from '../../hooks/useClientConfig';
export function AuthFooter() {
const { appVersion } = useClientConfig();
return (
<Box className={css.AuthFooter} justifyContent="Center" gap="400" wrap="Wrap">
<Text as="a" size="T300" href="https://cinny.in" target="_blank" rel="noreferrer">
@ -18,7 +15,7 @@ export function AuthFooter() {
target="_blank"
rel="noreferrer"
>
{`v${appVersion ?? '0.0.0'}`}
v3.2.0
</Text>
<Text as="a" size="T300" href="https://twitter.com/cinnyapp" target="_blank" rel="noreferrer">
Twitter

View file

@ -89,9 +89,9 @@ export const parseGeoUri = (location: string) => {
};
};
export const trimTrailingSlash = (str: string) => {
if (str.endsWith('/')) {
return str.slice(0, str.length - 1);
}
return str;
};
const START_SLASHES_REG = /^\/+/g;
const END_SLASHES_REG = /\/+$/g;
export const trimLeadingSlash = (str: string): string => str.replace(START_SLASHES_REG, '');
export const trimTrailingSlash = (str: string): string => str.replace(END_SLASHES_REG, '');
export const trimSlash = (str: string): string => trimLeadingSlash(trimTrailingSlash(str));

2
src/ext.d.ts vendored
View file

@ -1,3 +1,5 @@
/// <reference types="vite/client" />
declare module 'browser-encrypt-attachment' {
export interface EncryptedAttachmentInfo {
v: string;

View file

@ -8,6 +8,7 @@
"strict": true,
"esModuleInterop": true,
"moduleResolution": "Node",
"resolveJsonModule": true,
"outDir": "dist",
"skipLibCheck": true
},

View file

@ -5,8 +5,8 @@ import { viteStaticCopy } from 'vite-plugin-static-copy';
import { vanillaExtractPlugin } from "@vanilla-extract/vite-plugin";
import { NodeGlobalsPolyfillPlugin } from '@esbuild-plugins/node-globals-polyfill';
import inject from '@rollup/plugin-inject';
import { svgLoader } from './viteSvgLoader';
import config from './config.json'
import { svgLoader } from './viteSvgLoader'
import buildConfig from "./build.config"
const copyFiles = {
targets: [
@ -40,7 +40,7 @@ const copyFiles = {
export default defineConfig({
appType: 'spa',
publicDir: false,
base: config.basename ?? "/",
base: buildConfig.base,
server: {
port: 8080,
host: true,