forked from Kieran/snort
parent
8dc12b31df
commit
817b791e13
@ -157,11 +157,11 @@ export const WavlakeRegex =
|
|||||||
export const CashuRegex = /(cashuA[A-Za-z0-9_-]{0,10000}={0,3})/i;
|
export const CashuRegex = /(cashuA[A-Za-z0-9_-]{0,10000}={0,3})/i;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Max username length - profile/settings
|
* Max username length - profile/settings
|
||||||
*/
|
*/
|
||||||
export const MaxUsernameLength = 100;
|
export const MaxUsernameLength = 100;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Max about length - profile/settings
|
* Max about length - profile/settings
|
||||||
*/
|
*/
|
||||||
export const MaxAboutLength = 1000;
|
export const MaxAboutLength = 1000;
|
||||||
|
@ -101,9 +101,9 @@ export default defineMessages({
|
|||||||
ReBroadcast: { defaultMessage: "Broadcast Again", id: "c3g2hL" },
|
ReBroadcast: { defaultMessage: "Broadcast Again", id: "c3g2hL" },
|
||||||
IrisUserNameLengthError: { defaultMessage: "Name must be between 1 and 32 characters", id: "4MBtMa" },
|
IrisUserNameLengthError: { defaultMessage: "Name must be between 1 and 32 characters", id: "4MBtMa" },
|
||||||
IrisUserNameFormatError: { defaultMessage: "Username must only contain lowercase letters and numbers", id: "RSr2uB" },
|
IrisUserNameFormatError: { defaultMessage: "Username must only contain lowercase letters and numbers", id: "RSr2uB" },
|
||||||
InvalidNip05Address: { defaultMessage: "Invalid Nostr Address(nip05)", id: 'X6TK3B' },
|
InvalidNip05Address: { defaultMessage: "Invalid Nostr Address", id: "P2o+ZZ" },
|
||||||
ErrorValidatingNip05Address: { defaultMessage: "Cannot verify Nostr Address(nip05)", id: 'I32UtP'},
|
ErrorValidatingNip05Address: { defaultMessage: "Cannot verify Nostr Address", id: "LmdPXO" },
|
||||||
UserNameLengthError: { defaultMessage: "Name must be less than 100 characters", id: 'X/GZY6' },
|
UserNameLengthError: { defaultMessage: "Name must be less than {limit} characters", id: "u9NoC1" },
|
||||||
AboutLengthError: { defaultMessage: "About must be less than 1000 characters", id: 'vCanok' },
|
AboutLengthError: { defaultMessage: "About must be less than {limit} characters", id: "DrZqav" },
|
||||||
InvalidLud16:{ defaultMessage: "Invalid Lightning Address", id: 'GqQeu/' }
|
InvalidLud16: { defaultMessage: "Invalid Lightning Address", id: "GqQeu/" },
|
||||||
});
|
});
|
||||||
|
@ -14,10 +14,9 @@ import Icon from "@/Icons/Icon";
|
|||||||
import Avatar from "@/Element/User/Avatar";
|
import Avatar from "@/Element/User/Avatar";
|
||||||
import { FormattedMessage, useIntl } from "react-intl";
|
import { FormattedMessage, useIntl } from "react-intl";
|
||||||
import { ErrorOrOffline } from "@/Element/ErrorOrOffline";
|
import { ErrorOrOffline } from "@/Element/ErrorOrOffline";
|
||||||
import { LNURL, LNURLError } from '@snort/shared';
|
import { LNURL, fetchNip05Pubkey } from "@snort/shared";
|
||||||
import messages from "@/Element/messages";
|
import messages from "@/Element/messages";
|
||||||
import { MaxAboutLength, MaxUsernameLength } from "@/Const";
|
import { MaxAboutLength, MaxUsernameLength } from "@/Const";
|
||||||
import { fetchNip05Pubkey } from "../../Nip05/Verifier";
|
|
||||||
|
|
||||||
export interface ProfileSettingsProps {
|
export interface ProfileSettingsProps {
|
||||||
avatar?: boolean;
|
avatar?: boolean;
|
||||||
@ -41,15 +40,14 @@ export default function ProfileSettings(props: ProfileSettingsProps) {
|
|||||||
const [nip05, setNip05] = useState<string>();
|
const [nip05, setNip05] = useState<string>();
|
||||||
const [lud16, setLud16] = useState<string>();
|
const [lud16, setLud16] = useState<string>();
|
||||||
const [nip05AddressValid, setNip05AddressValid] = useState<boolean>();
|
const [nip05AddressValid, setNip05AddressValid] = useState<boolean>();
|
||||||
const [invalidNip05AddressMessage, setInvalidNip05AddressMessage] = useState<null | string>();
|
const [invalidNip05AddressMessage, setInvalidNip05AddressMessage] = useState<string>();
|
||||||
const [usernameValid, setUsernameValid] = useState<boolean>();
|
const [usernameValid, setUsernameValid] = useState<boolean>();
|
||||||
const [invalidUsernameMessage, setInvalidUsernameMessage] = useState<null | string>();
|
const [invalidUsernameMessage, setInvalidUsernameMessage] = useState<string>();
|
||||||
const [aboutValid, setAboutValid] = useState<boolean>();
|
const [aboutValid, setAboutValid] = useState<boolean>();
|
||||||
const [invalidAboutMessage, setInvalidAboutMessage] = useState<null | string>();
|
const [invalidAboutMessage, setInvalidAboutMessage] = useState<string>();
|
||||||
const [lud16Valid, setLud16Valid] = useState<boolean>();
|
const [lud16Valid, setLud16Valid] = useState<boolean>();
|
||||||
const [invalidLud16Message, setInvalidLud16Message] = useState<null | string>();
|
const [invalidLud16Message, setInvalidLud16Message] = useState<string>();
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (user) {
|
if (user) {
|
||||||
setName(user.name);
|
setName(user.name);
|
||||||
@ -63,43 +61,38 @@ export default function ProfileSettings(props: ProfileSettingsProps) {
|
|||||||
}, [user]);
|
}, [user]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
return debounce(500,async () => {
|
return debounce(500, async () => {
|
||||||
if(lud16){
|
if (lud16) {
|
||||||
try {
|
try {
|
||||||
await new LNURL(lud16).load();
|
await new LNURL(lud16).load();
|
||||||
setLud16Valid(true);
|
setLud16Valid(true);
|
||||||
setInvalidLud16Message("")
|
setInvalidLud16Message("");
|
||||||
}catch(e){
|
} catch (e) {
|
||||||
setLud16Valid(false);
|
setLud16Valid(false);
|
||||||
if(e instanceof LNURLError)
|
setInvalidLud16Message(formatMessage(messages.InvalidLud16));
|
||||||
setInvalidLud16Message((e as LNURLError).message);
|
}
|
||||||
else
|
} else {
|
||||||
setInvalidLud16Message(formatMessage(messages.InvalidLud16));
|
setInvalidLud16Message("");
|
||||||
}
|
|
||||||
}else{
|
|
||||||
setInvalidLud16Message("")
|
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}, [lud16]);
|
}, [lud16]);
|
||||||
|
|
||||||
useEffect(()=>{
|
useEffect(() => {
|
||||||
return debounce(500,async () => {
|
return debounce(500, async () => {
|
||||||
const Nip05AddressElements = nip05?.split('@') ?? [];
|
const Nip05AddressElements = nip05?.split("@") ?? [];
|
||||||
if (nip05.length === 0) {
|
if ((nip05?.length ?? 0) === 0) {
|
||||||
setNip05AddressValid(false)
|
setNip05AddressValid(false);
|
||||||
setInvalidNip05AddressMessage("")
|
setInvalidNip05AddressMessage("");
|
||||||
}else if(Nip05AddressElements.length < 2){
|
} else if (Nip05AddressElements.length < 2) {
|
||||||
setNip05AddressValid(false)
|
setNip05AddressValid(false);
|
||||||
setInvalidNip05AddressMessage(formatMessage(messages.InvalidNip05Address))
|
setInvalidNip05AddressMessage(formatMessage(messages.InvalidNip05Address));
|
||||||
}
|
} else if (Nip05AddressElements.length === 2) {
|
||||||
else if(Nip05AddressElements.length === 2){
|
|
||||||
nip05NostrAddressVerification(Nip05AddressElements.pop(), Nip05AddressElements.pop());
|
nip05NostrAddressVerification(Nip05AddressElements.pop(), Nip05AddressElements.pop());
|
||||||
|
} else {
|
||||||
|
setNip05AddressValid(false);
|
||||||
}
|
}
|
||||||
else{
|
});
|
||||||
setNip05AddressValid(false)
|
}, [nip05]);
|
||||||
}
|
|
||||||
})
|
|
||||||
},[nip05])
|
|
||||||
|
|
||||||
async function saveProfile() {
|
async function saveProfile() {
|
||||||
// copy user object and delete internal fields
|
// copy user object and delete internal fields
|
||||||
@ -165,51 +158,64 @@ export default function ProfileSettings(props: ProfileSettingsProps) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function onNip05Change(e: React.ChangeEvent<HTMLInputElement>){
|
async function onNip05Change(e: React.ChangeEvent<HTMLInputElement>) {
|
||||||
const Nip05Address = e.target.value.toLowerCase();
|
const Nip05Address = e.target.value.toLowerCase();
|
||||||
setNip05(Nip05Address)
|
setNip05(Nip05Address);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function onLimitCheck(val:string, field:string){
|
async function onLimitCheck(val: string, field: string) {
|
||||||
if(field === "username"){
|
if (field === "username") {
|
||||||
setName(val);
|
setName(val);
|
||||||
if(val?.length >= MaxUsernameLength){
|
if (val?.length >= MaxUsernameLength) {
|
||||||
setUsernameValid(false)
|
setUsernameValid(false);
|
||||||
setInvalidUsernameMessage(formatMessage(messages.UserNameLengthError))
|
setInvalidUsernameMessage(
|
||||||
}else{
|
formatMessage(messages.UserNameLengthError, {
|
||||||
setUsernameValid(true)
|
limit: MaxUsernameLength,
|
||||||
setInvalidUsernameMessage("")
|
}),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
setUsernameValid(true);
|
||||||
|
setInvalidUsernameMessage("");
|
||||||
}
|
}
|
||||||
}
|
} else if (field === "about") {
|
||||||
else if(field === "about"){
|
|
||||||
setAbout(val);
|
setAbout(val);
|
||||||
if(val?.length >= MaxAboutLength){
|
if (val?.length >= MaxAboutLength) {
|
||||||
setAboutValid(false)
|
setAboutValid(false);
|
||||||
setInvalidAboutMessage(formatMessage(messages.AboutLengthError))
|
setInvalidAboutMessage(
|
||||||
}else{
|
formatMessage(messages.AboutLengthError, {
|
||||||
setAboutValid(true)
|
limit: MaxAboutLength,
|
||||||
setInvalidAboutMessage("")
|
}),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
setAboutValid(true);
|
||||||
|
setInvalidAboutMessage("");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function nip05NostrAddressVerification(nip05Domain: string | undefined, nip05Name: string| undefined) {
|
async function nip05NostrAddressVerification(nip05Domain: string | undefined, nip05Name: string | undefined) {
|
||||||
try{
|
try {
|
||||||
const result = await fetchNip05Pubkey(nip05Name!,nip05Domain!);
|
const result = await fetchNip05Pubkey(nip05Name!, nip05Domain!);
|
||||||
if(result){
|
if (result) {
|
||||||
setNip05AddressValid(true);
|
if (result === id) {
|
||||||
}else{
|
setNip05AddressValid(true);
|
||||||
|
} else {
|
||||||
|
setInvalidNip05AddressMessage(
|
||||||
|
formatMessage({ defaultMessage: "Nostr address does not belong to you", id: "01iNut" }),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
setNip05AddressValid(false);
|
setNip05AddressValid(false);
|
||||||
setInvalidNip05AddressMessage(formatMessage(messages.InvalidNip05Address))
|
setInvalidNip05AddressMessage(formatMessage(messages.InvalidNip05Address));
|
||||||
}
|
}
|
||||||
}catch(e){
|
} catch (e) {
|
||||||
setNip05AddressValid(false)
|
setNip05AddressValid(false);
|
||||||
setInvalidNip05AddressMessage(formatMessage(messages.InvalidNip05Address))
|
setInvalidNip05AddressMessage(formatMessage(messages.InvalidNip05Address));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function onLud16Change(address:string){
|
async function onLud16Change(address: string) {
|
||||||
setLud16(address)
|
setLud16(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
function editor() {
|
function editor() {
|
||||||
@ -223,17 +229,11 @@ export default function ProfileSettings(props: ProfileSettingsProps) {
|
|||||||
className="w-max"
|
className="w-max"
|
||||||
type="text"
|
type="text"
|
||||||
value={name}
|
value={name}
|
||||||
onChange={e => onLimitCheck(e.target.value,"username")}
|
onChange={e => onLimitCheck(e.target.value, "username")}
|
||||||
disabled={readonly}
|
disabled={readonly}
|
||||||
maxLength={MaxUsernameLength}
|
maxLength={MaxUsernameLength}
|
||||||
/>
|
/>
|
||||||
<div>
|
<div>{usernameValid === false ? <span className="warning">{invalidUsernameMessage}</span> : <></>}</div>
|
||||||
{usernameValid === false ? (
|
|
||||||
<span className="error">{invalidUsernameMessage}</span>
|
|
||||||
)
|
|
||||||
: (<></>)
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col w-max g8">
|
<div className="flex flex-col w-max g8">
|
||||||
<h4>
|
<h4>
|
||||||
@ -241,16 +241,11 @@ export default function ProfileSettings(props: ProfileSettingsProps) {
|
|||||||
</h4>
|
</h4>
|
||||||
<textarea
|
<textarea
|
||||||
className="w-max"
|
className="w-max"
|
||||||
onChange={e => onLimitCheck(e.target.value,"about")}
|
onChange={e => onLimitCheck(e.target.value, "about")}
|
||||||
value={about}
|
value={about}
|
||||||
disabled={readonly} maxLength={MaxAboutLength}></textarea>
|
disabled={readonly}
|
||||||
<div>
|
maxLength={MaxAboutLength}></textarea>
|
||||||
{aboutValid === false ? (
|
<div>{aboutValid === false ? <span className="warning">{invalidAboutMessage}</span> : <></>}</div>
|
||||||
<span className="error">{invalidAboutMessage}</span>
|
|
||||||
)
|
|
||||||
: (<></>)
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col w-max g8">
|
<div className="flex flex-col w-max g8">
|
||||||
<h4>
|
<h4>
|
||||||
@ -269,24 +264,8 @@ export default function ProfileSettings(props: ProfileSettingsProps) {
|
|||||||
<FormattedMessage defaultMessage="Nostr Address" id="9pMqYs" />
|
<FormattedMessage defaultMessage="Nostr Address" id="9pMqYs" />
|
||||||
</h4>
|
</h4>
|
||||||
<div className="flex flex-col g8 w-max">
|
<div className="flex flex-col g8 w-max">
|
||||||
<input
|
<input type="text" className="w-max" value={nip05} onChange={e => onNip05Change(e)} disabled={readonly} />
|
||||||
type="text"
|
<div>{!nip05AddressValid && <span className="warning">{invalidNip05AddressMessage}</span>}</div>
|
||||||
className="w-max"
|
|
||||||
value={nip05}
|
|
||||||
onChange={e => onNip05Change(e)}
|
|
||||||
disabled={readonly}
|
|
||||||
/>
|
|
||||||
<div>
|
|
||||||
{nip05AddressValid ? (
|
|
||||||
<>
|
|
||||||
<span className="success">
|
|
||||||
<FormattedMessage defaultMessage="NIP05 Verified" id="vw95kf" />
|
|
||||||
</span>
|
|
||||||
</>
|
|
||||||
) : (
|
|
||||||
<span className="error">{invalidNip05AddressMessage}</span>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
<small>
|
<small>
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
defaultMessage="Usernames are not unique on Nostr. The nostr address is your unique human-readable address that is unique to you upon registration."
|
defaultMessage="Usernames are not unique on Nostr. The nostr address is your unique human-readable address that is unique to you upon registration."
|
||||||
@ -317,13 +296,7 @@ export default function ProfileSettings(props: ProfileSettingsProps) {
|
|||||||
onChange={e => onLud16Change(e.target.value.toLowerCase())}
|
onChange={e => onLud16Change(e.target.value.toLowerCase())}
|
||||||
disabled={readonly}
|
disabled={readonly}
|
||||||
/>
|
/>
|
||||||
<div>
|
<div>{lud16Valid === false ? <span className="warning">{invalidLud16Message}</span> : <></>}</div>
|
||||||
{lud16Valid === false ? (
|
|
||||||
<span className="error">{invalidLud16Message}</span>
|
|
||||||
)
|
|
||||||
: (<></>)
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<AsyncButton className="primary" onClick={() => saveProfile()} disabled={readonly}>
|
<AsyncButton className="primary" onClick={() => saveProfile()} disabled={readonly}>
|
||||||
<FormattedMessage defaultMessage="Save" id="jvo0vs" />
|
<FormattedMessage defaultMessage="Save" id="jvo0vs" />
|
||||||
|
@ -57,6 +57,9 @@
|
|||||||
"00LcfG": {
|
"00LcfG": {
|
||||||
"defaultMessage": "Load more"
|
"defaultMessage": "Load more"
|
||||||
},
|
},
|
||||||
|
"01iNut": {
|
||||||
|
"defaultMessage": "Nostr address does not belong to you"
|
||||||
|
},
|
||||||
"08zn6O": {
|
"08zn6O": {
|
||||||
"defaultMessage": "Export Keys"
|
"defaultMessage": "Export Keys"
|
||||||
},
|
},
|
||||||
@ -419,6 +422,9 @@
|
|||||||
"Dn82AL": {
|
"Dn82AL": {
|
||||||
"defaultMessage": "Live"
|
"defaultMessage": "Live"
|
||||||
},
|
},
|
||||||
|
"DrZqav": {
|
||||||
|
"defaultMessage": "About must be less than {limit} characters"
|
||||||
|
},
|
||||||
"DtYelJ": {
|
"DtYelJ": {
|
||||||
"defaultMessage": "Transfer"
|
"defaultMessage": "Transfer"
|
||||||
},
|
},
|
||||||
@ -506,6 +512,9 @@
|
|||||||
"Gcn9NQ": {
|
"Gcn9NQ": {
|
||||||
"defaultMessage": "Magnet Link"
|
"defaultMessage": "Magnet Link"
|
||||||
},
|
},
|
||||||
|
"GqQeu/": {
|
||||||
|
"defaultMessage": "Invalid Lightning Address"
|
||||||
|
},
|
||||||
"GspYR7": {
|
"GspYR7": {
|
||||||
"defaultMessage": "{n} Dislike"
|
"defaultMessage": "{n} Dislike"
|
||||||
},
|
},
|
||||||
@ -640,6 +649,9 @@
|
|||||||
"LgbKvU": {
|
"LgbKvU": {
|
||||||
"defaultMessage": "Comment"
|
"defaultMessage": "Comment"
|
||||||
},
|
},
|
||||||
|
"LmdPXO": {
|
||||||
|
"defaultMessage": "Cannot verify Nostr Address"
|
||||||
|
},
|
||||||
"Lu5/Bj": {
|
"Lu5/Bj": {
|
||||||
"defaultMessage": "Open on Zapstr"
|
"defaultMessage": "Open on Zapstr"
|
||||||
},
|
},
|
||||||
@ -722,6 +734,9 @@
|
|||||||
"ORGv1Q": {
|
"ORGv1Q": {
|
||||||
"defaultMessage": "Created"
|
"defaultMessage": "Created"
|
||||||
},
|
},
|
||||||
|
"P2o+ZZ": {
|
||||||
|
"defaultMessage": "Invalid Nostr Address"
|
||||||
|
},
|
||||||
"P61BTu": {
|
"P61BTu": {
|
||||||
"defaultMessage": "Copy Event JSON"
|
"defaultMessage": "Copy Event JSON"
|
||||||
},
|
},
|
||||||
@ -1453,6 +1468,9 @@
|
|||||||
"u4bHcR": {
|
"u4bHcR": {
|
||||||
"defaultMessage": "Check out the code here: {link}"
|
"defaultMessage": "Check out the code here: {link}"
|
||||||
},
|
},
|
||||||
|
"u9NoC1": {
|
||||||
|
"defaultMessage": "Name must be less than {limit} characters"
|
||||||
|
},
|
||||||
"uCk8r+": {
|
"uCk8r+": {
|
||||||
"defaultMessage": "Already have an account?"
|
"defaultMessage": "Already have an account?"
|
||||||
},
|
},
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
"/d6vEc": "Make your profile easier to find and share",
|
"/d6vEc": "Make your profile easier to find and share",
|
||||||
"/n5KSF": "{n} ms",
|
"/n5KSF": "{n} ms",
|
||||||
"00LcfG": "Load more",
|
"00LcfG": "Load more",
|
||||||
|
"01iNut": "Nostr address does not belong to you",
|
||||||
"08zn6O": "Export Keys",
|
"08zn6O": "Export Keys",
|
||||||
"0Azlrb": "Manage",
|
"0Azlrb": "Manage",
|
||||||
"0BUTMv": "Search...",
|
"0BUTMv": "Search...",
|
||||||
@ -138,6 +139,7 @@
|
|||||||
"DZzCem": "Show latest {n} notes",
|
"DZzCem": "Show latest {n} notes",
|
||||||
"Dh3hbq": "Auto Zap",
|
"Dh3hbq": "Auto Zap",
|
||||||
"Dn82AL": "Live",
|
"Dn82AL": "Live",
|
||||||
|
"DrZqav": "About must be less than {limit} characters",
|
||||||
"DtYelJ": "Transfer",
|
"DtYelJ": "Transfer",
|
||||||
"Dx4ey3": "Toggle all",
|
"Dx4ey3": "Toggle all",
|
||||||
"EJbFi7": "Search notes",
|
"EJbFi7": "Search notes",
|
||||||
@ -167,6 +169,7 @@
|
|||||||
"GSye7T": "Lightning Address",
|
"GSye7T": "Lightning Address",
|
||||||
"GUlSVG": "Claim your included Snort nostr address",
|
"GUlSVG": "Claim your included Snort nostr address",
|
||||||
"Gcn9NQ": "Magnet Link",
|
"Gcn9NQ": "Magnet Link",
|
||||||
|
"GqQeu/": "Invalid Lightning Address",
|
||||||
"GspYR7": "{n} Dislike",
|
"GspYR7": "{n} Dislike",
|
||||||
"Gxcr08": "Broadcast Event",
|
"Gxcr08": "Broadcast Event",
|
||||||
"H+vHiz": "Hex Key..",
|
"H+vHiz": "Hex Key..",
|
||||||
@ -211,6 +214,7 @@
|
|||||||
"LR1XjT": "Pin too short",
|
"LR1XjT": "Pin too short",
|
||||||
"LXxsbk": "Anonymous",
|
"LXxsbk": "Anonymous",
|
||||||
"LgbKvU": "Comment",
|
"LgbKvU": "Comment",
|
||||||
|
"LmdPXO": "Cannot verify Nostr Address",
|
||||||
"Lu5/Bj": "Open on Zapstr",
|
"Lu5/Bj": "Open on Zapstr",
|
||||||
"Lw+I+J": "{n,plural,=0{{name} zapped} other{{name} & {n} others zapped}}",
|
"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.",
|
"LwYmVi": "Zaps on this note will be split to the following users.",
|
||||||
@ -238,6 +242,7 @@
|
|||||||
"OQSOJF": "Get a free nostr address",
|
"OQSOJF": "Get a free nostr address",
|
||||||
"OQXnew": "You subscription is still active, you can't renew yet",
|
"OQXnew": "You subscription is still active, you can't renew yet",
|
||||||
"ORGv1Q": "Created",
|
"ORGv1Q": "Created",
|
||||||
|
"P2o+ZZ": "Invalid Nostr Address",
|
||||||
"P61BTu": "Copy Event JSON",
|
"P61BTu": "Copy Event JSON",
|
||||||
"P7FD0F": "System (Default)",
|
"P7FD0F": "System (Default)",
|
||||||
"P7nJT9": "Total today (UTC): {amount} sats",
|
"P7nJT9": "Total today (UTC): {amount} sats",
|
||||||
@ -479,6 +484,7 @@
|
|||||||
"u+LyXc": "Interactions",
|
"u+LyXc": "Interactions",
|
||||||
"u/vOPu": "Paid",
|
"u/vOPu": "Paid",
|
||||||
"u4bHcR": "Check out the code here: {link}",
|
"u4bHcR": "Check out the code here: {link}",
|
||||||
|
"u9NoC1": "Name must be less than {limit} characters",
|
||||||
"uCk8r+": "Already have an account?",
|
"uCk8r+": "Already have an account?",
|
||||||
"uKqSN+": "Follows Feed",
|
"uKqSN+": "Follows Feed",
|
||||||
"uSV4Ti": "Reposts need to be manually confirmed",
|
"uSV4Ti": "Reposts need to be manually confirmed",
|
||||||
|
Loading…
Reference in New Issue
Block a user