This commit is contained in:
2023-08-22 22:48:37 +01:00
parent d071736d4c
commit 16c54185bb
32 changed files with 57 additions and 49 deletions

View File

@ -65,7 +65,7 @@ export function ChatMessage({
inView?.isIntersecting ? ev.pubkey : undefined
);
const shouldShowMuteButton =
ev.pubkey !== streamer && ev.pubkey != login?.pubkey;
ev.pubkey !== streamer && ev.pubkey !== login?.pubkey;
const zapTarget = profile?.lud16 ?? profile?.lud06;
const zaps = useMemo(() => {
return reactions
@ -111,8 +111,8 @@ export function ChatMessage({
const pub = login?.publisher();
if (emoji.native) {
reply = await pub?.react(ev, emoji.native || "+1");
} else {
const e = getEmojiById(emoji.id!);
} else if (emoji.id) {
const e = getEmojiById(emoji.id);
if (e) {
reply = await pub?.generic((eb) => {
return eb
@ -120,7 +120,7 @@ export function ChatMessage({
.content(`:${emoji.id}:`)
.tag(["e", ev.id])
.tag(["p", ev.pubkey])
.tag(["emoji", e.at(1)!, e.at(2)!]);
.tag(["emoji", e[1], e[2]]);
});
}
}
@ -141,7 +141,7 @@ export function ChatMessage({
setShowEmojiPicker(!showEmojiPicker);
}
async function muteUser(e: React.MouseEvent) {
function muteUser(e: React.MouseEvent) {
e.stopPropagation();
mute();
}
@ -194,7 +194,7 @@ export function ChatMessage({
<div className="message-reaction-container">
{isCustomEmojiReaction && emoji ? (
<span className="message-reaction">
<EmojiComponent name={emoji.at(1)!} url={emoji.at(2)!} />
<EmojiComponent name={emoji[1]} url={emoji[2]} />
</span>
) : (
<span className="message-reaction">{e}</span>
@ -210,16 +210,16 @@ export function ChatMessage({
style={
isTablet
? {
display: showZapDialog || isHovering ? "flex" : "none",
}
display: showZapDialog || isHovering ? "flex" : "none",
}
: {
position: "fixed",
top: topOffset ? topOffset - 12 : 0,
left: leftOffset ? leftOffset - 32 : 0,
opacity: showZapDialog || isHovering ? 1 : 0,
pointerEvents:
showZapDialog || isHovering ? "auto" : "none",
}
position: "fixed",
top: topOffset ? topOffset - 12 : 0,
left: leftOffset ? leftOffset - 32 : 0,
opacity: showZapDialog || isHovering ? 1 : 0,
pointerEvents:
showZapDialog || isHovering ? "auto" : "none",
}
}
>
{zapTarget && (

View File

@ -12,7 +12,9 @@ export function LoggedInFollowButton({
value: string;
}) {
const login = useLogin();
const { tags, content, timestamp } = login!.follows;
if (!login) return;
const { tags, content, timestamp } = login.follows;
const follows = tags.filter((t) => t.at(0) === tag);
const isFollowing = follows.find((t) => t.at(1) === value);

View File

@ -325,8 +325,6 @@
text-transform: lowercase;
color: #fff;
font-size: 12px;
font-family: Outfit;
font-style: normal;
font-weight: 500;
line-height: 18px;
}

View File

@ -8,7 +8,7 @@ import {
parseZap,
encodeTLV,
} from "@snort/system";
import { unixNow } from "@snort/shared";
import { unixNow, unwrap } from "@snort/shared";
import { useEffect, useMemo } from "react";
import uniqBy from "lodash.uniqby";
@ -96,7 +96,7 @@ export function LiveChat({
const login = useLogin();
useEffect(() => {
const pubkeys = [
...new Set(feed.zaps.flatMap((a) => [a.pubkey, findTag(a, "p")!])),
...new Set(feed.zaps.flatMap((a) => [a.pubkey, unwrap(findTag(a, "p"))])),
];
System.ProfileLoader.TrackMetadata(pubkeys);
return () => System.ProfileLoader.UntrackMetadata(pubkeys);

View File

@ -9,6 +9,7 @@ import { StreamEditor, StreamEditorProps } from "./stream-editor";
import { useNavigate } from "react-router-dom";
import { eventLink, findTag } from "utils";
import { NostrProviderDialog } from "./nostr-provider-dialog";
import { unwrap } from "@snort/shared";
function NewStream({ ev, onFinish }: StreamEditorProps) {
const providers = useStreamProvider();
@ -19,7 +20,7 @@ function NewStream({ ev, onFinish }: StreamEditorProps) {
if (!currentProvider) {
setCurrentProvider(
ev !== undefined
? providers.find((a) => a.name.toLowerCase() === "manual")!
? unwrap(providers.find((a) => a.name.toLowerCase() === "manual"))
: providers.at(0)
);
}

View File

@ -1,9 +1,11 @@
import { Menu, MenuItem } from "@szhsin/react-menu";
import * as Dialog from "@radix-ui/react-dialog";
import { unwrap } from "@snort/shared";
import { NostrEvent, NostrPrefix, encodeTLV } from "@snort/system";
import { Icon } from "./icon";
import { useState } from "react";
import { Textarea } from "./textarea";
import { NostrEvent, NostrPrefix, encodeTLV } from "@snort/system";
import { findTag } from "utils";
import AsyncButton from "./async-button";
import { useLogin } from "hooks/login";
@ -18,7 +20,7 @@ export function ShareMenu({ ev }: { ev: NostrEvent }) {
const naddr = encodeTLV(
NostrPrefix.Address,
findTag(ev, "d")!,
unwrap(findTag(ev, "d")),
undefined,
ev.kind,
ev.pubkey

View File

@ -100,7 +100,7 @@ function Card({ canEdit, ev, cards }: CardProps) {
);
function findTagByIdentifier(d: string) {
return tags.find((t) => t.at(1)!.endsWith(`:${d}`));
return tags.find((t) => t[1].endsWith(`:${d}`));
}
const [dropStyle, dropRef] = useDrop(
@ -293,7 +293,7 @@ function EditCard({ card, cards }: EditCardProps) {
async function onCancel() {
const pub = login?.publisher();
if (pub) {
const newTags = tags.filter((t) => !t.at(1)!.endsWith(`:${identifier}`));
const newTags = tags.filter((t) => !t[1].endsWith(`:${identifier}`));
const userCardsEv = await pub.generic((eb) => {
eb.kind(USER_CARDS).content("");
for (const tag of newTags) {
@ -408,7 +408,7 @@ export function StreamCardEditor({ pubkey, tags }: StreamCardEditorProps) {
<>
<div className="stream-cards">
{cards.map((ev) => (
<Card canEdit={isEditing} cards={cards} key={ev.id} ev={ev!} />
<Card canEdit={isEditing} cards={cards} key={ev.id} ev={ev} />
))}
{isEditing && <AddCard cards={cards} />}
</div>
@ -433,7 +433,7 @@ export function ReadOnlyStreamCards({ host }: StreamCardsProps) {
return (
<div className="stream-cards">
{cards.map((ev) => (
<Card cards={cards} key={ev!.id} ev={ev!} />
<Card cards={cards} key={ev.id} ev={ev} />
))}
</div>
);

View File

@ -53,11 +53,11 @@ export function Textarea({ emojis, ...props }: TextareaProps) {
const userDataProvider = async (token: string) => {
const cache = System.ProfileLoader.Cache;
if (cache instanceof UserProfileCache) {
return cache.search(token);
return await cache.search(token);
}
};
const emojiDataProvider = async (token: string) => {
const emojiDataProvider = (token: string) => {
const results = emojis
.map((t) => {
return {

View File

@ -0,0 +1,72 @@
/* latin-ext */
@font-face {
font-family: 'Outfit';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url(outfit_400_latin-ext.woff2) format('woff2');
unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Outfit';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url(outfit_400_latin.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin-ext */
@font-face {
font-family: 'Outfit';
font-style: normal;
font-weight: 500;
font-display: swap;
src: url(outfit_500_latin-ext.woff2) format('woff2');
unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Outfit';
font-style: normal;
font-weight: 500;
font-display: swap;
src: url(outfit_500_latin.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin-ext */
@font-face {
font-family: 'Outfit';
font-style: normal;
font-weight: 600;
font-display: swap;
src: url(outfit_600_latin-ext.woff2) format('woff2');
unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Outfit';
font-style: normal;
font-weight: 600;
font-display: swap;
src: url(outfit_600_latin.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin-ext */
@font-face {
font-family: 'Outfit';
font-style: normal;
font-weight: 700;
font-display: swap;
src: url(outfit_700_latin-ext.woff2) format('woff2');
unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Outfit';
font-style: normal;
font-weight: 700;
font-display: swap;
src: url(outfit_700_latin.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -29,7 +29,7 @@ export function useUserCards(
const subRelated = useMemo(() => {
if (!pubkey) return null;
const splitted = related.map((t) => t.at(1)!.split(":"));
const splitted = related.map((t) => t[1].split(":"));
const authors = splitted
.map((s) => s.at(1))
.filter((s) => s)
@ -58,7 +58,7 @@ export function useUserCards(
const cards = useMemo(() => {
return related
.map((t) => {
const [k, pubkey, identifier] = t.at(1)!.split(":");
const [k, pubkey, identifier] = t[1].split(":");
const kind = Number(k);
return (data ?? []).find(
(e) =>
@ -104,7 +104,7 @@ export function useCards(pubkey: string, leaveOpen = false): TaggedRawEvent[] {
const subRelated = useMemo(() => {
if (!pubkey) return null;
const splitted = related.map((t) => t.at(1)!.split(":"));
const splitted = related.map((t) => t[1].split(":"));
const authors = splitted
.map((s) => s.at(1))
.filter((s) => s)
@ -134,7 +134,7 @@ export function useCards(pubkey: string, leaveOpen = false): TaggedRawEvent[] {
const cards = useMemo(() => {
return related
.map((t) => {
const [k, pubkey, identifier] = t.at(1)!.split(":");
const [k, pubkey, identifier] = t[1].split(":");
const kind = Number(k);
return cardEvents.find(
(e) =>

View File

@ -45,7 +45,7 @@ export function useUserEmojiPacks(pubkey?: string, userEmoji?: Tags) {
const subRelated = useMemo(() => {
if (!pubkey) return null;
const splitted = related.map((t) => t.at(1)!.split(":"));
const splitted = related.map((t) => t[1].split(":"));
const authors = splitted
.map((s) => s.at(1))
.filter((s) => s)

View File

@ -9,6 +9,7 @@ import {
parseZap,
} from "@snort/system";
import { useRequestBuilder } from "@snort/system-react";
import { unwrap } from "@snort/shared";
import { GOAL } from "const";
import { System } from "index";
@ -43,7 +44,7 @@ export function useZapGoal(host: string, link: NostrLink, leaveOpen = false) {
b.withFilter()
.kinds([GOAL])
.authors([host])
.tag("a", [`${link.kind}:${link.author!}:${link.id}`]);
.tag("a", [`${link.kind}:${unwrap(link.author)}:${link.id}`]);
return b;
}, [link, leaveOpen]);

View File

@ -1,5 +1,6 @@
import "@szhsin/react-menu/dist/index.css";
import "./index.css";
import "./fonts/outfit/outfit.css";
import React from "react";
import ReactDOM from "react-dom/client";

View File

@ -1,6 +1,6 @@
import { bytesToHex } from "@noble/curves/abstract/utils";
import { schnorr } from "@noble/curves/secp256k1";
import { ExternalStore } from "@snort/shared";
import { ExternalStore, unwrap } from "@snort/shared";
import { EventPublisher, Nip7Signer, PrivateKeySigner } from "@snort/system";
import type { EmojiPack, Tags } from "types";
@ -131,7 +131,7 @@ export function getPublisher(session: LoginSession) {
}
case LoginType.PrivateKey: {
return new EventPublisher(
new PrivateKeySigner(session.privateKey!),
new PrivateKeySigner(unwrap(session.privateKey)),
session.pubkey
);
}

View File

@ -2,12 +2,13 @@ import "./chat-popout.css";
import { LiveChat } from "element/live-chat";
import { useParams } from "react-router-dom";
import { NostrPrefix, encodeTLV, parseNostrLink } from "@snort/system";
import { unwrap } from "@snort/shared";
import { useCurrentStreamFeed } from "hooks/current-stream-feed";
import { findTag } from "utils";
export function ChatPopout() {
const params = useParams();
const link = parseNostrLink(params.id!);
const link = parseNostrLink(unwrap(params.id));
const ev = useCurrentStreamFeed(link, true);
const lnk = parseNostrLink(

View File

@ -10,6 +10,7 @@ import {
encodeTLV,
} from "@snort/system";
import { useUserProfile } from "@snort/system-react";
import { unwrap } from "@snort/shared";
import { Profile } from "element/profile";
import { Icon } from "element/icon";
import { SendZapsDialog } from "element/send-zap";
@ -52,7 +53,7 @@ const defaultBanner = "https://void.cat/d/Hn1AdN5UKmceuDkgDW847q.webp";
export function ProfilePage() {
const navigate = useNavigate();
const params = useParams();
const link = parseNostrLink(params.npub!);
const link = parseNostrLink(unwrap(params.npub));
const placeholder = usePlaceholder(link.id);
const profile = useUserProfile(System, link.id);
const zapTarget = profile?.lud16 ?? profile?.lud06;

View File

@ -1,5 +1,6 @@
import "./stream-page.css";
import { parseNostrLink, TaggedRawEvent } from "@snort/system";
import { unwrap } from "@snort/shared";
import { useLocation, useNavigate, useParams } from "react-router-dom";
import { Helmet } from "react-helmet";
@ -114,7 +115,7 @@ export function StreamPage() {
const params = useParams();
const location = useLocation();
const evPreload = getEventFromLocationState(location.state);
const link = parseNostrLink(params.id!);
const link = parseNostrLink(unwrap(params.id));
const ev = useCurrentStreamFeed(link, true, evPreload);
const host = getHost(ev);
const goal = useZapGoal(host, link, true);

View File

@ -1,5 +1,6 @@
import "./tag.css";
import { useParams } from "react-router-dom";
import { unwrap } from "@snort/shared";
import { VideoTile } from "element/video-tile";
import { FollowTagButton } from "element/follow-button";
@ -12,7 +13,7 @@ export function TagPage() {
<div className="tag-page">
<div className="tag-page-header">
<h1>#{tag}</h1>
<FollowTagButton tag={tag!} />
<FollowTagButton tag={unwrap(tag)} />
</div>
<div className="video-grid">
{live.map((e) => (

View File

@ -58,7 +58,7 @@ export class OwncastProvider implements StreamProvider {
body?: unknown
): Promise<T> {
const rsp = await fetch(`${this.#url}${path}`, {
method: method,
method,
body: body ? JSON.stringify(body) : undefined,
headers: {
"content-type": "application/json",

View File

@ -103,7 +103,7 @@ export class Nip103StreamProvider implements StreamProvider {
.tag(["method", method]);
});
const rsp = await fetch(u, {
method: method,
method,
body: body ? JSON.stringify(body) : undefined,
headers: {
"content-type": "application/json",

View File

@ -109,7 +109,7 @@ export function getHost(ev?: NostrEvent) {
);
}
export async function openFile(): Promise<File | undefined> {
export function openFile(): Promise<File | undefined> {
return new Promise((resolve) => {
const elm = document.createElement("input");
elm.type = "file";

View File

@ -503,7 +503,7 @@ export class WISH extends TypedEventTarget {
},
});
const body = await resp.text();
if (resp.status != 201) {
if (resp.status !== 201) {
throw new Error(`Unexpected status code ${resp.status}: ${body}`);
}
@ -611,7 +611,7 @@ export class WISH extends TypedEventTarget {
throw new Error(`Unexpected status code ${resp.status}: ${body}`);
}
async WithEndpoint(endpoint: string, trickle: boolean) {
WithEndpoint(endpoint: string, trickle: boolean) {
if (endpoint === "") {
throw new Error("Endpoint cannot be empty");
}
@ -637,7 +637,7 @@ export class WISH extends TypedEventTarget {
method: "DELETE",
mode: "cors",
});
if (resp.status != 200) {
if (resp.status !== 200) {
const body = await resp.text();
throw new Error(`Unexpected status code ${resp.status}: ${body}`);
}