chore: NDK update
This commit is contained in:
parent
d4ca14e0f7
commit
1abe455cfb
49
examples/31337-audio-track.json
Normal file
49
examples/31337-audio-track.json
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
{
|
||||||
|
"content": "PilotRedSun - Useful",
|
||||||
|
"created_at": 1711135644,
|
||||||
|
"id": "7fbc0371e5af6663d063c181dd93d3b71b12c749b46f9897f84e9208e2988ee1",
|
||||||
|
"kind": 31337,
|
||||||
|
"pubkey": "1ea10447aefec112de22860771f90e0243202ac121a72b2303a26ddbbb943637",
|
||||||
|
"sig": "c5a6a59519214fd12ca1b0db323e8e24e9a955d6c026a869c9d52991ab11051777c09a0f91f96d4b9aa0a51acbfb88b2c914a63c50cfb55fb920b28d36742e34",
|
||||||
|
"tags": [
|
||||||
|
[
|
||||||
|
"d",
|
||||||
|
"bc98fb9cn99fvxufigsof"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"title",
|
||||||
|
"Useful"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"c",
|
||||||
|
"IDM"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"creator",
|
||||||
|
"PilotRedSun"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"creator",
|
||||||
|
"PilotRedSun",
|
||||||
|
"Artist"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"imeta",
|
||||||
|
"url https://nostr.build/av/b057855ba5c38a598575e231a82175801d97a0a013d90c6b5761c05a40fecdf4.mp3",
|
||||||
|
"m audio/mpeg"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"version",
|
||||||
|
"1.0"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"media",
|
||||||
|
"https://nostr.build/av/b057855ba5c38a598575e231a82175801d97a0a013d90c6b5761c05a40fecdf4.mp3"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"subject",
|
||||||
|
"Useful"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
36
examples/34235-flare-video.json
Normal file
36
examples/34235-flare-video.json
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
{
|
||||||
|
"id": "7e39b40bf2155a7b8e5f60bfae4e46c8b0fb36fefaa8639164ad22830897137b",
|
||||||
|
"pubkey": "7dd040804955e939e63c9dd6b60aedf6c29b6ce7d3dcc91f37f06c3836f6813d",
|
||||||
|
"created_at": 1713306006,
|
||||||
|
"kind": 34235,
|
||||||
|
"tags": [
|
||||||
|
["d", "dmVyc3VzODM0ODQ3NzQx"],
|
||||||
|
[
|
||||||
|
"url",
|
||||||
|
"https://player.vimeo.com/progressive_redirect/playback/834847741/rendition/240p/file.mp4?loc=external&oauth2_token_id=1749830961&signature=e946680feb43b5f6975c7c6f9748c84944dff8f0d99539864c644494bb5eff8f"
|
||||||
|
],
|
||||||
|
["title", "Scoville Unit - Firepit"],
|
||||||
|
[
|
||||||
|
"summary",
|
||||||
|
"Starring Valentina Isleib and Scoville Unit\n\nDirected by Tarana Parekh\nProduced by HIP Video Productions"
|
||||||
|
],
|
||||||
|
["published_at", "1713306006"],
|
||||||
|
["client", "versusmedia"],
|
||||||
|
["m", "video/mp4"],
|
||||||
|
["size", "15571944"],
|
||||||
|
["duration", "238"],
|
||||||
|
[
|
||||||
|
"thumb",
|
||||||
|
"https://i.vimeocdn.com/video/1681906723-f59a373300f9996597487112c75d32e8794ac5540bde895cc015dc5df788ff9d-d_1280x720"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"image",
|
||||||
|
"https://i.vimeocdn.com/video/1681906723-f59a373300f9996597487112c75d32e8794ac5540bde895cc015dc5df788ff9d-d_1280x720"
|
||||||
|
],
|
||||||
|
["t", "Alternative"],
|
||||||
|
["t", "4291231"],
|
||||||
|
["t", "versusmedia"]
|
||||||
|
],
|
||||||
|
"content": "Scoville Unit - Firepit",
|
||||||
|
"sig": "95c90aafa24b5d8fbf00e65581d5b6fc542aef87a0238c7ccd8ec75ffc347f1cbea34ed82a57588fa32e2021d77cd8930fbf2991d2c9898796f0d653f30989d0"
|
||||||
|
}
|
30
package.json
30
package.json
@ -12,44 +12,44 @@
|
|||||||
"analyze": "vite-bundle-visualizer"
|
"analyze": "vite-bundle-visualizer"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@headlessui/react": "^1.7.18",
|
"@headlessui/react": "^1.7.19",
|
||||||
"@heroicons/react": "^2.1.3",
|
"@heroicons/react": "^2.1.3",
|
||||||
"@noble/hashes": "^1.4.0",
|
"@noble/hashes": "^1.4.0",
|
||||||
"@nostr-dev-kit/ndk": "^2.7.1",
|
"@nostr-dev-kit/ndk": "^2.8.1",
|
||||||
"@nostr-dev-kit/ndk-cache-dexie": "^2.3.1",
|
"@nostr-dev-kit/ndk-cache-dexie": "^2.4.1",
|
||||||
"@tanstack/react-query": "^5.29.0",
|
"@tanstack/react-query": "^5.32.0",
|
||||||
"@tanstack/react-query-devtools": "^5.29.0",
|
"@tanstack/react-query-devtools": "^5.32.0",
|
||||||
"add": "^2.0.6",
|
"add": "^2.0.6",
|
||||||
"axios": "^1.6.8",
|
"axios": "^1.6.8",
|
||||||
"blossom-client-sdk": "^0.4.0",
|
"blossom-client-sdk": "^0.4.0",
|
||||||
"dayjs": "^1.11.10",
|
"dayjs": "^1.11.10",
|
||||||
"id3js": "^2.1.1",
|
"id3js": "^2.1.1",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"nostr-tools": "^2.4.0",
|
"nostr-tools": "^2.5.0",
|
||||||
"p-limit": "^5.0.0",
|
"p-limit": "^5.0.0",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-pdf": "^7.7.1",
|
"react-pdf": "^7.7.1",
|
||||||
"react-router-dom": "^6.22.3"
|
"react-router-dom": "^6.23.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@tanstack/eslint-plugin-query": "^5.28.6",
|
"@tanstack/eslint-plugin-query": "^5.28.11",
|
||||||
"@types/lodash": "^4.17.0",
|
"@types/lodash": "^4.17.0",
|
||||||
"@types/react": "^18.2.74",
|
"@types/react": "^18.2.79",
|
||||||
"@types/react-dom": "^18.2.24",
|
"@types/react-dom": "^18.2.25",
|
||||||
"@typescript-eslint/eslint-plugin": "^7.2.0",
|
"@typescript-eslint/eslint-plugin": "^7.7.1",
|
||||||
"@typescript-eslint/parser": "^7.2.0",
|
"@typescript-eslint/parser": "^7.7.1",
|
||||||
"@vitejs/plugin-react-swc": "^3.6.0",
|
"@vitejs/plugin-react-swc": "^3.6.0",
|
||||||
"autoprefixer": "^10.4.19",
|
"autoprefixer": "^10.4.19",
|
||||||
"daisyui": "latest",
|
"daisyui": "latest",
|
||||||
"eslint": "^8.57.0",
|
"eslint": "^9.1.1",
|
||||||
"eslint-plugin-react-hooks": "^4.6.0",
|
"eslint-plugin-react-hooks": "^4.6.0",
|
||||||
"eslint-plugin-react-refresh": "^0.4.6",
|
"eslint-plugin-react-refresh": "^0.4.6",
|
||||||
"postcss": "^8.4.38",
|
"postcss": "^8.4.38",
|
||||||
"prettier": "^3.2.5",
|
"prettier": "^3.2.5",
|
||||||
"tailwindcss": "^3.4.3",
|
"tailwindcss": "^3.4.3",
|
||||||
"typescript": "^5.4.4",
|
"typescript": "^5.4.5",
|
||||||
"vite": "^5.2.8",
|
"vite": "^5.2.10",
|
||||||
"vite-bundle-visualizer": "^1.1.0"
|
"vite-bundle-visualizer": "^1.1.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import {
|
import {
|
||||||
ArrowPathIcon,
|
|
||||||
ArrowUpOnSquareStackIcon,
|
ArrowUpOnSquareStackIcon,
|
||||||
CheckBadgeIcon,
|
CheckBadgeIcon,
|
||||||
ClockIcon,
|
ClockIcon,
|
||||||
@ -10,7 +9,7 @@ import {
|
|||||||
ShieldExclamationIcon,
|
ShieldExclamationIcon,
|
||||||
XMarkIcon,
|
XMarkIcon,
|
||||||
} from '@heroicons/react/24/outline';
|
} from '@heroicons/react/24/outline';
|
||||||
import { Server as ServerType } from '../../utils/useServers';
|
import { Server as ServerType } from '../../utils/useUserServers';
|
||||||
import { ServerInfo } from '../../utils/useServerInfo';
|
import { ServerInfo } from '../../utils/useServerInfo';
|
||||||
import { formatDate, formatFileSize } from '../../utils';
|
import { formatDate, formatFileSize } from '../../utils';
|
||||||
|
|
||||||
@ -51,7 +50,7 @@ const Server = ({
|
|||||||
<div className="flex flex-col grow">
|
<div className="flex flex-col grow">
|
||||||
<div className="server-name">
|
<div className="server-name">
|
||||||
{server.name}
|
{server.name}
|
||||||
{serverInfo.isLoading && <ArrowPathIcon className="loading" />}
|
{serverInfo.isLoading && <span className="ml-2 loading loading-spinner loading-sm"></span>}
|
||||||
</div>
|
</div>
|
||||||
{serverInfo.isError ? (
|
{serverInfo.isError ? (
|
||||||
<div className="badge badge-error">
|
<div className="badge badge-error">
|
||||||
|
@ -44,21 +44,6 @@
|
|||||||
@apply cursor-pointer text-center flex flex-col items-center hover:text-white opacity-80 hover:opacity-100 gap-1;
|
@apply cursor-pointer text-center flex flex-col items-center hover:text-white opacity-80 hover:opacity-100 gap-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes spin {
|
|
||||||
0% {
|
|
||||||
transform: rotate(0deg);
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
transform: rotate(360deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.loading {
|
|
||||||
@apply w-6 ml-2 inline align-text-bottom;
|
|
||||||
transform-origin: center;
|
|
||||||
animation: spin 3s linear infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
.server-list-header {
|
.server-list-header {
|
||||||
@apply flex flex-row py-4;
|
@apply flex flex-row py-4;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { PlusIcon, ServerIcon } from '@heroicons/react/24/outline';
|
import { PlusIcon, ServerIcon } from '@heroicons/react/24/outline';
|
||||||
import { useServerInfo } from '../../utils/useServerInfo';
|
import { useServerInfo } from '../../utils/useServerInfo';
|
||||||
import { Server as ServerType } from '../../utils/useServers';
|
import { Server as ServerType } from '../../utils/useUserServers';
|
||||||
import Server from './Server';
|
import Server from './Server';
|
||||||
import './ServerList.css';
|
import './ServerList.css';
|
||||||
|
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import { ChangeEvent, DragEvent, useEffect, useMemo, useState } from 'react';
|
import { ChangeEvent, DragEvent, useEffect, useMemo, useRef, useState } from 'react';
|
||||||
import { Server, useServers } from '../utils/useServers';
|
|
||||||
import { BlobDescriptor, BlossomClient, SignedEvent } from 'blossom-client-sdk';
|
import { BlobDescriptor, BlossomClient, SignedEvent } from 'blossom-client-sdk';
|
||||||
import { useNDK } from '../ndk';
|
import { useNDK } from '../ndk';
|
||||||
import { useServerInfo } from '../utils/useServerInfo';
|
import { useServerInfo } from '../utils/useServerInfo';
|
||||||
@ -12,6 +11,8 @@ import ProgressBar from '../components/ProgressBar/ProgressBar';
|
|||||||
import { formatFileSize } from '../utils';
|
import { formatFileSize } from '../utils';
|
||||||
import FileEventEditor, { FileEventData } from '../components/FileEventEditor/FileEventEditor';
|
import FileEventEditor, { FileEventData } from '../components/FileEventEditor/FileEventEditor';
|
||||||
import pLimit from 'p-limit';
|
import pLimit from 'p-limit';
|
||||||
|
import { Server, useUserServers } from '../utils/useUserServers';
|
||||||
|
import useBlossomServerEvents from '../utils/useBlossomServerEvents';
|
||||||
|
|
||||||
type TransferStats = {
|
type TransferStats = {
|
||||||
enabled: boolean;
|
enabled: boolean;
|
||||||
@ -31,12 +32,10 @@ steps
|
|||||||
- upload
|
- upload
|
||||||
- server slection, progress bars, upload speed
|
- server slection, progress bars, upload speed
|
||||||
-
|
-
|
||||||
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function Upload() {
|
function Upload() {
|
||||||
const servers = useServers();
|
const servers = useUserServers();
|
||||||
const { signEventTemplate } = useNDK();
|
const { signEventTemplate } = useNDK();
|
||||||
const { serverInfo } = useServerInfo();
|
const { serverInfo } = useServerInfo();
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
@ -44,9 +43,10 @@ function Upload() {
|
|||||||
const [files, setFiles] = useState<File[]>([]);
|
const [files, setFiles] = useState<File[]>([]);
|
||||||
const [cleanPrivateData, setCleanPrivateData] = useState(true);
|
const [cleanPrivateData, setCleanPrivateData] = useState(true);
|
||||||
const limit = pLimit(3);
|
const limit = pLimit(3);
|
||||||
|
const fileInputRef = useRef<HTMLInputElement | null>(null);
|
||||||
|
const bs = useBlossomServerEvents();
|
||||||
const [fileEventsToPublish, setFileEventsToPublish] = useState<FileEventData[]>([]);
|
const [fileEventsToPublish, setFileEventsToPublish] = useState<FileEventData[]>([]);
|
||||||
|
console.log(bs);
|
||||||
// const [resizeImages, setResizeImages] = useState(false);
|
// const [resizeImages, setResizeImages] = useState(false);
|
||||||
// const [publishToNostr, setPublishToNostr] = useState(false);
|
// const [publishToNostr, setPublishToNostr] = useState(false);
|
||||||
|
|
||||||
@ -173,7 +173,19 @@ function Upload() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const clearTransfers = () => {
|
const clearTransfers = () => {
|
||||||
setTransfers(servers.reduce((acc, s) => ({ ...acc, [s.name]: { enabled: true, size: 0, transferred: 0 } }), {}));
|
setTransfers(tfs =>
|
||||||
|
servers.reduce(
|
||||||
|
(acc, s) => ({
|
||||||
|
...acc,
|
||||||
|
[s.name]: {
|
||||||
|
enabled: !serverInfo[s.name].isError && (tfs[s.name] !== undefined ? tfs[s.name].enabled : true),
|
||||||
|
size: 0,
|
||||||
|
transferred: 0,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
{}
|
||||||
|
)
|
||||||
|
);
|
||||||
setFileEventsToPublish([]);
|
setFileEventsToPublish([]);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -222,7 +234,7 @@ function Upload() {
|
|||||||
<>
|
<>
|
||||||
<h2 className=" py-4">Upload</h2>
|
<h2 className=" py-4">Upload</h2>
|
||||||
<div className=" bg-base-200 rounded-xl p-4 text-neutral-content gap-4 flex flex-col">
|
<div className=" bg-base-200 rounded-xl p-4 text-neutral-content gap-4 flex flex-col">
|
||||||
<input id="browse" type="file" hidden multiple onChange={handleFileChange} />
|
<input id="browse" type="file" ref={fileInputRef} hidden multiple onChange={handleFileChange} />
|
||||||
<label
|
<label
|
||||||
htmlFor="browse"
|
htmlFor="browse"
|
||||||
className="p-8 bg-base-100 rounded-lg hover:text-primary text-neutral-content border-dashed border-neutral-content border-opacity-50 border-2 block cursor-pointer text-center"
|
className="p-8 bg-base-100 rounded-lg hover:text-primary text-neutral-content border-dashed border-neutral-content border-opacity-50 border-2 block cursor-pointer text-center"
|
||||||
@ -289,6 +301,9 @@ function Upload() {
|
|||||||
onClick={() => {
|
onClick={() => {
|
||||||
clearTransfers();
|
clearTransfers();
|
||||||
setFiles([]);
|
setFiles([]);
|
||||||
|
if (fileInputRef.current) {
|
||||||
|
fileInputRef.current.value = '';
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<TrashIcon className="w-6" />
|
<TrashIcon className="w-6" />
|
||||||
|
27
src/utils/useBlossomServerEvents.ts
Normal file
27
src/utils/useBlossomServerEvents.ts
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import { useMemo } from 'react';
|
||||||
|
import useEvents from '../useEvents';
|
||||||
|
import { NDKKind } from '@nostr-dev-kit/ndk';
|
||||||
|
import countBy from 'lodash/countBy';
|
||||||
|
import sortBy from 'lodash/sortBy';
|
||||||
|
import toPairs from 'lodash/toPairs';
|
||||||
|
|
||||||
|
const blossomServerListFilter = { kinds: [10063 as NDKKind] };
|
||||||
|
|
||||||
|
const useBlossomServerEvents = () => {
|
||||||
|
const blossomServerEvents = useEvents(blossomServerListFilter);
|
||||||
|
|
||||||
|
const blossomServers = useMemo(() => {
|
||||||
|
const allRTags = blossomServerEvents.events.flatMap(ev =>
|
||||||
|
ev.tags.filter(t => t[0] == 'r').flatMap(t => ({ name: t[1] }))
|
||||||
|
);
|
||||||
|
const cnt = countBy(
|
||||||
|
allRTags.filter(s => !s.name.match(/https?:\/\/localhost/)),
|
||||||
|
'name'
|
||||||
|
);
|
||||||
|
return sortBy(toPairs(cnt), 1).reverse();
|
||||||
|
}, [blossomServerEvents.events]);
|
||||||
|
|
||||||
|
return blossomServers;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default useBlossomServerEvents;
|
@ -1,9 +1,9 @@
|
|||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
import { useServers } from './useServers';
|
|
||||||
import { useQueries } from '@tanstack/react-query';
|
import { useQueries } from '@tanstack/react-query';
|
||||||
import { BlobDescriptor, BlossomClient } from 'blossom-client-sdk';
|
import { BlobDescriptor, BlossomClient } from 'blossom-client-sdk';
|
||||||
import { useNDK } from '../ndk';
|
import { useNDK } from '../ndk';
|
||||||
import { nip19 } from 'nostr-tools';
|
import { nip19 } from 'nostr-tools';
|
||||||
|
import { useUserServers } from './useUserServers';
|
||||||
|
|
||||||
export type ServerInfo = {
|
export type ServerInfo = {
|
||||||
count: number;
|
count: number;
|
||||||
@ -21,7 +21,7 @@ type BlobDictionary = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const useServerInfo = () => {
|
export const useServerInfo = () => {
|
||||||
const servers = useServers();
|
const servers = useUserServers();
|
||||||
const { user, signEventTemplate } = useNDK();
|
const { user, signEventTemplate } = useNDK();
|
||||||
|
|
||||||
const pubkey = user?.npub && (nip19.decode(user?.npub).data as string); // TODO validate type
|
const pubkey = user?.npub && (nip19.decode(user?.npub).data as string); // TODO validate type
|
||||||
@ -37,6 +37,7 @@ export const useServerInfo = () => {
|
|||||||
},
|
},
|
||||||
enabled: !!pubkey && servers.length > 0,
|
enabled: !!pubkey && servers.length > 0,
|
||||||
staleTime: 1000 * 60 * 5,
|
staleTime: 1000 * 60 * 5,
|
||||||
|
retryOnMount: false,
|
||||||
})),
|
})),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ export type Server = {
|
|||||||
url: string;
|
url: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useServers = (): Server[] => {
|
export const useUserServers = (): Server[] => {
|
||||||
const { user } = useNDK();
|
const { user } = useNDK();
|
||||||
|
|
||||||
const pubkey = user?.npub && (nip19.decode(user?.npub).data as string); // TODO validate type
|
const pubkey = user?.npub && (nip19.decode(user?.npub).data as string); // TODO validate type
|
Loading…
Reference in New Issue
Block a user