mirror of
https://github.com/PrimalHQ/primal-web-app.git
synced 2024-10-01 17:31:13 +00:00
Remove general upload scoket
This commit is contained in:
parent
d6448040e9
commit
8e0e28b79d
@ -1,8 +1,6 @@
|
|||||||
import { Component, onCleanup, onMount } from 'solid-js';
|
import { Component, onCleanup, onMount } from 'solid-js';
|
||||||
import { AccountProvider } from './contexts/AccountContext';
|
import { AccountProvider } from './contexts/AccountContext';
|
||||||
import { connect, disconnect } from './sockets';
|
import { connect, disconnect } from './sockets';
|
||||||
import { connect as uploadConnect, disconnect as uploadDisconnet } from './uploadSocket';
|
|
||||||
import styles from './App.module.scss';
|
|
||||||
import Toaster from './components/Toaster/Toaster';
|
import Toaster from './components/Toaster/Toaster';
|
||||||
import { HomeProvider } from './contexts/HomeContext';
|
import { HomeProvider } from './contexts/HomeContext';
|
||||||
import { ExploreProvider } from './contexts/ExploreContext';
|
import { ExploreProvider } from './contexts/ExploreContext';
|
||||||
@ -23,12 +21,10 @@ const App: Component = () => {
|
|||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
connect();
|
connect();
|
||||||
uploadConnect();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
onCleanup(() => {
|
onCleanup(() => {
|
||||||
disconnect();
|
disconnect();
|
||||||
uploadDisconnet();
|
|
||||||
})
|
})
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -2,7 +2,7 @@ import { useIntl } from "@cookbook/solid-intl";
|
|||||||
import { Router, useLocation } from "@solidjs/router";
|
import { Router, useLocation } from "@solidjs/router";
|
||||||
import { nip19 } from "nostr-tools";
|
import { nip19 } from "nostr-tools";
|
||||||
import { Component, createEffect, createSignal, For, onCleanup, onMount, Show } from "solid-js";
|
import { Component, createEffect, createSignal, For, onCleanup, onMount, Show } from "solid-js";
|
||||||
import { createStore, reconcile, unwrap } from "solid-js/store";
|
import { createStore, unwrap } from "solid-js/store";
|
||||||
import { noteRegex, profileRegex, Kind, editMentionRegex, emojiSearchLimit } from "../../../constants";
|
import { noteRegex, profileRegex, Kind, editMentionRegex, emojiSearchLimit } from "../../../constants";
|
||||||
import { useAccountContext } from "../../../contexts/AccountContext";
|
import { useAccountContext } from "../../../contexts/AccountContext";
|
||||||
import { useSearchContext } from "../../../contexts/SearchContext";
|
import { useSearchContext } from "../../../contexts/SearchContext";
|
||||||
@ -11,10 +11,9 @@ import { getEvents } from "../../../lib/feed";
|
|||||||
import { parseNote1, sanitize, sendNote, replaceLinkPreviews, importEvents } from "../../../lib/notes";
|
import { parseNote1, sanitize, sendNote, replaceLinkPreviews, importEvents } from "../../../lib/notes";
|
||||||
import { getUserProfiles } from "../../../lib/profile";
|
import { getUserProfiles } from "../../../lib/profile";
|
||||||
import { subscribeTo } from "../../../sockets";
|
import { subscribeTo } from "../../../sockets";
|
||||||
import { subscribeTo as uploadSub, uploadServer } from "../../../uploadSocket";
|
|
||||||
import { convertToNotes, referencesToTags } from "../../../stores/note";
|
import { convertToNotes, referencesToTags } from "../../../stores/note";
|
||||||
import { convertToUser, nip05Verification, truncateNpub, userName } from "../../../stores/profile";
|
import { convertToUser, nip05Verification, truncateNpub, userName } from "../../../stores/profile";
|
||||||
import { EmojiOption, FeedPage, NostrEOSE, NostrEvent, NostrEventContent, NostrEventType, NostrMediaUploaded, NostrMentionContent, NostrNoteContent, NostrStatsContent, NostrUserContent, PrimalNote, PrimalUser, SendNoteResult } from "../../../types/primal";
|
import { EmojiOption, FeedPage, NostrMentionContent, NostrNoteContent, NostrStatsContent, NostrUserContent, PrimalNote, PrimalUser, SendNoteResult } from "../../../types/primal";
|
||||||
import { debounce, getScreenCordinates, isVisibleInContainer, uuidv4 } from "../../../utils";
|
import { debounce, getScreenCordinates, isVisibleInContainer, uuidv4 } from "../../../utils";
|
||||||
import Avatar from "../../Avatar/Avatar";
|
import Avatar from "../../Avatar/Avatar";
|
||||||
import EmbeddedNote from "../../EmbeddedNote/EmbeddedNote";
|
import EmbeddedNote from "../../EmbeddedNote/EmbeddedNote";
|
||||||
@ -24,9 +23,7 @@ import { useToastContext } from "../../Toaster/Toaster";
|
|||||||
import styles from './EditBox.module.scss';
|
import styles from './EditBox.module.scss';
|
||||||
import emojiSearch from '@jukben/emoji-search';
|
import emojiSearch from '@jukben/emoji-search';
|
||||||
import { getCaretCoordinates } from "../../../lib/textArea";
|
import { getCaretCoordinates } from "../../../lib/textArea";
|
||||||
import { startTimes, uploadMedia, uploadMediaCancel, uploadMediaChunk, uploadMediaConfirm } from "../../../lib/media";
|
|
||||||
import { APP_ID } from "../../../App";
|
import { APP_ID } from "../../../App";
|
||||||
import Loader from "../../Loader/Loader";
|
|
||||||
import {
|
import {
|
||||||
toast as tToast,
|
toast as tToast,
|
||||||
feedback as tFeedback,
|
feedback as tFeedback,
|
||||||
@ -43,8 +40,7 @@ import { useProfileContext } from "../../../contexts/ProfileContext";
|
|||||||
import ButtonGhost from "../../Buttons/ButtonGhost";
|
import ButtonGhost from "../../Buttons/ButtonGhost";
|
||||||
import EmojiPickPopover from "../../EmojiPickModal/EmojiPickPopover";
|
import EmojiPickPopover from "../../EmojiPickModal/EmojiPickPopover";
|
||||||
import ConfirmAlternativeModal from "../../ConfirmModal/ConfirmAlternativeModal";
|
import ConfirmAlternativeModal from "../../ConfirmModal/ConfirmAlternativeModal";
|
||||||
import { readNoteDraft, readUploadTime, saveNoteDraft, saveUploadTime } from "../../../lib/localStore";
|
import { readNoteDraft, saveNoteDraft } from "../../../lib/localStore";
|
||||||
import { Progress } from "@kobalte/core";
|
|
||||||
import Uploader from "../../Uploader/Uploader";
|
import Uploader from "../../Uploader/Uploader";
|
||||||
|
|
||||||
type AutoSizedTextArea = HTMLTextAreaElement & { _baseScrollHeight: number };
|
type AutoSizedTextArea = HTMLTextAreaElement & { _baseScrollHeight: number };
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { Component, createEffect, JSXElement, onCleanup, Show } from 'solid-js';
|
import { Component, createEffect, onCleanup, Show } from 'solid-js';
|
||||||
import { Progress, TextField } from '@kobalte/core';
|
import { Progress } from '@kobalte/core';
|
||||||
|
|
||||||
import styles from './Uploader.module.scss';
|
import styles from './Uploader.module.scss';
|
||||||
import { uploadServer } from '../../uploadSocket';
|
import { uploadServer } from '../../uploadSocket';
|
||||||
@ -9,7 +9,6 @@ import { readUploadTime, saveUploadTime } from '../../lib/localStore';
|
|||||||
import { startTimes, uploadMediaCancel, uploadMediaChunk, uploadMediaConfirm } from '../../lib/media';
|
import { startTimes, uploadMediaCancel, uploadMediaChunk, uploadMediaConfirm } from '../../lib/media';
|
||||||
import { sha256, uuidv4 } from '../../utils';
|
import { sha256, uuidv4 } from '../../utils';
|
||||||
import { Kind } from '../../constants';
|
import { Kind } from '../../constants';
|
||||||
import { account } from '../../translations';
|
|
||||||
import ButtonGhost from '../Buttons/ButtonGhost';
|
import ButtonGhost from '../Buttons/ButtonGhost';
|
||||||
|
|
||||||
const MB = 1024 * 1024;
|
const MB = 1024 * 1024;
|
||||||
@ -94,7 +93,6 @@ const Uploader: Component<{
|
|||||||
sockets[i] = newSocket;
|
sockets[i] = newSocket;
|
||||||
|
|
||||||
const chunkIndex = uploadsInProgress[i];
|
const chunkIndex = uploadsInProgress[i];
|
||||||
console.log('REOPEN SOCKET: ', i, chunkIndex);
|
|
||||||
if (chunkIndex > 0) {
|
if (chunkIndex > 0) {
|
||||||
uploadChunk(chunkIndex);
|
uploadChunk(chunkIndex);
|
||||||
}
|
}
|
||||||
@ -110,15 +108,6 @@ const Uploader: Component<{
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
createEffect(() => {
|
|
||||||
if (props.file) {
|
|
||||||
setTimeout(() => {
|
|
||||||
const s = sockets[2];
|
|
||||||
s.close();
|
|
||||||
}, 500);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
onCleanup(() => {
|
onCleanup(() => {
|
||||||
sockets.forEach(s => s.close());
|
sockets.forEach(s => s.close());
|
||||||
sockets = [];
|
sockets = [];
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
import { Kind } from "../constants";
|
import { Kind } from "../constants";
|
||||||
import { messages } from "../translations";
|
|
||||||
import { sendMessage } from "../uploadSocket";
|
|
||||||
import { signEvent } from "./nostrAPI";
|
import { signEvent } from "./nostrAPI";
|
||||||
|
|
||||||
export const getMediaUrl = (url: string | undefined, size = 'o', animated = 1) => {
|
export const getMediaUrl = (url: string | undefined, size = 'o', animated = 1) => {
|
||||||
@ -20,38 +18,6 @@ export const getMediaUrl = (url: string | undefined, size = 'o', animated = 1) =
|
|||||||
|
|
||||||
export let startTimes: number[] = [];
|
export let startTimes: number[] = [];
|
||||||
|
|
||||||
export const uploadMedia = async (
|
|
||||||
uploader: string | undefined,
|
|
||||||
subid: string,
|
|
||||||
content: string,
|
|
||||||
) => {
|
|
||||||
if (!uploader) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const event = {
|
|
||||||
content,
|
|
||||||
kind: Kind.Upload,
|
|
||||||
tags: [['p', uploader]],
|
|
||||||
created_at: Math.floor((new Date()).getTime() / 1000),
|
|
||||||
};
|
|
||||||
|
|
||||||
try {
|
|
||||||
const signedNote = await signEvent(event);
|
|
||||||
|
|
||||||
sendMessage(JSON.stringify([
|
|
||||||
"REQ",
|
|
||||||
subid,
|
|
||||||
{cache: ["upload", { event_from_user: signedNote }]},
|
|
||||||
]));
|
|
||||||
|
|
||||||
return true;
|
|
||||||
} catch (reason) {
|
|
||||||
console.error('Failed to upload: ', reason);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export const uploadMediaChunk = async (
|
export const uploadMediaChunk = async (
|
||||||
uploader: string | undefined,
|
uploader: string | undefined,
|
||||||
subid: string,
|
subid: string,
|
||||||
@ -95,8 +61,7 @@ export const uploadMediaChunk = async (
|
|||||||
socket.send(message);
|
socket.send(message);
|
||||||
socket.dispatchEvent(e);
|
socket.dispatchEvent(e);
|
||||||
} else {
|
} else {
|
||||||
console.log('NO SOCKET')
|
throw('no_socket');
|
||||||
sendMessage(message);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -139,13 +104,12 @@ export const uploadMediaCancel = async (
|
|||||||
if (socket) {
|
if (socket) {
|
||||||
socket.send(message);
|
socket.send(message);
|
||||||
} else {
|
} else {
|
||||||
console.log('NO SOCKET')
|
throw('no_socket');
|
||||||
sendMessage(message);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} catch (reason) {
|
} catch (reason) {
|
||||||
console.error('Failed to upload: ', reason);
|
console.error('Failed to cancel upload: ', reason);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -185,13 +149,12 @@ export const uploadMediaConfirm = async (
|
|||||||
if (socket) {
|
if (socket) {
|
||||||
socket.send(message);
|
socket.send(message);
|
||||||
} else {
|
} else {
|
||||||
console.log('NO SOCKET')
|
throw('no_socket');
|
||||||
sendMessage(message);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} catch (reason) {
|
} catch (reason) {
|
||||||
console.error('Failed to upload: ', reason);
|
console.error('Failed to complete upload: ', reason);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,19 +1,16 @@
|
|||||||
import { useIntl } from '@cookbook/solid-intl';
|
import { useIntl } from '@cookbook/solid-intl';
|
||||||
import { useNavigate } from '@solidjs/router';
|
import { useNavigate } from '@solidjs/router';
|
||||||
import { Component, createEffect, createMemo, createSignal, For, Match, onCleanup, onMount, Show, Switch } from 'solid-js';
|
import { Component, createEffect, createSignal, For, Match, onCleanup, onMount, Show, Switch } from 'solid-js';
|
||||||
import { APP_ID } from '../App';
|
import { APP_ID } from '../App';
|
||||||
import Avatar from '../components/Avatar/Avatar';
|
import Avatar from '../components/Avatar/Avatar';
|
||||||
import Loader from '../components/Loader/Loader';
|
|
||||||
import PageCaption from '../components/PageCaption/PageCaption';
|
import PageCaption from '../components/PageCaption/PageCaption';
|
||||||
import PageTitle from '../components/PageTitle/PageTitle';
|
import PageTitle from '../components/PageTitle/PageTitle';
|
||||||
import { useToastContext } from '../components/Toaster/Toaster';
|
import { useToastContext } from '../components/Toaster/Toaster';
|
||||||
import { usernameRegex, Kind, suggestedUsersToFollow } from '../constants';
|
import { usernameRegex, Kind } from '../constants';
|
||||||
import { useAccountContext } from '../contexts/AccountContext';
|
import { useAccountContext } from '../contexts/AccountContext';
|
||||||
import { useMediaContext } from '../contexts/MediaContext';
|
import { useMediaContext } from '../contexts/MediaContext';
|
||||||
import { useProfileContext } from '../contexts/ProfileContext';
|
import { useProfileContext } from '../contexts/ProfileContext';
|
||||||
import { uploadMedia } from '../lib/media';
|
|
||||||
import { getProfileContactList, getSuggestions, getUserProfiles, sendProfile } from '../lib/profile';
|
import { getProfileContactList, getSuggestions, getUserProfiles, sendProfile } from '../lib/profile';
|
||||||
import { subscribeTo as uploadSub } from "../uploadSocket";
|
|
||||||
import {
|
import {
|
||||||
actions as tActions,
|
actions as tActions,
|
||||||
account as tAccount,
|
account as tAccount,
|
||||||
@ -21,24 +18,19 @@ import {
|
|||||||
toast as tToast,
|
toast as tToast,
|
||||||
upload as tUpload,
|
upload as tUpload,
|
||||||
} from '../translations';
|
} from '../translations';
|
||||||
import { NostrMediaUploaded, NostrRelays, NostrUserContent, PrimalUser, UserCategory } from '../types/primal';
|
import { NostrRelays, NostrUserContent, PrimalUser } from '../types/primal';
|
||||||
|
|
||||||
import styles from './CreateAccount.module.scss';
|
import styles from './CreateAccount.module.scss';
|
||||||
import { createStore, reconcile } from 'solid-js/store';
|
import { createStore, reconcile } from 'solid-js/store';
|
||||||
import { generateKeys, setTempNsec } from '../lib/PrimalNostr';
|
import { generateKeys, setTempNsec } from '../lib/PrimalNostr';
|
||||||
import { hexToNpub, hexToNsec } from '../lib/keys';
|
import { hexToNsec } from '../lib/keys';
|
||||||
import { storeSec } from '../lib/localStore';
|
import { storeSec } from '../lib/localStore';
|
||||||
import { getPreConfiguredRelays } from '../lib/relays';
|
|
||||||
import CreatePinModal from '../components/CreatePinModal/CreatePinModal';
|
import CreatePinModal from '../components/CreatePinModal/CreatePinModal';
|
||||||
import { useSearchContext } from '../contexts/SearchContext';
|
import { useSearchContext } from '../contexts/SearchContext';
|
||||||
import ButtonFollow from '../components/Buttons/ButtonFlip';
|
|
||||||
import ButtonTertiary from '../components/Buttons/ButtonTertiary';
|
|
||||||
import { sendContacts } from '../lib/notes';
|
import { sendContacts } from '../lib/notes';
|
||||||
import ButtonSecondary from '../components/Buttons/ButtonSecondary';
|
import ButtonSecondary from '../components/Buttons/ButtonSecondary';
|
||||||
import { convertToUser, nip05Verification, userName } from '../stores/profile';
|
import { convertToUser, nip05Verification, userName } from '../stores/profile';
|
||||||
import { subscribeTo } from '../sockets';
|
import { subscribeTo } from '../sockets';
|
||||||
import { arrayMerge } from '../utils';
|
|
||||||
import { stringStyleToObject } from '@solid-primitives/props';
|
|
||||||
import ButtonPrimary from '../components/Buttons/ButtonPrimary';
|
import ButtonPrimary from '../components/Buttons/ButtonPrimary';
|
||||||
import ButtonFlip from '../components/Buttons/ButtonFlip';
|
import ButtonFlip from '../components/Buttons/ButtonFlip';
|
||||||
import Uploader from '../components/Uploader/Uploader';
|
import Uploader from '../components/Uploader/Uploader';
|
||||||
|
@ -13,17 +13,11 @@ import Avatar from '../components/Avatar/Avatar';
|
|||||||
import { useProfileContext } from '../contexts/ProfileContext';
|
import { useProfileContext } from '../contexts/ProfileContext';
|
||||||
import { useMediaContext } from '../contexts/MediaContext';
|
import { useMediaContext } from '../contexts/MediaContext';
|
||||||
import { useAccountContext } from '../contexts/AccountContext';
|
import { useAccountContext } from '../contexts/AccountContext';
|
||||||
import { NostrMediaUploaded } from '../types/primal';
|
|
||||||
import { sendProfile } from '../lib/profile';
|
import { sendProfile } from '../lib/profile';
|
||||||
import { useToastContext } from '../components/Toaster/Toaster';
|
import { useToastContext } from '../components/Toaster/Toaster';
|
||||||
import { APP_ID } from '../App';
|
import { usernameRegex } from '../constants';
|
||||||
import { subscribeTo as uploadSub } from "../uploadSocket";
|
|
||||||
import { Kind, usernameRegex } from '../constants';
|
|
||||||
import { uploadMedia } from '../lib/media';
|
|
||||||
import Loader from '../components/Loader/Loader';
|
import Loader from '../components/Loader/Loader';
|
||||||
import { useNavigate } from '@solidjs/router';
|
import { useNavigate } from '@solidjs/router';
|
||||||
import Branding from '../components/Branding/Branding';
|
|
||||||
import Wormhole from '../components/Wormhole/Wormhole';
|
|
||||||
import PageTitle from '../components/PageTitle/PageTitle';
|
import PageTitle from '../components/PageTitle/PageTitle';
|
||||||
import ButtonPrimary from '../components/Buttons/ButtonPrimary';
|
import ButtonPrimary from '../components/Buttons/ButtonPrimary';
|
||||||
import ButtonSecondary from '../components/Buttons/ButtonSecondary';
|
import ButtonSecondary from '../components/Buttons/ButtonSecondary';
|
||||||
|
@ -1,113 +1,2 @@
|
|||||||
import { createSignal } from "solid-js";
|
export let uploadServer = localStorage.getItem('uploadServer') ||
|
||||||
import { NostrEvent, NostrEOSE, NostrEventType, NostrEventContent, PrimalWindow } from "./types/primal";
|
import.meta.env.PRIMAL_UPLOAD_URL;
|
||||||
|
|
||||||
export const [socket, setSocket] = createSignal<WebSocket>();
|
|
||||||
|
|
||||||
export const [isConnected, setConnected] = createSignal<Boolean>(false);
|
|
||||||
|
|
||||||
export const isNotConnected = () => !isConnected();
|
|
||||||
|
|
||||||
const onOpen = () => {
|
|
||||||
setConnected(true);
|
|
||||||
if (localStorage.getItem('devMode') === 'true') {
|
|
||||||
const hook = (window as PrimalWindow).onPrimalUploadServerConnected;
|
|
||||||
|
|
||||||
hook && hook(uploadServer, socket());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const onClose = () => {
|
|
||||||
setConnected(false);
|
|
||||||
|
|
||||||
socket()?.removeEventListener('open', onOpen);
|
|
||||||
socket()?.removeEventListener('close', onClose);
|
|
||||||
socket()?.removeEventListener('error', onError);
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
connect();
|
|
||||||
}, 200);
|
|
||||||
}
|
|
||||||
|
|
||||||
const onError = (error: Event) => {
|
|
||||||
console.log("ws error: ", error);
|
|
||||||
};
|
|
||||||
|
|
||||||
export let uploadServer = '';
|
|
||||||
|
|
||||||
export const connect = () => {
|
|
||||||
if (isNotConnected()) {
|
|
||||||
uploadServer = localStorage.getItem('uploadServer') ||
|
|
||||||
import.meta.env.PRIMAL_UPLOAD_URL;
|
|
||||||
|
|
||||||
setSocket(new WebSocket(uploadServer));
|
|
||||||
console.log('UPLOAD SOCKET: ', socket());
|
|
||||||
|
|
||||||
socket()?.addEventListener('open', onOpen);
|
|
||||||
socket()?.addEventListener('close', onClose);
|
|
||||||
socket()?.addEventListener('error', onError);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export const disconnect = () => {
|
|
||||||
socket()?.close();
|
|
||||||
};
|
|
||||||
|
|
||||||
export const reset = () => {
|
|
||||||
disconnect();
|
|
||||||
setTimeout(connect, 1000);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const sendMessage = (message: string) => {
|
|
||||||
if (isConnected()) {
|
|
||||||
const e = new CustomEvent('send', { detail: { message, ws: socket() }});
|
|
||||||
socket()?.send(message);
|
|
||||||
socket()?.dispatchEvent(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const refreshSocketListeners = (
|
|
||||||
ws: WebSocket | undefined,
|
|
||||||
listeners: Record<string, (event: any) => any>,
|
|
||||||
) => {
|
|
||||||
|
|
||||||
if (!ws) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Object.keys(listeners).forEach((event: string) => {
|
|
||||||
ws.removeEventListener(event, listeners[event]);
|
|
||||||
ws.addEventListener(event, listeners[event]);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export const removeSocketListeners = (
|
|
||||||
ws: WebSocket | undefined,
|
|
||||||
listeners: Record<string, (event: any) => any>,
|
|
||||||
) => {
|
|
||||||
|
|
||||||
if (!ws) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Object.keys(listeners).forEach((event: string) => {
|
|
||||||
ws.removeEventListener(event, listeners[event]);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export const subscribeTo = (subId: string, cb: (type: NostrEventType, subId: string, content?: NostrEventContent) => void ) => {
|
|
||||||
const listener = (event: MessageEvent) => {
|
|
||||||
const message: NostrEvent | NostrEOSE = JSON.parse(event.data);
|
|
||||||
const [type, subscriptionId, content] = message;
|
|
||||||
|
|
||||||
if (subId === subscriptionId) {
|
|
||||||
cb(type, subscriptionId, content);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
socket()?.addEventListener('message', listener);
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
socket()?.removeEventListener('message', listener);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
Loading…
Reference in New Issue
Block a user