grid: wire to real settings store

This commit is contained in:
Liam Fitzgerald 2021-09-09 11:37:52 +10:00
parent 3ed00eda9d
commit d79130af47
3 changed files with 110 additions and 3 deletions

View File

@ -1,15 +1,23 @@
import React from 'react';
import { Setting } from '../../components/Setting';
import { useSettingsState, SettingsState } from '../../state/settings';
import { usePreferencesStore } from './usePreferencesStore';
const selDnd = (s: SettingsState) => s.display.doNotDisturb;
async function toggleDnd() {
const state = useSettingsState.getState();
await state.putEntry('display', 'doNotDisturb', !selDnd(state));
}
export const NotificationPrefs = () => {
const { doNotDisturb, mentions, toggleDoNotDisturb, toggleMentions } = usePreferencesStore();
const { mentions, toggleMentions } = usePreferencesStore();
const doNotDisturb = useSettingsState(selDnd);
return (
<>
<h2 className="h3 mb-7">Notifications</h2>
<div className="space-y-3">
<Setting on={doNotDisturb} toggle={toggleDoNotDisturb} name="Do Not Disturb">
<Setting on={doNotDisturb} toggle={toggleDnd} name="Do Not Disturb">
<p>
Block visual desktop notifications whenever Urbit software produces an in-Landscape
notification badge.

View File

@ -7,6 +7,7 @@ import { persist } from 'zustand/middleware';
import Urbit, { SubscriptionRequestInterface } from '@urbit/http-api';
import { Poke } from '@urbit/api';
import api from './api';
import { useMockData } from './util';
setAutoFreeze(false);
enablePatches();
@ -181,7 +182,7 @@ export async function pokeOptimisticallyN<A, S extends Record<string, unknown>>(
let num: string | undefined;
try {
num = optReduceState(state, poke.json, reduce);
await api.poke(poke);
await (useMockData ? new Promise((res) => setTimeout(res, 500)) : api.poke(poke));
state.getState().removePatch(num);
} catch (e) {
console.error(e);

View File

@ -0,0 +1,98 @@
/* eslint-disable no-param-reassign */
import {
SettingsUpdate,
Value,
putEntry as doPutEntry,
getDeskSettings,
DeskData
} from '@urbit/api/settings';
import _ from 'lodash';
import {
BaseState,
createState,
createSubscription,
pokeOptimisticallyN,
reduceStateN
} from './base';
import api from './api';
interface BaseSettingsState {
display: {
theme: 'light' | 'dark' | 'automatic';
doNotDisturb: boolean;
};
putEntry: (bucket: string, key: string, value: Value) => Promise<void>;
[ref: string]: unknown;
}
export type SettingsState = BaseSettingsState & BaseState<BaseSettingsState>;
function putBucket(json: SettingsUpdate, state: SettingsState): SettingsState {
const data = _.get(json, 'put-bucket', false);
if (data) {
state[data['bucket-key']] = data.bucket;
}
return state;
}
function delBucket(json: SettingsUpdate, state: SettingsState): SettingsState {
const data = _.get(json, 'del-bucket', false);
if (data) {
delete state[data['bucket-key']];
}
return state;
}
function putEntry(json: SettingsUpdate, state: any): SettingsState {
const data: Record<string, string> = _.get(json, 'put-entry', false);
if (data) {
if (!state[data['bucket-key']]) {
state[data['bucket-key']] = {};
}
state[data['bucket-key']][data['entry-key']] = data.value;
}
return state;
}
function delEntry(json: SettingsUpdate, state: any): SettingsState {
const data = _.get(json, 'del-entry', false);
if (data) {
delete state[data['bucket-key']][data['entry-key']];
}
return state;
}
export const reduceUpdate = [putBucket, delBucket, putEntry, delEntry];
export const useSettingsState = createState<BaseSettingsState>(
'Settings',
(set, get) => ({
display: {
theme: 'automatic',
doNotDisturb: true
},
loaded: false,
putEntry: async (bucket, key, val) => {
const poke = doPutEntry(window.desk, bucket, key, val);
await pokeOptimisticallyN(useSettingsState, poke, reduceUpdate);
},
fetchAll: async () => {
const result = (await api.scry<DeskData>(getDeskSettings(window.desk))).desk;
const newState = {
loaded: true,
..._.mergeWith(get(), result, (obj, src) => (_.isArray(src) ? src : undefined))
};
set(newState);
}
}),
[],
[
(set, get) =>
createSubscription('settings-store', `/desk/${window.desk}`, (e) => {
const data = _.get(e, 'settings-event', false);
if (data) {
reduceStateN(get(), data, reduceUpdate);
}
})
]
);