interface: add storage and hydration of settings

This commit is contained in:
Liam Fitzgerald 2020-07-31 13:00:27 +10:00
parent 41089c912d
commit d9a9ac991f
8 changed files with 123 additions and 6 deletions

View File

@ -70,6 +70,7 @@ class App extends React.Component {
this.api.local.setDark(this.themeWatcher.matches);
this.themeWatcher.addListener(this.updateTheme);
this.api.local.getBaseHash();
this.store.rehydrate();
}
componentWillUnmount() {

View File

@ -12,7 +12,7 @@ export default class LaunchApi extends BaseApi<StoreState> {
this.launchAction({ remove: name });
}
changeOrder(orderedTiles = []) {
changeOrder(orderedTiles: string[] = []) {
this.launchAction({ 'change-order': orderedTiles });
}

View File

@ -1,6 +1,6 @@
import BaseApi from "./base";
import { StoreState } from "../store/type";
import { SelectedGroup } from "../types/local-update";
import { SelectedGroup, BackgroundConfig } from "../types/local-update";
export default class LocalApi extends BaseApi<StoreState> {
getBaseHash() {
@ -39,4 +39,38 @@ export default class LocalApi extends BaseApi<StoreState> {
});
}
setBackground(backgroundConfig: BackgroundConfig) {
this.store.handleEvent({
data: {
local: {
backgroundConfig
}
}
});
}
hideAvatars(hideAvatars: boolean) {
this.store.handleEvent({
data: {
local: {
hideAvatars
}
}
});
}
hideNicknames(hideNicknames: boolean) {
this.store.handleEvent({
data: {
local: {
hideNicknames
}
}
});
}
dehydrate() {
this.store.dehydrate();
}
}

View File

@ -1,11 +1,26 @@
import _ from 'lodash';
import { StoreState } from '../store/type';
import { Cage } from '../types/cage';
import { LocalUpdate } from '../types/local-update';
import { LocalUpdate, BackgroundConfig } from '../types/local-update';
type LocalState = Pick<StoreState, 'sidebarShown' | 'selectedGroups' | 'dark' | 'baseHash'>;
type LocalState = Pick<StoreState, 'sidebarShown' | 'selectedGroups' | 'baseHash' | 'hideAvatars' | 'hideNicknames' | 'background' | 'dark'>;
export default class LocalReducer<S extends LocalState> {
rehydrate(state: S) {
try {
const json = JSON.parse(localStorage.getItem('localReducer') || '');
_.forIn(json, (value, key) => {
state[key] = value;
});
} catch (e) {
console.warn('Failed to rehydrate localStorage state', e);
}
}
dehydrate(state: S) {
const json = _.pick(state, ['hideNicknames' , 'hideAvatars' , 'background']);
localStorage.setItem('localReducer', JSON.stringify(json));
}
reduce(json: Cage, state: S) {
const data = json['local'];
if (data) {
@ -13,6 +28,9 @@ export default class LocalReducer<S extends LocalState> {
this.setSelected(data, state);
this.setDark(data, state);
this.baseHash(data, state);
this.backgroundConfig(data, state)
this.hideAvatars(data, state)
this.hideNicknames(data, state)
}
}
baseHash(obj: LocalUpdate, state: S) {
@ -38,4 +56,22 @@ export default class LocalReducer<S extends LocalState> {
state.dark = obj.setDark;
}
}
backgroundConfig(obj: LocalUpdate, state: S) {
if('backgroundConfig' in obj) {
state.background = obj.backgroundConfig;
}
}
hideAvatars(obj: LocalUpdate, state: S) {
if('hideAvatars' in obj) {
state.hideAvatars = obj.hideAvatars;
}
}
hideNicknames(obj: LocalUpdate, state: S) {
if( 'hideNicknames' in obj) {
state.hideNicknames = obj.hideNicknames;
}
}
}

View File

@ -5,6 +5,10 @@ export default class BaseStore<S extends object> {
this.state = this.initialState();
}
dehydrate() {}
rehydrate() {}
initialState() {
return {} as S;
}

View File

@ -34,6 +34,14 @@ export default class GlobalStore extends BaseStore<StoreState> {
launchReducer = new LaunchReducer();
connReducer = new ConnectionReducer();
rehydrate() {
this.localReducer.rehydrate(this.state);
}
dehydrate() {
this.localReducer.dehydrate(this.state);
}
initialState(): StoreState {
return {
@ -42,6 +50,9 @@ export default class GlobalStore extends BaseStore<StoreState> {
connection: 'connected',
sidebarShown: true,
baseHash: null,
background: undefined,
hideAvatars: false,
hideNicknames: false,
invites: {},
associations: {
chat: {},

View File

@ -2,7 +2,7 @@ import { Inbox, Envelope } from '../types/chat-update';
import { ChatHookUpdate } from '../types/chat-hook-update';
import { Path } from '../types/noun';
import { Invites } from '../types/invite-update';
import { SelectedGroup } from '../types/local-update';
import { SelectedGroup, BackgroundConfig } from '../types/local-update';
import { Associations } from '../types/metadata-update';
import { Rolodex } from '../types/contact-update';
import { Notebooks } from '../types/publish-update';
@ -20,6 +20,9 @@ export interface StoreState {
dark: boolean;
connection: ConnectionStatus;
baseHash: string | null;
background: BackgroundConfig;
hideAvatars: boolean;
hideNicknames: boolean;
// invite state
invites: Invites;
// metadata state

View File

@ -4,7 +4,10 @@ export type LocalUpdate =
LocalUpdateSidebarToggle
| LocalUpdateSelectedGroups
| LocalUpdateSetDark
| LocalUpdateBaseHash;
| LocalUpdateBaseHash
| LocalUpdateBackgroundConfig
| LocalUpdateHideAvatars
| LocalUpdateHideNicknames;
interface LocalUpdateSidebarToggle {
sidebarToggle: boolean;
@ -22,4 +25,29 @@ interface LocalUpdateBaseHash {
baseHash: string;
}
interface LocalUpdateBackgroundConfig {
backgroundConfig: BackgroundConfig;
}
interface LocalUpdateHideAvatars {
hideAvatars: boolean;
}
interface LocalUpdateHideNicknames {
hideNicknames: boolean;
}
export type BackgroundConfig = BackgroundConfigUrl | BackgroundConfigColor | undefined;
interface BackgroundConfigUrl {
type: 'url';
url: string;
}
interface BackgroundConfigColor {
type: 'color';
color: string;
}
export type SelectedGroup = [Path, string];