feat: fully migrate to pnpm workspace
parent
663d3c22d1
commit
6239160d09
|
|
@ -7,3 +7,6 @@
|
||||||
[submodule "external/revolt.js"]
|
[submodule "external/revolt.js"]
|
||||||
path = external/revolt.js
|
path = external/revolt.js
|
||||||
url = https://github.com/revoltchat/revolt.js
|
url = https://github.com/revoltchat/revolt.js
|
||||||
|
[submodule "packages/hast-util-table-cell-style"]
|
||||||
|
path = packages/hast-util-table-cell-style
|
||||||
|
url = https://github.com/revoltchat/hast-util-table-cell-style
|
||||||
|
|
|
||||||
9
.npmrc
9
.npmrc
|
|
@ -1 +1,8 @@
|
||||||
auto-install-peers=true
|
# Allow us to use the monorepo with client being the root
|
||||||
|
ignore-workspace-root-check=true
|
||||||
|
|
||||||
|
# We cannot satisfy certain peer dependencies
|
||||||
|
strict-peer-dependencies=false
|
||||||
|
|
||||||
|
# Required for Vite.js to resolve packages
|
||||||
|
shamefully-hoist=true
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -4,10 +4,11 @@ WORKDIR /usr/src/app
|
||||||
COPY . .
|
COPY . .
|
||||||
COPY .env.build .env
|
COPY .env.build .env
|
||||||
|
|
||||||
RUN yarn install --frozen-lockfile
|
RUN pnpm install --frozen-lockfile
|
||||||
RUN yarn typecheck
|
RUN pnpm typecheck
|
||||||
RUN yarn build:highmem
|
RUN pnpm build:highmem
|
||||||
RUN yarn workspaces focus --production --all
|
# wipe node_modules for all packages
|
||||||
|
RUN pnpm install --prod
|
||||||
|
|
||||||
FROM node:16-alpine
|
FROM node:16-alpine
|
||||||
WORKDIR /usr/src/app
|
WORKDIR /usr/src/app
|
||||||
|
|
|
||||||
|
|
@ -42,9 +42,9 @@ Get revite up and running locally.
|
||||||
```
|
```
|
||||||
git clone --recursive https://github.com/revoltchat/revite
|
git clone --recursive https://github.com/revoltchat/revite
|
||||||
cd revite
|
cd revite
|
||||||
yarn
|
pnpm i
|
||||||
yarn build:deps
|
pnpm build:deps
|
||||||
yarn dev
|
pnpm dev
|
||||||
```
|
```
|
||||||
|
|
||||||
You can now access the client at http://local.revolt.chat:3000.
|
You can now access the client at http://local.revolt.chat:3000.
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit e79862b5972b57c016b4c08676ac1b90bd52ee83
|
Subproject commit d314b2d191124f1b487ebd72409e748c1bfccb87
|
||||||
166
package.json
166
package.json
|
|
@ -4,9 +4,9 @@
|
||||||
"preinstall": "npx only-allow pnpm",
|
"preinstall": "npx only-allow pnpm",
|
||||||
"dev": "node scripts/setup_assets.js --check && vite",
|
"dev": "node scripts/setup_assets.js --check && vite",
|
||||||
"pull": "node scripts/setup_assets.js",
|
"pull": "node scripts/setup_assets.js",
|
||||||
"build:deps": "cd external && cd components && yarn && yarn build:esm && cd .. && cd revolt.js && yarn && yarn build",
|
"build:deps": "pnpm run -r build",
|
||||||
"build": "yarn && rimraf build && node scripts/setup_assets.js --check && yarn build:deps && vite build",
|
"build": "rimraf build && node scripts/setup_assets.js --check && vite build",
|
||||||
"build:highmem": "NODE_OPTIONS='--max-old-space-size=4096' yarn build",
|
"build:highmem": "NODE_OPTIONS='--max-old-space-size=4096' npm run build",
|
||||||
"preview": "vite preview",
|
"preview": "vite preview",
|
||||||
"lint": "eslint src/**/*.{js,jsx,ts,tsx}",
|
"lint": "eslint src/**/*.{js,jsx,ts,tsx}",
|
||||||
"fmt": "prettier --write 'src/**/*.{js,jsx,ts,tsx}'",
|
"fmt": "prettier --write 'src/**/*.{js,jsx,ts,tsx}'",
|
||||||
|
|
@ -45,123 +45,127 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"fs-extra": "^10.0.0",
|
"fs-extra": "^10.1.0",
|
||||||
"klaw": "^3.0.0",
|
"klaw": "^3.0.0",
|
||||||
"sirv-cli": "^1.0.14",
|
"sirv-cli": "^1.0.14",
|
||||||
"vite": "^3.0.5"
|
"vite": "^3.1.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/plugin-proposal-decorators": "^7.17.9",
|
"@babel/plugin-proposal-decorators": "^7.19.1",
|
||||||
|
"@babel/runtime": "^7.19.0",
|
||||||
"@floating-ui/react-dom": "^1.0.0",
|
"@floating-ui/react-dom": "^1.0.0",
|
||||||
"@floating-ui/react-dom-interactions": "^0.9.1",
|
"@floating-ui/react-dom-interactions": "^0.9.3",
|
||||||
"@fontsource/atkinson-hyperlegible": "^4.4.5",
|
"@fontsource/atkinson-hyperlegible": "^4.5.9",
|
||||||
"@fontsource/bitter": "^4.5.7",
|
"@fontsource/bitter": "^4.5.8",
|
||||||
"@fontsource/comic-neue": "^4.4.5",
|
"@fontsource/comic-neue": "^4.5.9",
|
||||||
"@fontsource/fira-code": "^4.4.5",
|
"@fontsource/fira-code": "^4.5.11",
|
||||||
"@fontsource/inter": "^4.4.5",
|
"@fontsource/inter": "^4.5.12",
|
||||||
"@fontsource/jetbrains-mono": "^4.4.5",
|
"@fontsource/jetbrains-mono": "^4.5.10",
|
||||||
"@fontsource/lato": "^4.4.5",
|
"@fontsource/lato": "^4.5.9",
|
||||||
"@fontsource/lexend": "^4.5.2",
|
"@fontsource/lexend": "^4.5.12",
|
||||||
"@fontsource/montserrat": "^4.4.5",
|
"@fontsource/montserrat": "^4.5.12",
|
||||||
"@fontsource/noto-sans": "^4.4.5",
|
"@fontsource/noto-sans": "^4.5.11",
|
||||||
"@fontsource/open-sans": "^4.5.2",
|
"@fontsource/open-sans": "^4.5.11",
|
||||||
"@fontsource/opendyslexic": "^4.5.2",
|
"@fontsource/opendyslexic": "^4.5.4",
|
||||||
"@fontsource/poppins": "^4.4.5",
|
"@fontsource/poppins": "^4.5.9",
|
||||||
"@fontsource/raleway": "^4.4.5",
|
"@fontsource/raleway": "^4.5.10",
|
||||||
"@fontsource/roboto": "^4.4.5",
|
"@fontsource/roboto": "^4.5.8",
|
||||||
"@fontsource/roboto-mono": "^4.4.5",
|
"@fontsource/roboto-mono": "^4.5.8",
|
||||||
"@fontsource/source-code-pro": "^4.4.5",
|
"@fontsource/source-code-pro": "^4.5.12",
|
||||||
"@fontsource/space-mono": "^4.4.5",
|
"@fontsource/space-mono": "^4.5.10",
|
||||||
"@fontsource/ubuntu": "^4.4.5",
|
"@fontsource/ubuntu": "^4.5.11",
|
||||||
"@fontsource/ubuntu-mono": "^4.4.5",
|
"@fontsource/ubuntu-mono": "^4.5.11",
|
||||||
"@hcaptcha/react-hcaptcha": "^0.3.6",
|
"@hcaptcha/react-hcaptcha": "^0.3.10",
|
||||||
"@insertish/vite-plugin-babel-macros": "^1.0.5",
|
"@insertish/vite-plugin-babel-macros": "^1.0.5",
|
||||||
"@preact/preset-vite": "^2.0.0",
|
"@mapbox/hast-util-table-cell-style": "workspace:0.2.0",
|
||||||
"@revoltchat/ui": "workspace:*",
|
"@preact/preset-vite": "^2.4.0",
|
||||||
|
"@revoltchat/ui": "workspace:1.0.77",
|
||||||
"@rollup/plugin-replace": "^2.4.2",
|
"@rollup/plugin-replace": "^2.4.2",
|
||||||
"@styled-icons/boxicons-logos": "^10.38.0",
|
"@styled-icons/boxicons-logos": "^10.46.0",
|
||||||
"@styled-icons/boxicons-regular": "^10.38.0",
|
"@styled-icons/boxicons-regular": "^10.46.0",
|
||||||
"@styled-icons/boxicons-solid": "^10.38.0",
|
"@styled-icons/boxicons-solid": "^10.46.0",
|
||||||
"@styled-icons/simple-icons": "^10.33.0",
|
"@styled-icons/simple-icons": "^10.46.0",
|
||||||
"@tippyjs/react": "4.2.6",
|
"@tippyjs/react": "4.2.6",
|
||||||
"@traptitech/markdown-it-katex": "^3.4.3",
|
"@traptitech/markdown-it-katex": "^3.6.0",
|
||||||
"@traptitech/markdown-it-spoiler": "^1.1.6",
|
"@traptitech/markdown-it-spoiler": "^1.1.6",
|
||||||
"@trivago/prettier-plugin-sort-imports": "^2.0.2",
|
"@trivago/prettier-plugin-sort-imports": "^2.0.4",
|
||||||
"@types/lodash": "^4",
|
"@types/lodash": "^4.14.185",
|
||||||
"@types/lodash.defaultsdeep": "^4.6.6",
|
"@types/lodash.defaultsdeep": "^4.6.7",
|
||||||
"@types/lodash.isequal": "^4.5.5",
|
"@types/lodash.isequal": "^4.5.6",
|
||||||
"@types/node": "^15.12.4",
|
"@types/node": "^15.14.9",
|
||||||
"@types/preact-i18n": "^2.3.0",
|
"@types/preact-i18n": "^2.3.1",
|
||||||
"@types/prismjs": "^1.16.5",
|
"@types/prismjs": "^1.26.0",
|
||||||
"@types/react-beautiful-dnd": "^13",
|
"@types/react-beautiful-dnd": "^13.0.0",
|
||||||
"@types/react-helmet": "^6.1.1",
|
"@types/react-helmet": "^6.1.5",
|
||||||
"@types/react-router-dom": "^5.1.7",
|
"@types/react-router-dom": "^5.3.3",
|
||||||
"@types/react-scroll": "^1.8.2",
|
"@types/react-scroll": "^1.8.4",
|
||||||
"@types/semver": "^7",
|
"@types/semver": "^7.3.12",
|
||||||
"@types/styled-components": "^5.1.10",
|
"@types/styled-components": "^5.1.26",
|
||||||
"@types/twemoji": "^12.1.1",
|
"@types/twemoji": "^12.1.2",
|
||||||
"@typescript-eslint/eslint-plugin": "^4.27.0",
|
"@typescript-eslint/eslint-plugin": "^4.33.0",
|
||||||
"@typescript-eslint/parser": "^4.27.0",
|
"@typescript-eslint/parser": "^4.33.0",
|
||||||
"@vitejs/plugin-legacy": "^1.7.1",
|
"@vitejs/plugin-legacy": "^1.8.2",
|
||||||
"classnames": "^2.3.1",
|
"classnames": "^2.3.2",
|
||||||
"color-rgba": "^2.4.0",
|
"color-rgba": "^2.4.0",
|
||||||
"dayjs": "^1.10.6",
|
"dayjs": "^1.11.5",
|
||||||
"detect-browser": "^5.2.0",
|
"detect-browser": "^5.3.0",
|
||||||
"eslint": "^7.28.0",
|
"eslint": "^7.32.0",
|
||||||
"eslint-config-preact": "^1.1.4",
|
"eslint-config-preact": "^1.3.0",
|
||||||
"eslint-plugin-jsdoc": "^39.3.2",
|
"eslint-plugin-jsdoc": "^39.3.6",
|
||||||
"eslint-plugin-mobx": "^0.0.8",
|
"eslint-plugin-mobx": "^0.0.8",
|
||||||
"eventemitter3": "^4.0.7",
|
"eventemitter3": "^4.0.7",
|
||||||
"history": "4",
|
"history": "^4.10.1",
|
||||||
"json-stringify-deterministic": "^1.0.2",
|
"json-stringify-deterministic": "^1.0.7",
|
||||||
"localforage": "^1.9.0",
|
"localforage": "^1.10.0",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"lodash.defaultsdeep": "^4.6.1",
|
"lodash.defaultsdeep": "^4.6.1",
|
||||||
"lodash.isequal": "^4.5.0",
|
"lodash.isequal": "^4.5.0",
|
||||||
"long": "^5.2.0",
|
"long": "^5.2.0",
|
||||||
"mdast-util-to-hast": "^12.1.2",
|
"mdast-util-to-hast": "^12.2.2",
|
||||||
"mediasoup-client": "npm:@insertish/mediasoup-client@3.6.36-esnext",
|
"mediasoup-client": "npm:@insertish/mediasoup-client@^3.6.36-esnext",
|
||||||
"mobx": "^6.6.0",
|
"mobx": "^6.6.2",
|
||||||
"mobx-react-lite": "3.4.0",
|
"mobx-react-lite": "3.4.0",
|
||||||
"preact": "^10.5.14",
|
"preact": "^10.11.0",
|
||||||
"preact-context-menu": "0.4.1",
|
"preact-context-menu": "0.4.1",
|
||||||
"preact-i18n": "^2.4.0-preactx",
|
"preact-i18n": "^2.4.0-preactx",
|
||||||
"prettier": "^2.3.1",
|
"prettier": "^2.7.1",
|
||||||
"prismjs": "^1.28.0",
|
"prismjs": "^1.29.0",
|
||||||
"qrcode.react": "^3.0.2",
|
"qrcode.react": "^3.1.0",
|
||||||
"react-beautiful-dnd": "^13.1.0",
|
"react-beautiful-dnd": "^13.1.1",
|
||||||
"react-device-detect": "2.2.2",
|
"react-device-detect": "2.2.2",
|
||||||
"react-helmet": "^6.1.0",
|
"react-helmet": "^6.1.0",
|
||||||
"react-hook-form": "6.3.0",
|
"react-hook-form": "6.3.0",
|
||||||
"react-overlapping-panels": "1.2.2",
|
"react-overlapping-panels": "1.2.2",
|
||||||
"react-router-dom": "^5.2.0",
|
"react-router-dom": "^5.3.3",
|
||||||
"react-scroll": "^1.8.2",
|
"react-scroll": "^1.8.7",
|
||||||
"react-virtuoso": "^2.12.0",
|
"react-virtuoso": "^2.19.0",
|
||||||
"rehype-katex": "^6.0.2",
|
"rehype-katex": "^6.0.2",
|
||||||
"rehype-prism": "^2.1.3",
|
"rehype-prism": "^2.1.3",
|
||||||
"rehype-react": "^7.1.1",
|
"rehype-react": "^7.1.1",
|
||||||
|
"remark": "^14.0.2",
|
||||||
"remark-breaks": "^3.0.2",
|
"remark-breaks": "^3.0.2",
|
||||||
"remark-gfm": "^3.0.1",
|
"remark-gfm": "^3.0.1",
|
||||||
"remark-math": "^5.1.1",
|
"remark-math": "^5.1.1",
|
||||||
"remark-parse": "^10.0.1",
|
"remark-parse": "^10.0.1",
|
||||||
"remark-rehype": "^10.1.0",
|
"remark-rehype": "^10.1.0",
|
||||||
"revolt.js": "workspace:*",
|
"revolt.js": "workspace:6.0.18",
|
||||||
"rimraf": "^3.0.2",
|
"rimraf": "^3.0.2",
|
||||||
"sass": "^1.35.1",
|
"sass": "^1.54.9",
|
||||||
"semver": "^7.3.7",
|
"semver": "^7.3.7",
|
||||||
"shade-blend-color": "^1.0.0",
|
"shade-blend-color": "^1.0.0",
|
||||||
"slate": "^0.81.1",
|
"slate": "^0.81.3",
|
||||||
"slate-history": "^0.66.0",
|
"slate-history": "^0.66.0",
|
||||||
"slate-react": "^0.81.0",
|
"slate-react": "^0.81.0",
|
||||||
"stacktrace-js": "^2.0.2",
|
"stacktrace-js": "^2.0.2",
|
||||||
"styled-components": "^5.3.0",
|
"styled-components": "^5.3.5",
|
||||||
"typescript": "^4.4.2",
|
"typescript": "^4.8.3",
|
||||||
"ulid": "^2.3.0",
|
"ulid": "^2.3.0",
|
||||||
"unified": "^10.1.2",
|
"unified": "^10.1.2",
|
||||||
"unist-util-visit": "^4.1.0",
|
"unist-util-visit": "^4.1.1",
|
||||||
"use-resize-observer": "^7.0.0",
|
"use-resize-observer": "^7.0.1",
|
||||||
"vite-plugin-pwa": "^0.12.3",
|
"vite-plugin-pwa": "^0.12.8",
|
||||||
"workbox-precaching": "^6.1.5"
|
"workbox-precaching": "^6.5.4",
|
||||||
|
"workbox-window": "^6.5.4"
|
||||||
},
|
},
|
||||||
"name": "client",
|
"name": "client",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 7803fa54410a7ef9fc3149c482253e74ca1d7d71
|
||||||
5310
pnpm-lock.yaml
5310
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
|
|
@ -1,3 +1,4 @@
|
||||||
packages:
|
packages:
|
||||||
|
- 'packages/**'
|
||||||
- 'external/**'
|
- 'external/**'
|
||||||
- '!external/lang'
|
- '!external/lang'
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
import { XCircle, Plus, Share, X, File } from "@styled-icons/boxicons-regular";
|
import { XCircle, Plus, Share, X, File } from "@styled-icons/boxicons-regular";
|
||||||
import styled from "styled-components/macro";
|
import styled from "styled-components/macro";
|
||||||
|
|
||||||
|
import { Fragment } from "preact";
|
||||||
import { Text } from "preact-i18n";
|
import { Text } from "preact-i18n";
|
||||||
import { useEffect, useState } from "preact/hooks";
|
import { useEffect, useState } from "preact/hooks";
|
||||||
|
|
||||||
|
|
@ -192,7 +193,6 @@ export default function FilePreview({ state, addFile, removeFile }: Props) {
|
||||||
<Container>
|
<Container>
|
||||||
<Carousel>
|
<Carousel>
|
||||||
{state.files.map((file, index) => (
|
{state.files.map((file, index) => (
|
||||||
// @ts-expect-error brokey
|
|
||||||
// eslint-disable-next-line react/jsx-no-undef
|
// eslint-disable-next-line react/jsx-no-undef
|
||||||
<Fragment key={file.name}>
|
<Fragment key={file.name}>
|
||||||
{index === CAN_UPLOAD_AT_ONCE && <Divider />}
|
{index === CAN_UPLOAD_AT_ONCE && <Divider />}
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,8 @@ import remarkRehype from "remark-rehype";
|
||||||
import styled, { css } from "styled-components";
|
import styled, { css } from "styled-components";
|
||||||
import { unified } from "unified";
|
import { unified } from "unified";
|
||||||
|
|
||||||
import { createElement } from "preact";
|
|
||||||
import { memo } from "preact/compat";
|
import { memo } from "preact/compat";
|
||||||
|
import { createElement, Fragment } from "preact";
|
||||||
import { useLayoutEffect, useMemo, useState } from "preact/hooks";
|
import { useLayoutEffect, useMemo, useState } from "preact/hooks";
|
||||||
|
|
||||||
import { MarkdownProps } from "./Markdown";
|
import { MarkdownProps } from "./Markdown";
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@ class ClientController {
|
||||||
injectController("client", this);
|
injectController("client", this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@action pickNextSession() {
|
pickNextSession() {
|
||||||
this.switchAccount(
|
this.switchAccount(
|
||||||
this.current ?? this.sessions.keys().next().value ?? null,
|
this.current ?? this.sessions.keys().next().value ?? null,
|
||||||
);
|
);
|
||||||
|
|
@ -69,7 +69,7 @@ class ClientController {
|
||||||
* Hydrate sessions and start client lifecycles.
|
* Hydrate sessions and start client lifecycles.
|
||||||
* @param auth Authentication store
|
* @param auth Authentication store
|
||||||
*/
|
*/
|
||||||
@action hydrate(auth: Auth) {
|
hydrate(auth: Auth) {
|
||||||
for (const entry of auth.getAccounts()) {
|
for (const entry of auth.getAccounts()) {
|
||||||
this.addSession(entry, "existing");
|
this.addSession(entry, "existing");
|
||||||
}
|
}
|
||||||
|
|
@ -81,7 +81,7 @@ class ClientController {
|
||||||
* Get the currently selected session
|
* Get the currently selected session
|
||||||
* @returns Active Session
|
* @returns Active Session
|
||||||
*/
|
*/
|
||||||
@computed getActiveSession() {
|
getActiveSession() {
|
||||||
return this.sessions.get(this.current!);
|
return this.sessions.get(this.current!);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -89,7 +89,7 @@ class ClientController {
|
||||||
* Get the currently ready client
|
* Get the currently ready client
|
||||||
* @returns Ready Client
|
* @returns Ready Client
|
||||||
*/
|
*/
|
||||||
@computed getReadyClient() {
|
getReadyClient() {
|
||||||
const session = this.getActiveSession();
|
const session = this.getActiveSession();
|
||||||
return session && session.ready ? session.client! : undefined;
|
return session && session.ready ? session.client! : undefined;
|
||||||
}
|
}
|
||||||
|
|
@ -98,7 +98,7 @@ class ClientController {
|
||||||
* Get an unauthenticated instance of the Revolt.js Client
|
* Get an unauthenticated instance of the Revolt.js Client
|
||||||
* @returns API Client
|
* @returns API Client
|
||||||
*/
|
*/
|
||||||
@computed getAnonymousClient() {
|
getAnonymousClient() {
|
||||||
return this.apiClient;
|
return this.apiClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -106,7 +106,7 @@ class ClientController {
|
||||||
* Get the next available client (either from session or API)
|
* Get the next available client (either from session or API)
|
||||||
* @returns Revolt.js Client
|
* @returns Revolt.js Client
|
||||||
*/
|
*/
|
||||||
@computed getAvailableClient() {
|
getAvailableClient() {
|
||||||
return this.getActiveSession()?.client ?? this.apiClient;
|
return this.getActiveSession()?.client ?? this.apiClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -114,7 +114,7 @@ class ClientController {
|
||||||
* Fetch server configuration
|
* Fetch server configuration
|
||||||
* @returns Server Configuration
|
* @returns Server Configuration
|
||||||
*/
|
*/
|
||||||
@computed getServerConfig() {
|
getServerConfig() {
|
||||||
return this.configuration;
|
return this.configuration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -122,7 +122,7 @@ class ClientController {
|
||||||
* Check whether we are logged in right now
|
* Check whether we are logged in right now
|
||||||
* @returns Whether we are logged in
|
* @returns Whether we are logged in
|
||||||
*/
|
*/
|
||||||
@computed isLoggedIn() {
|
isLoggedIn() {
|
||||||
return this.current !== null;
|
return this.current !== null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -130,7 +130,7 @@ class ClientController {
|
||||||
* Check whether we are currently ready
|
* Check whether we are currently ready
|
||||||
* @returns Whether we are ready to render
|
* @returns Whether we are ready to render
|
||||||
*/
|
*/
|
||||||
@computed isReady() {
|
isReady() {
|
||||||
return this.getActiveSession()?.ready;
|
return this.getActiveSession()?.ready;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -139,7 +139,7 @@ class ClientController {
|
||||||
* @param entry Session Information
|
* @param entry Session Information
|
||||||
* @param knowledge Whether the session is new or existing
|
* @param knowledge Whether the session is new or existing
|
||||||
*/
|
*/
|
||||||
@action addSession(
|
addSession(
|
||||||
entry: { session: SessionPrivate; apiUrl?: string },
|
entry: { session: SessionPrivate; apiUrl?: string },
|
||||||
knowledge: "new" | "existing",
|
knowledge: "new" | "existing",
|
||||||
) {
|
) {
|
||||||
|
|
@ -262,7 +262,7 @@ class ClientController {
|
||||||
* Log out of a specific user session
|
* Log out of a specific user session
|
||||||
* @param user_id Target User ID
|
* @param user_id Target User ID
|
||||||
*/
|
*/
|
||||||
@action logout(user_id: string) {
|
logout(user_id: string) {
|
||||||
const session = this.sessions.get(user_id);
|
const session = this.sessions.get(user_id);
|
||||||
if (session) {
|
if (session) {
|
||||||
if (user_id === this.current) {
|
if (user_id === this.current) {
|
||||||
|
|
@ -278,7 +278,7 @@ class ClientController {
|
||||||
/**
|
/**
|
||||||
* Logout of the current session
|
* Logout of the current session
|
||||||
*/
|
*/
|
||||||
@action logoutCurrent() {
|
logoutCurrent() {
|
||||||
if (this.current) {
|
if (this.current) {
|
||||||
this.logout(this.current);
|
this.logout(this.current);
|
||||||
}
|
}
|
||||||
|
|
@ -288,7 +288,7 @@ class ClientController {
|
||||||
* Switch to another user session
|
* Switch to another user session
|
||||||
* @param user_id Target User ID
|
* @param user_id Target User ID
|
||||||
*/
|
*/
|
||||||
@action switchAccount(user_id: string) {
|
switchAccount(user_id: string) {
|
||||||
this.current = user_id;
|
this.current = user_id;
|
||||||
|
|
||||||
// This will allow account switching to work more seamlessly,
|
// This will allow account switching to work more seamlessly,
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ export default class Session {
|
||||||
/**
|
/**
|
||||||
* Initiate logout and destroy client
|
* Initiate logout and destroy client
|
||||||
*/
|
*/
|
||||||
@action destroy() {
|
destroy() {
|
||||||
if (this.client) {
|
if (this.client) {
|
||||||
this.client.logout(false);
|
this.client.logout(false);
|
||||||
this.state = "Ready";
|
this.state = "Ready";
|
||||||
|
|
@ -165,7 +165,7 @@ export default class Session {
|
||||||
* Transition to a new state by a certain action
|
* Transition to a new state by a certain action
|
||||||
* @param data Transition Data
|
* @param data Transition Data
|
||||||
*/
|
*/
|
||||||
@action async emit(data: Transition) {
|
async emit(data: Transition) {
|
||||||
console.info(`[FSM ${this.user_id ?? "Anonymous"}]`, data);
|
console.info(`[FSM ${this.user_id ?? "Anonymous"}]`, data);
|
||||||
|
|
||||||
switch (data.action) {
|
switch (data.action) {
|
||||||
|
|
@ -269,7 +269,7 @@ export default class Session {
|
||||||
* Whether we are ready to render.
|
* Whether we are ready to render.
|
||||||
* @returns Boolean
|
* @returns Boolean
|
||||||
*/
|
*/
|
||||||
@computed get ready() {
|
get ready() {
|
||||||
return !!this.client?.user;
|
return !!this.client?.user;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@ export class ChannelRenderer {
|
||||||
this.currentRenderer.delete(this, id);
|
this.currentRenderer.delete(this, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@action async init(message_id?: string) {
|
async init(message_id?: string) {
|
||||||
if (message_id) {
|
if (message_id) {
|
||||||
if (this.state === "RENDER") {
|
if (this.state === "RENDER") {
|
||||||
const message = this.messages.find((x) => x._id === message_id);
|
const message = this.messages.find((x) => x._id === message_id);
|
||||||
|
|
@ -83,15 +83,15 @@ export class ChannelRenderer {
|
||||||
this.currentRenderer.init(this, message_id);
|
this.currentRenderer.init(this, message_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@action emitScroll(state: ScrollState) {
|
emitScroll(state: ScrollState) {
|
||||||
this.scrollState = state;
|
this.scrollState = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
@action markStale() {
|
markStale() {
|
||||||
this.stale = true;
|
this.stale = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@action complete() {
|
complete() {
|
||||||
this.fetching = false;
|
this.fetching = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ class VoiceStateReference {
|
||||||
|
|
||||||
// This takes information from the voice
|
// This takes information from the voice
|
||||||
// client and applies it to the state here.
|
// client and applies it to the state here.
|
||||||
@action syncState() {
|
syncState() {
|
||||||
if (!this.client) return;
|
if (!this.client) return;
|
||||||
this.roomId = toNullable(this.client.roomId);
|
this.roomId = toNullable(this.client.roomId);
|
||||||
this.participants.clear();
|
this.participants.clear();
|
||||||
|
|
@ -54,7 +54,7 @@ class VoiceStateReference {
|
||||||
}
|
}
|
||||||
|
|
||||||
// This imports and constructs the voice client.
|
// This imports and constructs the voice client.
|
||||||
@action async loadVoice() {
|
async loadVoice() {
|
||||||
if (this.status !== VoiceStatus.UNLOADED) return;
|
if (this.status !== VoiceStatus.UNLOADED) return;
|
||||||
this.status = VoiceStatus.LOADING;
|
this.status = VoiceStatus.LOADING;
|
||||||
|
|
||||||
|
|
@ -86,7 +86,7 @@ class VoiceStateReference {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Connect to a voice channel.
|
// Connect to a voice channel.
|
||||||
@action async connect(channel: Channel) {
|
async connect(channel: Channel) {
|
||||||
if (!this.client?.supported()) throw new Error("RTC is unavailable");
|
if (!this.client?.supported()) throw new Error("RTC is unavailable");
|
||||||
|
|
||||||
this.connecting = true;
|
this.connecting = true;
|
||||||
|
|
@ -131,7 +131,7 @@ class VoiceStateReference {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Disconnect from current channel.
|
// Disconnect from current channel.
|
||||||
@action disconnect() {
|
disconnect() {
|
||||||
this.connecting = false;
|
this.connecting = false;
|
||||||
this.status = VoiceStatus.READY;
|
this.status = VoiceStatus.READY;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -139,7 +139,7 @@ export default class State {
|
||||||
* Consume packets from the client.
|
* Consume packets from the client.
|
||||||
* @param packet Inbound Packet
|
* @param packet Inbound Packet
|
||||||
*/
|
*/
|
||||||
@action onPacket(packet: ClientboundNotification) {
|
onPacket(packet: ClientboundNotification) {
|
||||||
if (packet.type === "UserSettingsUpdate") {
|
if (packet.type === "UserSettingsUpdate") {
|
||||||
try {
|
try {
|
||||||
this.sync.apply(packet.update);
|
this.sync.apply(packet.update);
|
||||||
|
|
|
||||||
|
|
@ -46,13 +46,13 @@ export default class Auth implements Store, Persistent<Data> {
|
||||||
return "auth";
|
return "auth";
|
||||||
}
|
}
|
||||||
|
|
||||||
@action toJSON() {
|
toJSON() {
|
||||||
return {
|
return {
|
||||||
sessions: JSON.parse(JSON.stringify(mapToRecord(this.sessions))),
|
sessions: JSON.parse(JSON.stringify(mapToRecord(this.sessions))),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@action hydrate(data: Data) {
|
hydrate(data: Data) {
|
||||||
if (Array.isArray(data.sessions)) {
|
if (Array.isArray(data.sessions)) {
|
||||||
data.sessions.forEach(([key, value]) =>
|
data.sessions.forEach(([key, value]) =>
|
||||||
this.sessions.set(key, value),
|
this.sessions.set(key, value),
|
||||||
|
|
@ -73,7 +73,7 @@ export default class Auth implements Store, Persistent<Data> {
|
||||||
* @param session Session
|
* @param session Session
|
||||||
* @param apiUrl Custom API URL
|
* @param apiUrl Custom API URL
|
||||||
*/
|
*/
|
||||||
@action setSession(session: Session, apiUrl?: string) {
|
setSession(session: Session, apiUrl?: string) {
|
||||||
this.sessions.set(session.user_id, { session, apiUrl });
|
this.sessions.set(session.user_id, { session, apiUrl });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -81,7 +81,7 @@ export default class Auth implements Store, Persistent<Data> {
|
||||||
* Remove existing session by user ID.
|
* Remove existing session by user ID.
|
||||||
* @param user_id User ID tied to session
|
* @param user_id User ID tied to session
|
||||||
*/
|
*/
|
||||||
@action removeSession(user_id: string) {
|
removeSession(user_id: string) {
|
||||||
this.sessions.delete(user_id);
|
this.sessions.delete(user_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -89,14 +89,14 @@ export default class Auth implements Store, Persistent<Data> {
|
||||||
* Get all known accounts.
|
* Get all known accounts.
|
||||||
* @returns Array of accounts
|
* @returns Array of accounts
|
||||||
*/
|
*/
|
||||||
@computed getAccounts() {
|
getAccounts() {
|
||||||
return [...this.sessions.values()];
|
return [...this.sessions.values()];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove current session.
|
* Remove current session.
|
||||||
*/
|
*/
|
||||||
/*@action logout() {
|
/*logout() {
|
||||||
this.current && this.removeSession(this.current);
|
this.current && this.removeSession(this.current);
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
|
|
@ -104,7 +104,7 @@ export default class Auth implements Store, Persistent<Data> {
|
||||||
* Get current session.
|
* Get current session.
|
||||||
* @returns Current session
|
* @returns Current session
|
||||||
*/
|
*/
|
||||||
/*@computed getSession() {
|
/*getSession() {
|
||||||
if (!this.current) return;
|
if (!this.current) return;
|
||||||
return this.sessions.get(this.current)!.session;
|
return this.sessions.get(this.current)!.session;
|
||||||
}*/
|
}*/
|
||||||
|
|
@ -113,7 +113,7 @@ export default class Auth implements Store, Persistent<Data> {
|
||||||
* Check whether we are currently logged in.
|
* Check whether we are currently logged in.
|
||||||
* @returns Whether we are logged in
|
* @returns Whether we are logged in
|
||||||
*/
|
*/
|
||||||
@computed isLoggedIn() {
|
isLoggedIn() {
|
||||||
// ! FIXME: temp proxy info
|
// ! FIXME: temp proxy info
|
||||||
return clientController.getActiveSession()?.ready;
|
return clientController.getActiveSession()?.ready;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ export default class Changelog implements Store, Persistent<Data>, Syncable {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@action hydrate(data: Data) {
|
hydrate(data: Data) {
|
||||||
if (data.viewed) {
|
if (data.viewed) {
|
||||||
this.viewed = data.viewed;
|
this.viewed = data.viewed;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ export default class Draft implements Store, Persistent<Data> {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@action hydrate(data: Data) {
|
hydrate(data: Data) {
|
||||||
Object.keys(data.drafts).forEach((key) =>
|
Object.keys(data.drafts).forEach((key) =>
|
||||||
this.drafts.set(key, data.drafts[key]),
|
this.drafts.set(key, data.drafts[key]),
|
||||||
);
|
);
|
||||||
|
|
@ -43,7 +43,7 @@ export default class Draft implements Store, Persistent<Data> {
|
||||||
* Get draft for a channel.
|
* Get draft for a channel.
|
||||||
* @param channel Channel ID
|
* @param channel Channel ID
|
||||||
*/
|
*/
|
||||||
@computed get(channel: string) {
|
get(channel: string) {
|
||||||
return this.drafts.get(channel);
|
return this.drafts.get(channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -51,7 +51,7 @@ export default class Draft implements Store, Persistent<Data> {
|
||||||
* Check whether a channel has a draft.
|
* Check whether a channel has a draft.
|
||||||
* @param channel Channel ID
|
* @param channel Channel ID
|
||||||
*/
|
*/
|
||||||
@computed has(channel: string) {
|
has(channel: string) {
|
||||||
return this.drafts.has(channel) && this.drafts.get(channel)!.length > 0;
|
return this.drafts.has(channel) && this.drafts.get(channel)!.length > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -60,7 +60,7 @@ export default class Draft implements Store, Persistent<Data> {
|
||||||
* @param channel Channel ID
|
* @param channel Channel ID
|
||||||
* @param content Draft content
|
* @param content Draft content
|
||||||
*/
|
*/
|
||||||
@action set(channel: string, content?: string) {
|
set(channel: string, content?: string) {
|
||||||
if (typeof content === "undefined") {
|
if (typeof content === "undefined") {
|
||||||
return this.clear(channel);
|
return this.clear(channel);
|
||||||
}
|
}
|
||||||
|
|
@ -72,14 +72,14 @@ export default class Draft implements Store, Persistent<Data> {
|
||||||
* Clear draft from a channel.
|
* Clear draft from a channel.
|
||||||
* @param channel Channel ID
|
* @param channel Channel ID
|
||||||
*/
|
*/
|
||||||
@action clear(channel: string) {
|
clear(channel: string) {
|
||||||
this.drafts.delete(channel);
|
this.drafts.delete(channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reset and clear all drafts.
|
* Reset and clear all drafts.
|
||||||
*/
|
*/
|
||||||
@action reset() {
|
reset() {
|
||||||
this.drafts.clear();
|
this.drafts.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -77,7 +77,7 @@ export default class Experiments implements Store, Persistent<Data> {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@action hydrate(data: Data) {
|
hydrate(data: Data) {
|
||||||
if (data.enabled) {
|
if (data.enabled) {
|
||||||
for (const experiment of data.enabled) {
|
for (const experiment of data.enabled) {
|
||||||
this.enable(experiment as Experiment);
|
this.enable(experiment as Experiment);
|
||||||
|
|
@ -89,7 +89,7 @@ export default class Experiments implements Store, Persistent<Data> {
|
||||||
* Check if an experiment is enabled.
|
* Check if an experiment is enabled.
|
||||||
* @param experiment Experiment
|
* @param experiment Experiment
|
||||||
*/
|
*/
|
||||||
@computed isEnabled(experiment: Experiment) {
|
isEnabled(experiment: Experiment) {
|
||||||
return this.enabled.has(experiment);
|
return this.enabled.has(experiment);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -97,7 +97,7 @@ export default class Experiments implements Store, Persistent<Data> {
|
||||||
* Enable an experiment.
|
* Enable an experiment.
|
||||||
* @param experiment Experiment
|
* @param experiment Experiment
|
||||||
*/
|
*/
|
||||||
@action enable(experiment: Experiment) {
|
enable(experiment: Experiment) {
|
||||||
if (experiment === "offline_users") {
|
if (experiment === "offline_users") {
|
||||||
setOfflineSkipEnabled(false);
|
setOfflineSkipEnabled(false);
|
||||||
resetMemberSidebarFetched();
|
resetMemberSidebarFetched();
|
||||||
|
|
@ -110,7 +110,7 @@ export default class Experiments implements Store, Persistent<Data> {
|
||||||
* Disable an experiment.
|
* Disable an experiment.
|
||||||
* @param experiment Experiment
|
* @param experiment Experiment
|
||||||
*/
|
*/
|
||||||
@action disable(experiment: Experiment) {
|
disable(experiment: Experiment) {
|
||||||
if (experiment === "offline_users") setOfflineSkipEnabled(true);
|
if (experiment === "offline_users") setOfflineSkipEnabled(true);
|
||||||
|
|
||||||
this.enabled.delete(experiment);
|
this.enabled.delete(experiment);
|
||||||
|
|
@ -121,7 +121,7 @@ export default class Experiments implements Store, Persistent<Data> {
|
||||||
* @param key Experiment
|
* @param key Experiment
|
||||||
* @param enabled Whether this experiment is enabled.
|
* @param enabled Whether this experiment is enabled.
|
||||||
*/
|
*/
|
||||||
@computed setEnabled(key: Experiment, enabled: boolean): void {
|
setEnabled(key: Experiment, enabled: boolean): void {
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
this.enable(key);
|
this.enable(key);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -132,7 +132,7 @@ export default class Experiments implements Store, Persistent<Data> {
|
||||||
/**
|
/**
|
||||||
* Reset and disable all experiments.
|
* Reset and disable all experiments.
|
||||||
*/
|
*/
|
||||||
@action reset() {
|
reset() {
|
||||||
this.enabled.clear();
|
this.enabled.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -77,7 +77,7 @@ export default class Layout implements Store, Persistent<Data> {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@action hydrate(data: Data) {
|
hydrate(data: Data) {
|
||||||
if (data.lastSection) {
|
if (data.lastSection) {
|
||||||
this.lastSection = data.lastSection;
|
this.lastSection = data.lastSection;
|
||||||
}
|
}
|
||||||
|
|
@ -103,7 +103,7 @@ export default class Layout implements Store, Persistent<Data> {
|
||||||
* Get the last 'major section' the user had open.
|
* Get the last 'major section' the user had open.
|
||||||
* @returns Last open section
|
* @returns Last open section
|
||||||
*/
|
*/
|
||||||
@computed getLastSection() {
|
getLastSection() {
|
||||||
return this.lastSection;
|
return this.lastSection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -111,7 +111,7 @@ export default class Layout implements Store, Persistent<Data> {
|
||||||
* Get last opened channel in a server.
|
* Get last opened channel in a server.
|
||||||
* @param server Server ID
|
* @param server Server ID
|
||||||
*/
|
*/
|
||||||
@computed getLastOpened(server: string) {
|
getLastOpened(server: string) {
|
||||||
return this.lastOpened.get(server);
|
return this.lastOpened.get(server);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -120,7 +120,7 @@ export default class Layout implements Store, Persistent<Data> {
|
||||||
* @param server Server ID
|
* @param server Server ID
|
||||||
* @returns Pathname
|
* @returns Pathname
|
||||||
*/
|
*/
|
||||||
@computed getServerPath(server: string) {
|
getServerPath(server: string) {
|
||||||
let path = `/server/${server}`;
|
let path = `/server/${server}`;
|
||||||
if (this.lastOpened.has(server)) {
|
if (this.lastOpened.has(server)) {
|
||||||
path += `/channel/${this.getLastOpened(server)}`;
|
path += `/channel/${this.getLastOpened(server)}`;
|
||||||
|
|
@ -134,7 +134,7 @@ export default class Layout implements Store, Persistent<Data> {
|
||||||
* @param server Server ID
|
* @param server Server ID
|
||||||
* @param channel Channel ID
|
* @param channel Channel ID
|
||||||
*/
|
*/
|
||||||
@action setLastOpened(server: string, channel: string) {
|
setLastOpened(server: string, channel: string) {
|
||||||
this.lastOpened.set(server, channel);
|
this.lastOpened.set(server, channel);
|
||||||
this.lastSection = server;
|
this.lastSection = server;
|
||||||
}
|
}
|
||||||
|
|
@ -143,7 +143,7 @@ export default class Layout implements Store, Persistent<Data> {
|
||||||
* Get the last path the user had open in the home tab.
|
* Get the last path the user had open in the home tab.
|
||||||
* @returns Last home path
|
* @returns Last home path
|
||||||
*/
|
*/
|
||||||
@computed getLastHomePath() {
|
getLastHomePath() {
|
||||||
return this.lastHomePath;
|
return this.lastHomePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -151,7 +151,7 @@ export default class Layout implements Store, Persistent<Data> {
|
||||||
* Get the last path the user had open.
|
* Get the last path the user had open.
|
||||||
* @returns Last path
|
* @returns Last path
|
||||||
*/
|
*/
|
||||||
@computed getLastPath() {
|
getLastPath() {
|
||||||
return (
|
return (
|
||||||
(this.lastSection === "discover"
|
(this.lastSection === "discover"
|
||||||
? this.lastDiscoverPath
|
? this.lastDiscoverPath
|
||||||
|
|
@ -167,7 +167,7 @@ export default class Layout implements Store, Persistent<Data> {
|
||||||
* Set the last opened section.
|
* Set the last opened section.
|
||||||
* @param section Section name
|
* @param section Section name
|
||||||
*/
|
*/
|
||||||
@action setLastSection(section: string) {
|
setLastSection(section: string) {
|
||||||
this.lastSection = section;
|
this.lastSection = section;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -175,7 +175,7 @@ export default class Layout implements Store, Persistent<Data> {
|
||||||
* Set the current path open in the home tab.
|
* Set the current path open in the home tab.
|
||||||
* @param path Pathname
|
* @param path Pathname
|
||||||
*/
|
*/
|
||||||
@action setLastHomePath(path: string) {
|
setLastHomePath(path: string) {
|
||||||
if (path.startsWith("/bot")) return;
|
if (path.startsWith("/bot")) return;
|
||||||
if (path.startsWith("/invite")) return;
|
if (path.startsWith("/invite")) return;
|
||||||
|
|
||||||
|
|
@ -187,7 +187,7 @@ export default class Layout implements Store, Persistent<Data> {
|
||||||
* Set the last discover path.
|
* Set the last discover path.
|
||||||
* @param path Pathname
|
* @param path Pathname
|
||||||
*/
|
*/
|
||||||
@action setLastDiscoverPath(path: string) {
|
setLastDiscoverPath(path: string) {
|
||||||
this.lastDiscoverPath = path;
|
this.lastDiscoverPath = path;
|
||||||
this.lastSection = "discover";
|
this.lastSection = "discover";
|
||||||
}
|
}
|
||||||
|
|
@ -198,7 +198,7 @@ export default class Layout implements Store, Persistent<Data> {
|
||||||
* @returns Whether the section is open
|
* @returns Whether the section is open
|
||||||
* @param def Default state value
|
* @param def Default state value
|
||||||
*/
|
*/
|
||||||
@computed getSectionState(id: string, def?: boolean) {
|
getSectionState(id: string, def?: boolean) {
|
||||||
return this.openSections.get(id) ?? def ?? false;
|
return this.openSections.get(id) ?? def ?? false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -208,7 +208,7 @@ export default class Layout implements Store, Persistent<Data> {
|
||||||
* @param value New state value
|
* @param value New state value
|
||||||
* @param def Default state value
|
* @param def Default state value
|
||||||
*/
|
*/
|
||||||
@action setSectionState(id: string, value: boolean, def?: boolean) {
|
setSectionState(id: string, value: boolean, def?: boolean) {
|
||||||
if (value === def) {
|
if (value === def) {
|
||||||
this.openSections.delete(id);
|
this.openSections.delete(id);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -221,7 +221,7 @@ export default class Layout implements Store, Persistent<Data> {
|
||||||
* @param id Section ID
|
* @param id Section ID
|
||||||
* @param def Default state value
|
* @param def Default state value
|
||||||
*/
|
*/
|
||||||
@action toggleSectionState(id: string, def?: boolean) {
|
toggleSectionState(id: string, def?: boolean) {
|
||||||
this.setSectionState(id, !this.getSectionState(id, def), def);
|
this.setSectionState(id, !this.getSectionState(id, def), def);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -79,27 +79,27 @@ export default class LocaleOptions
|
||||||
this.hydrate(data as Data);
|
this.hydrate(data as Data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@computed toSyncable(): { [key: string]: object } {
|
toSyncable(): { [key: string]: object } {
|
||||||
return {
|
return {
|
||||||
locale: this.toJSON(),
|
locale: this.toJSON(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@action hydrate(data: Data) {
|
hydrate(data: Data) {
|
||||||
this.setLanguage(data.lang);
|
this.setLanguage(data.lang);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get current language.
|
* Get current language.
|
||||||
*/
|
*/
|
||||||
@computed getLanguage() {
|
getLanguage() {
|
||||||
return this.lang;
|
return this.lang;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set current language.
|
* Set current language.
|
||||||
*/
|
*/
|
||||||
@action setLanguage(language: Language) {
|
setLanguage(language: Language) {
|
||||||
if (typeof Languages[language] === "undefined") return;
|
if (typeof Languages[language] === "undefined") return;
|
||||||
this.lang = language;
|
this.lang = language;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@ export default class MessageQueue implements Store {
|
||||||
* @param channel Channel ID
|
* @param channel Channel ID
|
||||||
* @param data Message data
|
* @param data Message data
|
||||||
*/
|
*/
|
||||||
@action add(id: string, channel: string, data: QueuedMessageData) {
|
add(id: string, channel: string, data: QueuedMessageData) {
|
||||||
this.messages.push({
|
this.messages.push({
|
||||||
id,
|
id,
|
||||||
channel,
|
channel,
|
||||||
|
|
@ -76,7 +76,7 @@ export default class MessageQueue implements Store {
|
||||||
* @param id Nonce value
|
* @param id Nonce value
|
||||||
* @param error Error string
|
* @param error Error string
|
||||||
*/
|
*/
|
||||||
@action fail(id: string, error: string) {
|
fail(id: string, error: string) {
|
||||||
const entry = this.messages.find((x) => x.id === id)!;
|
const entry = this.messages.find((x) => x.id === id)!;
|
||||||
entry.status = QueueStatus.ERRORED;
|
entry.status = QueueStatus.ERRORED;
|
||||||
entry.error = error;
|
entry.error = error;
|
||||||
|
|
@ -86,7 +86,7 @@ export default class MessageQueue implements Store {
|
||||||
* Mark a queued message as sending.
|
* Mark a queued message as sending.
|
||||||
* @param id Nonce value
|
* @param id Nonce value
|
||||||
*/
|
*/
|
||||||
@action start(id: string) {
|
start(id: string) {
|
||||||
const entry = this.messages.find((x) => x.id === id)!;
|
const entry = this.messages.find((x) => x.id === id)!;
|
||||||
entry.status = QueueStatus.SENDING;
|
entry.status = QueueStatus.SENDING;
|
||||||
}
|
}
|
||||||
|
|
@ -95,7 +95,7 @@ export default class MessageQueue implements Store {
|
||||||
* Remove a queued message.
|
* Remove a queued message.
|
||||||
* @param id Nonce value
|
* @param id Nonce value
|
||||||
*/
|
*/
|
||||||
@action remove(id: string) {
|
remove(id: string) {
|
||||||
const entry = this.messages.find((x) => x.id === id)!;
|
const entry = this.messages.find((x) => x.id === id)!;
|
||||||
this.messages.remove(entry);
|
this.messages.remove(entry);
|
||||||
}
|
}
|
||||||
|
|
@ -105,7 +105,7 @@ export default class MessageQueue implements Store {
|
||||||
* @param channel Channel ID
|
* @param channel Channel ID
|
||||||
* @returns Array of queued messages
|
* @returns Array of queued messages
|
||||||
*/
|
*/
|
||||||
@computed get(channel: string) {
|
get(channel: string) {
|
||||||
return this.messages.filter((x) => x.channel === channel);
|
return this.messages.filter((x) => x.channel === channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -113,7 +113,7 @@ export default class MessageQueue implements Store {
|
||||||
* Handle an incoming Message
|
* Handle an incoming Message
|
||||||
* @param message Message
|
* @param message Message
|
||||||
*/
|
*/
|
||||||
@action onMessage(message: Message) {
|
onMessage(message: Message) {
|
||||||
if (!message.nonce) return;
|
if (!message.nonce) return;
|
||||||
if (!this.get(message.channel_id).find((x) => x.id === message.nonce))
|
if (!this.get(message.channel_id).find((x) => x.id === message.nonce))
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -104,7 +104,7 @@ export default class NotificationOptions
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@action hydrate(data: Data) {
|
hydrate(data: Data) {
|
||||||
if (data.server) {
|
if (data.server) {
|
||||||
Object.keys(data.server).forEach((key) =>
|
Object.keys(data.server).forEach((key) =>
|
||||||
this.server.set(key, data.server![key]),
|
this.server.set(key, data.server![key]),
|
||||||
|
|
@ -493,11 +493,11 @@ export default class NotificationOptions
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@action apply(_key: "notifications", data: unknown, _revision: number) {
|
apply(_key: "notifications", data: unknown, _revision: number) {
|
||||||
this.hydrate(data as Data);
|
this.hydrate(data as Data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@computed toSyncable() {
|
toSyncable() {
|
||||||
return {
|
return {
|
||||||
notifications: this.toJSON(),
|
notifications: this.toJSON(),
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ export default class Ordering implements Store, Persistent<Data>, Syncable {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@action hydrate(data: Data) {
|
hydrate(data: Data) {
|
||||||
if (data.servers) {
|
if (data.servers) {
|
||||||
this.servers = data.servers;
|
this.servers = data.servers;
|
||||||
}
|
}
|
||||||
|
|
@ -63,7 +63,7 @@ export default class Ordering implements Store, Persistent<Data>, Syncable {
|
||||||
/**
|
/**
|
||||||
* All known servers with ordering applied
|
* All known servers with ordering applied
|
||||||
*/
|
*/
|
||||||
@computed get orderedServers() {
|
get orderedServers() {
|
||||||
const client = clientController.getReadyClient();
|
const client = clientController.getReadyClient();
|
||||||
const known = new Set(client?.servers.keys() ?? []);
|
const known = new Set(client?.servers.keys() ?? []);
|
||||||
const ordered = [...this.servers];
|
const ordered = [...this.servers];
|
||||||
|
|
@ -85,7 +85,7 @@ export default class Ordering implements Store, Persistent<Data>, Syncable {
|
||||||
/**
|
/**
|
||||||
* Re-order a server
|
* Re-order a server
|
||||||
*/
|
*/
|
||||||
@action reorderServer(source: number, dest: number) {
|
reorderServer(source: number, dest: number) {
|
||||||
this.servers = reorder(
|
this.servers = reorder(
|
||||||
this.orderedServers.map((x) => x._id),
|
this.orderedServers.map((x) => x._id),
|
||||||
source,
|
source,
|
||||||
|
|
|
||||||
|
|
@ -110,7 +110,7 @@ export default class Plugins implements Store, Persistent<Data> {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@action hydrate(data: Data) {
|
hydrate(data: Data) {
|
||||||
Object.keys(data["revite:plugins"]).forEach((key) =>
|
Object.keys(data["revite:plugins"]).forEach((key) =>
|
||||||
this.plugins.set(key, data["revite:plugins"][key]),
|
this.plugins.set(key, data["revite:plugins"][key]),
|
||||||
);
|
);
|
||||||
|
|
@ -121,7 +121,7 @@ export default class Plugins implements Store, Persistent<Data> {
|
||||||
* @param namespace Namespace
|
* @param namespace Namespace
|
||||||
* @param id Plugin Id
|
* @param id Plugin Id
|
||||||
*/
|
*/
|
||||||
@computed get(namespace: string, id: string) {
|
get(namespace: string, id: string) {
|
||||||
return this.plugins.get(`${namespace}/${id}`);
|
return this.plugins.get(`${namespace}/${id}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ export default class ServerConfig
|
||||||
return JSON.parse(JSON.stringify(this.config));
|
return JSON.parse(JSON.stringify(this.config));
|
||||||
}
|
}
|
||||||
|
|
||||||
@action hydrate(data: API.RevoltConfig) {
|
hydrate(data: API.RevoltConfig) {
|
||||||
this.config = data ?? null;
|
this.config = data ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -58,7 +58,7 @@ export default class ServerConfig
|
||||||
* Get server configuration.
|
* Get server configuration.
|
||||||
* @returns Server configuration
|
* @returns Server configuration
|
||||||
*/
|
*/
|
||||||
@computed get() {
|
get() {
|
||||||
return this.config;
|
return this.config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -66,7 +66,7 @@ export default class ServerConfig
|
||||||
* Set server configuration.
|
* Set server configuration.
|
||||||
* @param config Server configuration
|
* @param config Server configuration
|
||||||
*/
|
*/
|
||||||
@action set(config: API.RevoltConfig) {
|
set(config: API.RevoltConfig) {
|
||||||
this.config = config;
|
this.config = config;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,7 @@ export default class Settings
|
||||||
return JSON.parse(JSON.stringify(mapToRecord(this.data)));
|
return JSON.parse(JSON.stringify(mapToRecord(this.data)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@action hydrate(data: ISettings) {
|
hydrate(data: ISettings) {
|
||||||
Object.keys(data).forEach(
|
Object.keys(data).forEach(
|
||||||
(key) =>
|
(key) =>
|
||||||
typeof (data as any)[key] !== "undefined" &&
|
typeof (data as any)[key] !== "undefined" &&
|
||||||
|
|
@ -77,9 +77,9 @@ export default class Settings
|
||||||
* @param key Colon-divided key
|
* @param key Colon-divided key
|
||||||
* @param value Value
|
* @param value Value
|
||||||
*/
|
*/
|
||||||
@action set<T extends keyof ISettings>(key: T, value: ISettings[T]) {
|
set<T extends keyof ISettings>(key: T, value: ISettings[T]) {
|
||||||
// Emoji needs to be immediately applied.
|
// Emoji needs to be immediately applied.
|
||||||
if (key === 'appearance:emoji') {
|
if (key === "appearance:emoji") {
|
||||||
setGlobalEmojiPack(value as EmojiPack);
|
setGlobalEmojiPack(value as EmojiPack);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -92,14 +92,11 @@ export default class Settings
|
||||||
* @param defaultValue Default value if not present
|
* @param defaultValue Default value if not present
|
||||||
* @returns Value at key
|
* @returns Value at key
|
||||||
*/
|
*/
|
||||||
@computed get<T extends keyof ISettings>(
|
get<T extends keyof ISettings>(key: T, defaultValue?: ISettings[T]) {
|
||||||
key: T,
|
|
||||||
defaultValue?: ISettings[T],
|
|
||||||
) {
|
|
||||||
return (this.data.get(key) as ISettings[T] | undefined) ?? defaultValue;
|
return (this.data.get(key) as ISettings[T] | undefined) ?? defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@action remove<T extends keyof ISettings>(key: T) {
|
remove<T extends keyof ISettings>(key: T) {
|
||||||
this.data.delete(key);
|
this.data.delete(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -108,7 +105,7 @@ export default class Settings
|
||||||
* @param key Colon-divided key
|
* @param key Colon-divided key
|
||||||
* @param value Value
|
* @param value Value
|
||||||
*/
|
*/
|
||||||
@action setUnchecked(key: string, value: unknown) {
|
setUnchecked(key: string, value: unknown) {
|
||||||
this.data.set(key, value);
|
this.data.set(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -117,15 +114,11 @@ export default class Settings
|
||||||
* @param key Colon-divided key
|
* @param key Colon-divided key
|
||||||
* @returns Value at key
|
* @returns Value at key
|
||||||
*/
|
*/
|
||||||
@computed getUnchecked(key: string) {
|
getUnchecked(key: string) {
|
||||||
return this.data.get(key);
|
return this.data.get(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
@action apply(
|
apply(key: "appearance" | "theme", data: unknown, _revision: number) {
|
||||||
key: "appearance" | "theme",
|
|
||||||
data: unknown,
|
|
||||||
_revision: number,
|
|
||||||
) {
|
|
||||||
if (key === "appearance") {
|
if (key === "appearance") {
|
||||||
this.remove("appearance:emoji");
|
this.remove("appearance:emoji");
|
||||||
this.remove("appearance:seasonal");
|
this.remove("appearance:seasonal");
|
||||||
|
|
@ -143,7 +136,7 @@ export default class Settings
|
||||||
this.hydrate(data as ISettings);
|
this.hydrate(data as ISettings);
|
||||||
}
|
}
|
||||||
|
|
||||||
@computed private pullKeys(keys: (keyof ISettings)[]) {
|
private pullKeys(keys: (keyof ISettings)[]) {
|
||||||
const obj: Partial<ISettings> = {};
|
const obj: Partial<ISettings> = {};
|
||||||
keys.forEach((key) => {
|
keys.forEach((key) => {
|
||||||
const value = this.get(key);
|
const value = this.get(key);
|
||||||
|
|
@ -154,7 +147,7 @@ export default class Settings
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
@computed toSyncable() {
|
toSyncable() {
|
||||||
const data: Record<"appearance" | "theme", Partial<ISettings>> = {
|
const data: Record<"appearance" | "theme", Partial<ISettings>> = {
|
||||||
appearance: this.pullKeys([
|
appearance: this.pullKeys([
|
||||||
"appearance:emoji",
|
"appearance:emoji",
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,7 @@ export default class Sync implements Store, Persistent<Data> {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@action hydrate(data: Data) {
|
hydrate(data: Data) {
|
||||||
if (data.disabled) {
|
if (data.disabled) {
|
||||||
for (const key of data.disabled) {
|
for (const key of data.disabled) {
|
||||||
this.disabled.add(key as SyncKeys);
|
this.disabled.add(key as SyncKeys);
|
||||||
|
|
@ -82,15 +82,15 @@ export default class Sync implements Store, Persistent<Data> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@action enable(key: SyncKeys) {
|
enable(key: SyncKeys) {
|
||||||
this.disabled.delete(key);
|
this.disabled.delete(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
@action disable(key: SyncKeys) {
|
disable(key: SyncKeys) {
|
||||||
this.disabled.add(key);
|
this.disabled.add(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
@action toggle(key: SyncKeys) {
|
toggle(key: SyncKeys) {
|
||||||
if (this.isEnabled(key)) {
|
if (this.isEnabled(key)) {
|
||||||
this.disable(key);
|
this.disable(key);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -98,20 +98,20 @@ export default class Sync implements Store, Persistent<Data> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@computed isEnabled(key: SyncKeys) {
|
isEnabled(key: SyncKeys) {
|
||||||
return !this.disabled.has(key) && SYNC_KEYS.includes(key);
|
return !this.disabled.has(key) && SYNC_KEYS.includes(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
@action setRevision(key: string, revision: number) {
|
setRevision(key: string, revision: number) {
|
||||||
if (revision < (this.getRevision(key) ?? 0)) return;
|
if (revision < (this.getRevision(key) ?? 0)) return;
|
||||||
this.revision.set(key, revision);
|
this.revision.set(key, revision);
|
||||||
}
|
}
|
||||||
|
|
||||||
@computed getRevision(key: string) {
|
getRevision(key: string) {
|
||||||
return this.revision.get(key);
|
return this.revision.get(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
@action apply(data: Record<string, [number, string]>) {
|
apply(data: Record<string, [number, string]>) {
|
||||||
const tryRead = (key: string) => {
|
const tryRead = (key: string) => {
|
||||||
if (key in data) {
|
if (key in data) {
|
||||||
const revision = data[key][0];
|
const revision = data[key][0];
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ export default class SAudio {
|
||||||
setTimeout(() => this.loadCache(), 0);
|
setTimeout(() => this.loadCache(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@action setEnabled(sound: Sounds, enabled: boolean) {
|
setEnabled(sound: Sounds, enabled: boolean) {
|
||||||
const obj = this.settings.get("notifications:sounds");
|
const obj = this.settings.get("notifications:sounds");
|
||||||
this.settings.set("notifications:sounds", {
|
this.settings.set("notifications:sounds", {
|
||||||
...obj,
|
...obj,
|
||||||
|
|
@ -64,7 +64,7 @@ export default class SAudio {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@computed getSound(sound: Sounds, options?: SoundOptions): Sound {
|
getSound(sound: Sounds, options?: SoundOptions): Sound {
|
||||||
return {
|
return {
|
||||||
path: DefaultSoundPack[sound],
|
path: DefaultSoundPack[sound],
|
||||||
enabled: DEFAULT_SOUNDS.includes(sound),
|
enabled: DEFAULT_SOUNDS.includes(sound),
|
||||||
|
|
@ -72,7 +72,7 @@ export default class SAudio {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@computed getState(): ({ id: Sounds } & Sound)[] {
|
getState(): ({ id: Sounds } & Sound)[] {
|
||||||
const options = this.settings.get("notifications:sounds");
|
const options = this.settings.get("notifications:sounds");
|
||||||
return ALL_SOUNDS.map((id) => {
|
return ALL_SOUNDS.map((id) => {
|
||||||
return { id, ...this.getSound(id, options) };
|
return { id, ...this.getSound(id, options) };
|
||||||
|
|
@ -82,11 +82,10 @@ export default class SAudio {
|
||||||
getAudio(path: string) {
|
getAudio(path: string) {
|
||||||
if (this.cache.has(path)) {
|
if (this.cache.has(path)) {
|
||||||
return this.cache.get(path)!;
|
return this.cache.get(path)!;
|
||||||
}
|
}
|
||||||
const el = new Audio(path);
|
const el = new Audio(path);
|
||||||
this.cache.set(path, el);
|
this.cache.set(path, el);
|
||||||
return el;
|
return el;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
loadCache() {
|
loadCache() {
|
||||||
|
|
@ -100,7 +99,7 @@ export default class SAudio {
|
||||||
try {
|
try {
|
||||||
audio.play();
|
audio.play();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error("Hit error while playing", `${sound }:`, err);
|
console.error("Hit error while playing", `${sound}:`, err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ export default class SSecurity {
|
||||||
makeAutoObservable(this);
|
makeAutoObservable(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@action addTrustedOrigin(origin: string) {
|
addTrustedOrigin(origin: string) {
|
||||||
this.settings.set("security:trustedOrigins", [
|
this.settings.set("security:trustedOrigins", [
|
||||||
...(this.settings.get("security:trustedOrigins") ?? []).filter(
|
...(this.settings.get("security:trustedOrigins") ?? []).filter(
|
||||||
(x) => x !== origin,
|
(x) => x !== origin,
|
||||||
|
|
@ -28,7 +28,7 @@ export default class SSecurity {
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@computed isTrustedOrigin(origin: string) {
|
isTrustedOrigin(origin: string) {
|
||||||
if (TRUSTED_DOMAINS.find((x) => origin.endsWith(x))) {
|
if (TRUSTED_DOMAINS.find((x) => origin.endsWith(x))) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ export default class STheme {
|
||||||
this.reset = this.reset.bind(this);
|
this.reset = this.reset.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@computed toJSON() {
|
toJSON() {
|
||||||
return JSON.parse(
|
return JSON.parse(
|
||||||
JSON.stringify({
|
JSON.stringify({
|
||||||
...this.getVariables(),
|
...this.getVariables(),
|
||||||
|
|
@ -46,7 +46,7 @@ export default class STheme {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@action hydrate(data: Partial<Theme>, resetCSS = false) {
|
hydrate(data: Partial<Theme>, resetCSS = false) {
|
||||||
if (resetCSS) this.setCSS();
|
if (resetCSS) this.setCSS();
|
||||||
|
|
||||||
for (const key of Object.keys(data)) {
|
for (const key of Object.keys(data)) {
|
||||||
|
|
@ -74,7 +74,7 @@ export default class STheme {
|
||||||
* Get the base theme used for this theme.
|
* Get the base theme used for this theme.
|
||||||
* @returns Id of base theme
|
* @returns Id of base theme
|
||||||
*/
|
*/
|
||||||
@computed getBase() {
|
getBase() {
|
||||||
return this.settings.get("appearance:theme:base") ?? "dark";
|
return this.settings.get("appearance:theme:base") ?? "dark";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -82,7 +82,7 @@ export default class STheme {
|
||||||
* Get whether the theme is light.
|
* Get whether the theme is light.
|
||||||
* @returns True if the theme is light
|
* @returns True if the theme is light
|
||||||
*/
|
*/
|
||||||
@computed isLight() {
|
isLight() {
|
||||||
return (
|
return (
|
||||||
this.settings.get("appearance:theme:light") ??
|
this.settings.get("appearance:theme:light") ??
|
||||||
this.getBase() === "light"
|
this.getBase() === "light"
|
||||||
|
|
@ -93,7 +93,7 @@ export default class STheme {
|
||||||
* Get the current theme's CSS variables.
|
* Get the current theme's CSS variables.
|
||||||
* @returns Record of CSS variables
|
* @returns Record of CSS variables
|
||||||
*/
|
*/
|
||||||
@computed getVariables(): Theme {
|
getVariables(): Theme {
|
||||||
return {
|
return {
|
||||||
...PRESETS[this.getBase()],
|
...PRESETS[this.getBase()],
|
||||||
...this.settings.get("appearance:theme:overrides"),
|
...this.settings.get("appearance:theme:overrides"),
|
||||||
|
|
@ -101,7 +101,7 @@ export default class STheme {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@computed computeVariables(): ComputedVariables {
|
computeVariables(): ComputedVariables {
|
||||||
const variables = this.getVariables() as Record<
|
const variables = this.getVariables() as Record<
|
||||||
string,
|
string,
|
||||||
string | boolean | number
|
string | boolean | number
|
||||||
|
|
@ -110,7 +110,7 @@ export default class STheme {
|
||||||
for (const key of Object.keys(variables)) {
|
for (const key of Object.keys(variables)) {
|
||||||
const value = variables[key];
|
const value = variables[key];
|
||||||
if (typeof value === "string") {
|
if (typeof value === "string") {
|
||||||
variables[`${key }-contrast`] = getContrastingColour(value);
|
variables[`${key}-contrast`] = getContrastingColour(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -126,7 +126,7 @@ export default class STheme {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@action setVariable(key: Variables, value: string) {
|
setVariable(key: Variables, value: string) {
|
||||||
this.settings.set("appearance:theme:overrides", {
|
this.settings.set("appearance:theme:overrides", {
|
||||||
...this.settings.get("appearance:theme:overrides"),
|
...this.settings.get("appearance:theme:overrides"),
|
||||||
[key]: value,
|
[key]: value,
|
||||||
|
|
@ -138,7 +138,7 @@ export default class STheme {
|
||||||
* @param key Variable
|
* @param key Variable
|
||||||
* @returns Value of variable
|
* @returns Value of variable
|
||||||
*/
|
*/
|
||||||
@computed getVariable(key: Variables) {
|
getVariable(key: Variables) {
|
||||||
return (this.settings.get("appearance:theme:overrides")?.[key] ??
|
return (this.settings.get("appearance:theme:overrides")?.[key] ??
|
||||||
PRESETS[this.getBase()]?.[key])!;
|
PRESETS[this.getBase()]?.[key])!;
|
||||||
}
|
}
|
||||||
|
|
@ -148,11 +148,11 @@ export default class STheme {
|
||||||
* @param key Variable
|
* @param key Variable
|
||||||
* @returns Contrasting value
|
* @returns Contrasting value
|
||||||
*/
|
*/
|
||||||
@computed getContrastingVariable(key: Variables, fallback?: string) {
|
getContrastingVariable(key: Variables, fallback?: string) {
|
||||||
return getContrastingColour(this.getVariable(key), fallback);
|
return getContrastingColour(this.getVariable(key), fallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
@action setFont(font: Fonts) {
|
setFont(font: Fonts) {
|
||||||
this.settings.set("appearance:theme:font", font);
|
this.settings.set("appearance:theme:font", font);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -160,11 +160,11 @@ export default class STheme {
|
||||||
* Get the current applied font.
|
* Get the current applied font.
|
||||||
* @returns Current font
|
* @returns Current font
|
||||||
*/
|
*/
|
||||||
@computed getFont() {
|
getFont() {
|
||||||
return this.settings.get("appearance:theme:font") ?? DEFAULT_FONT;
|
return this.settings.get("appearance:theme:font") ?? DEFAULT_FONT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@action setMonospaceFont(font: MonospaceFonts) {
|
setMonospaceFont(font: MonospaceFonts) {
|
||||||
this.settings.set("appearance:theme:monoFont", font);
|
this.settings.set("appearance:theme:monoFont", font);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -172,13 +172,13 @@ export default class STheme {
|
||||||
* Get the current applied monospace font.
|
* Get the current applied monospace font.
|
||||||
* @returns Current monospace font
|
* @returns Current monospace font
|
||||||
*/
|
*/
|
||||||
@computed getMonospaceFont() {
|
getMonospaceFont() {
|
||||||
return (
|
return (
|
||||||
this.settings.get("appearance:theme:monoFont") ?? DEFAULT_MONO_FONT
|
this.settings.get("appearance:theme:monoFont") ?? DEFAULT_MONO_FONT
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@action setCSS(value?: string) {
|
setCSS(value?: string) {
|
||||||
if (value && value.length > 0) {
|
if (value && value.length > 0) {
|
||||||
this.settings.set("appearance:theme:css", value);
|
this.settings.set("appearance:theme:css", value);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -190,18 +190,18 @@ export default class STheme {
|
||||||
* Get the currently applied CSS snippet.
|
* Get the currently applied CSS snippet.
|
||||||
* @returns CSS string
|
* @returns CSS string
|
||||||
*/
|
*/
|
||||||
@computed getCSS() {
|
getCSS() {
|
||||||
return this.settings.get("appearance:theme:css");
|
return this.settings.get("appearance:theme:css");
|
||||||
}
|
}
|
||||||
|
|
||||||
@computed isModified() {
|
isModified() {
|
||||||
return (
|
return (
|
||||||
Object.keys(this.settings.get("appearance:theme:overrides") ?? {})
|
Object.keys(this.settings.get("appearance:theme:overrides") ?? {})
|
||||||
.length > 0
|
.length > 0
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@action setBase(base?: "light" | "dark") {
|
setBase(base?: "light" | "dark") {
|
||||||
if (base) {
|
if (base) {
|
||||||
this.settings.set("appearance:theme:base", base);
|
this.settings.set("appearance:theme:base", base);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -209,7 +209,7 @@ export default class STheme {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@action reset() {
|
reset() {
|
||||||
this.settings.remove("appearance:theme:overrides");
|
this.settings.remove("appearance:theme:overrides");
|
||||||
this.settings.remove("appearance:theme:css");
|
this.settings.remove("appearance:theme:css");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -128,4 +128,7 @@ export default defineConfig({
|
||||||
resolve: {
|
resolve: {
|
||||||
preserveSymlinks: true,
|
preserveSymlinks: true,
|
||||||
},
|
},
|
||||||
|
define: {
|
||||||
|
"process.env": {},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue