chore(refactor): clean up component folder structure

This commit is contained in:
Paul Makles 2022-06-12 15:24:00 +01:00
parent 645e1af6db
commit 8eefc87b05
15 changed files with 246 additions and 200 deletions

14
src/components/README.md Normal file
View file

@ -0,0 +1,14 @@
The following folders should not be added to or modified:
- `common`
- `markdown`
- `native`
- `ui`
The following are part-legacy, will remain in place and will be rewritten to some degree still:
- `navigation`
The following are mostly good to go:
- `settings`

View file

@ -0,0 +1,64 @@
import { Block } from "@styled-icons/boxicons-regular";
import { Trash } from "@styled-icons/boxicons-solid";
import { Text } from "preact-i18n";
import { useContext } from "preact/hooks";
import { CategoryButton } from "@revoltchat/ui";
import { modalController } from "../../../context/modals";
import {
LogOutContext,
useClient,
} from "../../../context/revoltjs/RevoltClient";
export default function AccountManagement() {
const logOut = useContext(LogOutContext);
const client = useClient();
const callback = (route: "disable" | "delete") => () =>
modalController.push({
type: "mfa_flow",
state: "known",
client,
callback: ({ token }) =>
client.api
.post(`/auth/account/${route}`, undefined, {
headers: {
"X-MFA-Ticket": token,
},
})
.then(() => logOut(true)),
});
return (
<>
<h3>
<Text id="app.settings.pages.account.manage.title" />
</h3>
<h5>
<Text id="app.settings.pages.account.manage.description" />
</h5>
<CategoryButton
icon={<Block size={24} color="var(--error)" />}
description={
"Disable your account. You won't be able to access it unless you contact support."
}
action="chevron"
onClick={callback("disable")}>
<Text id="app.settings.pages.account.manage.disable" />
</CategoryButton>
<CategoryButton
icon={<Trash size={24} color="var(--error)" />}
description={
"Your account will be queued for deletion, a confirmation email will be sent."
}
action="chevron"
onClick={callback("delete")}>
<Text id="app.settings.pages.account.manage.delete" />
</CategoryButton>
</>
);
}

View file

@ -0,0 +1,75 @@
import { At } from "@styled-icons/boxicons-regular";
import { Envelope, Key, Pencil } from "@styled-icons/boxicons-solid";
import { Text } from "preact-i18n";
import { useContext, useEffect, useState } from "preact/hooks";
import {
AccountDetail,
CategoryButton,
Column,
HiddenValue,
} from "@revoltchat/ui";
import { useIntermediate } from "../../../context/intermediate/Intermediate";
import {
ClientStatus,
StatusContext,
useClient,
} from "../../../context/revoltjs/RevoltClient";
export default function EditAccount() {
const client = useClient();
const status = useContext(StatusContext);
const { openScreen } = useIntermediate();
const [email, setEmail] = useState("...");
useEffect(() => {
if (email === "..." && status === ClientStatus.ONLINE) {
client.api
.get("/auth/account/")
.then((account) => setEmail(account.email));
}
}, [client, email, status]);
return (
<>
<Column group>
<AccountDetail user={client.user!} />
</Column>
{(
[
["username", client.user!.username, At],
["email", email, Envelope],
["password", "•••••••••", Key],
] as const
).map(([field, value, Icon]) => (
<CategoryButton
key={field}
icon={<Icon size={24} />}
description={
field === "email" ? (
<HiddenValue
value={value}
placeholder={"•••••••••••@••••••.•••"}
/>
) : (
value
)
}
account
action={<Pencil size={20} />}
onClick={() =>
openScreen({
id: "modify_account",
field,
})
}>
<Text id={`login.${field}`} />
</CategoryButton>
))}
</>
);
}

View file

