diff --git a/src/app/chats/components/mediaUploader.tsx b/src/app/chats/components/mediaUploader.tsx index de4b8ac6..165b9470 100644 --- a/src/app/chats/components/mediaUploader.tsx +++ b/src/app/chats/components/mediaUploader.tsx @@ -3,20 +3,25 @@ import { Dispatch, SetStateAction, useState } from 'react'; import { LoaderIcon, MediaIcon } from '@shared/icons'; +import { useNostr } from '@utils/hooks/useNostr'; + export function MediaUploader({ setState, }: { setState: Dispatch>; }) { + const { upload } = useNostr(); const [loading, setLoading] = useState(false); const uploadMedia = async () => { setLoading(true); - const image = await upload(null); - if (image.url) { - setState((prev: string) => `${prev}\n${image.url}`); + + const image = await upload(['mp4', 'mp3', 'webm', 'mkv', 'avi', 'mov']); + + if (image) { + setState((prev: string) => `${prev}\n${image}`); + setLoading(false); } - setLoading(false); }; return ( diff --git a/src/app/new/components/mediaUploader.tsx b/src/app/new/components/mediaUploader.tsx index 947b64ee..89cdba11 100644 --- a/src/app/new/components/mediaUploader.tsx +++ b/src/app/new/components/mediaUploader.tsx @@ -1,11 +1,13 @@ -import { message, open } from '@tauri-apps/plugin-dialog'; -import { readBinaryFile } from '@tauri-apps/plugin-fs'; +import { message } from '@tauri-apps/plugin-dialog'; import { Editor } from '@tiptap/react'; import { useState } from 'react'; import { MediaIcon } from '@shared/icons'; +import { useNostr } from '@utils/hooks/useNostr'; + export function MediaUploader({ editor }: { editor: Editor }) { + const { upload } = useNostr(); const [loading, setLoading] = useState(false); const uploadToNostrBuild = async () => { @@ -13,52 +15,12 @@ export function MediaUploader({ editor }: { editor: Editor }) { // start loading setLoading(true); - const selected = await open({ - multiple: false, - filters: [ - { - name: 'Media', - extensions: [ - 'png', - 'jpeg', - 'jpg', - 'gif', - 'mp4', - 'mp3', - 'webm', - 'mkv', - 'avi', - 'mov', - ], - }, - ], - }); + const image = await upload(['mp4', 'mp3', 'webm', 'mkv', 'avi', 'mov']); - if (!selected) { - setLoading(false); - return; - } - - const file = await readBinaryFile(selected.path); - const blob = new Blob([file]); - - const data = new FormData(); - data.append('fileToUpload', blob); - data.append('submit', 'Upload Image'); - - const res = await fetch('https://nostr.build/api/v2/upload/files', { - method: 'POST', - body: data, - }); - - if (res.ok) { - const json = await res.json(); - const content = json.data[0]; - - editor.commands.setImage({ src: content.url }); + if (image) { + editor.commands.setImage({ src: image }); editor.commands.createParagraphNear(); - // stop loading setLoading(false); } } catch (e) { diff --git a/src/shared/avatarUploader.tsx b/src/shared/avatarUploader.tsx index 1a870867..f5e3ea3f 100644 --- a/src/shared/avatarUploader.tsx +++ b/src/shared/avatarUploader.tsx @@ -1,15 +1,16 @@ -import { message, open } from '@tauri-apps/plugin-dialog'; -import { readBinaryFile } from '@tauri-apps/plugin-fs'; -import { fetch } from '@tauri-apps/plugin-http'; +import { message } from '@tauri-apps/plugin-dialog'; import { Dispatch, SetStateAction, useState } from 'react'; import { LoaderIcon, PlusIcon } from '@shared/icons'; +import { useNostr } from '@utils/hooks/useNostr'; + export function AvatarUploader({ setPicture, }: { setPicture: Dispatch>; }) { + const { upload } = useNostr(); const [loading, setLoading] = useState(false); const uploadAvatar = async () => { @@ -17,42 +18,14 @@ export function AvatarUploader({ // start loading setLoading(true); - const selected = await open({ - multiple: false, - filters: [ - { - name: 'Image', - extensions: ['png', 'jpeg', 'jpg', 'gif'], - }, - ], - }); + const image = await upload(); - if (!selected) { - setLoading(false); - return; - } - - const file = await readBinaryFile(selected.path); - const blob = new Blob([file]); - - const data = new FormData(); - data.append('fileToUpload', blob); - data.append('submit', 'Upload Image'); - - const res = await fetch('https://nostr.build/api/v2/upload/files', { - method: 'POST', - body: data, - }); - - if (res.ok) { - const json = await res.json(); - const content = json.data[0]; - - setPicture(content.url); - - // stop loading + if (image) { + setPicture(image); setLoading(false); } + + return; } catch (e) { // stop loading setLoading(false); diff --git a/src/shared/bannerUploader.tsx b/src/shared/bannerUploader.tsx index 5ec88b5c..b3e308be 100644 --- a/src/shared/bannerUploader.tsx +++ b/src/shared/bannerUploader.tsx @@ -1,15 +1,16 @@ -import { message, open } from '@tauri-apps/plugin-dialog'; -import { readBinaryFile } from '@tauri-apps/plugin-fs'; -import { fetch } from '@tauri-apps/plugin-http'; +import { message } from '@tauri-apps/plugin-dialog'; import { Dispatch, SetStateAction, useState } from 'react'; import { LoaderIcon, PlusIcon } from '@shared/icons'; +import { useNostr } from '@utils/hooks/useNostr'; + export function BannerUploader({ setBanner, }: { setBanner: Dispatch>; }) { + const { upload } = useNostr(); const [loading, setLoading] = useState(false); const uploadBanner = async () => { @@ -17,42 +18,14 @@ export function BannerUploader({ // start loading setLoading(true); - const selected = await open({ - multiple: false, - filters: [ - { - name: 'Image', - extensions: ['png', 'jpeg', 'jpg', 'gif'], - }, - ], - }); + const image = await upload(); - if (!selected) { - setLoading(false); - return; - } - - const file = await readBinaryFile(selected.path); - const blob = new Blob([file]); - - const data = new FormData(); - data.append('fileToUpload', blob); - data.append('submit', 'Upload Image'); - - const res = await fetch('https://nostr.build/api/v2/upload/files', { - method: 'POST', - body: data, - }); - - if (res.ok) { - const json = await res.json(); - const content = json.data[0]; - - setBanner(content.url); - - // stop loading + if (image) { + setBanner(image); setLoading(false); } + + return; } catch (e) { // stop loading setLoading(false); diff --git a/src/utils/hooks/useNostr.ts b/src/utils/hooks/useNostr.ts index 4bd9a316..a02b996e 100644 --- a/src/utils/hooks/useNostr.ts +++ b/src/utils/hooks/useNostr.ts @@ -1,4 +1,7 @@ import { NDKEvent, NDKFilter, NDKKind, NDKSubscription } from '@nostr-dev-kit/ndk'; +import { open } from '@tauri-apps/plugin-dialog'; +import { readBinaryFile } from '@tauri-apps/plugin-fs'; +import { fetch } from '@tauri-apps/plugin-http'; import { LRUCache } from 'lru-cache'; import { NostrEventExt } from 'nostr-fetch'; import { useMemo } from 'react'; @@ -239,6 +242,41 @@ export function useNostr() { return res; }; + const upload = async (ext: string[] = []) => { + const defaultExts = ['png', 'jpeg', 'jpg', 'gif'].concat(ext); + + const selected = await open({ + multiple: false, + filters: [ + { + name: 'Image', + extensions: defaultExts, + }, + ], + }); + + if (!selected) return null; + + const file = await readBinaryFile(selected.path); + const blob = new Blob([file]); + + const data = new FormData(); + data.append('fileToUpload', blob); + data.append('submit', 'Upload Image'); + + const res = await fetch('https://nostr.build/api/v2/upload/files', { + method: 'POST', + body: data, + }); + + if (!res.ok) return null; + + const json = await res.json(); + const content = json.data[0]; + + return content.url as string; + }; + return { sub, getAllNIP04Chats, @@ -250,5 +288,6 @@ export function useNostr() { fetchNIP04Messages, fetchAllReplies, createZap, + upload, }; }