mirror of
https://github.com/block/buzz.git
synced 2026-08-18 06:50:31 +02:00
fix(desktop): add channel names to feed notifications
Co-authored-by: npub1jh9wn95s0472h86ahapupaf7m6kx4v9sx2n0atj2hltcfer8k06s5n3pyf <95cae996907d7cab9f5dbf43c0f53edeac6ab0b032a6feae4abfd784e467b3f5@sprout-oss.stage.blox.sqprod.co> Signed-off-by: npub1jh9wn95s0472h86ahapupaf7m6kx4v9sx2n0atj2hltcfer8k06s5n3pyf <95cae996907d7cab9f5dbf43c0f53edeac6ab0b032a6feae4abfd784e467b3f5@sprout-oss.stage.blox.sqprod.co>
This commit is contained in:
parent
1d8d006aaf
commit
f7bae829cf
@@ -373,6 +373,7 @@ export function AppShell() {
|
||||
threadActivityFeedItems,
|
||||
getThreadReadAt,
|
||||
getMessageReadAt,
|
||||
channels,
|
||||
);
|
||||
|
||||
const dueReminderBadge = useDueReminderBadgeCount(
|
||||
|
||||
@@ -3,7 +3,7 @@ import * as React from "react";
|
||||
import { useHomeFeedQuery } from "@/features/home/hooks";
|
||||
import { useUsersBatchQuery } from "@/features/profile/hooks";
|
||||
import type { UserProfileLookup } from "@/features/profile/lib/identity";
|
||||
import type { FeedItem, HomeFeedResponse } from "@/shared/api/types";
|
||||
import type { Channel, FeedItem, HomeFeedResponse } from "@/shared/api/types";
|
||||
import {
|
||||
getDesktopNotificationPermissionState,
|
||||
requestDesktopNotificationAccess,
|
||||
@@ -376,6 +376,7 @@ export function useHomeFeedNotificationState(
|
||||
// has been revealed in-channel, even if the aggregate `thread:<root>` marker
|
||||
// has not been advanced by opening Home.
|
||||
getMessageReadAt: (messageId: string) => number | null = () => null,
|
||||
channels: ReadonlyArray<Pick<Channel, "id" | "name" | "channelType">> = [],
|
||||
) {
|
||||
useFeedDesktopNotifications(
|
||||
feed,
|
||||
@@ -384,6 +385,7 @@ export function useHomeFeedNotificationState(
|
||||
setDesktopEnabled,
|
||||
profiles,
|
||||
mutedChannelIds,
|
||||
channels,
|
||||
);
|
||||
const normalizedPubkey = pubkey?.trim().toLowerCase() ?? "";
|
||||
const [seenFeedIds, setSeenFeedIds] = React.useState<string[]>(() =>
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
import assert from "node:assert/strict";
|
||||
import test from "node:test";
|
||||
|
||||
import { enrichFeedItemChannel, notificationTitle } from "./feed.ts";
|
||||
|
||||
const feedItem = (overrides = {}) => ({
|
||||
id: "event-id",
|
||||
kind: 46011,
|
||||
pubkey: "author",
|
||||
content: "Please review",
|
||||
createdAt: 1,
|
||||
channelId: "channel-id",
|
||||
channelName: "",
|
||||
channelType: undefined,
|
||||
tags: [["h", "channel-id"]],
|
||||
category: "needs_action",
|
||||
...overrides,
|
||||
});
|
||||
|
||||
const channels = [
|
||||
{ id: "channel-id", name: "ship-room", channelType: "stream" },
|
||||
];
|
||||
|
||||
test("enriches a feed notification with its loaded channel name", () => {
|
||||
const item = enrichFeedItemChannel(feedItem(), channels);
|
||||
|
||||
assert.equal(item.channelName, "ship-room");
|
||||
assert.equal(item.channelType, "stream");
|
||||
assert.equal(notificationTitle(item), "Needs Action in #ship-room");
|
||||
});
|
||||
|
||||
test("preserves feed-provided channel metadata", () => {
|
||||
const original = feedItem({
|
||||
channelName: "backend-name",
|
||||
channelType: "forum",
|
||||
});
|
||||
const item = enrichFeedItemChannel(original, channels);
|
||||
|
||||
assert.equal(item, original);
|
||||
assert.equal(notificationTitle(item), "Needs Action in #backend-name");
|
||||
});
|
||||
|
||||
test("falls back safely when the channel list has not loaded the channel", () => {
|
||||
const original = feedItem();
|
||||
const item = enrichFeedItemChannel(original, []);
|
||||
|
||||
assert.equal(item, original);
|
||||
assert.equal(notificationTitle(item), "Needs Action");
|
||||
});
|
||||
|
||||
test("does not replace direct-message notification titles", () => {
|
||||
const original = feedItem({ channelType: "dm" });
|
||||
const item = enrichFeedItemChannel(original, [
|
||||
{ id: "channel-id", name: "not-a-title", channelType: "dm" },
|
||||
]);
|
||||
|
||||
assert.equal(notificationTitle(item, "Taylor"), "Taylor");
|
||||
});
|
||||
@@ -1,9 +1,31 @@
|
||||
import type { FeedItem, HomeFeedResponse } from "@/shared/api/types";
|
||||
import type { Channel, FeedItem, HomeFeedResponse } from "@/shared/api/types";
|
||||
import {
|
||||
formatNotificationTitle,
|
||||
truncateNotificationBody,
|
||||
} from "@/features/notifications/lib/notificationFormat";
|
||||
|
||||
export type NotificationChannel = Pick<Channel, "id" | "name" | "channelType">;
|
||||
|
||||
export function enrichFeedItemChannel(
|
||||
item: FeedItem,
|
||||
channels: readonly NotificationChannel[],
|
||||
): FeedItem {
|
||||
if (!item.channelId || item.channelName.trim()) {
|
||||
return item;
|
||||
}
|
||||
|
||||
const channel = channels.find((candidate) => candidate.id === item.channelId);
|
||||
if (!channel) {
|
||||
return item;
|
||||
}
|
||||
|
||||
return {
|
||||
...item,
|
||||
channelName: channel.name,
|
||||
channelType: item.channelType ?? channel.channelType,
|
||||
};
|
||||
}
|
||||
|
||||
export function notificationTitle(item: FeedItem, senderName?: string) {
|
||||
const channelLabel =
|
||||
item.channelType !== "dm" && item.channelName.trim()
|
||||
|
||||
@@ -10,6 +10,8 @@ import type { FeedItem, HomeFeedResponse } from "@/shared/api/types";
|
||||
import {
|
||||
collectHomeAlertItems,
|
||||
eligibleFeedNotificationItems,
|
||||
enrichFeedItemChannel,
|
||||
type NotificationChannel,
|
||||
notificationBody,
|
||||
notificationTitle,
|
||||
} from "./lib/feed";
|
||||
@@ -74,6 +76,7 @@ export function useFeedDesktopNotifications(
|
||||
setDesktopEnabled: (enabled: boolean) => Promise<boolean>,
|
||||
profiles?: UserProfileLookup,
|
||||
mutedChannelIds?: ReadonlySet<string>,
|
||||
channels: readonly NotificationChannel[] = [],
|
||||
) {
|
||||
const normalizedPubkey = pubkey?.trim().toLowerCase() ?? "";
|
||||
const seenItemIdsRef = React.useRef<Set<string>>(
|
||||
@@ -192,7 +195,8 @@ export function useFeedDesktopNotifications(
|
||||
void autoRequestPermissionIfNeeded();
|
||||
}
|
||||
|
||||
for (const item of newItems) {
|
||||
for (const rawItem of newItems) {
|
||||
const item = enrichFeedItemChannel(rawItem, channels);
|
||||
const resolvedLabel = profiles
|
||||
? resolveUserLabel({
|
||||
pubkey: item.pubkey,
|
||||
@@ -209,6 +213,7 @@ export function useFeedDesktopNotifications(
|
||||
}
|
||||
}, [
|
||||
feed,
|
||||
channels,
|
||||
mutedChannelIds,
|
||||
normalizedPubkey,
|
||||
profiles,
|
||||
|
||||
Reference in New Issue
Block a user