chore: cleanup right widget styles & NIP-89 handler
This commit is contained in:
@ -65,7 +65,6 @@ export default function PubkeyList({ ev, className }: { ev: NostrEvent; classNam
|
||||
return (
|
||||
<FollowListBase
|
||||
pubkeys={ids}
|
||||
showAbout={true}
|
||||
className={className}
|
||||
title={findTag(ev, "title") ?? findTag(ev, "d")}
|
||||
actions={
|
||||
@ -81,6 +80,11 @@ export default function PubkeyList({ ev, className }: { ev: NostrEvent; classNam
|
||||
</AsyncButton>
|
||||
</>
|
||||
}
|
||||
profilePreviewProps={{
|
||||
options: {
|
||||
about: true,
|
||||
},
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@ -2,6 +2,8 @@ import { mapEventToProfile, NostrLink, TaggedNostrEvent } from "@snort/system";
|
||||
import { FormattedMessage } from "react-intl";
|
||||
|
||||
import Icon from "@/Components/Icons/Icon";
|
||||
import NostrIcon from "@/Components/Icons/Nostrich";
|
||||
import KindName from "@/Components/kind-name";
|
||||
import Avatar from "@/Components/User/Avatar";
|
||||
import DisplayName from "@/Components/User/DisplayName";
|
||||
import useAppHandler from "@/Hooks/useAppHandler";
|
||||
@ -11,32 +13,49 @@ export default function NoteAppHandler({ ev }: { ev: TaggedNostrEvent }) {
|
||||
const link = NostrLink.fromEvent(ev);
|
||||
|
||||
const profiles = handlers.apps
|
||||
.filter(a => a.tags.find(b => b[0] === "web" && b[2] === "nevent"))
|
||||
.map(a => ({ profile: mapEventToProfile(a), event: a }))
|
||||
.filter(a => a.profile)
|
||||
.slice(0, 5);
|
||||
|
||||
return (
|
||||
<div className="card flex flex-col gap-2">
|
||||
<div className="card flex flex-col gap-3">
|
||||
<small>
|
||||
<FormattedMessage defaultMessage="Sorry, we dont understand this event kind, please try one of the following apps instead!" />
|
||||
<FormattedMessage
|
||||
defaultMessage="Sorry, we dont understand this event kind ({name}), please try one of the following apps instead!"
|
||||
values={{
|
||||
name: <KindName kind={ev.kind} />,
|
||||
}}
|
||||
/>
|
||||
</small>
|
||||
<div
|
||||
className="flex justify-between items-center cursor-pointer"
|
||||
onClick={() => {
|
||||
window.open(`nostr:${link.encode()}`, "_blank");
|
||||
}}>
|
||||
<div className="flex items-center gap-2">
|
||||
<NostrIcon width={40} />
|
||||
<FormattedMessage defaultMessage="Native App" />
|
||||
</div>
|
||||
<Icon name="link" />
|
||||
</div>
|
||||
{profiles.map(a => (
|
||||
<div className="flex justify-between items-center" key={a.event.id}>
|
||||
<div
|
||||
className="flex justify-between items-center cursor-pointer"
|
||||
key={a.event.id}
|
||||
onClick={() => {
|
||||
const webHandler = a.event.tags.find(a => a[0] === "web" && a[2] === "nevent")?.[1];
|
||||
if (webHandler) {
|
||||
window.open(webHandler.replace("<bech32>", link.encode()), "_blank");
|
||||
}
|
||||
}}>
|
||||
<div className="flex items-center gap-2">
|
||||
<Avatar size={40} pubkey={a.event.pubkey} user={a.profile} />
|
||||
<div>
|
||||
<DisplayName pubkey={a.event.pubkey} user={a.profile} />
|
||||
</div>
|
||||
</div>
|
||||
<Icon
|
||||
name="link"
|
||||
onClick={() => {
|
||||
const webHandler = a.event.tags.find(a => a[0] === "web" && a[2] === "nevent")?.[1];
|
||||
if (webHandler) {
|
||||
window.open(webHandler.replace("<bech32>", link.encode()), "_blank");
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<Icon name="link" />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
@ -4,13 +4,14 @@ import { FormattedMessage } from "react-intl";
|
||||
export interface NoteTimeProps {
|
||||
from: number;
|
||||
fallback?: string;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
const secondsInAMinute = 60;
|
||||
const secondsInAnHour = secondsInAMinute * 60;
|
||||
const secondsInADay = secondsInAnHour * 24;
|
||||
|
||||
const NoteTime: React.FC<NoteTimeProps> = ({ from, fallback }) => {
|
||||
const NoteTime: React.FC<NoteTimeProps> = ({ from, fallback, className }) => {
|
||||
const calcTime = useCallback((fromTime: number) => {
|
||||
const currentTime = new Date();
|
||||
const timeDifference = Math.floor((currentTime.getTime() - fromTime) / 1000);
|
||||
@ -52,7 +53,7 @@ const NoteTime: React.FC<NoteTimeProps> = ({ from, fallback }) => {
|
||||
const isoDate = useMemo(() => new Date(from).toISOString(), [from]);
|
||||
|
||||
return (
|
||||
<time dateTime={isoDate} title={absoluteTime}>
|
||||
<time dateTime={isoDate} title={absoluteTime} className={className}>
|
||||
{time || fallback}
|
||||
</time>
|
||||
);
|
||||
|
@ -27,5 +27,14 @@ export default function UsersFeed({ keyword, sortPopular = true }: { keyword: st
|
||||
|
||||
if (!usersFeed) return <PageSpinner />;
|
||||
|
||||
return <FollowListBase pubkeys={usersFeed} showAbout={true} />;
|
||||
return (
|
||||
<FollowListBase
|
||||
pubkeys={usersFeed}
|
||||
profilePreviewProps={{
|
||||
options: {
|
||||
about: true,
|
||||
},
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@ -32,8 +32,10 @@ export default function InviteFriendsWidget() {
|
||||
<div className="flex flex-col gap-2">
|
||||
<FormattedMessage defaultMessage="Share a personalized invitation with friends!" />
|
||||
<div>
|
||||
<AsyncButton onClick={() => copy.copy(`https://${window.location.host}?ref=${refCode?.code}`)}>
|
||||
<Icon name="copy" />
|
||||
<AsyncButton
|
||||
className="secondary"
|
||||
onClick={() => copy.copy(`https://${window.location.host}?ref=${refCode?.code}`)}>
|
||||
<Icon name={copy.copied ? "check" : "copy"} />
|
||||
<FormattedMessage defaultMessage="Copy link" />
|
||||
</AsyncButton>
|
||||
</div>
|
||||
|
@ -60,7 +60,14 @@ export default function SuggestedProfiles() {
|
||||
{/*<option value={Provider.SemisolDev}>semisol.dev</option>*/}
|
||||
</select>
|
||||
</div>
|
||||
<FollowListBase pubkeys={userList as HexKey[]} showAbout={true} />
|
||||
<FollowListBase
|
||||
pubkeys={userList as HexKey[]}
|
||||
profilePreviewProps={{
|
||||
options: {
|
||||
about: true,
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
@ -5,25 +5,34 @@ import NoteTime from "@/Components/Event/Note/NoteTime";
|
||||
import Text from "@/Components/Text/Text";
|
||||
import ProfileImage from "@/Components/User/ProfileImage";
|
||||
|
||||
export default function ShortNote({ event }: { event: TaggedNostrEvent }) {
|
||||
import DisplayName from "../User/DisplayName";
|
||||
|
||||
export default function TrendingNote({ event }: { event: TaggedNostrEvent }) {
|
||||
// replace newlines with spaces, replace double spaces with single spaces
|
||||
const content = event.content.slice(0, 80).replace(/\n/g, " ").replace(/ +/g, " ");
|
||||
return (
|
||||
<Link to={`/${NostrLink.fromEvent(event).encode(CONFIG.eventLinkPrefix)}`} className="flex flex-col">
|
||||
<Link to={`/${NostrLink.fromEvent(event).encode(CONFIG.eventLinkPrefix)}`} className="flex flex-col gap-1">
|
||||
<div className="flex flex-row justify-between">
|
||||
<ProfileImage pubkey={event.pubkey} size={32} showProfileCard={true} />
|
||||
<NoteTime from={event.created_at * 1000} />
|
||||
</div>
|
||||
<div className="ml-10">
|
||||
<Text
|
||||
id={event.id + "short"}
|
||||
tags={event.tags}
|
||||
creator={event.pubkey}
|
||||
content={content}
|
||||
truncate={75}
|
||||
disableMedia={true}
|
||||
<ProfileImage
|
||||
pubkey={event.pubkey}
|
||||
size={28}
|
||||
showProfileCard={true}
|
||||
overrideUsername={
|
||||
<>
|
||||
<DisplayName pubkey={event.pubkey} className="font-semibold" />
|
||||
<NoteTime from={event.created_at * 1000} className="font-normal text-sm" />
|
||||
</>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<Text
|
||||
id={event.id + "short"}
|
||||
tags={event.tags}
|
||||
creator={event.pubkey}
|
||||
content={content}
|
||||
truncate={75}
|
||||
disableMedia={true}
|
||||
/>
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ import ImageGridItem from "@/Components/Feed/ImageGridItem";
|
||||
import { useLocale } from "@/Components/IntlProvider/useLocale";
|
||||
import PageSpinner from "@/Components/PageSpinner";
|
||||
import { SpotlightThreadModal } from "@/Components/Spotlight/SpotlightThreadModal";
|
||||
import ShortNote from "@/Components/Trending/ShortNote";
|
||||
import TrendingNote from "@/Components/Trending/ShortNote";
|
||||
import NostrBandApi from "@/External/NostrBand";
|
||||
import useCachedFetch from "@/Hooks/useCachedFetch";
|
||||
import useLogin from "@/Hooks/useLogin";
|
||||
@ -83,7 +83,7 @@ export default function TrendingNotes({ count = Infinity, small = false }: { cou
|
||||
const renderList = () => {
|
||||
return filteredAndLimitedPosts.map((e, index) =>
|
||||
small ? (
|
||||
<ShortNote key={e.id} event={e as TaggedNostrEvent} />
|
||||
<TrendingNote key={e.id} event={e as TaggedNostrEvent} />
|
||||
) : (
|
||||
<Note key={e.id} data={e as TaggedNostrEvent} depth={0} options={options} waitUntilInView={index > 5} />
|
||||
),
|
||||
@ -91,7 +91,7 @@ export default function TrendingNotes({ count = Infinity, small = false }: { cou
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={classNames("flex flex-col", { "gap-6": small, "py-4": small })}>
|
||||
<div className={classNames("flex flex-col", { "gap-4": small, "py-4": small })}>
|
||||
{!small && <DisplayAsSelector activeSelection={displayAs} onSelect={a => setDisplayAs(a)} />}
|
||||
{displayAs === "grid" ? renderGrid() : renderList()}
|
||||
{modalThread && (
|
||||
|
@ -11,15 +11,11 @@ import { ErrorOrOffline } from "../ErrorOrOffline";
|
||||
export default function TrendingUsers({
|
||||
title,
|
||||
count = Infinity,
|
||||
followAll = true,
|
||||
actions,
|
||||
profileActions,
|
||||
followListProps,
|
||||
}: {
|
||||
title?: ReactNode;
|
||||
count?: number;
|
||||
followAll?: boolean;
|
||||
actions?: FollowListBaseProps["actions"];
|
||||
profileActions?: FollowListBaseProps["profileActions"];
|
||||
followListProps?: Omit<FollowListBaseProps, "pubkeys">;
|
||||
}) {
|
||||
const api = new NostrBandApi();
|
||||
const trendingProfilesUrl = api.trendingProfilesUrl();
|
||||
@ -42,11 +38,14 @@ export default function TrendingUsers({
|
||||
return (
|
||||
<FollowListBase
|
||||
pubkeys={trendingUsersData.slice(0, count) as HexKey[]}
|
||||
showAbout={true}
|
||||
title={title}
|
||||
showFollowAll={followAll}
|
||||
actions={actions}
|
||||
profileActions={profileActions}
|
||||
showFollowAll={true}
|
||||
profilePreviewProps={{
|
||||
options: {
|
||||
about: true,
|
||||
},
|
||||
}}
|
||||
{...followListProps}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@ -10,13 +10,14 @@ import { getDisplayNameOrPlaceHolder } from "@/Utils";
|
||||
interface DisplayNameProps {
|
||||
pubkey: HexKey;
|
||||
user?: UserMetadata | undefined;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
const DisplayName = ({ pubkey, user }: DisplayNameProps) => {
|
||||
const DisplayName = ({ pubkey, user, className }: DisplayNameProps) => {
|
||||
const profile = useUserProfile(user ? undefined : pubkey) ?? user;
|
||||
const [name, isPlaceHolder] = useMemo(() => getDisplayNameOrPlaceHolder(profile, pubkey), [profile, pubkey]);
|
||||
|
||||
return <span className={classNames({ placeholder: isPlaceHolder })}>{name}</span>;
|
||||
return <span className={classNames(className, { placeholder: isPlaceHolder })}>{name}</span>;
|
||||
};
|
||||
|
||||
export default DisplayName;
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { HexKey } from "@snort/system";
|
||||
import classNames from "classnames";
|
||||
import { FormattedMessage } from "react-intl";
|
||||
|
||||
import AsyncButton from "@/Components/Button/AsyncButton";
|
||||
@ -17,11 +18,10 @@ export default function FollowButton(props: FollowButtonProps) {
|
||||
const readonly = useLogin(s => s.readonly);
|
||||
const control = useFollowsControls();
|
||||
const isFollowing = control.isFollowing(pubkey);
|
||||
const baseClassname = props.className ? `${props.className} ` : "";
|
||||
|
||||
return (
|
||||
<AsyncButton
|
||||
className={isFollowing ? `${baseClassname} secondary` : `${baseClassname} primary`}
|
||||
className={classNames(props.className, "secondary")}
|
||||
disabled={readonly}
|
||||
onClick={async e => {
|
||||
e.stopPropagation();
|
||||
|
@ -2,7 +2,7 @@ import { HexKey } from "@snort/system";
|
||||
import { ReactNode, useMemo } from "react";
|
||||
import { FormattedMessage } from "react-intl";
|
||||
|
||||
import ProfilePreview from "@/Components/User/ProfilePreview";
|
||||
import ProfilePreview, { ProfilePreviewProps } from "@/Components/User/ProfilePreview";
|
||||
import useFollowsControls from "@/Hooks/useFollowControls";
|
||||
import useLogin from "@/Hooks/useLogin";
|
||||
|
||||
@ -13,26 +13,22 @@ export interface FollowListBaseProps {
|
||||
pubkeys: HexKey[];
|
||||
title?: ReactNode;
|
||||
showFollowAll?: boolean;
|
||||
showAbout?: boolean;
|
||||
className?: string;
|
||||
actions?: ReactNode;
|
||||
profileActions?: (pk: string) => ReactNode;
|
||||
profilePreviewProps?: Omit<ProfilePreviewProps, "pubkey">;
|
||||
}
|
||||
|
||||
export default function FollowListBase({
|
||||
pubkeys,
|
||||
title,
|
||||
showFollowAll,
|
||||
showAbout,
|
||||
className,
|
||||
actions,
|
||||
profileActions,
|
||||
profilePreviewProps,
|
||||
}: FollowListBaseProps) {
|
||||
const control = useFollowsControls();
|
||||
const login = useLogin();
|
||||
|
||||
const profilePreviewOptions = useMemo(() => ({ about: showAbout, profileCards: true }), [showAbout]);
|
||||
|
||||
async function followAll() {
|
||||
await control.addFollow(pubkeys);
|
||||
}
|
||||
@ -50,13 +46,7 @@ export default function FollowListBase({
|
||||
)}
|
||||
<div className={className}>
|
||||
{pubkeys?.map((a, index) => (
|
||||
<ProfilePreview
|
||||
pubkey={a}
|
||||
key={a}
|
||||
options={profilePreviewOptions}
|
||||
actions={profileActions?.(a)}
|
||||
waitUntilInView={index > 10}
|
||||
/>
|
||||
<ProfilePreview pubkey={a} key={a} waitUntilInView={index > 10} {...profilePreviewProps} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,4 +1,3 @@
|
||||
import { HexKey, NostrPrefix } from "@snort/system";
|
||||
import { FormattedMessage } from "react-intl";
|
||||
|
||||
import MuteButton from "@/Components/User/MuteButton";
|
||||
@ -8,7 +7,7 @@ import useModeration from "@/Hooks/useModeration";
|
||||
import messages from "../messages";
|
||||
|
||||
export interface MutedListProps {
|
||||
pubkeys: HexKey[];
|
||||
pubkeys: Array<string>;
|
||||
}
|
||||
|
||||
export default function MutedList() {
|
||||
@ -22,15 +21,15 @@ export default function MutedList() {
|
||||
</div>
|
||||
</div>
|
||||
{muteList?.map(a => {
|
||||
switch (a.type) {
|
||||
case NostrPrefix.Profile:
|
||||
case NostrPrefix.PublicKey: {
|
||||
const tag = a.toEventTag();
|
||||
switch (tag?.at(0)) {
|
||||
case "p": {
|
||||
return (
|
||||
<ProfilePreview
|
||||
actions={<MuteButton pubkey={a.id} />}
|
||||
pubkey={a.id}
|
||||
actions={<MuteButton pubkey={tag[1]} />}
|
||||
pubkey={tag[1]}
|
||||
options={{ about: false }}
|
||||
key={a.id}
|
||||
key={tag[1]}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ export interface ProfileImageProps {
|
||||
link?: string;
|
||||
defaultNip?: string;
|
||||
verifyNip?: boolean;
|
||||
overrideUsername?: string;
|
||||
overrideUsername?: ReactNode;
|
||||
profile?: UserMetadata;
|
||||
size?: number;
|
||||
onClick?: (e: React.MouseEvent) => void;
|
||||
@ -57,12 +57,12 @@ export default function ProfileImage({
|
||||
|
||||
const handleMouseEnter = useCallback(() => {
|
||||
hoverTimeoutRef.current && clearTimeout(hoverTimeoutRef.current);
|
||||
hoverTimeoutRef.current = setTimeout(() => setIsHovering(true), 100); // Adjust timeout as needed
|
||||
hoverTimeoutRef.current = setTimeout(() => setIsHovering(true), 100);
|
||||
}, []);
|
||||
|
||||
const handleMouseLeave = useCallback(() => {
|
||||
hoverTimeoutRef.current && clearTimeout(hoverTimeoutRef.current);
|
||||
hoverTimeoutRef.current = setTimeout(() => setIsHovering(false), 300); // Adjust timeout as needed
|
||||
hoverTimeoutRef.current = setTimeout(() => setIsHovering(false), 300);
|
||||
}, []);
|
||||
|
||||
function handleClick(e: React.MouseEvent) {
|
||||
|
@ -2,27 +2,25 @@ import "./ProfilePreview.css";
|
||||
|
||||
import { HexKey, UserMetadata } from "@snort/system";
|
||||
import { useUserProfile } from "@snort/system-react";
|
||||
import { memo, ReactNode } from "react";
|
||||
import { ReactNode } from "react";
|
||||
import { useInView } from "react-intersection-observer";
|
||||
|
||||
import FollowButton from "@/Components/User/FollowButton";
|
||||
import ProfileImage from "@/Components/User/ProfileImage";
|
||||
import ProfileImage, { ProfileImageProps } from "@/Components/User/ProfileImage";
|
||||
|
||||
export interface ProfilePreviewProps {
|
||||
pubkey: HexKey;
|
||||
options?: {
|
||||
about?: boolean;
|
||||
linkToProfile?: boolean;
|
||||
profileCards?: boolean;
|
||||
};
|
||||
subHeader?: ReactNode;
|
||||
profile?: UserMetadata;
|
||||
actions?: ReactNode;
|
||||
className?: string;
|
||||
onClick?: (e: React.MouseEvent<HTMLDivElement>) => void;
|
||||
waitUntilInView?: boolean;
|
||||
profileImageProps?: Omit<ProfileImageProps, "pubkey" | "profile">;
|
||||
}
|
||||
export default memo(function ProfilePreview(props: ProfilePreviewProps) {
|
||||
export default function ProfilePreview(props: ProfilePreviewProps) {
|
||||
const pubkey = props.pubkey;
|
||||
const { ref, inView } = useInView({ triggerOnce: true, rootMargin: "500px" });
|
||||
const user = useUserProfile(inView ? pubkey : undefined);
|
||||
@ -50,9 +48,8 @@ export default memo(function ProfilePreview(props: ProfilePreviewProps) {
|
||||
<ProfileImage
|
||||
pubkey={pubkey}
|
||||
profile={props.profile}
|
||||
link={options.linkToProfile ?? true ? undefined : ""}
|
||||
subHeader={options.about ? <div className="about">{user?.about}</div> : props.subHeader}
|
||||
showProfileCard={options.profileCards}
|
||||
subHeader={options.about && <div className="about">{user?.about}</div>}
|
||||
{...props.profileImageProps}
|
||||
/>
|
||||
{props.actions ?? (
|
||||
<div className="whitespace-nowrap">
|
||||
@ -64,4 +61,4 @@ export default memo(function ProfilePreview(props: ProfilePreviewProps) {
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
});
|
||||
}
|
||||
|
226
packages/app/src/Components/kind-name.tsx
Normal file
226
packages/app/src/Components/kind-name.tsx
Normal file
@ -0,0 +1,226 @@
|
||||
import { FormattedMessage } from "react-intl";
|
||||
|
||||
export default function KindName({ kind }: { kind: number }) {
|
||||
switch (kind) {
|
||||
case 0:
|
||||
return <FormattedMessage defaultMessage="User Metadata" />;
|
||||
case 1:
|
||||
return <FormattedMessage defaultMessage="Short Text Note" />;
|
||||
case 2:
|
||||
return <FormattedMessage defaultMessage="Recommend Relay" />;
|
||||
case 3:
|
||||
return <FormattedMessage defaultMessage="Follows" />;
|
||||
case 4:
|
||||
return <FormattedMessage defaultMessage="Encrypted Direct Messages" />;
|
||||
case 5:
|
||||
return <FormattedMessage defaultMessage="Event Deletion Request" />;
|
||||
case 6:
|
||||
return <FormattedMessage defaultMessage="Repost" />;
|
||||
case 7:
|
||||
return <FormattedMessage defaultMessage="Reaction" />;
|
||||
case 8:
|
||||
return <FormattedMessage defaultMessage="Badge Award" />;
|
||||
case 9:
|
||||
return <FormattedMessage defaultMessage="Group Chat Message" />;
|
||||
case 10:
|
||||
return <FormattedMessage defaultMessage="Group Chat Threaded Reply" />;
|
||||
case 11:
|
||||
return <FormattedMessage defaultMessage="Group Thread" />;
|
||||
case 12:
|
||||
return <FormattedMessage defaultMessage="Group Thread Reply" />;
|
||||
case 13:
|
||||
return <FormattedMessage defaultMessage="Seal" />;
|
||||
case 14:
|
||||
return <FormattedMessage defaultMessage="Direct Message" />;
|
||||
case 16:
|
||||
return <FormattedMessage defaultMessage="Generic Repost" />;
|
||||
case 17:
|
||||
return <FormattedMessage defaultMessage="Reaction to a website" />;
|
||||
case 40:
|
||||
return <FormattedMessage defaultMessage="Channel Creation" />;
|
||||
case 41:
|
||||
return <FormattedMessage defaultMessage="Channel Metadata" />;
|
||||
case 42:
|
||||
return <FormattedMessage defaultMessage="Channel Message" />;
|
||||
case 43:
|
||||
return <FormattedMessage defaultMessage="Channel Hide Message" />;
|
||||
case 44:
|
||||
return <FormattedMessage defaultMessage="Channel Mute User" />;
|
||||
case 64:
|
||||
return <FormattedMessage defaultMessage="Chess (PGN)" />;
|
||||
case 818:
|
||||
return <FormattedMessage defaultMessage="Merge Requests" />;
|
||||
case 1021:
|
||||
return <FormattedMessage defaultMessage="Bid" />;
|
||||
case 1022:
|
||||
return <FormattedMessage defaultMessage="Bid confirmation" />;
|
||||
case 1040:
|
||||
return <FormattedMessage defaultMessage="OpenTimestamps" />;
|
||||
case 1059:
|
||||
return <FormattedMessage defaultMessage="Gift Wrap" />;
|
||||
case 1063:
|
||||
return <FormattedMessage defaultMessage="File Metadata" />;
|
||||
case 1311:
|
||||
return <FormattedMessage defaultMessage="Live Chat Message" />;
|
||||
case 1617:
|
||||
return <FormattedMessage defaultMessage="Patches" />;
|
||||
case 1621:
|
||||
return <FormattedMessage defaultMessage="Issues" />;
|
||||
case 1622:
|
||||
return <FormattedMessage defaultMessage="Replies" />;
|
||||
case 1971:
|
||||
return <FormattedMessage defaultMessage="Problem Tracker" />;
|
||||
case 1984:
|
||||
return <FormattedMessage defaultMessage="Reporting" />;
|
||||
case 1985:
|
||||
return <FormattedMessage defaultMessage="Label" />;
|
||||
case 1986:
|
||||
return <FormattedMessage defaultMessage="Relay reviews" />;
|
||||
case 1987:
|
||||
return <FormattedMessage defaultMessage="AI Embeddings / Vector lists" />;
|
||||
case 2003:
|
||||
return <FormattedMessage defaultMessage="Torrent" />;
|
||||
case 2004:
|
||||
return <FormattedMessage defaultMessage="Torrent Comment" />;
|
||||
case 2022:
|
||||
return <FormattedMessage defaultMessage="Coinjoin Pool" />;
|
||||
case 4550:
|
||||
return <FormattedMessage defaultMessage="Community Post Approval" />;
|
||||
case 7000:
|
||||
return <FormattedMessage defaultMessage="Job Feedback" />;
|
||||
case 9041:
|
||||
return <FormattedMessage defaultMessage="Zap Goal" />;
|
||||
case 9467:
|
||||
return <FormattedMessage defaultMessage="Tidal login" />;
|
||||
case 9734:
|
||||
return <FormattedMessage defaultMessage="Zap Request" />;
|
||||
case 9735:
|
||||
return <FormattedMessage defaultMessage="Zap" />;
|
||||
case 9802:
|
||||
return <FormattedMessage defaultMessage="Highlights" />;
|
||||
case 10000:
|
||||
return <FormattedMessage defaultMessage="Mute list" />;
|
||||
case 10001:
|
||||
return <FormattedMessage defaultMessage="Pin list" />;
|
||||
case 10002:
|
||||
return <FormattedMessage defaultMessage="Relay List Metadata" />;
|
||||
case 10003:
|
||||
return <FormattedMessage defaultMessage="Bookmark list" />;
|
||||
case 10004:
|
||||
return <FormattedMessage defaultMessage="Communities list" />;
|
||||
case 10005:
|
||||
return <FormattedMessage defaultMessage="Public chats list" />;
|
||||
case 10006:
|
||||
return <FormattedMessage defaultMessage="Blocked relays list" />;
|
||||
case 10007:
|
||||
return <FormattedMessage defaultMessage="Search relays list" />;
|
||||
case 10009:
|
||||
return <FormattedMessage defaultMessage="User groups" />;
|
||||
case 10015:
|
||||
return <FormattedMessage defaultMessage="Interests list" />;
|
||||
case 10030:
|
||||
return <FormattedMessage defaultMessage="User emoji list" />;
|
||||
case 10050:
|
||||
return <FormattedMessage defaultMessage="Relay list to receive DMs" />;
|
||||
case 10063:
|
||||
return <FormattedMessage defaultMessage="User server list" />;
|
||||
case 10096:
|
||||
return <FormattedMessage defaultMessage="File storage server list" />;
|
||||
case 13194:
|
||||
return <FormattedMessage defaultMessage="Wallet Info" />;
|
||||
case 21000:
|
||||
return <FormattedMessage defaultMessage="Lightning Pub RPC" />;
|
||||
case 22242:
|
||||
return <FormattedMessage defaultMessage="Client Authentication" />;
|
||||
case 23194:
|
||||
return <FormattedMessage defaultMessage="Wallet Request" />;
|
||||
case 23195:
|
||||
return <FormattedMessage defaultMessage="Wallet Response" />;
|
||||
case 24133:
|
||||
return <FormattedMessage defaultMessage="Nostr Connect" />;
|
||||
case 24242:
|
||||
return <FormattedMessage defaultMessage="Blobs stored on mediaservers" />;
|
||||
case 27235:
|
||||
return <FormattedMessage defaultMessage="HTTP Auth" />;
|
||||
case 30000:
|
||||
return <FormattedMessage defaultMessage="Follow sets" />;
|
||||
case 30001:
|
||||
return <FormattedMessage defaultMessage="Generic lists" />;
|
||||
case 30002:
|
||||
return <FormattedMessage defaultMessage="Relay sets" />;
|
||||
case 30003:
|
||||
return <FormattedMessage defaultMessage="Bookmark sets" />;
|
||||
case 30004:
|
||||
return <FormattedMessage defaultMessage="Curation sets" />;
|
||||
case 30005:
|
||||
return <FormattedMessage defaultMessage="Video sets" />;
|
||||
case 30007:
|
||||
return <FormattedMessage defaultMessage="Kind mute sets" />;
|
||||
case 30008:
|
||||
return <FormattedMessage defaultMessage="Profile Badges" />;
|
||||
case 30009:
|
||||
return <FormattedMessage defaultMessage="Badge Definition" />;
|
||||
case 30015:
|
||||
return <FormattedMessage defaultMessage="Interest sets" />;
|
||||
case 30017:
|
||||
return <FormattedMessage defaultMessage="Create or update a stall" />;
|
||||
case 30018:
|
||||
return <FormattedMessage defaultMessage="Create or update a product" />;
|
||||
case 30019:
|
||||
return <FormattedMessage defaultMessage="Marketplace UI/UX" />;
|
||||
case 30020:
|
||||
return <FormattedMessage defaultMessage="Product sold as an auction" />;
|
||||
case 30023:
|
||||
return <FormattedMessage defaultMessage="Long-form Content" />;
|
||||
case 30024:
|
||||
return <FormattedMessage defaultMessage="Draft Long-form Content" />;
|
||||
case 30030:
|
||||
return <FormattedMessage defaultMessage="Emoji sets" />;
|
||||
case 30040:
|
||||
return <FormattedMessage defaultMessage="Modular Article Header" />;
|
||||
case 30041:
|
||||
return <FormattedMessage defaultMessage="Modular Article Content" />;
|
||||
case 30063:
|
||||
return <FormattedMessage defaultMessage="Release artifact sets" />;
|
||||
case 30078:
|
||||
return <FormattedMessage defaultMessage="Application-specific Data" />;
|
||||
case 30311:
|
||||
return <FormattedMessage defaultMessage="Live Event" />;
|
||||
case 30315:
|
||||
return <FormattedMessage defaultMessage="User Statuses" />;
|
||||
case 30402:
|
||||
return <FormattedMessage defaultMessage="Classified Listing" />;
|
||||
case 30403:
|
||||
return <FormattedMessage defaultMessage="Draft Classified Listing" />;
|
||||
case 30617:
|
||||
return <FormattedMessage defaultMessage="Repository announcements" />;
|
||||
case 30618:
|
||||
return <FormattedMessage defaultMessage="Repository state announcements" />;
|
||||
case 30818:
|
||||
return <FormattedMessage defaultMessage="Wiki article" />;
|
||||
case 30819:
|
||||
return <FormattedMessage defaultMessage="Redirects" />;
|
||||
case 31890:
|
||||
return <FormattedMessage defaultMessage="Feed" />;
|
||||
case 31922:
|
||||
return <FormattedMessage defaultMessage="Date-Based Calendar Event" />;
|
||||
case 31923:
|
||||
return <FormattedMessage defaultMessage="Time-Based Calendar Event" />;
|
||||
case 31924:
|
||||
return <FormattedMessage defaultMessage="Calendar" />;
|
||||
case 31925:
|
||||
return <FormattedMessage defaultMessage="Calendar Event RSVP" />;
|
||||
case 31989:
|
||||
return <FormattedMessage defaultMessage="Handler recommendation" />;
|
||||
case 31990:
|
||||
return <FormattedMessage defaultMessage="Handler information" />;
|
||||
case 34235:
|
||||
return <FormattedMessage defaultMessage="Video Event" />;
|
||||
case 34236:
|
||||
return <FormattedMessage defaultMessage="Short-form Portrait Video Event" />;
|
||||
case 34237:
|
||||
return <FormattedMessage defaultMessage="Video View Event" />;
|
||||
case 34550:
|
||||
return <FormattedMessage defaultMessage="Community Definition" />;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user