chore: cleanup right widget styles & NIP-89 handler
Some checks failed
continuous-integration/drone/push Build is failing

This commit is contained in:
kieran 2024-09-19 10:37:11 +01:00
parent 17e8955f54
commit 41c0047f5b
Signed by: Kieran
GPG Key ID: DE71CEB3925BE941
23 changed files with 773 additions and 94 deletions

View File

@ -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,
},
}}
/>
);
}

View File

@ -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>

View File

@ -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>
);

View File

@ -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,
},
}}
/>
);
}

View File

@ -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>

View File

@ -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,
},
}}
/>
</>
);
}

View File

@ -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>
);
}

View File

@ -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 && (

View File

@ -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}
/>
);
}

View File

@ -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;

View File

@ -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();

View File

@ -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>

View File

@ -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]}
/>
);
}

View File

@ -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) {

View File

@ -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>
</>
);
});
}

View 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" />;
}
}

View File

@ -41,7 +41,18 @@ export default function RightColumn() {
case RightColumnWidget.TrendingPeople:
return (
<BaseWidget title={<FormattedMessage defaultMessage="Trending People" />}>
<TrendingUsers count={6} followAll={false} profileActions={pubkey ? () => undefined : () => <></>} />
<TrendingUsers
count={6}
followListProps={{
showFollowAll: false,
profilePreviewProps: {
actions: pubkey ? undefined : <></>,
profileImageProps: {
size: 32,
},
},
}}
/>
</BaseWidget>
);
case RightColumnWidget.TrendingHashtags:
@ -68,7 +79,7 @@ export default function RightColumn() {
<div>
<SearchBox />
</div>
<div className="flex flex-col gap-4 overflow-y-auto">{widgets.map(getWidget)}</div>
<div className="flex flex-col gap-4 overflow-y-auto hide-scrollbar">{widgets.map(getWidget)}</div>
</div>
);
}

View File

