fix: One store for Notifications + dev button to create notis
This commit is contained in:
parent
8f08812216
commit
92179d5419
7 changed files with 91 additions and 49 deletions
|
|
@ -1,5 +1,6 @@
|
|||
import { getProgramInfo } from '@onelauncher/client';
|
||||
import AnimatedRoutes from '~ui/components/AnimatedRoutes';
|
||||
import { NotificationProvider } from '~ui/hooks/useNotifications';
|
||||
import { onMount, type ParentProps } from 'solid-js';
|
||||
import { MultiProvider } from './ui/components/MultiProvider';
|
||||
import { AccountControllerProvider } from './ui/components/overlay/account/AddAccountModal';
|
||||
|
|
@ -39,6 +40,7 @@ function GlobalContexts(props: ParentProps) {
|
|||
<MultiProvider
|
||||
values={[
|
||||
ModalProvider,
|
||||
NotificationProvider,
|
||||
SettingsProvider,
|
||||
AccountControllerProvider,
|
||||
ClusterModalControllerProvider,
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ function NotificationOverlayComponent(props: NotificationComponentProps) {
|
|||
</div>
|
||||
|
||||
<Show when={disappearing() === true}>
|
||||
<div class="h-1.5 w-full bg-brand-disabled">
|
||||
<div class="h-1.5 w-full bg-brand-disabled/10">
|
||||
<div
|
||||
class="h-1.5 rounded-lg bg-brand transition-width"
|
||||
style={{
|
||||
|
|
@ -101,7 +101,7 @@ function NotificationPopupComponent(props: NotificationComponentProps) {
|
|||
|
||||
<div class="w-full flex flex-col gap-y-1">
|
||||
<span class="text-fg-primary font-medium capitalize">{props.title}</span>
|
||||
<span class="text-sm text-white/60 capitalize">{props.message}</span>
|
||||
<span class="text-sm text-fg-secondary/60 capitalize">{props.message}</span>
|
||||
</div>
|
||||
|
||||
<Show when={props.overlay !== true}>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import Popup from '../Popup';
|
|||
import NotificationComponent from './NotificationComponent';
|
||||
|
||||
export default function NotificationOverlay() {
|
||||
const [notifications] = useNotifications();
|
||||
const notifications = useNotifications();
|
||||
|
||||
return (
|
||||
<Popup
|
||||
|
|
@ -14,7 +14,7 @@ export default function NotificationOverlay() {
|
|||
visible={() => true}
|
||||
>
|
||||
<div class="flex flex-col-reverse gap-2">
|
||||
<For each={Object.values(notifications())}>
|
||||
<For each={Object.values(notifications.list())}>
|
||||
{notification => (
|
||||
<NotificationComponent overlay {...notification} />
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -7,22 +7,22 @@ import Popup, { type PopupProps } from '../Popup';
|
|||
import NotificationComponent from './NotificationComponent';
|
||||
|
||||
function NotificationPopup(props: PopupProps) {
|
||||
const [notifications, setNotifications] = useNotifications();
|
||||
const notifications = useNotifications();
|
||||
|
||||
let inner!: HTMLDivElement;
|
||||
let parent!: HTMLDivElement;
|
||||
|
||||
createEffect(on(notifications, () => {
|
||||
createEffect(on(notifications.list, () => {
|
||||
if (inner && parent) {
|
||||
const rect = inner.getBoundingClientRect();
|
||||
parent.style.height = `${rect.height}px`;
|
||||
}
|
||||
}));
|
||||
|
||||
const memoedNotifications = createMemo(() => Object.values(notifications()));
|
||||
const memoedNotifications = createMemo(() => Object.values(notifications.list()));
|
||||
|
||||
function clearNotifications() {
|
||||
setNotifications({});
|
||||
notifications.clear();
|
||||
}
|
||||
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -1,40 +0,0 @@
|
|||
import type { UnlistenFn } from '@tauri-apps/api/event';
|
||||
import type { NotificationData } from '~ui/components/overlay/notifications/NotificationComponent';
|
||||
import { events } from '@onelauncher/client/bindings';
|
||||
import { createSignal, onCleanup, onMount, type Signal } from 'solid-js';
|
||||
|
||||
type Notifications = Record<string, NotificationData>;
|
||||
type OnUpdateFn = () => unknown;
|
||||
|
||||
function useNotifications(onUpdate?: OnUpdateFn): Signal<Notifications> {
|
||||
const [notifications, setNotifications] = createSignal<Notifications>({});
|
||||
let unlisten: UnlistenFn | undefined;
|
||||
|
||||
async function update(id: string, data: NotificationData) {
|
||||
setNotifications((notifications) => {
|
||||
notifications[id] = data;
|
||||
return {
|
||||
...notifications,
|
||||
};
|
||||
});
|
||||
|
||||
if (onUpdate)
|
||||
onUpdate();
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
events.ingressPayload.listen(e => update(e.payload.ingress_uuid, {
|
||||
title: e.payload.event.type.replaceAll('_', ' '),
|
||||
message: e.payload.message,
|
||||
fraction: e.payload.fraction ?? undefined,
|
||||
})).then(u => unlisten = u);
|
||||
});
|
||||
|
||||
onCleanup(() => {
|
||||
unlisten?.();
|
||||
});
|
||||
|
||||
return [notifications, setNotifications];
|
||||
}
|
||||
|
||||
export default useNotifications;
|
||||
54
apps/frontend/src/ui/hooks/useNotifications.tsx
Normal file
54
apps/frontend/src/ui/hooks/useNotifications.tsx
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
import type { UnlistenFn } from '@tauri-apps/api/event';
|
||||
import type { NotificationData } from '~ui/components/overlay/notifications/NotificationComponent';
|
||||
import { events } from '@onelauncher/client/bindings';
|
||||
import { type Accessor, type Context, createContext, createSignal, onCleanup, onMount, type ParentProps, type Signal, useContext } from 'solid-js';
|
||||
|
||||
type Notifications = Record<string, NotificationData>;
|
||||
|
||||
interface HookReturn {
|
||||
list: Accessor<Notifications>;
|
||||
set: (id: string, data: NotificationData) => void;
|
||||
clear: () => void;
|
||||
}
|
||||
|
||||
const NotificationContext = createContext() as Context<Signal<Notifications>>;
|
||||
|
||||
export function NotificationProvider(props: ParentProps) {
|
||||
const [notifications, setNotifications] = createSignal<Notifications>({});
|
||||
let unlisten: UnlistenFn | undefined;
|
||||
|
||||
onMount(() => {
|
||||
events.ingressPayload.listen((e) => {
|
||||
setNotifications(notifications => ({
|
||||
...notifications,
|
||||
[e.payload.ingress_uuid]: {
|
||||
title: e.payload.event.type.replaceAll('_', ' '),
|
||||
message: e.payload.message,
|
||||
fraction: e.payload.fraction ?? undefined,
|
||||
},
|
||||
}));
|
||||
}).then(u => unlisten = u);
|
||||
});
|
||||
|
||||
onCleanup(() => {
|
||||
unlisten?.();
|
||||
});
|
||||
|
||||
return (
|
||||
<NotificationContext.Provider value={[notifications, setNotifications]}>
|
||||
{props.children}
|
||||
</NotificationContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
function useNotifications(): HookReturn {
|
||||
const [notifications, setNotifications] = useContext(NotificationContext);
|
||||
|
||||
return {
|
||||
list: notifications,
|
||||
set: (id, data) => setNotifications(notifications => ({ ...notifications, [id]: data })),
|
||||
clear: () => setNotifications({}),
|
||||
};
|
||||
}
|
||||
|
||||
export default useNotifications;
|
||||
|
|
@ -1,21 +1,35 @@
|
|||
import { useNavigate } from '@solidjs/router';
|
||||
import { CodeBrowserIcon, EyeIcon, GitMergeIcon, LinkExternal01Icon, RefreshCcw05Icon } from '@untitled-theme/icons-solid';
|
||||
import { CodeBrowserIcon, EyeIcon, GitMergeIcon, LinkExternal01Icon, PlusIcon, RefreshCcw05Icon } from '@untitled-theme/icons-solid';
|
||||
import Button from '~ui/components/base/Button';
|
||||
import Toggle from '~ui/components/base/Toggle';
|
||||
import ScrollableContainer from '~ui/components/ScrollableContainer';
|
||||
import SettingsRow from '~ui/components/SettingsRow';
|
||||
import Sidebar from '~ui/components/Sidebar';
|
||||
import useNotifications from '~ui/hooks/useNotifications';
|
||||
import useSettings from '~ui/hooks/useSettings';
|
||||
import { createSignal } from 'solid-js';
|
||||
|
||||
function SettingsDeveloper() {
|
||||
const notifications = useNotifications();
|
||||
const { settings, saveOnLeave } = useSettings();
|
||||
const navigate = useNavigate();
|
||||
|
||||
const [notiCounter, setNotiCounter] = createSignal(0);
|
||||
|
||||
saveOnLeave(() => ({
|
||||
debug_mode: settings().debug_mode!,
|
||||
onboarding_completed: settings().onboarding_completed!,
|
||||
}));
|
||||
|
||||
function createTestNotification() {
|
||||
notifications.set(`test_notification${notiCounter()}`, {
|
||||
title: `Test Notification ${notiCounter()}`,
|
||||
message: 'Test Notification Message body',
|
||||
});
|
||||
|
||||
setNotiCounter(count => count + 1);
|
||||
}
|
||||
|
||||
return (
|
||||
<Sidebar.Page>
|
||||
<h1>Developer Options</h1>
|
||||
|
|
@ -70,6 +84,18 @@ function SettingsDeveloper() {
|
|||
/>
|
||||
</SettingsRow>
|
||||
|
||||
<SettingsRow
|
||||
description="Creates a test notification."
|
||||
icon={<EyeIcon />}
|
||||
title="Create Test Notification"
|
||||
>
|
||||
<Button
|
||||
children="Create"
|
||||
iconLeft={<PlusIcon />}
|
||||
onClick={createTestNotification}
|
||||
/>
|
||||
</SettingsRow>
|
||||
|
||||
</ScrollableContainer>
|
||||
</Sidebar.Page>
|
||||
);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue