summaryrefslogtreecommitdiff
path: root/front/src/state/state.ts
diff options
context:
space:
mode:
Diffstat (limited to 'front/src/state/state.ts')
-rw-r--r--front/src/state/state.ts58
1 files changed, 58 insertions, 0 deletions
diff --git a/front/src/state/state.ts b/front/src/state/state.ts
index 715427d..f329145 100644
--- a/front/src/state/state.ts
+++ b/front/src/state/state.ts
@@ -6,6 +6,7 @@ import { create } from "zustand";
import type { UserProfile } from "@/types/nostrill";
import type { Event } from "@/types/nostr";
import type { FC, Poast } from "@/types/trill";
+import type { Notification } from "@/types/notifications";
import { useShallow } from "zustand/shallow";
// TODO handle airlock connection issues
// the SSE pipeline has a "status-update" event FWIW
@@ -26,6 +27,16 @@ export type LocalState = {
addProfile: (key: string, u: UserProfile) => void;
following: Map<string, FC>;
followers: string[];
+ // Notifications
+ notifications: Notification[];
+ unreadNotifications: number;
+ addNotification: (
+ notification: Omit<Notification, "id" | "timestamp" | "read">,
+ ) => void;
+ markNotificationRead: (id: string) => void;
+ markAllNotificationsRead: () => void;
+ clearNotifications: () => void;
+ lastFact: any;
};
const creator = create<LocalState>();
@@ -50,6 +61,20 @@ export const useStore = creator((set, get) => ({
pubkey,
});
} else if ("fact" in data) {
+ set({ lastFact: data.fact });
+ if ("fols" in data.fact) {
+ const { following, profiles } = get();
+ if ("new" in data.fact.fols) {
+ const { user, feed, profile } = data.fact.fols.new;
+ following.set(user, feed);
+ if (profile) profiles.set(user, profile);
+ set({ following, profiles });
+ }
+ if ("quit" in data.fact.fols) {
+ following.delete(data.fact.fols.quit);
+ set({ following });
+ }
+ }
if ("post" in data.fact) {
if ("add" in data.fact.post) {
const post: Poast = data.fact.post.add.post;
@@ -73,6 +98,7 @@ export const useStore = creator((set, get) => ({
profiles.set(key, profile);
set({ profiles });
},
+ lastFact: null,
relays: {},
nostrFeed: [],
following: new Map(),
@@ -83,6 +109,38 @@ export const useStore = creator((set, get) => ({
// composer data
composerData: null,
setComposerData: (composerData) => set({ composerData }),
+ // Notifications
+ notifications: [],
+ unreadNotifications: 0,
+ addNotification: (notification) => {
+ const newNotification: Notification = {
+ ...notification,
+ id: `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
+ timestamp: new Date(),
+ read: false,
+ };
+ set((state) => ({
+ notifications: [newNotification, ...state.notifications],
+ unreadNotifications: state.unreadNotifications + 1,
+ }));
+ },
+ markNotificationRead: (id) => {
+ set((state) => ({
+ notifications: state.notifications.map((n) =>
+ n.id === id ? { ...n, read: true } : n,
+ ),
+ unreadNotifications: Math.max(0, state.unreadNotifications - 1),
+ }));
+ },
+ markAllNotificationsRead: () => {
+ set((state) => ({
+ notifications: state.notifications.map((n) => ({ ...n, read: true })),
+ unreadNotifications: 0,
+ }));
+ },
+ clearNotifications: () => {
+ set({ notifications: [], unreadNotifications: 0 });
+ },
}));
const useShallowStore = <T extends (state: LocalState) => any>(