@ -105,7 +105,10 @@ export default function NewChatWindow() {
<ProfilePreview
pubkey={a}
key={`option-${a}`}
options={{ about: false, linkToProfile: false }}
profileImageProps={{
link: "",
}}
options={{ about: false }}
actions={<></>}
onClick={() => togglePubkey(a)}
className={newChat.includes(a) ? "active" : undefined}

View File

@ -12,7 +12,10 @@ export default function Nip28ChatProfile({ id, onClick }: { id: string; onClick:
<ProfilePreview
pubkey=""
profile={meta}
options={{ about: false, linkToProfile: false }}
profileImageProps={{
link: "",
}}
options={{ about: false }}
actions={<></>}
onClick={() => onClick(id)}
/>

View File

@ -53,7 +53,9 @@ export function ZapsProfileTab({ id }: { id: HexKey }) {
key={a.pubkey}>
<ProfilePreview
pubkey={a.pubkey}
subHeader={a.topZap.content ? <div className="about">&quot;{a.topZap.content}&quot;</div> : undefined}
profileImageProps={{
subHeader: a.topZap.content ? <div className="about">&quot;{a.topZap.content}&quot;</div> : undefined,
}}
options={{
about: false,
}}

View File

@ -17,7 +17,16 @@ const PROFILES = 1;
const Profiles = ({ keyword }: { keyword: string }) => {
const results = useProfileSearch(keyword);
const ids = useMemo(() => results.map(r => r.pubkey), [results]);
const content = keyword ? <FollowListBase pubkeys={ids} showAbout={true} /> : <TrendingUsers />;
const content = keyword ? (
<FollowListBase
pubkeys={ids}
profilePreviewProps={{
options: { about: true },
}}
/>
) : (
<TrendingUsers />
);
return <div className="px-3">{content}</div>;
};

View File

@ -53,6 +53,9 @@
"/Xf4UW": {
"defaultMessage": "Send anonymous usage metrics"
},
"/b1IHW": {
"defaultMessage": "Group Chat Message"
},
"/d6vEc": {
"defaultMessage": "Make your profile easier to find and share"
},
@ -147,6 +150,9 @@
"2BBGxX": {
"defaultMessage": "Subject tag in text events"
},
"2HIqeO": {
"defaultMessage": "User emoji list"
},
"2IFGap": {
"defaultMessage": "Donate"
},
@ -156,6 +162,9 @@
"2O2sfp": {
"defaultMessage": "Finish"
},
"2Qsf9/": {
"defaultMessage": "Generic lists"
},
"2a2YiP": {
"defaultMessage": "{n} Bookmarks"
},
@ -174,6 +183,9 @@
"2ukA4d": {
"defaultMessage": "{n} hours"
},
"3/onCd": {
"defaultMessage": "Replies"
},
"39AHJm": {
"defaultMessage": "Sign Up"
},
@ -183,6 +195,9 @@
"3KNMbJ": {
"defaultMessage": "Articles"
},
"3MKdAw": {
"defaultMessage": "Blobs stored on mediaservers"
},
"3QwfJR": {
"defaultMessage": "~{amount}"
},
@ -225,6 +240,9 @@
"47FYwb": {
"defaultMessage": "Cancel"
},
"48zn4v": {
"defaultMessage": "Bid"
},
"4IPzdn": {
"defaultMessage": "Primary Developers"
},
@ -264,6 +282,9 @@
"5PRWs7": {
"defaultMessage": "Notifications API Enabled"
},
"5dfmvv": {
"defaultMessage": "Zap Goal"
},
"5oTnfy": {
"defaultMessage": "Buy Handle"
},
@ -282,6 +303,9 @@
"6/hB3S": {
"defaultMessage": "Watch Replay"
},
"60kEE3": {
"defaultMessage": "Mute list"
},
"62nsdy": {
"defaultMessage": "Retry"
},
@ -294,6 +318,12 @@
"65BmHb": {
"defaultMessage": "Failed to proxy image from {host}, click here to load directly"
},
"6D4Hhn": {
"defaultMessage": "Recommend Relay"
},
"6KGebm": {
"defaultMessage": "Seal"
},
"6OSOXl": {
"defaultMessage": "Reason: <i>{reason}</i>"
},
@ -324,6 +354,12 @@
"712i26": {
"defaultMessage": "Proxy uses HODL invoices to forward the payment, which hides the pubkey of your node"
},
"753yX5": {
"defaultMessage": "Label"
},
"769A8p": {
"defaultMessage": "Wiki article"
},
"77nkEO": {
"defaultMessage": "Relay Information Document"
},
@ -336,9 +372,15 @@
"7YkSA2": {
"defaultMessage": "Community Leader"
},
"7gMmSL": {
"defaultMessage": "Reaction"
},
"7hp70g": {
"defaultMessage": "NIP-05"
},
"7jfPsW": {
"defaultMessage": "Modular Article Content"
},
"7nAz/z": {
"defaultMessage": "Mute notes from people who are outside your web of trust"
},
@ -369,6 +411,9 @@
"8Y6bZQ": {
"defaultMessage": "Invalid zap split: {input}"
},
"8ZGqWl": {
"defaultMessage": "Group Thread"
},
"8g2vyB": {
"defaultMessage": "name too long"
},
@ -378,6 +423,12 @@
"8v1NN+": {
"defaultMessage": "Pairing phrase"
},
"8xdDLn": {
"defaultMessage": "Follow sets"
},
"8za9Pq": {
"defaultMessage": "Draft Classified Listing"
},
"9+Ddtu": {
"defaultMessage": "Next"
},
@ -387,6 +438,9 @@
"9SvQep": {
"defaultMessage": "Follows {n}"
},
"9V0wg3": {
"defaultMessage": "Calendar Event RSVP"
},
"9WRlF4": {
"defaultMessage": "Send"
},
@ -402,6 +456,9 @@
"9wO4wJ": {
"defaultMessage": "Lightning Invoice"
},
"A86fJ+": {
"defaultMessage": "Generic Repost"
},
"ADmfQT": {
"defaultMessage": "Parent",
"description": "Link to parent note in thread"
@ -415,6 +472,9 @@
"ASRK0S": {
"defaultMessage": "This author has been muted"
},
"AedFVZ": {
"defaultMessage": "Create or update a product"
},
"Ai8VHU": {
"defaultMessage": "Unlimited note retention on Snort relay"
},
@ -427,6 +487,9 @@
"Am8glJ": {
"defaultMessage": "Game"
},
"AqGfF4": {
"defaultMessage": "Channel Creation"
},
"Aujn2T": {
"defaultMessage": "Count"
},
@ -454,12 +517,18 @@
"BGCM48": {
"defaultMessage": "Write access to Snort relay, with 1 year of event retention"
},
"BGGacK": {
"defaultMessage": "AI Embeddings / Vector lists"
},
"BQW4gi": {
"defaultMessage": "Relay-based Groups"
},
"BWpuKl": {
"defaultMessage": "Update"
},
"BfuAQ5": {
"defaultMessage": "Marketplace UI/UX"
},
"BjNwZW": {
"defaultMessage": "Nostr address (nip05)"
},
@ -473,6 +542,9 @@
"C1LjMx": {
"defaultMessage": "Lightning Donation"
},
"C6Lhhp": {
"defaultMessage": "Live Event"
},
"C7642/": {
"defaultMessage": "Quote Repost"
},
@ -485,6 +557,9 @@
"C8HhVE": {
"defaultMessage": "Suggested Follows"
},
"CA1efg": {
"defaultMessage": "Video sets"
},
"CHTbO3": {
"defaultMessage": "Failed to load invoice"
},
@ -503,9 +578,15 @@
"CYkOCI": {
"defaultMessage": "and {count} others you follow"
},
"Cdxwi0": {
"defaultMessage": "Repository announcements"
},
"CmZ9ls": {
"defaultMessage": "{n} Muted"
},
"Coy6SH": {
"defaultMessage": "Calendar"
},
"CsCUYo": {
"defaultMessage": "{n} sats"
},
@ -521,9 +602,15 @@
"D+KzKd": {
"defaultMessage": "Automatically zap every note when loaded"
},
"D09wbg": {
"defaultMessage": "Badge Definition"
},
"D3idYv": {
"defaultMessage": "Settings"
},
"D9xTLE": {
"defaultMessage": "Channel Hide Message"
},
"DBiVK1": {
"defaultMessage": "Cache"
},
@ -539,6 +626,9 @@
"Dn82AL": {
"defaultMessage": "Live"
},
"DqUmXt": {
"defaultMessage": "Product sold as an auction"
},
"DrZqav": {
"defaultMessage": "About must be less than {limit} characters"
},
@ -566,12 +656,18 @@
"EQKRE4": {
"defaultMessage": "Show badges on profile pages"
},
"EWeVrH": {
"defaultMessage": "Reaction to a website"
},
"EWyQH5": {
"defaultMessage": "Global"
},
"Ebl/B2": {
"defaultMessage": "Translate to {lang}"
},
"Ec+xLY": {
"defaultMessage": "Curation sets"
},
"EcZF24": {
"defaultMessage": "Custom Relays"
},
@ -587,6 +683,9 @@
"EnCOBJ": {
"defaultMessage": "Buy"
},
"EsHX35": {
"defaultMessage": "Sorry, we dont understand this event kind ({name}), please try one of the following apps instead!"
},
"F/6VqP": {
"defaultMessage": "Server"
},
@ -599,6 +698,9 @@
"FDguSC": {
"defaultMessage": "{n} Zaps"
},
"FHWpHC": {
"defaultMessage": "Wallet Response"
},
"FHvSk3": {
"defaultMessage": "Authentication of clients to relays"
},
@ -608,6 +710,9 @@
"FSYL8G": {
"defaultMessage": "Trending Users"
},
"FWJR1B": {
"defaultMessage": "User groups"
},
"FcNSft": {
"defaultMessage": "Redirect issues HTTP redirect to the supplied lightning address"
},
@ -653,6 +758,9 @@
"Gcn9NQ": {
"defaultMessage": "Magnet Link"
},
"GpkNYn": {
"defaultMessage": "Torrent"
},
"GqQeu/": {
"defaultMessage": "Invalid Lightning Address"
},
@ -675,6 +783,9 @@
"H0OG3T": {
"defaultMessage": "Leader Info"
},
"H1GTaC": {
"defaultMessage": "Bookmark list"
},
"H6/kLh": {
"defaultMessage": "Order Paid!"
},
@ -696,12 +807,18 @@
"HhcAVH": {
"defaultMessage": "You don't follow this person, click here to load media from <i>{link}</i>, or update <a><i>your preferences</i></a> to always load media from everybody."
},
"HpAmQZ": {
"defaultMessage": "Relay reviews"
},
"HqRNN8": {
"defaultMessage": "Support"
},
"HzSFeV": {
"defaultMessage": "Expiration Timestamp"
},
"I0tYZf": {
"defaultMessage": "Create or update a stall"
},
"I1AoOu": {
"defaultMessage": "Last post {time}"
},
@ -750,6 +867,9 @@
"J2HeQ+": {
"defaultMessage": "Use commas to separate words e.g. word1, word2, word3"
},
"J2Q92B": {
"defaultMessage": "Emoji sets"
},
"JCIgkj": {
"defaultMessage": "Username"
},
@ -771,6 +891,9 @@
"JeoS4y": {
"defaultMessage": "Repost"
},
"Jh5zKH": {
"defaultMessage": "Search relays list"
},
"JjGgXI": {
"defaultMessage": "Search users"
},
@ -801,6 +924,9 @@
"KGmQjH": {
"defaultMessage": "Highlights"
},
"KJryGq": {
"defaultMessage": "Live Chat Message"
},
"KQvWvD": {
"defaultMessage": "Deleted"
},
@ -816,6 +942,9 @@
"KtsyO0": {
"defaultMessage": "Enter Pin"
},
"KyRp/q": {
"defaultMessage": "Wallet Request"
},
"LBAnc7": {
"defaultMessage": "View as user?"
},
@ -871,6 +1000,12 @@
"MWTx65": {
"defaultMessage": "Default Page"
},
"MYBYdJ": {
"defaultMessage": "Short Text Note"
},
"MYUBaG": {
"defaultMessage": "Client Authentication"
},
"MiMipu": {
"defaultMessage": "Set as primary Nostr address (nip05)"
},
@ -904,6 +1039,9 @@
"NAuFNH": {
"defaultMessage": "You already have a subscription of this type, please renew or pay"
},
"NDTFsp": {
"defaultMessage": "Job Feedback"
},
"NepkXH": {
"defaultMessage": "Can't vote with {amount} sats, please set a different default zap amount"
},
@ -943,6 +1081,9 @@
"ORGv1Q": {
"defaultMessage": "Created"
},
"ORa81+": {
"defaultMessage": "Merge Requests"
},
"OoZgbB": {
"defaultMessage": "Failed to update, please try again"
},
@ -991,6 +1132,9 @@
"QWhotP": {
"defaultMessage": "Zap Pool only works if you use one of the supported wallet connections (WebLN, LNC, LNDHub or Nostr Wallet Connect)"
},
"QpaLA3": {
"defaultMessage": "Channel Message"
},
"Qxv0B2": {
"defaultMessage": "You currently have {number} sats in your zap pool."
},
@ -1006,12 +1150,18 @@
"RDha9y": {
"defaultMessage": "Service Worker Not Running"
},
"RRz1cA": {
"defaultMessage": "Repository state announcements"
},
"RSr2uB": {
"defaultMessage": "Username must only contain lowercase letters and numbers"
},
"RahCRH": {
"defaultMessage": "Expired"
},
"RefZpK": {
"defaultMessage": "Short-form Portrait Video Event"
},
"RfhLwC": {
"defaultMessage": "By: {author}"
},
@ -1051,6 +1201,12 @@
"SYQtZ7": {
"defaultMessage": "LN Address Proxy"
},
"Sd0PKc": {
"defaultMessage": "Relay sets"
},
"SfwSIm": {
"defaultMessage": "Problem Tracker"
},
"ShdEie": {
"defaultMessage": "Mark all read"
},
@ -1063,6 +1219,9 @@
"Ss0sWu": {
"defaultMessage": "Pay Now"
},
"SsUQnC": {
"defaultMessage": "Application-specific Data"
},
"StKzTE": {
"defaultMessage": "The author has marked this note as a <i>sensitive topic</i>"
},
@ -1072,6 +1231,9 @@
"TDR5ge": {
"defaultMessage": "Media in notes will automatically be shown for selected people, otherwise only the link will show"
},
"TGc5nI": {
"defaultMessage": "Handler information"
},
"TH1fFo": {
"defaultMessage": "Telegram"
},
@ -1093,6 +1255,9 @@
"TdtZQ5": {
"defaultMessage": "Crypto"
},
"Tdv6NY": {
"defaultMessage": "Interest sets"
},
"TgDKhI": {
"defaultMessage": "Calendar Events"
},
@ -1109,12 +1274,12 @@
"TwyMau": {
"defaultMessage": "Account"
},
"TzeMlV": {
"defaultMessage": "Sorry, we dont understand this event kind, please try one of the following apps instead!"
},
"U1aPPi": {
"defaultMessage": "Stop listening"
},
"U30H69": {
"defaultMessage": "Community Definition"
},
"UJTWqI": {
"defaultMessage": "Remove from my relays"
},
@ -1187,6 +1352,9 @@
"WeLEuL": {
"defaultMessage": "From Server"
},
"Wj5TbN": {
"defaultMessage": "Issues"
},
"WmZhfL": {
"defaultMessage": "Automatically translate notes to your local language"
},
@ -1253,6 +1421,9 @@
"YuoEb9": {
"defaultMessage": "Try another relay"
},
"Z48UEo": {
"defaultMessage": "Channel Metadata"
},
"Z4BMCZ": {
"defaultMessage": "Enter pairing phrase"
},
@ -1274,6 +1445,9 @@
"Zff6lu": {
"defaultMessage": "Username iris.to/<b>{name}</b> is reserved for you!"
},
"ZlIh4/": {
"defaultMessage": "Encrypted Direct Messages"
},
"ZlmK/p": {
"defaultMessage": "{name} invited you to {app}"
},
@ -1340,9 +1514,15 @@
"bxv59V": {
"defaultMessage": "Just now"
},
"c+1p0i": {
"defaultMessage": "Kind mute sets"
},
"c+JYNI": {
"defaultMessage": "No thanks"
},
"c2T+1B": {
"defaultMessage": "Redirects"
},
"c35bj2": {
"defaultMessage": "If you have an enquiry about your NIP-05 order please DM {link}"
},
@ -1361,6 +1541,9 @@
"cHCwbF": {
"defaultMessage": "Photography"
},
"cKbMRX": {
"defaultMessage": "Direct Message"
},
"cPIKU2": {
"defaultMessage": "Following"
},
@ -1377,6 +1560,9 @@
"cg1VJ2": {
"defaultMessage": "Connect Wallet"
},
"cnwHgH": {
"defaultMessage": "OpenTimestamps"
},
"cuP16y": {
"defaultMessage": "Multi account support"
},
@ -1407,6 +1593,9 @@
"dOQCL8": {
"defaultMessage": "Display name"
},
"dZZIGe": {
"defaultMessage": "Modular Article Header"
},
"ddd3JX": {
"defaultMessage": "Popular Hashtags"
},
@ -1419,6 +1608,9 @@
"djNL6D": {
"defaultMessage": "Read-only"
},
"dmcsBA": {
"defaultMessage": "Classified Listing"
},
"dmsiLv": {
"defaultMessage": "A default Zap Pool split of {n} has been configured for {site} developers, you can disable it at any time in {link}"
},
@ -1446,6 +1638,9 @@
"eSzf2G": {
"defaultMessage": "A single zap of {nIn} sats will allocate {nOut} sats to the zap pool."
},
"eW/Bj9": {
"defaultMessage": "Feed"
},
"eXT2QQ": {
"defaultMessage": "Group Chat"
},
@ -1500,6 +1695,9 @@
"fqwcJ1": {
"defaultMessage": "On-chain Donation"
},
"fr+XYA": {
"defaultMessage": "Lightning Pub RPC"
},
"fsB/4p": {
"defaultMessage": "Saved"
},
@ -1536,6 +1734,9 @@
"gl1NeW": {
"defaultMessage": "Lists"
},
"go2/QF": {
"defaultMessage": "User server list"
},
"grQ+mI": {
"defaultMessage": "Proof of Work"
},
@ -1548,6 +1749,9 @@
"h8XMJL": {
"defaultMessage": "Badges"
},
"h9M0rW": {
"defaultMessage": "User Metadata"
},
"hF6IN2": {
"defaultMessage": "Prune Follow List"
},
@ -1578,6 +1782,9 @@
"hniz8Z": {
"defaultMessage": "here"
},
"hv/eRj": {
"defaultMessage": "Blocked relays list"
},
"hvFRBo": {
"defaultMessage": "Interaction"
},
@ -1617,6 +1824,9 @@
"ieGrWo": {
"defaultMessage": "Follow"
},
"igUUst": {
"defaultMessage": "Group Chat Threaded Reply"
},
"ipHVx5": {
"defaultMessage": "Generate Invoice"
},
@ -1641,6 +1851,9 @@
"jMzO1S": {
"defaultMessage": "Internal error: {msg}"
},
"jiAVXu": {
"defaultMessage": "Video Event"
},
"jvo0vs": {
"defaultMessage": "Save"
},
@ -1665,6 +1878,12 @@
"kJYo0u": {
"defaultMessage": "{n,plural,=0{{name} reposted} other{{name} & {n} others reposted}}"
},
"kKC9ya": {
"defaultMessage": "Wallet Info"
},
"kNd2FL": {
"defaultMessage": "Tidal login"
},
"kQAf2d": {
"defaultMessage": "Select"
},
@ -1674,6 +1893,9 @@
"kc79d3": {
"defaultMessage": "Topics"
},
"klCm96": {
"defaultMessage": "Community Post Approval"
},
"kqPQJD": {
"defaultMessage": "Configure zap pool"
},
@ -1725,6 +1947,12 @@
"lvlPhZ": {
"defaultMessage": "Pay Invoice"
},
"m/59y2": {
"defaultMessage": "Zap Request"
},
"m6h2Eg": {
"defaultMessage": "Handler recommendation"
},
"mCEKiZ": {
"defaultMessage": "{n} notes have been muted"
},
@ -1752,9 +1980,15 @@
"n1Whvj": {
"defaultMessage": "Switch"
},
"n5l7tP": {
"defaultMessage": "Time-Based Calendar Event"
},
"n8k1SG": {
"defaultMessage": "{n}MiB"
},
"nD4frR": {
"defaultMessage": "Bid confirmation"
},
"nDejmx": {
"defaultMessage": "Unblock"
},
@ -1767,6 +2001,9 @@
"nIchMQ": {
"defaultMessage": "Searching for account activity ({progress})"
},
"nPHrqp": {
"defaultMessage": "Coinjoin Pool"
},
"nUT0Lv": {
"defaultMessage": "Tools"
},
@ -1794,6 +2031,9 @@
"ojzbwv": {
"defaultMessage": "Hey, it looks like you dont have a Nostr Address yet, you should get one! Check out {link}"
},
"ozZ2Cj": {
"defaultMessage": "Badge Award"
},
"p4N05H": {
"defaultMessage": "Upload"
},
@ -1812,6 +2052,9 @@
"plOM0t": {
"defaultMessage": "Custom Emoji"
},
"plg2Ua": {
"defaultMessage": "Channel Mute User"
},
"puLNUJ": {
"defaultMessage": "Pin"
},
@ -1821,12 +2064,24 @@
"pzTOmv": {
"defaultMessage": "Followers"
},
"q3OuMw": {
"defaultMessage": "Torrent Comment"
},
"qAY40L": {
"defaultMessage": "Date-Based Calendar Event"
},
"qBYNMb": {
"defaultMessage": "Group Thread Reply"
},
"qD9EUF": {
"defaultMessage": "Email <> DM bridge for your Snort nostr address"
},
"qDwvZ4": {
"defaultMessage": "Unknown error"
},
"qFIVx4": {
"defaultMessage": "Profile Badges"
},
"qMePPG": {
"defaultMessage": "Note"
},
@ -1878,6 +2133,9 @@
"rAQG0X": {
"defaultMessage": "Relay List Metadata"
},
"rIsVe+": {
"defaultMessage": "Public chats list"
},
"rMgF34": {
"defaultMessage": "Back up now"
},
@ -1905,6 +2163,9 @@
"rx1i0i": {
"defaultMessage": "Short link"
},
"sFUkSN": {
"defaultMessage": "Bookmark sets"
},
"sKDn4e": {
"defaultMessage": "Show Badges"
},
@ -1926,6 +2187,12 @@
"t79a6U": {
"defaultMessage": "Connection Success:"
},
"tDDiRL": {
"defaultMessage": "Interests list"
},
"tFpT/O": {
"defaultMessage": "Release artifact sets"
},
"tO1oq9": {
"defaultMessage": "Video Events"
},
@ -1938,6 +2205,9 @@
"tU0ADf": {
"defaultMessage": "Unknown NIP-{x}"
},
"tVuVg9": {
"defaultMessage": "Video View Event"
},
"tf1lIh": {
"defaultMessage": "Free"
},
@ -1962,6 +2232,9 @@
"u/vOPu": {
"defaultMessage": "Paid"
},
"u4I8q8": {
"defaultMessage": "Pin list"
},
"u81G9+": {
"defaultMessage": "Uptime"
},
@ -1974,6 +2247,9 @@
"uD7Els": {
"defaultMessage": "External Identities in Profiles"
},
"uJaMkO": {
"defaultMessage": "Relay list to receive DMs"
},
"uSV4Ti": {
"defaultMessage": "Reposts need to be manually confirmed"
},
@ -1998,6 +2274,9 @@
"vB3oQ/": {
"defaultMessage": "Must be a contact list or pubkey list"
},
"vBsZhD": {
"defaultMessage": "Communities list"
},
"vN5UH8": {
"defaultMessage": "Profile Image"
},
@ -2028,6 +2307,9 @@
"wEQDC6": {
"defaultMessage": "Edit"
},
"wOyDTB": {
"defaultMessage": "File storage server list"
},
"wSZR47": {
"defaultMessage": "Submit"
},
@ -2040,6 +2322,9 @@
"wih7iJ": {
"defaultMessage": "name is blocked"
},
"wlWMuh": {
"defaultMessage": "Patches"
},
"wofVHy": {
"defaultMessage": "Moderation"
},
@ -2103,9 +2388,15 @@
"yLzgxH": {
"defaultMessage": "Popular Relays"
},
"yeX8yA": {
"defaultMessage": "Native App"
},
"z3UjXR": {
"defaultMessage": "Debug"
},
"z3Ukvq": {
"defaultMessage": "Draft Long-form Content"
},
"zCb8fX": {
"defaultMessage": "Weight"
},

View File

@ -17,6 +17,7 @@
"/JE/X+": "Account Support",
"/T7HId": "HTTP File Storage Integration",
"/Xf4UW": "Send anonymous usage metrics",
"/b1IHW": "Group Chat Message",
"/d6vEc": "Make your profile easier to find and share",
"/ioUrF": "From File",
"/n5KSF": "{n} ms",
@ -48,18 +49,22 @@
"28oKbu": "Moderated Communities",
"29sHFE": "Wallet Connect",
"2BBGxX": "Subject tag in text events",
"2HIqeO": "User emoji list",
"2IFGap": "Donate",
"2LbrkB": "Enter password",
"2O2sfp": "Finish",
"2Qsf9/": "Generic lists",
"2a2YiP": "{n} Bookmarks",
"2k0Cv+": "Dislikes ({n})",
"2mcwT8": "New Note",
"2oCF7O": "Followed by friends of friends",
"2raFAu": "Application-specific data",
"2ukA4d": "{n} hours",
"3/onCd": "Replies",
"39AHJm": "Sign Up",
"3GWu6/": "User Statuses",
"3KNMbJ": "Articles",
"3MKdAw": "Blobs stored on mediaservers",
"3QwfJR": "~{amount}",
"3adEeb": "{n} viewers",
"3cc4Ct": "Light",
@ -74,6 +79,7 @@
"450Fty": "None",
"47E53q": "Wiki",
"47FYwb": "Cancel",
"48zn4v": "Bid",
"4IPzdn": "Primary Developers",
"4L2vUY": "Your new NIP-05 handle is:",
"4MjsHk": "Life",
@ -87,16 +93,20 @@
"5BVs2e": "zap",
"5CB6zB": "Zap Splits",
"5PRWs7": "Notifications API Enabled",
"5dfmvv": "Zap Goal",
"5oTnfy": "Buy Handle",
"5qEWCr": "File Metadata",
"5u6iEc": "Transfer to Pubkey",
"5vMmmR": "Usernames are not unique on Nostr. The nostr address is your unique human-readable address that is unique to you upon registration.",
"5ykRmX": "Send zap",
"6/hB3S": "Watch Replay",
"60kEE3": "Mute list",
"62nsdy": "Retry",
"634VVz": "Connection Failed:",
"6559gb": "New follow list length {length}",
"65BmHb": "Failed to proxy image from {host}, click here to load directly",
"6D4Hhn": "Recommend Relay",
"6KGebm": "Seal",
"6OSOXl": "Reason: <i>{reason}</i>",
"6WWD34": "Looking for: {noteId}",
"6bgpn+": "Not all clients support this, you may still receive some zaps as if zap splits was not configured",
@ -107,11 +117,15 @@
"6xap9L": "Good",
"7+Domh": "Notes",
"712i26": "Proxy uses HODL invoices to forward the payment, which hides the pubkey of your node",
"753yX5": "Label",
"769A8p": "Wiki article",
"77nkEO": "Relay Information Document",
"7LFU8U": "Search Capability",
"7UOvbT": "Offline",
"7YkSA2": "Community Leader",
"7gMmSL": "Reaction",
"7hp70g": "NIP-05",
"7jfPsW": "Modular Article Content",
"7nAz/z": "Mute notes from people who are outside your web of trust",
"7pFGAQ": "Close Relays",
"8/vBbP": "Reposts ({n})",
@ -122,25 +136,32 @@
"8QDesP": "Zap {n} sats",
"8Rkoyb": "Recipient",
"8Y6bZQ": "Invalid zap split: {input}",
"8ZGqWl": "Group Thread",
"8g2vyB": "name too long",
"8jmwT8": "bech32-encoded entities",
"8v1NN+": "Pairing phrase",
"8xdDLn": "Follow sets",
"8za9Pq": "Draft Classified Listing",
"9+Ddtu": "Next",
"9HU8vw": "Reply",
"9SvQep": "Follows {n}",
"9V0wg3": "Calendar Event RSVP",
"9WRlF4": "Send",
"9kO0VQ": "Hide muted notes",
"9kSari": "Retry publishing",
"9pMqYs": "Nostr Address",
"9wO4wJ": "Lightning Invoice",
"A86fJ+": "Generic Repost",
"ADmfQT": "Parent",
"ALdW69": "Note by {name}",
"AN0Z7Q": "Muted Words",
"ASRK0S": "This author has been muted",
"AedFVZ": "Create or update a product",
"Ai8VHU": "Unlimited note retention on Snort relay",
"AkCxS/": "Reason",
"AktAk2": "Great",
"Am8glJ": "Game",
"AqGfF4": "Channel Creation",
"Aujn2T": "Count",
"Awq32I": "Push notifications",
"AxDOiG": "Months",
@ -150,34 +171,43 @@
"B6H7eJ": "nsec, npub, nip-05, hex",
"B7wvUM": "You can add a single or multiple relays, one per line.",
"BGCM48": "Write access to Snort relay, with 1 year of event retention",
"BGGacK": "AI Embeddings / Vector lists",
"BQW4gi": "Relay-based Groups",
"BWpuKl": "Update",
"BfuAQ5": "Marketplace UI/UX",
"BjNwZW": "Nostr address (nip05)",
"Blxcdx": "Relay",
"Bo+O//": "HTTP Auth",
"C1LjMx": "Lightning Donation",
"C6Lhhp": "Live Event",
"C7642/": "Quote Repost",
"C81/uG": "Logout",
"C8FsOr": "Popular Servers",
"C8HhVE": "Suggested Follows",
"CA1efg": "Video sets",
"CHTbO3": "Failed to load invoice",
"CJx5Nd": "Profile Zaps",
"CM+Cfj": "Follow List",
"CM0k0d": "Prune follow list",
"CVWeJ6": "Trending People",
"CYkOCI": "and {count} others you follow",
"Cdxwi0": "Repository announcements",
"CmZ9ls": "{n} Muted",
"Coy6SH": "Calendar",
"CsCUYo": "{n} sats",
"Cu/K85": "Translated from {lang}",
"CzHZoc": "Social Graph",
"D++Njw": "Text Note References",
"D+KzKd": "Automatically zap every note when loaded",
"D09wbg": "Badge Definition",
"D3idYv": "Settings",
"D9xTLE": "Channel Hide Message",
"DBiVK1": "Cache",
"DKnriN": "Send sats",
"DZzCem": "Show latest {n} notes",
"Dh3hbq": "Auto Zap",
"Dn82AL": "Live",
"DqUmXt": "Product sold as an auction",
"DrZqav": "About must be less than {limit} characters",
"DtYelJ": "Transfer",
"Dx4ey3": "Toggle all",
@ -187,20 +217,25 @@
"EJbFi7": "Search notes",
"ELbg9p": "Data Providers",
"EQKRE4": "Show badges on profile pages",
"EWeVrH": "Reaction to a website",
"EWyQH5": "Global",
"Ebl/B2": "Translate to {lang}",
"Ec+xLY": "Curation sets",
"EcZF24": "Custom Relays",
"EcfIwB": "Username is available",
"EcglP9": "Key",
"EjFyoR": "On-chain Donation Address",
"EnCOBJ": "Buy",
"EsHX35": "Sorry, we dont understand this event kind ({name}), please try one of the following apps instead!",
"F/6VqP": "Server",
"F3l7xL": "Add Account",
"F4eJ/3": "Classified Listings",
"FDguSC": "{n} Zaps",
"FHWpHC": "Wallet Response",
"FHvSk3": "Authentication of clients to relays",
"FMfjrl": "Show status messages on profile pages",
"FSYL8G": "Trending Users",
"FWJR1B": "User groups",
"FcNSft": "Redirect issues HTTP redirect to the supplied lightning address",
"FdhSU2": "Claim Now",
"FfYsOb": "An error has occured!",
@ -216,6 +251,7 @@
"GSye7T": "Lightning Address",
"GUlSVG": "Claim your included Snort nostr address",
"Gcn9NQ": "Magnet Link",
"GpkNYn": "Torrent",
"GqQeu/": "Invalid Lightning Address",
"GspYR7": "{n} Dislike",
"Gxcr08": "Broadcast Event",
@ -223,6 +259,7 @@
"H/oroO": "Dealing with Unknown Events",
"H0JBH6": "Log Out",
"H0OG3T": "Leader Info",
"H1GTaC": "Bookmark list",
"H6/kLh": "Order Paid!",
"HAlOn1": "Name",
"HFls6j": "name will be available later",
@ -230,8 +267,10 @@
"HWbkEK": "Clear cache and reload",
"HbefNb": "Open Wallet",
"HhcAVH": "You don't follow this person, click here to load media from <i>{link}</i>, or update <a><i>your preferences</i></a> to always load media from everybody.",
"HpAmQZ": "Relay reviews",
"HqRNN8": "Support",
"HzSFeV": "Expiration Timestamp",
"I0tYZf": "Create or update a stall",
"I1AoOu": "Last post {time}",
"IEwZvs": "Are you sure you want to unpin this note?",
"IIOul1": "Account Data",
@ -248,6 +287,7 @@
"J+dIsA": "Subscriptions",
"J1iLmb": "Notifications Not Allowed",
"J2HeQ+": "Use commas to separate words e.g. word1, word2, word3",
"J2Q92B": "Emoji sets",
"JCIgkj": "Username",
"JGrt9q": "Send sats to {name}",
"JHEHCk": "Zaps ({n})",
@ -255,6 +295,7 @@
"JPFYIM": "No lightning address",
"JSx7y9": "Subscribe to {site_name} {plan} for {price} and receive the following rewards",
"JeoS4y": "Repost",
"Jh5zKH": "Search relays list",
"JjGgXI": "Search users",
"JkLHGw": "Website",
"JmcxzF": "Relays are servers you connect to for sending and receiving events. Aim for 4-8 relays.",
@ -265,11 +306,13 @@
"K9zklU": "External Content IDs",
"KAhAcM": "Enter LNDHub config",
"KGmQjH": "Highlights",
"KJryGq": "Live Chat Message",
"KQvWvD": "Deleted",
"KT9nox": "Protected Events",
"KahimY": "Unknown event kind: {kind}",
"KipVeG": "Mapping Nostr keys to DNS-based internet identifiers",
"KtsyO0": "Enter Pin",
"KyRp/q": "Wallet Request",
"LBAnc7": "View as user?",
"LEmxc8": "Zap Goals",
"LKw/ue": "Check out the code {link}",
@ -288,6 +331,8 @@
"MI2jkA": "Not available:",
"MP54GY": "Wallet password",
"MWTx65": "Default Page",
"MYBYdJ": "Short Text Note",
"MYUBaG": "Client Authentication",
"MiMipu": "Set as primary Nostr address (nip05)",
"MkQ4FX": "Proxy Tags",
"Ml7+RS": "Send this link to your friends and share the magic of the nostr.",
@ -299,6 +344,7 @@
"N2IrpM": "Confirm",
"NAidKb": "Notifications",
"NAuFNH": "You already have a subscription of this type, please renew or pay",
"NDTFsp": "Job Feedback",
"NepkXH": "Can't vote with {amount} sats, please set a different default zap amount",
"NndBJE": "New users page",
"Nr9Yyx": "Reposts",
@ -312,6 +358,7 @@
"OQSOJF": "Get a free nostr address",
"OQXnew": "You subscription is still active, you can't renew yet",
"ORGv1Q": "Created",
"ORa81+": "Merge Requests",
"OoZgbB": "Failed to update, please try again",
"OuProE": "Long-form Content",
"OxPdQ0": "Scanning {date}",
@ -328,13 +375,16 @@
"QDFTjG": "{n} Relays",
"QJfhKt": "The private key is like a password, but it cannot be reset. Guard it carefully and never show it to anyone. Once someone has your private key, they will have access to your account forever.",
"QWhotP": "Zap Pool only works if you use one of the supported wallet connections (WebLN, LNC, LNDHub or Nostr Wallet Connect)",
"QpaLA3": "Channel Message",
"Qxv0B2": "You currently have {number} sats in your zap pool.",
"Qy6/Ft": "Private Direct Messages",
"R/6nsx": "Subscription",
"R81upa": "People you follow",
"RDha9y": "Service Worker Not Running",
"RRz1cA": "Repository state announcements",
"RSr2uB": "Username must only contain lowercase letters and numbers",
"RahCRH": "Expired",
"RefZpK": "Short-form Portrait Video Event",
"RfhLwC": "By: {author}",
"RhDAoS": "Are you sure you want to delete {id}",
"RmxSZo": "Data Vending Machines",
@ -348,13 +398,17 @@
"SP0+yi": "Buy Subscription",
"SW3TFA": "Popular relays used by people you follow.",
"SYQtZ7": "LN Address Proxy",
"Sd0PKc": "Relay sets",
"SfwSIm": "Problem Tracker",
"ShdEie": "Mark all read",
"Sjo1P4": "Custom",
"SmuYUd": "What should we call you?",
"Ss0sWu": "Pay Now",
"SsUQnC": "Application-specific Data",
"StKzTE": "The author has marked this note as a <i>sensitive topic</i>",
"T83nqf": "Relays close to your geographic location.",
"TDR5ge": "Media in notes will automatically be shown for selected people, otherwise only the link will show",
"TGc5nI": "Handler information",
"TH1fFo": "Telegram",
"TJo5E6": "Preview",
"TOG64f": "Use Local Relay",
@ -362,13 +416,14 @@
"TaeBqw": "Sign in with Nostr Extension",
"TdTXXf": "Learn more",
"TdtZQ5": "Crypto",
"Tdv6NY": "Interest sets",
"TgDKhI": "Calendar Events",
"TpgeGw": "Hex Salt..",
"Tpy00S": "People",
"TvKqBp": "liked",
"TwyMau": "Account",
"TzeMlV": "Sorry, we dont understand this event kind, please try one of the following apps instead!",
"U1aPPi": "Stop listening",
"U30H69": "Community Definition",
"UJTWqI": "Remove from my relays",
"ULXFfP": "Receive",
"UNjfWJ": "Check all event signatures received from relays",
@ -393,6 +448,7 @@
"W4SaxY": "Local",
"W9355R": "Unmute",
"WeLEuL": "From Server",
"Wj5TbN": "Issues",
"WmZhfL": "Automatically translate notes to your local language",
"WvGmZT": "npub / nprofile / nostr address",
"X6tipZ": "Sign in with key",
@ -415,6 +471,7 @@
"YXA3AH": "Enable reactions",
"Yf3DwC": "Connect a wallet to send instant payments",
"YuoEb9": "Try another relay",
"Z48UEo": "Channel Metadata",
"Z4BMCZ": "Enter pairing phrase",
"Z7kkeJ": "Delegated Event Signing",
"ZFe9tl": "Compose a note",
@ -422,6 +479,7 @@
"ZLmyG9": "Contributors",
"ZS+jRE": "Send zap splits to",
"Zff6lu": "Username iris.to/<b>{name}</b> is reserved for you!",
"ZlIh4/": "Encrypted Direct Messages",
"ZlmK/p": "{name} invited you to {app}",
"a1x4gD": "Media servers store media which you can share in notes as images and videos",
"a5UPxh": "Fund developers and platforms providing NIP-05 verification services",
@ -444,18 +502,22 @@
"bep9C3": "Public Key",
"bfvyfs": "Anon",
"bxv59V": "Just now",
"c+1p0i": "Kind mute sets",
"c+JYNI": "No thanks",
"c2T+1B": "Redirects",
"c35bj2": "If you have an enquiry about your NIP-05 order please DM {link}",
"c3LlRO": "{n}KiB",
"c3g2hL": "Broadcast Again",
"cFbU1B": "Using Alby? Go to {link} to get your NWC config!",
"cG/bKQ": "Native nostr wallet connection",
"cHCwbF": "Photography",
"cKbMRX": "Direct Message",
"cPIKU2": "Following",
"cQfLWb": "URL..",
"cVcgLJ": "Media Servers",
"cWx9t8": "Mute all",
"cg1VJ2": "Connect Wallet",
"cnwHgH": "OpenTimestamps",
"cuP16y": "Multi account support",
"cuV2gK": "name is registered",
"cw1Ftc": "Live Activities",
@ -466,10 +528,12 @@
"d7d0/x": "LN Address",
"dK2CcV": "The public key is like your username, you can share it with anyone.",
"dOQCL8": "Display name",
"dZZIGe": "Modular Article Header",
"ddd3JX": "Popular Hashtags",
"deEeEI": "Register",
"djLctd": "Amount in sats",
"djNL6D": "Read-only",
"dmcsBA": "Classified Listing",
"dmsiLv": "A default Zap Pool split of {n} has been configured for {site} developers, you can disable it at any time in {link}",
"e5x8FT": "Kind",
"e61Jf3": "Coming soon",
@ -479,6 +543,7 @@
"eHAneD": "Reaction emoji",
"eJj8HD": "Get Verified",
"eSzf2G": "A single zap of {nIn} sats will allocate {nOut} sats to the zap pool.",
"eW/Bj9": "Feed",
"eXT2QQ": "Group Chat",
"eZtOxB": "window.nostr capability for web browsers",
"egib+2": "{n,plural,=1{& {n} other} other{& {n} others}}",
@ -497,6 +562,7 @@
"fjAcWo": "Gift Wraps",
"flnGvv": "What's on your mind?",
"fqwcJ1": "On-chain Donation",
"fr+XYA": "Lightning Pub RPC",
"fsB/4p": "Saved",
"fucxlm": "Attach Media",
"furjvW": "Watch Stream",
@ -509,10 +575,12 @@
"gjBiyj": "Loading...",
"gkMmvC": "Android Signer Application",
"gl1NeW": "Lists",
"go2/QF": "User server list",
"grQ+mI": "Proof of Work",
"gtNjNP": "Basic protocol flow description",
"h7jvCs": "{site} is more fun together!",
"h8XMJL": "Badges",
"h9M0rW": "User Metadata",
"hF6IN2": "Prune Follow List",
"hMQmIw": "Sync Account",
"hMzcSq": "Messages",
@ -523,6 +591,7 @@
"hicxcO": "Show replies",
"hmZ3Bz": "Media",
"hniz8Z": "here",
"hv/eRj": "Blocked relays list",
"hvFRBo": "Interaction",
"i/dBAR": "Zap Pool",
"i5gBFz": "Your sent and received payments will show up here.",
@ -536,6 +605,7 @@
"iYc3Ld": "Payments",
"icCxlA": "new users page",
"ieGrWo": "Follow",
"igUUst": "Group Chat Threaded Reply",
"ipHVx5": "Generate Invoice",
"itPgxd": "Profile",
"izWS4J": "Unfollow",
@ -544,6 +614,7 @@
"jAmfGl": "Your {site_name} subscription is expired",
"jHa/ko": "Clean up your feed",
"jMzO1S": "Internal error: {msg}",
"jiAVXu": "Video Event",
"jvo0vs": "Save",
"jzgQ2z": "{n} Reactions",
"k0kCJp": "Apply Now",
@ -552,9 +623,12 @@
"k9SQm1": "Relays which you have connected to before and appear to be reliable.",
"kEZUR8": "Register an Iris username",
"kJYo0u": "{n,plural,=0{{name} reposted} other{{name} & {n} others reposted}}",
"kKC9ya": "Wallet Info",
"kNd2FL": "Tidal login",
"kQAf2d": "Select",
"kaaf1E": "now",
"kc79d3": "Topics",
"klCm96": "Community Post Approval",
"kqPQJD": "Configure zap pool",
"kuPHYE": "{n,plural,=0{{name} liked} other{{name} & {n} others liked}}",
"l+ikU1": "Everything in {plan}",
@ -572,6 +646,8 @@
"lnaT9F": "Following {n}",
"lsNFM1": "Click to load content from {link}",
"lvlPhZ": "Pay Invoice",
"m/59y2": "Zap Request",
"m6h2Eg": "Handler recommendation",
"mCEKiZ": "{n} notes have been muted",
"mErPop": "It looks like you dont have any, check {link} to buy one!",
"mFtdYh": "{type} Worker Relay",
@ -581,11 +657,14 @@
"mOFG3K": "Start",
"mfe8RW": "Option: {n}",
"n1Whvj": "Switch",
"n5l7tP": "Time-Based Calendar Event",
"n8k1SG": "{n}MiB",
"nD4frR": "Bid confirmation",
"nDejmx": "Unblock",
"nGBrvw": "Bookmarks",
"nGGDsi": "Notifications Allowed",
"nIchMQ": "Searching for account activity ({progress})",
"nPHrqp": "Coinjoin Pool",
"nUT0Lv": "Tools",
"nWQFic": "Renew",
"nihgfo": "Listen to this article",
@ -595,17 +674,23 @@
"oJ+JJN": "Nothing found :/",
"odFwjL": "Follows only",
"ojzbwv": "Hey, it looks like you dont have a Nostr Address yet, you should get one! Check out {link}",
"ozZ2Cj": "Badge Award",
"p4N05H": "Upload",
"p9Ps2l": "{x}/{y} have relays ({percent})",
"pEEBFk": "Reliable Relays",
"pI+77w": "Downloadable backups from Snort relay",
"pRess9": "ZapPool",
"plOM0t": "Custom Emoji",
"plg2Ua": "Channel Mute User",
"puLNUJ": "Pin",
"pyjJ5f": "Nostr Marketplace (for resilient marketplaces)",
"pzTOmv": "Followers",
"q3OuMw": "Torrent Comment",
"qAY40L": "Date-Based Calendar Event",
"qBYNMb": "Group Thread Reply",
"qD9EUF": "Email <> DM bridge for your Snort nostr address",
"qDwvZ4": "Unknown error",
"qFIVx4": "Profile Badges",
"qMePPG": "Note",
"qMx1sA": "Default Zap amount",
"qUJTsT": "Blocked",
@ -623,6 +708,7 @@
"r3C4x/": "Software",
"r5srDR": "Enter wallet password",
"rAQG0X": "Relay List Metadata",
"rIsVe+": "Public chats list",
"rMgF34": "Back up now",
"rRRXtB": "Lightning Zaps",
"rT14Ow": "Add Relays",
@ -632,6 +718,7 @@
"rmdsT4": "{n} days",
"rn52n9": "Public Chat Channels",
"rx1i0i": "Short link",
"sFUkSN": "Bookmark sets",
"sKDn4e": "Show Badges",
"sUNhQE": "user",
"sZQzjQ": "Failed to parse zap split: {input}",
@ -639,10 +726,13 @@
"saorw+": "Event Deletion Request",
"sfL/O+": "Muted notes will not be shown",
"t79a6U": "Connection Success:",
"tDDiRL": "Interests list",
"tFpT/O": "Release artifact sets",
"tO1oq9": "Video Events",
"tOdNiY": "Dark",
"tRGdV1": "Versioned Encryption",
"tU0ADf": "Unknown NIP-{x}",
"tVuVg9": "Video View Event",
"tf1lIh": "Free",
"th5lxp": "Send note to a subset of your write relays",
"thnRpU": "Getting NIP-05 verified can help:",
@ -651,10 +741,12 @@
"ttxS0b": "Supporter Badge",
"tzMNF3": "Status",
"u/vOPu": "Paid",
"u4I8q8": "Pin list",
"u81G9+": "Uptime",
"u9NoC1": "Name must be less than {limit} characters",
"uCk8r+": "Already have an account?",
"uD7Els": "External Identities in Profiles",
"uJaMkO": "Relay list to receive DMs",
"uSV4Ti": "Reposts need to be manually confirmed",
"uc0din": "Send sats splits to",
"ufvXH1": "Found {n} events",
@ -663,6 +755,7 @@
"usAvMr": "Edit Profile",
"v8lolG": "Start chat",
"vB3oQ/": "Must be a contact list or pubkey list",
"vBsZhD": "Communities list",
"vN5UH8": "Profile Image",
"vU/Q5i": "This tool will search for the last event published by all of your follows and remove those who have not posted in 6 months",
"vZ4quW": "NIP-05 is a DNS based verification spec which helps to validate you as a real user.",
@ -673,10 +766,12 @@
"w1Fanr": "Business",
"w6qrwX": "NSFW",
"wEQDC6": "Edit",
"wOyDTB": "File storage server list",
"wSZR47": "Submit",
"wc9st7": "Media Attachments",
"whSrs+": "Nostr Public Chat",
"wih7iJ": "name is blocked",
"wlWMuh": "Patches",
"wofVHy": "Moderation",
"wqyN/i": "Find out more info about {service} at {link}",
"wtLjP6": "Copy ID",
@ -698,7 +793,9 @@
"yAztTU": "{n} eSats",
"yCLnBC": "LNURL or Lightning Address",
"yLzgxH": "Popular Relays",
"yeX8yA": "Native App",
"z3UjXR": "Debug",
"z3Ukvq": "Draft Long-form Content",
"zCb8fX": "Weight",
"zFegDD": "Contact",
"zINlao": "Owner",