diff --git a/package.json b/package.json index 2b793266..41b9a254 100644 --- a/package.json +++ b/package.json @@ -52,6 +52,7 @@ "@tippyjs/react": "^4.2.5", "@traptitech/markdown-it-katex": "^3.4.3", "@traptitech/markdown-it-spoiler": "^1.1.6", + "@trivago/prettier-plugin-sort-imports": "^2.0.2", "@types/lodash.defaultsdeep": "^4.6.6", "@types/lodash.isequal": "^4.5.5", "@types/markdown-it": "^12.0.2", diff --git a/src/components/common/LocaleSelector.tsx b/src/components/common/LocaleSelector.tsx index 9e68cd72..fbebe8f1 100644 --- a/src/components/common/LocaleSelector.tsx +++ b/src/components/common/LocaleSelector.tsx @@ -1,9 +1,9 @@ import ComboBox from "../ui/ComboBox"; +import { dispatch } from "../../redux"; import { connectState } from "../../redux/connector"; -import { WithDispatcher } from "../../redux/reducers"; import { LanguageEntry, Languages } from "../../context/Locale"; -type Props = WithDispatcher & { +type Props = { locale: string; }; @@ -12,8 +12,7 @@ export function LocaleSelector(props: Props) { - props.dispatcher && - props.dispatcher({ + dispatch({ type: "SET_LOCALE", locale: e.currentTarget.value as any }) @@ -37,6 +36,5 @@ export default connectState( return { locale: state.locale }; - }, - true + } ); diff --git a/src/components/common/UpdateIndicator.tsx b/src/components/common/UpdateIndicator.tsx index d6730eb6..937d6522 100644 --- a/src/components/common/UpdateIndicator.tsx +++ b/src/components/common/UpdateIndicator.tsx @@ -15,7 +15,7 @@ export default function UpdateIndicator() { return internalSubscribe('PWA', 'update', () => setPending(true)); }); - if (!pending) return; + if (!pending) return null; const theme = useContext(ThemeContext); return ( diff --git a/src/components/common/messaging/MessageBox.tsx b/src/components/common/messaging/MessageBox.tsx index b035bfa6..486f6f28 100644 --- a/src/components/common/messaging/MessageBox.tsx +++ b/src/components/common/messaging/MessageBox.tsx @@ -1,11 +1,11 @@ import { ulid } from "ulid"; import { Text } from "preact-i18n"; -import Tooltip, { PermissionTooltip } from "../Tooltip"; import { Channel } from "revolt.js"; import styled from "styled-components"; +import { dispatch } from "../../../redux"; import { defer } from "../../../lib/defer"; import IconButton from "../../ui/IconButton"; -import { X } from '@styled-icons/boxicons-regular'; +import { PermissionTooltip } from "../Tooltip"; import { Send } from '@styled-icons/boxicons-solid'; import { debounce } from "../../../lib/debounce"; import Axios, { CancelTokenSource } from "axios"; @@ -13,7 +13,6 @@ import { useTranslation } from "../../../lib/i18n"; import { Reply } from "../../../redux/reducers/queue"; import { connectState } from "../../../redux/connector"; import { SoundContext } from "../../../context/Settings"; -import { WithDispatcher } from "../../../redux/reducers"; import { takeError } from "../../../context/revoltjs/util"; import TextAreaAutoSize from "../../../lib/TextAreaAutoSize"; import AutoComplete, { useAutoComplete } from "../AutoComplete"; @@ -30,9 +29,8 @@ import { ShieldX } from "@styled-icons/boxicons-regular"; import ReplyBar from "./bars/ReplyBar"; import FilePreview from './bars/FilePreview'; -import { Styleshare } from "@styled-icons/simple-icons"; -type Props = WithDispatcher & { +type Props = { channel: Channel; draft?: string; }; @@ -77,7 +75,7 @@ const Action = styled.div` // ! FIXME: add to app config and load from app config export const CAN_UPLOAD_AT_ONCE = 5; -function MessageBox({ channel, draft, dispatcher }: Props) { +function MessageBox({ channel, draft }: Props) { const [ uploadState, setUploadState ] = useState({ type: 'none' }); const [ typing, setTyping ] = useState(false); const [ replies, setReplies ] = useState([]); @@ -102,13 +100,13 @@ function MessageBox({ channel, draft, dispatcher }: Props) { function setMessage(content?: string) { if (content) { - dispatcher({ + dispatch({ type: "SET_DRAFT", channel: channel._id, content }); } else { - dispatcher({ + dispatch({ type: "CLEAR_DRAFT", channel: channel._id }); @@ -148,7 +146,7 @@ function MessageBox({ channel, draft, dispatcher }: Props) { playSound('outbound'); const nonce = ulid(); - dispatcher({ + dispatch({ type: "QUEUE_ADD", nonce, channel: channel._id, @@ -171,7 +169,7 @@ function MessageBox({ channel, draft, dispatcher }: Props) { replies }); } catch (error) { - dispatcher({ + dispatch({ type: "QUEUE_FAIL", error: takeError(error), nonce @@ -383,7 +381,7 @@ function MessageBox({ channel, draft, dispatcher }: Props) { ) } -export default connectState>(MessageBox, (state, { channel }) => { +export default connectState>(MessageBox, (state, { channel }) => { return { draft: state.drafts[channel._id] } diff --git a/src/components/navigation/left/HomeSidebar.tsx b/src/components/navigation/left/HomeSidebar.tsx index 16e586bb..fc883f42 100644 --- a/src/components/navigation/left/HomeSidebar.tsx +++ b/src/components/navigation/left/HomeSidebar.tsx @@ -3,12 +3,12 @@ import { useContext, useEffect } from "preact/hooks"; import { Home, UserDetail, Wrench, Notepad } from "@styled-icons/boxicons-solid"; import Category from '../../ui/Category'; +import { dispatch } from "../../../redux"; import PaintCounter from "../../../lib/PaintCounter"; import UserHeader from "../../common/user/UserHeader"; import { Channels } from "revolt.js/dist/api/objects"; import { connectState } from "../../../redux/connector"; import ConnectionStatus from '../items/ConnectionStatus'; -import { WithDispatcher } from "../../../redux/reducers"; import { Unreads } from "../../../redux/reducers/unreads"; import ConditionalLink from "../../../lib/ConditionalLink"; import { mapChannelWithUnread, useUnreads } from "./common"; @@ -23,7 +23,7 @@ import { useDMs, useForceUpdate, useUsers } from "../../../context/revoltjs/hook import placeholderSVG from "../items/placeholder.svg"; -type Props = WithDispatcher & { +type Props = { unreads: Unreads; } @@ -43,7 +43,7 @@ function HomeSidebar(props: Props) { useEffect(() => { if (!channel) return; - props.dispatcher({ + dispatch({ type: 'LAST_OPENED_SET', parent: 'home', child: channel @@ -148,6 +148,5 @@ export default connectState( unreads: state.unreads }; }, - true, true ); diff --git a/src/components/navigation/left/ServerSidebar.tsx b/src/components/navigation/left/ServerSidebar.tsx index 3dd7aff9..280dd829 100644 --- a/src/components/navigation/left/ServerSidebar.tsx +++ b/src/components/navigation/left/ServerSidebar.tsx @@ -2,7 +2,6 @@ import { Redirect, useParams } from "react-router"; import { ChannelButton } from "../items/ButtonItem"; import { Channels } from "revolt.js/dist/api/objects"; import { Unreads } from "../../../redux/reducers/unreads"; -import { WithDispatcher } from "../../../redux/reducers"; import { useChannels, useForceUpdate, useServer } from "../../../context/revoltjs/hooks"; import { mapChannelWithUnread, useUnreads } from "./common"; import ConnectionStatus from '../items/ConnectionStatus'; @@ -13,6 +12,7 @@ import { attachContextMenu } from 'preact-context-menu'; import ServerHeader from "../../common/ServerHeader"; import { useEffect } from "preact/hooks"; import Category from "../../ui/Category"; +import { dispatch } from "../../../redux"; import ConditionalLink from "../../../lib/ConditionalLink"; import CollapsibleSection from "../../common/CollapsibleSection"; @@ -43,7 +43,7 @@ const ServerList = styled.div` } `; -function ServerSidebar(props: Props & WithDispatcher) { +function ServerSidebar(props: Props) { const { server: server_id, channel: channel_id } = useParams<{ server?: string, channel?: string }>(); const ctx = useForceUpdate(); @@ -61,7 +61,7 @@ function ServerSidebar(props: Props & WithDispatcher) { useEffect(() => { if (!channel_id) return; - props.dispatcher({ + dispatch({ type: 'LAST_OPENED_SET', parent: server_id!, child: channel_id! @@ -130,6 +130,5 @@ export default connectState( return { unreads: state.unreads }; - }, - true + } ); diff --git a/src/components/navigation/left/common.ts b/src/components/navigation/left/common.ts index 2a681d10..f7ca164f 100644 --- a/src/components/navigation/left/common.ts +++ b/src/components/navigation/left/common.ts @@ -1,15 +1,15 @@ import { Channel } from "revolt.js"; +import { dispatch } from "../../../redux"; import { useLayoutEffect } from "preact/hooks"; -import { WithDispatcher } from "../../../redux/reducers"; import { Unreads } from "../../../redux/reducers/unreads"; import { HookContext, useForceUpdate } from "../../../context/revoltjs/hooks"; -type UnreadProps = WithDispatcher & { +type UnreadProps = { channel: Channel; unreads: Unreads; } -export function useUnreads({ channel, unreads, dispatcher }: UnreadProps, context?: HookContext) { +export function useUnreads({ channel, unreads }: UnreadProps, context?: HookContext) { const ctx = useForceUpdate(context); useLayoutEffect(() => { @@ -23,7 +23,7 @@ export function useUnreads({ channel, unreads, dispatcher }: UnreadProps, contex if (target.last_message) { const message = typeof target.last_message === 'string' ? target.last_message : target.last_message._id; if (!unread || (unread && message.localeCompare(unread) > 0)) { - dispatcher({ + dispatch({ type: "UNREADS_MARK_READ", channel: channel._id, message diff --git a/src/components/navigation/right/MemberSidebar.tsx b/src/components/navigation/right/MemberSidebar.tsx index e8cc3601..303b86c0 100644 --- a/src/components/navigation/right/MemberSidebar.tsx +++ b/src/components/navigation/right/MemberSidebar.tsx @@ -2,7 +2,6 @@ import { Text } from "preact-i18n"; import { useContext, useEffect, useState } from "preact/hooks"; import { User } from "revolt.js"; -import Details from "../../../components/ui/Details"; import Category from "../../ui/Category"; import { useParams } from "react-router"; import { UserButton } from "../items/ButtonItem"; @@ -15,6 +14,7 @@ import { AppContext, ClientStatus, StatusContext } from "../../../context/revolt import { HookContext, useChannel, useForceUpdate, useUsers } from "../../../context/revoltjs/hooks"; import placeholderSVG from "../items/placeholder.svg"; +import Preloader from "../../ui/Preloader"; interface Props { ctx: HookContext @@ -130,6 +130,7 @@ export function GroupMemberSidebar({ channel, ctx }: Props & { channel: Channels export function ServerMemberSidebar({ channel, ctx }: Props & { channel: Channels.TextChannel }) { const [members, setMembers] = useState(undefined); const users = useUsers(members?.map(x => x._id.user) ?? []).filter(x => typeof x !== 'undefined', ctx) as Users.User[]; + const { openScreen } = useIntermediate(); const status = useContext(StatusContext); const client = useContext(AppContext); @@ -188,17 +189,16 @@ export function ServerMemberSidebar({ channel, ctx }: Props & { channel: Channel } /> - {users.length === 0 && } + {!members && } + {members && users.length === 0 && } {users.map( user => user && ( - // - - // + openScreen({ id: 'profile', user_id: user._id })} /> ) )} diff --git a/src/context/Theme.tsx b/src/context/Theme.tsx index 61fba717..51f42554 100644 --- a/src/context/Theme.tsx +++ b/src/context/Theme.tsx @@ -187,6 +187,9 @@ export const MONOSCAPE_FONTS: Record export const FONT_KEYS = Object.keys(FONTS).sort(); export const MONOSCAPE_FONT_KEYS = Object.keys(MONOSCAPE_FONTS).sort(); +export const DEFAULT_FONT = 'Open Sans'; +export const DEFAULT_MONO_FONT = 'Fira Code'; + // Generated from https://gitlab.insrt.uk/revolt/community/themes export const PRESETS: { [key: string]: Theme } = { light: { @@ -272,13 +275,13 @@ function Theme({ children, options }: Props) { const root = document.documentElement.style; useEffect(() => { - const font = theme.font ?? 'Inter'; + const font = theme.font ?? DEFAULT_FONT; root.setProperty('--font', `"${font}"`); FONTS[font].load(); }, [ theme.font ]); useEffect(() => { - const font = theme.monoscapeFont ?? 'Fira Code'; + const font = theme.monoscapeFont ?? DEFAULT_MONO_FONT; root.setProperty('--monoscape-font', `"${font}"`); MONOSCAPE_FONTS[font].load(); }, [ theme.monoscapeFont ]); diff --git a/src/context/revoltjs/RevoltClient.tsx b/src/context/revoltjs/RevoltClient.tsx index 08617827..ea33dfb1 100644 --- a/src/context/revoltjs/RevoltClient.tsx +++ b/src/context/revoltjs/RevoltClient.tsx @@ -2,12 +2,12 @@ import { openDB } from 'idb'; import { Client } from "revolt.js"; import { takeError } from "./util"; import { createContext } from "preact"; +import { dispatch } from '../../redux'; import { Children } from "../../types/Preact"; import { useHistory } from 'react-router-dom'; import { Route } from "revolt.js/dist/api/routes"; import { connectState } from "../../redux/connector"; import Preloader from "../../components/ui/Preloader"; -import { WithDispatcher } from "../../redux/reducers"; import { AuthState } from "../../redux/reducers/auth"; import { useEffect, useMemo, useState } from "preact/hooks"; import { useIntermediate } from '../intermediate/Intermediate'; @@ -38,12 +38,12 @@ export const AppContext = createContext(undefined as any); export const StatusContext = createContext(undefined as any); export const OperationsContext = createContext(undefined as any); -type Props = WithDispatcher & { +type Props = { auth: AuthState; children: Children; }; -function Context({ auth, children, dispatcher }: Props) { +function Context({ auth, children }: Props) { const history = useHistory(); const { openScreen } = useIntermediate(); const [status, setStatus] = useState(ClientStatus.INIT); @@ -91,7 +91,7 @@ function Context({ auth, children, dispatcher }: Props) { const onboarding = await client.login(data); setReconnectDisallowed(false); const login = () => - dispatcher({ + dispatch({ type: "LOGIN", session: client.session as any }); @@ -113,10 +113,10 @@ function Context({ auth, children, dispatcher }: Props) { } }, logout: async shouldRequest => { - dispatcher({ type: "LOGOUT" }); + dispatch({ type: "LOGOUT" }); client.reset(); - dispatcher({ type: "RESET" }); + dispatch({ type: "RESET" }); openScreen({ id: "none" }); setStatus(ClientStatus.READY); @@ -144,7 +144,7 @@ function Context({ auth, children, dispatcher }: Props) { } }, [ client, auth.active ]); - useEffect(() => registerEvents({ operations, dispatcher }, setStatus, client), [ client ]); + useEffect(() => registerEvents({ operations }, setStatus, client), [ client ]); useEffect(() => { (async () => { @@ -153,7 +153,7 @@ function Context({ auth, children, dispatcher }: Props) { } if (auth.active) { - dispatcher({ type: "QUEUE_FAIL_ALL" }); + dispatch({ type: "QUEUE_FAIL_ALL" }); const active = auth.accounts[auth.active]; client.user = client.users.get(active.session.user_id); @@ -225,6 +225,5 @@ export default connectState<{ children: Children }>( auth: state.auth, sync: state.sync }; - }, - true + } ); diff --git a/src/context/revoltjs/StateMonitor.tsx b/src/context/revoltjs/StateMonitor.tsx index 1269acc3..bffdfdbb 100644 --- a/src/context/revoltjs/StateMonitor.tsx +++ b/src/context/revoltjs/StateMonitor.tsx @@ -7,10 +7,10 @@ import { AppContext } from "./RevoltClient"; import { Typing } from "../../redux/reducers/typing"; import { useContext, useEffect } from "preact/hooks"; import { connectState } from "../../redux/connector"; -import { WithDispatcher } from "../../redux/reducers"; import { QueuedMessage } from "../../redux/reducers/queue"; +import { dispatch } from "../../redux"; -type Props = WithDispatcher & { +type Props = { messages: QueuedMessage[]; typing: Typing }; @@ -19,7 +19,7 @@ function StateMonitor(props: Props) { const client = useContext(AppContext); useEffect(() => { - props.dispatcher({ + dispatch({ type: 'QUEUE_DROP_ALL' }); }, [ ]); @@ -29,7 +29,7 @@ function StateMonitor(props: Props) { if (!msg.nonce) return; if (!props.messages.find(x => x.id === msg.nonce)) return; - props.dispatcher({ + dispatch({ type: 'QUEUE_REMOVE', nonce: msg.nonce }); @@ -47,7 +47,7 @@ function StateMonitor(props: Props) { for (let user of users) { if (+ new Date() > user.started + 5000) { - props.dispatcher({ + dispatch({ type: 'TYPING_STOP', channel, user: user.id @@ -73,6 +73,5 @@ export default connectState( messages: [...state.queue], typing: state.typing }; - }, - true + } ); diff --git a/src/context/revoltjs/SyncManager.tsx b/src/context/revoltjs/SyncManager.tsx index d3fd7ca7..285713f3 100644 --- a/src/context/revoltjs/SyncManager.tsx +++ b/src/context/revoltjs/SyncManager.tsx @@ -7,14 +7,14 @@ import { Language } from "../Locale"; import { Sync } from "revolt.js/dist/api/objects"; import { useContext, useEffect } from "preact/hooks"; import { connectState } from "../../redux/connector"; -import { WithDispatcher } from "../../redux/reducers"; import { Settings } from "../../redux/reducers/settings"; import { Notifications } from "../../redux/reducers/notifications"; import { AppContext, ClientStatus, StatusContext } from "./RevoltClient"; import { ClientboundNotification } from "revolt.js/dist/websocket/notifications"; import { DEFAULT_ENABLED_SYNC, SyncData, SyncKeys, SyncOptions } from "../../redux/reducers/sync"; +import { dispatch } from "../../redux"; -type Props = WithDispatcher & { +type Props = { settings: Settings, locale: Language, sync: SyncOptions, @@ -54,7 +54,7 @@ function SyncManager(props: Props) { client .syncFetchSettings(DEFAULT_ENABLED_SYNC.filter(x => !props.sync?.disabled?.includes(x))) .then(data => { - props.dispatcher({ + dispatch({ type: 'SYNC_UPDATE', update: mapSync(data) }); @@ -62,13 +62,13 @@ function SyncManager(props: Props) { client .syncFetchUnreads() - .then(unreads => props.dispatcher({ type: 'UNREADS_SET', unreads })); + .then(unreads => dispatch({ type: 'UNREADS_SET', unreads })); } }, [ status ]); function syncChange(key: SyncKeys, data: any) { let timestamp = + new Date(); - props.dispatcher({ + dispatch({ type: 'SYNC_SET_REVISION', key, timestamp @@ -99,7 +99,7 @@ function SyncManager(props: Props) { if (packet.type === 'UserSettingsUpdate') { let update: { [key in SyncKeys]?: [ number, SyncData[key] ] } = mapSync(packet.update, props.sync.revision); - props.dispatcher({ + dispatch({ type: 'SYNC_UPDATE', update }); @@ -122,6 +122,5 @@ export default connectState( sync: state.sync, notifications: state.notifications }; - }, - true + } ); diff --git a/src/context/revoltjs/events.ts b/src/context/revoltjs/events.ts index 806ddcef..08941512 100644 --- a/src/context/revoltjs/events.ts +++ b/src/context/revoltjs/events.ts @@ -1,11 +1,11 @@ import { ClientboundNotification } from "revolt.js/dist/websocket/notifications"; -import { WithDispatcher } from "../../redux/reducers"; import { Client, Message } from "revolt.js/dist"; import { ClientOperations, ClientStatus } from "./RevoltClient"; import { StateUpdater } from "preact/hooks"; +import { dispatch } from "../../redux"; export var preventReconnect = false; let preventUntil = 0; @@ -15,9 +15,8 @@ export function setReconnectDisallowed(allowed: boolean) { } export function registerEvents({ - operations, - dispatcher -}: { operations: ClientOperations } & WithDispatcher, setStatus: StateUpdater, client: Client) { + operations +}: { operations: ClientOperations }, setStatus: StateUpdater, client: Client) { function attemptReconnect() { if (preventReconnect) return; function reconnect() { @@ -47,7 +46,7 @@ export function registerEvents({ switch (packet.type) { case "ChannelStartTyping": { if (packet.user === client.user?._id) return; - dispatcher({ + dispatch({ type: "TYPING_START", channel: packet.id, user: packet.user @@ -56,7 +55,7 @@ export function registerEvents({ } case "ChannelStopTyping": { if (packet.user === client.user?._id) return; - dispatcher({ + dispatch({ type: "TYPING_STOP", channel: packet.id, user: packet.user @@ -64,7 +63,7 @@ export function registerEvents({ break; } case "ChannelAck": { - dispatcher({ + dispatch({ type: "UNREADS_MARK_READ", channel: packet.id, message: packet.message_id @@ -76,7 +75,7 @@ export function registerEvents({ message: (message: Message) => { if (message.mentions?.includes(client.user!._id)) { - dispatcher({ + dispatch({ type: "UNREADS_MENTION", channel: message.channel, message: message._id diff --git a/src/lib/ContextMenus.tsx b/src/lib/ContextMenus.tsx index 7252d8ba..5c5769f9 100644 --- a/src/lib/ContextMenus.tsx +++ b/src/lib/ContextMenus.tsx @@ -10,7 +10,6 @@ import { } from "preact-context-menu"; import { ChannelPermission, ServerPermission, UserPermission } from "revolt.js/dist/api/permissions"; import { QueuedMessage } from "../redux/reducers/queue"; -import { WithDispatcher } from "../redux/reducers"; import { useIntermediate } from "../context/intermediate/Intermediate"; import { AppContext, ClientStatus, StatusContext } from "../context/revoltjs/RevoltClient"; import { takeError } from "../context/revoltjs/util"; @@ -24,6 +23,7 @@ import { Cog } from "@styled-icons/boxicons-solid"; import { getNotificationState, Notifications, NotificationState } from "../redux/reducers/notifications"; import UserStatus from "../components/common/user/UserStatus"; import IconButton from "../components/ui/IconButton"; +import { dispatch } from "../redux"; interface ContextMenuData { user?: string; @@ -81,7 +81,7 @@ type Action = | { action: "open_server_channel_settings", server: string, id: string } | { action: "set_notification_state", key: string, state?: NotificationState }; -type Props = WithDispatcher & { +type Props = { notifications: Notifications }; @@ -110,7 +110,7 @@ function ContextMenus(props: Props) { data.channel.channel_type === 'VoiceChannel') return; let message = data.channel.channel_type === 'TextChannel' ? data.channel.last_message : data.channel.last_message._id; - props.dispatcher({ + dispatch({ type: "UNREADS_MARK_READ", channel: data.channel._id, message @@ -124,7 +124,7 @@ function ContextMenus(props: Props) { { const nonce = data.message.id; const fail = (error: any) => - props.dispatcher({ + dispatch({ type: "QUEUE_FAIL", nonce, error @@ -141,7 +141,7 @@ function ContextMenus(props: Props) { ) .catch(fail); - props.dispatcher({ + dispatch({ type: "QUEUE_START", nonce }); @@ -150,7 +150,7 @@ function ContextMenus(props: Props) { case "cancel_message": { - props.dispatcher({ + dispatch({ type: "QUEUE_REMOVE", nonce: data.message.id }); @@ -326,9 +326,9 @@ function ContextMenus(props: Props) { case "set_notification_state": { const { key, state } = data; if (state) { - props.dispatcher({ type: "NOTIFICATIONS_SET", key, state }); + dispatch({ type: "NOTIFICATIONS_SET", key, state }); } else { - props.dispatcher({ type: "NOTIFICATIONS_REMOVE", key }); + dispatch({ type: "NOTIFICATIONS_REMOVE", key }); } break; } @@ -758,6 +758,5 @@ export default connectState( return { notifications: state.notifications }; - }, - true + } ); diff --git a/src/pages/settings/panes/Appearance.tsx b/src/pages/settings/panes/Appearance.tsx index 54964416..58426b31 100644 --- a/src/pages/settings/panes/Appearance.tsx +++ b/src/pages/settings/panes/Appearance.tsx @@ -6,14 +6,13 @@ import Checkbox from "../../../components/ui/Checkbox"; import ComboBox from "../../../components/ui/ComboBox"; import InputBox from "../../../components/ui/InputBox"; import { connectState } from "../../../redux/connector"; -import { WithDispatcher } from "../../../redux/reducers"; import TextAreaAutoSize from "../../../lib/TextAreaAutoSize"; import ColourSwatches from "../../../components/ui/ColourSwatches"; import { EmojiPacks, Settings } from "../../../redux/reducers/settings"; import { useCallback, useContext, useEffect, useState } from "preact/hooks"; import { useIntermediate } from "../../../context/intermediate/Intermediate"; import CollapsibleSection from "../../../components/common/CollapsibleSection"; -import { FONTS, FONT_KEYS, MONOSCAPE_FONTS, MONOSCAPE_FONT_KEYS, Theme, ThemeContext, ThemeOptions } from "../../../context/Theme"; +import { DEFAULT_FONT, DEFAULT_MONO_FONT, FONTS, FONT_KEYS, MONOSCAPE_FONTS, MONOSCAPE_FONT_KEYS, Theme, ThemeContext, ThemeOptions } from "../../../context/Theme"; // @ts-ignore import pSBC from 'shade-blend-color'; @@ -25,25 +24,26 @@ import mutantSVG from '../assets/mutant_emoji.svg'; import notoSVG from '../assets/noto_emoji.svg'; import openmojiSVG from '../assets/openmoji_emoji.svg'; import twemojiSVG from '../assets/twemoji_emoji.svg'; +import { dispatch } from "../../../redux"; interface Props { settings: Settings; } // ! FIXME: code needs to be rewritten to fix jittering -export function Component(props: Props & WithDispatcher) { +export function Component(props: Props) { const theme = useContext(ThemeContext); const { writeClipboard, openScreen } = useIntermediate(); function setTheme(theme: ThemeOptions) { - props.dispatcher({ + dispatch({ type: "SETTINGS_SET_THEME", theme }); } function pushOverride(custom: Partial) { - props.dispatcher({ + dispatch({ type: "SETTINGS_SET_THEME_OVERRIDE", custom }); @@ -58,7 +58,7 @@ export function Component(props: Props & WithDispatcher) { const emojiPack = props.settings.appearance?.emojiPack ?? 'mutant'; function setEmojiPack(emojiPack: EmojiPacks) { - props.dispatcher({ + dispatch({ type: 'SETTINGS_SET_APPEARANCE', options: { emojiPack @@ -135,7 +135,7 @@ export function Component(props: Props & WithDispatcher) {

- setTheme({ custom: { font: e.currentTarget.value as any } })}> + setTheme({ custom: { font: e.currentTarget.value as any } })}> { FONT_KEYS .map(key => @@ -285,7 +285,7 @@ export function Component(props: Props & WithDispatcher) {

- setTheme({ custom: { monoscapeFont: e.currentTarget.value as any } })}> + setTheme({ custom: { monoscapeFont: e.currentTarget.value as any } })}> { MONOSCAPE_FONT_KEYS .map(key => @@ -314,6 +314,5 @@ export const Appearance = connectState( return { settings: state.settings }; - }, - true + } ); diff --git a/src/pages/settings/panes/Experiments.tsx b/src/pages/settings/panes/Experiments.tsx index 5d3d6ee9..c5dee4a9 100644 --- a/src/pages/settings/panes/Experiments.tsx +++ b/src/pages/settings/panes/Experiments.tsx @@ -1,15 +1,15 @@ import { Text } from "preact-i18n"; import styles from "./Panes.module.scss"; +import { dispatch } from "../../../redux"; import Checkbox from "../../../components/ui/Checkbox"; import { connectState } from "../../../redux/connector"; -import { WithDispatcher } from "../../../redux/reducers"; import { AVAILABLE_EXPERIMENTS, ExperimentOptions } from "../../../redux/reducers/experiments"; interface Props { options?: ExperimentOptions; } -export function Component(props: Props & WithDispatcher) { +export function Component(props: Props) { return (

@@ -20,12 +20,12 @@ export function Component(props: Props & WithDispatcher) { key => -1} - onChange={enabled => { - props.dispatcher({ + onChange={enabled => + dispatch({ type: enabled ? 'EXPERIMENTS_ENABLE' : 'EXPERIMENTS_DISABLE', key - }); - }} + }) + } >

@@ -51,6 +51,5 @@ export const ExperimentsPage = connectState( return { options: state.experiments }; - }, - true + } ); diff --git a/src/pages/settings/panes/Languages.tsx b/src/pages/settings/panes/Languages.tsx index e7ae6bf9..077391a5 100644 --- a/src/pages/settings/panes/Languages.tsx +++ b/src/pages/settings/panes/Languages.tsx @@ -1,19 +1,19 @@ import { Text } from "preact-i18n"; import styles from "./Panes.module.scss"; +import { dispatch } from "../../../redux"; import Tip from "../../../components/ui/Tip"; import Emoji from "../../../components/common/Emoji"; import Checkbox from "../../../components/ui/Checkbox"; import { connectState } from "../../../redux/connector"; -import { WithDispatcher } from "../../../redux/reducers"; import { Language, LanguageEntry, Languages as Langs } from "../../../context/Locale"; -type Props = WithDispatcher & { +type Props = { locale: Language; } type Key = [ string, LanguageEntry ]; -function Entry({ entry: [ x, lang ], locale, dispatcher }: { entry: Key } & Props) { +function Entry({ entry: [ x, lang ], locale }: { entry: Key } & Props) { return ( { if (v) { - dispatcher({ + dispatch({ type: "SET_LOCALE", locale: x as Language }); @@ -80,6 +80,5 @@ export const Languages = connectState( return { locale: state.locale }; - }, - true + } ); diff --git a/src/pages/settings/panes/Notifications.tsx b/src/pages/settings/panes/Notifications.tsx index 9f1e3018..ae3c1657 100644 --- a/src/pages/settings/panes/Notifications.tsx +++ b/src/pages/settings/panes/Notifications.tsx @@ -1,9 +1,9 @@ import { Text } from "preact-i18n"; import styles from "./Panes.module.scss"; +import { dispatch } from "../../../redux"; import defaultsDeep from "lodash.defaultsdeep"; import Checkbox from "../../../components/ui/Checkbox"; import { connectState } from "../../../redux/connector"; -import { WithDispatcher } from "../../../redux/reducers"; import { SOUNDS_ARRAY } from "../../../assets/sounds/Audio"; import { useContext, useEffect, useState } from "preact/hooks"; import { urlBase64ToUint8Array } from "../../../lib/conversion"; @@ -15,7 +15,7 @@ interface Props { options?: NotificationOptions; } -export function Component({ options, dispatcher }: Props & WithDispatcher) { +export function Component({ options }: Props) { const client = useContext(AppContext); const { openScreen } = useIntermediate(); const [pushEnabled, setPushEnabled] = useState( @@ -51,7 +51,7 @@ export function Component({ options, dispatcher }: Props & WithDispatcher) { } } - dispatcher({ + dispatch({ type: "SETTINGS_SET_NOTIFICATION_OPTIONS", options: { desktopEnabled } }); @@ -107,7 +107,7 @@ export function Component({ options, dispatcher }: Props & WithDispatcher) { - dispatcher({ + dispatch({ type: "SETTINGS_SET_NOTIFICATION_OPTIONS", options: { sounds: { @@ -131,6 +131,5 @@ export const Notifications = connectState( return { options: state.settings.notification }; - }, - true + } ); diff --git a/src/pages/settings/panes/Sync.tsx b/src/pages/settings/panes/Sync.tsx index 2055016b..20d51136 100644 --- a/src/pages/settings/panes/Sync.tsx +++ b/src/pages/settings/panes/Sync.tsx @@ -1,15 +1,15 @@ import { Text } from "preact-i18n"; import styles from "./Panes.module.scss"; +import { dispatch } from "../../../redux"; import Checkbox from "../../../components/ui/Checkbox"; import { connectState } from "../../../redux/connector"; -import { WithDispatcher } from "../../../redux/reducers"; import { SyncKeys, SyncOptions } from "../../../redux/reducers/sync"; interface Props { options?: SyncOptions; } -export function Component(props: Props & WithDispatcher) { +export function Component(props: Props) { return (

@@ -26,12 +26,12 @@ export function Component(props: Props & WithDispatcher) { } - onChange={enabled => { - props.dispatcher({ + onChange={enabled => + dispatch({ type: enabled ? 'SYNC_ENABLE_KEY' : 'SYNC_DISABLE_KEY', key - }); - }} + }) + } > @@ -47,6 +47,5 @@ export const Sync = connectState( return { options: state.sync }; - }, - true + } ); diff --git a/src/pages/settings/server/Roles.tsx b/src/pages/settings/server/Roles.tsx index 0fea1988..a1391929 100644 --- a/src/pages/settings/server/Roles.tsx +++ b/src/pages/settings/server/Roles.tsx @@ -30,7 +30,7 @@ export function Roles({ server }: Props) { if (role !== 'default' && typeof roles[role] === 'undefined') { useEffect(() => setRole('default')); - return; + return null; } const v = (id: string) => I32ToU32(id === 'default' ? server.default_permissions : roles[id].permissions) diff --git a/src/redux/State.tsx b/src/redux/State.tsx index c7f8575d..2b3576ff 100644 --- a/src/redux/State.tsx +++ b/src/redux/State.tsx @@ -1,7 +1,7 @@ -import { store } from "."; import localForage from "localforage"; import { Provider } from "react-redux"; import { Children } from "../types/Preact"; +import { dispatch, State, store } from "."; import { useEffect, useState } from "preact/hooks"; interface Props { @@ -15,7 +15,7 @@ export default function State(props: Props) { localForage.getItem("state") .then(state => { if (state !== null) { - store.dispatch({ type: "__INIT", state }); + dispatch({ type: "__INIT", state: state as State }); } setLoaded(true); diff --git a/src/redux/connector.tsx b/src/redux/connector.tsx index 06ee1d91..6d9075ca 100644 --- a/src/redux/connector.tsx +++ b/src/redux/connector.tsx @@ -8,16 +8,8 @@ import { connect, ConnectedComponent } from "react-redux"; export function connectState( component: (props: any) => h.JSX.Element | null, mapKeys: (state: State, props: T) => any, - useDispatcher?: boolean, memoize?: boolean ): ConnectedComponent<(props: any) => h.JSX.Element | null, T> { - let c = ( - useDispatcher - ? connect(mapKeys, (dispatcher) => { - return { dispatcher }; - }) - : connect(mapKeys) - )(component); - + let c = connect(mapKeys)(component); return memoize ? memo(c) : c; } diff --git a/src/redux/index.ts b/src/redux/index.ts index 4bee0dcd..e57d60ea 100644 --- a/src/redux/index.ts +++ b/src/redux/index.ts @@ -1,6 +1,6 @@ import { createStore } from "redux"; -import rootReducer from "./reducers"; import localForage from "localforage"; +import rootReducer, { Action } from "./reducers"; import { Core } from "revolt.js/dist/api/objects"; import { Typing } from "./reducers/typing"; @@ -77,3 +77,7 @@ store.subscribe(() => { sectionToggle }); }); + +export function dispatch(action: Action) { + store.dispatch(action); +} diff --git a/src/redux/reducers/index.ts b/src/redux/reducers/index.ts index baf217dc..15b7e362 100644 --- a/src/redux/reducers/index.ts +++ b/src/redux/reducers/index.ts @@ -47,8 +47,6 @@ export type Action = | SectionToggleAction | { type: "__INIT"; state: State }; -export type WithDispatcher = { dispatcher: (action: Action) => void }; - // eslint-disable-next-line @typescript-eslint/no-explicit-any export function filter(obj: any, keys: string[]) { // eslint-disable-next-line @typescript-eslint/no-explicit-any diff --git a/yarn.lock b/yarn.lock index c3f2ec5c..9362c74f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9,7 +9,7 @@ dependencies: "@babel/highlight" "^7.10.4" -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.14.5": +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.14.5": version "7.14.5" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.14.5.tgz#23b08d740e83f49c5e59945fbf1b43e80bbf4edb" integrity sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw== @@ -21,6 +21,28 @@ resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.14.5.tgz#8ef4c18e58e801c5c95d3c1c0f2874a2680fadea" integrity sha512-kixrYn4JwfAVPa0f2yfzc2AWti6WRRyO3XjWW5PJAvtE11qhSayrrcrEnee05KAtNaPC+EwehE8Qt1UedEVB8w== +"@babel/core@7.13.10": + version "7.13.10" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.13.10.tgz#07de050bbd8193fcd8a3c27918c0890613a94559" + integrity sha512-bfIYcT0BdKeAZrovpMqX2Mx5NrgAckGbwT982AkdS5GNfn3KMGiprlBAtmBcFZRUmpaufS6WZFP8trvx8ptFDw== + dependencies: + "@babel/code-frame" "^7.12.13" + "@babel/generator" "^7.13.9" + "@babel/helper-compilation-targets" "^7.13.10" + "@babel/helper-module-transforms" "^7.13.0" + "@babel/helpers" "^7.13.10" + "@babel/parser" "^7.13.10" + "@babel/template" "^7.12.13" + "@babel/traverse" "^7.13.0" + "@babel/types" "^7.13.0" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.1.2" + lodash "^4.17.19" + semver "^6.3.0" + source-map "^0.5.0" + "@babel/core@^7.11.1", "@babel/core@^7.9.6": version "7.14.6" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.14.6.tgz#e0814ec1a950032ff16c13a2721de39a8416fcab" @@ -42,7 +64,16 @@ semver "^6.3.0" source-map "^0.5.0" -"@babel/generator@^7.14.5": +"@babel/generator@7.13.9": + version "7.13.9" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.13.9.tgz#3a7aa96f9efb8e2be42d38d80e2ceb4c64d8de39" + integrity sha512-mHOOmY0Axl/JCTkxTU6Lf5sWOg/v8nUa+Xkt4zMTftX0wqmb6Sh7J8gvcehBw7q0AhrhAR+FDacKjCZ2X8K+Sw== + dependencies: + "@babel/types" "^7.13.0" + jsesc "^2.5.1" + source-map "^0.5.0" + +"@babel/generator@^7.13.0", "@babel/generator@^7.13.9", "@babel/generator@^7.14.5": version "7.14.5" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.14.5.tgz#848d7b9f031caca9d0cd0af01b063f226f52d785" integrity sha512-y3rlP+/G25OIX3mYKKIOlQRcqj7YgrvHxOLbVmyLJ9bPmi5ttvUmpydVjcFjZphOktWuA7ovbx91ECloWTfjIA== @@ -66,7 +97,7 @@ "@babel/helper-explode-assignable-expression" "^7.14.5" "@babel/types" "^7.14.5" -"@babel/helper-compilation-targets@^7.13.0", "@babel/helper-compilation-targets@^7.14.5": +"@babel/helper-compilation-targets@^7.13.0", "@babel/helper-compilation-targets@^7.13.10", "@babel/helper-compilation-targets@^7.14.5": version "7.14.5" resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.14.5.tgz#7a99c5d0967911e972fe2c3411f7d5b498498ecf" integrity sha512-v+QtZqXEiOnpO6EYvlImB6zCD2Lel06RzOPzmkz/D/XgQiUu3C/Jb1LOqSt/AIA34TYi/Q+KlT8vTQrgdxkbLw== @@ -117,7 +148,7 @@ dependencies: "@babel/types" "^7.14.5" -"@babel/helper-function-name@^7.14.5": +"@babel/helper-function-name@^7.12.13", "@babel/helper-function-name@^7.14.5": version "7.14.5" resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz#89e2c474972f15d8e233b52ee8c480e2cfcd50c4" integrity sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ== @@ -154,7 +185,7 @@ dependencies: "@babel/types" "^7.14.5" -"@babel/helper-module-transforms@^7.14.5": +"@babel/helper-module-transforms@^7.13.0", "@babel/helper-module-transforms@^7.14.5": version "7.14.5" resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.14.5.tgz#7de42f10d789b423eb902ebd24031ca77cb1e10e" integrity sha512-iXpX4KW8LVODuAieD7MzhNjmM6dzYY5tfRqT+R9HDXWl0jPn/djKmA+G9s/2C2T9zggw5tK1QNqZ70USfedOwA== @@ -213,14 +244,14 @@ dependencies: "@babel/types" "^7.14.5" -"@babel/helper-split-export-declaration@^7.14.5": +"@babel/helper-split-export-declaration@^7.12.13", "@babel/helper-split-export-declaration@^7.14.5": version "7.14.5" resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.14.5.tgz#22b23a54ef51c2b7605d851930c1976dd0bc693a" integrity sha512-hprxVPu6e5Kdp2puZUmvOGjaLv9TCe58E/Fl6hRq4YiVQxIcNvuq6uTM2r1mT/oPskuS9CgR+I94sqAYv0NGKA== dependencies: "@babel/types" "^7.14.5" -"@babel/helper-validator-identifier@^7.14.5": +"@babel/helper-validator-identifier@^7.12.11", "@babel/helper-validator-identifier@^7.14.5": version "7.14.5" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz#d0f0e277c512e0c938277faa85a3968c9a44c0e8" integrity sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg== @@ -240,7 +271,7 @@ "@babel/traverse" "^7.14.5" "@babel/types" "^7.14.5" -"@babel/helpers@^7.14.6": +"@babel/helpers@^7.13.10", "@babel/helpers@^7.14.6": version "7.14.6" resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.14.6.tgz#5b58306b95f1b47e2a0199434fa8658fa6c21635" integrity sha512-yesp1ENQBiLI+iYHSJdoZKUtRpfTlL1grDIX9NRlAVppljLw/4tTyYupIB7uIYmC3stW/imAv8EqaKaS/ibmeA== @@ -258,6 +289,16 @@ chalk "^2.0.0" js-tokens "^4.0.0" +"@babel/parser@7.13.10": + version "7.13.10" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.13.10.tgz#8f8f9bf7b3afa3eabd061f7a5bcdf4fec3c48409" + integrity sha512-0s7Mlrw9uTWkYua7xWr99Wpk2bnGa0ANleKfksYAES8LpWH4gW1OUr42vqKNf0us5UQNfru2wPqMqRITzq/SIQ== + +"@babel/parser@^7.13.0", "@babel/parser@^7.13.10": + version "7.14.7" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.14.7.tgz#6099720c8839ca865a2637e6c85852ead0bdb595" + integrity sha512-X67Z5y+VBJuHB/RjwECp8kSl5uYi0BvRbNeWqkaJCVh+LiTPl19WBUfG627psSgp9rSf6ojuXghQM3ha6qHHdA== + "@babel/parser@^7.14.5", "@babel/parser@^7.14.6", "@babel/parser@^7.7.0": version "7.14.6" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.14.6.tgz#d85cc68ca3cac84eae384c06f032921f5227f4b2" @@ -843,7 +884,7 @@ dependencies: regenerator-runtime "^0.13.4" -"@babel/template@^7.14.5": +"@babel/template@^7.12.13", "@babel/template@^7.14.5": version "7.14.5" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.14.5.tgz#a9bc9d8b33354ff6e55a9c60d1109200a68974f4" integrity sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g== @@ -852,6 +893,21 @@ "@babel/parser" "^7.14.5" "@babel/types" "^7.14.5" +"@babel/traverse@7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.13.0.tgz#6d95752475f86ee7ded06536de309a65fc8966cc" + integrity sha512-xys5xi5JEhzC3RzEmSGrs/b3pJW/o87SypZ+G/PhaE7uqVQNv/jlmVIBXuoh5atqQ434LfXV+sf23Oxj0bchJQ== + dependencies: + "@babel/code-frame" "^7.12.13" + "@babel/generator" "^7.13.0" + "@babel/helper-function-name" "^7.12.13" + "@babel/helper-split-export-declaration" "^7.12.13" + "@babel/parser" "^7.13.0" + "@babel/types" "^7.13.0" + debug "^4.1.0" + globals "^11.1.0" + lodash "^4.17.19" + "@babel/traverse@^7.13.0", "@babel/traverse@^7.14.5", "@babel/traverse@^7.4.5", "@babel/traverse@^7.7.0": version "7.14.5" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.14.5.tgz#c111b0f58afab4fea3d3385a406f692748c59870" @@ -867,7 +923,16 @@ debug "^4.1.0" globals "^11.1.0" -"@babel/types@^7.14.5", "@babel/types@^7.4.4", "@babel/types@^7.7.0": +"@babel/types@7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.13.0.tgz#74424d2816f0171b4100f0ab34e9a374efdf7f80" + integrity sha512-hE+HE8rnG1Z6Wzo+MhaKE5lM5eMx71T4EHJgku2E3xIfaULhDcxiiRxUYgwX8qwP1BBSlag+TdGOt6JAidIZTA== + dependencies: + "@babel/helper-validator-identifier" "^7.12.11" + lodash "^4.17.19" + to-fast-properties "^2.0.0" + +"@babel/types@^7.13.0", "@babel/types@^7.14.5", "@babel/types@^7.4.4", "@babel/types@^7.7.0": version "7.14.5" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.14.5.tgz#3bb997ba829a2104cedb20689c4a5b8121d383ff" integrity sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg== @@ -1229,6 +1294,21 @@ resolved "https://registry.yarnpkg.com/@traptitech/markdown-it-spoiler/-/markdown-it-spoiler-1.1.6.tgz#973e92045699551e2c9fb39bbd673ee48bc90b83" integrity sha512-tH/Fk1WMsnSuLpuRsXw8iHtdivoCEI5V08hQ7doVm6WmzAnBf/cUzyH9+GbOldPq9Hwv9v9tuy5t/MxmdNAGXg== +"@trivago/prettier-plugin-sort-imports@^2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@trivago/prettier-plugin-sort-imports/-/prettier-plugin-sort-imports-2.0.2.tgz#62c52462220df6fb35815aaefeaa383fc2535ab1" + integrity sha512-esk6vplzXYwXQs079wBbKog4AFuZfxpJU+MygiijV0wbAibI0tEm+diFFhYP7B2lAaKKdU4+w+BW+McNZCw9HA== + dependencies: + "@babel/core" "7.13.10" + "@babel/generator" "7.13.9" + "@babel/parser" "7.13.10" + "@babel/traverse" "7.13.0" + "@babel/types" "7.13.0" + "@types/lodash" "4.14.168" + javascript-natural-sort "0.7.1" + lodash "4.17.21" + prettier "2.2.1" + "@types/debug@^4.1.5": version "4.1.5" resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.5.tgz#b14efa8852b7768d898906613c23f688713e02cd" @@ -1291,6 +1371,11 @@ resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.170.tgz#0d67711d4bf7f4ca5147e9091b847479b87925d6" integrity sha512-bpcvu/MKHHeYX+qeEN8GE7DIravODWdACVA1ctevD8CN24RhPZIKMn9ntfAsrvLfSX3cR5RrBKAbYm9bGs0A+Q== +"@types/lodash@4.14.168": + version "4.14.168" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.168.tgz#fe24632e79b7ade3f132891afff86caa5e5ce008" + integrity sha512-oVfRvqHV/V6D1yifJbVRU3TMp8OT6o6BG+U9MkwuJ3U8/CsDHvalRpsxBqivn71ztOFZBTfJMvETbqHiaNSj7Q== + "@types/markdown-it@^12.0.2": version "12.0.2" resolved "https://registry.yarnpkg.com/@types/markdown-it/-/markdown-it-12.0.2.tgz#153e5477970ed2a47b2f619ed4ab66f870de8a04" @@ -2732,6 +2817,11 @@ isomorphic-ws@^4.0.1: resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz#55fd4cd6c5e6491e76dc125938dd863f5cd4f2dc" integrity sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w== +javascript-natural-sort@0.7.1: + version "0.7.1" + resolved "https://registry.yarnpkg.com/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz#f9e2303d4507f6d74355a73664d1440fb5a0ef59" + integrity sha1-+eIwPUUH9tdDVac2ZNFED7Wg71k= + jest-worker@^26.2.1: version "26.6.2" resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-26.6.2.tgz#7f72cbc4d643c365e27b9fd775f9d0eaa9c7a8ed" @@ -2896,7 +2986,7 @@ lodash.truncate@^4.4.2: resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" integrity sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM= -lodash@^4.17.11, lodash@^4.17.15, lodash@^4.17.20, lodash@^4.17.21: +lodash@4.17.21, lodash@^4.17.11, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -3233,6 +3323,11 @@ prelude-ls@^1.2.1: resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== +prettier@2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.2.1.tgz#795a1a78dd52f073da0cd42b21f9c91381923ff5" + integrity sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q== + prettier@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.3.1.tgz#76903c3f8c4449bc9ac597acefa24dc5ad4cbea6"