mirror of
https://github.com/hoornet/vega.git
synced 2026-05-06 12:19:11 -07:00
Mark new followers with badge, sort to top of follows list
Track new follower pubkeys in notification store. When user opens the follows view, new followers are highlighted with an accent "new" badge and sorted to the top. Badge clears on view open (one-time).
This commit is contained in:
@@ -11,9 +11,11 @@ import { shortenPubkey, profileName } from "../../lib/utils";
|
||||
function FollowRow({
|
||||
pubkey,
|
||||
followsYou,
|
||||
isNew,
|
||||
}: {
|
||||
pubkey: string;
|
||||
followsYou?: boolean;
|
||||
isNew?: boolean;
|
||||
}) {
|
||||
const profile = useProfile(pubkey);
|
||||
const name = profileName(profile, shortenPubkey(pubkey));
|
||||
@@ -60,6 +62,9 @@ function FollowRow({
|
||||
{followsYou && (
|
||||
<span className="text-[9px] text-text-dim bg-bg-raised px-1.5 py-0.5 rounded-sm">follows you</span>
|
||||
)}
|
||||
{isNew && (
|
||||
<span className="text-[9px] text-accent bg-accent/15 px-1.5 py-0.5 rounded-sm font-medium">new</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -82,12 +87,14 @@ function FollowRow({
|
||||
export function FollowsView() {
|
||||
const { followsTab, setFollowsTab } = useUIStore();
|
||||
const { pubkey, follows } = useUserStore();
|
||||
const { clearNewFollowers } = useNotificationsStore();
|
||||
const { newFollowerPubkeys, clearNewFollowers } = useNotificationsStore();
|
||||
|
||||
const [followers, setFollowers] = useState<string[]>([]);
|
||||
const [followersLoading, setFollowersLoading] = useState(false);
|
||||
const [followersError, setFollowersError] = useState<string | null>(null);
|
||||
const [followersFetched, setFollowersFetched] = useState(false);
|
||||
// Snapshot new follower pubkeys on mount, before clearing
|
||||
const [newPubkeys] = useState(() => new Set(newFollowerPubkeys));
|
||||
|
||||
// Clear badge when view opens
|
||||
useEffect(() => {
|
||||
@@ -191,8 +198,14 @@ export function FollowsView() {
|
||||
{!followersLoading && !followersError && followers.length === 0 && followersFetched && (
|
||||
<p className="px-4 py-8 text-text-dim text-[12px] text-center">No followers found yet.</p>
|
||||
)}
|
||||
{followers.map((pk) => (
|
||||
<FollowRow key={pk} pubkey={pk} />
|
||||
{[...followers]
|
||||
.sort((a, b) => {
|
||||
const aNew = newPubkeys.has(a) ? 1 : 0;
|
||||
const bNew = newPubkeys.has(b) ? 1 : 0;
|
||||
return bNew - aNew; // new followers first
|
||||
})
|
||||
.map((pk) => (
|
||||
<FollowRow key={pk} pubkey={pk} isNew={newPubkeys.has(pk)} />
|
||||
))}
|
||||
</>
|
||||
)}
|
||||
|
||||
@@ -96,7 +96,7 @@ async function pollOnce(pubkey: string) {
|
||||
for (const e of newFollowers) {
|
||||
const name = await getProfileName(e.pubkey);
|
||||
notifyFollower(name).catch(() => {});
|
||||
useNotificationsStore.getState().incrementNewFollowers();
|
||||
useNotificationsStore.getState().addNewFollower(e.pubkey);
|
||||
}
|
||||
}
|
||||
} catch { /* non-critical */ }
|
||||
|
||||
@@ -17,6 +17,7 @@ interface NotificationsState {
|
||||
dmLastSeen: Record<string, number>;
|
||||
dmUnreadCount: number;
|
||||
newFollowersCount: number;
|
||||
newFollowerPubkeys: Set<string>;
|
||||
|
||||
loadFromDb: (pubkey: string) => Promise<void>;
|
||||
fetchNotifications: (pubkey: string) => Promise<void>;
|
||||
@@ -25,7 +26,7 @@ interface NotificationsState {
|
||||
isRead: (eventId: string) => boolean;
|
||||
markDMRead: (partnerPubkey: string) => void;
|
||||
computeDMUnread: (conversations: Array<{ partnerPubkey: string; lastAt: number }>) => void;
|
||||
incrementNewFollowers: () => void;
|
||||
addNewFollower: (pubkey: string) => void;
|
||||
clearNewFollowers: () => void;
|
||||
}
|
||||
|
||||
@@ -76,6 +77,7 @@ export const useNotificationsStore = create<NotificationsState>((set, get) => ({
|
||||
dmLastSeen: loadDMLastSeen(),
|
||||
dmUnreadCount: 0,
|
||||
newFollowersCount: 0,
|
||||
newFollowerPubkeys: new Set<string>(),
|
||||
|
||||
loadFromDb: async (pubkey: string) => {
|
||||
const isNewAccount = pubkey !== get().currentPubkey;
|
||||
@@ -210,6 +212,9 @@ export const useNotificationsStore = create<NotificationsState>((set, get) => ({
|
||||
set({ dmUnreadCount });
|
||||
},
|
||||
|
||||
incrementNewFollowers: () => set((s) => ({ newFollowersCount: s.newFollowersCount + 1 })),
|
||||
clearNewFollowers: () => set({ newFollowersCount: 0 }),
|
||||
addNewFollower: (pubkey: string) => set((s) => ({
|
||||
newFollowersCount: s.newFollowersCount + 1,
|
||||
newFollowerPubkeys: new Set([...s.newFollowerPubkeys, pubkey]),
|
||||
})),
|
||||
clearNewFollowers: () => set({ newFollowersCount: 0, newFollowerPubkeys: new Set() }),
|
||||
}));
|
||||
|
||||
Reference in New Issue
Block a user