mirror of
https://github.com/revoltchat/revite.git
synced 2024-12-24 06:32:08 -05:00
feat(mobx): write experiments, lastOpened and localeOptions stores
This commit is contained in:
parent
5a41c25e3c
commit
185f76d850
4 changed files with 236 additions and 10 deletions
|
@ -1,4 +1,4 @@
|
|||
import { makeAutoObservable } from "mobx";
|
||||
import { makeAutoObservable, ObservableMap } from "mobx";
|
||||
import { Session } from "revolt-api/types/Auth";
|
||||
import { Nullable } from "revolt.js/dist/util/null";
|
||||
|
||||
|
@ -15,14 +15,14 @@ interface Data {
|
|||
* accounts and their sessions.
|
||||
*/
|
||||
export default class Auth implements Persistent<Data> {
|
||||
private sessions: Record<string, Session>;
|
||||
private sessions: ObservableMap<string, Session>;
|
||||
private current: Nullable<string>;
|
||||
|
||||
/**
|
||||
* Construct new Auth store.
|
||||
*/
|
||||
constructor() {
|
||||
this.sessions = {};
|
||||
this.sessions = new ObservableMap();
|
||||
this.current = null;
|
||||
makeAutoObservable(this);
|
||||
}
|
||||
|
@ -37,8 +37,11 @@ export default class Auth implements Persistent<Data> {
|
|||
|
||||
// eslint-disable-next-line require-jsdoc
|
||||
hydrate(data: Data) {
|
||||
this.sessions = data.sessions;
|
||||
if (data.current && this.sessions[data.current]) {
|
||||
Object.keys(data.sessions).forEach((id) =>
|
||||
this.sessions.set(id, data.sessions[id]),
|
||||
);
|
||||
|
||||
if (data.current && this.sessions.has(data.current)) {
|
||||
this.current = data.current;
|
||||
}
|
||||
}
|
||||
|
@ -48,11 +51,7 @@ export default class Auth implements Persistent<Data> {
|
|||
* @param session Session
|
||||
*/
|
||||
setSession(session: Session) {
|
||||
this.sessions = {
|
||||
...this.sessions,
|
||||
[session.user_id]: session,
|
||||
};
|
||||
|
||||
this.sessions.set(session.user_id, session);
|
||||
this.current = session.user_id;
|
||||
}
|
||||
|
||||
|
|
86
src/mobx/stores/Experiments.ts
Normal file
86
src/mobx/stores/Experiments.ts
Normal file
|
@ -0,0 +1,86 @@
|
|||
import { action, computed, makeAutoObservable, ObservableSet } from "mobx";
|
||||
|
||||
import Persistent from "../Persistent";
|
||||
|
||||
export type Experiment = "search" | "theme_shop";
|
||||
|
||||
export const AVAILABLE_EXPERIMENTS: Experiment[] = ["theme_shop"];
|
||||
|
||||
export const EXPERIMENTS: {
|
||||
[key in Experiment]: { title: string; description: string };
|
||||
} = {
|
||||
search: {
|
||||
title: "Search",
|
||||
description: "Allows you to search for messages in channels.",
|
||||
},
|
||||
theme_shop: {
|
||||
title: "Theme Shop",
|
||||
description: "Allows you to access and set user submitted themes.",
|
||||
},
|
||||
};
|
||||
|
||||
interface Data {
|
||||
enabled?: Experiment[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles enabling and disabling client experiments.
|
||||
*/
|
||||
export default class Experiments implements Persistent<Data> {
|
||||
private enabled: ObservableSet<Experiment>;
|
||||
|
||||
/**
|
||||
* Construct new Experiments store.
|
||||
*/
|
||||
constructor() {
|
||||
this.enabled = new ObservableSet();
|
||||
makeAutoObservable(this);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line require-jsdoc
|
||||
toJSON() {
|
||||
return {
|
||||
enabled: this.enabled,
|
||||
};
|
||||
}
|
||||
|
||||
// eslint-disable-next-line require-jsdoc
|
||||
@action hydrate(data: Data) {
|
||||
if (data.enabled) {
|
||||
for (const experiment of data.enabled) {
|
||||
this.enabled.add(experiment as Experiment);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if an experiment is enabled.
|
||||
* @param experiment Experiment
|
||||
*/
|
||||
@computed isEnabled(experiment: Experiment) {
|
||||
return this.enabled.has(experiment);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable an experiment.
|
||||
* @param experiment Experiment
|
||||
*/
|
||||
@action enable(experiment: Experiment) {
|
||||
this.enabled.add(experiment);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable an experiment.
|
||||
* @param experiment Experiment
|
||||
*/
|
||||
@action disable(experiment: Experiment) {
|
||||
this.enabled.delete(experiment);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset and disable all experiments.
|
||||
*/
|
||||
@action reset() {
|
||||
this.enabled.clear();
|
||||
}
|
||||
}
|
57
src/mobx/stores/LastOpened.ts
Normal file
57
src/mobx/stores/LastOpened.ts
Normal file
|
@ -0,0 +1,57 @@
|
|||
import { action, computed, makeAutoObservable, ObservableMap } from "mobx";
|
||||
|
||||
import Persistent from "../Persistent";
|
||||
|
||||
interface Data {
|
||||
server?: Record<string, string>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Keeps track of the last open channels, tabs, etc.
|
||||
* Handles providing good UX experience on navigating
|
||||
* back and forth between different parts of the app.
|
||||
*/
|
||||
export default class Experiments implements Persistent<Data> {
|
||||
private server: ObservableMap<string, string>;
|
||||
|
||||
/**
|
||||
* Construct new Experiments store.
|
||||
*/
|
||||
constructor() {
|
||||
this.server = new ObservableMap();
|
||||
makeAutoObservable(this);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line require-jsdoc
|
||||
toJSON() {
|
||||
return {
|
||||
server: this.server,
|
||||
};
|
||||
}
|
||||
|
||||
// eslint-disable-next-line require-jsdoc
|
||||
@action hydrate(data: Data) {
|
||||
if (data.server) {
|
||||
Object.keys(data.server).forEach((key) =>
|
||||
this.server.set(key, data.server![key]),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get last opened channel in a server.
|
||||
* @param server Server ID
|
||||
*/
|
||||
@computed get(server: string) {
|
||||
return this.server.get(server);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set last opened channel in a server.
|
||||
* @param server Server ID
|
||||
* @param channel Channel ID
|
||||
*/
|
||||
@action enable(server: string, channel: string) {
|
||||
this.server.set(server, channel);
|
||||
}
|
||||
}
|
84
src/mobx/stores/LocaleOptions.ts
Normal file
84
src/mobx/stores/LocaleOptions.ts
Normal file
|
@ -0,0 +1,84 @@
|
|||
import { action, computed, makeAutoObservable } from "mobx";
|
||||
|
||||
import { Language, Languages } from "../../context/Locale";
|
||||
|
||||
import Persistent from "../Persistent";
|
||||
|
||||
interface Data {
|
||||
lang: Language;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect the browser language or match given language.
|
||||
* @param lang Language to find
|
||||
* @returns Matched Language
|
||||
*/
|
||||
export function findLanguage(lang?: string): Language {
|
||||
if (!lang) {
|
||||
if (typeof navigator === "undefined") {
|
||||
lang = Language.ENGLISH;
|
||||
} else {
|
||||
lang = navigator.language;
|
||||
}
|
||||
}
|
||||
|
||||
const code = lang.replace("-", "_");
|
||||
const short = code.split("_")[0];
|
||||
|
||||
const values = [];
|
||||
for (const key in Language) {
|
||||
const value = Language[key as keyof typeof Language];
|
||||
|
||||
// Skip alternative/joke languages
|
||||
if (Languages[value].cat === "alt") continue;
|
||||
|
||||
values.push(value);
|
||||
if (value.startsWith(code)) {
|
||||
return value as Language;
|
||||
}
|
||||
}
|
||||
|
||||
for (const value of values.reverse()) {
|
||||
if (value.startsWith(short)) {
|
||||
return value as Language;
|
||||
}
|
||||
}
|
||||
|
||||
return Language.ENGLISH;
|
||||
}
|
||||
|
||||
/**
|
||||
* Keeps track of the last open channels, tabs, etc.
|
||||
* Handles providing good UX experience on navigating
|
||||
* back and forth between different parts of the app.
|
||||
*/
|
||||
export default class LocaleOptions implements Persistent<Data> {
|
||||
private lang: Language;
|
||||
|
||||
/**
|
||||
* Construct new LocaleOptions store.
|
||||
*/
|
||||
constructor() {
|
||||
this.lang = findLanguage();
|
||||
makeAutoObservable(this);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line require-jsdoc
|
||||
toJSON() {
|
||||
return {
|
||||
lang: this.lang,
|
||||
};
|
||||
}
|
||||
|
||||
// eslint-disable-next-line require-jsdoc
|
||||
@action hydrate(data: Data) {
|
||||
this.lang = data.lang;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current language.
|
||||
*/
|
||||
@computed getLang() {
|
||||
return this.lang;
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue