feat: added file transfer progress

This commit is contained in:
florian 2024-03-30 17:22:56 +01:00
parent 7e8ebd8c58
commit bbb5e2ed11
3 changed files with 44 additions and 8 deletions

View File

@ -19,6 +19,7 @@
"@nostr-dev-kit/ndk-cache-dexie": "^2.2.8", "@nostr-dev-kit/ndk-cache-dexie": "^2.2.8",
"@tanstack/react-query": "^5.28.6", "@tanstack/react-query": "^5.28.6",
"@tanstack/react-query-devtools": "^5.28.6", "@tanstack/react-query-devtools": "^5.28.6",
"axios": "^1.6.8",
"blossom-client-sdk": "^0.4.0", "blossom-client-sdk": "^0.4.0",
"dayjs": "^1.11.10", "dayjs": "^1.11.10",
"nostr-tools": "^2.3.2", "nostr-tools": "^2.3.2",

View File

@ -3,11 +3,11 @@
} }
.content { .content {
@apply flex flex-col self-center sm:w-10/12 lg:w-4/6 w-full min-h-[80vh] @apply flex flex-col self-center sm:w-10/12 xl:w-4/6 w-full min-h-[80vh];
} }
.title { .title {
@apply text-white text-4xl flex flex-row items-center gap-2 p-4 sm:w-10/12 lg:w-4/6 w-full self-center; @apply text-white text-4xl flex flex-row items-center gap-2 p-4 sm:w-10/12 xl:w-4/6 w-full self-center;
} }
.title img { .title img {

View File

@ -1,6 +1,6 @@
import { ChangeEvent, DragEvent, useEffect, useState } from 'react'; import { ChangeEvent, DragEvent, useEffect, useState } from 'react';
import { useServers } from '../utils/useServers'; import { useServers } from '../utils/useServers';
import { BlossomClient } 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';
import { useQueryClient } from '@tanstack/react-query'; import { useQueryClient } from '@tanstack/react-query';
@ -8,6 +8,7 @@ import { ArrowUpOnSquareIcon } from '@heroicons/react/24/outline';
import ProgressBar from '../components/ProgressBar/ProgressBar'; import ProgressBar from '../components/ProgressBar/ProgressBar';
import { removeExifData } from '../exif'; import { removeExifData } from '../exif';
import CheckBox from '../components/CheckBox/CheckBox'; import CheckBox from '../components/CheckBox/CheckBox';
import axios, { AxiosProgressEvent } from 'axios';
type TransferStats = { type TransferStats = {
enabled: boolean; enabled: boolean;
@ -23,8 +24,27 @@ function Upload() {
const [transfers, setTransfers] = useState<{ [key: string]: TransferStats }>({}); const [transfers, setTransfers] = useState<{ [key: string]: TransferStats }>({});
const [files, setFiles] = useState<File[]>([]); const [files, setFiles] = useState<File[]>([]);
const [cleanPrivateData, setCleanPrivateData] = useState(true); const [cleanPrivateData, setCleanPrivateData] = useState(true);
const [resizeImages, setResizeImages] = useState(false); // const [resizeImages, setResizeImages] = useState(false);
const [publishToNostr, setPublishToNostr] = useState(false); // const [publishToNostr, setPublishToNostr] = useState(false);
async function uploadBlob(
server: string,
file: File,
auth?: SignedEvent,
onUploadProgress?: (progressEvent: AxiosProgressEvent) => void
) {
const headers = {
Accept: 'application/json',
'Content-Type': file.type,
};
const res = await axios.put<BlobDescriptor>(`${server}/upload`, file, {
headers: auth ? { ...headers, authorization: BlossomClient.encodeAuthorizationHeader(auth) } : headers,
onUploadProgress,
});
return res.data;
}
const upload = async () => { const upload = async () => {
const filesToUpload: File[] = []; const filesToUpload: File[] = [];
@ -59,11 +79,23 @@ function Upload() {
continue; continue;
} }
const serverUrl = serverInfo[server.name].url; const serverUrl = serverInfo[server.name].url;
let serverTransferred = 0;
for (const file of filesToUpload) { for (const file of filesToUpload) {
const uploadAuth = await BlossomClient.getUploadAuth(file, signEventTemplate, 'Upload Blob'); const uploadAuth = await BlossomClient.getUploadAuth(file, signEventTemplate, 'Upload Blob');
const newBlob = await BlossomClient.uploadBlob(serverUrl, file, uploadAuth);
transfers[server.name].transferred += file.size; const newBlob = await uploadBlob(serverUrl, file, uploadAuth, progressEvent => {
setTransfers(ut => ({
...ut,
[server.name]: { ...ut[server.name], transferred: serverTransferred + progressEvent.loaded },
}));
});
serverTransferred += file.size;
setTransfers(ut => ({
...ut,
[server.name]: { ...ut[server.name], transferred: serverTransferred },
}));
console.log(newBlob); console.log(newBlob);
} }
queryClient.invalidateQueries({ queryKey: ['blobs', server.name] }); queryClient.invalidateQueries({ queryKey: ['blobs', server.name] });
@ -138,6 +170,7 @@ function Upload() {
setChecked={c => setCleanPrivateData(c)} setChecked={c => setCleanPrivateData(c)}
label="Clean private data in images (EXIF)" label="Clean private data in images (EXIF)"
></CheckBox> ></CheckBox>
{/*
<CheckBox <CheckBox
name="resize" name="resize"
checked={resizeImages} checked={resizeImages}
@ -150,10 +183,12 @@ function Upload() {
setChecked={c => setPublishToNostr(c)} setChecked={c => setPublishToNostr(c)}
label="Publish to NOSTR (as 1063 file metadata event) (NOT IMPLEMENTED YET!)" label="Publish to NOSTR (as 1063 file metadata event) (NOT IMPLEMENTED YET!)"
></CheckBox> ></CheckBox>
*/}
</div> </div>
<button <button
className="p-2 px-4 bg-neutral-600 hover:bg-pink-700 text-white rounded-lg w-2/6" className="p-2 px-4 bg-neutral-600 hover:bg-pink-700 text-white rounded-lg w-2/6 disabled:text-neutral-800 disabled:bg-neutral-900 "
onClick={() => upload()} onClick={() => upload()}
disabled={files.length == 0}
> >
Upload{files.length > 0 ? (files.length == 1 ? ` 1 file` : ` ${files.length} files`) : ''} Upload{files.length > 0 ? (files.length == 1 ? ` 1 file` : ` ${files.length} files`) : ''}
</button> </button>