feat(mobx): add experiments store

This commit is contained in:
Paul 2021-12-11 13:23:01 +00:00
parent 830b24a393
commit f87ecfcbd7
4 changed files with 33 additions and 31 deletions

View file

@ -5,6 +5,7 @@ import { useContext } from "preact/hooks";
import Auth from "./stores/Auth"; import Auth from "./stores/Auth";
import Draft from "./stores/Draft"; import Draft from "./stores/Draft";
import Experiments from "./stores/Experiments";
import LocaleOptions from "./stores/LocaleOptions"; import LocaleOptions from "./stores/LocaleOptions";
interface StoreDefinition { interface StoreDefinition {
@ -22,6 +23,7 @@ export default class State {
auth: Auth; auth: Auth;
draft: Draft; draft: Draft;
locale: LocaleOptions; locale: LocaleOptions;
experiments: Experiments;
/** /**
* Construct new State. * Construct new State.
@ -30,6 +32,7 @@ export default class State {
this.auth = new Auth(); this.auth = new Auth();
this.draft = new Draft(); this.draft = new Draft();
this.locale = new LocaleOptions(); this.locale = new LocaleOptions();
this.experiments = new Experiments();
makeAutoObservable(this); makeAutoObservable(this);
} }

View file

@ -10,7 +10,7 @@ export type Experiment = "dummy" | "theme_shop";
/** /**
* Currently active experiments. * Currently active experiments.
*/ */
export const AVAILABLE_EXPERIMENTS: Experiment[] = ["theme_shop"]; export const AVAILABLE_EXPERIMENTS: Experiment[] = ["dummy", "theme_shop"];
/** /**
* Definitions for experiments listed by {@link Experiment}. * Definitions for experiments listed by {@link Experiment}.
@ -84,6 +84,19 @@ export default class Experiments implements Persistent<Data> {
this.enabled.delete(experiment); this.enabled.delete(experiment);
} }
/**
* Set the state of an experiment.
* @param key Experiment
* @param enabled Whether this experiment is enabled.
*/
@computed setEnabled(key: Experiment, enabled: boolean): void {
if (enabled) {
this.enable(key);
} else {
this.disable(key);
}
}
/** /**
* Reset and disable all experiments. * Reset and disable all experiments.
*/ */

View file

@ -18,6 +18,7 @@ import {
Speaker, Speaker,
Store, Store,
} from "@styled-icons/boxicons-solid"; } from "@styled-icons/boxicons-solid";
import { observer } from "mobx-react-lite";
import { Route, Switch, useHistory } from "react-router-dom"; import { Route, Switch, useHistory } from "react-router-dom";
import { LIBRARY_VERSION } from "revolt.js"; import { LIBRARY_VERSION } from "revolt.js";
@ -25,7 +26,7 @@ import styles from "./Settings.module.scss";
import { Text } from "preact-i18n"; import { Text } from "preact-i18n";
import { useContext } from "preact/hooks"; import { useContext } from "preact/hooks";
import { isExperimentEnabled } from "../../redux/reducers/experiments"; import { useApplicationState } from "../../mobx/State";
import RequiresOnline from "../../context/revoltjs/RequiresOnline"; import RequiresOnline from "../../context/revoltjs/RequiresOnline";
import { import {
@ -53,10 +54,11 @@ import { Sessions } from "./panes/Sessions";
import { Sync } from "./panes/Sync"; import { Sync } from "./panes/Sync";
import { ThemeShop } from "./panes/ThemeShop"; import { ThemeShop } from "./panes/ThemeShop";
export default function Settings() { export default observer(() => {
const history = useHistory(); const history = useHistory();
const client = useContext(AppContext); const client = useContext(AppContext);
const operations = useContext(OperationsContext); const operations = useContext(OperationsContext);
const experiments = useApplicationState().experiments;
function switchPage(to?: string) { function switchPage(to?: string) {
if (to) { if (to) {
@ -127,14 +129,14 @@ export default function Settings() {
title: <Text id="app.settings.pages.experiments.title" />, title: <Text id="app.settings.pages.experiments.title" />,
}, },
{ {
divider: !isExperimentEnabled("theme_shop"), divider: !experiments.isEnabled("theme_shop"),
category: "revolt", category: "revolt",
id: "bots", id: "bots",
icon: <Bot size={20} />, icon: <Bot size={20} />,
title: <Text id="app.settings.pages.bots.title" />, title: <Text id="app.settings.pages.bots.title" />,
}, },
{ {
hidden: !isExperimentEnabled("theme_shop"), hidden: !experiments.isEnabled("theme_shop"),
divider: true, divider: true,
id: "theme_shop", id: "theme_shop",
icon: <Store size={20} />, icon: <Store size={20} />,
@ -180,7 +182,7 @@ export default function Settings() {
<Route path="/settings/bots"> <Route path="/settings/bots">
<MyBots /> <MyBots />
</Route> </Route>
{isExperimentEnabled("theme_shop") && ( {experiments.isEnabled("theme_shop") && (
<Route path="/settings/theme_shop"> <Route path="/settings/theme_shop">
<ThemeShop /> <ThemeShop />
</Route> </Route>
@ -260,4 +262,4 @@ export default function Settings() {
} }
/> />
); );
} });

View file

@ -1,22 +1,19 @@
import { observer } from "mobx-react-lite";
import styles from "./Panes.module.scss"; import styles from "./Panes.module.scss";
import { Text } from "preact-i18n"; import { Text } from "preact-i18n";
import { dispatch } from "../../../redux"; import { useApplicationState } from "../../../mobx/State";
import { connectState } from "../../../redux/connector";
import { import {
AVAILABLE_EXPERIMENTS, AVAILABLE_EXPERIMENTS,
ExperimentOptions,
EXPERIMENTS, EXPERIMENTS,
isExperimentEnabled, } from "../../../mobx/stores/Experiments";
} from "../../../redux/reducers/experiments";
import Checkbox from "../../../components/ui/Checkbox"; import Checkbox from "../../../components/ui/Checkbox";
interface Props { export const ExperimentsPage = observer(() => {
options?: ExperimentOptions; const experiments = useApplicationState().experiments;
}
export function Component(props: Props) {
return ( return (
<div className={styles.experiments}> <div className={styles.experiments}>
<h3> <h3>
@ -25,15 +22,8 @@ export function Component(props: Props) {
{AVAILABLE_EXPERIMENTS.map((key) => ( {AVAILABLE_EXPERIMENTS.map((key) => (
<Checkbox <Checkbox
key={key} key={key}
checked={isExperimentEnabled(key, props.options)} checked={experiments.isEnabled(key)}
onChange={(enabled) => onChange={(enabled) => experiments.setEnabled(key, enabled)}
dispatch({
type: enabled
? "EXPERIMENTS_ENABLE"
: "EXPERIMENTS_DISABLE",
key,
})
}
description={EXPERIMENTS[key].description}> description={EXPERIMENTS[key].description}>
{EXPERIMENTS[key].title} {EXPERIMENTS[key].title}
</Checkbox> </Checkbox>
@ -45,10 +35,4 @@ export function Component(props: Props) {
)} )}
</div> </div>
); );
}
export const ExperimentsPage = connectState(Component, (state) => {
return {
options: state.experiments,
};
}); });