Use tabWidth 4 without actual tabs.

This commit is contained in:
Paul
2021-07-05 11:25:20 +01:00
parent 7bd33d8d34
commit b5a11d5c8f
180 changed files with 16619 additions and 16622 deletions

View File

@@ -13,15 +13,15 @@ import { connectState } from "../../../redux/connector";
import { EmojiPacks, Settings } from "../../../redux/reducers/settings";
import {
DEFAULT_FONT,
DEFAULT_MONO_FONT,
FONTS,
FONT_KEYS,
MONOSCAPE_FONTS,
MONOSCAPE_FONT_KEYS,
Theme,
ThemeContext,
ThemeOptions,
DEFAULT_FONT,
DEFAULT_MONO_FONT,
FONTS,
FONT_KEYS,
MONOSCAPE_FONTS,
MONOSCAPE_FONT_KEYS,
Theme,
ThemeContext,
ThemeOptions,
} from "../../../context/Theme";
import { useIntermediate } from "../../../context/intermediate/Intermediate";
@@ -39,92 +39,92 @@ import openmojiSVG from "../assets/openmoji_emoji.svg";
import twemojiSVG from "../assets/twemoji_emoji.svg";
interface Props {
settings: Settings;
settings: Settings;
}
// ! FIXME: code needs to be rewritten to fix jittering
export function Component(props: Props) {
const theme = useContext(ThemeContext);
const { writeClipboard, openScreen } = useIntermediate();
const theme = useContext(ThemeContext);
const { writeClipboard, openScreen } = useIntermediate();
function setTheme(theme: ThemeOptions) {
dispatch({
type: "SETTINGS_SET_THEME",
theme,
});
}
function setTheme(theme: ThemeOptions) {
dispatch({
type: "SETTINGS_SET_THEME",
theme,
});
}
function pushOverride(custom: Partial<Theme>) {
dispatch({
type: "SETTINGS_SET_THEME_OVERRIDE",
custom,
});
}
function pushOverride(custom: Partial<Theme>) {
dispatch({
type: "SETTINGS_SET_THEME_OVERRIDE",
custom,
});
}
function setAccent(accent: string) {
setOverride({
accent,
"scrollbar-thumb": pSBC(-0.2, accent),
});
}
function setAccent(accent: string) {
setOverride({
accent,
"scrollbar-thumb": pSBC(-0.2, accent),
});
}
const emojiPack = props.settings.appearance?.emojiPack ?? "mutant";
function setEmojiPack(emojiPack: EmojiPacks) {
dispatch({
type: "SETTINGS_SET_APPEARANCE",
options: {
emojiPack,
},
});
}
const emojiPack = props.settings.appearance?.emojiPack ?? "mutant";
function setEmojiPack(emojiPack: EmojiPacks) {
dispatch({
type: "SETTINGS_SET_APPEARANCE",
options: {
emojiPack,
},
});
}
const setOverride = useCallback(debounce(pushOverride, 200), []) as (
custom: Partial<Theme>,
) => void;
const [css, setCSS] = useState(props.settings.theme?.custom?.css ?? "");
const setOverride = useCallback(debounce(pushOverride, 200), []) as (
custom: Partial<Theme>,
) => void;
const [css, setCSS] = useState(props.settings.theme?.custom?.css ?? "");
useEffect(() => setOverride({ css }), [css]);
useEffect(() => setOverride({ css }), [css]);
const selected = props.settings.theme?.preset ?? "dark";
return (
<div className={styles.appearance}>
<h3>
<Text id="app.settings.pages.appearance.theme" />
</h3>
<div className={styles.themes}>
<div className={styles.theme}>
<img
src={lightSVG}
data-active={selected === "light"}
onClick={() =>
selected !== "light" &&
setTheme({ preset: "light" })
}
/>
<h4>
<Text id="app.settings.pages.appearance.color.light" />
</h4>
</div>
<div className={styles.theme}>
<img
src={darkSVG}
data-active={selected === "dark"}
onClick={() =>
selected !== "dark" && setTheme({ preset: "dark" })
}
/>
<h4>
<Text id="app.settings.pages.appearance.color.dark" />
</h4>
</div>
</div>
const selected = props.settings.theme?.preset ?? "dark";
return (
<div className={styles.appearance}>
<h3>
<Text id="app.settings.pages.appearance.theme" />
</h3>
<div className={styles.themes}>
<div className={styles.theme}>
<img
src={lightSVG}
data-active={selected === "light"}
onClick={() =>
selected !== "light" &&
setTheme({ preset: "light" })
}
/>
<h4>
<Text id="app.settings.pages.appearance.color.light" />
</h4>
</div>
<div className={styles.theme}>
<img
src={darkSVG}
data-active={selected === "dark"}
onClick={() =>
selected !== "dark" && setTheme({ preset: "dark" })
}
/>
<h4>
<Text id="app.settings.pages.appearance.color.dark" />
</h4>
</div>
</div>
<h3>
<Text id="app.settings.pages.appearance.accent_selector" />
</h3>
<ColourSwatches value={theme.accent} onChange={setAccent} />
<h3>
<Text id="app.settings.pages.appearance.accent_selector" />
</h3>
<ColourSwatches value={theme.accent} onChange={setAccent} />
{/*<h3>
{/*<h3>
<Text id="app.settings.pages.appearance.message_display" />
</h3>
<div className={styles.display}>
@@ -146,229 +146,229 @@ export function Component(props: Props) {
</Radio>
</div>*/}
<h3>
<Text id="app.settings.pages.appearance.font" />
</h3>
<ComboBox
value={theme.font ?? DEFAULT_FONT}
onChange={(e) =>
setTheme({ custom: { font: e.currentTarget.value as any } })
}>
{FONT_KEYS.map((key) => (
<option value={key}>
{FONTS[key as keyof typeof FONTS].name}
</option>
))}
</ComboBox>
<p>
<Checkbox
checked={props.settings.theme?.ligatures === true}
onChange={() =>
setTheme({
ligatures: !props.settings.theme?.ligatures,
})
}
description={
<Text id="app.settings.pages.appearance.ligatures_desc" />
}>
<Text id="app.settings.pages.appearance.ligatures" />
</Checkbox>
</p>
<h3>
<Text id="app.settings.pages.appearance.font" />
</h3>
<ComboBox
value={theme.font ?? DEFAULT_FONT}
onChange={(e) =>
setTheme({ custom: { font: e.currentTarget.value as any } })
}>
{FONT_KEYS.map((key) => (
<option value={key}>
{FONTS[key as keyof typeof FONTS].name}
</option>
))}
</ComboBox>
<p>
<Checkbox
checked={props.settings.theme?.ligatures === true}
onChange={() =>
setTheme({
ligatures: !props.settings.theme?.ligatures,
})
}
description={
<Text id="app.settings.pages.appearance.ligatures_desc" />
}>
<Text id="app.settings.pages.appearance.ligatures" />
</Checkbox>
</p>
<h3>
<Text id="app.settings.pages.appearance.emoji_pack" />
</h3>
<div className={styles.emojiPack}>
<div className={styles.row}>
<div>
<div
className={styles.button}
onClick={() => setEmojiPack("mutant")}
data-active={emojiPack === "mutant"}>
<img src={mutantSVG} draggable={false} />
</div>
<h4>
Mutant Remix{" "}
<a
href="https://mutant.revolt.chat"
target="_blank">
(by Revolt)
</a>
</h4>
</div>
<div>
<div
className={styles.button}
onClick={() => setEmojiPack("twemoji")}
data-active={emojiPack === "twemoji"}>
<img src={twemojiSVG} draggable={false} />
</div>
<h4>Twemoji</h4>
</div>
</div>
<div className={styles.row}>
<div>
<div
className={styles.button}
onClick={() => setEmojiPack("openmoji")}
data-active={emojiPack === "openmoji"}>
<img src={openmojiSVG} draggable={false} />
</div>
<h4>Openmoji</h4>
</div>
<div>
<div
className={styles.button}
onClick={() => setEmojiPack("noto")}
data-active={emojiPack === "noto"}>
<img src={notoSVG} draggable={false} />
</div>
<h4>Noto Emoji</h4>
</div>
</div>
</div>
<h3>
<Text id="app.settings.pages.appearance.emoji_pack" />
</h3>
<div className={styles.emojiPack}>
<div className={styles.row}>
<div>
<div
className={styles.button}
onClick={() => setEmojiPack("mutant")}
data-active={emojiPack === "mutant"}>
<img src={mutantSVG} draggable={false} />
</div>
<h4>
Mutant Remix{" "}
<a
href="https://mutant.revolt.chat"
target="_blank">
(by Revolt)
</a>
</h4>
</div>
<div>
<div
className={styles.button}
onClick={() => setEmojiPack("twemoji")}
data-active={emojiPack === "twemoji"}>
<img src={twemojiSVG} draggable={false} />
</div>
<h4>Twemoji</h4>
</div>
</div>
<div className={styles.row}>
<div>
<div
className={styles.button}
onClick={() => setEmojiPack("openmoji")}
data-active={emojiPack === "openmoji"}>
<img src={openmojiSVG} draggable={false} />
</div>
<h4>Openmoji</h4>
</div>
<div>
<div
className={styles.button}
onClick={() => setEmojiPack("noto")}
data-active={emojiPack === "noto"}>
<img src={notoSVG} draggable={false} />
</div>
<h4>Noto Emoji</h4>
</div>
</div>
</div>
<CollapsibleSection
id="settings_advanced_appearance"
defaultValue={false}
summary={<Text id="app.settings.pages.appearance.advanced" />}>
<h3>
<Text id="app.settings.pages.appearance.overrides" />
</h3>
<div className={styles.actions}>
<Button contrast onClick={() => setTheme({ custom: {} })}>
<Text id="app.settings.pages.appearance.reset_overrides" />
</Button>
<Button
contrast
onClick={() => writeClipboard(JSON.stringify(theme))}>
<Text id="app.settings.pages.appearance.export_clipboard" />
</Button>
<Button
contrast
onClick={async () => {
const text = await navigator.clipboard.readText();
setOverride(JSON.parse(text));
}}>
<Text id="app.settings.pages.appearance.import_clipboard" />
</Button>
<Button
contrast
onClick={async () => {
openScreen({
id: "_input",
question: (
<Text id="app.settings.pages.appearance.import_theme" />
),
field: (
<Text id="app.settings.pages.appearance.theme_data" />
),
callback: async (string) =>
setOverride(JSON.parse(string)),
});
}}>
<Text id="app.settings.pages.appearance.import_manual" />
</Button>
</div>
<div className={styles.overrides}>
{(
[
"accent",
"background",
"foreground",
"primary-background",
"primary-header",
"secondary-background",
"secondary-foreground",
"secondary-header",
"tertiary-background",
"tertiary-foreground",
"block",
"message-box",
"mention",
"scrollbar-thumb",
"scrollbar-track",
"status-online",
"status-away",
"status-busy",
"status-streaming",
"status-invisible",
"success",
"warning",
"error",
"hover",
] as const
).map((x) => (
<div className={styles.entry} key={x}>
<span>{x}</span>
<div className={styles.override}>
<div
className={styles.picker}
style={{ backgroundColor: theme[x] }}>
<input
type="color"
value={theme[x]}
onChange={(v) =>
setOverride({
[x]: v.currentTarget.value,
})
}
/>
</div>
<InputBox
className={styles.text}
value={theme[x]}
onChange={(y) =>
setOverride({
[x]: y.currentTarget.value,
})
}
/>
</div>
</div>
))}
</div>
<CollapsibleSection
id="settings_advanced_appearance"
defaultValue={false}
summary={<Text id="app.settings.pages.appearance.advanced" />}>
<h3>
<Text id="app.settings.pages.appearance.overrides" />
</h3>
<div className={styles.actions}>
<Button contrast onClick={() => setTheme({ custom: {} })}>
<Text id="app.settings.pages.appearance.reset_overrides" />
</Button>
<Button
contrast
onClick={() => writeClipboard(JSON.stringify(theme))}>
<Text id="app.settings.pages.appearance.export_clipboard" />
</Button>
<Button
contrast
onClick={async () => {
const text = await navigator.clipboard.readText();
setOverride(JSON.parse(text));
}}>
<Text id="app.settings.pages.appearance.import_clipboard" />
</Button>
<Button
contrast
onClick={async () => {
openScreen({
id: "_input",
question: (
<Text id="app.settings.pages.appearance.import_theme" />
),
field: (
<Text id="app.settings.pages.appearance.theme_data" />
),
callback: async (string) =>
setOverride(JSON.parse(string)),
});
}}>
<Text id="app.settings.pages.appearance.import_manual" />
</Button>
</div>
<div className={styles.overrides}>
{(
[
"accent",
"background",
"foreground",
"primary-background",
"primary-header",
"secondary-background",
"secondary-foreground",
"secondary-header",
"tertiary-background",
"tertiary-foreground",
"block",
"message-box",
"mention",
"scrollbar-thumb",
"scrollbar-track",
"status-online",
"status-away",
"status-busy",
"status-streaming",
"status-invisible",
"success",
"warning",
"error",
"hover",
] as const
).map((x) => (
<div className={styles.entry} key={x}>
<span>{x}</span>
<div className={styles.override}>
<div
className={styles.picker}
style={{ backgroundColor: theme[x] }}>
<input
type="color"
value={theme[x]}
onChange={(v) =>
setOverride({
[x]: v.currentTarget.value,
})
}
/>
</div>
<InputBox
className={styles.text}
value={theme[x]}
onChange={(y) =>
setOverride({
[x]: y.currentTarget.value,
})
}
/>
</div>
</div>
))}
</div>
<h3>
<Text id="app.settings.pages.appearance.mono_font" />
</h3>
<ComboBox
value={theme.monoscapeFont ?? DEFAULT_MONO_FONT}
onChange={(e) =>
setTheme({
custom: {
monoscapeFont: e.currentTarget.value as any,
},
})
}>
{MONOSCAPE_FONT_KEYS.map((key) => (
<option value={key}>
{
MONOSCAPE_FONTS[
key as keyof typeof MONOSCAPE_FONTS
].name
}
</option>
))}
</ComboBox>
<h3>
<Text id="app.settings.pages.appearance.mono_font" />
</h3>
<ComboBox
value={theme.monoscapeFont ?? DEFAULT_MONO_FONT}
onChange={(e) =>
setTheme({
custom: {
monoscapeFont: e.currentTarget.value as any,
},
})
}>
{MONOSCAPE_FONT_KEYS.map((key) => (
<option value={key}>
{
MONOSCAPE_FONTS[
key as keyof typeof MONOSCAPE_FONTS
].name
}
</option>
))}
</ComboBox>
<h3>
<Text id="app.settings.pages.appearance.custom_css" />
</h3>
<TextAreaAutoSize
maxRows={20}
minHeight={480}
code
value={css}
onChange={(ev) => setCSS(ev.currentTarget.value)}
/>
</CollapsibleSection>
</div>
);
<h3>
<Text id="app.settings.pages.appearance.custom_css" />
</h3>
<TextAreaAutoSize
maxRows={20}
minHeight={480}
code
value={css}
onChange={(ev) => setCSS(ev.currentTarget.value)}
/>
</CollapsibleSection>
</div>
);
}
export const Appearance = connectState(Component, (state) => {
return {
settings: state.settings,
};
return {
settings: state.settings,
};
});