@ -0,0 +1,37 @@
import { Lock } from "@styled-icons/boxicons-solid";
import { Text } from "preact-i18n";
import { CategoryButton } from "@revoltchat/ui";
export default function MultiFactorAuthentication() {
return (
<>
<h3>
<Text id="app.settings.pages.account.2fa.title" />
</h3>
<h5>
{/*<Text id="app.settings.pages.account.2fa.description" />*/}
Two-factor authentication is currently in-development, see{" "}
<a href="https://github.com/revoltchat/revite/issues/675">
tracking issue here
</a>
.
</h5>
<CategoryButton
icon={<Lock size={24} color="var(--error)" />}
description={"Set up 2FA on your account."}
disabled
action={<Text id="general.unavailable" />}>
Set up Two-factor authentication
</CategoryButton>
{/*<CategoryButton
icon={<ListOl size={24} />}
description={"View and download your 2FA backup codes."}
disabled
action="chevron">
View my backup codes
</CategoryButton>*/}
</>
);
}

View file

@ -2,10 +2,10 @@ import styled from "styled-components/macro";
import { Text } from "preact-i18n"; import { Text } from "preact-i18n";
import mutantSVG from "./mutant_emoji.svg"; import mutantSVG from "./assets/mutant_emoji.svg";
import notoSVG from "./noto_emoji.svg"; import notoSVG from "./assets/noto_emoji.svg";
import openmojiSVG from "./openmoji_emoji.svg"; import openmojiSVG from "./assets/openmoji_emoji.svg";
import twemojiSVG from "./twemoji_emoji.svg"; import twemojiSVG from "./assets/twemoji_emoji.svg";
import { EmojiPack } from "../../common/Emoji"; import { EmojiPack } from "../../common/Emoji";

View file

