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