Skip to content

Commit 92179d5

Browse files
committed
fix: One store for Notifications + dev button to create notis
1 parent 8f08812 commit 92179d5

File tree

7 files changed

+91
-49
lines changed

7 files changed

+91
-49
lines changed

apps/frontend/src/RootLayout.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { getProgramInfo } from '@onelauncher/client';
22
import AnimatedRoutes from '~ui/components/AnimatedRoutes';
3+
import { NotificationProvider } from '~ui/hooks/useNotifications';
34
import { onMount, type ParentProps } from 'solid-js';
45
import { MultiProvider } from './ui/components/MultiProvider';
56
import { AccountControllerProvider } from './ui/components/overlay/account/AddAccountModal';
@@ -39,6 +40,7 @@ function GlobalContexts(props: ParentProps) {
3940
<MultiProvider
4041
values={[
4142
ModalProvider,
43+
NotificationProvider,
4244
SettingsProvider,
4345
AccountControllerProvider,
4446
ClusterModalControllerProvider,

apps/frontend/src/ui/components/overlay/notifications/NotificationComponent.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ function NotificationOverlayComponent(props: NotificationComponentProps) {
7676
</div>
7777

7878
<Show when={disappearing() === true}>
79-
<div class="h-1.5 w-full bg-brand-disabled">
79+
<div class="h-1.5 w-full bg-brand-disabled/10">
8080
<div
8181
class="h-1.5 rounded-lg bg-brand transition-width"
8282
style={{
@@ -101,7 +101,7 @@ function NotificationPopupComponent(props: NotificationComponentProps) {
101101

102102
<div class="w-full flex flex-col gap-y-1">
103103
<span class="text-fg-primary font-medium capitalize">{props.title}</span>
104-
<span class="text-sm text-white/60 capitalize">{props.message}</span>
104+
<span class="text-sm text-fg-secondary/60 capitalize">{props.message}</span>
105105
</div>
106106

107107
<Show when={props.overlay !== true}>

apps/frontend/src/ui/components/overlay/notifications/NotificationOverlay.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import Popup from '../Popup';
44
import NotificationComponent from './NotificationComponent';
55

66
export default function NotificationOverlay() {
7-
const [notifications] = useNotifications();
7+
const notifications = useNotifications();
88

99
return (
1010
<Popup
@@ -14,7 +14,7 @@ export default function NotificationOverlay() {
1414
visible={() => true}
1515
>
1616
<div class="flex flex-col-reverse gap-2">
17-
<For each={Object.values(notifications())}>
17+
<For each={Object.values(notifications.list())}>
1818
{notification => (
1919
<NotificationComponent overlay {...notification} />
2020
)}

apps/frontend/src/ui/components/overlay/notifications/NotificationPopup.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,22 @@ import Popup, { type PopupProps } from '../Popup';
77
import NotificationComponent from './NotificationComponent';
88

99
function NotificationPopup(props: PopupProps) {
10-
const [notifications, setNotifications] = useNotifications();
10+
const notifications = useNotifications();
1111

1212
let inner!: HTMLDivElement;
1313
let parent!: HTMLDivElement;
1414

15-
createEffect(on(notifications, () => {
15+
createEffect(on(notifications.list, () => {
1616
if (inner && parent) {
1717
const rect = inner.getBoundingClientRect();
1818
parent.style.height = `${rect.height}px`;
1919
}
2020
}));
2121

22-
const memoedNotifications = createMemo(() => Object.values(notifications()));
22+
const memoedNotifications = createMemo(() => Object.values(notifications.list()));
2323

2424
function clearNotifications() {
25-
setNotifications({});
25+
notifications.clear();
2626
}
2727

2828
return (

apps/frontend/src/ui/hooks/useNotifications.ts

Lines changed: 0 additions & 40 deletions
This file was deleted.
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import type { UnlistenFn } from '@tauri-apps/api/event';
2+
import type { NotificationData } from '~ui/components/overlay/notifications/NotificationComponent';
3+
import { events } from '@onelauncher/client/bindings';
4+
import { type Accessor, type Context, createContext, createSignal, onCleanup, onMount, type ParentProps, type Signal, useContext } from 'solid-js';
5+
6+
type Notifications = Record<string, NotificationData>;
7+
8+
interface HookReturn {
9+
list: Accessor<Notifications>;
10+
set: (id: string, data: NotificationData) => void;
11+
clear: () => void;
12+
}
13+
14+
const NotificationContext = createContext() as Context<Signal<Notifications>>;
15+
16+
export function NotificationProvider(props: ParentProps) {
17+
const [notifications, setNotifications] = createSignal<Notifications>({});
18+
let unlisten: UnlistenFn | undefined;
19+
20+
onMount(() => {
21+
events.ingressPayload.listen((e) => {
22+
setNotifications(notifications => ({
23+
...notifications,
24+
[e.payload.ingress_uuid]: {
25+
title: e.payload.event.type.replaceAll('_', ' '),
26+
message: e.payload.message,
27+
fraction: e.payload.fraction ?? undefined,
28+
},
29+
}));
30+
}).then(u => unlisten = u);
31+
});
32+
33+
onCleanup(() => {
34+
unlisten?.();
35+
});
36+
37+
return (
38+
<NotificationContext.Provider value={[notifications, setNotifications]}>
39+
{props.children}
40+
</NotificationContext.Provider>
41+
);
42+
}
43+
44+
function useNotifications(): HookReturn {
45+
const [notifications, setNotifications] = useContext(NotificationContext);
46+
47+
return {
48+
list: notifications,
49+
set: (id, data) => setNotifications(notifications => ({ ...notifications, [id]: data })),
50+
clear: () => setNotifications({}),
51+
};
52+
}
53+
54+
export default useNotifications;

apps/frontend/src/ui/pages/settings/about/SettingsDeveloper.tsx

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,35 @@
11
import { useNavigate } from '@solidjs/router';
2-
import { CodeBrowserIcon, EyeIcon, GitMergeIcon, LinkExternal01Icon, RefreshCcw05Icon } from '@untitled-theme/icons-solid';
2+
import { CodeBrowserIcon, EyeIcon, GitMergeIcon, LinkExternal01Icon, PlusIcon, RefreshCcw05Icon } from '@untitled-theme/icons-solid';
33
import Button from '~ui/components/base/Button';
44
import Toggle from '~ui/components/base/Toggle';
55
import ScrollableContainer from '~ui/components/ScrollableContainer';
66
import SettingsRow from '~ui/components/SettingsRow';
77
import Sidebar from '~ui/components/Sidebar';
8+
import useNotifications from '~ui/hooks/useNotifications';
89
import useSettings from '~ui/hooks/useSettings';
10+
import { createSignal } from 'solid-js';
911

1012
function SettingsDeveloper() {
13+
const notifications = useNotifications();
1114
const { settings, saveOnLeave } = useSettings();
1215
const navigate = useNavigate();
1316

17+
const [notiCounter, setNotiCounter] = createSignal(0);
18+
1419
saveOnLeave(() => ({
1520
debug_mode: settings().debug_mode!,
1621
onboarding_completed: settings().onboarding_completed!,
1722
}));
1823

24+
function createTestNotification() {
25+
notifications.set(`test_notification${notiCounter()}`, {
26+
title: `Test Notification ${notiCounter()}`,
27+
message: 'Test Notification Message body',
28+
});
29+
30+
setNotiCounter(count => count + 1);
31+
}
32+
1933
return (
2034
<Sidebar.Page>
2135
<h1>Developer Options</h1>
@@ -70,6 +84,18 @@ function SettingsDeveloper() {
7084
/>
7185
</SettingsRow>
7286

87+
<SettingsRow
88+
description="Creates a test notification."
89+
icon={<EyeIcon />}
90+
title="Create Test Notification"
91+
>
92+
<Button
93+
children="Create"
94+
iconLeft={<PlusIcon />}
95+
onClick={createTestNotification}
96+
/>
97+
</SettingsRow>
98+
7399
</ScrollableContainer>
74100
</Sidebar.Page>
75101
);

0 commit comments

Comments
 (0)