This commit is contained in:
parent
a937c75c64
commit
7040253f32
@ -28,11 +28,6 @@ export const KieranPubKey = "npub1v0lxxxxutpvrelsksy8cdhgfux9l6a42hsj2qzquu2zk7v
|
|||||||
*/
|
*/
|
||||||
export const SnortPubKey = "npub1sn0rtcjcf543gj4wsg7fa59s700d5ztys5ctj0g69g2x6802npjqhjjtws";
|
export const SnortPubKey = "npub1sn0rtcjcf543gj4wsg7fa59s700d5ztys5ctj0g69g2x6802npjqhjjtws";
|
||||||
|
|
||||||
/**
|
|
||||||
* Default bootstrap relays
|
|
||||||
*/
|
|
||||||
export const DefaultRelays = new Map(Object.entries(CONFIG.defaultRelays));
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default search relays
|
* Default search relays
|
||||||
*/
|
*/
|
||||||
|
6
packages/app/src/External/SnortApi.ts
vendored
6
packages/app/src/External/SnortApi.ts
vendored
@ -81,6 +81,8 @@ export interface RelayDistance {
|
|||||||
export interface RefCodeResponse {
|
export interface RefCodeResponse {
|
||||||
code: string;
|
code: string;
|
||||||
pubkey: string;
|
pubkey: string;
|
||||||
|
revShare?: number;
|
||||||
|
leaderState?: "pending" | "approved";
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class SnortApi {
|
export default class SnortApi {
|
||||||
@ -148,6 +150,10 @@ export default class SnortApi {
|
|||||||
return this.#getJson<RefCodeResponse>(`api/v1/referral/${code}`, "GET");
|
return this.#getJson<RefCodeResponse>(`api/v1/referral/${code}`, "GET");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
applyForLeader() {
|
||||||
|
return this.#getJsonAuthd<RefCodeResponse>("api/v1/referral/leader-apply", "POST");
|
||||||
|
}
|
||||||
|
|
||||||
async #getJsonAuthd<T>(
|
async #getJsonAuthd<T>(
|
||||||
path: string,
|
path: string,
|
||||||
method?: "GET" | string,
|
method?: "GET" | string,
|
||||||
|
@ -3,9 +3,8 @@ import * as utils from "@noble/curves/abstract/utils";
|
|||||||
import { v4 as uuid } from "uuid";
|
import { v4 as uuid } from "uuid";
|
||||||
|
|
||||||
import { HexKey, RelaySettings, EventPublisher, KeyStorage, NotEncrypted, socialGraphInstance } from "@snort/system";
|
import { HexKey, RelaySettings, EventPublisher, KeyStorage, NotEncrypted, socialGraphInstance } from "@snort/system";
|
||||||
import { deepClone, sanitizeRelayUrl, unwrap, ExternalStore } from "@snort/shared";
|
import { deepClone, unwrap, ExternalStore } from "@snort/shared";
|
||||||
|
|
||||||
import { DefaultRelays } from "@/Const";
|
|
||||||
import { LoginSession, LoginSessionType, createPublisher } from "@/Login";
|
import { LoginSession, LoginSessionType, createPublisher } from "@/Login";
|
||||||
import { DefaultPreferences, UserPreferences } from "./Preferences";
|
import { DefaultPreferences, UserPreferences } from "./Preferences";
|
||||||
|
|
||||||
@ -39,7 +38,7 @@ const LoggedOut = {
|
|||||||
timestamp: 0,
|
timestamp: 0,
|
||||||
},
|
},
|
||||||
relays: {
|
relays: {
|
||||||
item: Object.fromEntries([...DefaultRelays.entries()].map(a => [unwrap(sanitizeRelayUrl(a[0])), a[1]])),
|
item: CONFIG.defaultRelays,
|
||||||
timestamp: 0,
|
timestamp: 0,
|
||||||
},
|
},
|
||||||
latestNotification: 0,
|
latestNotification: 0,
|
||||||
@ -49,6 +48,7 @@ const LoggedOut = {
|
|||||||
item: {
|
item: {
|
||||||
mutedWords: [],
|
mutedWords: [],
|
||||||
preferences: DefaultPreferences,
|
preferences: DefaultPreferences,
|
||||||
|
showContentWarningPosts: false,
|
||||||
},
|
},
|
||||||
timestamp: 0,
|
timestamp: 0,
|
||||||
},
|
},
|
||||||
@ -179,7 +179,7 @@ export class MultiAccountStore extends ExternalStore<LoginSession> {
|
|||||||
if (relays && Object.keys(relays).length > 0) {
|
if (relays && Object.keys(relays).length > 0) {
|
||||||
return relays;
|
return relays;
|
||||||
}
|
}
|
||||||
return Object.fromEntries(DefaultRelays.entries());
|
return CONFIG.defaultRelays;
|
||||||
}
|
}
|
||||||
|
|
||||||
loginWithPrivateKey(key: KeyStorage, entropy?: string, relays?: Record<string, RelaySettings>) {
|
loginWithPrivateKey(key: KeyStorage, entropy?: string, relays?: Record<string, RelaySettings>) {
|
||||||
|
@ -1,20 +1,100 @@
|
|||||||
|
import AsyncButton from "@/Element/Button/AsyncButton";
|
||||||
import { LeaderBadge } from "@/Element/CommunityLeaders/LeaderBadge";
|
import { LeaderBadge } from "@/Element/CommunityLeaders/LeaderBadge";
|
||||||
import Copy from "@/Element/Copy";
|
import Copy from "@/Element/Copy";
|
||||||
import SnortApi from "@/External/SnortApi";
|
import SnortApi, { RefCodeResponse } from "@/External/SnortApi";
|
||||||
import useEventPublisher from "@/Hooks/useEventPublisher";
|
import useEventPublisher from "@/Hooks/useEventPublisher";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { FormattedMessage } from "react-intl";
|
import { FormattedMessage, FormattedNumber } from "react-intl";
|
||||||
|
import { Link } from "react-router-dom";
|
||||||
|
|
||||||
export function ReferralsPage() {
|
export function ReferralsPage() {
|
||||||
const [refCode, setRefCode] = useState("");
|
const [refCode, setRefCode] = useState<RefCodeResponse>();
|
||||||
const { publisher } = useEventPublisher();
|
const { publisher } = useEventPublisher();
|
||||||
|
const api = new SnortApi(undefined, publisher);
|
||||||
|
|
||||||
|
async function loadRefCode() {
|
||||||
|
const c = await api.getRefCode();
|
||||||
|
setRefCode(c);
|
||||||
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const api = new SnortApi(undefined, publisher);
|
loadRefCode();
|
||||||
|
|
||||||
api.getRefCode().then(v => setRefCode(v.code));
|
|
||||||
}, [publisher]);
|
}, [publisher]);
|
||||||
|
|
||||||
|
async function applyNow() {
|
||||||
|
await api.applyForLeader();
|
||||||
|
await loadRefCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
function becomeLeader() {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<h2>
|
||||||
|
<FormattedMessage defaultMessage="Become a leader" id="M6C/px" />
|
||||||
|
</h2>
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<Link to="https://community.snort.social/" target="_blank">
|
||||||
|
<button>
|
||||||
|
<FormattedMessage defaultMessage="Learn more" id="TdTXXf" />
|
||||||
|
</button>
|
||||||
|
</Link>
|
||||||
|
|
||||||
|
<LeaderBadge />
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
<AsyncButton className="primary" onClick={applyNow}>
|
||||||
|
<FormattedMessage defaultMessage="Apply Now" id="k0kCJp" />
|
||||||
|
</AsyncButton>
|
||||||
|
</p>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function leaderPending() {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<h2>
|
||||||
|
<FormattedMessage defaultMessage="Become a leader" id="M6C/px" />
|
||||||
|
</h2>
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<Link to="https://community.snort.social/" target="_blank">
|
||||||
|
<button>
|
||||||
|
<FormattedMessage defaultMessage="Learn more" id="TdTXXf" />
|
||||||
|
</button>
|
||||||
|
</Link>
|
||||||
|
|
||||||
|
<LeaderBadge />
|
||||||
|
</div>
|
||||||
|
<h3>
|
||||||
|
<FormattedMessage defaultMessage="Your application is pending" id="Ups2/p" />
|
||||||
|
</h3>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function leaderInfo() {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<h2>
|
||||||
|
<FormattedMessage defaultMessage="Leader Info" id="H0OG3T" />
|
||||||
|
</h2>
|
||||||
|
<p>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="You are a community leader and are earning <b>{percent}</b> of referred users subscriptions!"
|
||||||
|
id="bF1MYT"
|
||||||
|
values={{
|
||||||
|
b: c => <b>{c}</b>,
|
||||||
|
percent: <FormattedNumber style="percent" value={refCode?.revShare ?? 0} />,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<FormattedMessage defaultMessage="Use your invite code to earn sats!" id="O3Jz4E" />
|
||||||
|
</p>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<h1>
|
<h1>
|
||||||
@ -25,7 +105,7 @@ export function ReferralsPage() {
|
|||||||
defaultMessage="Your referral code is {code}"
|
defaultMessage="Your referral code is {code}"
|
||||||
id="UxgyeY"
|
id="UxgyeY"
|
||||||
values={{
|
values={{
|
||||||
code: <span className="font-mono text-highlight select-all">{refCode}</span>,
|
code: <span className="font-mono text-highlight select-all">{refCode?.code}</span>,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</p>
|
</p>
|
||||||
@ -36,18 +116,11 @@ export function ReferralsPage() {
|
|||||||
/>
|
/>
|
||||||
</p>
|
</p>
|
||||||
<div className="border border-zinc-900 rounded-2xl px-3 py-2">
|
<div className="border border-zinc-900 rounded-2xl px-3 py-2">
|
||||||
<Copy text={`https://${window.location.host}?ref=${refCode}`} maxSize={Number.MAX_VALUE} />
|
<Copy text={`https://${window.location.host}?ref=${refCode?.code}`} maxSize={Number.MAX_VALUE} />
|
||||||
</div>
|
</div>
|
||||||
|
{refCode?.leaderState === undefined && becomeLeader()}
|
||||||
<h2>
|
{refCode?.leaderState === "pending" && leaderPending()}
|
||||||
<FormattedMessage defaultMessage="Become a leader" id="M6C/px" />
|
{refCode?.leaderState === "approved" && leaderInfo()}
|
||||||
</h2>
|
|
||||||
<div className="flex">
|
|
||||||
<LeaderBadge />
|
|
||||||
</div>
|
|
||||||
<p>
|
|
||||||
<FormattedMessage defaultMessage="Coming soon" id="e61Jf3" />
|
|
||||||
</p>
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -543,6 +543,9 @@
|
|||||||
"H0JBH6": {
|
"H0JBH6": {
|
||||||
"defaultMessage": "Log Out"
|
"defaultMessage": "Log Out"
|
||||||
},
|
},
|
||||||
|
"H0OG3T": {
|
||||||
|
"defaultMessage": "Leader Info"
|
||||||
|
},
|
||||||
"H6/kLh": {
|
"H6/kLh": {
|
||||||
"defaultMessage": "Order Paid!"
|
"defaultMessage": "Order Paid!"
|
||||||
},
|
},
|
||||||
@ -737,6 +740,9 @@
|
|||||||
"NndBJE": {
|
"NndBJE": {
|
||||||
"defaultMessage": "New users page"
|
"defaultMessage": "New users page"
|
||||||
},
|
},
|
||||||
|
"O3Jz4E": {
|
||||||
|
"defaultMessage": "Use your invite code to earn sats!"
|
||||||
|
},
|
||||||
"O8Z8t9": {
|
"O8Z8t9": {
|
||||||
"defaultMessage": "Show More"
|
"defaultMessage": "Show More"
|
||||||
},
|
},
|
||||||
@ -872,6 +878,9 @@
|
|||||||
"TaeBqw": {
|
"TaeBqw": {
|
||||||
"defaultMessage": "Sign in with Nostr Extension"
|
"defaultMessage": "Sign in with Nostr Extension"
|
||||||
},
|
},
|
||||||
|
"TdTXXf": {
|
||||||
|
"defaultMessage": "Learn more"
|
||||||
|
},
|
||||||
"TdtZQ5": {
|
"TdtZQ5": {
|
||||||
"defaultMessage": "Crypto"
|
"defaultMessage": "Crypto"
|
||||||
},
|
},
|
||||||
@ -909,6 +918,9 @@
|
|||||||
"Up5U7K": {
|
"Up5U7K": {
|
||||||
"defaultMessage": "Block"
|
"defaultMessage": "Block"
|
||||||
},
|
},
|
||||||
|
"Ups2/p": {
|
||||||
|
"defaultMessage": "Your application is pending"
|
||||||
|
},
|
||||||
"UrKTqQ": {
|
"UrKTqQ": {
|
||||||
"defaultMessage": "You have an active iris.to account"
|
"defaultMessage": "You have an active iris.to account"
|
||||||
},
|
},
|
||||||
@ -1030,6 +1042,9 @@
|
|||||||
"b5vAk0": {
|
"b5vAk0": {
|
||||||
"defaultMessage": "Your handle will act like a lightning address and will redirect to your chosen LNURL or Lightning address"
|
"defaultMessage": "Your handle will act like a lightning address and will redirect to your chosen LNURL or Lightning address"
|
||||||
},
|
},
|
||||||
|
"bF1MYT": {
|
||||||
|
"defaultMessage": "You are a community leader and are earning <b>{percent}</b> of referred users subscriptions!"
|
||||||
|
},
|
||||||
"bG00/W": {
|
"bG00/W": {
|
||||||
"defaultMessage": "Service Worker Running"
|
"defaultMessage": "Service Worker Running"
|
||||||
},
|
},
|
||||||
@ -1293,6 +1308,9 @@
|
|||||||
"jzgQ2z": {
|
"jzgQ2z": {
|
||||||
"defaultMessage": "{n} Reactions"
|
"defaultMessage": "{n} Reactions"
|
||||||
},
|
},
|
||||||
|
"k0kCJp": {
|
||||||
|
"defaultMessage": "Apply Now"
|
||||||
|
},
|
||||||
"k2veDA": {
|
"k2veDA": {
|
||||||
"defaultMessage": "Write"
|
"defaultMessage": "Write"
|
||||||
},
|
},
|
||||||
|
@ -179,6 +179,7 @@
|
|||||||
"Gxcr08": "Broadcast Event",
|
"Gxcr08": "Broadcast Event",
|
||||||
"H+vHiz": "Hex Key..",
|
"H+vHiz": "Hex Key..",
|
||||||
"H0JBH6": "Log Out",
|
"H0JBH6": "Log Out",
|
||||||
|
"H0OG3T": "Leader Info",
|
||||||
"H6/kLh": "Order Paid!",
|
"H6/kLh": "Order Paid!",
|
||||||
"HAlOn1": "Name",
|
"HAlOn1": "Name",
|
||||||
"HFls6j": "name will be available later",
|
"HFls6j": "name will be available later",
|
||||||
@ -243,6 +244,7 @@
|
|||||||
"NdOYJJ": "Hmm nothing here.. Checkout {newUsersPage} to follow some recommended nostrich's!",
|
"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",
|
"NepkXH": "Can't vote with {amount} sats, please set a different default zap amount",
|
||||||
"NndBJE": "New users page",
|
"NndBJE": "New users page",
|
||||||
|
"O3Jz4E": "Use your invite code to earn sats!",
|
||||||
"O8Z8t9": "Show More",
|
"O8Z8t9": "Show More",
|
||||||
"OEW7yJ": "Zaps",
|
"OEW7yJ": "Zaps",
|
||||||
"OKhRC6": "Share",
|
"OKhRC6": "Share",
|
||||||
@ -287,6 +289,7 @@
|
|||||||
"TJo5E6": "Preview",
|
"TJo5E6": "Preview",
|
||||||
"TP/cMX": "Ended",
|
"TP/cMX": "Ended",
|
||||||
"TaeBqw": "Sign in with Nostr Extension",
|
"TaeBqw": "Sign in with Nostr Extension",
|
||||||
|
"TdTXXf": "Learn more",
|
||||||
"TdtZQ5": "Crypto",
|
"TdtZQ5": "Crypto",
|
||||||
"TpgeGw": "Hex Salt..",
|
"TpgeGw": "Hex Salt..",
|
||||||
"Tpy00S": "People",
|
"Tpy00S": "People",
|
||||||
@ -299,6 +302,7 @@
|
|||||||
"UUPFlt": "Users must accept the content warning to show the content of your note.",
|
"UUPFlt": "Users must accept the content warning to show the content of your note.",
|
||||||
"Ub+AGc": "Sign In",
|
"Ub+AGc": "Sign In",
|
||||||
"Up5U7K": "Block",
|
"Up5U7K": "Block",
|
||||||
|
"Ups2/p": "Your application is pending",
|
||||||
"UrKTqQ": "You have an active iris.to account",
|
"UrKTqQ": "You have an active iris.to account",
|
||||||
"UxgyeY": "Your referral code is {code}",
|
"UxgyeY": "Your referral code is {code}",
|
||||||
"VL900k": "Recommended Relays",
|
"VL900k": "Recommended Relays",
|
||||||
@ -339,6 +343,7 @@
|
|||||||
"aWpBzj": "Show more",
|
"aWpBzj": "Show more",
|
||||||
"b12Goz": "Mnemonic",
|
"b12Goz": "Mnemonic",
|
||||||
"b5vAk0": "Your handle will act like a lightning address and will redirect to your chosen LNURL or Lightning address",
|
"b5vAk0": "Your handle will act like a lightning address and will redirect to your chosen LNURL or Lightning address",
|
||||||
|
"bF1MYT": "You are a community leader and are earning <b>{percent}</b> of referred users subscriptions!",
|
||||||
"bG00/W": "Service Worker Running",
|
"bG00/W": "Service Worker Running",
|
||||||
"bLZL5a": "Get Address",
|
"bLZL5a": "Get Address",
|
||||||
"bMphls": "Logged in with read-only access",
|
"bMphls": "Logged in with read-only access",
|
||||||
@ -426,6 +431,7 @@
|
|||||||
"jTrbGf": "{n} km - {location}",
|
"jTrbGf": "{n} km - {location}",
|
||||||
"jvo0vs": "Save",
|
"jvo0vs": "Save",
|
||||||
"jzgQ2z": "{n} Reactions",
|
"jzgQ2z": "{n} Reactions",
|
||||||
|
"k0kCJp": "Apply Now",
|
||||||
"k2veDA": "Write",
|
"k2veDA": "Write",
|
||||||
"k7sKNy": "Our very own NIP-05 verification service, help support the development of this site and get a shiny special badge on our site!",
|
"k7sKNy": "Our very own NIP-05 verification service, help support the development of this site and get a shiny special badge on our site!",
|
||||||
"kEZUR8": "Register an Iris username",
|
"kEZUR8": "Register an Iris username",
|
||||||
|
Loading…
Reference in New Issue
Block a user