fix: notification avatar overflow
refactor: sort notification group avatar by WoT score
This commit is contained in:
parent
f10ad6dd53
commit
22863a289d
@ -21,8 +21,8 @@ export function userSearch(search: string) {
|
||||
const combinedResults = fuseResults
|
||||
.map(result => {
|
||||
const fuseScore = result.score === undefined ? 1 : result.score;
|
||||
const followDistance =
|
||||
socialGraphInstance.getFollowDistance(result.item.pubkey) / followDistanceNormalizationFactor;
|
||||
|
||||
const followDistance = wotScore(result.item.pubkey) / followDistanceNormalizationFactor;
|
||||
|
||||
const startsWithSearchString = [result.item.name, result.item.display_name, result.item.nip05].some(
|
||||
field => field && field.toLowerCase?.().startsWith(searchString.toLowerCase()),
|
||||
@ -49,4 +49,12 @@ export function userSearch(search: string) {
|
||||
});
|
||||
|
||||
return combinedResults.map(r => r.item);
|
||||
}
|
||||
|
||||
export function wotScore(pubkey: string) {
|
||||
return socialGraphInstance.getFollowDistance(pubkey);
|
||||
}
|
||||
|
||||
export function sortByWoT(pubkeys: Array<string>) {
|
||||
return pubkeys.sort((a, b) => wotScore(a) > wotScore(b) ? 1 : -1);
|
||||
}
|
@ -8,11 +8,12 @@ import { useNavigate } from "react-router-dom";
|
||||
|
||||
import Icon from "@/Components/Icons/Icon";
|
||||
import ProfileImage from "@/Components/User/ProfileImage";
|
||||
import { sortByWoT } from "@/Hooks/useProfileSearch";
|
||||
import { dedupe, getDisplayName } from "@/Utils";
|
||||
import { formatShort } from "@/Utils/Number";
|
||||
|
||||
import { notificationContext } from "./notificationContext";
|
||||
import { NotificationContext } from "./Notifications";
|
||||
import { getNotificationContext } from "./getNotificationContext";
|
||||
import { NotificationContext } from "./notificationContext";
|
||||
|
||||
export function NotificationGroup({
|
||||
evs,
|
||||
@ -40,7 +41,7 @@ export function NotificationGroup({
|
||||
);
|
||||
const firstPubkey = pubkeys[0];
|
||||
const firstPubkeyProfile = useUserProfile(inView ? (firstPubkey === "anon" ? "" : firstPubkey) : "");
|
||||
const context = notificationContext(evs[0]);
|
||||
const context = getNotificationContext(evs[0]);
|
||||
const totalZaps = zaps.reduce((acc, v) => acc + v.amount, 0);
|
||||
|
||||
const iconName = () => {
|
||||
@ -113,9 +114,9 @@ export function NotificationGroup({
|
||||
<div>{kind === EventKind.ZapReceipt && formatShort(totalZaps)}</div>
|
||||
</div>
|
||||
<div className="flex flex-col w-max g12">
|
||||
<div className="flex">
|
||||
{pubkeys
|
||||
.filter(a => a !== "anon")
|
||||
<div className="flex w-max overflow-hidden">
|
||||
{sortByWoT(pubkeys
|
||||
.filter(a => a !== "anon"))
|
||||
.slice(0, 12)
|
||||
.map(v => (
|
||||
<ProfileImage
|
||||
|
@ -1,22 +1,18 @@
|
||||
import "./Notifications.css";
|
||||
|
||||
import { unwrap } from "@snort/shared";
|
||||
import { EventKind, NostrEvent, NostrLink, NostrPrefix, TaggedNostrEvent } from "@snort/system";
|
||||
import { useEventFeed } from "@snort/system-react";
|
||||
import { NostrEvent, NostrLink, TaggedNostrEvent } from "@snort/system";
|
||||
import { lazy, Suspense, useEffect, useMemo } from "react";
|
||||
|
||||
import { ShowMoreInView } from "@/Components/Event/ShowMore";
|
||||
import { LiveEvent } from "@/Components/LiveStream/LiveEvent";
|
||||
import PageSpinner from "@/Components/PageSpinner";
|
||||
import Text from "@/Components/Text/Text";
|
||||
import ProfilePreview from "@/Components/User/ProfilePreview";
|
||||
import { useNotificationsView } from "@/Feed/WorkerRelayView";
|
||||
import useLogin from "@/Hooks/useLogin";
|
||||
import useModeration from "@/Hooks/useModeration";
|
||||
import { orderDescending } from "@/Utils";
|
||||
import { markNotificationsRead } from "@/Utils/Login";
|
||||
|
||||
import { notificationContext } from "./notificationContext";
|
||||
import { getNotificationContext } from "./getNotificationContext";
|
||||
import { NotificationGroup } from "./NotificationGroup";
|
||||
const NotificationGraph = lazy(() => import("@/Pages/Notifications/NotificationChart"));
|
||||
|
||||
@ -44,9 +40,8 @@ export default function NotificationsPage({ onClick }: { onClick?: (link: NostrL
|
||||
|
||||
const timeGrouped = useMemo(() => {
|
||||
return myNotifications.reduce((acc, v) => {
|
||||
const key = `${timeKey(v)}:${notificationContext(v as TaggedNostrEvent)?.encode(CONFIG.eventLinkPrefix)}:${
|
||||
v.kind
|
||||
}`;
|
||||
const key = `${timeKey(v)}:${getNotificationContext(v as TaggedNostrEvent)?.encode(CONFIG.eventLinkPrefix)}:${v.kind
|
||||
}`;
|
||||
if (acc.has(key)) {
|
||||
unwrap(acc.get(key)).push(v as TaggedNostrEvent);
|
||||
} else {
|
||||
@ -67,31 +62,8 @@ export default function NotificationsPage({ onClick }: { onClick?: (link: NostrL
|
||||
{login.publicKey &&
|
||||
[...timeGrouped.entries()].map(([k, g]) => <NotificationGroup key={k} evs={g} onClick={onClick} />)}
|
||||
|
||||
<ShowMoreInView onClick={() => {}} />
|
||||
<ShowMoreInView onClick={() => { }} />
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export function NotificationContext({ link, onClick }: { link: NostrLink; onClick: () => void }) {
|
||||
const ev = useEventFeed(link);
|
||||
if (link.type === NostrPrefix.PublicKey) {
|
||||
return <ProfilePreview pubkey={link.id} actions={<></>} />;
|
||||
}
|
||||
if (!ev) return;
|
||||
if (ev.kind === EventKind.LiveEvent) {
|
||||
return <LiveEvent ev={ev} />;
|
||||
}
|
||||
return (
|
||||
<Text
|
||||
id={ev.id}
|
||||
content={ev.content}
|
||||
tags={ev.tags}
|
||||
creator={ev.pubkey}
|
||||
truncate={120}
|
||||
disableLinkPreview={true}
|
||||
className="content"
|
||||
onClick={onClick}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@ -0,0 +1,35 @@
|
||||
import { unwrap } from "@snort/shared";
|
||||
import { EventExt, EventKind, NostrLink, TaggedNostrEvent } from "@snort/system";
|
||||
|
||||
export function getNotificationContext(ev: TaggedNostrEvent) {
|
||||
switch (ev.kind) {
|
||||
case EventKind.ZapReceipt: {
|
||||
const aTag = ev.tags.find(a => a[0] === "a");
|
||||
if (aTag) {
|
||||
return NostrLink.fromTag(aTag);
|
||||
}
|
||||
const eTag = ev.tags.find(a => a[0] === "e");
|
||||
if (eTag) {
|
||||
return NostrLink.fromTag(eTag);
|
||||
}
|
||||
const pTag = ev.tags.find(a => a[0] === "p");
|
||||
if (pTag) {
|
||||
return NostrLink.fromTag(pTag);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case EventKind.Repost:
|
||||
case EventKind.Reaction: {
|
||||
const thread = EventExt.extractThread(ev);
|
||||
const tag = unwrap(thread?.replyTo ?? thread?.root ?? { value: ev.id, key: "e" });
|
||||
if (tag.key === "e" || tag.key === "a") {
|
||||
return NostrLink.fromThreadTag(tag);
|
||||
} else {
|
||||
throw new Error("Unknown thread context");
|
||||
}
|
||||
}
|
||||
case EventKind.TextNote: {
|
||||
return NostrLink.fromEvent(ev);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,35 +1,29 @@
|
||||
import { unwrap } from "@snort/shared";
|
||||
import { EventExt, EventKind, NostrLink, TaggedNostrEvent } from "@snort/system";
|
||||
import { EventKind, NostrLink, NostrPrefix } from "@snort/system";
|
||||
import { useEventFeed } from "@snort/system-react";
|
||||
|
||||
export function notificationContext(ev: TaggedNostrEvent) {
|
||||
switch (ev.kind) {
|
||||
case EventKind.ZapReceipt: {
|
||||
const aTag = ev.tags.find(a => a[0] === "a");
|
||||
if (aTag) {
|
||||
return NostrLink.fromTag(aTag);
|
||||
}
|
||||
const eTag = ev.tags.find(a => a[0] === "e");
|
||||
if (eTag) {
|
||||
return NostrLink.fromTag(eTag);
|
||||
}
|
||||
const pTag = ev.tags.find(a => a[0] === "p");
|
||||
if (pTag) {
|
||||
return NostrLink.fromTag(pTag);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case EventKind.Repost:
|
||||
case EventKind.Reaction: {
|
||||
const thread = EventExt.extractThread(ev);
|
||||
const tag = unwrap(thread?.replyTo ?? thread?.root ?? { value: ev.id, key: "e" });
|
||||
if (tag.key === "e" || tag.key === "a") {
|
||||
return NostrLink.fromThreadTag(tag);
|
||||
} else {
|
||||
throw new Error("Unknown thread context");
|
||||
}
|
||||
}
|
||||
case EventKind.TextNote: {
|
||||
return NostrLink.fromEvent(ev);
|
||||
}
|
||||
import { LiveEvent } from "@/Components/LiveStream/LiveEvent";
|
||||
import Text from "@/Components/Text/Text";
|
||||
import ProfilePreview from "@/Components/User/ProfilePreview";
|
||||
|
||||
export function NotificationContext({ link, onClick }: { link: NostrLink; onClick: () => void }) {
|
||||
const ev = useEventFeed(link);
|
||||
if (link.type === NostrPrefix.PublicKey) {
|
||||
return <ProfilePreview pubkey={link.id} actions={<></>} />;
|
||||
}
|
||||
if (!ev) return;
|
||||
if (ev.kind === EventKind.LiveEvent) {
|
||||
return <LiveEvent ev={ev} />;
|
||||
}
|
||||
return (
|
||||
<Text
|
||||
id={ev.id}
|
||||
content={ev.content}
|
||||
tags={ev.tags}
|
||||
creator={ev.pubkey}
|
||||
truncate={120}
|
||||
disableLinkPreview={true}
|
||||
className="content"
|
||||
onClick={onClick}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user