mirror of
https://github.com/urbit/shrub.git
synced 2024-12-01 06:35:32 +03:00
prefs: hooking up mentions pref
This commit is contained in:
parent
50c42c3558
commit
8dd9113843
@ -8,6 +8,7 @@ import useKilnState from './state/kiln';
|
||||
import { usePreferencesStore } from './nav/preferences/usePreferencesStore';
|
||||
import useContactState from './state/contact';
|
||||
import api from './state/api';
|
||||
import { useHarkStore } from './state/hark';
|
||||
|
||||
const AppRoutes = () => {
|
||||
const { push } = useHistory();
|
||||
@ -46,6 +47,7 @@ const AppRoutes = () => {
|
||||
fetchVats();
|
||||
fetchLag();
|
||||
useContactState.getState().initialize(api);
|
||||
useHarkStore.getState().initialize(api);
|
||||
|
||||
Mousetrap.bind(['command+/', 'ctrl+/'], () => {
|
||||
push('/leap/search');
|
||||
|
@ -20,12 +20,12 @@ export const Setting: FC<SettingsProps> = ({ name, on, toggle, className, childr
|
||||
<h3 id={id} className="flex items-center h4 mb-2">
|
||||
{name} {status === 'loading' && <Spinner className="ml-2" />}
|
||||
</h3>
|
||||
<div className="flex items-center space-x-2">
|
||||
<div className="flex space-x-2">
|
||||
<Toggle
|
||||
aria-labelledby={id}
|
||||
pressed={on}
|
||||
onPressedChange={call}
|
||||
className="text-blue-400"
|
||||
className="flex-none self-start text-blue-400"
|
||||
/>
|
||||
<div className="flex-1 space-y-6">{children}</div>
|
||||
</div>
|
||||
|
@ -6,12 +6,13 @@ import type * as Polymorphic from '@radix-ui/react-polymorphic';
|
||||
type ToggleComponent = Polymorphic.ForwardRefComponent<
|
||||
Polymorphic.IntrinsicElement<typeof RadixToggle.Root>,
|
||||
Polymorphic.OwnProps<typeof RadixToggle.Root> & {
|
||||
toggleClass?: string;
|
||||
knobClass?: string;
|
||||
}
|
||||
>;
|
||||
|
||||
export const Toggle = React.forwardRef(
|
||||
({ defaultPressed, pressed, onPressedChange, disabled, className }, ref) => {
|
||||
({ defaultPressed, pressed, onPressedChange, disabled, className, toggleClass }, ref) => {
|
||||
const [on, setOn] = useState(defaultPressed);
|
||||
const isControlled = !!onPressedChange;
|
||||
const proxyPressed = isControlled ? pressed : on;
|
||||
@ -20,14 +21,14 @@ export const Toggle = React.forwardRef(
|
||||
|
||||
return (
|
||||
<RadixToggle.Root
|
||||
className="default-ring rounded-full"
|
||||
className={classNames('default-ring rounded-full', className)}
|
||||
pressed={proxyPressed}
|
||||
onPressedChange={proxyOnPressedChange}
|
||||
disabled={disabled}
|
||||
ref={ref}
|
||||
>
|
||||
<svg
|
||||
className={classNames('w-12 h-8', className)}
|
||||
className={classNames('w-12 h-8', toggleClass)}
|
||||
viewBox="0 0 48 32"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
|
@ -1,6 +1,5 @@
|
||||
import React from 'react';
|
||||
import { Setting } from '../../components/Setting';
|
||||
import { ShipName } from '../../components/ShipName';
|
||||
import { useProtocolHandling, setLocalState } from '../../state/local';
|
||||
|
||||
export function InterfacePrefs() {
|
||||
@ -8,9 +7,13 @@ export function InterfacePrefs() {
|
||||
const toggleProtoHandling = async () => {
|
||||
if (!protocolHandling && window?.navigator?.registerProtocolHandler) {
|
||||
try {
|
||||
window.navigator.registerProtocolHandler('web+urbitgraph', '/apps/grid/perma?ext=%s', 'Urbit Links');
|
||||
setLocalState((s) => {
|
||||
s.protocolHandling = true;
|
||||
window.navigator.registerProtocolHandler(
|
||||
'web+urbitgraph',
|
||||
'/apps/grid/perma?ext=%s',
|
||||
'Urbit Links'
|
||||
);
|
||||
setLocalState((draft) => {
|
||||
draft.protocolHandling = true;
|
||||
});
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
@ -18,8 +21,8 @@ export function InterfacePrefs() {
|
||||
} else if (protocolHandling && window.navigator?.unregisterProtocolHandler) {
|
||||
try {
|
||||
window.navigator.unregisterProtocolHandler('web+urbitgraph', '/apps/grid/perma?ext=%s');
|
||||
setLocalState((s) => {
|
||||
s.protocolHandling = false;
|
||||
setLocalState((draft) => {
|
||||
draft.protocolHandling = false;
|
||||
});
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
@ -31,10 +34,10 @@ export function InterfacePrefs() {
|
||||
<>
|
||||
<h2 className="h3 mb-7">Interface Settings</h2>
|
||||
<Setting on={protocolHandling} toggle={toggleProtoHandling} name="Handle Urbit links">
|
||||
<p>Automatically open urbit links with this urbit</p>
|
||||
<p className="flex flex-col justify-center h-full">
|
||||
Automatically open urbit links with this urbit
|
||||
</p>
|
||||
</Setting>
|
||||
|
||||
<div className="space-y-3"> </div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
@ -1,7 +1,9 @@
|
||||
import { setMentions } from '@urbit/api/dist';
|
||||
import React from 'react';
|
||||
import { Setting } from '../../components/Setting';
|
||||
import { pokeOptimisticallyN } from '../../state/base';
|
||||
import { HarkState, reduceGraph, useHarkStore } from '../../state/hark';
|
||||
import { useSettingsState, SettingsState } from '../../state/settings';
|
||||
import { usePreferencesStore } from './usePreferencesStore';
|
||||
|
||||
const selDnd = (s: SettingsState) => s.display.doNotDisturb;
|
||||
async function toggleDnd() {
|
||||
@ -9,9 +11,15 @@ async function toggleDnd() {
|
||||
await state.putEntry('display', 'doNotDisturb', !selDnd(state));
|
||||
}
|
||||
|
||||
const selMentions = (s: HarkState) => s.notificationsGraphConfig.mentions;
|
||||
async function toggleMentions() {
|
||||
const state = useHarkStore.getState();
|
||||
await pokeOptimisticallyN(useHarkStore, setMentions(!selMentions(state)), reduceGraph);
|
||||
}
|
||||
|
||||
export const NotificationPrefs = () => {
|
||||
const { mentions, toggleMentions } = usePreferencesStore();
|
||||
const doNotDisturb = useSettingsState(selDnd);
|
||||
const mentions = useHarkStore(selMentions);
|
||||
|
||||
return (
|
||||
<>
|
||||
|
@ -1,12 +1,57 @@
|
||||
import create from 'zustand';
|
||||
import _ from 'lodash';
|
||||
import { NotificationGraphConfig } from '@urbit/api';
|
||||
import { Notification } from './hark-types';
|
||||
import { mockNotification } from './mock-data';
|
||||
import { useMockData } from './util';
|
||||
import { BaseState, createState, createSubscription, reduceStateN } from './base';
|
||||
|
||||
interface HarkStore {
|
||||
export interface HarkState {
|
||||
notifications: Notification[];
|
||||
notificationsGraphConfig: NotificationGraphConfig;
|
||||
[ref: string]: unknown;
|
||||
}
|
||||
|
||||
export const useHarkStore = create<HarkStore>(() => ({
|
||||
notifications: useMockData ? [mockNotification] : []
|
||||
}));
|
||||
type BaseHarkState = HarkState & BaseState<HarkState>;
|
||||
|
||||
function updateState(
|
||||
key: string,
|
||||
transform: (state: BaseHarkState, data: any) => void
|
||||
): (json: any, state: BaseHarkState) => BaseHarkState {
|
||||
return (json: any, state: BaseHarkState) => {
|
||||
if (_.has(json, key)) {
|
||||
transform(state, _.get(json, key, undefined));
|
||||
}
|
||||
return state;
|
||||
};
|
||||
}
|
||||
|
||||
export const reduceGraph = [
|
||||
updateState('initial', (draft, data) => {
|
||||
draft.notificationsGraphConfig = data;
|
||||
}),
|
||||
updateState('set-mentions', (draft, data) => {
|
||||
draft.notificationsGraphConfig.mentions = data;
|
||||
})
|
||||
];
|
||||
|
||||
export const useHarkStore = createState<HarkState>(
|
||||
'Hark',
|
||||
() => ({
|
||||
notifications: useMockData ? [mockNotification] : [],
|
||||
notificationsGraphConfig: {
|
||||
watchOnSelf: false,
|
||||
mentions: false,
|
||||
watching: []
|
||||
}
|
||||
}),
|
||||
[],
|
||||
[
|
||||
(set, get) =>
|
||||
createSubscription('hark-graph-hook', '/updates', (j) => {
|
||||
const graphHookData = _.get(j, 'hark-graph-hook-update', false);
|
||||
if (graphHookData) {
|
||||
reduceStateN(get(), graphHookData, reduceGraph);
|
||||
}
|
||||
})
|
||||
]
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user