Yarn upgrade

@snort/system upgrade
Setup ts-load for react-intl
This commit is contained in:
Kieran 2023-08-27 14:26:22 +01:00
parent 7cba67e4c1
commit 6587923bdc
Signed by: Kieran
GPG Key ID: DE71CEB3925BE941
29 changed files with 1266 additions and 1570 deletions

File diff suppressed because one or more lines are too long

View File

@ -1,6 +1,6 @@
{ {
"name": "eslint", "name": "eslint",
"version": "8.45.0-sdk", "version": "8.48.0-sdk",
"main": "./lib/api.js", "main": "./lib/api.js",
"type": "commonjs" "type": "commonjs"
} }

View File

@ -1,6 +1,6 @@
{ {
"name": "typescript", "name": "typescript",
"version": "5.1.3-sdk", "version": "5.2.2-sdk",
"main": "./lib/typescript.js", "main": "./lib/typescript.js",
"type": "commonjs" "type": "commonjs"
} }

View File

@ -1 +1 @@
yarnPath: .yarn/releases/yarn-3.6.1.cjs yarnPath: .yarn/releases/yarn-3.6.3.cjs

View File

@ -15,8 +15,8 @@
"@react-hook/resize-observer": "^1.2.6", "@react-hook/resize-observer": "^1.2.6",
"@scure/base": "^1.1.1", "@scure/base": "^1.1.1",
"@snort/shared": "^1.0.4", "@snort/shared": "^1.0.4",
"@snort/system": "^1.0.16", "@snort/system": "^1.0.17",
"@snort/system-react": "^1.0.11", "@snort/system-react": "^1.0.12",
"@szhsin/react-menu": "^4.0.2", "@szhsin/react-menu": "^4.0.2",
"@testing-library/jest-dom": "^5.14.1", "@testing-library/jest-dom": "^5.14.1",
"@testing-library/react": "^13.0.0", "@testing-library/react": "^13.0.0",
@ -41,11 +41,12 @@
"react-markdown": "^8.0.7", "react-markdown": "^8.0.7",
"react-router-dom": "^6.13.0", "react-router-dom": "^6.13.0",
"react-tag-input-component": "^2.0.2", "react-tag-input-component": "^2.0.2",
"semantic-sdp": "^3.26.2", "semantic-sdp": "^3.26.3",
"usehooks-ts": "^2.9.1", "usehooks-ts": "^2.9.1",
"web-vitals": "^2.1.0", "web-vitals": "^2.1.0",
"webrtc-adapter": "^8.2.3", "webrtc-adapter": "^8.2.3",
"workbox-core": "^7.0.0", "workbox-core": "^7.0.0",
"workbox-precaching": "^7.0.0",
"workbox-routing": "^7.0.0", "workbox-routing": "^7.0.0",
"workbox-strategies": "^7.0.0" "workbox-strategies": "^7.0.0"
}, },
@ -81,23 +82,22 @@
"@babel/preset-env": "^7.21.5", "@babel/preset-env": "^7.21.5",
"@babel/preset-react": "^7.18.6", "@babel/preset-react": "^7.18.6",
"@babel/preset-typescript": "^7.22.5", "@babel/preset-typescript": "^7.22.5",
"@formatjs/cli": "^6.0.1", "@formatjs/cli": "^6.1.3",
"@formatjs/ts-transformer": "^3.13.1", "@formatjs/ts-transformer": "^3.13.3",
"@testing-library/dom": "^9.3.1", "@testing-library/dom": "^9.3.1",
"@types/lodash": "^4.14.195", "@types/lodash": "^4.14.195",
"@types/lodash.uniqby": "^4.7.7", "@types/lodash.uniqby": "^4.7.7",
"@types/react": "^18.2.15", "@types/react": "^18.2.21",
"@types/react-dom": "^18.2.7", "@types/react-dom": "^18.2.7",
"@types/react-helmet": "^6.1.6", "@types/react-helmet": "^6.1.6",
"@typescript-eslint/eslint-plugin": "^6.1.0", "@typescript-eslint/eslint-plugin": "^6.4.1",
"@typescript-eslint/parser": "^6.1.0", "@typescript-eslint/parser": "^6.4.1",
"@webbtc/webln-types": "^1.0.12", "@webbtc/webln-types": "^1.0.12",
"babel-loader": "^9.1.2", "babel-loader": "^9.1.3",
"babel-plugin-formatjs": "^10.5.3",
"copy-webpack-plugin": "^11.0.0", "copy-webpack-plugin": "^11.0.0",
"css-loader": "^6.7.3", "css-loader": "^6.8.1",
"css-minimizer-webpack-plugin": "^5.0.0", "css-minimizer-webpack-plugin": "^5.0.0",
"eslint": "^8.45.0", "eslint": "^8.48.0",
"eslint-plugin-formatjs": "^4.10.1", "eslint-plugin-formatjs": "^4.10.1",
"eslint-webpack-plugin": "^4.0.1", "eslint-webpack-plugin": "^4.0.1",
"html-webpack-plugin": "^5.5.1", "html-webpack-plugin": "^5.5.1",
@ -107,12 +107,12 @@
"source-map-loader": "^4.0.1", "source-map-loader": "^4.0.1",
"terser-webpack-plugin": "^5.3.9", "terser-webpack-plugin": "^5.3.9",
"ts-loader": "^9.4.4", "ts-loader": "^9.4.4",
"typescript": "^5.1.3", "typescript": "^5.2.2",
"webpack": "^5.82.1", "webpack": "^5.82.1",
"webpack-bundle-analyzer": "^4.8.0", "webpack-bundle-analyzer": "^4.8.0",
"webpack-cli": "^5.1.1", "webpack-cli": "^5.1.1",
"webpack-dev-server": "^4.15.0", "webpack-dev-server": "^4.15.0",
"workbox-webpack-plugin": "^6.5.4" "workbox-webpack-plugin": "^7.0.0"
}, },
"packageManager": "yarn@3.6.1" "packageManager": "yarn@3.6.3"
} }

