Add client notification (#771)

* ClientNotification WIP

* Test

* ClientNotification WIP

* Add client notification dialog and related functionality

* Update ClientNotificationDialog.tsx

---------

Co-authored-by: philon- <philon-@users.noreply.github.com>
This commit is contained in:
Jeremy Gallant
2025-08-10 21:59:03 -04:00
committed by GitHub
co-authored by philon-
parent 176d554ef9
commit 32f31cb502
8 changed files with 160 additions and 0 deletions
@@ -44,7 +44,10 @@ export const mockDeviceStore: Device = {
refreshKeys: false,
deleteMessages: false,
managedMode: false,
clientNotification: false,
},
clientNotifications: [],
setStatus: vi.fn(),
setConfig: vi.fn(),
setModuleConfig: vi.fn(),
@@ -85,6 +88,9 @@ export const mockDeviceStore: Device = {
sendAdminMessage: vi.fn(),
updateFavorite: vi.fn(),
updateIgnored: vi.fn(),
addClientNotification: vi.fn(),
removeClientNotification: vi.fn(),
getClientNotification: vi.fn(),
getAllUnreadCount: vi.fn().mockReturnValue(0),
getUnreadCount: vi.fn().mockReturnValue(0),
};
@@ -62,7 +62,9 @@ export interface Device {
refreshKeys: boolean;
deleteMessages: boolean;
managedMode: boolean;
clientNotification: boolean;
};
clientNotifications: Protobuf.Mesh.ClientNotification[];
setStatus: (status: Types.DeviceStatusEnum) => void;
setConfig: (config: Protobuf.Config.Config) => void;
@@ -125,6 +127,13 @@ export interface Device {
sendAdminMessage: (message: Protobuf.Admin.AdminMessage) => void;
updateFavorite: (nodeNum: number, isFavorite: boolean) => void;
updateIgnored: (nodeNum: number, isIgnored: boolean) => void;
addClientNotification: (
clientNotificationPacket: Protobuf.Mesh.ClientNotification,
) => void;
removeClientNotification: (index: number) => void;
getClientNotification: (
index: number,
) => Protobuf.Mesh.ClientNotification | undefined;
}
export interface DeviceState {
@@ -173,12 +182,14 @@ export const useDeviceStore = createStore<PrivateDeviceState>((set, get) => ({
refreshKeys: false,
deleteMessages: false,
managedMode: false,
clientNotification: false,
},
pendingSettingsChanges: false,
messageDraft: "",
nodeErrors: new Map(),
unreadCounts: new Map(),
nodesMap: new Map(),
clientNotifications: [],
setStatus: (status: Types.DeviceStatusEnum) => {
set(
@@ -847,6 +858,37 @@ export const useDeviceStore = createStore<PrivateDeviceState>((set, get) => ({
}),
);
},
addClientNotification: (
clientNotificationPacket: Protobuf.Mesh.ClientNotification,
) => {
set(
produce<PrivateDeviceState>((draft) => {
const device = draft.devices.get(id);
if (!device) {
return;
}
device.clientNotifications.push(clientNotificationPacket);
}),
);
},
removeClientNotification: (index: number) => {
set(
produce<PrivateDeviceState>((draft) => {
const device = draft.devices.get(id);
if (!device) {
return;
}
device.clientNotifications.splice(index, 1);
}),
);
},
getClientNotification: (index: number) => {
const device = get().devices.get(id);
if (!device) {
return;
}
return device.clientNotifications[index];
},
});
}),
);
+7
View File
@@ -114,6 +114,13 @@ export const subscribeAll = (
});
});
connection.events.onClientNotificationPacket.subscribe(
(clientNotificationPacket) => {
device.addClientNotification(clientNotificationPacket);
device.setDialogOpen("clientNotification", true);
},
);
connection.events.onRoutingPacket.subscribe((routingPacket) => {
if (routingPacket.data.variant.case === "errorReason") {
switch (routingPacket.data.variant.value) {