feat: relay info page
This commit is contained in:
parent
9660c07633
commit
6fafae67aa
@ -33,10 +33,11 @@ interface CollapsedSectionProps {
|
||||
title: ReactNode;
|
||||
children: ReactNode;
|
||||
className?: string;
|
||||
startClosed?: boolean;
|
||||
}
|
||||
|
||||
export const CollapsedSection = ({ title, children, className }: CollapsedSectionProps) => {
|
||||
const [collapsed, setCollapsed] = useState(true);
|
||||
export const CollapsedSection = ({ title, children, className, startClosed }: CollapsedSectionProps) => {
|
||||
const [collapsed, setCollapsed] = useState(startClosed ?? true);
|
||||
const icon = (
|
||||
<div className={classNames("collapse-icon", { flip: !collapsed })}>
|
||||
<Icon name="arrowFront" />
|
||||
|
@ -1,6 +1,4 @@
|
||||
import { RelaySettings } from "@snort/system";
|
||||
import classNames from "classnames";
|
||||
import { FormattedMessage } from "react-intl";
|
||||
import { Link } from "react-router-dom";
|
||||
|
||||
import useRelayState from "@/Feed/RelayState";
|
||||
import useLogin from "@/Hooks/useLogin";
|
||||
@ -8,65 +6,30 @@ import RelayUptime from "@/Pages/settings/relays/uptime";
|
||||
import { getRelayName } from "@/Utils";
|
||||
|
||||
import Icon from "../Icons/Icon";
|
||||
import RelayPermissions from "./permissions";
|
||||
import RelayStatusLabel from "./status-label";
|
||||
|
||||
export interface RelayProps {
|
||||
addr: string;
|
||||
}
|
||||
|
||||
export default function Relay(props: RelayProps) {
|
||||
const { state } = useLogin(s => ({ v: s.state.version, state: s.state }));
|
||||
const connection = useRelayState(props.addr);
|
||||
|
||||
const settings = state.relays?.find(a => a.url === props.addr)?.settings;
|
||||
if (!connection || !settings) return;
|
||||
|
||||
async function configure(o: RelaySettings) {
|
||||
await state.updateRelay(props.addr, o);
|
||||
}
|
||||
|
||||
const { state } = useLogin(s => ({ v: s.state.version, state: s.state }));
|
||||
if (!connection) return;
|
||||
const name = connection.info?.name ?? getRelayName(props.addr);
|
||||
return (
|
||||
<tr>
|
||||
<td className="text-ellipsis" title={props.addr}>
|
||||
{name.length > 20 ? <>{name.slice(0, 20)}...</> : name}
|
||||
<Link to={`/settings/relays/${encodeURIComponent(props.addr)}`}>
|
||||
{name.length > 20 ? <>{name.slice(0, 20)}...</> : name}
|
||||
</Link>
|
||||
</td>
|
||||
<td>
|
||||
<div className="flex gap-1 items-center">
|
||||
<div
|
||||
className={classNames("rounded-full w-4 h-4", {
|
||||
"bg-success": connection.isOpen,
|
||||
"bg-error": !connection.isOpen,
|
||||
})}></div>
|
||||
{connection.isOpen ? (
|
||||
<FormattedMessage defaultMessage="Connected" />
|
||||
) : (
|
||||
<FormattedMessage defaultMessage="Offline" />
|
||||
)}
|
||||
</div>
|
||||
<RelayStatusLabel conn={connection} />
|
||||
</td>
|
||||
<td>
|
||||
<div className="flex gap-2 cursor-pointer select-none justify-center">
|
||||
<div
|
||||
className={settings.read ? "" : "text-gray"}
|
||||
onClick={() =>
|
||||
configure({
|
||||
read: !settings.read,
|
||||
write: settings.write,
|
||||
})
|
||||
}>
|
||||
<FormattedMessage defaultMessage="Read" />
|
||||
</div>
|
||||
<div
|
||||
className={settings.write ? "" : "text-gray"}
|
||||
onClick={() =>
|
||||
configure({
|
||||
read: settings.read,
|
||||
write: !settings.write,
|
||||
})
|
||||
}>
|
||||
<FormattedMessage defaultMessage="Write" />
|
||||
</div>
|
||||
</div>
|
||||
<RelayPermissions conn={connection} />
|
||||
</td>
|
||||
<td className="text-center">
|
||||
<RelayUptime url={props.addr} />
|
||||
|
@ -1,9 +0,0 @@
|
||||
.favicon {
|
||||
width: 21px;
|
||||
height: 21px;
|
||||
max-width: unset;
|
||||
}
|
||||
|
||||
.relay-active {
|
||||
color: var(--highlight);
|
||||
}
|
@ -1,12 +1,10 @@
|
||||
import "./RelaysMetadata.css";
|
||||
|
||||
import { FullRelaySettings } from "@snort/system";
|
||||
import { useState } from "react";
|
||||
|
||||
import Nostrich from "@/assets/img/nostrich.webp";
|
||||
import Icon from "@/Components/Icons/Icon";
|
||||
|
||||
export const RelayFavicon = ({ url }: { url: string }) => {
|
||||
export const RelayFavicon = ({ url, size }: { url: string; size?: number }) => {
|
||||
const cleanUrl = url
|
||||
.replace(/^wss:\/\//, "https://")
|
||||
.replace(/^ws:\/\//, "http://")
|
||||
@ -14,10 +12,12 @@ export const RelayFavicon = ({ url }: { url: string }) => {
|
||||
const [faviconUrl, setFaviconUrl] = useState(`${cleanUrl}/favicon.ico`);
|
||||
return (
|
||||
<img
|
||||
className="circle favicon"
|
||||
className="rounded-full object-cover"
|
||||
src={faviconUrl}
|
||||
onError={() => setFaviconUrl(Nostrich)}
|
||||
alt={`favicon for ${url}`}
|
||||
width={size ?? 20}
|
||||
height={size ?? 20}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
17
packages/app/src/Components/Relay/paid.tsx
Normal file
17
packages/app/src/Components/Relay/paid.tsx
Normal file
@ -0,0 +1,17 @@
|
||||
import { RelayInfo } from "@snort/system";
|
||||
import classNames from "classnames";
|
||||
import { FormattedMessage } from "react-intl";
|
||||
|
||||
export default function RelayPaymentLabel({ info }: { info: RelayInfo }) {
|
||||
const isPaid = info?.limitation?.payment_required ?? false;
|
||||
return (
|
||||
<div
|
||||
className={classNames("rounded-full px-2 py-1 font-medium", {
|
||||
"bg-[var(--pro)] text-black": isPaid,
|
||||
"bg-[var(--free)]": !isPaid,
|
||||
})}>
|
||||
{isPaid && <FormattedMessage defaultMessage="Paid" />}
|
||||
{!isPaid && <FormattedMessage defaultMessage="Free" />}
|
||||
</div>
|
||||
);
|
||||
}
|
33
packages/app/src/Components/Relay/permissions.tsx
Normal file
33
packages/app/src/Components/Relay/permissions.tsx
Normal file
@ -0,0 +1,33 @@
|
||||
import { ConnectionType } from "@snort/system/dist/connection-pool";
|
||||
import { FormattedMessage } from "react-intl";
|
||||
|
||||
import useLogin from "@/Hooks/useLogin";
|
||||
|
||||
export default function RelayPermissions({ conn }: { conn: ConnectionType }) {
|
||||
const { state } = useLogin(s => ({ v: s.state.version, state: s.state }));
|
||||
|
||||
return (
|
||||
<div className="flex gap-2 cursor-pointer select-none">
|
||||
<div
|
||||
className={conn.settings.read ? "" : "text-gray"}
|
||||
onClick={async () =>
|
||||
await state.updateRelay(conn.address, {
|
||||
read: !conn.settings.read,
|
||||
write: conn.settings.write,
|
||||
})
|
||||
}>
|
||||
<FormattedMessage defaultMessage="Read" />
|
||||
</div>
|
||||
<div
|
||||
className={conn.settings.write ? "" : "text-gray"}
|
||||
onClick={async () =>
|
||||
await state.updateRelay(conn.address, {
|
||||
read: conn.settings.read,
|
||||
write: !conn.settings.write,
|
||||
})
|
||||
}>
|
||||
<FormattedMessage defaultMessage="Write" />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
9
packages/app/src/Components/Relay/software.tsx
Normal file
9
packages/app/src/Components/Relay/software.tsx
Normal file
@ -0,0 +1,9 @@
|
||||
import { Link } from "react-router-dom";
|
||||
|
||||
export default function RelaySoftware({ software }: { software: string }) {
|
||||
if (software.includes("git")) {
|
||||
const u = new URL(software);
|
||||
return <Link to={software}>{u.pathname.split("/").at(-1)?.replace(".git", "")}</Link>;
|
||||
}
|
||||
return software;
|
||||
}
|
16
packages/app/src/Components/Relay/status-label.tsx
Normal file
16
packages/app/src/Components/Relay/status-label.tsx
Normal file
@ -0,0 +1,16 @@
|
||||
import { ConnectionType } from "@snort/system/dist/connection-pool";
|
||||
import classNames from "classnames";
|
||||
import { FormattedMessage } from "react-intl";
|
||||
|
||||
export default function RelayStatusLabel({ conn }: { conn: ConnectionType }) {
|
||||
return (
|
||||
<div className="flex gap-1 items-center">
|
||||
<div
|
||||
className={classNames("rounded-full w-4 h-4", {
|
||||
"bg-success": conn.isOpen,
|
||||
"bg-error": !conn.isOpen,
|
||||
})}></div>
|
||||
{conn.isOpen ? <FormattedMessage defaultMessage="Connected" /> : <FormattedMessage defaultMessage="Offline" />}
|
||||
</div>
|
||||
);
|
||||
}
|
149
packages/app/src/Components/nip.tsx
Normal file
149
packages/app/src/Components/nip.tsx
Normal file
@ -0,0 +1,149 @@
|
||||
import { FormattedMessage } from "react-intl";
|
||||
|
||||
export default function NipDescription({ nip }: { nip: number }) {
|
||||
switch (nip) {
|
||||
case 1:
|
||||
return <FormattedMessage defaultMessage="Basic protocol flow description" />;
|
||||
case 2:
|
||||
return <FormattedMessage defaultMessage="Follow List" />;
|
||||
case 3:
|
||||
return <FormattedMessage defaultMessage="OpenTimestamps Attestations for Events" />;
|
||||
case 4:
|
||||
return <FormattedMessage defaultMessage="Encrypted Direct Message" />;
|
||||
case 5:
|
||||
return <FormattedMessage defaultMessage="Mapping Nostr keys to DNS-based internet identifiers" />;
|
||||
case 6:
|
||||
return <FormattedMessage defaultMessage="Basic key derivation from mnemonic seed phrase" />;
|
||||
case 7:
|
||||
return <FormattedMessage defaultMessage="window.nostr capability for web browsers" />;
|
||||
case 8:
|
||||
return <FormattedMessage defaultMessage="Handling Mentions" />;
|
||||
case 9:
|
||||
return <FormattedMessage defaultMessage="Event Deletion Request" />;
|
||||
case 10:
|
||||
return <FormattedMessage defaultMessage="Conventions for clients' use of e and p tags in text events" />;
|
||||
case 11:
|
||||
return <FormattedMessage defaultMessage="Relay Information Document" />;
|
||||
case 13:
|
||||
return <FormattedMessage defaultMessage="Proof of Work" />;
|
||||
case 14:
|
||||
return <FormattedMessage defaultMessage="Subject tag in text events" />;
|
||||
case 15:
|
||||
return <FormattedMessage defaultMessage="Nostr Marketplace (for resilient marketplaces)" />;
|
||||
case 17:
|
||||
return <FormattedMessage defaultMessage="Private Direct Messages" />;
|
||||
case 18:
|
||||
return <FormattedMessage defaultMessage="Reposts" />;
|
||||
case 19:
|
||||
return <FormattedMessage defaultMessage="bech32-encoded entities" />;
|
||||
case 21:
|
||||
return <FormattedMessage defaultMessage="nostr: URI scheme" />;
|
||||
case 23:
|
||||
return <FormattedMessage defaultMessage="Long-form Content" />;
|
||||
case 24:
|
||||
return <FormattedMessage defaultMessage="Extra metadata fields and tags" />;
|
||||
case 25:
|
||||
return <FormattedMessage defaultMessage="Reactions" />;
|
||||
case 26:
|
||||
return <FormattedMessage defaultMessage="Delegated Event Signing" />;
|
||||
case 27:
|
||||
return <FormattedMessage defaultMessage="Text Note References" />;
|
||||
case 28:
|
||||
return <FormattedMessage defaultMessage="Public Chat" />;
|
||||
case 29:
|
||||
return <FormattedMessage defaultMessage="Relay-based Groups" />;
|
||||
case 30:
|
||||
return <FormattedMessage defaultMessage="Custom Emoji" />;
|
||||
case 31:
|
||||
return <FormattedMessage defaultMessage="Dealing with Unknown Events" />;
|
||||
case 32:
|
||||
return <FormattedMessage defaultMessage="Labeling" />;
|
||||
case 34:
|
||||
return <FormattedMessage defaultMessage="git stuff" />;
|
||||
case 35:
|
||||
return <FormattedMessage defaultMessage="Torrents" />;
|
||||
case 36:
|
||||
return <FormattedMessage defaultMessage="Sensitive Content" />;
|
||||
case 38:
|
||||
return <FormattedMessage defaultMessage="User Statuses" />;
|
||||
case 39:
|
||||
return <FormattedMessage defaultMessage="External Identities in Profiles" />;
|
||||
case 40:
|
||||
return <FormattedMessage defaultMessage="Expiration Timestamp" />;
|
||||
case 42:
|
||||
return <FormattedMessage defaultMessage="Authentication of clients to relays" />;
|
||||
case 44:
|
||||
return <FormattedMessage defaultMessage="Versioned Encryption" />;
|
||||
case 45:
|
||||
return <FormattedMessage defaultMessage="Counting results" />;
|
||||
case 46:
|
||||
return <FormattedMessage defaultMessage="Nostr Connect" />;
|
||||
case 47:
|
||||
return <FormattedMessage defaultMessage="Wallet Connect" />;
|
||||
case 48:
|
||||
return <FormattedMessage defaultMessage="Proxy Tags" />;
|
||||
case 49:
|
||||
return <FormattedMessage defaultMessage="Private Key Encryption" />;
|
||||
case 50:
|
||||
return <FormattedMessage defaultMessage="Search Capability" />;
|
||||
case 51:
|
||||
return <FormattedMessage defaultMessage="Lists" />;
|
||||
case 52:
|
||||
return <FormattedMessage defaultMessage="Calendar Events" />;
|
||||
case 53:
|
||||
return <FormattedMessage defaultMessage="Live Activities" />;
|
||||
case 54:
|
||||
return <FormattedMessage defaultMessage="Wiki" />;
|
||||
case 55:
|
||||
return <FormattedMessage defaultMessage="Android Signer Application" />;
|
||||
case 56:
|
||||
return <FormattedMessage defaultMessage="Reporting" />;
|
||||
case 57:
|
||||
return <FormattedMessage defaultMessage="Lightning Zaps" />;
|
||||
case 58:
|
||||
return <FormattedMessage defaultMessage="Badges" />;
|
||||
case 59:
|
||||
return <FormattedMessage defaultMessage="Gift Wrap" />;
|
||||
case 64:
|
||||
return <FormattedMessage defaultMessage="Chess (PGN)" />;
|
||||
case 65:
|
||||
return <FormattedMessage defaultMessage="Relay List Metadata" />;
|
||||
case 70:
|
||||
return <FormattedMessage defaultMessage="Protected Events" />;
|
||||
case 71:
|
||||
return <FormattedMessage defaultMessage="Video Events" />;
|
||||
case 72:
|
||||
return <FormattedMessage defaultMessage="Moderated Communities" />;
|
||||
case 73:
|
||||
return <FormattedMessage defaultMessage="External Content IDs" />;
|
||||
case 75:
|
||||
return <FormattedMessage defaultMessage="Zap Goals" />;
|
||||
case 78:
|
||||
return <FormattedMessage defaultMessage="Application-specific data" />;
|
||||
case 84:
|
||||
return <FormattedMessage defaultMessage="Highlights" />;
|
||||
case 89:
|
||||
return <FormattedMessage defaultMessage="Recommended Application Handlers" />;
|
||||
case 90:
|
||||
return <FormattedMessage defaultMessage="Data Vending Machines" />;
|
||||
case 92:
|
||||
return <FormattedMessage defaultMessage="Media Attachments" />;
|
||||
case 94:
|
||||
return <FormattedMessage defaultMessage="File Metadata" />;
|
||||
case 96:
|
||||
return <FormattedMessage defaultMessage="HTTP File Storage Integration" />;
|
||||
case 98:
|
||||
return <FormattedMessage defaultMessage="HTTP Auth" />;
|
||||
case 99:
|
||||
return <FormattedMessage defaultMessage="Classified Listings" />;
|
||||
default:
|
||||
return (
|
||||
<FormattedMessage
|
||||
defaultMessage="Unknown NIP-{x}"
|
||||
values={{
|
||||
x: nip.toString().padStart(2, "0"),
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
@ -1,126 +1,212 @@
|
||||
import { Connection } from "@snort/system";
|
||||
import { FormattedMessage } from "react-intl";
|
||||
import { useNavigate, useParams } from "react-router-dom";
|
||||
import { RelayInfo as RI } from "@snort/system";
|
||||
import { useEffect, useState, useSyncExternalStore } from "react";
|
||||
import { FormattedMessage, FormattedNumber } from "react-intl";
|
||||
import { Link, useParams } from "react-router-dom";
|
||||
|
||||
import AsyncButton from "@/Components/Button/AsyncButton";
|
||||
import ProfilePreview from "@/Components/User/ProfilePreview";
|
||||
import { RelayMetrics } from "@/Cache";
|
||||
import { CollapsedSection } from "@/Components/Collapsed";
|
||||
import NipDescription from "@/Components/nip";
|
||||
import RelayPaymentLabel from "@/Components/Relay/paid";
|
||||
import RelayPermissions from "@/Components/Relay/permissions";
|
||||
import { RelayFavicon } from "@/Components/Relay/RelaysMetadata";
|
||||
import RelaySoftware from "@/Components/Relay/software";
|
||||
import RelayStatusLabel from "@/Components/Relay/status-label";
|
||||
import ProfileImage from "@/Components/User/ProfileImage";
|
||||
import useRelayState from "@/Feed/RelayState";
|
||||
import useEventPublisher from "@/Hooks/useEventPublisher";
|
||||
import useLogin from "@/Hooks/useLogin";
|
||||
import { parseId, unwrap } from "@/Utils";
|
||||
import { getRelayName, parseId } from "@/Utils";
|
||||
|
||||
import messages from "./messages";
|
||||
import RelayUptime from "./relays/uptime";
|
||||
|
||||
const RelayInfo = () => {
|
||||
const params = useParams();
|
||||
const navigate = useNavigate();
|
||||
const login = useLogin();
|
||||
const { system } = useEventPublisher();
|
||||
const [info, setInfo] = useState<RI>();
|
||||
|
||||
const conn = [...system.pool].find(([, a]) => a.id === params.id)?.[1];
|
||||
const conn = useRelayState(params.id ?? "");
|
||||
|
||||
async function loadRelayInfo() {
|
||||
const u = new URL(params.id ?? "");
|
||||
const rsp = await fetch(`${u.protocol === "wss:" ? "https:" : "http:"}//${u.host}`, {
|
||||
headers: {
|
||||
accept: "application/nostr+json",
|
||||
},
|
||||
});
|
||||
if (rsp.ok) {
|
||||
const data = await rsp.json();
|
||||
for (const [k, v] of Object.entries(data)) {
|
||||
if (v === "unset" || v === "" || v === "~") {
|
||||
data[k] = undefined;
|
||||
}
|
||||
}
|
||||
setInfo(data);
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
loadRelayInfo().catch(console.error);
|
||||
}, []);
|
||||
|
||||
const stats = useSyncExternalStore(
|
||||
c => RelayMetrics.hook(c, "*"),
|
||||
() => RelayMetrics.snapshot(),
|
||||
).find(a => a.addr === params.id);
|
||||
|
||||
const stats = useRelayState(conn?.address ?? "");
|
||||
return (
|
||||
<>
|
||||
<h3 className="pointer" onClick={() => navigate("/settings/relays")}>
|
||||
<FormattedMessage {...messages.Relays} />
|
||||
</h3>
|
||||
<div>
|
||||
<h3>{stats?.info?.name}</h3>
|
||||
<p>{stats?.info?.description}</p>
|
||||
|
||||
{stats?.info?.pubkey && (
|
||||
<>
|
||||
<h4>
|
||||
<FormattedMessage {...messages.Owner} />
|
||||
</h4>
|
||||
<ProfilePreview pubkey={parseId(stats.info.pubkey)} />
|
||||
</>
|
||||
)}
|
||||
{stats?.info?.software && (
|
||||
<div className="flex">
|
||||
<h4 className="grow">
|
||||
<FormattedMessage {...messages.Software} />
|
||||
</h4>
|
||||
<div className="flex flex-col">
|
||||
{stats.info.software.startsWith("http") ? (
|
||||
<a href={stats.info.software} target="_blank" rel="noreferrer">
|
||||
{stats.info.software}
|
||||
</a>
|
||||
) : (
|
||||
<>{stats.info.software}</>
|
||||
)}
|
||||
<small>
|
||||
{!stats.info.version?.startsWith("v") && "v"}
|
||||
{stats.info.version}
|
||||
</small>
|
||||
<div className="flex flex-col gap-4">
|
||||
<div className="flex justify-between">
|
||||
<div className="flex gap-4 items-center">
|
||||
<RelayFavicon url={params.id ?? ""} size={80} />
|
||||
<div className="flex flex-col gap-2">
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="text-2xl font-bold">{info?.name ?? getRelayName(params.id ?? "")}</div>
|
||||
{info && <RelayPaymentLabel info={info} />}
|
||||
</div>
|
||||
<div className="text-gray-light">{params.id}</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{stats?.info?.contact && (
|
||||
<div className="flex">
|
||||
<h4 className="grow">
|
||||
<FormattedMessage {...messages.Contact} />
|
||||
</h4>
|
||||
<a
|
||||
href={`${stats.info.contact.startsWith("mailto:") ? "" : "mailto:"}${stats.info.contact}`}
|
||||
target="_blank"
|
||||
rel="noreferrer">
|
||||
{stats.info.contact}
|
||||
</a>
|
||||
</div>
|
||||
)}
|
||||
{stats?.info?.supported_nips && (
|
||||
<>
|
||||
<h4>
|
||||
<FormattedMessage {...messages.Supports} />
|
||||
</h4>
|
||||
<div className="grow">
|
||||
{stats.info?.supported_nips?.map(a => (
|
||||
<a key={a} target="_blank" rel="noreferrer" href={`https://nips.be/${a}`} className="pill">
|
||||
NIP-{a.toString().padStart(2, "0")}
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
{conn instanceof Connection && (
|
||||
<>
|
||||
<h4>
|
||||
<FormattedMessage defaultMessage="Active Subscriptions" />
|
||||
</h4>
|
||||
<div className="grow">
|
||||
{conn.ActiveRequests.map(a => (
|
||||
<span className="pill" key={a}>
|
||||
{a}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
{conn instanceof Connection && (
|
||||
<>
|
||||
<h4>
|
||||
<FormattedMessage defaultMessage="Pending Subscriptions" />
|
||||
</h4>
|
||||
<div className="grow">
|
||||
{conn.PendingRequests.map(a => (
|
||||
<span className="pill" key={a.obj[1]}>
|
||||
{a.obj[1]}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
<div className="flex mt10 justify-end">
|
||||
<AsyncButton
|
||||
onClick={async () => {
|
||||
await login.state.removeRelay(unwrap(conn).address, true);
|
||||
navigate("/settings/relays");
|
||||
}}>
|
||||
<FormattedMessage {...messages.Remove} />
|
||||
</AsyncButton>
|
||||
</div>
|
||||
|
||||
{info && (
|
||||
<div className="grid grid-cols-3 gap-4">
|
||||
<div className="flex flex-col gap-2">
|
||||
<div className="uppercase text-secondary font-bold text-sm">
|
||||
<FormattedMessage defaultMessage="Admin" />
|
||||
</div>
|
||||
<div>{info?.pubkey && <ProfileImage pubkey={parseId(info.pubkey)} size={30} />}</div>
|
||||
</div>
|
||||
<div className="flex flex-col gap-2">
|
||||
<div className="uppercase text-secondary font-bold text-sm">
|
||||
<FormattedMessage defaultMessage="Contact" />
|
||||
</div>
|
||||
<div>
|
||||
{info?.contact && (
|
||||
<a
|
||||
href={`${info.contact.startsWith("mailto:") ? "" : "mailto:"}${info.contact}`}
|
||||
target="_blank"
|
||||
rel="noreferrer">
|
||||
{info.contact.replace("mailto:", "")}
|
||||
</a>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col gap-2">
|
||||
<div className="uppercase text-secondary font-bold text-sm">
|
||||
<FormattedMessage defaultMessage="Software" />
|
||||
</div>
|
||||
<div>{info?.software && <RelaySoftware software={info.software} />}</div>
|
||||
</div>
|
||||
{conn && (
|
||||
<>
|
||||
<div className="flex flex-col gap-2">
|
||||
<div className="uppercase text-secondary font-bold text-sm">
|
||||
<FormattedMessage defaultMessage="Status" />
|
||||
</div>
|
||||
<div>
|
||||
<RelayStatusLabel conn={conn} />
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col gap-2">
|
||||
<div className="uppercase text-secondary font-bold text-sm">
|
||||
<FormattedMessage defaultMessage="Permissions" />
|
||||
</div>
|
||||
<div>
|
||||
<RelayPermissions conn={conn} />
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col gap-2">
|
||||
<div className="uppercase text-secondary font-bold text-sm">
|
||||
<FormattedMessage defaultMessage="Uptime" />
|
||||
</div>
|
||||
<div>
|
||||
<RelayUptime url={conn.address} />
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<hr className="border-border-color" />
|
||||
|
||||
{stats && (
|
||||
<CollapsedSection
|
||||
title={
|
||||
<div className="text-xl font-semibold">
|
||||
<FormattedMessage defaultMessage="Relay Stats" />
|
||||
</div>
|
||||
}
|
||||
startClosed={false}>
|
||||
<ul className="list-disc">
|
||||
<li>
|
||||
<span className="text-gray-light">
|
||||
<FormattedMessage defaultMessage="Total Events:" />
|
||||
</span>
|
||||
|
||||
<FormattedNumber value={stats.events} />
|
||||
</li>
|
||||
<li>
|
||||
<span className="text-gray-light">
|
||||
<FormattedMessage defaultMessage="Connection Success:" />
|
||||
</span>
|
||||
|
||||
<FormattedNumber value={stats.connects} />
|
||||
</li>
|
||||
<li>
|
||||
<span className="text-gray-light">
|
||||
<FormattedMessage defaultMessage="Connection Failed:" />
|
||||
</span>
|
||||
|
||||
<FormattedNumber value={stats.disconnects} />
|
||||
</li>
|
||||
<li>
|
||||
<span className="text-gray-light">
|
||||
<FormattedMessage defaultMessage="Average Latency:" />
|
||||
</span>
|
||||
|
||||
<FormattedMessage
|
||||
defaultMessage="{n} ms"
|
||||
values={{
|
||||
n: (
|
||||
<FormattedNumber
|
||||
maximumFractionDigits={0}
|
||||
value={stats.latency.reduce((acc, v) => acc + v, 0) / stats.latency.length}
|
||||
/>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
</li>
|
||||
<li>
|
||||
<span className="text-gray-light">
|
||||
<FormattedMessage defaultMessage="Last Seen:" />
|
||||
</span>
|
||||
|
||||
{new Date(stats.lastSeen).toLocaleString()}
|
||||
</li>
|
||||
</ul>
|
||||
</CollapsedSection>
|
||||
)}
|
||||
<hr className="border-border-color" />
|
||||
{info?.supported_nips && (
|
||||
<CollapsedSection
|
||||
title={
|
||||
<div className="text-xl font-semibold">
|
||||
<FormattedMessage defaultMessage="Supported NIPs" />
|
||||
</div>
|
||||
}
|
||||
startClosed={false}>
|
||||
<ul className="list-disc">
|
||||
{info.supported_nips.map(n => (
|
||||
<li key={n}>
|
||||
<Link
|
||||
target="_blank"
|
||||
to={`https://github.com/nostr-protocol/nips/blob/master/${n.toString().padStart(2, "0")}.md`}>
|
||||
<NipDescription nip={n} />
|
||||
</Link>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</CollapsedSection>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
|
@ -3,6 +3,7 @@ import { OutboxModel } from "@snort/system";
|
||||
import { SnortContext } from "@snort/system-react";
|
||||
import { useContext, useMemo, useSyncExternalStore } from "react";
|
||||
import { FormattedMessage } from "react-intl";
|
||||
import { Link } from "react-router-dom";
|
||||
|
||||
import { RelayMetrics } from "@/Cache";
|
||||
import AsyncButton from "@/Components/Button/AsyncButton";
|
||||
@ -89,9 +90,11 @@ export function DiscoverRelays() {
|
||||
.slice(0, 20)
|
||||
.map(a => (
|
||||
<tr key={a.relay}>
|
||||
<td className="flex gap-2 items-center">
|
||||
<RelayFavicon url={a.relay} />
|
||||
{getRelayName(a.relay)}
|
||||
<td>
|
||||
<Link to={`/settings/relays/${encodeURIComponent(a.relay)}`} className="flex gap-2 items-center">
|
||||
<RelayFavicon url={a.relay} />
|
||||
{getRelayName(a.relay)}
|
||||
</Link>
|
||||
</td>
|
||||
<td className="text-center">
|
||||
<RelayUptime url={a.relay} />
|
||||
@ -135,9 +138,11 @@ export function DiscoverRelays() {
|
||||
<tbody>
|
||||
{reliableRelays.slice(0, 40).map(a => (
|
||||
<tr key={a.addr}>
|
||||
<td className="flex gap-2 items-center" title={a.addr}>
|
||||
<RelayFavicon url={a.addr} />
|
||||
{getRelayName(a.addr)}
|
||||
<td title={a.addr}>
|
||||
<Link to={`/settings/relays/${encodeURIComponent(a.addr)}`} className="flex gap-2 items-center">
|
||||
<RelayFavicon url={a.addr} />
|
||||
{getRelayName(a.addr)}
|
||||
</Link>
|
||||
</td>
|
||||
<td className="text-center">
|
||||
<UptimeLabel avgPing={a.avgLatency} />
|
||||
|
@ -54,6 +54,7 @@
|
||||
--primary-bg: #ff3f15;
|
||||
--cashu-gradient: linear-gradient(90deg, #40b039, #adff2a);
|
||||
--pro: #ffdd65;
|
||||
--free: #1a5aff;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
@ -121,6 +122,10 @@ code {
|
||||
font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", monospace;
|
||||
}
|
||||
|
||||
ul {
|
||||
padding-inline-start: 2rem;
|
||||
}
|
||||
|
||||
a {
|
||||
color: inherit;
|
||||
line-height: 1.3em;
|
||||
@ -227,7 +232,8 @@ a.ext {
|
||||
small {
|
||||
color: var(--font-secondary-color);
|
||||
font-size: 14px;
|
||||
line-height: 22px; /* 157.143% */
|
||||
line-height: 22px;
|
||||
/* 157.143% */
|
||||
}
|
||||
|
||||
.button {
|
||||
@ -898,6 +904,7 @@ svg.repeat {
|
||||
border: 1px solid var(--border-color);
|
||||
box-shadow: rgba(0, 0, 0, 0.08) 0 1px 1px;
|
||||
}
|
||||
|
||||
.light button.primary {
|
||||
background: var(--primary-bg);
|
||||
color: #fff;
|
||||
@ -909,6 +916,7 @@ svg.repeat {
|
||||
.light button.secondary:hover {
|
||||
box-shadow: rgba(0, 0, 0, 0.2) 0 1px 3px !important;
|
||||
}
|
||||
|
||||
.light button.primary:hover {
|
||||
box-shadow: 0px 0px 10px var(--primary-bg) !important;
|
||||
}
|
||||
@ -923,7 +931,8 @@ svg.repeat {
|
||||
}
|
||||
|
||||
.hide-scrollbar::-webkit-scrollbar {
|
||||
display: none; /* Safari and Chrome */
|
||||
display: none;
|
||||
/* Safari and Chrome */
|
||||
}
|
||||
|
||||
.pb-safe-area {
|
||||
|
@ -8,6 +8,9 @@
|
||||
"+QM0PJ": {
|
||||
"defaultMessage": "Sync all events for your profile into local cache"
|
||||
},
|
||||
"+QMdsy": {
|
||||
"defaultMessage": "Relay Stats"
|
||||
},
|
||||
"+UjDmN": {
|
||||
"defaultMessage": "Logged in with write access"
|
||||
},
|
||||
@ -44,6 +47,9 @@
|
||||
"/JE/X+": {
|
||||
"defaultMessage": "Account Support"
|
||||
},
|
||||
"/T7HId": {
|
||||
"defaultMessage": "HTTP File Storage Integration"
|
||||
},
|
||||
"/Xf4UW": {
|
||||
"defaultMessage": "Send anonymous usage metrics"
|
||||
},
|
||||
@ -77,6 +83,9 @@
|
||||
"0jOEtS": {
|
||||
"defaultMessage": "Invalid LNURL"
|
||||
},
|
||||
"0kOBMu": {
|
||||
"defaultMessage": "Handling Mentions"
|
||||
},
|
||||
"0mch2Y": {
|
||||
"defaultMessage": "name has disallowed characters"
|
||||
},
|
||||
@ -93,6 +102,9 @@
|
||||
"defaultMessage": "Go",
|
||||
"description": "Button text after entering username in quick signup"
|
||||
},
|
||||
"1/BFEj": {
|
||||
"defaultMessage": "git stuff"
|
||||
},
|
||||
"1Mo59U": {
|
||||
"defaultMessage": "Are you sure you want to remove this note from bookmarks?"
|
||||
},
|
||||
@ -126,6 +138,15 @@
|
||||
"25WwxF": {
|
||||
"defaultMessage": "Don't have an account?"
|
||||
},
|
||||
"28oKbu": {
|
||||
"defaultMessage": "Moderated Communities"
|
||||
},
|
||||
"29sHFE": {
|
||||
"defaultMessage": "Wallet Connect"
|
||||
},
|
||||
"2BBGxX": {
|
||||
"defaultMessage": "Subject tag in text events"
|
||||
},
|
||||
"2IFGap": {
|
||||
"defaultMessage": "Donate"
|
||||
},
|
||||
@ -147,12 +168,18 @@
|
||||
"2oCF7O": {
|
||||
"defaultMessage": "Followed by friends of friends"
|
||||
},
|
||||
"2raFAu": {
|
||||
"defaultMessage": "Application-specific data"
|
||||
},
|
||||
"2ukA4d": {
|
||||
"defaultMessage": "{n} hours"
|
||||
},
|
||||
"39AHJm": {
|
||||
"defaultMessage": "Sign Up"
|
||||
},
|
||||
"3GWu6/": {
|
||||
"defaultMessage": "User Statuses"
|
||||
},
|
||||
"3KNMbJ": {
|
||||
"defaultMessage": "Articles"
|
||||
},
|
||||
@ -177,9 +204,18 @@
|
||||
"3yk8fB": {
|
||||
"defaultMessage": "Wallet"
|
||||
},
|
||||
"40VR6s": {
|
||||
"defaultMessage": "Nostr Connect"
|
||||
},
|
||||
"41BSaT": {
|
||||
"defaultMessage": "Total Events:"
|
||||
},
|
||||
"450Fty": {
|
||||
"defaultMessage": "None"
|
||||
},
|
||||
"47E53q": {
|
||||
"defaultMessage": "Wiki"
|
||||
},
|
||||
"47FYwb": {
|
||||
"defaultMessage": "Cancel"
|
||||
},
|
||||
@ -195,6 +231,9 @@
|
||||
"4OB335": {
|
||||
"defaultMessage": "Dislike"
|
||||
},
|
||||
"4P/kKm": {
|
||||
"defaultMessage": "Private Key Encryption"
|
||||
},
|
||||
"4Vmpt4": {
|
||||
"defaultMessage": "Nostr Plebs is one of the first NIP-05 providers in the space and offers a good collection of domains at reasonable prices"
|
||||
},
|
||||
@ -207,6 +246,9 @@
|
||||
"4rYCjn": {
|
||||
"defaultMessage": "Note to Self"
|
||||
},
|
||||
"4wgYpI": {
|
||||
"defaultMessage": "Recommended Application Handlers"
|
||||
},
|
||||
"5BVs2e": {
|
||||
"defaultMessage": "zap"
|
||||
},
|
||||
@ -219,6 +261,9 @@
|
||||
"5oTnfy": {
|
||||
"defaultMessage": "Buy Handle"
|
||||
},
|
||||
"5qEWCr": {
|
||||
"defaultMessage": "File Metadata"
|
||||
},
|
||||
"5u6iEc": {
|
||||
"defaultMessage": "Transfer to Pubkey"
|
||||
},
|
||||
@ -234,6 +279,9 @@
|
||||
"62nsdy": {
|
||||
"defaultMessage": "Retry"
|
||||
},
|
||||
"634VVz": {
|
||||
"defaultMessage": "Connection Failed:"
|
||||
},
|
||||
"6559gb": {
|
||||
"defaultMessage": "New follow list length {length}"
|
||||
},
|
||||
@ -255,6 +303,9 @@
|
||||
"6mr8WU": {
|
||||
"defaultMessage": "Followed by"
|
||||
},
|
||||
"6pdxsi": {
|
||||
"defaultMessage": "Extra metadata fields and tags"
|
||||
},
|
||||
"6uMqL1": {
|
||||
"defaultMessage": "Unpaid"
|
||||
},
|
||||
@ -267,6 +318,12 @@
|
||||
"712i26": {
|
||||
"defaultMessage": "Proxy uses HODL invoices to forward the payment, which hides the pubkey of your node"
|
||||
},
|
||||
"77nkEO": {
|
||||
"defaultMessage": "Relay Information Document"
|
||||
},
|
||||
"7LFU8U": {
|
||||
"defaultMessage": "Search Capability"
|
||||
},
|
||||
"7UOvbT": {
|
||||
"defaultMessage": "Offline"
|
||||
},
|
||||
@ -282,6 +339,9 @@
|
||||
"89q5wc": {
|
||||
"defaultMessage": "Confirm Reposts"
|
||||
},
|
||||
"8BDFvJ": {
|
||||
"defaultMessage": "Conventions for clients' use of e and p tags in text events"
|
||||
},
|
||||
"8ED/4u": {
|
||||
"defaultMessage": "Reply To"
|
||||
},
|
||||
@ -300,6 +360,9 @@
|
||||
"8g2vyB": {
|
||||
"defaultMessage": "name too long"
|
||||
},
|
||||
"8jmwT8": {
|
||||
"defaultMessage": "bech32-encoded entities"
|
||||
},
|
||||
"8v1NN+": {
|
||||
"defaultMessage": "Pairing phrase"
|
||||
},
|
||||
@ -379,6 +442,9 @@
|
||||
"BGCM48": {
|
||||
"defaultMessage": "Write access to Snort relay, with 1 year of event retention"
|
||||
},
|
||||
"BQW4gi": {
|
||||
"defaultMessage": "Relay-based Groups"
|
||||
},
|
||||
"BWpuKl": {
|
||||
"defaultMessage": "Update"
|
||||
},
|
||||
@ -389,6 +455,9 @@
|
||||
"defaultMessage": "Relay",
|
||||
"description": "Relay name (URL)"
|
||||
},
|
||||
"Bo+O//": {
|
||||
"defaultMessage": "HTTP Auth"
|
||||
},
|
||||
"C1LjMx": {
|
||||
"defaultMessage": "Lightning Donation"
|
||||
},
|
||||
@ -431,6 +500,9 @@
|
||||
"CzHZoc": {
|
||||
"defaultMessage": "Social Graph"
|
||||
},
|
||||
"D++Njw": {
|
||||
"defaultMessage": "Text Note References"
|
||||
},
|
||||
"D+KzKd": {
|
||||
"defaultMessage": "Automatically zap every note when loaded"
|
||||
},
|
||||
@ -500,9 +572,15 @@
|
||||
"F3l7xL": {
|
||||
"defaultMessage": "Add Account"
|
||||
},
|
||||
"F4eJ/3": {
|
||||
"defaultMessage": "Classified Listings"
|
||||
},
|
||||
"FDguSC": {
|
||||
"defaultMessage": "{n} Zaps"
|
||||
},
|
||||
"FHvSk3": {
|
||||
"defaultMessage": "Authentication of clients to relays"
|
||||
},
|
||||
"FMfjrl": {
|
||||
"defaultMessage": "Show status messages on profile pages"
|
||||
},
|
||||
@ -539,6 +617,9 @@
|
||||
"GFOoEE": {
|
||||
"defaultMessage": "Salt"
|
||||
},
|
||||
"GIqktu": {
|
||||
"defaultMessage": "Supported NIPs"
|
||||
},
|
||||
"GL8aXW": {
|
||||
"defaultMessage": "Bookmarks ({n})"
|
||||
},
|
||||
@ -564,6 +645,9 @@
|
||||
"defaultMessage": "Hex Key..",
|
||||
"description": "Hexidecimal 'key' input for improxy"
|
||||
},
|
||||
"H/oroO": {
|
||||
"defaultMessage": "Dealing with Unknown Events"
|
||||
},
|
||||
"H0JBH6": {
|
||||
"defaultMessage": "Log Out"
|
||||
},
|
||||
@ -594,6 +678,9 @@
|
||||
"HqRNN8": {
|
||||
"defaultMessage": "Support"
|
||||
},
|
||||
"HzSFeV": {
|
||||
"defaultMessage": "Expiration Timestamp"
|
||||
},
|
||||
"I1AoOu": {
|
||||
"defaultMessage": "Last post {time}"
|
||||
},
|
||||
@ -615,6 +702,9 @@
|
||||
"IWz1ta": {
|
||||
"defaultMessage": "Auto Translate"
|
||||
},
|
||||
"IcHcWj": {
|
||||
"defaultMessage": "Last Seen:"
|
||||
},
|
||||
"Ig9/a1": {
|
||||
"defaultMessage": "Sent {n} sats to {name}"
|
||||
},
|
||||
@ -678,27 +768,45 @@
|
||||
"JymXbw": {
|
||||
"defaultMessage": "Private Key"
|
||||
},
|
||||
"K1wl1/": {
|
||||
"defaultMessage": "Average Latency:"
|
||||
},
|
||||
"K3r6DQ": {
|
||||
"defaultMessage": "Delete"
|
||||
},
|
||||
"K7AkdL": {
|
||||
"defaultMessage": "Show"
|
||||
},
|
||||
"K9zklU": {
|
||||
"defaultMessage": "External Content IDs"
|
||||
},
|
||||
"KAhAcM": {
|
||||
"defaultMessage": "Enter LNDHub config"
|
||||
},
|
||||
"KGmQjH": {
|
||||
"defaultMessage": "Highlights"
|
||||
},
|
||||
"KQvWvD": {
|
||||
"defaultMessage": "Deleted"
|
||||
},
|
||||
"KT9nox": {
|
||||
"defaultMessage": "Protected Events"
|
||||
},
|
||||
"KahimY": {
|
||||
"defaultMessage": "Unknown event kind: {kind}"
|
||||
},
|
||||
"KipVeG": {
|
||||
"defaultMessage": "Mapping Nostr keys to DNS-based internet identifiers"
|
||||
},
|
||||
"KtsyO0": {
|
||||
"defaultMessage": "Enter Pin"
|
||||
},
|
||||
"LBAnc7": {
|
||||
"defaultMessage": "View as user?"
|
||||
},
|
||||
"LEmxc8": {
|
||||
"defaultMessage": "Zap Goals"
|
||||
},
|
||||
"LKw/ue": {
|
||||
"defaultMessage": "Check out the code {link}"
|
||||
},
|
||||
@ -720,6 +828,9 @@
|
||||
"Lu5/Bj": {
|
||||
"defaultMessage": "Open on Zapstr"
|
||||
},
|
||||
"LuDBLj": {
|
||||
"defaultMessage": "Torrents"
|
||||
},
|
||||
"Lw+I+J": {
|
||||
"defaultMessage": "{n,plural,=0{{name} zapped} other{{name} & {n} others zapped}}"
|
||||
},
|
||||
@ -748,6 +859,9 @@
|
||||
"MiMipu": {
|
||||
"defaultMessage": "Set as primary Nostr address (nip05)"
|
||||
},
|
||||
"MkQ4FX": {
|
||||
"defaultMessage": "Proxy Tags"
|
||||
},
|
||||
"Ml7+RS": {
|
||||
"defaultMessage": "Send this link to your friends and share the magic of the nostr."
|
||||
},
|
||||
@ -757,6 +871,9 @@
|
||||
"MuVeKe": {
|
||||
"defaultMessage": "Buy nostr address"
|
||||
},
|
||||
"Muhna4": {
|
||||
"defaultMessage": "Counting results"
|
||||
},
|
||||
"MzRYWH": {
|
||||
"defaultMessage": "Buying {item}"
|
||||
},
|
||||
@ -781,6 +898,9 @@
|
||||
"NndBJE": {
|
||||
"defaultMessage": "New users page"
|
||||
},
|
||||
"Nr9Yyx": {
|
||||
"defaultMessage": "Reposts"
|
||||
},
|
||||
"NxzeNU": {
|
||||
"defaultMessage": "Dead"
|
||||
},
|
||||
@ -790,6 +910,12 @@
|
||||
"OEW7yJ": {
|
||||
"defaultMessage": "Zaps"
|
||||
},
|
||||
"OIqnZN": {
|
||||
"defaultMessage": "OpenTimestamps Attestations for Events"
|
||||
},
|
||||
"OJHKIL": {
|
||||
"defaultMessage": "Gift Wrap"
|
||||
},
|
||||
"OKhRC6": {
|
||||
"defaultMessage": "Share"
|
||||
},
|
||||
@ -808,6 +934,9 @@
|
||||
"OoZgbB": {
|
||||
"defaultMessage": "Failed to update, please try again"
|
||||
},
|
||||
"OuProE": {
|
||||
"defaultMessage": "Long-form Content"
|
||||
},
|
||||
"OxPdQ0": {
|
||||
"defaultMessage": "Scanning {date}"
|
||||
},
|
||||
@ -850,6 +979,9 @@
|
||||
"Qxv0B2": {
|
||||
"defaultMessage": "You currently have {number} sats in your zap pool."
|
||||
},
|
||||
"Qy6/Ft": {
|
||||
"defaultMessage": "Private Direct Messages"
|
||||
},
|
||||
"R/6nsx": {
|
||||
"defaultMessage": "Subscription"
|
||||
},
|
||||
@ -871,6 +1003,9 @@
|
||||
"RhDAoS": {
|
||||
"defaultMessage": "Are you sure you want to delete {id}"
|
||||
},
|
||||
"RmxSZo": {
|
||||
"defaultMessage": "Data Vending Machines"
|
||||
},
|
||||
"RoOyAh": {
|
||||
"defaultMessage": "Relays"
|
||||
},
|
||||
@ -937,6 +1072,9 @@
|
||||
"TdtZQ5": {
|
||||
"defaultMessage": "Crypto"
|
||||
},
|
||||
"TgDKhI": {
|
||||
"defaultMessage": "Calendar Events"
|
||||
},
|
||||
"TpgeGw": {
|
||||
"defaultMessage": "Hex Salt..",
|
||||
"description": "Hexidecimal 'salt' input for imgproxy"
|
||||
@ -953,9 +1091,6 @@
|
||||
"U1aPPi": {
|
||||
"defaultMessage": "Stop listening"
|
||||
},
|
||||
"UDYlxu": {
|
||||
"defaultMessage": "Pending Subscriptions"
|
||||
},
|
||||
"UJTWqI": {
|
||||
"defaultMessage": "Remove from my relays"
|
||||
},
|
||||
@ -989,6 +1124,9 @@
|
||||
"UxgyeY": {
|
||||
"defaultMessage": "Your referral code is {code}"
|
||||
},
|
||||
"V20Og0": {
|
||||
"defaultMessage": "Labeling"
|
||||
},
|
||||
"VOjC1i": {
|
||||
"defaultMessage": "Pick which upload service you want to upload attachments to"
|
||||
},
|
||||
@ -1064,6 +1202,9 @@
|
||||
"YR2I9M": {
|
||||
"defaultMessage": "No keys, no {app}, There is no way to reset it if you don't back up. It only takes a minute."
|
||||
},
|
||||
"YU7ZYp": {
|
||||
"defaultMessage": "Public Chat"
|
||||
},
|
||||
"YXA3AH": {
|
||||
"defaultMessage": "Enable reactions"
|
||||
},
|
||||
@ -1073,6 +1214,9 @@
|
||||
"Z4BMCZ": {
|
||||
"defaultMessage": "Enter pairing phrase"
|
||||
},
|
||||
"Z7kkeJ": {
|
||||
"defaultMessage": "Delegated Event Signing"
|
||||
},
|
||||
"ZKORll": {
|
||||
"defaultMessage": "Activate Now"
|
||||
},
|
||||
@ -1185,6 +1329,9 @@
|
||||
"cuV2gK": {
|
||||
"defaultMessage": "name is registered"
|
||||
},
|
||||
"cw1Ftc": {
|
||||
"defaultMessage": "Live Activities"
|
||||
},
|
||||
"cyR7Kh": {
|
||||
"defaultMessage": "Back"
|
||||
},
|
||||
@ -1242,6 +1389,9 @@
|
||||
"eXT2QQ": {
|
||||
"defaultMessage": "Group Chat"
|
||||
},
|
||||
"eZtOxB": {
|
||||
"defaultMessage": "window.nostr capability for web browsers"
|
||||
},
|
||||
"egib+2": {
|
||||
"defaultMessage": "{n,plural,=1{& {n} other} other{& {n} others}}"
|
||||
},
|
||||
@ -1317,9 +1467,18 @@
|
||||
"gjBiyj": {
|
||||
"defaultMessage": "Loading..."
|
||||
},
|
||||
"gkMmvC": {
|
||||
"defaultMessage": "Android Signer Application"
|
||||
},
|
||||
"gl1NeW": {
|
||||
"defaultMessage": "Lists"
|
||||
},
|
||||
"grQ+mI": {
|
||||
"defaultMessage": "Proof of Work"
|
||||
},
|
||||
"gtNjNP": {
|
||||
"defaultMessage": "Basic protocol flow description"
|
||||
},
|
||||
"h7jvCs": {
|
||||
"defaultMessage": "{site} is more fun together!"
|
||||
},
|
||||
@ -1374,6 +1533,9 @@
|
||||
"iGT1eE": {
|
||||
"defaultMessage": "Prevent fake accounts from imitating you"
|
||||
},
|
||||
"iHN12u": {
|
||||
"defaultMessage": "Admin"
|
||||
},
|
||||
"iICVoL": {
|
||||
"defaultMessage": "{x} follows ({y} duplicates)"
|
||||
},
|
||||
@ -1455,6 +1617,9 @@
|
||||
"l3H1EK": {
|
||||
"defaultMessage": "Invite your friends"
|
||||
},
|
||||
"l3nTjd": {
|
||||
"defaultMessage": "Basic key derivation from mnemonic seed phrase"
|
||||
},
|
||||
"lCILNz": {
|
||||
"defaultMessage": "Buy Now"
|
||||
},
|
||||
@ -1551,9 +1716,6 @@
|
||||
"p4N05H": {
|
||||
"defaultMessage": "Upload"
|
||||
},
|
||||
"p85Uwy": {
|
||||
"defaultMessage": "Active Subscriptions"
|
||||
},
|
||||
"p9Ps2l": {
|
||||
"defaultMessage": "{x}/{y} have relays ({percent})"
|
||||
},
|
||||
@ -1566,9 +1728,15 @@
|
||||
"pRess9": {
|
||||
"defaultMessage": "ZapPool"
|
||||
},
|
||||
"plOM0t": {
|
||||
"defaultMessage": "Custom Emoji"
|
||||
},
|
||||
"puLNUJ": {
|
||||
"defaultMessage": "Pin"
|
||||
},
|
||||
"pyjJ5f": {
|
||||
"defaultMessage": "Nostr Marketplace (for resilient marketplaces)"
|
||||
},
|
||||
"pzTOmv": {
|
||||
"defaultMessage": "Followers"
|
||||
},
|
||||
@ -1626,15 +1794,27 @@
|
||||
"r5srDR": {
|
||||
"defaultMessage": "Enter wallet password"
|
||||
},
|
||||
"rAQG0X": {
|
||||
"defaultMessage": "Relay List Metadata"
|
||||
},
|
||||
"rMgF34": {
|
||||
"defaultMessage": "Back up now"
|
||||
},
|
||||
"rRRXtB": {
|
||||
"defaultMessage": "Lightning Zaps"
|
||||
},
|
||||
"rT14Ow": {
|
||||
"defaultMessage": "Add Relays"
|
||||
},
|
||||
"reFEEC": {
|
||||
"defaultMessage": "Reporting"
|
||||
},
|
||||
"rfuMjE": {
|
||||
"defaultMessage": "(Default)"
|
||||
},
|
||||
"rkM7l8": {
|
||||
"defaultMessage": "Encrypted Direct Message"
|
||||
},
|
||||
"rmdsT4": {
|
||||
"defaultMessage": "{n} days"
|
||||
},
|
||||
@ -1656,12 +1836,30 @@
|
||||
"saInmO": {
|
||||
"defaultMessage": "The relay name shown is not the same as the full URL entered."
|
||||
},
|
||||
"saorw+": {
|
||||
"defaultMessage": "Event Deletion Request"
|
||||
},
|
||||
"sfL/O+": {
|
||||
"defaultMessage": "Muted notes will not be shown"
|
||||
},
|
||||
"t79a6U": {
|
||||
"defaultMessage": "Connection Success:"
|
||||
},
|
||||
"tO1oq9": {
|
||||
"defaultMessage": "Video Events"
|
||||
},
|
||||
"tOdNiY": {
|
||||
"defaultMessage": "Dark"
|
||||
},
|
||||
"tRGdV1": {
|
||||
"defaultMessage": "Versioned Encryption"
|
||||
},
|
||||
"tU0ADf": {
|
||||
"defaultMessage": "Unknown NIP-{x}"
|
||||
},
|
||||
"tf1lIh": {
|
||||
"defaultMessage": "Free"
|
||||
},
|
||||
"th5lxp": {
|
||||
"defaultMessage": "Send note to a subset of your write relays"
|
||||
},
|
||||
@ -1692,6 +1890,9 @@
|
||||
"uCk8r+": {
|
||||
"defaultMessage": "Already have an account?"
|
||||
},
|
||||
"uD7Els": {
|
||||
"defaultMessage": "External Identities in Profiles"
|
||||
},
|
||||
"uSV4Ti": {
|
||||
"defaultMessage": "Reposts need to be manually confirmed"
|
||||
},
|
||||
@ -1749,6 +1950,9 @@
|
||||
"wSZR47": {
|
||||
"defaultMessage": "Submit"
|
||||
},
|
||||
"wc9st7": {
|
||||
"defaultMessage": "Media Attachments"
|
||||
},
|
||||
"whSrs+": {
|
||||
"defaultMessage": "Nostr Public Chat"
|
||||
},
|
||||
@ -1782,6 +1986,9 @@
|
||||
"xIoGG9": {
|
||||
"defaultMessage": "Go to"
|
||||
},
|
||||
"xPCyu+": {
|
||||
"defaultMessage": "nostr: URI scheme"
|
||||
},
|
||||
"xSoIUU": {
|
||||
"defaultMessage": "Worker Relay"
|
||||
},
|
||||
@ -1836,6 +2043,9 @@
|
||||
"zcaOTs": {
|
||||
"defaultMessage": "Zap amount in sats"
|
||||
},
|
||||
"zi9MdS": {
|
||||
"defaultMessage": "Chess (PGN)"
|
||||
},
|
||||
"zm6qS1": {
|
||||
"defaultMessage": "{n} mins to read"
|
||||
},
|
||||
|
@ -2,6 +2,7 @@
|
||||
"+D82kt": "Are you sure you want to repost: {id}",
|
||||
"+PzQ9Y": "Payout Now",
|
||||
"+QM0PJ": "Sync all events for your profile into local cache",
|
||||
"+QMdsy": "Relay Stats",
|
||||
"+UjDmN": "Logged in with write access",
|
||||
"+Vxixo": "Secret Group Chat",
|
||||
"+aZY2h": "Zap Type",
|
||||
@ -14,6 +15,7 @@
|
||||
"/B8zwF": "Your space the way you want it 😌",
|
||||
"/GCoTA": "Clear",
|
||||
"/JE/X+": "Account Support",
|
||||
"/T7HId": "HTTP File Storage Integration",
|
||||
"/Xf4UW": "Send anonymous usage metrics",
|
||||
"/clOBU": "Weekly",
|
||||
"/d6vEc": "Make your profile easier to find and share",
|
||||
@ -25,11 +27,13 @@
|
||||
"0BUTMv": "Search...",
|
||||
"0MndVW": "Generic LNDHub wallet (BTCPayServer / Alby / LNBits)",
|
||||
"0jOEtS": "Invalid LNURL",
|
||||
"0kOBMu": "Handling Mentions",
|
||||
"0mch2Y": "name has disallowed characters",
|
||||
"0siT4z": "Politics",
|
||||
"0uoY11": "Show Status",
|
||||
"0yO7wF": "{n} secs",
|
||||
"0zASjL": "Go",
|
||||
"1/BFEj": "git stuff",
|
||||
"1Mo59U": "Are you sure you want to remove this note from bookmarks?",
|
||||
"1R43+L": "Enter Nostr Wallet Connect config",
|
||||
"1UWegE": "Be sure to back up your keys!",
|
||||
@ -41,6 +45,9 @@
|
||||
"2/2yg+": "Add",
|
||||
"25V4l1": "Banner",
|
||||
"25WwxF": "Don't have an account?",
|
||||
"28oKbu": "Moderated Communities",
|
||||
"29sHFE": "Wallet Connect",
|
||||
"2BBGxX": "Subject tag in text events",
|
||||
"2IFGap": "Donate",
|
||||
"2LbrkB": "Enter password",
|
||||
"2O2sfp": "Finish",
|
||||
@ -48,8 +55,10 @@
|
||||
"2k0Cv+": "Dislikes ({n})",
|
||||
"2mcwT8": "New Note",
|
||||
"2oCF7O": "Followed by friends of friends",
|
||||
"2raFAu": "Application-specific data",
|
||||
"2ukA4d": "{n} hours",
|
||||
"39AHJm": "Sign Up",
|
||||
"3GWu6/": "User Statuses",
|
||||
"3KNMbJ": "Articles",
|
||||
"3QwfJR": "~{amount}",
|
||||
"3cc4Ct": "Light",
|
||||
@ -58,25 +67,32 @@
|
||||
"3t3kok": "{n,plural,=1{{n} new note} other{{n} new notes}}",
|
||||
"3tVy+Z": "{n} Followers",
|
||||
"3yk8fB": "Wallet",
|
||||
"40VR6s": "Nostr Connect",
|
||||
"41BSaT": "Total Events:",
|
||||
"450Fty": "None",
|
||||
"47E53q": "Wiki",
|
||||
"47FYwb": "Cancel",
|
||||
"4IPzdn": "Primary Developers",
|
||||
"4L2vUY": "Your new NIP-05 handle is:",
|
||||
"4MjsHk": "Life",
|
||||
"4OB335": "Dislike",
|
||||
"4P/kKm": "Private Key Encryption",
|
||||
"4Vmpt4": "Nostr Plebs is one of the first NIP-05 providers in the space and offers a good collection of domains at reasonable prices",
|
||||
"4Z3t5i": "Use imgproxy to compress images",
|
||||
"4emo2p": "Missing Relays",
|
||||
"4rYCjn": "Note to Self",
|
||||
"4wgYpI": "Recommended Application Handlers",
|
||||
"5BVs2e": "zap",
|
||||
"5CB6zB": "Zap Splits",
|
||||
"5PRWs7": "Notifications API Enabled",
|
||||
"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",
|
||||
"62nsdy": "Retry",
|
||||
"634VVz": "Connection Failed:",
|
||||
"6559gb": "New follow list length {length}",
|
||||
"65BmHb": "Failed to proxy image from {host}, click here to load directly",
|
||||
"6OSOXl": "Reason: <i>{reason}</i>",
|
||||
@ -84,21 +100,26 @@
|
||||
"6ewQqw": "Likes ({n})",
|
||||
"6k7xfM": "Trending notes",
|
||||
"6mr8WU": "Followed by",
|
||||
"6pdxsi": "Extra metadata fields and tags",
|
||||
"6uMqL1": "Unpaid",
|
||||
"6xap9L": "Good",
|
||||
"7+Domh": "Notes",
|
||||
"712i26": "Proxy uses HODL invoices to forward the payment, which hides the pubkey of your node",
|
||||
"77nkEO": "Relay Information Document",
|
||||
"7LFU8U": "Search Capability",
|
||||
"7UOvbT": "Offline",
|
||||
"7YkSA2": "Community Leader",
|
||||
"7hp70g": "NIP-05",
|
||||
"8/vBbP": "Reposts ({n})",
|
||||
"89q5wc": "Confirm Reposts",
|
||||
"8BDFvJ": "Conventions for clients' use of e and p tags in text events",
|
||||
"8ED/4u": "Reply To",
|
||||
"8HJxXG": "Sign up",
|
||||
"8QDesP": "Zap {n} sats",
|
||||
"8Rkoyb": "Recipient",
|
||||
"8Y6bZQ": "Invalid zap split: {input}",
|
||||
"8g2vyB": "name too long",
|
||||
"8jmwT8": "bech32-encoded entities",
|
||||
"8v1NN+": "Pairing phrase",
|
||||
"9+Ddtu": "Next",
|
||||
"9HU8vw": "Reply",
|
||||
@ -125,9 +146,11 @@
|
||||
"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",
|
||||
"BQW4gi": "Relay-based Groups",
|
||||
"BWpuKl": "Update",
|
||||
"BjNwZW": "Nostr address (nip05)",
|
||||
"Blxcdx": "Relay",
|
||||
"Bo+O//": "HTTP Auth",
|
||||
"C1LjMx": "Lightning Donation",
|
||||
"C7642/": "Quote Repost",
|
||||
"C81/uG": "Logout",
|
||||
@ -142,6 +165,7 @@
|
||||
"CsCUYo": "{n} sats",
|
||||
"Cu/K85": "Translated from {lang}",
|
||||
"CzHZoc": "Social Graph",
|
||||
"D++Njw": "Text Note References",
|
||||
"D+KzKd": "Automatically zap every note when loaded",
|
||||
"D3idYv": "Settings",
|
||||
"DBiVK1": "Cache",
|
||||
@ -165,7 +189,9 @@
|
||||
"EjFyoR": "On-chain Donation Address",
|
||||
"EnCOBJ": "Buy",
|
||||
"F3l7xL": "Add Account",
|
||||
"F4eJ/3": "Classified Listings",
|
||||
"FDguSC": "{n} Zaps",
|
||||
"FHvSk3": "Authentication of clients to relays",
|
||||
"FMfjrl": "Show status messages on profile pages",
|
||||
"FSYL8G": "Trending Users",
|
||||
"FcNSft": "Redirect issues HTTP redirect to the supplied lightning address",
|
||||
@ -178,6 +204,7 @@
|
||||
"G1BGCg": "Select Wallet",
|
||||
"G3A56c": "Subscribed to Push",
|
||||
"GFOoEE": "Salt",
|
||||
"GIqktu": "Supported NIPs",
|
||||
"GL8aXW": "Bookmarks ({n})",
|
||||
"GSye7T": "Lightning Address",
|
||||
"GUlSVG": "Claim your included Snort nostr address",
|
||||
@ -186,6 +213,7 @@
|
||||
"GspYR7": "{n} Dislike",
|
||||
"Gxcr08": "Broadcast Event",
|
||||
"H+vHiz": "Hex Key..",
|
||||
"H/oroO": "Dealing with Unknown Events",
|
||||
"H0JBH6": "Log Out",
|
||||
"H0OG3T": "Leader Info",
|
||||
"H6/kLh": "Order Paid!",
|
||||
@ -196,6 +224,7 @@
|
||||
"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.",
|
||||
"HqRNN8": "Support",
|
||||
"HzSFeV": "Expiration Timestamp",
|
||||
"I1AoOu": "Last post {time}",
|
||||
"IEwZvs": "Are you sure you want to unpin this note?",
|
||||
"IIOul1": "Account Data",
|
||||
@ -203,6 +232,7 @@
|
||||
"IOu4Xh": "You must be a {tier} subscriber to access {app} deck",
|
||||
"IVbtTS": "Zap all {n} sats",
|
||||
"IWz1ta": "Auto Translate",
|
||||
"IcHcWj": "Last Seen:",
|
||||
"Ig9/a1": "Sent {n} sats to {name}",
|
||||
"IgsWFG": "Not followed by anyone you follow",
|
||||
"IoQq+a": "Click here to load anyway",
|
||||
@ -224,13 +254,19 @@
|
||||
"JkLHGw": "Website",
|
||||
"JmcxzF": "Relays are servers you connect to for sending and receiving events. Aim for 4-8 relays.",
|
||||
"JymXbw": "Private Key",
|
||||
"K1wl1/": "Average Latency:",
|
||||
"K3r6DQ": "Delete",
|
||||
"K7AkdL": "Show",
|
||||
"K9zklU": "External Content IDs",
|
||||
"KAhAcM": "Enter LNDHub config",
|
||||
"KGmQjH": "Highlights",
|
||||
"KQvWvD": "Deleted",
|
||||
"KT9nox": "Protected Events",
|
||||
"KahimY": "Unknown event kind: {kind}",
|
||||
"KipVeG": "Mapping Nostr keys to DNS-based internet identifiers",
|
||||
"KtsyO0": "Enter Pin",
|
||||
"LBAnc7": "View as user?",
|
||||
"LEmxc8": "Zap Goals",
|
||||
"LKw/ue": "Check out the code {link}",
|
||||
"LR1XjT": "Pin too short",
|
||||
"LXxsbk": "Anonymous",
|
||||
@ -238,6 +274,7 @@
|
||||
"LhLvRx": "Name must be between 8 and 15 characters",
|
||||
"LmdPXO": "Cannot verify Nostr Address",
|
||||
"Lu5/Bj": "Open on Zapstr",
|
||||
"LuDBLj": "Torrents",
|
||||
"Lw+I+J": "{n,plural,=0{{name} zapped} other{{name} & {n} others zapped}}",
|
||||
"LwYmVi": "Zaps on this note will be split to the following users.",
|
||||
"M3Oirc": "Debug Menus",
|
||||
@ -247,9 +284,11 @@
|
||||
"MP54GY": "Wallet password",
|
||||
"MWTx65": "Default Page",
|
||||
"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.",
|
||||
"Mrpkot": "Pay for subscription",
|
||||
"MuVeKe": "Buy nostr address",
|
||||
"Muhna4": "Counting results",
|
||||
"MzRYWH": "Buying {item}",
|
||||
"Mzizei": "Iris.to account",
|
||||
"N2IrpM": "Confirm",
|
||||
@ -258,15 +297,19 @@
|
||||
"NdOYJJ": "Hmm nothing here.. Checkout {newUsersPage} to follow some recommended nostrich's!",
|
||||
"NepkXH": "Can't vote with {amount} sats, please set a different default zap amount",
|
||||
"NndBJE": "New users page",
|
||||
"Nr9Yyx": "Reposts",
|
||||
"NxzeNU": "Dead",
|
||||
"O3Jz4E": "Use your invite code to earn sats!",
|
||||
"OEW7yJ": "Zaps",
|
||||
"OIqnZN": "OpenTimestamps Attestations for Events",
|
||||
"OJHKIL": "Gift Wrap",
|
||||
"OKhRC6": "Share",
|
||||
"OLEm6z": "Unknown login error",
|
||||
"OQSOJF": "Get a free nostr address",
|
||||
"OQXnew": "You subscription is still active, you can't renew yet",
|
||||
"ORGv1Q": "Created",
|
||||
"OoZgbB": "Failed to update, please try again",
|
||||
"OuProE": "Long-form Content",
|
||||
"OxPdQ0": "Scanning {date}",
|
||||
"P2o+ZZ": "Invalid Nostr Address",
|
||||
"P61BTu": "Copy Event JSON",
|
||||
@ -281,6 +324,7 @@
|
||||
"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)",
|
||||
"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",
|
||||
@ -288,6 +332,7 @@
|
||||
"RahCRH": "Expired",
|
||||
"RfhLwC": "By: {author}",
|
||||
"RhDAoS": "Are you sure you want to delete {id}",
|
||||
"RmxSZo": "Data Vending Machines",
|
||||
"RoOyAh": "Relays",
|
||||
"RrCui3": "Summary",
|
||||
"Rs4kCE": "Bookmark",
|
||||
@ -310,12 +355,12 @@
|
||||
"TaeBqw": "Sign in with Nostr Extension",
|
||||
"TdTXXf": "Learn more",
|
||||
"TdtZQ5": "Crypto",
|
||||
"TgDKhI": "Calendar Events",
|
||||
"TpgeGw": "Hex Salt..",
|
||||
"Tpy00S": "People",
|
||||
"TvKqBp": "liked",
|
||||
"TwyMau": "Account",
|
||||
"U1aPPi": "Stop listening",
|
||||
"UDYlxu": "Pending Subscriptions",
|
||||
"UJTWqI": "Remove from my relays",
|
||||
"ULXFfP": "Receive",
|
||||
"UNjfWJ": "Check all event signatures received from relays",
|
||||
@ -327,6 +372,7 @@
|
||||
"Ups2/p": "Your application is pending",
|
||||
"UrKTqQ": "You have an active iris.to account",
|
||||
"UxgyeY": "Your referral code is {code}",
|
||||
"V20Og0": "Labeling",
|
||||
"VOjC1i": "Pick which upload service you want to upload attachments to",
|
||||
"VR5eHw": "Public key (npub/nprofile)",
|
||||
"VcwrfF": "Yes please",
|
||||
@ -352,9 +398,11 @@
|
||||
"YDMrKK": "Users",
|
||||
"YDURw6": "Service URL",
|
||||
"YR2I9M": "No keys, no {app}, There is no way to reset it if you don't back up. It only takes a minute.",
|
||||
"YU7ZYp": "Public Chat",
|
||||
"YXA3AH": "Enable reactions",
|
||||
"Yf3DwC": "Connect a wallet to send instant payments",
|
||||
"Z4BMCZ": "Enter pairing phrase",
|
||||
"Z7kkeJ": "Delegated Event Signing",
|
||||
"ZKORll": "Activate Now",
|
||||
"ZLmyG9": "Contributors",
|
||||
"ZS+jRE": "Send zap splits to",
|
||||
@ -392,6 +440,7 @@
|
||||
"cg1VJ2": "Connect Wallet",
|
||||
"cuP16y": "Multi account support",
|
||||
"cuV2gK": "name is registered",
|
||||
"cw1Ftc": "Live Activities",
|
||||
"cyR7Kh": "Back",
|
||||
"d+6YsV": "Lists to mute:",
|
||||
"d2ebEu": "Not Subscribed to Push",
|
||||
@ -411,6 +460,7 @@
|
||||
"eJj8HD": "Get Verified",
|
||||
"eSzf2G": "A single zap of {nIn} sats will allocate {nOut} sats to the zap pool.",
|
||||
"eXT2QQ": "Group Chat",
|
||||
"eZtOxB": "window.nostr capability for web browsers",
|
||||
"egib+2": "{n,plural,=1{& {n} other} other{& {n} others}}",
|
||||
"ejEGdx": "Home",
|
||||
"eoV49s": "Poor",
|
||||
@ -436,7 +486,10 @@
|
||||
"gczcC5": "Subscribe",
|
||||
"geppt8": "{count} ({count2} in memory)",
|
||||
"gjBiyj": "Loading...",
|
||||
"gkMmvC": "Android Signer Application",
|
||||
"gl1NeW": "Lists",
|
||||
"grQ+mI": "Proof of Work",
|
||||
"gtNjNP": "Basic protocol flow description",
|
||||
"h7jvCs": "{site} is more fun together!",
|
||||
"h8XMJL": "Badges",
|
||||
"hF6IN2": "Prune Follow List",
|
||||
@ -455,6 +508,7 @@
|
||||
"iCqGww": "Reactions ({n})",
|
||||
"iEoXYx": "DeepL translations",
|
||||
"iGT1eE": "Prevent fake accounts from imitating you",
|
||||
"iHN12u": "Admin",
|
||||
"iICVoL": "{x} follows ({y} duplicates)",
|
||||
"iNWbVV": "Handle",
|
||||
"iXPL0Z": "Can't login with private key on an insecure connection, please use a Nostr key manager extension instead",
|
||||
@ -482,6 +536,7 @@
|
||||
"kuPHYE": "{n,plural,=0{{name} liked} other{{name} & {n} others liked}}",
|
||||
"l+ikU1": "Everything in {plan}",
|
||||
"l3H1EK": "Invite your friends",
|
||||
"l3nTjd": "Basic key derivation from mnemonic seed phrase",
|
||||
"lCILNz": "Buy Now",
|
||||
"lD3+8a": "Pay",
|
||||
"lEnclp": "My events: {n}",
|
||||
@ -514,12 +569,13 @@
|
||||
"odFwjL": "Follows only",
|
||||
"ojzbwv": "Hey, it looks like you dont have a Nostr Address yet, you should get one! Check out {link}",
|
||||
"p4N05H": "Upload",
|
||||
"p85Uwy": "Active Subscriptions",
|
||||
"p9Ps2l": "{x}/{y} have relays ({percent})",
|
||||
"pEEBFk": "Reliable Relays",
|
||||
"pI+77w": "Downloadable backups from Snort relay",
|
||||
"pRess9": "ZapPool",
|
||||
"plOM0t": "Custom Emoji",
|
||||
"puLNUJ": "Pin",
|
||||
"pyjJ5f": "Nostr Marketplace (for resilient marketplaces)",
|
||||
"pzTOmv": "Followers",
|
||||
"qD9EUF": "Email <> DM bridge for your Snort nostr address",
|
||||
"qDwvZ4": "Unknown error",
|
||||
@ -539,9 +595,13 @@
|
||||
"qz9fty": "Incorrect pin",
|
||||
"r3C4x/": "Software",
|
||||
"r5srDR": "Enter wallet password",
|
||||
"rAQG0X": "Relay List Metadata",
|
||||
"rMgF34": "Back up now",
|
||||
"rRRXtB": "Lightning Zaps",
|
||||
"rT14Ow": "Add Relays",
|
||||
"reFEEC": "Reporting",
|
||||
"rfuMjE": "(Default)",
|
||||
"rkM7l8": "Encrypted Direct Message",
|
||||
"rmdsT4": "{n} days",
|
||||
"rn52n9": "Public Chat Channels",
|
||||
"rx1i0i": "Short link",
|
||||
@ -549,8 +609,14 @@
|
||||
"sUNhQE": "user",
|
||||
"sZQzjQ": "Failed to parse zap split: {input}",
|
||||
"saInmO": "The relay name shown is not the same as the full URL entered.",
|
||||
"saorw+": "Event Deletion Request",
|
||||
"sfL/O+": "Muted notes will not be shown",
|
||||
"t79a6U": "Connection Success:",
|
||||
"tO1oq9": "Video Events",
|
||||
"tOdNiY": "Dark",
|
||||
"tRGdV1": "Versioned Encryption",
|
||||
"tU0ADf": "Unknown NIP-{x}",
|
||||
"tf1lIh": "Free",
|
||||
"th5lxp": "Send note to a subset of your write relays",
|
||||
"thnRpU": "Getting NIP-05 verified can help:",
|
||||
"tj6kdX": "{sign} {amount} sats",
|
||||
@ -561,6 +627,7 @@
|
||||
"u81G9+": "Uptime",
|
||||
"u9NoC1": "Name must be less than {limit} characters",
|
||||
"uCk8r+": "Already have an account?",
|
||||
"uD7Els": "External Identities in Profiles",
|
||||
"uSV4Ti": "Reposts need to be manually confirmed",
|
||||
"uc0din": "Send sats splits to",
|
||||
"ufvXH1": "Found {n} events",
|
||||
@ -580,6 +647,7 @@
|
||||
"w6qrwX": "NSFW",
|
||||
"wEQDC6": "Edit",
|
||||
"wSZR47": "Submit",
|
||||
"wc9st7": "Media Attachments",
|
||||
"whSrs+": "Nostr Public Chat",
|
||||
"wih7iJ": "name is blocked",
|
||||
"wofVHy": "Moderation",
|
||||
@ -591,6 +659,7 @@
|
||||
"xEjBS7": "For you",
|
||||
"xIcAOU": "Votes by {type}",
|
||||
"xIoGG9": "Go to",
|
||||
"xPCyu+": "nostr: URI scheme",
|
||||
"xSoIUU": "Worker Relay",
|
||||
"xaj9Ba": "Provider",
|
||||
"xbVgIm": "Automatically load media",
|
||||
@ -609,6 +678,7 @@
|
||||
"zINlao": "Owner",
|
||||
"zQvVDJ": "All",
|
||||
"zcaOTs": "Zap amount in sats",
|
||||
"zi9MdS": "Chess (PGN)",
|
||||
"zm6qS1": "{n} mins to read",
|
||||
"zonsdq": "Failed to load LNURL service",
|
||||
"zvCDao": "Automatically show latest notes",
|
||||
|
Loading…
x
Reference in New Issue
Block a user