diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index 7ba4fae9..00000000 --- a/.eslintrc.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "root": true, - "parser": "@typescript-eslint/parser", - "plugins": ["solid", "spellcheck"], - "extends": [ - "eslint:recommended", - "plugin:solid/typescript", - "plugin:@typescript-eslint/recommended", - "prettier" - ], - "rules": { - "@typescript-eslint/no-non-null-assertion": "off", - "spellcheck/spell-checker": [ - "warn", - { - "lang": "en_GB", - "strings": false, - "identifiers": false, - "templates": false, - "skipWords": ["dismissable", "regex", "accessor", "dnd", "webhooks"], - "minLength": 3 - } - ], - "@typescript-eslint/no-unused-vars": [ - "warn", - { - "varsIgnorePattern": "^_" - } - ], - "no-unused-vars": [ - "warn", - { - "varsIgnorePattern": "^_" - } - ], - "require-jsdoc": [ - "warn", - { - "require": { - "FunctionDeclaration": true, - "MethodDefinition": true, - "ClassDeclaration": true, - "ArrowFunctionExpression": true, - "FunctionExpression": true - } - } - ] - } -} diff --git a/.gitignore b/.gitignore index 233f6745..84fa7fc3 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ dist .env* !.env.example .vercel +.idea diff --git a/.prettierrc b/.prettierrc deleted file mode 100644 index d15c81ce..00000000 --- a/.prettierrc +++ /dev/null @@ -1,15 +0,0 @@ -{ - "tabWidth": 2, - "useTabs": false, - "plugins": ["@trivago/prettier-plugin-sort-imports"], - "importOrder": [ - "^solid", - "", - "^@revolt", - "^@material-design-icons", - "^\\.\\.", - "^[./]" - ], - "importOrderSeparation": true, - "importOrderSortSpecifiers": true -} diff --git a/.prettierrc.cjs b/.prettierrc.cjs new file mode 100644 index 00000000..d14cd8be --- /dev/null +++ b/.prettierrc.cjs @@ -0,0 +1,14 @@ +const prettierConfigStandard = require('prettier-config-standard'); + +const modifiedConfig = { + ...prettierConfigStandard, + semi: true, + parser: 'typescript', + singleQuote: true, + trailingComma: 'es5', + proseWrap: 'never', + arrowParens: 'always', + tabWidth: 2, +}; + +module.exports = modifiedConfig; \ No newline at end of file diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 00000000..f434f30d --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,52 @@ +// @ts-check +import eslint from '@eslint/js'; +import prettier from 'eslint-plugin-prettier/recommended'; +import promise from 'eslint-plugin-promise'; +import simpleImportSort from 'eslint-plugin-simple-import-sort'; +import solid from 'eslint-plugin-solid/configs/typescript'; +import tseslint from 'typescript-eslint'; +import path from 'node:path'; +import tsParser from '@typescript-eslint/parser'; + +export default tseslint.config( + prettier, + eslint.configs.recommended, + ...tseslint.configs.recommended, + ...tseslint.configs.stylistic, + { + ignores: ['**/styled-system/'], + }, + { + files: ['**/*.tsx', '**/*.ts'], + extends: [solid], + plugins: { + 'simple-import-sort': simpleImportSort, + promise, + }, + languageOptions: { + parser: tsParser, + parserOptions: { + project: path.resolve( + import.meta.dirname, + 'packages', + 'client', + 'tsconfig.json' + ), + tsconfigRootDir: path.resolve( + import.meta.dirname, + 'packages', + 'client' + ), + }, + }, + rules: { + 'simple-import-sort/imports': 'error', + 'simple-import-sort/exports': 'error', + '@typescript-eslint/consistent-type-imports': 'error', + '@typescript-eslint/no-non-null-assertion': 'off', + '@typescript-eslint/no-unused-vars': 'off', + 'solid/jsx-no-undef': 'off', + 'no-unused-vars': 'off', + }, + } +); diff --git a/package.json b/package.json index 7494cbd3..496465ba 100644 --- a/package.json +++ b/package.json @@ -1,9 +1,10 @@ { "name": "resolvite", + "type": "module", "version": "1.0.0", "description": "Revolt's front-end monorepo.", "scripts": { - "test": "pnpm --filter test-runner test", + "test": "pnpm test --filter=client", "test:coverage": "pnpm --filter test-runner coverage", "test:browser:install": "pnpm --filter browser-test-runner exec playwright install", "test:browser:regression": "pnpm --filter browser-test-runner exec playwright test regression", @@ -20,6 +21,20 @@ "fmt:check": "prettier --check '**/*.{ts,tsx,json}'", "typecheck": "cd packages/client && pnpm run typecheck" }, + "devDependencies": { + "@eslint/js": "^9.12.0", + "@types/node": "^22.7.5", + "eslint": "^9.12.0", + "eslint-config-prettier": "^8.10.0", + "eslint-plugin-prettier": "^5.2.1", + "eslint-plugin-promise": "^7.1.0", + "eslint-plugin-simple-import-sort": "^12.1.1", + "eslint-plugin-solid": "^0.14.3", + "prettier": "^3.3.3", + "prettier-config-standard": "^7.0.0", + "typescript-eslint": "^8.8.1", + "@typescript-eslint/parser": "^8.8.1" + }, "keywords": [], "engines": { "node": ">=16", diff --git a/packages/client/.storybook/main.ts b/packages/client/.storybook/main.ts index b6631c16..eed860f8 100644 --- a/packages/client/.storybook/main.ts +++ b/packages/client/.storybook/main.ts @@ -1,16 +1,16 @@ -import type { StorybookConfig } from "storybook-solidjs-vite"; +import type { StorybookConfig } from 'storybook-solidjs-vite'; const config: StorybookConfig = { - stories: ["../**/*.mdx", "../**/*.story.@(js|jsx|mjs|ts|tsx)"], + stories: ['../**/*.mdx', '../**/*.story.@(js|jsx|mjs|ts|tsx)'], // stories: ["../src/**/*.mdx", "../src/**/*.stories.@(js|jsx|mjs|ts|tsx)"], addons: [ - "@storybook/addon-links", - "@storybook/addon-essentials", - "@chromatic-com/storybook", - "@storybook/addon-interactions", + '@storybook/addon-links', + '@storybook/addon-essentials', + '@chromatic-com/storybook', + '@storybook/addon-interactions', ], framework: { - name: "storybook-solidjs-vite", + name: 'storybook-solidjs-vite', options: {}, }, }; diff --git a/packages/client/.storybook/preview.tsx b/packages/client/.storybook/preview.tsx index 9be8a494..1cb9a139 100644 --- a/packages/client/.storybook/preview.tsx +++ b/packages/client/.storybook/preview.tsx @@ -1,7 +1,7 @@ -import { ApplyGlobalStyles, ThemeProvider, darkTheme } from "@revolt/ui"; -import "@revolt/ui/styles"; +import '@revolt/ui/styles'; +import './panda.css'; -import "./panda.css"; +import { ApplyGlobalStyles, darkTheme, ThemeProvider } from '@revolt/ui'; const preview: Preview = { parameters: { @@ -14,7 +14,7 @@ const preview: Preview = { }, decorators: [ (story) => ( - + {story} ), diff --git a/packages/client/codegen.plugin.ts b/packages/client/codegen.plugin.ts index 0ec019d4..d0d59141 100644 --- a/packages/client/codegen.plugin.ts +++ b/packages/client/codegen.plugin.ts @@ -1,27 +1,27 @@ -import { readdirSync } from "node:fs"; +import { readdirSync } from 'node:fs'; const fileRegex = /\.tsx$/; const codegenRegex = /\/\/ @codegen (.*)/g; -const DIRECTIVES = readdirSync("./components/ui/directives") - .filter((x) => x !== "index.ts") +const DIRECTIVES = readdirSync('./components/ui/directives') + .filter((x) => x !== 'index.ts') .map((x) => x.substring(0, x.length - 3)); -const directiveRegex = new RegExp("use:(" + DIRECTIVES.join("|") + ")"); +const directiveRegex = new RegExp('use:(' + DIRECTIVES.join('|') + ')'); export default function codegenPlugin() { return { - name: "codegen", - enforce: "pre", + name: 'codegen', + enforce: 'pre' as const, transform(src: string, id: string) { if (fileRegex.test(id)) { src = src.replace(codegenRegex, (substring, group1) => { - const rawArgs: string[] = group1.split(" "); + const rawArgs: string[] = group1.split(' '); const type = rawArgs.shift(); const args = rawArgs.reduce( (d, arg) => { - const [key, value] = arg.split("="); + const [key, value] = arg.split('='); return { ...d, [key]: value, @@ -29,30 +29,30 @@ export default function codegenPlugin() { }, { type } ) as { - type: "directives"; + type: 'directives'; props?: string; include?: string; }; switch (args.type) { - case "directives": + case 'directives': // Generate directives forwarding - const source = args.props ?? "props"; + const source = args.props ?? 'props'; const permitted: string[] = - args.include?.split(",") ?? DIRECTIVES; + args.include?.split(',') ?? DIRECTIVES; return DIRECTIVES.filter((d) => permitted.includes(d)) .map((d) => `use:${d}={${source}["use:${d}"]}`) - .join("\n"); + .join('\n'); default: return substring; } }); if (directiveRegex.test(src)) { - if (!id.endsWith("client/components/ui/index.tsx")) + if (!id.endsWith('client/components/ui/index.tsx')) src = `import { ${DIRECTIVES.join( - ", " + ', ' )} } from "@revolt/ui/directives";\n` + src; } diff --git a/packages/client/components/app/index.tsx b/packages/client/components/app/index.tsx index 411a38df..ef1a4817 100644 --- a/packages/client/components/app/index.tsx +++ b/packages/client/components/app/index.tsx @@ -1,6 +1,5 @@ -export { Message } from "./interface/channels/text/Message"; -export { Messages } from "./interface/channels/text/Messages"; -export { DraftMessages } from "./interface/channels/text/DraftMessages"; - -export * from "./interface/settings"; -export * from "./menus"; +export { DraftMessages } from './interface/channels/text/DraftMessages'; +export { Message } from './interface/channels/text/Message'; +export { Messages } from './interface/channels/text/Messages'; +export * from './interface/settings'; +export * from './menus'; diff --git a/packages/client/components/app/interface/channels/text/DraftMessage.tsx b/packages/client/components/app/interface/channels/text/DraftMessage.tsx index d3be1fbd..c7ae33d0 100644 --- a/packages/client/components/app/interface/channels/text/DraftMessage.tsx +++ b/packages/client/components/app/interface/channels/text/DraftMessage.tsx @@ -1,13 +1,11 @@ -import { For } from "solid-js"; +import { useClient, useUser } from '@revolt/client'; +import { userInformation } from '@revolt/markdown/users'; +import type { UnsentMessage } from '@revolt/state/stores/Draft'; +import { Avatar, MessageContainer, MessageReply, Username } from '@revolt/ui'; +import type { Channel } from 'revolt.js'; +import { For } from 'solid-js'; -import type { Channel } from "revolt.js"; - -import { useClient, useUser } from "@revolt/client"; -import { userInformation } from "@revolt/markdown/users"; -import type { UnsentMessage } from "@revolt/state/stores/Draft"; -import { Avatar, MessageContainer, MessageReply, Username } from "@revolt/ui"; - -import { DraftMessageContextMenu } from "../../../menus/DraftMessageContextMenu"; +import { DraftMessageContextMenu } from '../../../menus/DraftMessageContextMenu'; interface Props { draft: UnsentMessage; @@ -31,13 +29,13 @@ export function DraftMessage(props: Props) { timestamp={ // TODO // i18n missing - props.draft.status === "sending" - ? "Sending..." - : props.draft.status === "failed" - ? "Failed to send" // add icons here - : "Unsent message" // add icons here + props.draft.status === 'sending' + ? 'Sending...' + : props.draft.status === 'failed' + ? 'Failed to send' // add icons here + : 'Unsent message' // add icons here } - sendStatus={props.draft.status === "sending" ? "sending" : "failed"} + sendStatus={props.draft.status === 'sending' ? 'sending' : 'failed'} username={} header={ diff --git a/packages/client/components/app/interface/channels/text/DraftMessages.tsx b/packages/client/components/app/interface/channels/text/DraftMessages.tsx index fb376643..96c23e1e 100644 --- a/packages/client/components/app/interface/channels/text/DraftMessages.tsx +++ b/packages/client/components/app/interface/channels/text/DraftMessages.tsx @@ -1,10 +1,8 @@ -import { For } from "solid-js"; +import { state } from '@revolt/state'; +import type { Channel } from 'revolt.js'; +import { For } from 'solid-js'; -import { Channel } from "revolt.js"; - -import { state } from "@revolt/state"; - -import { DraftMessage } from "./DraftMessage"; +import { DraftMessage } from './DraftMessage'; interface Props { channel: Channel; @@ -19,12 +17,12 @@ export function DraftMessages(props: Props) { const unsent = () => state.draft .getPendingMessages(props.channel.id) - .filter((draft) => draft.status === "sending"); + .filter((draft) => draft.status === 'sending'); const failed = () => state.draft .getPendingMessages(props.channel.id) - .filter((draft) => draft.status !== "sending"); + .filter((draft) => draft.status !== 'sending'); return ( <> diff --git a/packages/client/components/app/interface/channels/text/Message.tsx b/packages/client/components/app/interface/channels/text/Message.tsx index 8224673b..80cac219 100644 --- a/packages/client/components/app/interface/channels/text/Message.tsx +++ b/packages/client/components/app/interface/channels/text/Message.tsx @@ -1,41 +1,38 @@ -import { For, Match, Show, Switch, onMount } from "solid-js"; - -import { Message as MessageInterface, WebsiteEmbed } from "revolt.js"; -import { decodeTime } from "ulid"; - -import { useClient } from "@revolt/client"; -import { dayjs, useTranslation } from "@revolt/i18n"; -import { Markdown } from "@revolt/markdown"; -import { state } from "@revolt/state"; +import MdCloud from '@material-design-icons/svg/filled/cloud.svg?component-solid'; +import MdLink from '@material-design-icons/svg/filled/link.svg?component-solid'; +import MdNotificationsOff from '@material-design-icons/svg/filled/notifications_off.svg?component-solid'; +import MdShield from '@material-design-icons/svg/filled/shield.svg?component-solid'; +import MdSmartToy from '@material-design-icons/svg/filled/smart_toy.svg?component-solid'; +import MdSpa from '@material-design-icons/svg/filled/spa.svg?component-solid'; +import { useClient } from '@revolt/client'; +import { dayjs, useTranslation } from '@revolt/i18n'; +import { Markdown } from '@revolt/markdown'; +import { state } from '@revolt/state'; import { Attachment, Avatar, BreakText, Column, Embed, + iconSize, MessageContainer, MessageReply, Reactions, + styled, SystemMessage, SystemMessageIcon, Tooltip, Username, - iconSize, - styled, -} from "@revolt/ui"; - -import MdCloud from "@material-design-icons/svg/filled/cloud.svg?component-solid"; -import MdLink from "@material-design-icons/svg/filled/link.svg?component-solid"; -import MdNotificationsOff from "@material-design-icons/svg/filled/notifications_off.svg?component-solid"; -import MdShield from "@material-design-icons/svg/filled/shield.svg?component-solid"; -import MdSmartToy from "@material-design-icons/svg/filled/smart_toy.svg?component-solid"; -import MdSpa from "@material-design-icons/svg/filled/spa.svg?component-solid"; +} from '@revolt/ui'; +import type { Message as MessageInterface, WebsiteEmbed } from 'revolt.js'; +import { For, Match, onMount, Show, Switch } from 'solid-js'; +import { decodeTime } from 'ulid'; -import { MessageContextMenu } from "../../../menus/MessageContextMenu"; +import { MessageContextMenu } from '../../../menus/MessageContextMenu'; import { floatingUserMenus, floatingUserMenusFromMessage, -} from "../../../menus/UserContextMenu"; +} from '../../../menus/UserContextMenu'; /** * Regex for matching URLs @@ -73,10 +70,10 @@ export function Message(props: Props) { const isOnlyGIF = () => props.message.embeds && props.message.embeds.length === 1 && - props.message.embeds[0].type === "Website" && - (props.message.embeds[0] as WebsiteEmbed).specialContent?.type === "GIF" && + props.message.embeds[0].type === 'Website' && + (props.message.embeds[0] as WebsiteEmbed).specialContent?.type === 'GIF' && props.message.content && - !props.message.content.replace(RE_URL, "").length; + !props.message.content.replace(RE_URL, '').length; /** * React with an emoji @@ -112,7 +109,7 @@ export function Message(props: Props) { edited={props.message.editedAt} mentioned={props.message.mentioned} highlight={props.highlight} - tail={props.tail || state.settings.getValue("appearance:compact_mode")} + tail={props.tail || state.settings.getValue('appearance:compact_mode')} header={ @@ -145,46 +142,46 @@ export function Message(props: Props) { - + - + - + - + - + - + - + @@ -192,16 +189,16 @@ export function Message(props: Props) { - + - + he/him · @@ -209,7 +206,7 @@ export function Message(props: Props) { } compact={ !!props.message.systemMessage || - state.settings.getValue("appearance:compact_mode") + state.settings.getValue('appearance:compact_mode') } infoMatch={ @@ -221,7 +218,7 @@ export function Message(props: Props) { } > - + (); /** @@ -185,7 +182,7 @@ export function Messages(props: Props) { async function caseInitialLoad(nearby?: string) { // Pre-empt any fetches preempt(); - setFetching("initial"); + setFetching('initial'); // Handle incoming pre-emptions const preempted = newPreempted(); @@ -213,7 +210,7 @@ export function Messages(props: Props) { // Assume we are not at the end if we jumped to a message // NB. we set this late to not display the "jump to bottom" bar - if (typeof nearby === "string") { + if (typeof nearby === 'string') { setEnd( // If the messages fetched include the latest message, // then we are at the end and mark the channel as such. @@ -262,7 +259,7 @@ export function Messages(props: Props) { if (atStart() || !canFetch()) return; // Indicate we are fetching upwards - setFetching("upwards"); + setFetching('upwards'); // Handle incoming pre-emptions const preempted = newPreempted(); @@ -334,7 +331,7 @@ export function Messages(props: Props) { if (atEnd() || !canFetch()) return; // Indicate we are fetching downwards - setFetching("downwards"); + setFetching('downwards'); // Handle incoming pre-emptions const preempted = newPreempted(); @@ -344,7 +341,7 @@ export function Messages(props: Props) { const result = await props.channel.fetchMessagesWithUsers({ limit: props.fetchLimit, after: messages()[0].id, - sort: "Oldest", + sort: 'Oldest', }); // Cancel if we've been pre-empted @@ -407,7 +404,7 @@ export function Messages(props: Props) { function findScrollContainer(el: Element | null) { if (!el) { return null; - } else if (getComputedStyle(el).overflowY === "scroll") { + } else if (getComputedStyle(el).overflowY === 'scroll') { return el; } else { return el.parentElement; @@ -418,15 +415,15 @@ export function Messages(props: Props) { if (atEnd()) { const containerChild = findScrollContainer(listRef!)!.children[0]; containerChild!.scrollIntoView({ - behavior: "smooth", - block: "end", + behavior: 'smooth', + block: 'end', }); } // Otherwise fetch present messages else { // Pre-empty any fetches preempt(); - setFetching("jump_end"); + setFetching('jump_end'); // Handle incoming pre-emptions const preempted = newPreempted(); @@ -470,14 +467,14 @@ export function Messages(props: Props) { const containerChild = findScrollContainer(listRef!)!.children[0]; containerChild!.scrollIntoView({ - behavior: "instant", - block: "start", + behavior: 'instant', + block: 'start', }); setTimeout(() => { containerChild!.scrollIntoView({ - behavior: "smooth", - block: "end", + behavior: 'smooth', + block: 'end', }); // Mark as fetching has ended @@ -505,8 +502,8 @@ export function Messages(props: Props) { ); // use localeCompare listRef!.children[index + (atStart() ? 1 : 0)].scrollIntoView({ - behavior: "smooth", - block: "center", + behavior: 'smooth', + block: 'center', }); }; @@ -517,7 +514,7 @@ export function Messages(props: Props) { // Pre-empty any fetches preempt(); - setFetching("jump_msg"); + setFetching('jump_msg'); // Handle incoming pre-emptions const preempted = newPreempted(); @@ -611,14 +608,14 @@ export function Messages(props: Props) { // Add listener for messages onMount(() => { const c = client(); - c.addListener("messageCreate", onMessage); - c.addListener("messageDelete", onMessageDelete); + c.addListener('messageCreate', onMessage); + c.addListener('messageDelete', onMessageDelete); }); onCleanup(() => { const c = client(); - c.removeListener("messageCreate", onMessage); - c.removeListener("messageDelete", onMessageDelete); + c.removeListener('messageCreate', onMessage); + c.removeListener('messageDelete', onMessageDelete); }); // We need to cache created objects to prevent needless re-rendering @@ -627,7 +624,7 @@ export function Messages(props: Props) { // Determine which messages have a tail and add message dividers const messagesWithTail = createMemo(() => { const messagesWithTail: ListEntry[] = []; - const lastReadId = props.lastReadId() ?? "0"; + const lastReadId = props.lastReadId() ?? '0'; let blockedMessages = 0; let insertedUnreadDivider = false; @@ -698,7 +695,7 @@ export function Messages(props: Props) { ); } - if (message.author?.relationship === "Blocked") { + if (message.author?.relationship === 'Blocked') { blockedMessages++; } else { // Push any blocked messages if they haven't been yet @@ -719,7 +716,7 @@ export function Messages(props: Props) { messagesWithTail.push( objectCache.get(date) ?? { t: 1, - date: dayjs(date).format("LL"), + date: dayjs(date).format('LL'), } ); } @@ -837,8 +834,8 @@ type ListEntry = /** * Render individual list entry */ -function Entry(props: ListEntry & Pick) { - const [local, other] = splitProps(props, ["t", "highlightedMessageId"]); +function Entry(props: ListEntry & Pick) { + const [local, other] = splitProps(props, ['t', 'highlightedMessageId']); return ( diff --git a/packages/client/components/app/interface/settings/Settings.tsx b/packages/client/components/app/interface/settings/Settings.tsx index c91a7ac1..1da9c640 100644 --- a/packages/client/components/app/interface/settings/Settings.tsx +++ b/packages/client/components/app/interface/settings/Settings.tsx @@ -1,17 +1,11 @@ -import { - Accessor, - createContext, - createSignal, - untrack, - useContext, -} from "solid-js"; +import { Rerun } from '@solid-primitives/keyed'; +import type { Accessor } from 'solid-js'; +import { createContext, createSignal, untrack, useContext } from 'solid-js'; +import { Motion, Presence } from 'solid-motionone'; -import { Motion, Presence } from "@motionone/solid"; -import { Rerun } from "@solid-primitives/keyed"; - -import { SettingsConfiguration, SettingsEntry } from "."; -import { SettingsContent } from "./_layout/Content"; -import { SettingsSidebar } from "./_layout/Sidebar"; +import type { SettingsConfiguration, SettingsEntry } from '.'; +import { SettingsContent } from './_layout/Content'; +import { SettingsSidebar } from './_layout/Sidebar'; export interface SettingsProps { /** @@ -28,7 +22,7 @@ export interface SettingsProps { /** * Transition animation */ -export type SettingsTransition = "normal" | "to-child" | "to-parent"; +export type SettingsTransition = 'normal' | 'to-child' | 'to-parent'; /** * Provide navigation to child components @@ -44,18 +38,18 @@ const SettingsNavigationContext = createContext<{ export function Settings(props: SettingsProps & SettingsConfiguration) { const [page, setPage] = createSignal(); const [transition, setTransition] = - createSignal("normal"); + createSignal('normal'); /** * Navigate to a certain page */ function navigate(entry: string | SettingsEntry) { let id; - if (typeof entry === "object") { + if (typeof entry === 'object') { if (entry.onClick) { entry.onClick(); } else if (entry.href) { - window.open(entry.href, "_blank"); + window.open(entry.href, '_blank'); } else if (entry.id) { id = entry.id; } @@ -67,11 +61,11 @@ export function Settings(props: SettingsProps & SettingsConfiguration) { const current = page(); if (current?.startsWith(id)) { - setTransition("to-parent"); + setTransition('to-parent'); } else if (current && id.startsWith(current)) { - setTransition("to-child"); + setTransition('to-child'); } else { - setTransition("normal"); + setTransition('normal'); } setPage(id); @@ -95,20 +89,20 @@ export function Settings(props: SettingsProps & SettingsConfiguration) { - untrack(transition) !== "normal" && - setTimeout(() => (el.style.visibility = "visible"), 250) + untrack(transition) !== 'normal' && + setTimeout(() => (el.style.visibility = 'visible'), 250) } initial={ - transition() === "normal" + transition() === 'normal' ? { opacity: 0, y: 50 } - : transition() === "to-child" - ? { - x: "100vw", - } - : { x: "-100vw" } + : transition() === 'to-child' + ? { + x: '100vw', + } + : { x: '-100vw' } } animate={{ opacity: 1, @@ -116,13 +110,13 @@ export function Settings(props: SettingsProps & SettingsConfiguration) { y: 0, }} exit={ - transition() === "normal" + transition() === 'normal' ? undefined - : transition() === "to-child" - ? { - x: "-100vw", - } - : { x: "100vw" } + : transition() === 'to-child' + ? { + x: '-100vw', + } + : { x: '100vw' } } transition={{ duration: 0.2, easing: [0.17, 0.67, 0.58, 0.98] }} > diff --git a/packages/client/components/app/interface/settings/_layout/Content.tsx b/packages/client/components/app/interface/settings/_layout/Content.tsx index f45e8140..a4a08255 100644 --- a/packages/client/components/app/interface/settings/_layout/Content.tsx +++ b/packages/client/components/app/interface/settings/_layout/Content.tsx @@ -1,12 +1,10 @@ -import { Accessor, JSX, Show } from "solid-js"; +import MdClose from '@material-design-icons/svg/outlined/close.svg?component-solid'; +import { Breadcrumbs, Column, iconSize, styled, Typography } from '@revolt/ui'; +import type { Accessor, JSX } from 'solid-js'; +import { Show } from 'solid-js'; +import { cva } from 'styled-system/css'; -import { cva } from "styled-system/css"; - -import { Breadcrumbs, Column, Typography, iconSize, styled } from "@revolt/ui"; - -import MdClose from "@material-design-icons/svg/outlined/close.svg?component-solid"; - -import { useSettingsNavigation } from "../Settings"; +import { useSettingsNavigation } from '../Settings'; /** * Content portion of the settings menu @@ -22,19 +20,19 @@ export function SettingsContent(props: { return (
- - + + props.title(key)} - navigate={(keys) => navigate(keys.join("/"))} + navigate={(keys) => navigate(keys.join('/'))} /> {props.children} @@ -58,17 +56,17 @@ export function SettingsContent(props: { const base = cva({ base: { minWidth: 0, - flex: "1 1 800px", - flexDirection: "row", + flex: '1 1 800px', + flexDirection: 'row', - display: "flex", - background: "var(--colours-settings-content-background)", + display: 'flex', + background: 'var(--colours-settings-content-background)', - borderStartStartRadius: "30px", - borderEndStartRadius: "30px", + borderStartStartRadius: '30px', + borderEndStartRadius: '30px', - "& > a": { - textDecoration: "none", + '& > a': { + textDecoration: 'none', }, }, }); @@ -76,7 +74,7 @@ const base = cva({ /** * Settings pane */ -const InnerContent = styled("div", "Pane")` +const InnerContent = styled('div', 'Pane')` gap: 13px; min-width: 0; width: 100%; @@ -106,22 +104,22 @@ const CloseAnchor = styled.a` justify-content: center; border-radius: ${(props) => props.theme!.borderRadius.full}; - border: 3px solid ${(props) => props.theme!.colours["settings-close-anchor"]}; + border: 3px solid ${(props) => props.theme!.colours['settings-close-anchor']}; transition: ${(props) => props.theme!.transitions.fast} background-color; svg { transition: ${(props) => props.theme!.transitions.fast} background-color; color: ${(props) => - props.theme!.colours["settings-close-anchor"]} !important; + props.theme!.colours['settings-close-anchor']} !important; } &:hover { - background: ${(props) => props.theme!.colours["settings-close-anchor"]}; + background: ${(props) => props.theme!.colours['settings-close-anchor']}; } &:hover svg { color: ${(props) => - props.theme!.colours["settings-close-anchor-hover"]} !important; + props.theme!.colours['settings-close-anchor-hover']} !important; } &:active { @@ -141,13 +139,13 @@ const CloseAction = styled.div` top: 0; &:after { - content: "ESC"; + content: 'ESC'; margin-top: 4px; display: flex; justify-content: center; width: 36px; font-weight: 600; - color: ${(props) => props.theme!.colours["settings-content-foreground"]}; + color: ${(props) => props.theme!.colours['settings-content-foreground']}; font-size: 0.75rem; } `; diff --git a/packages/client/components/app/interface/settings/_layout/Sidebar.tsx b/packages/client/components/app/interface/settings/_layout/Sidebar.tsx index 064f1c1f..49994584 100644 --- a/packages/client/components/app/interface/settings/_layout/Sidebar.tsx +++ b/packages/client/components/app/interface/settings/_layout/Sidebar.tsx @@ -1,17 +1,16 @@ -import { Accessor, For, Setter, Show, createMemo, onMount } from "solid-js"; - -import { Column, OverflowingText, styled } from "@revolt/ui"; +import { Column, OverflowingText, styled } from '@revolt/ui'; +import type { Accessor, Setter } from 'solid-js'; +import { createMemo, For, onMount, Show } from 'solid-js'; // import MdError from "@material-design-icons/svg/filled/error.svg?component-solid"; // import MdOpenInNew from "@material-design-icons/svg/filled/open_in_new.svg?component-solid"; -import { SettingsList } from ".."; -import { useSettingsNavigation } from "../Settings"; - +import type { SettingsList } from '..'; +import { useSettingsNavigation } from '../Settings'; import { SidebarButton, SidebarButtonContent, SidebarButtonTitle, -} from "./SidebarButton"; +} from './SidebarButton'; /** * Settings Sidebar Layout @@ -44,7 +43,7 @@ export function SettingsSidebar(props: {
- + {list().prepend} {(category) => ( @@ -53,15 +52,15 @@ export function SettingsSidebar(props: { {category.title} - + {(entry) => ( navigate(entry)} aria-selected={ - props.page()?.split("/")[0] === - entry.id?.split("/")[0] + props.page()?.split('/')[0] === + entry.id?.split('/')[0] } > @@ -102,19 +101,19 @@ export function SettingsSidebar(props: { /** * Base layout of the sidebar */ -const Base = styled("div", "Sidebar")` +const Base = styled('div', 'Sidebar')` display: flex; flex: 1 0 218px; padding-left: 8px; justify-content: flex-end; - color: ${(props) => props.theme!.colours["settings-foreground"]}; + color: ${(props) => props.theme!.colours['settings-foreground']}; `; /** * Aligned content within the sidebar */ -const Content = styled("div", "Content")` +const Content = styled('div', 'Content')` min-width: 230px; max-width: 300px; padding: 74px 0 8px; @@ -137,5 +136,5 @@ const CategoryTitle = styled(OverflowingText)` font-weight: 700; margin: 0 8px; margin-inline-end: 20px; - color: ${(props) => props.theme!.colours["settings-sidebar-category"]}; + color: ${(props) => props.theme!.colours['settings-sidebar-category']}; `; diff --git a/packages/client/components/app/interface/settings/_layout/SidebarButton.tsx b/packages/client/components/app/interface/settings/_layout/SidebarButton.tsx index aca5b8eb..b1b97ef9 100644 --- a/packages/client/components/app/interface/settings/_layout/SidebarButton.tsx +++ b/packages/client/components/app/interface/settings/_layout/SidebarButton.tsx @@ -1,4 +1,4 @@ -import { styled } from "@revolt/ui"; +import { styled } from '@revolt/ui'; // TODO: move to @revolt/ui package @@ -19,11 +19,11 @@ export const SidebarButton = styled.a` font-size: 15px; user-select: none; transition: background-color 0.1s ease-in-out; - color: ${(props) => props.theme!.colours["settings-sidebar-foreground"]}; + color: ${(props) => props.theme!.colours['settings-sidebar-foreground']}; background: ${(props) => - props["aria-selected"] - ? props.theme!.colours["settings-sidebar-button-hover"] - : "unset"}; + props['aria-selected'] + ? props.theme!.colours['settings-sidebar-button-hover'] + : 'unset'}; svg { flex-shrink: 0; @@ -31,12 +31,12 @@ export const SidebarButton = styled.a` &:hover { background-color: ${(props) => - props.theme!.colours["settings-sidebar-button-hover"]}; + props.theme!.colours['settings-sidebar-button-hover']}; } &:active { background-color: ${(props) => - props.theme!.colours["settings-sidebar-button-active"]}; + props.theme!.colours['settings-sidebar-button-active']}; } `; diff --git a/packages/client/components/app/interface/settings/channel/Webhooks.tsx b/packages/client/components/app/interface/settings/channel/Webhooks.tsx index 63059910..94e1d4e0 100644 --- a/packages/client/components/app/interface/settings/channel/Webhooks.tsx +++ b/packages/client/components/app/interface/settings/channel/Webhooks.tsx @@ -1,20 +1,17 @@ -import { BiSolidCloud, BiSolidTrash } from "solid-icons/bi"; -import { For, Match, Show, Switch, createSignal, onMount } from "solid-js"; - -import type { ChannelWebhook } from "revolt.js"; - -import { useClient } from "@revolt/client"; +import { useClient } from '@revolt/client'; import { Avatar, CategoryButton, Column, Preloader, Typography, -} from "@revolt/ui"; - -import { useSettingsNavigation } from "../Settings"; +} from '@revolt/ui'; +import type { ChannelWebhook } from 'revolt.js'; +import { BiSolidCloud, BiSolidTrash } from 'solid-icons/bi'; +import { createSignal, For, Match, onMount, Show, Switch } from 'solid-js'; -import { ChannelSettingsProps } from "."; +import { useSettingsNavigation } from '../Settings'; +import type { ChannelSettingsProps } from '.'; /** * Webhooks @@ -37,9 +34,9 @@ export default function Webhooks(props: ChannelSettingsProps) { }); return ( - + } onClick={() => void 0} > @@ -48,8 +45,8 @@ export default function Webhooks(props: ChannelSettingsProps) { - My Bots - }> + My Bots + }> {(webhook) => ( @@ -57,7 +54,7 @@ export default function Webhooks(props: ChannelSettingsProps) { icon={} description={webhook.id} onClick={() => navigate(`webhooks/${webhook.id}`)} - action="chevron" + action='chevron' > {webhook.name} @@ -76,9 +73,9 @@ export default function Webhooks(props: ChannelSettingsProps) { */ export function Webhook(props: { webhook: ChannelWebhook }) { return ( - + } onClick={() => void 0} > diff --git a/packages/client/components/app/interface/settings/channel/index.tsx b/packages/client/components/app/interface/settings/channel/index.tsx index 436f0f93..19bba971 100644 --- a/packages/client/components/app/interface/settings/channel/index.tsx +++ b/packages/client/components/app/interface/settings/channel/index.tsx @@ -1,21 +1,18 @@ +import { useClient } from '@revolt/client'; +import { getController } from '@revolt/common'; +import { useTranslation } from '@revolt/i18n'; +import { TextWithEmoji } from '@revolt/markdown'; +import { ColouredText, useTheme } from '@revolt/ui'; +import type { Channel } from 'revolt.js'; import { BiRegularListUl, BiSolidCloud, BiSolidInfoCircle, BiSolidTrash, -} from "solid-icons/bi"; +} from 'solid-icons/bi'; -import { Channel } from "revolt.js"; - -import { useClient } from "@revolt/client"; -import { getController } from "@revolt/common"; -import { useTranslation } from "@revolt/i18n"; -import { TextWithEmoji } from "@revolt/markdown"; -import { ColouredText, useTheme } from "@revolt/ui"; - -import { SettingsConfiguration } from ".."; - -import Webhooks, { Webhook } from "./Webhooks"; +import type { SettingsConfiguration } from '..'; +import Webhooks, { Webhook } from './Webhooks'; const Config: SettingsConfiguration = { /** @@ -26,29 +23,28 @@ const Config: SettingsConfiguration = { const t = useTranslation(); const client = useClient(); - if (key.startsWith("webhooks/")) { + if (key.startsWith('webhooks/')) { const webhook = client().channelWebhooks.get(key.substring(9)); return webhook!.name; } - return t(`app.settings.channel_pages.${key.replaceAll("/", ".")}.title`); + return t(`app.settings.channel_pages.${key.replaceAll('/', '.')}.title`); }, /** * Render the current channel settings page */ render(props, channel) { - // eslint-disable-next-line solid/reactivity const id = props.page(); const client = useClient(); - if (id?.startsWith("webhooks/")) { + if (id?.startsWith('webhooks/')) { const webhook = client().channelWebhooks.get(id.substring(9)); return ; } switch (id) { - case "webhooks": + case 'webhooks': return ; default: return null; @@ -69,27 +65,27 @@ const Config: SettingsConfiguration = { title: , entries: [ { - id: "overview", + id: 'overview', icon: , - title: t("app.settings.channel_pages.overview.title"), + title: t('app.settings.channel_pages.overview.title'), }, { - hidden: !channel.havePermission("ManagePermissions"), - id: "permissions", + hidden: !channel.havePermission('ManagePermissions'), + id: 'permissions', icon: , - title: t("app.settings.channel_pages.permissions.title"), + title: t('app.settings.channel_pages.permissions.title'), }, { - hidden: !channel.havePermission("ManageWebhooks"), - id: "webhooks", + hidden: !channel.havePermission('ManageWebhooks'), + id: 'webhooks', icon: , - title: t("app.settings.channel_pages.webhooks.title"), + title: t('app.settings.channel_pages.webhooks.title'), }, ], }, { hidden: !( - channel.type !== "Group" && channel.havePermission("ManageChannel") + channel.type !== 'Group' && channel.havePermission('ManageChannel') ), entries: [ { @@ -101,15 +97,15 @@ const Config: SettingsConfiguration = { ), title: ( - {t("app.context_menu.delete_channel")} + {t('app.context_menu.delete_channel')} ), /** * Handle server deletion request */ onClick() { - getController("modal").push({ - type: "delete_channel", + getController('modal').push({ + type: 'delete_channel', channel, }); }, @@ -123,9 +119,9 @@ const Config: SettingsConfiguration = { export default Config; -export type ChannelSettingsProps = { +export interface ChannelSettingsProps { /** * Channel */ channel: Channel; -}; +} diff --git a/packages/client/components/app/interface/settings/index.tsx b/packages/client/components/app/interface/settings/index.tsx index adc2c182..7d25f5bc 100644 --- a/packages/client/components/app/interface/settings/index.tsx +++ b/packages/client/components/app/interface/settings/index.tsx @@ -1,13 +1,14 @@ -import { Accessor, JSX } from "solid-js"; +import type { Accessor, JSX } from 'solid-js'; -import { Settings, SettingsProps } from "./Settings"; -import channel from "./channel"; -import server from "./server"; -import user from "./user"; +import channel from './channel'; +import server from './server'; +import type { SettingsProps } from './Settings'; +import { Settings } from './Settings'; +import user from './user'; -export { Settings } from "./Settings"; +export { Settings } from './Settings'; -export type SettingsConfiguration = { +export interface SettingsConfiguration { /** * Generate list of categories and entries * @returns List @@ -28,12 +29,12 @@ export type SettingsConfiguration = { props: { page: Accessor }, context: T ) => JSX.Element; -}; +} /** * List of categories and entries */ -export type SettingsList = { +export interface SettingsList { prepend?: JSX.Element; append?: JSX.Element; entries: { @@ -41,12 +42,12 @@ export type SettingsList = { title?: JSX.Element; entries: SettingsEntry[]; }[]; -}; +} /** * Individual settings entry */ -export type SettingsEntry = { +export interface SettingsEntry { id?: string; href?: string; onClick?: () => void; @@ -55,7 +56,7 @@ export type SettingsEntry = { icon: JSX.Element; title: JSX.Element; -}; +} export const SettingsConfigurations: Record< string, @@ -75,7 +76,7 @@ export function SettingsUsingConfiguration( props: SettingsProps & { configKey: string } ) { // eslint-disable-next-line solid/reactivity - const config = SettingsConfigurations[props.configKey ?? "client"]; + const config = SettingsConfigurations[props.configKey ?? 'client']; return ( + - Platform + Platform } - description="Set visible badges on server" + description='Set visible badges on server' > } action={ } action={ = { /** @@ -28,7 +25,7 @@ const Config: SettingsConfiguration = { title(key) { const t = useTranslation(); return t( - `app.settings.server_pages.${key.replaceAll("/", ".")}.title`, + `app.settings.server_pages.${key.replaceAll('/', '.')}.title`, undefined, key ); @@ -38,16 +35,15 @@ const Config: SettingsConfiguration = { * Render the current server settings page */ render(props, server) { - // eslint-disable-next-line solid/reactivity const id = props.page(); if (!server.$exists) { - getController("modal").pop(); + getController('modal').pop(); return null; } switch (id) { - case "overview": + case 'overview': return ; default: return null; @@ -69,14 +65,14 @@ const Config: SettingsConfiguration = { title: , entries: [ { - id: "overview", + id: 'overview', icon: , - title: t("app.settings.server_pages.overview.title"), + title: t('app.settings.server_pages.overview.title'), }, { - id: "members", + id: 'members', icon: , - title: t("app.settings.server_pages.members.title"), + title: t('app.settings.server_pages.members.title'), }, /*{ TODO: deprecate id: "categories", @@ -85,43 +81,43 @@ const Config: SettingsConfiguration = { },*/ { hidden: !( - server.havePermission("ManageRole") || - server.havePermission("AssignRoles") + server.havePermission('ManageRole') || + server.havePermission('AssignRoles') ), - id: "roles", + id: 'roles', icon: , - title: t("app.settings.server_pages.roles.title"), + title: t('app.settings.server_pages.roles.title'), }, ], }, { - hidden: !server.havePermission("ManageCustomisation"), - title: t("app.settings.server_pages.customisation.title"), + hidden: !server.havePermission('ManageCustomisation'), + title: t('app.settings.server_pages.customisation.title'), entries: [ { - id: "emojis", + id: 'emojis', icon: , - title: t("app.settings.server_pages.emojis.title"), + title: t('app.settings.server_pages.emojis.title'), }, ], }, { hidden: - !server.havePermission("ManageServer") && - !server.havePermission("BanMembers"), - title: t("app.settings.server_pages.management.title"), + !server.havePermission('ManageServer') && + !server.havePermission('BanMembers'), + title: t('app.settings.server_pages.management.title'), entries: [ { - hidden: !server.havePermission("ManageServer"), - id: "invites", + hidden: !server.havePermission('ManageServer'), + id: 'invites', icon: , - title: t("app.settings.server_pages.invites.title"), + title: t('app.settings.server_pages.invites.title'), }, { - hidden: !server.havePermission("BanMembers"), - id: "bans", + hidden: !server.havePermission('BanMembers'), + id: 'bans', icon: , - title: t("app.settings.server_pages.bans.title"), + title: t('app.settings.server_pages.bans.title'), }, ], }, @@ -137,15 +133,15 @@ const Config: SettingsConfiguration = { ), title: ( - {t("app.context_menu.delete_server")} + {t('app.context_menu.delete_server')} ), /** * Handle server deletion request */ onClick() { - getController("modal").push({ - type: "delete_server", + getController('modal').push({ + type: 'delete_server', server, }); }, @@ -159,9 +155,9 @@ const Config: SettingsConfiguration = { export default Config; -export type ServerSettingsProps = { +export interface ServerSettingsProps { /** * Server */ server: Server; -}; +} diff --git a/packages/client/components/app/interface/settings/user/Accessibility.tsx b/packages/client/components/app/interface/settings/user/Accessibility.tsx index 2fce479f..ff667ee6 100644 --- a/packages/client/components/app/interface/settings/user/Accessibility.tsx +++ b/packages/client/components/app/interface/settings/user/Accessibility.tsx @@ -1,35 +1,36 @@ -import { useTranslation } from "@revolt/i18n"; +import MdAnimation from '@material-design-icons/svg/outlined/animation.svg?component-solid'; +import { useTranslation } from '@revolt/i18n'; import { - CategoryButton, - CategoryButtonGroup, - Checkbox, - Column, - FormGroup, - iconSize, -} from "@revolt/ui"; - -import MdAnimation from "@material-design-icons/svg/outlined/animation.svg?component-solid"; + CategoryButton, + CategoryButtonGroup, + Checkbox, + Column, + FormGroup, + iconSize, +} from '@revolt/ui'; /** * Accessibility settings page */ export default function Accessibility() { - const t = useTranslation(); + const t = useTranslation(); - return ( - - - - void value} />} - onClick={() => void 0} - icon={} - description={t("app.settings.pages.accessibility.descriptions.reduced_motion")} - > - {t("app.settings.pages.accessibility.reduced_motion")} - - - - - ); + return ( + + + + void value} />} + onClick={() => void 0} + icon={} + description={t( + 'app.settings.pages.accessibility.descriptions.reduced_motion' + )} + > + {t('app.settings.pages.accessibility.reduced_motion')} + + + + + ); } diff --git a/packages/client/components/app/interface/settings/user/Account.tsx b/packages/client/components/app/interface/settings/user/Account.tsx index 2d58805c..47dcdb9f 100644 --- a/packages/client/components/app/interface/settings/user/Account.tsx +++ b/packages/client/components/app/interface/settings/user/Account.tsx @@ -1,47 +1,44 @@ -import { - Accessor, - Match, - Show, - Switch, - createMemo, - createSignal, - onMount, -} from "solid-js"; - -import { clientController, useClient } from "@revolt/client"; +import MdCakeFill from '@material-design-icons/svg/filled/cake.svg?component-solid'; +import MdAlternateEmail from '@material-design-icons/svg/outlined/alternate_email.svg?component-solid'; +import MdBlock from '@material-design-icons/svg/outlined/block.svg?component-solid'; +import MdDelete from '@material-design-icons/svg/outlined/delete.svg?component-solid'; +import MdDraw from '@material-design-icons/svg/outlined/draw.svg?component-solid'; +import MdEdit from '@material-design-icons/svg/outlined/edit.svg?component-solid'; +import MdLock from '@material-design-icons/svg/outlined/lock.svg?component-solid'; +import MdMail from '@material-design-icons/svg/outlined/mail.svg?component-solid'; +import MdPassword from '@material-design-icons/svg/outlined/password.svg?component-solid'; +import MdVerifiedUser from '@material-design-icons/svg/outlined/verified_user.svg?component-solid'; +import { clientController, useClient } from '@revolt/client'; import { createMfaResource, createOwnProfileResource, -} from "@revolt/client/resources"; -import { getController } from "@revolt/common"; -import { dayjs, useTranslation } from "@revolt/i18n"; +} from '@revolt/client/resources'; +import { getController } from '@revolt/common'; +import { dayjs, useTranslation } from '@revolt/i18n'; import { Avatar, CategoryButton, CategoryButtonGroup, CategoryCollapse, Column, - Row, - Typography, iconSize, + Row, styled, + Typography, useTheme, -} from "@revolt/ui"; - -import MdCakeFill from "@material-design-icons/svg/filled/cake.svg?component-solid"; -import MdAlternateEmail from "@material-design-icons/svg/outlined/alternate_email.svg?component-solid"; -import MdBlock from "@material-design-icons/svg/outlined/block.svg?component-solid"; -import MdDelete from "@material-design-icons/svg/outlined/delete.svg?component-solid"; -import MdDraw from "@material-design-icons/svg/outlined/draw.svg?component-solid"; -import MdEdit from "@material-design-icons/svg/outlined/edit.svg?component-solid"; -import MdLock from "@material-design-icons/svg/outlined/lock.svg?component-solid"; -import MdMail from "@material-design-icons/svg/outlined/mail.svg?component-solid"; -import MdPassword from "@material-design-icons/svg/outlined/password.svg?component-solid"; -import MdVerifiedUser from "@material-design-icons/svg/outlined/verified_user.svg?component-solid"; - -import { useSettingsNavigation } from "../Settings"; +} from '@revolt/ui'; +import { + type Accessor, + createMemo, + createSignal, + Match, + onMount, + Show, + Switch, +} from 'solid-js'; -import { UserSummary } from "./account"; +import { useSettingsNavigation } from '../Settings'; +import { UserSummary } from './account/index'; /** * Account Page @@ -52,11 +49,11 @@ export default function MyAccount() { const { navigate } = useSettingsNavigation(); return ( - + navigate("profile")} + onEdit={() => navigate('profile')} showBadges /> @@ -72,36 +69,36 @@ export default function MyAccount() { function EditAccount() { const t = useTranslation(); const client = useClient(); - const [email, setEmail] = createSignal("•••••••••••@•••••••••••"); + const [email, setEmail] = createSignal('•••••••••••@•••••••••••'); return ( - getController("modal").push({ - type: "edit_username", + getController('modal').push({ + type: 'edit_username', client: client(), }) } icon={} description={client().user?.username} > - {t("login.username")} + {t('login.username')} - getController("modal").push({ - type: "edit_email", + getController('modal').push({ + type: 'edit_email', client: client(), }) } icon={} description={ - {email()}{" "} - + {email()}{' '} + { event.stopPropagation(); @@ -114,20 +111,20 @@ function EditAccount() { } > - {t("login.email")} + {t('login.email')} - getController("modal").push({ - type: "edit_password", + getController('modal').push({ + type: 'edit_password', client: client(), }) } icon={} - description={"•••••••••"} + description={'•••••••••'} > - {t("login.password")} + {t('login.password')} ); @@ -144,12 +141,12 @@ function MultiFactorAuth() { * Show recovery codes */ async function showRecoveryCodes() { - const modals = getController("modal"); + const modals = getController('modal'); const ticket = await modals.mfaFlow(mfa.data!); ticket!.fetchRecoveryCodes().then((codes) => - getController("modal").push({ - type: "mfa_recovery", + getController('modal').push({ + type: 'mfa_recovery', mfa: mfa.data!, codes, }) @@ -160,12 +157,12 @@ function MultiFactorAuth() { * Generate recovery codes */ async function generateRecoveryCodes() { - const modals = getController("modal"); + const modals = getController('modal'); const ticket = await modals.mfaFlow(mfa.data!); ticket!.generateRecoveryCodes().then((codes) => - getController("modal").push({ - type: "mfa_recovery", + getController('modal').push({ + type: 'mfa_recovery', mfa: mfa.data!, codes, }) @@ -176,7 +173,7 @@ function MultiFactorAuth() { * Configure authenticator app */ async function setupAuthenticatorApp() { - const modals = getController("modal"); + const modals = getController('modal'); const ticket = await modals.mfaFlow(mfa.data!); const secret = await ticket!.generateAuthenticatorSecret(); @@ -202,7 +199,7 @@ function MultiFactorAuth() { * Disable authenticator app */ function disableAuthenticatorApp() { - getController("modal") + getController('modal') .mfaFlow(mfa.data!) .then((ticket) => ticket!.disableAuthenticator()); } @@ -211,16 +208,16 @@ function MultiFactorAuth() { } - title="Recovery Codes" - description="Configure a way to get back into your account in case your 2FA is lost" + title='Recovery Codes' + description='Configure a way to get back into your account in case your 2FA is lost' > Generate Recovery Codes @@ -228,15 +225,15 @@ function MultiFactorAuth() { > View Recovery Codes Reset Recovery Codes @@ -246,16 +243,16 @@ function MultiFactorAuth() { } - title="Authenticator App" - description="Configure one-time password authentication" + title='Authenticator App' + description='Configure one-time password authentication' > Enable Authenticator @@ -263,8 +260,8 @@ function MultiFactorAuth() { > Remove Authenticator @@ -295,7 +292,7 @@ function ManageAccount() { * Disable account */ function disableAccount() { - getController("modal") + getController('modal') .mfaFlow(mfa.data!) .then((ticket) => ticket!.disableAccount().then(() => clientController.logout()) @@ -306,7 +303,7 @@ function ManageAccount() { * Delete account */ function deleteAccount() { - getController("modal") + getController('modal') .mfaFlow(mfa.data!) .then((ticket) => ticket!.deleteAccount().then(() => clientController.logout()) @@ -316,29 +313,29 @@ function ManageAccount() { return ( } - description={t("app.settings.pages.account.manage.disable_description")} + description={t('app.settings.pages.account.manage.disable_description')} > - {t("app.settings.pages.account.manage.disable")} + {t('app.settings.pages.account.manage.disable')} } - description={t("app.settings.pages.account.manage.delete_description")} + description={t('app.settings.pages.account.manage.delete_description')} > {t( stillOwnServers() - ? "app.settings.pages.account.manage.delete_still_own_servers" - : "app.settings.pages.account.manage.delete" + ? 'app.settings.pages.account.manage.delete_still_own_servers' + : 'app.settings.pages.account.manage.delete' )} diff --git a/packages/client/components/app/interface/settings/user/Appearance.tsx b/packages/client/components/app/interface/settings/user/Appearance.tsx index ae40f989..8fa34f4b 100644 --- a/packages/client/components/app/interface/settings/user/Appearance.tsx +++ b/packages/client/components/app/interface/settings/user/Appearance.tsx @@ -1,20 +1,19 @@ +import MdBrush from '@material-design-icons/svg/outlined/brush.svg?component-solid'; +import MdDataObject from '@material-design-icons/svg/outlined/data_object.svg?component-solid'; +import MdFormatSize from '@material-design-icons/svg/outlined/format_size.svg?component-solid'; +import MdPalette from '@material-design-icons/svg/outlined/palette.svg?component-solid'; +import MdSentimentVerySatisfied from '@material-design-icons/svg/outlined/sentiment_very_satisfied.svg?component-solid'; +import MdWallpaper from '@material-design-icons/svg/outlined/wallpaper.svg?component-solid'; import { CategoryButton, CategoryButtonGroup, Column, - Row, iconSize, + Row, styled, -} from "@revolt/ui"; - -import MdBrush from "@material-design-icons/svg/outlined/brush.svg?component-solid"; -import MdDataObject from "@material-design-icons/svg/outlined/data_object.svg?component-solid"; -import MdFormatSize from "@material-design-icons/svg/outlined/format_size.svg?component-solid"; -import MdPalette from "@material-design-icons/svg/outlined/palette.svg?component-solid"; -import MdSentimentVerySatisfied from "@material-design-icons/svg/outlined/sentiment_very_satisfied.svg?component-solid"; -import MdWallpaper from "@material-design-icons/svg/outlined/wallpaper.svg?component-solid"; +} from '@revolt/ui'; -import { useSettingsNavigation } from "../Settings"; +import { useSettingsNavigation } from '../Settings'; /** * Appearance @@ -22,61 +21,61 @@ import { useSettingsNavigation } from "../Settings"; export default function Appearance() { const { navigate } = useSettingsNavigation(); return ( - + hello } - onClick={() => navigate("appearance/colours")} - description="Customise accent colour, additional colours, and transparency" + onClick={() => navigate('appearance/colours')} + description='Customise accent colour, additional colours, and transparency' > Colours } - onClick={() => navigate("appearance/fonts")} - description="Customise display and text options" + onClick={() => navigate('appearance/fonts')} + description='Customise display and text options' > Display and fonts } - onClick={() => navigate("appearance/wallpaper")} - description="Set a wallpaper for your chats" + onClick={() => navigate('appearance/wallpaper')} + description='Set a wallpaper for your chats' > Wallpaper } - onClick={() => navigate("appearance/emoji")} - description="Change how your emojis look" + onClick={() => navigate('appearance/emoji')} + description='Change how your emojis look' > Emoji } - onClick={() => navigate("appearance/advanced_options")} - description="Customise theme variables and apply custom CSS" + onClick={() => navigate('appearance/advanced_options')} + description='Customise theme variables and apply custom CSS' > Advanced Options } - description="Browse themes made by the community" + description='Browse themes made by the community' > Discover themes @@ -101,6 +100,6 @@ const ThemeProperties = styled.div` display: flex; width: 100%; padding: 20px; - background: ${(props) => props.theme!.colours["temp-1"]}; + background: ${(props) => props.theme!.colours['temp-1']}; border-radius: ${(props) => props.theme!.borderRadius.xl}; `; diff --git a/packages/client/components/app/interface/settings/user/Experiments.tsx b/packages/client/components/app/interface/settings/user/Experiments.tsx index 3b92b248..d69adae5 100644 --- a/packages/client/components/app/interface/settings/user/Experiments.tsx +++ b/packages/client/components/app/interface/settings/user/Experiments.tsx @@ -1,16 +1,15 @@ -import { For } from "solid-js"; - -import { state } from "@revolt/state"; +import { state } from '@revolt/state'; import { AVAILABLE_EXPERIMENTS, EXPERIMENTS, -} from "@revolt/state/stores/Experiments"; +} from '@revolt/state/stores/Experiments'; import { CategoryButton, CategoryButtonGroup, Checkbox, FormGroup, -} from "@revolt/ui"; +} from '@revolt/ui'; +import { For } from 'solid-js'; /** * Experiments diff --git a/packages/client/components/app/interface/settings/user/Feedback.tsx b/packages/client/components/app/interface/settings/user/Feedback.tsx index 5ab31801..6490cafa 100644 --- a/packages/client/components/app/interface/settings/user/Feedback.tsx +++ b/packages/client/components/app/interface/settings/user/Feedback.tsx @@ -1,17 +1,16 @@ -import { useTranslation } from "@revolt/i18n"; +import MdBugReport from '@material-design-icons/svg/outlined/bug_report.svg?component-solid'; +import MdExitToApp from '@material-design-icons/svg/outlined/exit_to_app.svg?component-solid'; +import MdFormatListNumbered from '@material-design-icons/svg/outlined/format_list_numbered.svg?component-solid'; +import MdStar from '@material-design-icons/svg/outlined/star_outline.svg?component-solid'; +import MdViewKanban from '@material-design-icons/svg/outlined/view_kanban.svg?component-solid'; +import { useTranslation } from '@revolt/i18n'; import { CategoryButton, CategoryButtonGroup, Column, iconSize, styled, -} from "@revolt/ui"; - -import MdBugReport from "@material-design-icons/svg/outlined/bug_report.svg?component-solid"; -import MdExitToApp from "@material-design-icons/svg/outlined/exit_to_app.svg?component-solid"; -import MdFormatListNumbered from "@material-design-icons/svg/outlined/format_list_numbered.svg?component-solid"; -import MdStar from "@material-design-icons/svg/outlined/star_outline.svg?component-solid"; -import MdViewKanban from "@material-design-icons/svg/outlined/view_kanban.svg?component-solid"; +} from '@revolt/ui'; /** * Feedback @@ -20,14 +19,14 @@ export default function Feedback() { const t = useTranslation(); return ( - + } onClick={() => void 0} description="See what we're currently working on." @@ -36,51 +35,51 @@ export default function Feedback() { } onClick={() => void 0} - description={t("app.settings.pages.feedback.suggest_desc")} + description={t('app.settings.pages.feedback.suggest_desc')} > - {t("app.settings.pages.feedback.suggest")} + {t('app.settings.pages.feedback.suggest')} } onClick={() => void 0} - description={t("app.settings.pages.feedback.issue_desc")} + description={t('app.settings.pages.feedback.issue_desc')} > - {t("app.settings.pages.feedback.issue")} + {t('app.settings.pages.feedback.issue')} } onClick={() => void 0} - description={t("app.settings.pages.feedback.bug_desc")} + description={t('app.settings.pages.feedback.bug_desc')} > - {t("app.settings.pages.feedback.bug")} + {t('app.settings.pages.feedback.bug')} } onClick={() => void 0} - description="You can report issues and discuss improvements with us directly here." + description='You can report issues and discuss improvements with us directly here.' > Join the Revolt Lounge diff --git a/packages/client/components/app/interface/settings/user/Keybinds.tsx b/packages/client/components/app/interface/settings/user/Keybinds.tsx index bb60a440..de650851 100644 --- a/packages/client/components/app/interface/settings/user/Keybinds.tsx +++ b/packages/client/components/app/interface/settings/user/Keybinds.tsx @@ -1,17 +1,9 @@ -import { - BiSolidPencil, - BiSolidPlusCircle, - BiSolidXCircle, -} from "solid-icons/bi"; -import { BiRegularReset } from "solid-icons/bi"; -import { For, Match, Switch, createMemo, createSignal } from "solid-js"; - -import { getController } from "@revolt/common"; -import { useTranslation } from "@revolt/i18n"; -import { KeybindAction } from "@revolt/keybinds"; -import { KeyComboSequence } from "@revolt/keybinds"; -import { KeyCombo } from "@revolt/keybinds"; -import { state } from "@revolt/state"; +import { getController } from '@revolt/common'; +import { useTranslation } from '@revolt/i18n'; +import type { KeyComboSequence } from '@revolt/keybinds'; +import type { KeyCombo } from '@revolt/keybinds'; +import { KeybindAction } from '@revolt/keybinds'; +import { state } from '@revolt/state'; import { Button, CategoryButton, @@ -20,7 +12,14 @@ import { Input, KeySequence, styled, -} from "@revolt/ui"; +} from '@revolt/ui'; +import { + BiSolidPencil, + BiSolidPlusCircle, + BiSolidXCircle, +} from 'solid-icons/bi'; +import { BiRegularReset } from 'solid-icons/bi'; +import { createMemo, createSignal, For, Match, Switch } from 'solid-js'; const categories: Record = { navigation: [ @@ -62,15 +61,15 @@ export default function Keybinds() { const translateCombo = (combo: KeyCombo, short: boolean) => combo - .map((key) => t(`keys.${key}.${short ? "short" : "full"}`, {}, key)) - .join("+"); + .map((key) => t(`keys.${key}.${short ? 'short' : 'full'}`, {}, key)) + .join('+'); const translateSequence = (sequence: KeyComboSequence, short: boolean) => - sequence.map((combo) => translateCombo(combo, short)).join(" "); + sequence.map((combo) => translateCombo(combo, short)).join(' '); const editKeybind = (action: KeybindAction, index: number) => - getController("modal").push({ - type: "edit_keybind", + getController('modal').push({ + type: 'edit_keybind', action, onSubmit: (sequence) => { state.keybinds.setKeybind(action, index, sequence); @@ -78,8 +77,8 @@ export default function Keybinds() { }); const addKeybind = (action: KeybindAction) => - getController("modal").push({ - type: "edit_keybind", + getController('modal').push({ + type: 'edit_keybind', action, onSubmit: (sequence) => { state.keybinds.addKeybind(action, sequence); @@ -98,14 +97,13 @@ export default function Keybinds() { t(`app.settings.pages.keybinds.action.${action}.title`) as string, ...state.keybinds .getKeybinds() - [action].flatMap((sequence) => [ - translateSequence(sequence, false), - translateSequence(sequence, true), - ]), + [ + action + ].flatMap((sequence) => [translateSequence(sequence, false), translateSequence(sequence, true)]), ]) ); - const [searchText, setSearchText] = createSignal(""); + const [searchText, setSearchText] = createSignal(''); const filteredData = createMemo(() => { const foundActions = searchData() @@ -128,9 +126,9 @@ export default function Keybinds() { return ( setSearchText(e.target.value)} - placeholder={t("app.settings.pages.keybinds.search")} + placeholder={t('app.settings.pages.keybinds.search')} /> {([category, actions]) => ( @@ -138,7 +136,7 @@ export default function Keybinds() { title={t(`app.settings.pages.keybinds.category.${category}`)} // TODO: open={category !== "advanced"} > - + {(action) => ( @@ -165,8 +163,8 @@ export default function Keybinds() { editKeybind(action, index())} > @@ -176,8 +174,8 @@ export default function Keybinds() { when={!keybindIsDefault && indexIsDefault} > @@ -54,9 +51,9 @@ export function UserSummary(props: { + @@ -39,26 +37,26 @@ function CreateBot() { return ( } onClick={() => modalController.push({ - type: "create_bot", + type: 'create_bot', client: client(), onCreate(bot) { navigate(`bots/${bot.id}`); }, }) } - description="You agree that your bot is subject to the Acceptable Usage Policy." + description='You agree that your bot is subject to the Acceptable Usage Policy.' > Create Bot } - onClick={() => window.open("https://developers.revolt.chat", "_blank")} - description="Learn more about how to create bots on Revolt." + onClick={() => window.open('https://developers.revolt.chat', '_blank')} + description='Learn more about how to create bots on Revolt.' > Developer Documentation @@ -74,8 +72,8 @@ function ListBots() { const bots = createOwnBotsResource(); return ( - - }> + + }> {(bot) => ( @@ -88,7 +86,7 @@ function ListBots() { /> } onClick={() => navigate(`bots/${bot.id}`)} - action="chevron" + action='chevron' // description={bot.id} > {bot.user!.displayName} diff --git a/packages/client/components/app/interface/settings/user/bots/ViewBot.tsx b/packages/client/components/app/interface/settings/user/bots/ViewBot.tsx index 421d1f97..a9fd09ba 100644 --- a/packages/client/components/app/interface/settings/user/bots/ViewBot.tsx +++ b/packages/client/components/app/interface/settings/user/bots/ViewBot.tsx @@ -1,20 +1,19 @@ -import { useClient } from "@revolt/client"; -import { createProfileResource } from "@revolt/client/resources"; +import MdLink from '@material-design-icons/svg/outlined/link.svg?component-solid'; +import MdPersonAdd from '@material-design-icons/svg/outlined/person_add.svg?component-solid'; +import MdPublic from '@material-design-icons/svg/outlined/public.svg?component-solid'; +import MdToken from '@material-design-icons/svg/outlined/token.svg?component-solid'; +import { useClient } from '@revolt/client'; +import { createProfileResource } from '@revolt/client/resources'; import { CategoryButton, CategoryButtonGroup, Column, iconSize, -} from "@revolt/ui"; +} from '@revolt/ui'; -import MdLink from "@material-design-icons/svg/outlined/link.svg?component-solid"; -import MdPersonAdd from "@material-design-icons/svg/outlined/person_add.svg?component-solid"; -import MdPublic from "@material-design-icons/svg/outlined/public.svg?component-solid"; -import MdToken from "@material-design-icons/svg/outlined/token.svg?component-solid"; - -import { useSettingsNavigation } from "../../Settings"; -import { UserSummary } from "../account"; -import { EditProfileButtons } from "../profile/EditProfileButtons"; +import { useSettingsNavigation } from '../../Settings'; +import { UserSummary } from '../account/index'; +import { EditProfileButtons } from '../profile/EditProfileButtons'; /** * View a specific bot @@ -23,11 +22,11 @@ export function ViewBot() { const client = useClient(); const { page } = useSettingsNavigation(); - const bot = () => client().bots.get(page()!.substring("bots/".length))!; + const bot = () => client().bots.get(page()!.substring('bots/'.length))!; const profile = createProfileResource(bot().user!); return ( - + } - action="chevron" + action='chevron' > Reset Token } - action="chevron" + action='chevron' > Submit to Discover - } action="copy"> + } action='copy'> Copy Invite } - action="chevron" + action='chevron' > Invite Bot diff --git a/packages/client/components/app/interface/settings/user/bots/index.ts b/packages/client/components/app/interface/settings/user/bots/index.ts index 645bc0cf..d52fb65b 100644 --- a/packages/client/components/app/interface/settings/user/bots/index.ts +++ b/packages/client/components/app/interface/settings/user/bots/index.ts @@ -1,2 +1,2 @@ -export { MyBots } from "./MyBots"; -export { ViewBot } from "./ViewBot"; +export { MyBots } from './MyBots'; +export { ViewBot } from './ViewBot'; diff --git a/packages/client/components/app/interface/settings/user/index.tsx b/packages/client/components/app/interface/settings/user/index.tsx index 798e6397..d8b183b8 100644 --- a/packages/client/components/app/interface/settings/user/index.tsx +++ b/packages/client/components/app/interface/settings/user/index.tsx @@ -1,66 +1,63 @@ -import { Component, Show } from "solid-js"; - -import { Server } from "revolt.js"; - -import { getController } from "@revolt/common"; -import { useTranslation } from "@revolt/i18n"; -import { useUser } from "@revolt/markdown/users"; -import { ColouredText, Column, iconSize, useTheme } from "@revolt/ui"; -import { ColourSwatches } from "@revolt/ui/components/design/atoms/inputs/ColourSwatches"; - // Filled Icons -import MdAccountCircleFill from "@material-design-icons/svg/filled/account_circle.svg?component-solid"; -import MdDesktopWindowsFill from "@material-design-icons/svg/filled/desktop_windows.svg?component-solid"; -import MdExtensionFill from "@material-design-icons/svg/filled/extension.svg?component-solid"; -import MdFormatListBulletedFill from "@material-design-icons/svg/filled/format_list_bulleted.svg?component-solid"; -import MdLanguageFill from "@material-design-icons/svg/filled/language.svg?component-solid"; -import MdLocalCafeFill from "@material-design-icons/svg/filled/local_cafe.svg?component-solid"; -import MdLogoutFill from "@material-design-icons/svg/filled/logout.svg?component-solid"; -import MdMemoryFill from "@material-design-icons/svg/filled/memory.svg?component-solid"; -import MdNotificationsFill from "@material-design-icons/svg/filled/notifications.svg?component-solid"; -import MdPaletteFill from "@material-design-icons/svg/filled/palette.svg?component-solid"; -import MdRateReviewFill from "@material-design-icons/svg/filled/rate_review.svg?component-solid"; -import MdScienceFill from "@material-design-icons/svg/filled/science.svg?component-solid"; -import MdSmartToyFill from "@material-design-icons/svg/filled/smart_toy.svg?component-solid"; -import MdSpeakerFill from "@material-design-icons/svg/filled/speaker.svg?component-solid"; -import MdSyncFill from "@material-design-icons/svg/filled/sync.svg?component-solid"; -import MdVerifiedUserFill from "@material-design-icons/svg/filled/verified_user.svg?component-solid"; -import MdAccessibility from "@material-design-icons/svg/outlined/accessibility.svg?component-solid"; +import MdAccountCircleFill from '@material-design-icons/svg/filled/account_circle.svg?component-solid'; +import MdDesktopWindowsFill from '@material-design-icons/svg/filled/desktop_windows.svg?component-solid'; +import MdExtensionFill from '@material-design-icons/svg/filled/extension.svg?component-solid'; +import MdFormatListBulletedFill from '@material-design-icons/svg/filled/format_list_bulleted.svg?component-solid'; +import MdLanguageFill from '@material-design-icons/svg/filled/language.svg?component-solid'; +import MdLocalCafeFill from '@material-design-icons/svg/filled/local_cafe.svg?component-solid'; +import MdLogoutFill from '@material-design-icons/svg/filled/logout.svg?component-solid'; +import MdMemoryFill from '@material-design-icons/svg/filled/memory.svg?component-solid'; +import MdNotificationsFill from '@material-design-icons/svg/filled/notifications.svg?component-solid'; +import MdPaletteFill from '@material-design-icons/svg/filled/palette.svg?component-solid'; +import MdRateReviewFill from '@material-design-icons/svg/filled/rate_review.svg?component-solid'; +import MdScienceFill from '@material-design-icons/svg/filled/science.svg?component-solid'; +import MdSmartToyFill from '@material-design-icons/svg/filled/smart_toy.svg?component-solid'; +import MdSpeakerFill from '@material-design-icons/svg/filled/speaker.svg?component-solid'; +import MdSyncFill from '@material-design-icons/svg/filled/sync.svg?component-solid'; +import MdVerifiedUserFill from '@material-design-icons/svg/filled/verified_user.svg?component-solid'; +import MdAccessibility from '@material-design-icons/svg/outlined/accessibility.svg?component-solid'; // Outlined Icons -import MdAccountCircle from "@material-design-icons/svg/outlined/account_circle.svg?component-solid"; -import MdDesktopWindows from "@material-design-icons/svg/outlined/desktop_windows.svg?component-solid"; -import MdExtension from "@material-design-icons/svg/outlined/extension.svg?component-solid"; -import MdFormatListBulleted from "@material-design-icons/svg/outlined/format_list_bulleted.svg?component-solid"; -import MdKeybinds from "@material-design-icons/svg/outlined/keyboard.svg?component-solid"; -import MdLanguage from "@material-design-icons/svg/outlined/language.svg?component-solid"; -import MdLocalCafe from "@material-design-icons/svg/outlined/local_cafe.svg?component-solid"; -import MdLogout from "@material-design-icons/svg/outlined/logout.svg?component-solid"; -import MdMemory from "@material-design-icons/svg/outlined/memory.svg?component-solid"; -import MdNotifications from "@material-design-icons/svg/outlined/notifications.svg?component-solid"; -import MdPalette from "@material-design-icons/svg/outlined/palette.svg?component-solid"; -import MdRateReview from "@material-design-icons/svg/outlined/rate_review.svg?component-solid"; -import MdScience from "@material-design-icons/svg/outlined/science.svg?component-solid"; -import MdSmartToy from "@material-design-icons/svg/outlined/smart_toy.svg?component-solid"; -import MdSpeaker from "@material-design-icons/svg/outlined/speaker.svg?component-solid"; -import MdSync from "@material-design-icons/svg/outlined/sync.svg?component-solid"; -import MdVerifiedUser from "@material-design-icons/svg/outlined/verified_user.svg?component-solid"; - -import { SettingsConfiguration } from ".."; +import MdAccountCircle from '@material-design-icons/svg/outlined/account_circle.svg?component-solid'; +import MdDesktopWindows from '@material-design-icons/svg/outlined/desktop_windows.svg?component-solid'; +import MdExtension from '@material-design-icons/svg/outlined/extension.svg?component-solid'; +import MdFormatListBulleted from '@material-design-icons/svg/outlined/format_list_bulleted.svg?component-solid'; +import MdKeybinds from '@material-design-icons/svg/outlined/keyboard.svg?component-solid'; +import MdLanguage from '@material-design-icons/svg/outlined/language.svg?component-solid'; +import MdLocalCafe from '@material-design-icons/svg/outlined/local_cafe.svg?component-solid'; +import MdLogout from '@material-design-icons/svg/outlined/logout.svg?component-solid'; +import MdMemory from '@material-design-icons/svg/outlined/memory.svg?component-solid'; +import MdNotifications from '@material-design-icons/svg/outlined/notifications.svg?component-solid'; +import MdPalette from '@material-design-icons/svg/outlined/palette.svg?component-solid'; +import MdRateReview from '@material-design-icons/svg/outlined/rate_review.svg?component-solid'; +import MdScience from '@material-design-icons/svg/outlined/science.svg?component-solid'; +import MdSmartToy from '@material-design-icons/svg/outlined/smart_toy.svg?component-solid'; +import MdSpeaker from '@material-design-icons/svg/outlined/speaker.svg?component-solid'; +import MdSync from '@material-design-icons/svg/outlined/sync.svg?component-solid'; +import MdVerifiedUser from '@material-design-icons/svg/outlined/verified_user.svg?component-solid'; +import { getController } from '@revolt/common'; +import { useTranslation } from '@revolt/i18n'; +import { useUser } from '@revolt/markdown/users'; +import { ColouredText, Column, iconSize, useTheme } from '@revolt/ui'; +import { ColourSwatches } from '@revolt/ui/components/design/atoms/inputs/ColourSwatches'; +import type { Server } from 'revolt.js'; +import type { Component } from 'solid-js'; +import { Show } from 'solid-js'; -import accessibility from "./Accessibility"; -import account from "./Account"; -import appearance from "./Appearance"; -import experiments from "./Experiments"; -import feedback from "./Feedback"; -import keybinds from "./Keybinds"; -import language from "./Language"; -import native from "./Native"; -import notifications from "./Notifications"; -import sessions from "./Sessions"; -import sync from "./Sync"; -import { AccountCard } from "./_AccountCard"; -import { MyBots, ViewBot } from "./bots"; -import { EditProfile } from "./profile"; +import type { SettingsConfiguration } from '..'; +import { AccountCard } from './_AccountCard'; +import accessibility from './Accessibility'; +import account from './Account'; +import appearance from './Appearance'; +import { MyBots, ViewBot } from './bots'; +import experiments from './Experiments'; +import feedback from './Feedback'; +import keybinds from './Keybinds'; +import language from './Language'; +import native from './Native'; +import notifications from './Notifications'; +import { EditProfile } from './profile'; +import sessions from './Sessions'; +import sync from './Sync'; /** * All the available routes for client settings @@ -72,12 +69,12 @@ const ClientSettingsRouting: Record = { // Bots bots: MyBots, - "bots/view": ViewBot, + 'bots/view': ViewBot, feedback, audio: () => null, appearance, - "appearance/colours": () => , + 'appearance/colours': () => , accessibility, notifications, language, @@ -93,8 +90,8 @@ const ClientSettingsRouting: Record = { * @returns New Id */ function mapRoutingId(id: string) { - if (id.startsWith("bots/")) { - return "bots/view"; + if (id.startsWith('bots/')) { + return 'bots/view'; } return id; @@ -108,13 +105,13 @@ const Config: SettingsConfiguration<{ server: Server }> = { title(key) { const t = useTranslation(); - if (key.startsWith("bots/")) { + if (key.startsWith('bots/')) { const user = useUser(key.substring(5)); return user()!.username; } return t( - `app.settings.pages.${key.replaceAll("/", ".")}.title`, + `app.settings.pages.${key.replaceAll('/', '.')}.title`, undefined, key ); @@ -147,55 +144,55 @@ const Config: SettingsConfiguration<{ server: Server }> = { return { prepend: ( - +
), entries: [ { - title: t("app.settings.categories.user_settings"), + title: t('app.settings.categories.user_settings'), entries: [ { - id: "account", + id: 'account', icon: <>, title: <>, hidden: true, }, { - id: "profile", + id: 'profile', icon: , - title: t("app.settings.pages.profile.title"), + title: t('app.settings.pages.profile.title'), }, { - id: "sessions", + id: 'sessions', icon: , - title: t("app.settings.pages.sessions.title"), + title: t('app.settings.pages.sessions.title'), }, ], }, { - title: "Revolt", + title: 'Revolt', entries: [ { - id: "bots", + id: 'bots', icon: , - title: t("app.settings.pages.bots.title"), + title: t('app.settings.pages.bots.title'), }, { - id: "feedback", + id: 'feedback', icon: , - title: t("app.settings.pages.feedback.title"), + title: t('app.settings.pages.feedback.title'), }, { - href: "https://insrt.uk/donate", + href: 'https://insrt.uk/donate', icon: , - title: t("app.settings.pages.donate.title"), + title: t('app.settings.pages.donate.title'), }, ], }, { - title: t("app.settings.categories.client_settings"), + title: t('app.settings.categories.client_settings'), entries: [ // { // id: "audio", @@ -231,9 +228,9 @@ const Config: SettingsConfiguration<{ server: Server }> = { // title: t("app.settings.pages.keybinds.title"), // }, { - id: "language", + id: 'language', icon: , - title: t("app.settings.pages.language.title"), + title: t('app.settings.pages.language.title'), }, // { // id: "sync", @@ -247,9 +244,9 @@ const Config: SettingsConfiguration<{ server: Server }> = { // title: t("app.settings.pages.native.title"), // }, { - id: "experiments", + id: 'experiments', icon: , - title: t("app.settings.pages.experiments.title"), + title: t('app.settings.pages.experiments.title'), }, ], }, @@ -262,12 +259,12 @@ const Config: SettingsConfiguration<{ server: Server }> = { // title: t("app.special.modals.changelogs.title"), // }, { - href: "https://github.com/revoltchat", + href: 'https://github.com/revoltchat', icon: , - title: t("app.settings.pages.source_code"), + title: t('app.settings.pages.source_code'), }, { - id: "logout", + id: 'logout', icon: ( = { ), title: ( - {t("app.settings.pages.logOut")} + {t('app.settings.pages.logOut')} ), onClick: () => { - getController("modal").pop(); - getController("client").logout(); + getController('modal').pop(); + getController('client').logout(); }, }, ], diff --git a/packages/client/components/app/interface/settings/user/profile/EditProfile.tsx b/packages/client/components/app/interface/settings/user/profile/EditProfile.tsx index 30d04683..533dbc84 100644 --- a/packages/client/components/app/interface/settings/user/profile/EditProfile.tsx +++ b/packages/client/components/app/interface/settings/user/profile/EditProfile.tsx @@ -1,8 +1,7 @@ -import { For } from "solid-js"; - -import { useClient } from "@revolt/client"; -import { createOwnProfileResource } from "@revolt/client/resources"; -import { modalController } from "@revolt/modal"; +import MdGroups from '@material-design-icons/svg/outlined/groups.svg?component-solid'; +import { useClient } from '@revolt/client'; +import { createOwnProfileResource } from '@revolt/client/resources'; +import { modalController } from '@revolt/modal'; import { Avatar, CategoryButton, @@ -10,13 +9,11 @@ import { CategoryCollapse, Column, iconSize, -} from "@revolt/ui"; - -import MdGroups from "@material-design-icons/svg/outlined/groups.svg?component-solid"; - -import { UserSummary } from "../account"; +} from '@revolt/ui'; +import { For } from 'solid-js'; -import { EditProfileButtons } from "./EditProfileButtons"; +import { UserSummary } from '../account/index'; +import { EditProfileButtons } from './EditProfileButtons'; /** * Edit profile @@ -26,7 +23,7 @@ export function EditProfile() { const profile = createOwnProfileResource(); return ( - + } - title="Server Identities" - description="Change your profile per-server" + title='Server Identities' + description='Change your profile per-server' scrollable > @@ -53,7 +50,7 @@ export function EditProfile() { } onClick={() => modalController.push({ - type: "server_identity", + type: 'server_identity', member: server.member!, }) } diff --git a/packages/client/components/app/interface/settings/user/profile/EditProfileButtons.tsx b/packages/client/components/app/interface/settings/user/profile/EditProfileButtons.tsx index 230e8e64..475cd602 100644 --- a/packages/client/components/app/interface/settings/user/profile/EditProfileButtons.tsx +++ b/packages/client/components/app/interface/settings/user/profile/EditProfileButtons.tsx @@ -1,44 +1,41 @@ -import { Match, Switch } from "solid-js"; - -import { User } from "revolt.js"; - -import { useClient } from "@revolt/client"; -import { createOwnProfileResource } from "@revolt/client/resources"; -import { modalController } from "@revolt/modal"; +import MdBadge from '@material-design-icons/svg/outlined/badge.svg?component-solid'; +import MdCrop169 from '@material-design-icons/svg/outlined/crop_16_9.svg?component-solid'; +import MdDelete from '@material-design-icons/svg/outlined/delete.svg?component-solid'; +import MdReplaceImage from '@material-design-icons/svg/outlined/edit.svg?component-solid'; +import MdEditNote from '@material-design-icons/svg/outlined/edit_note.svg?component-solid'; +import MdImage from '@material-design-icons/svg/outlined/image.svg?component-solid'; +import { useClient } from '@revolt/client'; +import { createOwnProfileResource } from '@revolt/client/resources'; +import { modalController } from '@revolt/modal'; import { CategoryButton, CategoryButtonGroup, CategoryCollapse, iconSize, -} from "@revolt/ui"; - -import MdBadge from "@material-design-icons/svg/outlined/badge.svg?component-solid"; -import MdCrop169 from "@material-design-icons/svg/outlined/crop_16_9.svg?component-solid"; -import MdDelete from "@material-design-icons/svg/outlined/delete.svg?component-solid"; -import MdReplaceImage from "@material-design-icons/svg/outlined/edit.svg?component-solid"; -import MdEditNote from "@material-design-icons/svg/outlined/edit_note.svg?component-solid"; -import MdImage from "@material-design-icons/svg/outlined/image.svg?component-solid"; +} from '@revolt/ui'; +import type { User } from 'revolt.js'; +import { Match, Switch } from 'solid-js'; export function EditProfileButtons(props: { user: User }) { const client = useClient(); const profile = createOwnProfileResource(); function selectImage(tag: string, cb: (id: string) => void) { - const el = document.createElement("input"); - el.type = "file"; - el.accept = "image/*"; + const el = document.createElement('input'); + el.type = 'file'; + el.accept = 'image/*'; el.onchange = async () => { if (el.files) { const [file] = el.files; if (file) { const body = new FormData(); - body.append("file", file); + body.append('file', file); const data = await fetch( `${client().configuration?.features.autumn.url}/${tag}`, { - method: "POST", + method: 'POST', body, } ).then((res) => res.json()); @@ -57,11 +54,11 @@ export function EditProfileButtons(props: { user: User }) { } function replaceAvatar() { - selectImage("avatars", (avatar) => props.user.edit({ avatar })); + selectImage('avatars', (avatar) => props.user.edit({ avatar })); } function replaceBanner() { - selectImage("backgrounds", (background) => + selectImage('backgrounds', (background) => props.user.edit({ profile: { background } }).then(() => profile.refetch()) ); } @@ -69,12 +66,12 @@ export function EditProfileButtons(props: { user: User }) { return ( } - action="chevron" + action='chevron' onClick={() => modalController.push({ - type: "edit_display_name", + type: 'edit_display_name', user: props.user, }) } @@ -84,9 +81,9 @@ export function EditProfileButtons(props: { user: User }) { } - action="chevron" + action='chevron' onClick={replaceAvatar} > Avatar @@ -96,22 +93,22 @@ export function EditProfileButtons(props: { user: User }) { } - title="Avatar" - description="Change or remove your profile picture" + title='Avatar' + description='Change or remove your profile picture' > } - action="chevron" + action='chevron' onClick={replaceAvatar} > Replace Avatar } - action="chevron" - onClick={() => props.user.edit({ remove: ["Avatar"] })} + action='chevron' + onClick={() => props.user.edit({ remove: ['Avatar'] })} > Remove Avatar @@ -121,9 +118,9 @@ export function EditProfileButtons(props: { user: User }) { } - action="chevron" + action='chevron' onClick={replaceBanner} > Banner @@ -133,22 +130,22 @@ export function EditProfileButtons(props: { user: User }) { } - title="Banner" - description="Change or remove your profile banner" + title='Banner' + description='Change or remove your profile banner' > } - action="chevron" + action='chevron' onClick={replaceBanner} > Replace Banner } - action="chevron" - onClick={() => props.user.edit({ remove: ["ProfileBackground"] })} + action='chevron' + onClick={() => props.user.edit({ remove: ['ProfileBackground'] })} > Remove Banner @@ -156,9 +153,9 @@ export function EditProfileButtons(props: { user: User }) { } - action="chevron" + action='chevron' > Bio diff --git a/packages/client/components/app/interface/settings/user/profile/index.ts b/packages/client/components/app/interface/settings/user/profile/index.ts index 30d571ff..a839133b 100644 --- a/packages/client/components/app/interface/settings/user/profile/index.ts +++ b/packages/client/components/app/interface/settings/user/profile/index.ts @@ -1 +1 @@ -export * from "./EditProfile"; +export * from './EditProfile'; diff --git a/packages/client/components/app/menus/ChannelContextMenu.tsx b/packages/client/components/app/menus/ChannelContextMenu.tsx index 9975646d..3c94a6bd 100644 --- a/packages/client/components/app/menus/ChannelContextMenu.tsx +++ b/packages/client/components/app/menus/ChannelContextMenu.tsx @@ -1,25 +1,22 @@ -import { Show } from "solid-js"; - -import { Channel } from "revolt.js"; - -import { getController } from "@revolt/common"; -import { useTranslation } from "@revolt/i18n"; - -import MdBadge from "@material-design-icons/svg/outlined/badge.svg?component-solid"; -import MdDelete from "@material-design-icons/svg/outlined/delete.svg?component-solid"; -import MdGroupAdd from "@material-design-icons/svg/outlined/group_add.svg?component-solid"; -import MdLibraryAdd from "@material-design-icons/svg/outlined/library_add.svg?component-solid"; -import MdLogout from "@material-design-icons/svg/outlined/logout.svg?component-solid"; -import MdMarkChatRead from "@material-design-icons/svg/outlined/mark_chat_read.svg?component-solid"; -import MdSettings from "@material-design-icons/svg/outlined/settings.svg?component-solid"; -import MdShare from "@material-design-icons/svg/outlined/share.svg?component-solid"; -import MdShield from "@material-design-icons/svg/outlined/shield.svg?component-solid"; +import MdBadge from '@material-design-icons/svg/outlined/badge.svg?component-solid'; +import MdDelete from '@material-design-icons/svg/outlined/delete.svg?component-solid'; +import MdGroupAdd from '@material-design-icons/svg/outlined/group_add.svg?component-solid'; +import MdLibraryAdd from '@material-design-icons/svg/outlined/library_add.svg?component-solid'; +import MdLogout from '@material-design-icons/svg/outlined/logout.svg?component-solid'; +import MdMarkChatRead from '@material-design-icons/svg/outlined/mark_chat_read.svg?component-solid'; +import MdSettings from '@material-design-icons/svg/outlined/settings.svg?component-solid'; +import MdShare from '@material-design-icons/svg/outlined/share.svg?component-solid'; +import MdShield from '@material-design-icons/svg/outlined/shield.svg?component-solid'; +import { getController } from '@revolt/common'; +import { useTranslation } from '@revolt/i18n'; +import type { Channel } from 'revolt.js'; +import { Show } from 'solid-js'; import { ContextMenu, ContextMenuButton, ContextMenuDivider, -} from "./ContextMenu"; +} from './ContextMenu'; /** * Context menu for channels @@ -38,8 +35,8 @@ export function ChannelContextMenu(props: { channel: Channel }) { * Create a new invite */ function createInvite() { - getController("modal").push({ - type: "create_invite", + getController('modal').push({ + type: 'create_invite', channel: props.channel, }); } @@ -48,8 +45,8 @@ export function ChannelContextMenu(props: { channel: Channel }) { * Create a new channel */ function createChannel() { - getController("modal").push({ - type: "create_channel", + getController('modal').push({ + type: 'create_channel', server: props.channel.server!, }); } @@ -58,9 +55,9 @@ export function ChannelContextMenu(props: { channel: Channel }) { * Edit channel */ function editChannel() { - getController("modal").push({ - type: "settings", - config: "channel", + getController('modal').push({ + type: 'settings', + config: 'channel', context: props.channel, }); } @@ -69,8 +66,8 @@ export function ChannelContextMenu(props: { channel: Channel }) { * Delete channel */ function deleteChannel() { - getController("modal").push({ - type: "delete_channel", + getController('modal').push({ + type: 'delete_channel', channel: props.channel, }); } @@ -81,7 +78,7 @@ export function ChannelContextMenu(props: { channel: Channel }) { function openAdminPanel() { window.open( `https://admin.revolt.chat/panel/inspect/channel/${props.channel.id}`, - "_blank" + '_blank' ); } @@ -91,7 +88,7 @@ export function ChannelContextMenu(props: { channel: Channel }) { function copyLink() { navigator.clipboard.writeText( `${location.origin}${ - props.channel.server ? `/server/${props.channel.server?.id}` : "" + props.channel.server ? `/server/${props.channel.server?.id}` : '' }/channel/${props.channel.id}` ); } @@ -107,48 +104,48 @@ export function ChannelContextMenu(props: { channel: Channel }) { - {t("app.context_menu.mark_as_read")} + {t('app.context_menu.mark_as_read')} - + - {t("app.context_menu.create_invite")} + {t('app.context_menu.create_invite')} - + - {t("app.context_menu.create_channel")} + {t('app.context_menu.create_channel')} - + - {t("app.context_menu.open_channel_settings")} + {t('app.context_menu.open_channel_settings')} {t( - props.channel.type === "Group" - ? "app.context_menu.leave_group" - : "app.context_menu.delete_channel" + props.channel.type === 'Group' + ? 'app.context_menu.leave_group' + : 'app.context_menu.delete_channel' )} @@ -158,10 +155,10 @@ export function ChannelContextMenu(props: { channel: Channel }) { Admin Panel - {t("app.context_menu.copy_link")} + {t('app.context_menu.copy_link')} - {t("app.context_menu.copy_cid")} + {t('app.context_menu.copy_cid')} ); diff --git a/packages/client/components/app/menus/ContextMenu.tsx b/packages/client/components/app/menus/ContextMenu.tsx index 9edac6ff..f60bb6e4 100644 --- a/packages/client/components/app/menus/ContextMenu.tsx +++ b/packages/client/components/app/menus/ContextMenu.tsx @@ -1,6 +1,6 @@ -import { Component, ComponentProps, JSX, splitProps } from "solid-js"; - -import { iconSize, styled } from "@revolt/ui"; +import { iconSize, styled } from '@revolt/ui'; +import type { Component, ComponentProps, JSX } from 'solid-js'; +import { splitProps } from 'solid-js'; export const ContextMenu = styled.div` display: flex; @@ -10,29 +10,29 @@ export const ContextMenu = styled.div` overflow: hidden; border-radius: ${(props) => props.theme!.borderRadius.md}; background: ${(props) => - props.theme!.colours["component-context-menu-background"]}; + props.theme!.colours['component-context-menu-background']}; color: ${(props) => - props.theme!.colours["component-context-menu-foreground"]}; - fill: ${(props) => props.theme!.colours["component-context-menu-foreground"]}; + props.theme!.colours['component-context-menu-foreground']}; + fill: ${(props) => props.theme!.colours['component-context-menu-foreground']}; box-shadow: 0 0 3px - ${(props) => props.theme!.colours["component-context-menu-shadow"]}; + ${(props) => props.theme!.colours['component-context-menu-shadow']}; `; export const ContextMenuDivider = styled.div` height: 1px; margin: ${(props) => props.theme!.gap.sm} 0; background: ${(props) => - props.theme!.colours["component-context-menu-divider"]}; + props.theme!.colours['component-context-menu-divider']}; `; -export const ContextMenuItem = styled("a", "MenuItem")` +export const ContextMenuItem = styled('a', 'MenuItem')` display: block; padding: ${(props) => props.theme!.gap.md} ${(props) => props.theme!.gap.lg}; &:hover { background: ${(props) => - props.theme!.colours["component-context-menu-item-hover-background"]}; + props.theme!.colours['component-context-menu-item-hover-background']}; } `; @@ -52,7 +52,7 @@ const ButtonBase = styled(ContextMenuItem)<{ destructive?: boolean }>` ? `fill: ${props.theme!.customColours.error.color}; color: ${ props.theme!.customColours.error.color };` - : ""} + : ''} `; type ButtonProps = ComponentProps & { @@ -61,11 +61,11 @@ type ButtonProps = ComponentProps & { }; export function ContextMenuButton(props: ButtonProps) { - const [local, remote] = splitProps(props, ["icon", "children"]); + const [local, remote] = splitProps(props, ['icon', 'children']); return ( - {local.icon?.(iconSize("1.2em"))} + {local.icon?.(iconSize('1.2em'))} {local.children} ); diff --git a/packages/client/components/app/menus/DraftMessageContextMenu.tsx b/packages/client/components/app/menus/DraftMessageContextMenu.tsx index 1a602535..898e9fb5 100644 --- a/packages/client/components/app/menus/DraftMessageContextMenu.tsx +++ b/packages/client/components/app/menus/DraftMessageContextMenu.tsx @@ -1,17 +1,14 @@ -import { Show } from "solid-js"; +import MdClose from '@material-design-icons/svg/outlined/close.svg?component-solid'; +import MdDelete from '@material-design-icons/svg/outlined/delete.svg?component-solid'; +import MdRefresh from '@material-design-icons/svg/outlined/refresh.svg?component-solid'; +import { useClient } from '@revolt/client'; +import { useTranslation } from '@revolt/i18n'; +import { state } from '@revolt/state'; +import type { UnsentMessage } from '@revolt/state/stores/Draft'; +import type { Channel } from 'revolt.js'; +import { Show } from 'solid-js'; -import { Channel } from "revolt.js"; - -import { useClient } from "@revolt/client"; -import { useTranslation } from "@revolt/i18n"; -import { state } from "@revolt/state"; -import { UnsentMessage } from "@revolt/state/stores/Draft"; - -import MdClose from "@material-design-icons/svg/outlined/close.svg?component-solid"; -import MdDelete from "@material-design-icons/svg/outlined/delete.svg?component-solid"; -import MdRefresh from "@material-design-icons/svg/outlined/refresh.svg?component-solid"; - -import { ContextMenu, ContextMenuButton } from "./ContextMenu"; +import { ContextMenu, ContextMenuButton } from './ContextMenu'; interface Props { draft: UnsentMessage; @@ -40,27 +37,27 @@ export function DraftMessageContextMenu(props: Props) { } return ( - + - {t("app.context_menu.cancel_message")} + {t('app.context_menu.cancel_message')} - {t("app.context_menu.retry_message")} + {t('app.context_menu.retry_message')} - {t("app.context_menu.delete_message")} + {t('app.context_menu.delete_message')} diff --git a/packages/client/components/app/menus/MessageContextMenu.tsx b/packages/client/components/app/menus/MessageContextMenu.tsx index f6cb0c67..43abe244 100644 --- a/packages/client/components/app/menus/MessageContextMenu.tsx +++ b/packages/client/components/app/menus/MessageContextMenu.tsx @@ -1,26 +1,23 @@ -import { Show } from "solid-js"; - -import { Message } from "revolt.js"; - -import { useClient, useUser } from "@revolt/client"; -import { getController } from "@revolt/common"; -import { useTranslation } from "@revolt/i18n"; -import { state } from "@revolt/state"; - -import MdBadge from "@material-design-icons/svg/outlined/badge.svg?component-solid"; -import MdContentCopy from "@material-design-icons/svg/outlined/content_copy.svg?component-solid"; -import MdDelete from "@material-design-icons/svg/outlined/delete.svg?component-solid"; -import MdMarkChatUnread from "@material-design-icons/svg/outlined/mark_chat_unread.svg?component-solid"; -import MdReply from "@material-design-icons/svg/outlined/reply.svg?component-solid"; -import MdReport from "@material-design-icons/svg/outlined/report.svg?component-solid"; -import MdShare from "@material-design-icons/svg/outlined/share.svg?component-solid"; -import MdShield from "@material-design-icons/svg/outlined/shield.svg?component-solid"; +import MdBadge from '@material-design-icons/svg/outlined/badge.svg?component-solid'; +import MdContentCopy from '@material-design-icons/svg/outlined/content_copy.svg?component-solid'; +import MdDelete from '@material-design-icons/svg/outlined/delete.svg?component-solid'; +import MdMarkChatUnread from '@material-design-icons/svg/outlined/mark_chat_unread.svg?component-solid'; +import MdReply from '@material-design-icons/svg/outlined/reply.svg?component-solid'; +import MdReport from '@material-design-icons/svg/outlined/report.svg?component-solid'; +import MdShare from '@material-design-icons/svg/outlined/share.svg?component-solid'; +import MdShield from '@material-design-icons/svg/outlined/shield.svg?component-solid'; +import { useClient, useUser } from '@revolt/client'; +import { getController } from '@revolt/common'; +import { useTranslation } from '@revolt/i18n'; +import { state } from '@revolt/state'; +import type { Message } from 'revolt.js'; +import { Show } from 'solid-js'; import { ContextMenu, ContextMenuButton, ContextMenuDivider, -} from "./ContextMenu"; +} from './ContextMenu'; /** * Context menu for messages @@ -55,8 +52,8 @@ export function MessageContextMenu(props: { message: Message }) { * Report the message */ function report() { - getController("modal").push({ - type: "report_content", + getController('modal').push({ + type: 'report_content', target: props.message, client: client(), }); @@ -69,8 +66,8 @@ export function MessageContextMenu(props: { message: Message }) { if (ev.shiftKey) { props.message.delete(); } else { - getController("modal").push({ - type: "delete_message", + getController('modal').push({ + type: 'delete_message', message: props.message, }); } @@ -82,7 +79,7 @@ export function MessageContextMenu(props: { message: Message }) { function openAdminPanel() { window.open( `https://admin.revolt.chat/panel/inspect/message/${props.message.id}`, - "_blank" + '_blank' ); } @@ -92,7 +89,7 @@ export function MessageContextMenu(props: { message: Message }) { function copyLink() { navigator.clipboard.writeText( `${location.origin}${ - props.message.server ? `/server/${props.message.server?.id}` : "" + props.message.server ? `/server/${props.message.server?.id}` : '' }/channel/${props.message.channelId}/${props.message.id}` ); } @@ -107,28 +104,28 @@ export function MessageContextMenu(props: { message: Message }) { return ( - {t("app.context_menu.reply_message")} + {t('app.context_menu.reply_message')} - {t("app.context_menu.mark_unread")} + {t('app.context_menu.mark_unread')} - {t("app.context_menu.copy_text")} + {t('app.context_menu.copy_text')} - {t("app.context_menu.report_message")} + {t('app.context_menu.report_message')} - {t("app.context_menu.delete_message")} + {t('app.context_menu.delete_message')} @@ -136,10 +133,10 @@ export function MessageContextMenu(props: { message: Message }) { Admin Panel - {t("app.context_menu.copy_link")} + {t('app.context_menu.copy_link')} - {t("app.context_menu.copy_mid")} + {t('app.context_menu.copy_mid')} ); diff --git a/packages/client/components/app/menus/ServerContextMenu.tsx b/packages/client/components/app/menus/ServerContextMenu.tsx index 45fd8dd4..3b839a1d 100644 --- a/packages/client/components/app/menus/ServerContextMenu.tsx +++ b/packages/client/components/app/menus/ServerContextMenu.tsx @@ -1,25 +1,22 @@ -import { Show } from "solid-js"; - -import { Server } from "revolt.js"; - -import { useClient } from "@revolt/client"; -import { getController } from "@revolt/common"; -import { useTranslation } from "@revolt/i18n"; - -import MdBadge from "@material-design-icons/svg/outlined/badge.svg?component-solid"; -import MdFace from "@material-design-icons/svg/outlined/face.svg?component-solid"; -import MdLogout from "@material-design-icons/svg/outlined/logout.svg?component-solid"; -import MdMarkChatRead from "@material-design-icons/svg/outlined/mark_chat_read.svg?component-solid"; -import MdPersonAdd from "@material-design-icons/svg/outlined/person_add.svg?component-solid"; -import MdReport from "@material-design-icons/svg/outlined/report.svg?component-solid"; -import MdSettings from "@material-design-icons/svg/outlined/settings.svg?component-solid"; -import MdShield from "@material-design-icons/svg/outlined/shield.svg?component-solid"; +import MdBadge from '@material-design-icons/svg/outlined/badge.svg?component-solid'; +import MdFace from '@material-design-icons/svg/outlined/face.svg?component-solid'; +import MdLogout from '@material-design-icons/svg/outlined/logout.svg?component-solid'; +import MdMarkChatRead from '@material-design-icons/svg/outlined/mark_chat_read.svg?component-solid'; +import MdPersonAdd from '@material-design-icons/svg/outlined/person_add.svg?component-solid'; +import MdReport from '@material-design-icons/svg/outlined/report.svg?component-solid'; +import MdSettings from '@material-design-icons/svg/outlined/settings.svg?component-solid'; +import MdShield from '@material-design-icons/svg/outlined/shield.svg?component-solid'; +import { useClient } from '@revolt/client'; +import { getController } from '@revolt/common'; +import { useTranslation } from '@revolt/i18n'; +import type { Server } from 'revolt.js'; +import { Show } from 'solid-js'; import { ContextMenu, ContextMenuButton, ContextMenuDivider, -} from "./ContextMenu"; +} from './ContextMenu'; /** * Context menu for servers @@ -43,13 +40,13 @@ export function ServerContextMenu(props: { server: Server }) { const channel = props.server.orderedChannels .find((category) => category.channels.find((channel) => - channel.havePermission("InviteOthers") + channel.havePermission('InviteOthers') ) )! - .channels.find((channel) => channel.havePermission("InviteOthers"))!; + .channels.find((channel) => channel.havePermission('InviteOthers'))!; - getController("modal").push({ - type: "create_invite", + getController('modal').push({ + type: 'create_invite', channel, }); } @@ -58,8 +55,8 @@ export function ServerContextMenu(props: { server: Server }) { * Open server settings */ function editIdentity() { - getController("modal").push({ - type: "server_identity", + getController('modal').push({ + type: 'server_identity', member: props.server.member!, }); } @@ -68,9 +65,9 @@ export function ServerContextMenu(props: { server: Server }) { * Open server settings */ function openSettings() { - getController("modal").push({ - type: "settings", - config: "server", + getController('modal').push({ + type: 'settings', + config: 'server', context: props.server, }); } @@ -79,8 +76,8 @@ export function ServerContextMenu(props: { server: Server }) { * Report the server */ function report() { - getController("modal").push({ - type: "report_content", + getController('modal').push({ + type: 'report_content', target: props.server, client: client(), }); @@ -90,8 +87,8 @@ export function ServerContextMenu(props: { server: Server }) { * Leave the server */ function leave() { - getController("modal").push({ - type: "leave_server", + getController('modal').push({ + type: 'leave_server', server: props.server, }); } @@ -102,7 +99,7 @@ export function ServerContextMenu(props: { server: Server }) { function openAdminPanel() { window.open( `https://admin.revolt.chat/panel/inspect/server/${props.server.id}`, - "_blank" + '_blank' ); } @@ -118,54 +115,54 @@ export function ServerContextMenu(props: { server: Server }) { */ const permissionInviteOthers = () => props.server.channels.find((channel) => - channel.havePermission("InviteOthers") + channel.havePermission('InviteOthers') ); /** * Determine whether we can edit our identity */ const permissionEditIdentity = () => - props.server.havePermission("ChangeNickname") || - props.server.havePermission("ChangeAvatar"); + props.server.havePermission('ChangeNickname') || + props.server.havePermission('ChangeAvatar'); /** * Determine whether we can access settings */ const permissionServerSettings = () => props.server.owner?.self || - props.server.havePermission("AssignRoles") || - props.server.havePermission("BanMembers") || - props.server.havePermission("KickMembers") || - props.server.havePermission("ManageChannel") || - props.server.havePermission("ManageCustomisation") || - props.server.havePermission("ManageNicknames") || - props.server.havePermission("ManagePermissions") || - props.server.havePermission("ManageRole") || - props.server.havePermission("ManageServer") || - props.server.havePermission("ManageWebhooks"); + props.server.havePermission('AssignRoles') || + props.server.havePermission('BanMembers') || + props.server.havePermission('KickMembers') || + props.server.havePermission('ManageChannel') || + props.server.havePermission('ManageCustomisation') || + props.server.havePermission('ManageNicknames') || + props.server.havePermission('ManagePermissions') || + props.server.havePermission('ManageRole') || + props.server.havePermission('ManageServer') || + props.server.havePermission('ManageWebhooks'); return ( - {t("app.context_menu.mark_as_read")} + {t('app.context_menu.mark_as_read')} - {t("app.context_menu.create_invite")} + {t('app.context_menu.create_invite')} - {t("app.context_menu.edit_your_identity")} + {t('app.context_menu.edit_your_identity')} - {t("app.context_menu.open_server_settings")} + {t('app.context_menu.open_server_settings')} - {t("app.context_menu.report_server")} + {t('app.context_menu.report_server')} - {t("app.context_menu.leave_server")} + {t('app.context_menu.leave_server')} @@ -191,7 +188,7 @@ export function ServerContextMenu(props: { server: Server }) { Admin Panel - {t("app.context_menu.copy_sid")} + {t('app.context_menu.copy_sid')} ); diff --git a/packages/client/components/app/menus/ServerSidebarContextMenu.tsx b/packages/client/components/app/menus/ServerSidebarContextMenu.tsx index b0d83790..a5916ec0 100644 --- a/packages/client/components/app/menus/ServerSidebarContextMenu.tsx +++ b/packages/client/components/app/menus/ServerSidebarContextMenu.tsx @@ -1,13 +1,10 @@ -import { Show } from "solid-js"; +import MdLibraryAdd from '@material-design-icons/svg/outlined/library_add.svg?component-solid'; +import { getController } from '@revolt/common'; +import { useTranslation } from '@revolt/i18n'; +import type { Server } from 'revolt.js'; +import { Show } from 'solid-js'; -import { Server } from "revolt.js"; - -import { getController } from "@revolt/common"; -import { useTranslation } from "@revolt/i18n"; - -import MdLibraryAdd from "@material-design-icons/svg/outlined/library_add.svg?component-solid"; - -import { ContextMenu, ContextMenuButton } from "./ContextMenu"; +import { ContextMenu, ContextMenuButton } from './ContextMenu'; /** * Context menu for server sidebar @@ -19,17 +16,17 @@ export function ServerSidebarContextMenu(props: { server: Server }) { * Create a new channel */ function createChannel() { - getController("modal").push({ - type: "create_channel", + getController('modal').push({ + type: 'create_channel', server: props.server!, }); } return ( - + - {t("app.context_menu.create_channel")} + {t('app.context_menu.create_channel')} diff --git a/packages/client/components/app/menus/UserContextMenu.tsx b/packages/client/components/app/menus/UserContextMenu.tsx index 2c6dd3f9..436903f0 100644 --- a/packages/client/components/app/menus/UserContextMenu.tsx +++ b/packages/client/components/app/menus/UserContextMenu.tsx @@ -1,29 +1,27 @@ -import { JSX, Show } from "solid-js"; - -import { Channel, Message, ServerMember, User } from "revolt.js"; - -import { useClient } from "@revolt/client"; -import { getController } from "@revolt/common"; -import { useTranslation } from "@revolt/i18n"; - -import MdAddCircleOutline from "@material-design-icons/svg/outlined/add_circle_outline.svg?component-solid"; -import MdAdminPanelSettings from "@material-design-icons/svg/outlined/admin_panel_settings.svg?component-solid"; -import MdAlternateEmail from "@material-design-icons/svg/outlined/alternate_email.svg?component-solid"; -import MdBadge from "@material-design-icons/svg/outlined/badge.svg?component-solid"; -import MdBlock from "@material-design-icons/svg/outlined/block.svg?component-solid"; -import MdCancel from "@material-design-icons/svg/outlined/cancel.svg?component-solid"; -import MdClose from "@material-design-icons/svg/outlined/close.svg?component-solid"; -import MdDoNotDisturbOn from "@material-design-icons/svg/outlined/do_not_disturb_on.svg?component-solid"; -import MdFace from "@material-design-icons/svg/outlined/face.svg?component-solid"; -import MdPersonAddAlt from "@material-design-icons/svg/outlined/person_add_alt.svg?component-solid"; -import MdPersonRemove from "@material-design-icons/svg/outlined/person_remove.svg?component-solid"; -import MdReport from "@material-design-icons/svg/outlined/report.svg?component-solid"; +import MdAddCircleOutline from '@material-design-icons/svg/outlined/add_circle_outline.svg?component-solid'; +import MdAdminPanelSettings from '@material-design-icons/svg/outlined/admin_panel_settings.svg?component-solid'; +import MdAlternateEmail from '@material-design-icons/svg/outlined/alternate_email.svg?component-solid'; +import MdBadge from '@material-design-icons/svg/outlined/badge.svg?component-solid'; +import MdBlock from '@material-design-icons/svg/outlined/block.svg?component-solid'; +import MdCancel from '@material-design-icons/svg/outlined/cancel.svg?component-solid'; +import MdClose from '@material-design-icons/svg/outlined/close.svg?component-solid'; +import MdDoNotDisturbOn from '@material-design-icons/svg/outlined/do_not_disturb_on.svg?component-solid'; +import MdFace from '@material-design-icons/svg/outlined/face.svg?component-solid'; +import MdPersonAddAlt from '@material-design-icons/svg/outlined/person_add_alt.svg?component-solid'; +import MdPersonRemove from '@material-design-icons/svg/outlined/person_remove.svg?component-solid'; +import MdReport from '@material-design-icons/svg/outlined/report.svg?component-solid'; +import { useClient } from '@revolt/client'; +import { getController } from '@revolt/common'; +import { useTranslation } from '@revolt/i18n'; +import type { Channel, Message, ServerMember, User } from 'revolt.js'; +import type { JSX } from 'solid-js'; +import { Show } from 'solid-js'; import { ContextMenu, ContextMenuButton, ContextMenuDivider, -} from "./ContextMenu"; +} from './ContextMenu'; /** * Context menu for users @@ -43,8 +41,8 @@ export function UserContextMenu(props: { * Delete channel */ function closeDm() { - getController("modal").push({ - type: "delete_channel", + getController('modal').push({ + type: 'delete_channel', channel: props.channel!, }); } @@ -53,15 +51,15 @@ export function UserContextMenu(props: { * Mention the user */ function mention() { - getController("state").draft.insertText(props.user.toString()); + getController('state').draft.insertText(props.user.toString()); } /** * Edit server identity for user */ function editIdentity() { - getController("modal").push({ - type: "server_identity", + getController('modal').push({ + type: 'server_identity', member: props.member!, }); } @@ -70,8 +68,8 @@ export function UserContextMenu(props: { * Report the user */ function reportUser() { - getController("modal").push({ - type: "report_content", + getController('modal').push({ + type: 'report_content', target: props.user!, client: client(), contextMessage: props.contextMessage, @@ -82,8 +80,8 @@ export function UserContextMenu(props: { * Kick the member */ function kickMember() { - getController("modal").push({ - type: "kick_member", + getController('modal').push({ + type: 'kick_member', member: props.member!, }); } @@ -92,8 +90,8 @@ export function UserContextMenu(props: { * Ban the member */ function banMember() { - getController("modal").push({ - type: "ban_member", + getController('modal').push({ + type: 'ban_member', member: props.member!, }); } @@ -132,7 +130,7 @@ export function UserContextMenu(props: { function openAdminPanel() { window.open( `https://admin.revolt.chat/panel/inspect/user/${props.user.id}`, - "_blank" + '_blank' ); } @@ -147,12 +145,12 @@ export function UserContextMenu(props: { - {t("app.context_menu.close_dm")} + {t('app.context_menu.close_dm')} - {t("app.context_menu.mention")} + {t('app.context_menu.mention')} @@ -161,17 +159,17 @@ export function UserContextMenu(props: { when={ props.member && (props.user.self - ? props.member!.server!.havePermission("ChangeNickname") || - props.member!.server!.havePermission("ChangeAvatar") - : (props.member!.server!.havePermission("ManageNicknames") || - props.member!.server!.havePermission("RemoveAvatars")) && + ? props.member!.server!.havePermission('ChangeNickname') || + props.member!.server!.havePermission('ChangeAvatar') + : (props.member!.server!.havePermission('ManageNicknames') || + props.member!.server!.havePermission('RemoveAvatars')) && props.member!.inferiorTo(props.member!.server!.member!)) } > {t( `app.context_menu.${ - props.user.self ? "edit_your_identity" : "edit_identity" + props.user.self ? 'edit_your_identity' : 'edit_identity' }` )} @@ -181,7 +179,7 @@ export function UserContextMenu(props: { @@ -190,13 +188,13 @@ export function UserContextMenu(props: { onClick={kickMember} destructive > - {t("app.context_menu.kick_member")} + {t('app.context_menu.kick_member')} @@ -205,7 +203,7 @@ export function UserContextMenu(props: { onClick={banMember} destructive > - {t("app.context_menu.ban_member")} + {t('app.context_menu.ban_member')} @@ -215,42 +213,42 @@ export function UserContextMenu(props: { - {t("app.context_menu.report_user")} + {t('app.context_menu.report_user')} {/* TODO: #286 show profile / message */} - + - {t("app.context_menu.add_friend")} + {t('app.context_menu.add_friend')} - + - {t("app.context_menu.remove_friend")} + {t('app.context_menu.remove_friend')} - + - {t("app.context_menu.accept_friend")} + {t('app.context_menu.accept_friend')} - + - {t("app.context_menu.reject_friend")} + {t('app.context_menu.reject_friend')} - + - {t("app.context_menu.cancel_friend")} + {t('app.context_menu.cancel_friend')} - + - {t("app.context_menu.block_user")} + {t('app.context_menu.block_user')} - + - {t("app.context_menu.unblock_user")} + {t('app.context_menu.unblock_user')} @@ -260,7 +258,7 @@ export function UserContextMenu(props: { Admin Panel - {t("app.context_menu.copy_uid")} + {t('app.context_menu.copy_uid')} ); @@ -275,7 +273,7 @@ export function floatingUserMenus( user: User, member?: ServerMember, contextMessage?: Message -): JSX.Directives["floating"] & object { +): JSX.Directives['floating'] & object { return { userCard: { user, diff --git a/packages/client/components/app/menus/index.tsx b/packages/client/components/app/menus/index.tsx index e25bf8f5..6110f9b5 100644 --- a/packages/client/components/app/menus/index.tsx +++ b/packages/client/components/app/menus/index.tsx @@ -1,5 +1,5 @@ -export { MessageContextMenu } from "./MessageContextMenu"; -export { UserContextMenu } from "./UserContextMenu"; -export { ServerContextMenu } from "./ServerContextMenu"; -export { ChannelContextMenu } from "./ChannelContextMenu"; -export { ServerSidebarContextMenu } from "./ServerSidebarContextMenu"; +export { ChannelContextMenu } from './ChannelContextMenu'; +export { MessageContextMenu } from './MessageContextMenu'; +export { ServerContextMenu } from './ServerContextMenu'; +export { ServerSidebarContextMenu } from './ServerSidebarContextMenu'; +export { UserContextMenu } from './UserContextMenu'; diff --git a/packages/client/components/auth/index.tsx b/packages/client/components/auth/index.tsx index 66bc7085..48277fbd 100644 --- a/packages/client/components/auth/index.tsx +++ b/packages/client/components/auth/index.tsx @@ -1,3 +1,3 @@ -import "../ui/styled.d.ts"; +import '../ui/styled.d.ts'; -export { AuthPage } from "./src/AuthPage"; +export { AuthPage } from './src/AuthPage'; diff --git a/packages/client/components/auth/src/AuthPage.tsx b/packages/client/components/auth/src/AuthPage.tsx index 9e6bc942..eb1293a8 100644 --- a/packages/client/components/auth/src/AuthPage.tsx +++ b/packages/client/components/auth/src/AuthPage.tsx @@ -1,41 +1,37 @@ -import { BiLogosGithub, BiLogosMastodon, BiLogosTwitter } from "solid-icons/bi"; -import { JSX } from "solid-js"; - -import { styled } from "styled-system/jsx"; - -import { useTranslation } from "@revolt/i18n"; -import { Button, iconSize } from "@revolt/ui"; - -import MdDarkMode from "@material-design-icons/svg/filled/dark_mode.svg?component-solid"; - -import background from "./background.jpg"; -import { FlowBase } from "./flows/Flow"; - +import MdDarkMode from '@material-design-icons/svg/filled/dark_mode.svg?component-solid'; +import { useTranslation } from '@revolt/i18n'; +import { Button, iconSize } from '@revolt/ui'; +import { BiLogosGithub, BiLogosMastodon, BiLogosTwitter } from 'solid-icons/bi'; +import type { JSX } from 'solid-js'; +import { styled } from 'styled-system/jsx'; + +import background from './background.jpg'; +import { FlowBase } from './flows/Flow'; /** * Authentication page layout */ -const Base = styled("div", { +const Base = styled('div', { base: { - width: "100%", - height: "100%", - padding: "40px 35px", + width: '100%', + height: '100%', + padding: '40px 35px', - userSelect: "none", - overflowY: "scroll", + userSelect: 'none', + overflowY: 'scroll', - color: "white", + color: 'white', background: `var(--url)`, - backgroundPosition: "center", - backgroundRepeat: "no-repeat", - backgroundSize: "cover", + backgroundPosition: 'center', + backgroundRepeat: 'no-repeat', + backgroundSize: 'cover', - display: "flex", - flexDirection: "column", - justifyContent: "space-between", + display: 'flex', + flexDirection: 'column', + justifyContent: 'space-between', mdDown: { - padding: "30px 20px", - background: "var(--colours-background)", + padding: '30px 20px', + background: 'var(--colours-background)', }, }, }); @@ -43,19 +39,19 @@ const Base = styled("div", { /** * Top and bottom navigation bars */ -const Nav = styled("div", { +const Nav = styled('div', { base: { - height: "32px", - display: "flex", - alignItems: "center", - flexDirection: "row", - justifyContent: "space-between", + height: '32px', + display: 'flex', + alignItems: 'center', + flexDirection: 'row', + justifyContent: 'space-between', - color: "white", - textDecoration: "none", + color: 'white', + textDecoration: 'none', mdDown: { - color: "var(--colours-foreground)", + color: 'var(--colours-foreground)', }, }, }); @@ -65,51 +61,51 @@ const Nav = styled("div", { */ const NavItems = styled(`div`, { base: { - gap: "10px", - display: "flex", - alignItems: "center", + gap: '10px', + display: 'flex', + alignItems: 'center', - fontSize: "0.9em", + fontSize: '0.9em', }, variants: { variant: { default: {}, stack: { mdDown: { - flexDirection: "column", + flexDirection: 'column', }, }, hide: { mdDown: { - display: "none", + display: 'none', }, }, }, }, defaultVariants: { - variant: "default", + variant: 'default', }, }); /** * Link with an icon inside */ -const LinkWithIcon = styled("a", { - base: { height: "24px" }, +const LinkWithIcon = styled('a', { + base: { height: '24px' }, }); /** * Middot-like bullet */ -const Bullet = styled("div", { +const Bullet = styled('div', { base: { - height: "5px", - width: "5px", - background: "grey", - borderRadius: "50%", + height: '5px', + width: '5px', + background: 'grey', + borderRadius: '50%', mdDown: { - display: "none", + display: 'none', }, }, }); @@ -117,9 +113,9 @@ const Bullet = styled("div", { /** * Revolt Wordmark */ -const Logo = styled("img", { +const Logo = styled('img', { base: { - height: "24px", + height: '24px', }, }); @@ -132,17 +128,17 @@ export function AuthPage(props: { children: JSX.Element }) { const t = useTranslation(); return ( - + {/**/} {props.children}