@ -14,9 +14,9 @@ import {
Radio, Radio,
} from "@revoltchat/ui"; } from "@revoltchat/ui";
import TextAreaAutoSize from "../../lib/TextAreaAutoSize"; import TextAreaAutoSize from "../../../lib/TextAreaAutoSize";
import { useApplicationState } from "../../mobx/State"; import { useApplicationState } from "../../../mobx/State";
import { import {
Fonts, Fonts,
@ -25,15 +25,15 @@ import {
MonospaceFonts, MonospaceFonts,
MONOSPACE_FONTS, MONOSPACE_FONTS,
MONOSPACE_FONT_KEYS, MONOSPACE_FONT_KEYS,
} from "../../context/Theme"; } from "../../../context/Theme";
import { EmojiSelector } from "./appearance/EmojiSelector"; import { EmojiSelector } from "./EmojiSelector";
import { ThemeBaseSelector } from "./appearance/ThemeBaseSelector"; import { ThemeBaseSelector } from "./ThemeBaseSelector";
/** /**
* Component providing a way to switch the base theme being used. * Component providing a way to switch the base theme being used.
*/ */
export const ThemeBaseSelectorShim = observer(() => { export const ShimThemeBaseSelector = observer(() => {
const theme = useApplicationState().settings.theme; const theme = useApplicationState().settings.theme;
return ( return (
<ThemeBaseSelector <ThemeBaseSelector
@ -49,9 +49,8 @@ export const ThemeBaseSelectorShim = observer(() => {
/** /**
* Component providing a link to the theme shop. * Component providing a link to the theme shop.
* Only appears if experiment is enabled. * Only appears if experiment is enabled.
* TODO: stabilise
*/ */
export const ThemeShopShim = () => { export const ShimThemeShop = () => {
return ( return (
<Link to="/discover/themes" replace> <Link to="/discover/themes" replace>
<CategoryButton <CategoryButton
@ -69,7 +68,7 @@ export const ThemeShopShim = () => {
/** /**
* Component providing a way to change current accent colour. * Component providing a way to change current accent colour.
*/ */
export const ThemeAccentShim = observer(() => { export const ShimThemeAccent = observer(() => {
const theme = useApplicationState().settings.theme; const theme = useApplicationState().settings.theme;
return ( return (
<> <>
@ -90,7 +89,7 @@ export const ThemeAccentShim = observer(() => {
/** /**
* Component providing a way to edit custom CSS. * Component providing a way to edit custom CSS.
*/ */
export const ThemeCustomCSSShim = observer(() => { export const ShimThemeCustomCSS = observer(() => {
const theme = useApplicationState().settings.theme; const theme = useApplicationState().settings.theme;
return ( return (
<> <>
@ -111,7 +110,7 @@ export const ThemeCustomCSSShim = observer(() => {
/** /**
* Component providing a way to switch between compact and normal message view. * Component providing a way to switch between compact and normal message view.
*/ */
export const DisplayCompactShim = () => { export const ShimDisplayCompact = () => {
// TODO: WIP feature // TODO: WIP feature
return ( return (
<> <>
@ -146,7 +145,7 @@ export const DisplayCompactShim = () => {
/** /**
* Component providing a way to change primary text font. * Component providing a way to change primary text font.
*/ */
export const DisplayFontShim = observer(() => { export const ShimDisplayFont = observer(() => {
const theme = useApplicationState().settings.theme; const theme = useApplicationState().settings.theme;
return ( return (
<> <>
@ -169,7 +168,7 @@ export const DisplayFontShim = observer(() => {
/** /**
* Component providing a way to change secondary, monospace text font. * Component providing a way to change secondary, monospace text font.
*/ */
export const DisplayMonospaceFontShim = observer(() => { export const ShimDisplayMonospaceFont = observer(() => {
const theme = useApplicationState().settings.theme; const theme = useApplicationState().settings.theme;
return ( return (
<> <>
@ -199,7 +198,7 @@ export const DisplayMonospaceFontShim = observer(() => {
/** /**
* Component providing a way to toggle font ligatures. * Component providing a way to toggle font ligatures.
*/ */
export const DisplayLigaturesShim = observer(() => { export const ShimDisplayLigatures = observer(() => {
const settings = useApplicationState().settings; const settings = useApplicationState().settings;
if (settings.theme.getFont() !== "Inter") return null; if (settings.theme.getFont() !== "Inter") return null;
@ -220,7 +219,7 @@ export const DisplayLigaturesShim = observer(() => {
/** /**
* Component providing a way to toggle showing the send button on desktop. * Component providing a way to toggle showing the send button on desktop.
*/ */
export const ShowSendButtonShim = observer(() => { export const ShimShowSendButton = observer(() => {
const settings = useApplicationState().settings; const settings = useApplicationState().settings;
return ( return (
@ -240,7 +239,7 @@ export const ShowSendButtonShim = observer(() => {
/** /**
* Component providing a way to toggle seasonal themes. * Component providing a way to toggle seasonal themes.
*/ */
export const DisplaySeasonalShim = observer(() => { export const ShimDisplaySeasonal = observer(() => {
const settings = useApplicationState().settings; const settings = useApplicationState().settings;
return ( return (
@ -260,7 +259,7 @@ export const DisplaySeasonalShim = observer(() => {
/** /**
* Component providing a way to toggle transparency effects. * Component providing a way to toggle transparency effects.
*/ */
export const DisplayTransparencyShim = observer(() => { export const ShimDisplayTransparency = observer(() => {
const settings = useApplicationState().settings; const settings = useApplicationState().settings;
return ( return (
@ -280,7 +279,7 @@ export const DisplayTransparencyShim = observer(() => {
/** /**
* Component providing a way to change emoji pack. * Component providing a way to change emoji pack.
*/ */
export const DisplayEmojiShim = observer(() => { export const ShimDisplayEmoji = observer(() => {
const settings = useApplicationState().settings; const settings = useApplicationState().settings;
return ( return (
<EmojiSelector <EmojiSelector

View file

@ -2,8 +2,8 @@ import styled from "styled-components/macro";
import { Text } from "preact-i18n"; import { Text } from "preact-i18n";
import darkSVG from "./dark.svg"; import darkSVG from "./assets/dark.svg";
import lightSVG from "./light.svg"; import lightSVG from "./assets/light.svg";
const List = styled.div` const List = styled.div`
gap: 8px; gap: 8px;

View file

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View file

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View file

Before

Width:  |  Height:  |  Size: 4.9 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

View file

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View file

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

View file

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

View file

@ -1,168 +1,25 @@
import { At, Key, Block } from "@styled-icons/boxicons-regular";
import { Envelope, Lock, Trash, Pencil } from "@styled-icons/boxicons-solid";
import { observer } from "mobx-react-lite";
import { Link } from "react-router-dom"; import { Link } from "react-router-dom";
import styles from "./Panes.module.scss"; import styles from "./Panes.module.scss";
import { Text } from "preact-i18n"; import { Text } from "preact-i18n";
import { useContext, useEffect, useState } from "preact/hooks";
import { import { Tip } from "@revoltchat/ui";
AccountDetail,
CategoryButton,
Column,
HiddenValue,
Tip,
} from "@revoltchat/ui";
import { useIntermediate } from "../../../context/intermediate/Intermediate"; import AccountManagement from "../../../components/settings/account/AccountManagement";
import { modalController } from "../../../context/modals"; import EditAccount from "../../../components/settings/account/EditAccount";
import { import MultiFactorAuthentication from "../../../components/settings/account/MultiFactorAuthentication";
ClientStatus,
LogOutContext,
StatusContext,
useClient,
} from "../../../context/revoltjs/RevoltClient";
export const Account = observer(() => {
const { openScreen } = useIntermediate();
const logOut = useContext(LogOutContext);
const status = useContext(StatusContext);
const client = useClient();
const [email, setEmail] = useState("...");
useEffect(() => {
if (email === "..." && status === ClientStatus.ONLINE) {
client.api
.get("/auth/account/")
.then((account) => setEmail(account.email));
}
}, [client, email, status]);
export function Account() {
return ( return (
<div className={styles.user}> <div className={styles.user}>
<Column group> <EditAccount />
<AccountDetail user={client.user!} />
</Column>
{(
[
["username", client.user!.username, At],
["email", email, Envelope],
["password", "•••••••••", Key],
] as const
).map(([field, value, Icon]) => (
<CategoryButton
key={field}
icon={<Icon size={24} />}
description={
field === "email" ? (
<HiddenValue
value={value}
placeholder={"•••••••••••@••••••.•••"}
/>
) : (
value
)
}
account
action={<Pencil size={20} />}
onClick={() =>
openScreen({
id: "modify_account",
field,
})
}>
<Text id={`login.${field}`} />
</CategoryButton>
))}
<hr /> <hr />
<h3> <MultiFactorAuthentication />
<Text id="app.settings.pages.account.2fa.title" />
</h3>
<h5>
{/*<Text id="app.settings.pages.account.2fa.description" />*/}
Two-factor authentication is currently in-development, see{" "}
<a href="https://github.com/revoltchat/revite/issues/675">
tracking issue here
</a>
.
</h5>
<CategoryButton
icon={<Lock size={24} color="var(--error)" />}
description={"Set up 2FA on your account."}
disabled
action={<Text id="general.unavailable" />}>
Set up Two-factor authentication
</CategoryButton>
{/*<CategoryButton
icon={<ListOl size={24} />}
description={"View and download your 2FA backup codes."}
disabled
action="chevron">
View my backup codes
</CategoryButton>*/}
<hr /> <hr />
<h3> <AccountManagement />
<Text id="app.settings.pages.account.manage.title" /> <hr />
</h3>
<h5>
<Text id="app.settings.pages.account.manage.description" />
</h5>
<CategoryButton
icon={<Block size={24} color="var(--error)" />}
description={
"Disable your account. You won't be able to access it unless you contact support."
}
action="chevron"
onClick={() =>
modalController.push({
type: "mfa_flow",
state: "known",
client,
callback: ({ token }) =>
client.api
.post("/auth/account/disable", undefined, {
headers: {
"X-MFA-Ticket": token,
},
})
.then(() => logOut(true)),
})
}>
<Text id="app.settings.pages.account.manage.disable" />
</CategoryButton>
<CategoryButton
icon={<Trash size={24} color="var(--error)" />}
description={
"Your account will be queued for deletion, a confirmation email will be sent."
}
action="chevron"
onClick={() =>
modalController.push({
type: "mfa_flow",
state: "known",
client,
callback: ({ token }) =>
client.api
.post("/auth/account/delete", undefined, {
headers: {
"X-MFA-Ticket": token,
},
})
.then(() => logOut(true)),
})
}>
<Text id="app.settings.pages.account.manage.delete" />
</CategoryButton>
<Tip> <Tip>
<span> <span>
@ -174,4 +31,4 @@ export const Account = observer(() => {
</Tip> </Tip>
</div> </div>
); );
}); }

View file

@ -7,46 +7,46 @@ import { Column } from "@revoltchat/ui";
import CollapsibleSection from "../../../components/common/CollapsibleSection"; import CollapsibleSection from "../../../components/common/CollapsibleSection";
import { import {
ThemeBaseSelectorShim, ShimThemeBaseSelector,
ThemeShopShim, ShimThemeShop,
ThemeAccentShim, ShimThemeAccent,
DisplayFontShim, ShimDisplayFont,
DisplayMonospaceFontShim, ShimDisplayMonospaceFont,
DisplayLigaturesShim, ShimDisplayLigatures,
DisplayEmojiShim, ShimDisplayEmoji,
ThemeCustomCSSShim, ShimThemeCustomCSS,
DisplaySeasonalShim, ShimDisplaySeasonal,
DisplayTransparencyShim, ShimDisplayTransparency,
ShowSendButtonShim, ShimShowSendButton,
} from "../../../components/settings/AppearanceShims"; } from "../../../components/settings/appearance/Shims";
import ThemeOverrides from "../../../components/settings/appearance/ThemeOverrides"; import ThemeOverrides from "../../../components/settings/appearance/ThemeOverrides";
import ThemeTools from "../../../components/settings/appearance/ThemeTools"; import ThemeTools from "../../../components/settings/appearance/ThemeTools";
export const Appearance = observer(() => { export const Appearance = observer(() => {
return ( return (
<div className={styles.appearance}> <div className={styles.appearance}>
<ThemeBaseSelectorShim /> <ShimThemeBaseSelector />
<ThemeShopShim /> <ShimThemeShop />
<hr /> <hr />
<ThemeAccentShim /> <ShimThemeAccent />
<hr /> <hr />
<h3> <h3>
<Text id="app.settings.pages.appearance.appearance_options.title" /> <Text id="app.settings.pages.appearance.appearance_options.title" />
</h3> </h3>
<ShowSendButtonShim /> <ShimShowSendButton />
<hr /> <hr />
<h3> <h3>
<Text id="app.settings.pages.appearance.theme_options.title" /> <Text id="app.settings.pages.appearance.theme_options.title" />
</h3> </h3>
<Column> <Column>
<DisplayTransparencyShim /> <ShimDisplayTransparency />
<DisplaySeasonalShim /> <ShimDisplaySeasonal />
</Column> </Column>
<hr /> <hr />
<DisplayFontShim /> <ShimDisplayFont />
<DisplayLigaturesShim /> <ShimDisplayLigatures />
<hr /> <hr />
<DisplayEmojiShim /> <ShimDisplayEmoji />
<hr /> <hr />
<CollapsibleSection <CollapsibleSection
defaultValue={false} defaultValue={false}
@ -60,8 +60,8 @@ export const Appearance = observer(() => {
id="settings_advanced_appearance" id="settings_advanced_appearance"
defaultValue={false} defaultValue={false}
summary={<Text id="app.settings.pages.appearance.advanced" />}> summary={<Text id="app.settings.pages.appearance.advanced" />}>
<DisplayMonospaceFontShim /> <ShimDisplayMonospaceFont />
<ThemeCustomCSSShim /> <ShimThemeCustomCSS />
</CollapsibleSection> </CollapsibleSection>
</div> </div>
); );