123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185 |
- import { uploadAssetsStore } from '$lib/stores/upload';
- import { addAssetsToAlbum } from '$lib/utils/asset-utils';
- import type { AssetFileUploadResponseDto } from '@api';
- import axios from 'axios';
- import { notificationController, NotificationType } from './../components/shared-components/notification/notification';
- const extensions = [
- '.3fr',
- '.3gp',
- '.ari',
- '.arw',
- '.avi',
- '.avif',
- '.cap',
- '.cin',
- '.cr2',
- '.cr3',
- '.crw',
- '.dcr',
- '.dng',
- '.erf',
- '.fff',
- '.flv',
- '.gif',
- '.heic',
- '.heif',
- '.iiq',
- '.jpeg',
- '.jpg',
- '.k25',
- '.kdc',
- '.mkv',
- '.mov',
- '.mp2t',
- '.mp4',
- '.mpeg',
- '.mrw',
- '.nef',
- '.orf',
- '.ori',
- '.pef',
- '.png',
- '.raf',
- '.raw',
- '.rwl',
- '.sr2',
- '.srf',
- '.srw',
- '.tiff',
- '.webm',
- '.webp',
- '.wmv',
- '.x3f',
- ];
- export const openFileUploadDialog = async (
- albumId: string | undefined = undefined,
- sharedKey: string | undefined = undefined,
- ) => {
- return new Promise<(string | undefined)[]>((resolve, reject) => {
- try {
- const fileSelector = document.createElement('input');
- fileSelector.type = 'file';
- fileSelector.multiple = true;
- fileSelector.accept = extensions.join(',');
- fileSelector.onchange = async (e: Event) => {
- const target = e.target as HTMLInputElement;
- if (!target.files) {
- return;
- }
- const files = Array.from(target.files);
- resolve(fileUploadHandler(files, albumId, sharedKey));
- };
- fileSelector.click();
- } catch (e) {
- console.log('Error selecting file', e);
- reject(e);
- }
- });
- };
- export const fileUploadHandler = async (
- files: File[],
- albumId: string | undefined = undefined,
- sharedKey: string | undefined = undefined,
- ) => {
- const iterable = {
- files: files.filter((file) => extensions.some((ext) => file.name.toLowerCase().endsWith(ext)))[Symbol.iterator](),
- async *[Symbol.asyncIterator]() {
- for (const file of this.files) {
- yield fileUploader(file, albumId, sharedKey);
- }
- },
- };
- const concurrency = 2;
- // TODO: use Array.fromAsync instead when it's available universally.
- return Promise.all([...Array(concurrency)].map(() => fromAsync(iterable))).then((res) => res.flat());
- };
- // polyfill for Array.fromAsync.
- //
- // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/fromAsync
- const fromAsync = async function <T>(iterable: AsyncIterable<T>) {
- const result = [];
- for await (const value of iterable) {
- result.push(value);
- }
- return result;
- };
- // TODO: should probably use the @api SDK
- async function fileUploader(
- asset: File,
- albumId: string | undefined = undefined,
- sharedKey: string | undefined = undefined,
- ): Promise<string | undefined> {
- const formData = new FormData();
- const fileCreatedAt = new Date(asset.lastModified).toISOString();
- const deviceAssetId = 'web' + '-' + asset.name + '-' + asset.lastModified;
- try {
- formData.append('deviceAssetId', deviceAssetId);
- formData.append('deviceId', 'WEB');
- formData.append('fileCreatedAt', fileCreatedAt);
- formData.append('fileModifiedAt', new Date(asset.lastModified).toISOString());
- formData.append('isFavorite', 'false');
- formData.append('duration', '0:00:00.000000');
- formData.append('assetData', new File([asset], asset.name));
- uploadAssetsStore.addNewUploadAsset({
- id: deviceAssetId,
- file: asset,
- progress: 0,
- });
- const response = await axios.post('/api/asset/upload', formData, {
- params: {
- key: sharedKey,
- },
- onUploadProgress: (event) => {
- const percentComplete = Math.floor((event.loaded / event.total) * 100);
- uploadAssetsStore.updateProgress(deviceAssetId, percentComplete);
- },
- });
- if (response.status == 200 || response.status == 201) {
- const res: AssetFileUploadResponseDto = response.data;
- if (albumId && res.id) {
- await addAssetsToAlbum(albumId, [res.id], sharedKey);
- }
- setTimeout(() => {
- uploadAssetsStore.removeUploadAsset(deviceAssetId);
- }, 1000);
- return res.id;
- }
- } catch (e) {
- console.log('error uploading file ', e);
- handleUploadError(asset, JSON.stringify(e));
- uploadAssetsStore.removeUploadAsset(deviceAssetId);
- }
- }
- function handleUploadError(asset: File, respBody = '{}', extraMessage?: string) {
- try {
- const res = JSON.parse(respBody);
- const extraMsg = res ? ' ' + res?.message : '';
- notificationController.show({
- type: NotificationType.Error,
- message: `Cannot upload file ${asset.name} ${extraMsg}${extraMessage}`,
- timeout: 5000,
- });
- } catch (e) {
- console.error('ERROR parsing data JSON in handleUploadError');
- }
- }
|