-
-
-
-
-
-
+
+
+
{"Welcome to Revolt."}
+
+
+ {loading ? (
+
+ ) : (
+ <>
+
+ {"It's time to choose a username."}
+
+ {
+ "Others will be able to find, recognise and mention you with this name, so choose wisely."
+ }
+
+ {
+ "You can change it at any time in your User Settings."
+ }
+
+
+ >
+ )}
+
-
- {loading ? (
-
- ) : (
- <>
-
-
-
-
- >
- )}
-
-
+
);
}
diff --git a/src/controllers/modals/components/legacy/UserProfile.tsx b/src/controllers/modals/components/legacy/UserProfile.tsx
index 0ec0eebd..e7f82328 100644
--- a/src/controllers/modals/components/legacy/UserProfile.tsx
+++ b/src/controllers/modals/components/legacy/UserProfile.tsx
@@ -41,8 +41,8 @@ import { ModalProps } from "../../types";
export const UserProfile = observer(
({
user_id,
- dummy,
- dummyProfile,
+ isPlaceholder,
+ placeholderProfile,
...props
}: ModalProps<"user_profile">) => {
const [profile, setProfile] = useState<
@@ -87,21 +87,21 @@ export const UserProfile = observer(
}, [user_id]);
useEffect(() => {
- if (dummy) {
- setProfile(dummyProfile);
+ if (isPlaceholder) {
+ setProfile(placeholderProfile);
}
- }, [dummy, dummyProfile]);
+ }, [isPlaceholder, placeholderProfile]);
useEffect(() => {
- if (dummy) return;
+ if (isPlaceholder) return;
if (session.state === "Online" && typeof mutual === "undefined") {
setMutual(null);
user.fetchMutual().then(setMutual);
}
- }, [mutual, session.state, dummy, user]);
+ }, [mutual, session.state, isPlaceholder, user]);
useEffect(() => {
- if (dummy) return;
+ if (isPlaceholder) return;
if (session.state === "Online" && typeof profile === "undefined") {
setProfile(null);
@@ -109,7 +109,7 @@ export const UserProfile = observer(
user.fetchProfile().then(setProfile).catch(noop);
}
}
- }, [profile, session.state, dummy, user]);
+ }, [profile, session.state, isPlaceholder, user]);
useEffect(() => {
if (
@@ -169,7 +169,8 @@ export const UserProfile = observer(
onClick={() =>
modalController.writeText(user.username)
}>
- @{user.username}
+ {"@"}
+ {user.username}
{user.status?.text && (
@@ -184,11 +185,11 @@ export const UserProfile = observer(
palette="accent"
compact
onClick={props.onClose}>
- Add to server
+ {"Add to server" /* FIXME: i18n */}
)}
- {user.relationship === "Friend" && (
+ {(user.relationship === "Friend" || user.bot) && (
)}
- {user.relationship === "User" && !dummy && (
+ {user.relationship === "User" && !isPlaceholder && (
{
props.onClose?.();
@@ -237,11 +238,13 @@ export const UserProfile = observer(
{user.relationship !== "User" && (
<>
- setTab("groups")}>
@@ -281,8 +284,9 @@ export const UserProfile = observer(
) : undefined}
{user.bot ? (
<>
+ {/* FIXME: this too */}
- bot owner
+ {"bot owner"}
@@ -432,12 +436,12 @@ export const UserProfile = observer(
>
);
- if (dummy) return
{children}
;
+ if (isPlaceholder) return
{children}
;
return (
{children}
diff --git a/src/controllers/modals/components/legacy/assets/onboarding_background.svg b/src/controllers/modals/components/legacy/assets/onboarding_background.svg
new file mode 100644
index 00000000..45975c95
--- /dev/null
+++ b/src/controllers/modals/components/legacy/assets/onboarding_background.svg
@@ -0,0 +1,2 @@
+
+
diff --git a/src/controllers/modals/types.ts b/src/controllers/modals/types.ts
index 1275fe4c..033776a6 100644
--- a/src/controllers/modals/types.ts
+++ b/src/controllers/modals/types.ts
@@ -98,8 +98,8 @@ export type Modal = {
| {
type: "user_profile";
user_id: string;
- dummy?: boolean;
- dummyProfile?: API.UserProfile;
+ isPlaceholder?: boolean;
+ placeholderProfile?: API.UserProfile;
}
| {
type: "create_bot";
diff --git a/src/lib/ContextMenus.tsx b/src/lib/ContextMenus.tsx
index 3298a4aa..16dd239a 100644
--- a/src/lib/ContextMenus.tsx
+++ b/src/lib/ContextMenus.tsx
@@ -974,6 +974,10 @@ export default function ContextMenus() {
}
}
+ // workaround to prevent button duplication
+ let hideIDButton;
+ if (sid && server) hideIDButton = true;
+
if (sid && server) {
generateAction(
{
@@ -1015,15 +1019,28 @@ export default function ContextMenus() {
"open_server_settings",
);
+ // workaround to move this above the delete/leave button
+ generateAction(
+ { action: "copy_id", id },
+ "copy_sid",
+ );
+
+ pushDivider();
if (userId === server.owner) {
generateAction(
{ action: "delete_server", target: server },
"delete_server",
+ undefined,
+ undefined,
+ "var(--error)",
);
} else {
generateAction(
{ action: "leave_server", target: server },
"leave_server",
+ undefined,
+ undefined,
+ "var(--error)",
);
}
}
@@ -1035,16 +1052,16 @@ export default function ContextMenus() {
});
}
- generateAction(
- { action: "copy_id", id },
- sid
- ? "copy_sid"
- : cid
- ? "copy_cid"
- : message
- ? "copy_mid"
- : "copy_uid",
- );
+ if (!hideIDButton) {
+ generateAction(
+ { action: "copy_id", id },
+ cid
+ ? "copy_cid"
+ : message
+ ? "copy_mid"
+ : "copy_uid",
+ );
+ }
}
return elements;
diff --git a/src/lib/vortex/VoiceState.ts b/src/lib/vortex/VoiceState.ts
index e83bafec..f284820b 100644
--- a/src/lib/vortex/VoiceState.ts
+++ b/src/lib/vortex/VoiceState.ts
@@ -1,6 +1,5 @@
import { action, makeAutoObservable, runInAction } from "mobx";
-import { Channel } from "revolt.js";
-import { Nullable, toNullable } from "revolt.js";
+import { Channel, Nullable, toNullable } from "revolt.js";
import type { ProduceType, VoiceUser } from "./Types";
import type VoiceClient from "./VoiceClient";
diff --git a/src/mobx/stores/Draft.ts b/src/mobx/stores/Draft.ts
index de84c1f9..345351d7 100644
--- a/src/mobx/stores/Draft.ts
+++ b/src/mobx/stores/Draft.ts
@@ -5,15 +5,22 @@ import { mapToRecord } from "../../lib/conversion";
import Persistent from "../interfaces/Persistent";
import Store from "../interfaces/Store";
+interface DraftObject {
+ content?: string;
+ masquerade?: {
+ avatar: string;
+ name: string;
+ };
+}
export interface Data {
- drafts: Record;
+ drafts: Record;
}
/**
* Handles storing draft (currently being written) messages.
*/
export default class Draft implements Store, Persistent {
- private drafts: ObservableMap;
+ private drafts: ObservableMap;
/**
* Construct new Draft store.
@@ -52,7 +59,10 @@ export default class Draft implements Store, Persistent {
* @param channel Channel ID
*/
@computed has(channel: string) {
- return this.drafts.has(channel) && this.drafts.get(channel)!.length > 0;
+ return (
+ this.drafts.has(channel) &&
+ this.drafts.get(channel)!.content!.length > 0
+ );
}
/**
@@ -60,7 +70,7 @@ export default class Draft implements Store, Persistent {
* @param channel Channel ID
* @param content Draft content
*/
- @action set(channel: string, content?: string) {
+ @action set(channel: string, content?: DraftObject) {
if (typeof content === "undefined") {
return this.clear(channel);
}
diff --git a/src/mobx/stores/Experiments.ts b/src/mobx/stores/Experiments.ts
index 23dd1751..63df9811 100644
--- a/src/mobx/stores/Experiments.ts
+++ b/src/mobx/stores/Experiments.ts
@@ -29,13 +29,13 @@ export const EXPERIMENTS: {
[key in Experiment]: { title: string; description: string };
} = {
dummy: {
- title: "Dummy Experiment",
- description: "This is a dummy experiment.",
+ title: "Placeholder Experiment",
+ description: "This is a placeholder experiment.",
},
offline_users: {
title: "Re-enable offline users in large servers (>10k members)",
description:
- "If you can take the performance hit (for example, you're on desktop), you can re-enable offline users for big servers such as Revolt Lounge.",
+ "If you can take the performance hit - for example, if you're on desktop - you can re-enable offline users for big servers such as the Revolt Lounge.",
},
plugins: {
title: "Experimental Plugin API",
@@ -45,7 +45,7 @@ export const EXPERIMENTS: {
picker: {
title: "Custom Emoji",
description:
- "This will enable a work-in-progress emoji picker, custom emoji settings and reaction picker.",
+ "This will enable a work-in-progress emoji picker, custom emoji settings and a reaction picker.",
},
};
diff --git a/src/mobx/stores/Settings.ts b/src/mobx/stores/Settings.ts
index 344d65a7..bfb28cf4 100644
--- a/src/mobx/stores/Settings.ts
+++ b/src/mobx/stores/Settings.ts
@@ -21,6 +21,7 @@ export interface ISettings {
"appearance:seasonal": boolean;
"appearance:transparency": boolean;
"appearance:show_send_button": boolean;
+ "appearance:show_account_age": boolean;
"appearance:theme:base": "dark" | "light";
"appearance:theme:overrides": Partial;
@@ -79,7 +80,7 @@ export default class Settings
*/
@action set(key: T, value: ISettings[T]) {
// Emoji needs to be immediately applied.
- if (key === 'appearance:emoji') {
+ if (key === "appearance:emoji") {
setGlobalEmojiPack(value as EmojiPack);
}
diff --git a/src/pages/RevoltApp.tsx b/src/pages/RevoltApp.tsx
index 23849dd6..3f9d2c48 100644
--- a/src/pages/RevoltApp.tsx
+++ b/src/pages/RevoltApp.tsx
@@ -126,7 +126,7 @@ export default function App() {
)}
{alert.dismissable !== false && (
setStatusBar(false)}>
- Dismiss
+ {"Dismiss"}
)}
diff --git a/src/pages/developer/Developer.tsx b/src/pages/developer/Developer.tsx
index 3c6009db..5cfcd391 100644
--- a/src/pages/developer/Developer.tsx
+++ b/src/pages/developer/Developer.tsx
@@ -2,6 +2,8 @@ import { Wrench } from "@styled-icons/boxicons-solid";
import { useEffect, useState } from "preact/hooks";
+import { Button } from "@revoltchat/ui";
+
import PaintCounter from "../../lib/PaintCounter";
import { TextReact } from "../../lib/i18n";
@@ -45,8 +47,15 @@ export default function Developer() {
-
setCrash(true)}>click to crash app
- {crash && (window as any).sus.sus()}
+
+ {
+ crash &&
+ (
+ window as any
+ ).sus.sus() /* this runs a function that doesn't exist */
+ }
{/*
Voice Status: {VoiceStatus[voice.status]}
diff --git a/src/pages/home/Home.tsx b/src/pages/home/Home.tsx
index 75609150..f6c82ba1 100644
--- a/src/pages/home/Home.tsx
+++ b/src/pages/home/Home.tsx
@@ -51,21 +51,37 @@ export default observer(() => {
state.settings.set("appearance:seasonal", !seasonalTheme);
const isDecember = !isTouchscreenDevice && new Date().getMonth() === 11;
+ const isOctober = !isTouchscreenDevice && new Date().getMonth() === 9
const snowflakes = useMemo(() => {
const flakes = [];
- // Disable outside of December
- if (!isDecember) return [];
+ if (isDecember) {
+ for (let i = 0; i < 15; i++) {
+ flakes.push("❄️");
+ flakes.push("❄");
+ }
- for (let i = 0; i < 15; i++) {
- flakes.push("❄️");
- flakes.push("❄");
+ for (let i = 0; i < 2; i++) {
+ flakes.push("🎄");
+ flakes.push("☃️");
+ flakes.push("⛄");
+ }
+
+ return flakes;
}
+ if (isOctober) {
+ for (let i = 0; i < 15; i++) {
+ flakes.push("🎃");
+ flakes.push("💀");
+ }
- for (let i = 0; i < 2; i++) {
- flakes.push("🎄");
- flakes.push("☃️");
- flakes.push("⛄");
+ for (let i = 0; i < 2; i++) {
+ flakes.push("👻");
+ flakes.push("⚰️");
+ flakes.push("🕷️");
+ }
+
+ return flakes;
}
return flakes;
diff --git a/src/pages/login/background-old.jpg b/src/pages/login/background-old.jpg
deleted file mode 100644
index 44254ed7..00000000
Binary files a/src/pages/login/background-old.jpg and /dev/null differ
diff --git a/src/pages/settings/channel/Permissions.tsx b/src/pages/settings/channel/Permissions.tsx
index 1b8069ae..699067aa 100644
--- a/src/pages/settings/channel/Permissions.tsx
+++ b/src/pages/settings/channel/Permissions.tsx
@@ -1,7 +1,6 @@
import isEqual from "lodash.isequal";
import { observer } from "mobx-react-lite";
-import { Channel, API } from "revolt.js";
-import { DEFAULT_PERMISSION_DIRECT_MESSAGE } from "revolt.js";
+import { Channel, API, DEFAULT_PERMISSION_DIRECT_MESSAGE } from "revolt.js";
import { Text } from "preact-i18n";
import { useState } from "preact/hooks";
diff --git a/src/pages/settings/panes/Feedback.tsx b/src/pages/settings/panes/Feedback.tsx
index 66125beb..c22eba74 100644
--- a/src/pages/settings/panes/Feedback.tsx
+++ b/src/pages/settings/panes/Feedback.tsx
@@ -24,7 +24,7 @@ export function Feedback() {
}
description="You can report issues and discuss improvements with us directly here.">
- Join Testers server.
+ {"Join the Revolt Lounge"}
diff --git a/src/pages/settings/panes/Native.tsx b/src/pages/settings/panes/Native.tsx
index da02d777..ad6f620b 100644
--- a/src/pages/settings/panes/Native.tsx
+++ b/src/pages/settings/panes/Native.tsx
@@ -165,18 +165,22 @@ export function Native() {
title="I understand there's no going back."
description={
<>
- This will change the app to the 'dev' branch,
- instead loading the app from a local server on
- your machine.
+ {
+ "This will change the app to the 'dev' branch, instead loading the app from a local server on your machine."
+ }
- Without a server running,{" "}
+ {"Without a server running, "}
- the app will not load!
+ {"the app will not load!"}
-
yarn dev --port 3001
+ {
+ "Make sure the app is available on port 3001 by running "
+ }
+
{"yarn dev --port 3001 --host"}
+ {"."}
>
}
/>
diff --git a/src/pages/settings/panes/Profile.tsx b/src/pages/settings/panes/Profile.tsx
index 76f68e37..75b01403 100644
--- a/src/pages/settings/panes/Profile.tsx
+++ b/src/pages/settings/panes/Profile.tsx
@@ -72,8 +72,8 @@ export const Profile = observer(() => {
diff --git a/src/pages/settings/panes/Sessions.tsx b/src/pages/settings/panes/Sessions.tsx
index b937686b..c2fab342 100644
--- a/src/pages/settings/panes/Sessions.tsx
+++ b/src/pages/settings/panes/Sessions.tsx
@@ -1,4 +1,4 @@
-import { Chrome, Android, Apple, Windows } from "@styled-icons/boxicons-logos";
+import { Chrome, Android, Windows } from "@styled-icons/boxicons-logos";
import { HelpCircle, Desktop, LogOut } from "@styled-icons/boxicons-regular";
import {
Safari,
@@ -6,6 +6,7 @@ import {
Microsoftedge,
Linux,
Macos,
+ Ios,
Opera,
Samsung,
Windowsxp,
@@ -99,7 +100,7 @@ export function Sessions() {
case /mac.*os/i.test(name):
return
;
case /i(Pad)?os/i.test(name):
- return
;
+ return
;
case /windows 7/i.test(name):
return
;
case /windows/i.test(name):
diff --git a/src/pages/settings/server/Overview.tsx b/src/pages/settings/server/Overview.tsx
index 7dc56c39..3d8c026d 100644
--- a/src/pages/settings/server/Overview.tsx
+++ b/src/pages/settings/server/Overview.tsx
@@ -96,14 +96,14 @@ export const Overview = observer(({ server }: Props) => {
diff --git a/src/pages/settings/server/Panes.module.scss b/src/pages/settings/server/Panes.module.scss
index 2c26ffcb..9fe31f8c 100644
--- a/src/pages/settings/server/Panes.module.scss
+++ b/src/pages/settings/server/Panes.module.scss
@@ -80,7 +80,7 @@
}
code {
- font-size: 1.4em;
+ font-family: var(--monospace-font);
user-select: all;
}
diff --git a/src/pages/settings/server/Roles.tsx b/src/pages/settings/server/Roles.tsx
index de43c626..a46c87bd 100644
--- a/src/pages/settings/server/Roles.tsx
+++ b/src/pages/settings/server/Roles.tsx
@@ -1,6 +1,8 @@
+import { HelpCircle } from "@styled-icons/boxicons-solid";
import isEqual from "lodash.isequal";
import { observer } from "mobx-react-lite";
import { Server } from "revolt.js";
+import styled from "styled-components";
import { Text } from "preact-i18n";
import { useMemo, useState } from "preact/hooks";
@@ -16,6 +18,7 @@ import {
Category,
} from "@revoltchat/ui";
+import Tooltip from "../../../components/common/Tooltip";
import { PermissionList } from "../../../components/settings/roles/PermissionList";
import { RoleOrDefault } from "../../../components/settings/roles/RoleSelection";
import { modalController } from "../../../controllers/modals/ModalController";
@@ -53,6 +56,20 @@ export const Roles = observer(({ server }: Props) => {
// Consolidate all permissions that we can change right now.
const currentRoles = useRoles(server);
+ const RoleId = styled.div`
+ gap: 4px;
+ display: flex;
+ align-items: center;
+
+ font-size: 12px;
+ font-weight: 600;
+ color: var(--tertiary-foreground);
+
+ a {
+ color: var(--tertiary-foreground);
+ }
+ `;
+
return (
{
/>
+
diff --git a/yarn.lock b/yarn.lock
index a0bf5d13..4afa15be 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1590,7 +1590,7 @@ __metadata:
languageName: node
linkType: hard
-"@babel/runtime@npm:^7.1.2, @babel/runtime@npm:^7.10.5, @babel/runtime@npm:^7.11.2, @babel/runtime@npm:^7.12.1, @babel/runtime@npm:^7.12.13, @babel/runtime@npm:^7.14.8, @babel/runtime@npm:^7.8.4":
+"@babel/runtime@npm:^7.1.2, @babel/runtime@npm:^7.10.5, @babel/runtime@npm:^7.11.2, @babel/runtime@npm:^7.12.1, @babel/runtime@npm:^7.12.13, @babel/runtime@npm:^7.8.4":
version: 7.15.3
resolution: "@babel/runtime@npm:7.15.3"
dependencies:
@@ -1617,6 +1617,15 @@ __metadata:
languageName: node
linkType: hard
+"@babel/runtime@npm:^7.17.9":
+ version: 7.18.9
+ resolution: "@babel/runtime@npm:7.18.9"
+ dependencies:
+ regenerator-runtime: ^0.13.4
+ checksum: 36dd736baba7164e82b3cc9d43e081f0cb2d05ff867ad39cac515d99546cee75b7f782018b02a3dcf5f2ef3d27f319faa68965fdfec49d4912c60c6002353a2e
+ languageName: node
+ linkType: hard
+
"@babel/standalone@npm:^7.17.2":
version: 7.17.6
resolution: "@babel/standalone@npm:7.17.6"
@@ -2020,13 +2029,15 @@ __metadata:
languageName: node
linkType: hard
-"@hcaptcha/react-hcaptcha@npm:^0.3.6":
- version: 0.3.7
- resolution: "@hcaptcha/react-hcaptcha@npm:0.3.7"
+"@hcaptcha/react-hcaptcha@npm:^1.4.4":
+ version: 1.4.4
+ resolution: "@hcaptcha/react-hcaptcha@npm:1.4.4"
+ dependencies:
+ "@babel/runtime": ^7.17.9
peerDependencies:
react: ">= 16.3.0"
react-dom: ">= 16.3.0"
- checksum: 4a0ce88dd7a719cae2dc84255466a8636540287c2208f8fe46003a67c72f65509cabf8452cad73982a514cfce2e475d209a3e67cd41a559465f185fb4176a92f
+ checksum: 16b046702957f4ca5041c37f2a5012e07415469667fee0396b4764baa7ce0fe5a8577cf652b977732f026d745c999f7e1522bca3b3ca6effea5cfff189ddff2f
languageName: node
linkType: hard
@@ -2414,16 +2425,16 @@ __metadata:
languageName: node
linkType: hard
-"@styled-icons/simple-icons@npm:^10.33.0":
- version: 10.37.0
- resolution: "@styled-icons/simple-icons@npm:10.37.0"
+"@styled-icons/simple-icons@npm:^10.45.0":
+ version: 10.45.0
+ resolution: "@styled-icons/simple-icons@npm:10.45.0"
dependencies:
- "@babel/runtime": ^7.14.8
+ "@babel/runtime": ^7.15.4
"@styled-icons/styled-icon": ^10.6.3
peerDependencies:
react: "*"
styled-components: "*"
- checksum: d94b94f6ad82aef50c69933f2f99d9ccdcadf3579f1ecd9fc5b5537ff1a2d7c0630579c4f1e0f73d6893a4e1cea4010d4ab927ba848a6bab7b1fba31e59c0f01
+ checksum: fda28f4ce59282916413ac2d638440a186f4ae2b1b5904c0e9695efdeec3849800a659f1292299d9afa45276e926f4110b6cbe9259dc38d9ffdc41ef0b4c0086
languageName: node
linkType: hard
@@ -2692,7 +2703,7 @@ __metadata:
languageName: node
linkType: hard
-"@types/node@npm:^15.12.4":
+"@types/node@npm:^15.14.9":
version: 15.14.9
resolution: "@types/node@npm:15.14.9"
checksum: 49f7f0522a3af4b8389aee660e88426490cd54b86356672a1fedb49919a8797c00d090ec2dcc4a5df34edc2099d57fc2203d796c4e7fbd382f2022ccd789eee7
@@ -2722,14 +2733,7 @@ __metadata:
languageName: node
linkType: hard
-"@types/prismjs@npm:^1.16.5":
- version: 1.16.6
- resolution: "@types/prismjs@npm:1.16.6"
- checksum: fcb489d19d21292ceffc661fd9c9aa8ba36bcd2835388fa85812aa60cdf14d4720ceb22be7a088aa753c48462e75bcd8191d178a085e4a8b0d3f34471d30d86a
- languageName: node
- linkType: hard
-
-"@types/prismjs@npm:^1.16.6":
+"@types/prismjs@npm:^1.16.6, @types/prismjs@npm:^1.26.0":
version: 1.26.0
resolution: "@types/prismjs@npm:1.26.0"
checksum: cd5e7a6214c1f4213ec512a5fcf6d8fe37a56b813fc57ac95b5ff5ee074742bfdbd2f2730d9fd985205bf4586728e09baa97023f739e5aa1c9735a7c1ecbd11a
@@ -3681,7 +3685,7 @@ __metadata:
"@fontsource/space-mono": ^4.4.5
"@fontsource/ubuntu": ^4.4.5
"@fontsource/ubuntu-mono": ^4.4.5
- "@hcaptcha/react-hcaptcha": ^0.3.6
+ "@hcaptcha/react-hcaptcha": ^1.4.4
"@insertish/vite-plugin-babel-macros": ^1.0.5
"@preact/preset-vite": ^2.0.0
"@revoltchat/ui": ^1.0.77
@@ -3689,7 +3693,7 @@ __metadata:
"@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/simple-icons": ^10.45.0
"@tippyjs/react": 4.2.6
"@traptitech/markdown-it-katex": ^3.4.3
"@traptitech/markdown-it-spoiler": ^1.1.6
@@ -3697,9 +3701,9 @@ __metadata:
"@types/lodash": ^4
"@types/lodash.defaultsdeep": ^4.6.6
"@types/lodash.isequal": ^4.5.5
- "@types/node": ^15.12.4
+ "@types/node": ^15.14.9
"@types/preact-i18n": ^2.3.0
- "@types/prismjs": ^1.16.5
+ "@types/prismjs": ^1.26.0
"@types/react-beautiful-dnd": ^13
"@types/react-helmet": ^6.1.1
"@types/react-router-dom": ^5.1.7