Compare commits
5
Commits
lotus
...
50bb509484
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
50bb509484 | ||
|
|
149ea96957 | ||
|
|
093f10db5c | ||
|
|
6a0037ecec | ||
|
|
2bbd390a3b |
@@ -13,7 +13,38 @@ The source code is licensed under [AGPLv3](LICENSE), the same license as the ups
|
|||||||
The Lotus Chat logo (`public/res/Lotus.png`) is a derivative work based on the original Cinny logo by Ajay Bura and contributors, used under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/). The modified logo is © Lotus Guild and is also made available under CC BY 4.0.
|
The Lotus Chat logo (`public/res/Lotus.png`) is a derivative work based on the original Cinny logo by Ajay Bura and contributors, used under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/). The modified logo is © Lotus Guild and is also made available under CC BY 4.0.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
## Development Environment Setup
|
||||||
|
#### Getting correct Node version
|
||||||
|
- Ensure you have the correct version of node installed, specified in `.node-version`
|
||||||
|
- Use this command from the terminal to install nvm
|
||||||
|
```bash
|
||||||
|
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash
|
||||||
|
```
|
||||||
|
- Reload your terminal shell using (for Ubuntu):
|
||||||
|
```bash
|
||||||
|
source ~/.bashrc
|
||||||
|
```
|
||||||
|
- Install the specified Node version
|
||||||
|
```bash
|
||||||
|
NODE_VERSION="$(tr -d '[:space:]' < .node-version)"
|
||||||
|
nvm install "$NODE_VERSION"
|
||||||
|
nvm use "$NODE_VERSION"
|
||||||
|
```
|
||||||
|
- verify the correct version was installed by running
|
||||||
|
```bash
|
||||||
|
node --version
|
||||||
|
```
|
||||||
|
and comparing the output to what is listed in `.node-version`
|
||||||
|
#### Install npm packages
|
||||||
|
- To install the npm packages listed in `package.json` run:
|
||||||
|
```bash
|
||||||
|
npm i
|
||||||
|
```
|
||||||
|
### Start Development Server
|
||||||
|
```bash
|
||||||
|
npm run start
|
||||||
|
```
|
||||||
|
You should now have an active development server at `localhost:8080`, where you can make changes to the code and see the UI update in real time
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
### Messaging
|
### Messaging
|
||||||
|
|||||||
@@ -4,10 +4,11 @@ import { Page, PageContent, PageHeader } from '../../../components/page';
|
|||||||
import { SequenceCard } from '../../../components/sequence-card';
|
import { SequenceCard } from '../../../components/sequence-card';
|
||||||
import { SequenceCardStyle } from '../styles.css';
|
import { SequenceCardStyle } from '../styles.css';
|
||||||
import { SettingTile } from '../../../components/setting-tile';
|
import { SettingTile } from '../../../components/setting-tile';
|
||||||
import LotusLogo from '../../../../../public/res/Lotus.png';
|
|
||||||
import pkg from '../../../../../package.json';
|
import pkg from '../../../../../package.json';
|
||||||
import { clearCacheAndReload } from '../../../../client/initMatrix';
|
import { clearCacheAndReload } from '../../../../client/initMatrix';
|
||||||
import { useMatrixClient } from '../../../hooks/useMatrixClient';
|
import { useMatrixClient } from '../../../hooks/useMatrixClient';
|
||||||
|
import { getOriginBaseUrl, withOriginBaseUrl } from '../../../pages/pathUtils';
|
||||||
|
const LotusLogo = withOriginBaseUrl(getOriginBaseUrl(), '/Lotus.png');
|
||||||
|
|
||||||
type MSC1929Contact = {
|
type MSC1929Contact = {
|
||||||
matrix_id?: string;
|
matrix_id?: string;
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ import {
|
|||||||
} from '../../hooks/useClientConfig';
|
} from '../../hooks/useClientConfig';
|
||||||
import { AsyncStatus, useAsyncCallback } from '../../hooks/useAsyncCallback';
|
import { AsyncStatus, useAsyncCallback } from '../../hooks/useAsyncCallback';
|
||||||
import { LOGIN_PATH, REGISTER_PATH, RESET_PASSWORD_PATH } from '../paths';
|
import { LOGIN_PATH, REGISTER_PATH, RESET_PASSWORD_PATH } from '../paths';
|
||||||
import LotusLogo from '../../../../public/res/Lotus.png';
|
|
||||||
import { ServerPicker } from './ServerPicker';
|
import { ServerPicker } from './ServerPicker';
|
||||||
import { AutoDiscoveryAction, autoDiscovery } from '../../cs-api';
|
import { AutoDiscoveryAction, autoDiscovery } from '../../cs-api';
|
||||||
import { SpecVersionsLoader } from '../../components/SpecVersionsLoader';
|
import { SpecVersionsLoader } from '../../components/SpecVersionsLoader';
|
||||||
@@ -30,6 +29,8 @@ import { AuthFlowsLoader } from '../../components/AuthFlowsLoader';
|
|||||||
import { AuthFlowsProvider } from '../../hooks/useAuthFlows';
|
import { AuthFlowsProvider } from '../../hooks/useAuthFlows';
|
||||||
import { AuthServerProvider } from '../../hooks/useAuthServer';
|
import { AuthServerProvider } from '../../hooks/useAuthServer';
|
||||||
import { tryDecodeURIComponent } from '../../utils/dom';
|
import { tryDecodeURIComponent } from '../../utils/dom';
|
||||||
|
import { getOriginBaseUrl, withOriginBaseUrl } from '../pathUtils';
|
||||||
|
const LotusLogo = withOriginBaseUrl(getOriginBaseUrl(), '/Lotus.png');
|
||||||
|
|
||||||
const currentAuthPath = (pathname: string): string => {
|
const currentAuthPath = (pathname: string): string => {
|
||||||
if (matchPath(LOGIN_PATH, pathname)) {
|
if (matchPath(LOGIN_PATH, pathname)) {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import type { OidcRegistrationClientMetadata } from 'matrix-js-sdk';
|
import type { OidcRegistrationClientMetadata } from 'matrix-js-sdk';
|
||||||
import LotusLogo from '../../../../../public/res/Lotus.png';
|
|
||||||
import { OIDC_CALLBACK_PATH } from '../../paths';
|
import { OIDC_CALLBACK_PATH } from '../../paths';
|
||||||
import { getOriginBaseUrl, withOriginBaseUrl } from '../../pathUtils';
|
import { getOriginBaseUrl, withOriginBaseUrl } from '../../pathUtils';
|
||||||
|
const LotusLogo = withOriginBaseUrl(getOriginBaseUrl(), '/Lotus.png');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Absolute URL the OIDC provider redirects back to after authorization.
|
* Absolute URL the OIDC provider redirects back to after authorization.
|
||||||
|
|||||||
@@ -17,9 +17,6 @@ import { manualDndAtom } from '../../state/manualDnd';
|
|||||||
import { isSnoozeActive, notificationSnoozeUntilAtom } from '../../state/notificationSnooze';
|
import { isSnoozeActive, notificationSnoozeUntilAtom } from '../../state/notificationSnooze';
|
||||||
import { isWithinTimeWindow } from '../../utils/timeWindow';
|
import { isWithinTimeWindow } from '../../utils/timeWindow';
|
||||||
import { roomToUnreadAtom } from '../../state/room/roomToUnread';
|
import { roomToUnreadAtom } from '../../state/room/roomToUnread';
|
||||||
import LogoSVG from '../../../../public/res/lotus.png';
|
|
||||||
import LogoUnreadSVG from '../../../../public/res/lotus-unread.png';
|
|
||||||
import LogoHighlightSVG from '../../../../public/res/lotus-highlight.png';
|
|
||||||
import NotificationSound from '../../../../public/sound/notification.ogg';
|
import NotificationSound from '../../../../public/sound/notification.ogg';
|
||||||
import InviteSound from '../../../../public/sound/invite.ogg';
|
import InviteSound from '../../../../public/sound/invite.ogg';
|
||||||
import { notificationPermission, setFavicon, showOsNotification } from '../../utils/dom';
|
import { notificationPermission, setFavicon, showOsNotification } from '../../utils/dom';
|
||||||
@@ -29,7 +26,13 @@ import { settingsAtom } from '../../state/settings';
|
|||||||
import { allInvitesAtom } from '../../state/room-list/inviteList';
|
import { allInvitesAtom } from '../../state/room-list/inviteList';
|
||||||
import { useMatrixClient } from '../../hooks/useMatrixClient';
|
import { useMatrixClient } from '../../hooks/useMatrixClient';
|
||||||
import { useHydrateMsgDrafts } from '../../hooks/useHydrateMsgDrafts';
|
import { useHydrateMsgDrafts } from '../../hooks/useHydrateMsgDrafts';
|
||||||
import { getDirectRoomPath, getHomeRoomPath, getInboxInvitesPath } from '../pathUtils';
|
import {
|
||||||
|
getDirectRoomPath,
|
||||||
|
getHomeRoomPath,
|
||||||
|
getInboxInvitesPath,
|
||||||
|
getOriginBaseUrl,
|
||||||
|
withOriginBaseUrl,
|
||||||
|
} from '../pathUtils';
|
||||||
import { mDirectAtom } from '../../state/mDirectList';
|
import { mDirectAtom } from '../../state/mDirectList';
|
||||||
import {
|
import {
|
||||||
getMemberName,
|
getMemberName,
|
||||||
@@ -66,6 +69,9 @@ import {
|
|||||||
shouldNotifyThreadReply,
|
shouldNotifyThreadReply,
|
||||||
THREAD_NOTIFICATIONS_FALLBACK_BEHAVIOR,
|
THREAD_NOTIFICATIONS_FALLBACK_BEHAVIOR,
|
||||||
} from '../../utils/threadNotifications';
|
} from '../../utils/threadNotifications';
|
||||||
|
const LogoSVG = withOriginBaseUrl(getOriginBaseUrl(), '/lotus.png');
|
||||||
|
const LogoUnreadSVG = withOriginBaseUrl(getOriginBaseUrl(), '/lotus-unread.png');
|
||||||
|
const LogoHighlightSVG = withOriginBaseUrl(getOriginBaseUrl(), '/lotus-highlight.png');
|
||||||
|
|
||||||
// Grace period after the initial sync settles before invite notifications arm, so
|
// Grace period after the initial sync settles before invite notifications arm, so
|
||||||
// the async invite-atom population lands first and isn't mistaken for new invites.
|
// the async invite-atom population lands first and isn't mistaken for new invites.
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Box, Button, Icon, Icons, Text, config, toRem } from 'folds';
|
import { Box, Button, Icon, Icons, Text, config, toRem } from 'folds';
|
||||||
import { Page, PageHero, PageHeroSection } from '../../components/page';
|
import { Page, PageHero, PageHeroSection } from '../../components/page';
|
||||||
import LotusLogo from '../../../../public/res/Lotus.png';
|
|
||||||
import pkg from '../../../../package.json';
|
import pkg from '../../../../package.json';
|
||||||
|
import { getOriginBaseUrl, withOriginBaseUrl } from '../pathUtils';
|
||||||
|
const LotusLogo = withOriginBaseUrl(getOriginBaseUrl(), '/Lotus.png');
|
||||||
|
|
||||||
export function WelcomePage() {
|
export function WelcomePage() {
|
||||||
return (
|
return (
|
||||||
|
|||||||
+29
-6
@@ -17,23 +17,46 @@ import App from './app/pages/App';
|
|||||||
import './app/i18n';
|
import './app/i18n';
|
||||||
import { pushSessionToSW } from './sw-session';
|
import { pushSessionToSW } from './sw-session';
|
||||||
import { getFallbackSession } from './app/state/sessions';
|
import { getFallbackSession } from './app/state/sessions';
|
||||||
|
import { register } from 'module';
|
||||||
|
|
||||||
document.body.classList.add(configClass, varsClass);
|
document.body.classList.add(configClass, varsClass);
|
||||||
|
|
||||||
// Register Service Worker
|
// Register Service Worker
|
||||||
if ('serviceWorker' in navigator) {
|
if ('serviceWorker' in navigator) {
|
||||||
const swUrl =
|
const isProduction = import.meta.env.PROD;
|
||||||
import.meta.env.MODE === 'production'
|
const swUrl = isProduction
|
||||||
? `${trimTrailingSlash(import.meta.env.BASE_URL)}/sw.js`
|
? `${trimTrailingSlash(import.meta.env.BASE_URL)}/sw.js`
|
||||||
: `/dev-sw.js?dev-sw`;
|
: `/dev-sw.js?dev-sw`;
|
||||||
|
|
||||||
const sendSessionToSW = () => {
|
const sendSessionToSW = () => {
|
||||||
const session = getFallbackSession();
|
const session = getFallbackSession();
|
||||||
pushSessionToSW(session?.baseUrl, session?.accessToken);
|
pushSessionToSW(session?.baseUrl, session?.accessToken);
|
||||||
};
|
};
|
||||||
|
|
||||||
navigator.serviceWorker.register(swUrl).then(sendSessionToSW);
|
const registerServiceWorker = async () => {
|
||||||
navigator.serviceWorker.ready.then(sendSessionToSW);
|
try {
|
||||||
|
const registration = await navigator.serviceWorker.register(
|
||||||
|
swUrl,
|
||||||
|
isProduction
|
||||||
|
? undefined
|
||||||
|
: {
|
||||||
|
type: 'module',
|
||||||
|
scope: '/',
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
sendSessionToSW();
|
||||||
|
|
||||||
|
await navigator.serviceWorker.ready;
|
||||||
|
sendSessionToSW();
|
||||||
|
|
||||||
|
console.info('Service worker registered:', registration.scope);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Service worker registration failed:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void registerServiceWorker();
|
||||||
|
|
||||||
navigator.serviceWorker.addEventListener('message', (ev) => {
|
navigator.serviceWorker.addEventListener('message', (ev) => {
|
||||||
const { type } = ev.data ?? {};
|
const { type } = ev.data ?? {};
|
||||||
|
|||||||
+1
-1
@@ -246,7 +246,7 @@ const vendorChunks = (id) => {
|
|||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
appType: 'spa',
|
appType: 'spa',
|
||||||
publicDir: false,
|
publicDir: './public/res',
|
||||||
base: buildConfig.base,
|
base: buildConfig.base,
|
||||||
server: {
|
server: {
|
||||||
port: 8080,
|
port: 8080,
|
||||||
|
|||||||
Reference in New Issue
Block a user