Skip to content

Commit 1780df9

Browse files
committed
activity: make bell work closer to old desktop
1 parent d630acc commit 1780df9

File tree

12 files changed

+169
-11
lines changed

12 files changed

+169
-11
lines changed

packages/app/navigation/desktop/TopLevelDrawer.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ const Drawer = createDrawerNavigator<RootDrawerParamList>();
3030

3131
const DrawerContent = (props: DrawerContentComponentProps) => {
3232
const userId = useCurrentUserId();
33-
const haveUnreadUnseenActivity = store.useHaveUnreadUnseenActivity();
33+
const { data: baseUnread } = store.useBaseUnread();
3434
const { webAppNeedsUpdate, triggerWebAppUpdate } = useWebAppUpdate();
3535
const lastHomeStateRef =
3636
useRef<DrawerNavigationState<RootDrawerParamList> | null>(null);
@@ -96,7 +96,7 @@ const DrawerContent = (props: DrawerContentComponentProps) => {
9696
<NavIcon
9797
type="Notifications"
9898
activeType="NotificationsFilled"
99-
hasUnreads={haveUnreadUnseenActivity}
99+
hasUnreads={baseUnread?.notify || false}
100100
isActive={isRouteActive('Activity')}
101101
onPress={() => {
102102
saveHomeState();

packages/shared/src/api/activityApi.ts

+37-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import {
1313
parseGroupId,
1414
udToDate,
1515
} from './apiUtils';
16-
import { poke, scry, subscribe } from './urbit';
16+
import { getCurrentUserId, poke, scry, subscribe } from './urbit';
1717

1818
const logger = createDevLogger('activityApi', false);
1919

@@ -378,6 +378,7 @@ function getInfoFromMessageKey(
378378
}
379379

380380
export type ActivityEvent =
381+
| { type: 'updateBaseUnread'; unread: db.BaseUnread }
381382
| {
382383
type: 'updateChannelUnread';
383384
activity: db.ChannelUnread;
@@ -414,6 +415,18 @@ export function subscribeToActivity(handler: (event: ActivityEvent) => void) {
414415
const source = sourceIdToSource(sourceId);
415416

416417
switch (source.type) {
418+
case 'base':
419+
handler({
420+
type: 'updateBaseUnread',
421+
unread: {
422+
userId: getCurrentUserId(),
423+
count: summary.count,
424+
notify: summary.notify,
425+
notifyCount: summary['notify-count'],
426+
updatedAt: summary.recency,
427+
},
428+
});
429+
break;
417430
case 'group':
418431
handler({
419432
type: 'updateGroupUnread',
@@ -724,6 +737,10 @@ export function getMessageKey(
724737
Sources can be represented as a string or an object (see urbit/activity.ts for details).
725738
*/
726739

740+
interface ClientBaseSource {
741+
type: 'base';
742+
}
743+
727744
interface ClientGroupSource {
728745
type: 'group';
729746
groupId: string;
@@ -751,13 +768,18 @@ interface ClientContactSource {
751768
}
752769

753770
export type ClientSource =
771+
| ClientBaseSource
754772
| ClientGroupSource
755773
| ClientChannelSource
756774
| ClientThreadSource
757775
| ClientUnknownSource
758776
| ClientContactSource;
759777

760778
export function sourceIdToSource(sourceId: string): ClientSource {
779+
if (sourceId === 'base') {
780+
return { type: 'base' };
781+
}
782+
761783
const parts = sourceId.split('/');
762784
const sourceType = parts[0];
763785

@@ -934,6 +956,7 @@ export async function getPushNotificationsSetting(): Promise<ub.PushNotification
934956
}
935957

936958
export type ActivityUpdateQueue = {
959+
baseUnread?: db.BaseUnread;
937960
groupUnreads: db.GroupUnread[];
938961
channelUnreads: db.ChannelUnread[];
939962
threadUnreads: db.ThreadUnreadState[];
@@ -942,17 +965,29 @@ export type ActivityUpdateQueue = {
942965
};
943966

944967
export type ActivityInit = {
968+
baseUnread?: db.BaseUnread;
945969
groupUnreads: db.GroupUnread[];
946970
channelUnreads: db.ChannelUnread[];
947971
threadActivity: db.ThreadUnreadState[];
948972
};
949973

950974
export const toClientUnreads = (activity: ub.Activity): ActivityInit => {
975+
const userId = getCurrentUserId();
951976
const groupUnreads: db.GroupUnread[] = [];
952977
const channelUnreads: db.ChannelUnread[] = [];
953978
const threadActivity: db.ThreadUnreadState[] = [];
979+
let baseUnread: db.BaseUnread | undefined = undefined;
954980

955981
Object.entries(activity).forEach(([sourceId, summary]) => {
982+
if (sourceId === 'base') {
983+
baseUnread = {
984+
userId,
985+
count: summary.count,
986+
notify: summary.notify,
987+
notifyCount: summary['notify-count'],
988+
updatedAt: summary.recency,
989+
};
990+
}
956991
const [activityId, ...rest] = sourceId.split('/');
957992
if (activityId === 'ship' || activityId === 'club') {
958993
const channelId = rest.join('/');
@@ -984,7 +1019,7 @@ export const toClientUnreads = (activity: ub.Activity): ActivityInit => {
9841019
}
9851020
});
9861021

987-
return { channelUnreads, threadActivity, groupUnreads };
1022+
return { baseUnread, channelUnreads, threadActivity, groupUnreads };
9881023
};
9891024

9901025
export const toGroupUnread = (

packages/shared/src/db/migrations/0000_sour_wonder_man.sql packages/shared/src/db/migrations/0000_slow_luminals.sql

+12-2
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,14 @@ CREATE TABLE `activity_events` (
2828
PRIMARY KEY(`id`, `bucket_id`)
2929
);
3030
--> statement-breakpoint
31+
CREATE TABLE `base_unreads` (
32+
`user_id` text PRIMARY KEY NOT NULL,
33+
`notify` integer,
34+
`count` integer,
35+
`notify_count` integer,
36+
`updated_at` integer NOT NULL
37+
);
38+
--> statement-breakpoint
3139
CREATE TABLE `channel_readers` (
3240
`channel_id` text NOT NULL,
3341
`role_id` text NOT NULL,
@@ -95,7 +103,8 @@ CREATE TABLE `group_members` (
95103
`contact_id` text NOT NULL,
96104
`joined_at` integer,
97105
`status` text,
98-
PRIMARY KEY(`chat_id`, `contact_id`)
106+
PRIMARY KEY(`chat_id`, `contact_id`),
107+
FOREIGN KEY (`chat_id`) REFERENCES `channels`(`id`) ON UPDATE no action ON DELETE cascade
99108
);
100109
--> statement-breakpoint
101110
CREATE TABLE `contact_group_pins` (
@@ -299,7 +308,8 @@ CREATE TABLE `posts` (
299308
`last_edit_title` text,
300309
`last_edit_image` text,
301310
`synced_at` integer,
302-
`backend_time` text
311+
`backend_time` text,
312+
FOREIGN KEY (`channel_id`) REFERENCES `channels`(`id`) ON UPDATE no action ON DELETE cascade
303313
);
304314
--> statement-breakpoint
305315
CREATE UNIQUE INDEX `posts_sent_at_unique` ON `posts` (`sent_at`);--> statement-breakpoint

packages/shared/src/db/migrations/meta/0000_snapshot.json

+46-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"version": "6",
33
"dialect": "sqlite",
4-
"id": "fa25c16a-e15a-45be-9783-6405cc7a2e14",
4+
"id": "2382e17a-2a61-410f-a131-80c411b4f4fb",
55
"prevId": "00000000-0000-0000-0000-000000000000",
66
"tables": {
77
"activity_event_contact_group_pins": {
@@ -207,6 +207,51 @@
207207
"uniqueConstraints": {},
208208
"checkConstraints": {}
209209
},
210+
"base_unreads": {
211+
"name": "base_unreads",
212+
"columns": {
213+
"user_id": {
214+
"name": "user_id",
215+
"type": "text",
216+
"primaryKey": true,
217+
"notNull": true,
218+
"autoincrement": false
219+
},
220+
"notify": {
221+
"name": "notify",
222+
"type": "integer",
223+
"primaryKey": false,
224+
"notNull": false,
225+
"autoincrement": false
226+
},
227+
"count": {
228+
"name": "count",
229+
"type": "integer",
230+
"primaryKey": false,
231+
"notNull": false,
232+
"autoincrement": false
233+
},
234+
"notify_count": {
235+
"name": "notify_count",
236+
"type": "integer",
237+
"primaryKey": false,
238+
"notNull": false,
239+
"autoincrement": false
240+
},
241+
"updated_at": {
242+
"name": "updated_at",
243+
"type": "integer",
244+
"primaryKey": false,
245+
"notNull": true,
246+
"autoincrement": false
247+
}
248+
},
249+
"indexes": {},
250+
"foreignKeys": {},
251+
"compositePrimaryKeys": {},
252+
"uniqueConstraints": {},
253+
"checkConstraints": {}
254+
},
210255
"channel_readers": {
211256
"name": "channel_readers",
212257
"columns": {

packages/shared/src/db/migrations/meta/_journal.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
{
66
"idx": 0,
77
"version": "6",
8-
"when": 1742234785697,
9-
"tag": "0000_sour_wonder_man",
8+
"when": 1742417414724,
9+
"tag": "0000_slow_luminals",
1010
"breakpoints": true
1111
}
1212
]

packages/shared/src/db/migrations/migrations.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// This file is required for Expo/React Native SQLite migrations - https://orm.drizzle.team/quick-sqlite/expo
22

33
import journal from './meta/_journal.json';
4-
import m0000 from './0000_sour_wonder_man.sql';
4+
import m0000 from './0000_slow_luminals.sql';
55

66
export default {
77
journal,

packages/shared/src/db/queries.ts

+27
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ import {
4949
import {
5050
activityEventContactGroups as $activityEventContactGroups,
5151
activityEvents as $activityEvents,
52+
baseUnreads as $baseUnreads,
5253
channelReaders as $channelReaders,
5354
channelUnreads as $channelUnreads,
5455
channelWriters as $channelWriters,
@@ -80,6 +81,7 @@ import {
8081
import {
8182
ActivityBucket,
8283
ActivityEvent,
84+
BaseUnread,
8385
Channel,
8486
ChannelUnread,
8587
Chat,
@@ -1555,6 +1557,16 @@ export const getGroupUnread = createReadQuery(
15551557
['groupUnreads']
15561558
);
15571559

1560+
export const getBaseUnread = createReadQuery(
1561+
'getBaseUnread',
1562+
async (userId: string, ctx: QueryCtx) => {
1563+
return ctx.db.query.baseUnreads.findFirst({
1564+
where: eq($baseUnreads.userId, userId),
1565+
});
1566+
},
1567+
['baseUnreads']
1568+
);
1569+
15581570
export const getThreadActivity = createReadQuery(
15591571
'getThreadActivity',
15601572
async (
@@ -3324,6 +3336,21 @@ export const insertGroupUnreads = createWriteQuery(
33243336
['groupUnreads']
33253337
);
33263338

3339+
export const insertBaseUnread = createWriteQuery(
3340+
'insertBaseUnread',
3341+
async (unread: BaseUnread, ctx: QueryCtx) => {
3342+
logger.log('insertBaseUnread', unread);
3343+
return ctx.db
3344+
.insert($baseUnreads)
3345+
.values([unread])
3346+
.onConflictDoUpdate({
3347+
target: [$baseUnreads.userId],
3348+
set: conflictUpdateSetAll($baseUnreads),
3349+
});
3350+
},
3351+
['baseUnreads']
3352+
);
3353+
33273354
export const updateGroupUnreadCount = createWriteQuery(
33283355
'updateGroupUnreadCount',
33293356
async (

packages/shared/src/db/schema.ts

+8
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,14 @@ export const groupUnreadsRelations = relations(groupUnreads, ({ one }) => ({
180180
}),
181181
}));
182182

183+
export const baseUnreads = sqliteTable('base_unreads', {
184+
userId: text('user_id').primaryKey(),
185+
notify: boolean('notify'),
186+
count: integer('count'),
187+
notifyCount: integer('notify_count'),
188+
updatedAt: timestamp('updated_at').notNull(),
189+
});
190+
183191
export type ActivityBucket = 'all' | 'mentions' | 'replies';
184192
export const activityEvents = sqliteTable(
185193
'activity_events',

packages/shared/src/db/types.ts

+1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ export type Contact = BaseModel<'contacts'> & {
4040
export type ContactPinnedGroups = Contact['pinnedGroups'];
4141
export type ChannelUnread = BaseModel<'channelUnreads'>;
4242
export type GroupUnread = BaseModel<'groupUnreads'>;
43+
export type BaseUnread = BaseModel<'baseUnreads'>;
4344
export type ActivityEvent = BaseModel<'activityEvents'>;
4445
export type ActivityEventContactUpdateGroups =
4546
ActivityEvent['contactUpdateGroups'];

packages/shared/src/store/activityActions.ts

+9
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,15 @@ export async function advanceActivitySeenMarker(timestamp: number) {
136136
const currentUserId = api.getCurrentUserId();
137137
const settings = await db.getSettings(currentUserId);
138138
const existingMarker = settings?.activitySeenTimestamp ?? 1;
139+
const base = await db.getBaseUnread(currentUserId);
140+
if (base) {
141+
await db.insertBaseUnread({
142+
...base,
143+
userId: currentUserId,
144+
notify: false,
145+
notifyCount: 0,
146+
});
147+
}
139148
if (timestamp > existingMarker) {
140149
// optimistic update
141150
db.insertSettings({

packages/shared/src/store/dbHooks.ts

+11
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,17 @@ export const useLiveGroupUnread = (unread: db.GroupUnread | null) => {
277277
});
278278
};
279279

280+
export const useBaseUnread = () => {
281+
const depsKey = useKeyFromQueryDeps(db.getBaseUnread);
282+
const userId = api.getCurrentUserId();
283+
return useQuery({
284+
queryKey: ['baseUnreads', depsKey, userId],
285+
queryFn: async () => {
286+
return db.getBaseUnread(userId);
287+
},
288+
});
289+
};
290+
280291
export const useLiveUnread = (
281292
unread: db.ChannelUnread | db.ThreadUnreadState | db.GroupUnread | null
282293
) => {

0 commit comments

Comments
 (0)