View File

@ -1,6 +1,6 @@
import { useUserProfile } from "@snort/system-react"; import { useUserProfile, SnortContext } from "@snort/system-react";
import { NostrEvent, parseZap, EventKind } from "@snort/system"; import { NostrEvent, parseZap, EventKind } from "@snort/system";
import React, { useRef, useState, useMemo } from "react"; import React, { useRef, useState, useMemo, useContext } from "react";
import { import {
useMediaQuery, useMediaQuery,
useHover, useHover,
@ -20,7 +20,6 @@ import { useLogin } from "hooks/login";
import { formatSats } from "number"; import { formatSats } from "number";
import { findTag } from "utils"; import { findTag } from "utils";
import type { Badge, Emoji, EmojiPack } from "types"; import type { Badge, Emoji, EmojiPack } from "types";
import { System } from "index";
function emojifyReaction(reaction: string) { function emojifyReaction(reaction: string) {
if (reaction === "+") { if (reaction === "+") {
@ -61,16 +60,16 @@ export function ChatMessage({
const [showEmojiPicker, setShowEmojiPicker] = useState(false); const [showEmojiPicker, setShowEmojiPicker] = useState(false);
const login = useLogin(); const login = useLogin();
const profile = useUserProfile( const profile = useUserProfile(
System,
inView?.isIntersecting ? ev.pubkey : undefined inView?.isIntersecting ? ev.pubkey : undefined
); );
const shouldShowMuteButton = const shouldShowMuteButton =
ev.pubkey !== streamer && ev.pubkey !== login?.pubkey; ev.pubkey !== streamer && ev.pubkey !== login?.pubkey;
const zapTarget = profile?.lud16 ?? profile?.lud06; const zapTarget = profile?.lud16 ?? profile?.lud06;
const system = useContext(SnortContext);
const zaps = useMemo(() => { const zaps = useMemo(() => {
return reactions return reactions
.filter((a) => a.kind === EventKind.ZapReceipt) .filter((a) => a.kind === EventKind.ZapReceipt)
.map((a) => parseZap(a, System.ProfileLoader.Cache)) .map((a) => parseZap(a, system.ProfileLoader.Cache))
.filter((a) => a && a.valid); .filter((a) => a && a.valid);
}, [reactions]); }, [reactions]);
const emojiReactions = useMemo(() => { const emojiReactions = useMemo(() => {
@ -126,7 +125,7 @@ export function ChatMessage({
} }
if (reply) { if (reply) {
console.debug(reply); console.debug(reply);
System.BroadcastEvent(reply); system.BroadcastEvent(reply);
} }
} catch { } catch {
//ignore //ignore

View File

@ -12,11 +12,10 @@ import usePreviousValue from "hooks/usePreviousValue";
import { SendZapsDialog } from "element/send-zap"; import { SendZapsDialog } from "element/send-zap";
import { useZaps } from "hooks/goals"; import { useZaps } from "hooks/goals";
import { getName } from "element/profile"; import { getName } from "element/profile";
import { System } from "index";
import { Icon } from "./icon"; import { Icon } from "./icon";
export function Goal({ ev }: { ev: NostrEvent }) { export function Goal({ ev }: { ev: NostrEvent }) {
const profile = useUserProfile(System, ev.pubkey); const profile = useUserProfile(ev.pubkey);
const zapTarget = profile?.lud16 ?? profile?.lud06; const zapTarget = profile?.lud16 ?? profile?.lud06;
const zaps = useZaps(ev, true); const zaps = useZaps(ev, true);
const goalAmount = useMemo(() => { const goalAmount = useMemo(() => {

View File

@ -1,6 +1,5 @@
import { Link } from "react-router-dom"; import { Link } from "react-router-dom";
import { useUserProfile } from "@snort/system-react"; import { useUserProfile } from "@snort/system-react";
import { System } from "index";
import { hexToBech32 } from "utils"; import { hexToBech32 } from "utils";
interface MentionProps { interface MentionProps {
@ -9,7 +8,7 @@ interface MentionProps {
} }
export function Mention({ pubkey }: MentionProps) { export function Mention({ pubkey }: MentionProps) {
const user = useUserProfile(System, pubkey); const user = useUserProfile(pubkey);
const npub = hexToBech32("npub", pubkey); const npub = hexToBech32("npub", pubkey);
return <Link to={`/p/${npub}`}>{user?.name || pubkey}</Link>; return <Link to={`/p/${npub}`}>{user?.name || pubkey}</Link>;
} }

View File

@ -7,7 +7,6 @@ import { hexToBech32 } from "@snort/shared";
import { Icon } from "element/icon"; import { Icon } from "element/icon";
import usePlaceholder from "hooks/placeholders"; import usePlaceholder from "hooks/placeholders";
import { System } from "index";
import { useInView } from "react-intersection-observer"; import { useInView } from "react-intersection-observer";
export interface ProfileOptions { export interface ProfileOptions {
@ -46,7 +45,7 @@ export function Profile({
}) { }) {
const { inView, ref } = useInView(); const { inView, ref } = useInView();
const pLoaded = const pLoaded =
useUserProfile(System, inView && !profile ? pubkey : undefined) || profile; useUserProfile(inView && !profile ? pubkey : undefined) || profile;
const showAvatar = options?.showAvatar ?? true; const showAvatar = options?.showAvatar ?? true;
const showName = options?.showName ?? true; const showName = options?.showName ?? true;
const placeholder = usePlaceholder(pubkey); const placeholder = usePlaceholder(pubkey);

View File

@ -5,7 +5,7 @@ import * as Dialog from "@radix-ui/react-dialog";
import { DndProvider, useDrag, useDrop } from "react-dnd"; import { DndProvider, useDrag, useDrop } from "react-dnd";
import { HTML5Backend } from "react-dnd-html5-backend"; import { HTML5Backend } from "react-dnd-html5-backend";
import type { TaggedRawEvent } from "@snort/system"; import { TaggedNostrEvent } from "@snort/system";
import { Toggle } from "element/toggle"; import { Toggle } from "element/toggle";
import { Icon } from "element/icon"; import { Icon } from "element/icon";
@ -64,8 +64,8 @@ const CardPreview = forwardRef(
interface CardProps { interface CardProps {
canEdit?: boolean; canEdit?: boolean;
ev: TaggedRawEvent; ev: TaggedNostrEvent;
cards: TaggedRawEvent[]; cards: TaggedNostrEvent[];
} }
interface CardItem { interface CardItem {
@ -259,7 +259,7 @@ function CardDialog({
interface EditCardProps { interface EditCardProps {
card: CardType; card: CardType;
cards: TaggedRawEvent[]; cards: TaggedNostrEvent[];
} }
function EditCard({ card, cards }: EditCardProps) { function EditCard({ card, cards }: EditCardProps) {
@ -332,7 +332,7 @@ function EditCard({ card, cards }: EditCardProps) {
} }
interface AddCardProps { interface AddCardProps {
cards: TaggedRawEvent[]; cards: TaggedNostrEvent[];
} }
function AddCard({ cards }: AddCardProps) { function AddCard({ cards }: AddCardProps) {

View File

@ -1,7 +1,7 @@
import { useMemo } from "react"; import { useMemo } from "react";
import { import {
TaggedRawEvent, TaggedNostrEvent,
EventKind, EventKind,
NoteCollection, NoteCollection,
RequestBuilder, RequestBuilder,
@ -9,14 +9,13 @@ import {
import { useRequestBuilder } from "@snort/system-react"; import { useRequestBuilder } from "@snort/system-react";
import { findTag, toAddress, getTagValues } from "utils"; import { findTag, toAddress, getTagValues } from "utils";
import { System } from "index";
import type { Badge } from "types"; import type { Badge } from "types";
export function useBadges( export function useBadges(
pubkey: string, pubkey: string,
since: number, since: number,
leaveOpen = true leaveOpen = true
): { badges: Badge[]; awards: TaggedRawEvent[] } { ): { badges: Badge[]; awards: TaggedNostrEvent[] } {
const rb = useMemo(() => { const rb = useMemo(() => {
const rb = new RequestBuilder(`badges:${pubkey.slice(0, 12)}`); const rb = new RequestBuilder(`badges:${pubkey.slice(0, 12)}`);
rb.withOptions({ leaveOpen }); rb.withOptions({ leaveOpen });
@ -28,11 +27,7 @@ export function useBadges(
return rb; return rb;
}, [pubkey, since]); }, [pubkey, since]);
const { data: badgeEvents } = useRequestBuilder<NoteCollection>( const { data: badgeEvents } = useRequestBuilder(NoteCollection, rb);
System,
NoteCollection,
rb
);
const rawBadges = useMemo(() => { const rawBadges = useMemo(() => {
if (badgeEvents) { if (badgeEvents) {
@ -59,11 +54,7 @@ export function useBadges(
return rb; return rb;
}, [rawBadges]); }, [rawBadges]);
const acceptedStream = useRequestBuilder<NoteCollection>( const acceptedStream = useRequestBuilder(NoteCollection, acceptedSub);
System,
NoteCollection,
acceptedSub
);
const acceptedEvents = acceptedStream.data ?? []; const acceptedEvents = acceptedStream.data ?? [];
const badges = useMemo(() => { const badges = useMemo(() => {

View File

@ -1,7 +1,7 @@
import { useMemo } from "react"; import { useMemo } from "react";
import { import {
TaggedRawEvent, TaggedNostrEvent,
ReplaceableNoteStore, ReplaceableNoteStore,
NoteCollection, NoteCollection,
RequestBuilder, RequestBuilder,
@ -10,13 +10,12 @@ import { useRequestBuilder } from "@snort/system-react";
import { USER_CARDS, CARD } from "const"; import { USER_CARDS, CARD } from "const";
import { findTag } from "utils"; import { findTag } from "utils";
import { System } from "index";
export function useUserCards( export function useUserCards(
pubkey: string, pubkey: string,
userCards: Array<string[]>, userCards: Array<string[]>,
leaveOpen = false leaveOpen = false
): TaggedRawEvent[] { ): TaggedNostrEvent[] {
const related = useMemo(() => { const related = useMemo(() => {
// filtering to only show CARD kinds for now, but in the future we could link and render anything // filtering to only show CARD kinds for now, but in the future we could link and render anything
if (userCards?.length > 0) { if (userCards?.length > 0) {
@ -49,11 +48,7 @@ export function useUserCards(
return rb; return rb;
}, [pubkey, related]); }, [pubkey, related]);
const { data } = useRequestBuilder<NoteCollection>( const { data } = useRequestBuilder(NoteCollection, subRelated);
System,
NoteCollection,
subRelated
);
const cards = useMemo(() => { const cards = useMemo(() => {
return related return related
@ -68,13 +63,16 @@ export function useUserCards(
); );
}) })
.filter((e) => e) .filter((e) => e)
.map((e) => e as TaggedRawEvent); .map((e) => e as TaggedNostrEvent);
}, [related, data]); }, [related, data]);
return cards; return cards;
} }
export function useCards(pubkey: string, leaveOpen = false): TaggedRawEvent[] { export function useCards(
pubkey: string,
leaveOpen = false
): TaggedNostrEvent[] {
const sub = useMemo(() => { const sub = useMemo(() => {
const b = new RequestBuilder(`user-cards:${pubkey.slice(0, 12)}`); const b = new RequestBuilder(`user-cards:${pubkey.slice(0, 12)}`);
b.withOptions({ b.withOptions({
@ -86,11 +84,7 @@ export function useCards(pubkey: string, leaveOpen = false): TaggedRawEvent[] {
return b; return b;
}, [pubkey, leaveOpen]); }, [pubkey, leaveOpen]);
const { data: userCards } = useRequestBuilder<ReplaceableNoteStore>( const { data: userCards } = useRequestBuilder(ReplaceableNoteStore, sub);
System,
ReplaceableNoteStore,
sub
);
const related = useMemo(() => { const related = useMemo(() => {
// filtering to only show CARD kinds for now, but in the future we could link and render anything // filtering to only show CARD kinds for now, but in the future we could link and render anything
@ -124,11 +118,7 @@ export function useCards(pubkey: string, leaveOpen = false): TaggedRawEvent[] {
return rb; return rb;
}, [pubkey, related]); }, [pubkey, related]);
const { data } = useRequestBuilder<NoteCollection>( const { data } = useRequestBuilder(NoteCollection, subRelated);
System,
NoteCollection,
subRelated
);
const cardEvents = data ?? []; const cardEvents = data ?? [];
const cards = useMemo(() => { const cards = useMemo(() => {
@ -144,7 +134,7 @@ export function useCards(pubkey: string, leaveOpen = false): TaggedRawEvent[] {
); );
}) })
.filter((e) => e) .filter((e) => e)
.map((e) => e as TaggedRawEvent); .map((e) => e as TaggedNostrEvent);
}, [related, cardEvents]); }, [related, cardEvents]);
return cards; return cards;

View File

@ -5,11 +5,10 @@ import {
NostrPrefix, NostrPrefix,
NoteCollection, NoteCollection,
RequestBuilder, RequestBuilder,
TaggedRawEvent, TaggedNostrEvent,
} from "@snort/system"; } from "@snort/system";
import { useRequestBuilder } from "@snort/system-react"; import { useRequestBuilder } from "@snort/system-react";
import { LIVE_STREAM } from "const"; import { LIVE_STREAM } from "const";
import { System } from "index";
import { useMemo } from "react"; import { useMemo } from "react";
export function useCurrentStreamFeed( export function useCurrentStreamFeed(
@ -42,10 +41,10 @@ export function useCurrentStreamFeed(
return b; return b;
}, [link.id, leaveOpen]); }, [link.id, leaveOpen]);
const q = useRequestBuilder(System, NoteCollection, sub); const q = useRequestBuilder(NoteCollection, sub);
if (evPreload) { if (evPreload) {
q.add(evPreload as TaggedRawEvent); q.add(evPreload as TaggedNostrEvent);
} }
return useMemo(() => { return useMemo(() => {

View File

@ -8,7 +8,6 @@ import {
NostrEvent, NostrEvent,
} from "@snort/system"; } from "@snort/system";
import { useRequestBuilder } from "@snort/system-react"; import { useRequestBuilder } from "@snort/system-react";
import { System } from "index";
import { findTag } from "utils"; import { findTag } from "utils";
import { EMOJI_PACK, USER_EMOJIS } from "const"; import { EMOJI_PACK, USER_EMOJIS } from "const";
import type { EmojiPack, Tags, EmojiTag } from "types"; import type { EmojiPack, Tags, EmojiTag } from "types";
@ -64,11 +63,7 @@ export function useUserEmojiPacks(pubkey?: string, userEmoji?: Tags) {
return rb; return rb;
}, [pubkey, related]); }, [pubkey, related]);
const { data: relatedData } = useRequestBuilder<NoteCollection>( const { data: relatedData } = useRequestBuilder(NoteCollection, subRelated);
System,
NoteCollection,
subRelated
);
const emojiPacks = useMemo(() => { const emojiPacks = useMemo(() => {
return relatedData ?? []; return relatedData ?? [];
@ -92,11 +87,7 @@ export default function useEmoji(pubkey?: string) {
return rb; return rb;
}, [pubkey]); }, [pubkey]);
const { data: userEmoji } = useRequestBuilder<ReplaceableNoteStore>( const { data: userEmoji } = useRequestBuilder(ReplaceableNoteStore, sub);
System,
ReplaceableNoteStore,
sub
);
const emojis = useUserEmojiPacks(pubkey, userEmoji?.tags ?? []); const emojis = useUserEmojiPacks(pubkey, userEmoji?.tags ?? []);
return emojis; return emojis;

View File

@ -7,8 +7,6 @@ import {
} from "@snort/system"; } from "@snort/system";
import { useRequestBuilder } from "@snort/system-react"; import { useRequestBuilder } from "@snort/system-react";
import { System } from "index";
export default function useEventFeed(link: NostrLink, leaveOpen = false) { export default function useEventFeed(link: NostrLink, leaveOpen = false) {
const sub = useMemo(() => { const sub = useMemo(() => {
const b = new RequestBuilder(`event:${link.id.slice(0, 12)}`); const b = new RequestBuilder(`event:${link.id.slice(0, 12)}`);
@ -35,9 +33,5 @@ export default function useEventFeed(link: NostrLink, leaveOpen = false) {
return b; return b;
}, [link, leaveOpen]); }, [link, leaveOpen]);
return useRequestBuilder<ReplaceableNoteStore>( return useRequestBuilder(ReplaceableNoteStore, sub);
System,
ReplaceableNoteStore,
sub
);
} }

View File

@ -8,8 +8,6 @@ import {
} from "@snort/system"; } from "@snort/system";
import { useRequestBuilder } from "@snort/system-react"; import { useRequestBuilder } from "@snort/system-react";
import { System } from "index";
export function useAddress(kind: number, pubkey: string, identifier: string) { export function useAddress(kind: number, pubkey: string, identifier: string) {
const sub = useMemo(() => { const sub = useMemo(() => {
const b = new RequestBuilder(`event:${kind}:${identifier}`); const b = new RequestBuilder(`event:${kind}:${identifier}`);
@ -17,11 +15,7 @@ export function useAddress(kind: number, pubkey: string, identifier: string) {
return b; return b;
}, [kind, pubkey, identifier]); }, [kind, pubkey, identifier]);
const { data } = useRequestBuilder<ReplaceableNoteStore>( const { data } = useRequestBuilder(ReplaceableNoteStore, sub);
System,
ReplaceableNoteStore,
sub
);
return data; return data;
} }
@ -49,11 +43,7 @@ export function useEvent(link: NostrLink) {
return b; return b;
}, [link]); }, [link]);
const { data } = useRequestBuilder<ReplaceableNoteStore>( const { data } = useRequestBuilder(ReplaceableNoteStore, sub);
System,
ReplaceableNoteStore,
sub
);
return data; return data;
} }

View File

@ -24,11 +24,7 @@ export function useZaps(goal: NostrEvent, leaveOpen = false) {
return b; return b;
}, [goal, leaveOpen]); }, [goal, leaveOpen]);
const { data } = useRequestBuilder<NoteCollection>( const { data } = useRequestBuilder(NoteCollection, sub);
System,
NoteCollection,
sub
);
return ( return (
data data
@ -49,11 +45,7 @@ export function useZapGoal(host: string, link?: NostrLink, leaveOpen = false) {
return b; return b;
}, [link, leaveOpen]); }, [link, leaveOpen]);
const { data } = useRequestBuilder<ReplaceableNoteStore>( const { data } = useRequestBuilder(ReplaceableNoteStore, sub);
System,
ReplaceableNoteStore,
sub
);
return data; return data;
} }

View File

@ -5,7 +5,6 @@ import { useRequestBuilder } from "@snort/system-react";
import { MUTED } from "const"; import { MUTED } from "const";
import { getTagValues } from "utils"; import { getTagValues } from "utils";
import { System } from "index";
export function useMutedPubkeys(host?: string, leaveOpen = false) { export function useMutedPubkeys(host?: string, leaveOpen = false) {
const mutedSub = useMemo(() => { const mutedSub = useMemo(() => {
@ -16,11 +15,7 @@ export function useMutedPubkeys(host?: string, leaveOpen = false) {
return rb; return rb;
}, [host]); }, [host]);
const { data: muted } = useRequestBuilder<ReplaceableNoteStore>( const { data: muted } = useRequestBuilder(ReplaceableNoteStore, mutedSub);
System,
ReplaceableNoteStore,
mutedSub
);
const mutedPubkeys = useMemo(() => { const mutedPubkeys = useMemo(() => {
return new Set(getTagValues(muted?.tags ?? [], "p")); return new Set(getTagValues(muted?.tags ?? [], "p"));
}, [muted]); }, [muted]);

View File

@ -2,11 +2,10 @@ import {
NostrLink, NostrLink,
RequestBuilder, RequestBuilder,
EventKind, EventKind,
FlatNoteStore, NoteCollection,
} from "@snort/system"; } from "@snort/system";
import { useRequestBuilder } from "@snort/system-react"; import { useRequestBuilder } from "@snort/system-react";
import { unixNow } from "@snort/shared"; import { unixNow } from "@snort/shared";
import { System } from "index";
import { useMemo } from "react"; import { useMemo } from "react";
import { LIVE_STREAM_CHAT, WEEK } from "const"; import { LIVE_STREAM_CHAT, WEEK } from "const";
@ -27,7 +26,7 @@ export function useLiveChatFeed(link: NostrLink, eZaps?: Array<string>) {
return rb; return rb;
}, [link.id, since, eZaps]); }, [link.id, since, eZaps]);
const feed = useRequestBuilder<FlatNoteStore>(System, FlatNoteStore, sub); const feed = useRequestBuilder(NoteCollection, sub);
const messages = useMemo(() => { const messages = useMemo(() => {
return (feed.data ?? []).filter((ev) => ev.kind === LIVE_STREAM_CHAT); return (feed.data ?? []).filter((ev) => ev.kind === LIVE_STREAM_CHAT);
@ -52,11 +51,7 @@ export function useLiveChatFeed(link: NostrLink, eZaps?: Array<string>) {
return rb; return rb;
}, [etags]); }, [etags]);
const reactionsSub = useRequestBuilder<FlatNoteStore>( const reactionsSub = useRequestBuilder(NoteCollection, esub);
System,
FlatNoteStore,
esub
);
const reactions = reactionsSub.data ?? []; const reactions = reactionsSub.data ?? [];

View File

@ -5,7 +5,7 @@ import { useRequestBuilder } from "@snort/system-react";
import { unixNow } from "@snort/shared"; import { unixNow } from "@snort/shared";
import { LIVE_STREAM } from "const"; import { LIVE_STREAM } from "const";
import { System, StreamState } from "index"; import { StreamState } from "index";
import { findTag } from "utils"; import { findTag } from "utils";
import { WEEK } from "const"; import { WEEK } from "const";
@ -34,7 +34,7 @@ export function useStreamsFeed(tag?: string) {
return bStart > aStart ? 1 : -1; return bStart > aStart ? 1 : -1;
} }
const feed = useRequestBuilder<NoteCollection>(System, NoteCollection, rb); const feed = useRequestBuilder(NoteCollection, rb);
const feedSorted = useMemo(() => { const feedSorted = useMemo(() => {
if (feed.data) { if (feed.data) {
if (__XXX) { if (__XXX) {

View File

@ -6,8 +6,8 @@ import { useRequestBuilder } from "@snort/system-react";
import { useUserEmojiPacks } from "hooks/emoji"; import { useUserEmojiPacks } from "hooks/emoji";
import { MUTED, USER_CARDS, USER_EMOJIS } from "const"; import { MUTED, USER_CARDS, USER_EMOJIS } from "const";
import type { Tags } from "types"; import type { Tags } from "types";
import { System, Login } from "index";
import { getPublisher } from "login"; import { getPublisher } from "login";
import { Login } from "index";
export function useLogin() { export function useLogin() {
const session = useSyncExternalStore( const session = useSyncExternalStore(
@ -42,11 +42,7 @@ export function useLoginEvents(pubkey?: string, leaveOpen = false) {
return b; return b;
}, [pubkey, leaveOpen]); }, [pubkey, leaveOpen]);
const { data } = useRequestBuilder<NoteCollection>( const { data } = useRequestBuilder(NoteCollection, sub);
System,
NoteCollection,
sub
);
useEffect(() => { useEffect(() => {
if (!data) { if (!data) {

View File

@ -1,7 +1,6 @@
import { useMemo } from "react"; import { useMemo } from "react";
import { import {
RequestBuilder, RequestBuilder,
FlatNoteStore,
NoteCollection, NoteCollection,
NostrLink, NostrLink,
EventKind, EventKind,
@ -27,11 +26,7 @@ export function useProfile(link: NostrLink, leaveOpen = false) {
return b; return b;
}, [link, leaveOpen]); }, [link, leaveOpen]);
const { data: streamsData } = useRequestBuilder<NoteCollection>( const { data: streamsData } = useRequestBuilder(NoteCollection, sub);
System,
NoteCollection,
sub
);
const streams = streamsData ?? []; const streams = streamsData ?? [];
const addresses = useMemo(() => { const addresses = useMemo(() => {
@ -52,11 +47,7 @@ export function useProfile(link: NostrLink, leaveOpen = false) {
return b; return b;
}, [link, addresses, leaveOpen]); }, [link, addresses, leaveOpen]);
const { data: zapsData } = useRequestBuilder<FlatNoteStore>( const { data: zapsData } = useRequestBuilder(NoteCollection, zapsSub);
System,
FlatNoteStore,
zapsSub
);
const zaps = (zapsData ?? []) const zaps = (zapsData ?? [])
.map((ev) => parseZap(ev, System.ProfileLoader.Cache)) .map((ev) => parseZap(ev, System.ProfileLoader.Cache))
.filter((z) => z && z.valid && z.receiver === link.id); .filter((z) => z && z.valid && z.receiver === link.id);

View File

@ -17,6 +17,7 @@ import { LoginStore } from "login";
import { StreamProvidersPage } from "pages/providers"; import { StreamProvidersPage } from "pages/providers";
import { defaultRelays } from "const"; import { defaultRelays } from "const";
import { CatchAllRoutePage } from "pages/catch-all"; import { CatchAllRoutePage } from "pages/catch-all";
import { SnortContext } from "@snort/system-react";
export enum StreamState { export enum StreamState {
Live = "live", Live = "live",
@ -76,6 +77,8 @@ const root = ReactDOM.createRoot(
); );
root.render( root.render(
<React.StrictMode> <React.StrictMode>
<RouterProvider router={router} /> <SnortContext.Provider value={System}>
<RouterProvider router={router} />
</SnortContext.Provider>
</React.StrictMode> </React.StrictMode>
); );

View File

@ -21,7 +21,7 @@ import { useProfile } from "hooks/profile";
import useTopZappers from "hooks/top-zappers"; import useTopZappers from "hooks/top-zappers";
import usePlaceholder from "hooks/placeholders"; import usePlaceholder from "hooks/placeholders";
import { Text } from "element/text"; import { Text } from "element/text";
import { StreamState, System } from "index"; import { StreamState } from "index";
import { findTag } from "utils"; import { findTag } from "utils";
import { formatSats } from "number"; import { formatSats } from "number";
@ -55,7 +55,7 @@ export function ProfilePage() {
const params = useParams(); const params = useParams();
const link = parseNostrLink(unwrap(params.npub)); const link = parseNostrLink(unwrap(params.npub));
const placeholder = usePlaceholder(link.id); const placeholder = usePlaceholder(link.id);
const profile = useUserProfile(System, link.id); const profile = useUserProfile(link.id);
const zapTarget = profile?.lud16 ?? profile?.lud06; const zapTarget = profile?.lud16 ?? profile?.lud06;
const { streams, zaps } = useProfile(link, true); const { streams, zaps } = useProfile(link, true);
const liveEvent = useMemo(() => { const liveEvent = useMemo(() => {

View File

@ -1,5 +1,10 @@
import "./stream-page.css"; import "./stream-page.css";
import { NostrLink, NostrPrefix, TaggedRawEvent, tryParseNostrLink } from "@snort/system"; import {
NostrLink,
NostrPrefix,
TaggedNostrEvent,
tryParseNostrLink,
} from "@snort/system";
import { fetchNip05Pubkey } from "@snort/shared"; import { fetchNip05Pubkey } from "@snort/shared";
import { useLocation, useNavigate, useParams } from "react-router-dom"; import { useLocation, useNavigate, useParams } from "react-router-dom";
import { Helmet } from "react-helmet"; import { Helmet } from "react-helmet";
@ -35,11 +40,17 @@ import {
import { useCurrentStreamFeed } from "hooks/current-stream-feed"; import { useCurrentStreamFeed } from "hooks/current-stream-feed";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
function ProfileInfo({ ev, goal }: { ev?: NostrEvent; goal?: TaggedRawEvent }) { function ProfileInfo({
ev,
goal,
}: {
ev?: NostrEvent;
goal?: TaggedNostrEvent;
}) {
const login = useLogin(); const login = useLogin();
const navigate = useNavigate(); const navigate = useNavigate();
const host = getHost(ev); const host = getHost(ev);
const profile = useUserProfile(System, host); const profile = useUserProfile(host);
const zapTarget = profile?.lud16 ?? profile?.lud06; const zapTarget = profile?.lud16 ?? profile?.lud06;
const status = findTag(ev, "status") ?? ""; const status = findTag(ev, "status") ?? "";
@ -125,26 +136,34 @@ export function StreamPageHandler() {
if (parsedLink) { if (parsedLink) {
setLink(parsedLink); setLink(parsedLink);
} else { } else {
const [handle, domain] = (params.id.includes("@") ? params.id : `${params.id}@zap.stream`).split("@"); const [handle, domain] = (
fetchNip05Pubkey(handle, domain).then(d => { params.id.includes("@") ? params.id : `${params.id}@zap.stream`
).split("@");
fetchNip05Pubkey(handle, domain).then((d) => {
if (d) { if (d) {
setLink({ setLink({
id: d, id: d,
type: NostrPrefix.PublicKey, type: NostrPrefix.PublicKey,
encode: () => hexToBech32(NostrPrefix.PublicKey, d) encode: () => hexToBech32(NostrPrefix.PublicKey, d),
} as NostrLink); } as NostrLink);
} }
}) });
} }
} }
}, [params.id]); }, [params.id]);
if (link) { if (link) {
return <StreamPage link={link} evPreload={evPreload} /> return <StreamPage link={link} evPreload={evPreload} />;
} }
} }
export function StreamPage({ link, evPreload }: { evPreload?: NostrEvent, link: NostrLink }) { export function StreamPage({
link,
evPreload,
}: {
evPreload?: NostrEvent;
link: NostrLink;
}) {
const ev = useCurrentStreamFeed(link, true, evPreload); const ev = useCurrentStreamFeed(link, true, evPreload);
const host = getHost(ev); const host = getHost(ev);
const goal = useZapGoal(host, createNostrLink(ev), true); const goal = useZapGoal(host, createNostrLink(ev), true);

View File

@ -1,39 +1,14 @@
/// <reference lib="webworker" /> /// <reference lib="webworker" />
import {} from "."; declare const self: ServiceWorkerGlobalScope & {
declare const self: ServiceWorkerGlobalScope; __WB_MANIFEST: (string | PrecacheEntry)[];
};
import { clientsClaim } from "workbox-core"; import { clientsClaim } from "workbox-core";
import { registerRoute } from "workbox-routing"; import { PrecacheEntry, precacheAndRoute } from "workbox-precaching";
import { CacheFirst } from "workbox-strategies";
precacheAndRoute(self.__WB_MANIFEST);
clientsClaim(); clientsClaim();
const staticTypes = ["image", "video", "audio", "script", "style", "font"];
registerRoute(
({ request, url }) =>
url.origin === self.location.origin &&
staticTypes.includes(request.destination),
new CacheFirst({
cacheName: "static-content",
})
);
// External media domains which have unique urls (never changing content) and can be cached forever
const externalMediaHosts = [
"void.cat",
"nostr.build",
"imgur.com",
"i.imgur.com",
"pbs.twimg.com",
"i.ibb.co",
];
registerRoute(
({ url }) => externalMediaHosts.includes(url.host),
new CacheFirst({
cacheName: "ext-content-hosts",
})
);
self.addEventListener("message", (event) => { self.addEventListener("message", (event) => {
if (event.data && event.data.type === "SKIP_WAITING") { if (event.data && event.data.type === "SKIP_WAITING") {
self.skipWaiting(); self.skipWaiting();

View File

@ -1,7 +1,7 @@
import { import {
NostrEvent, NostrEvent,
NostrPrefix, NostrPrefix,
TaggedRawEvent, TaggedNostrEvent,
encodeTLV, encodeTLV,
parseNostrLink, parseNostrLink,
} from "@snort/system"; } from "@snort/system";
@ -77,7 +77,7 @@ export function splitByUrl(str: string) {
return str.split(urlRegex); return str.split(urlRegex);
} }
export function eventLink(ev: NostrEvent | TaggedRawEvent) { export function eventLink(ev: NostrEvent | TaggedNostrEvent) {
if (ev.kind && ev.kind >= 30000 && ev.kind <= 40000) { if (ev.kind && ev.kind >= 30000 && ev.kind <= 40000) {
const d = findTag(ev, "d") ?? ""; const d = findTag(ev, "d") ?? "";
return encodeTLV( return encodeTLV(

View File

@ -8,16 +8,14 @@ const ESLintPlugin = require("eslint-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin"); const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin"); const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
const CopyPlugin = require("copy-webpack-plugin"); const CopyPlugin = require("copy-webpack-plugin");
const WorkboxPlugin = require("workbox-webpack-plugin");
const IntlTsTransformer = require("@formatjs/ts-transformer");
const isProduction = process.env.NODE_ENV == "production"; const isProduction = process.env.NODE_ENV == "production";
const config = { const config = {
entry: { entry: {
main: "./src/index.tsx", main: "./src/index.tsx",
sw: {
import: "./src/service-worker.ts",
filename: "service-worker.js",
},
}, },
target: "browserslist", target: "browserslist",
mode: isProduction ? "production" : "development", mode: isProduction ? "production" : "development",
@ -25,12 +23,7 @@ const config = {
output: { output: {
publicPath: "/", publicPath: "/",
path: path.resolve(__dirname, "build"), path: path.resolve(__dirname, "build"),
filename: ({ runtime }) => { filename: isProduction ? "[name].[chunkhash].js" : "[name].js",
if (runtime === "sw") {
return "[name].js";
}
return isProduction ? "[name].[chunkhash].js" : "[name].js";
},
clean: isProduction, clean: isProduction,
}, },
devServer: { devServer: {
@ -51,12 +44,11 @@ const config = {
new HtmlWebpackPlugin({ new HtmlWebpackPlugin({
template: "public/index.html", template: "public/index.html",
favicon: "public/favicon.ico", favicon: "public/favicon.ico",
excludeChunks: ["sw"],
}), }),
new ESLintPlugin({ new ESLintPlugin({
extensions: ["js", "mjs", "jsx", "ts", "tsx"], extensions: ["js", "mjs", "jsx", "ts", "tsx"],
eslintPath: require.resolve("eslint"), eslintPath: require.resolve("eslint"),
failOnError: !isProduction, failOnError: true,
cache: true, cache: true,
}), }),
new MiniCssExtractPlugin({ new MiniCssExtractPlugin({
@ -70,6 +62,9 @@ const config = {
__XXX: process.env["__XXX"] || JSON.stringify(false), __XXX: process.env["__XXX"] || JSON.stringify(false),
__XXX_HOST: JSON.stringify("https://xxzap.com"), __XXX_HOST: JSON.stringify("https://xxzap.com"),
}), }),
new WorkboxPlugin.InjectManifest({
swSrc: "./src/service-worker.ts",
}),
], ],
module: { module: {
rules: [ rules: [
@ -89,27 +84,26 @@ const config = {
babelrc: false, babelrc: false,
configFile: false, configFile: false,
presets: [ presets: [
[ ["@babel/preset-env"],
"@babel/preset-env",
{
targets: "defaults",
},
],
["@babel/preset-react", { runtime: "automatic" }], ["@babel/preset-react", { runtime: "automatic" }],
"@babel/preset-typescript",
],
plugins: [
[
"formatjs",
{
idInterpolationPattern: "[sha512:contenthash:base64:6]",
ast: true,
},
],
], ],
}, },
}, },
require.resolve("ts-loader"), {
loader: require.resolve("ts-loader"),
options: {
getCustomTransformers() {
return {
before: [
IntlTsTransformer.transform({
overrideIdFn: "[sha512:contenthash:base64:6]",
ast: true,
}),
],
};
},
},
},
], ],
}, },
{ {

2085
yarn.lock

File diff suppressed because it is too large Load Diff