Update api
This commit is contained in:
@ -1,5 +1,5 @@
|
|||||||
import { NostrEvent } from "@snort/system";
|
import { NostrEvent } from "@snort/system";
|
||||||
import { StreamProvider, StreamProviderInfo } from "providers";
|
import { StreamProvider, StreamProviderEndpoint, StreamProviderInfo } from "providers";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { SendZaps } from "./send-zap";
|
import { SendZaps } from "./send-zap";
|
||||||
import { StreamEditor, StreamEditorProps } from "./stream-editor";
|
import { StreamEditor, StreamEditorProps } from "./stream-editor";
|
||||||
@ -11,9 +11,13 @@ const DummyEvent = { content: "", id: "", pubkey: "", sig: "", kind: LIVE_STREAM
|
|||||||
export function NostrProviderDialog({ provider, ...others }: { provider: StreamProvider } & StreamEditorProps) {
|
export function NostrProviderDialog({ provider, ...others }: { provider: StreamProvider } & StreamEditorProps) {
|
||||||
const [topup, setTopup] = useState(false);
|
const [topup, setTopup] = useState(false);
|
||||||
const [info, setInfo] = useState<StreamProviderInfo>();
|
const [info, setInfo] = useState<StreamProviderInfo>();
|
||||||
|
const [ep, setEndpoint] = useState<StreamProviderEndpoint>();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
provider.info().then(v => setInfo(v));
|
provider.info().then(v => {
|
||||||
|
setInfo(v);
|
||||||
|
setEndpoint(v.endpoints[0]);
|
||||||
|
});
|
||||||
}, [provider]);
|
}, [provider]);
|
||||||
|
|
||||||
if (!info) {
|
if (!info) {
|
||||||
@ -38,30 +42,39 @@ export function NostrProviderDialog({ provider, ...others }: { provider: StreamP
|
|||||||
}
|
}
|
||||||
|
|
||||||
function calcEstimate() {
|
function calcEstimate() {
|
||||||
if (!info?.rate || !info?.unit || !info?.balance || !info.balance) return;
|
if (!ep?.rate || !ep?.unit || !info?.balance || !info.balance) return;
|
||||||
|
|
||||||
const raw = Math.max(0, info.balance / info.rate);
|
const raw = Math.max(0, info.balance / ep.rate);
|
||||||
if (info.unit === "min" && raw > 60) {
|
if (ep.unit === "min" && raw > 60) {
|
||||||
return `${(raw / 60).toFixed(0)} hour`
|
return `${(raw / 60).toFixed(0)} hour @ ${ep.rate} sats/${ep.unit}`
|
||||||
}
|
}
|
||||||
return `${raw.toFixed(0)} ${info.unit}`
|
return `${raw.toFixed(0)} ${ep.unit} @ ${ep.rate} sats/${ep.unit}`
|
||||||
}
|
}
|
||||||
|
|
||||||
const streamEvent = others.ev ?? info.publishedEvent ?? DummyEvent;
|
const streamEvent = others.ev ?? info.publishedEvent ?? DummyEvent;
|
||||||
return <>
|
return <>
|
||||||
|
{info.endpoints.length > 1 && <div>
|
||||||
|
<p>Endpoint</p>
|
||||||
|
<div className="flex g12">
|
||||||
|
{info.endpoints.map(a => <span className={`pill${ep?.name === a.name ? " active" : ""}`}
|
||||||
|
onClick={() => setEndpoint(a)}>
|
||||||
|
{a.name}
|
||||||
|
</span>)}
|
||||||
|
</div>
|
||||||
|
</div>}
|
||||||
<div>
|
<div>
|
||||||
<p>Stream Url</p>
|
<p>Stream Url</p>
|
||||||
<div className="paper">
|
<div className="paper">
|
||||||
<input type="text" value={info.ingressUrl} disabled />
|
<input type="text" value={ep?.url} disabled />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p>Stream Key</p>
|
<p>Stream Key</p>
|
||||||
<div className="flex g12">
|
<div className="flex g12">
|
||||||
<div className="paper f-grow">
|
<div className="paper f-grow">
|
||||||
<input type="password" value={info.ingressKey} disabled />
|
<input type="password" value={ep?.key} disabled />
|
||||||
</div>
|
</div>
|
||||||
<button className="btn btn-primary" onClick={() => window.navigator.clipboard.writeText(info.ingressKey ?? "")}>
|
<button className="btn btn-primary" onClick={() => window.navigator.clipboard.writeText(ep?.key ?? "")}>
|
||||||
Copy
|
Copy
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@ -76,7 +89,7 @@ export function NostrProviderDialog({ provider, ...others }: { provider: StreamP
|
|||||||
Topup
|
Topup
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<small>About {calcEstimate()} @ {info.rate} sats/{info.unit}</small>
|
<small>About {calcEstimate()}</small>
|
||||||
</div>
|
</div>
|
||||||
{streamEvent && <StreamEditor onFinish={(ex) => {
|
{streamEvent && <StreamEditor onFinish={(ex) => {
|
||||||
provider.updateStreamInfo(ex);
|
provider.updateStreamInfo(ex);
|
||||||
|
@ -44,14 +44,18 @@ export interface StreamProviderInfo {
|
|||||||
version?: string
|
version?: string
|
||||||
state: StreamState
|
state: StreamState
|
||||||
viewers?: number
|
viewers?: number
|
||||||
ingressUrl?: string
|
|
||||||
ingressKey?: string
|
|
||||||
balance?: number
|
|
||||||
publishedEvent?: NostrEvent
|
publishedEvent?: NostrEvent
|
||||||
|
balance?: number
|
||||||
|
endpoints: Array<StreamProviderEndpoint>
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface StreamProviderEndpoint {
|
||||||
|
name: string
|
||||||
|
url: string
|
||||||
|
key: string
|
||||||
rate?: number
|
rate?: number
|
||||||
unit?: string
|
unit?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ProviderStore extends ExternalStore<Array<StreamProvider>> {
|
export class ProviderStore extends ExternalStore<Array<StreamProvider>> {
|
||||||
#providers: Array<StreamProvider> = []
|
#providers: Array<StreamProvider> = []
|
||||||
|
|
||||||
@ -86,7 +90,8 @@ export class ProviderStore extends ExternalStore<Array<StreamProvider>> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
takeSnapshot() {
|
takeSnapshot() {
|
||||||
return [new Nip103StreamProvider("https://api.zap.stream/api/nostr/"), new ManualProvider(), ...this.#providers];
|
//const defaultProvider = new Nip103StreamProvider("https://api.zap.stream/api/nostr/");
|
||||||
|
return [new ManualProvider(), ...this.#providers];
|
||||||
}
|
}
|
||||||
|
|
||||||
#save() {
|
#save() {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { StreamProvider, StreamProviderInfo, StreamProviders } from ".";
|
import { StreamProvider, StreamProviderEndpoint, StreamProviderInfo, StreamProviders } from ".";
|
||||||
import { EventKind, NostrEvent } from "@snort/system";
|
import { EventKind, NostrEvent } from "@snort/system";
|
||||||
import { Login } from "index";
|
import { Login } from "index";
|
||||||
import { getPublisher } from "login";
|
import { getPublisher } from "login";
|
||||||
@ -28,12 +28,17 @@ export class Nip103StreamProvider implements StreamProvider {
|
|||||||
name: title ?? "",
|
name: title ?? "",
|
||||||
state: state,
|
state: state,
|
||||||
viewers: 0,
|
viewers: 0,
|
||||||
ingressUrl: rsp.url,
|
|
||||||
ingressKey: rsp.key,
|
|
||||||
balance: rsp.quota.remaining,
|
|
||||||
publishedEvent: rsp.event,
|
publishedEvent: rsp.event,
|
||||||
rate: rsp.quota.rate,
|
balance: rsp.balance,
|
||||||
unit: rsp.quota.unit
|
endpoints: rsp.endpoints.map(a => {
|
||||||
|
return {
|
||||||
|
name: a.name,
|
||||||
|
url: a.url,
|
||||||
|
key: a.key,
|
||||||
|
rate: a.cost.rate,
|
||||||
|
unit: a.cost.unit,
|
||||||
|
} as StreamProviderEndpoint
|
||||||
|
})
|
||||||
} as StreamProviderInfo
|
} as StreamProviderInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,14 +94,20 @@ export class Nip103StreamProvider implements StreamProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface AccountResponse {
|
interface AccountResponse {
|
||||||
|
balance: number
|
||||||
|
event?: NostrEvent
|
||||||
|
endpoints: Array<IngestEndpoint>
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IngestEndpoint {
|
||||||
|
name: string
|
||||||
url: string
|
url: string
|
||||||
key: string
|
key: string
|
||||||
event?: NostrEvent
|
cost: {
|
||||||
quota: {
|
|
||||||
unit: string
|
unit: string
|
||||||
rate: number
|
rate: number
|
||||||
remaining: number
|
|
||||||
}
|
}
|
||||||
|
capabilities: Array<string>
|
||||||
}
|
}
|
||||||
|
|
||||||
interface TopUpResponse {
|
interface TopUpResponse {
|
||||||
|
Reference in New Issue
Block a user