Feature - Add upload functionality on Web (#231)

* Added file selector

* Extract metadata to upload files to the web

* Added request for uploading

* Generate jpeg/Webp thumbnail for asset uploaded without thumbnail data

* Added generating thumbnail for video and WebSocket broadcast after thumbnail is generated

* Added video length extraction

* Added Uploading Panel

* Added upload progress store and styling the uploaded asset

* Added condition to only show upload panel when there is upload in progress

* Remove asset from the upload list after successfully uploading

* Added WebSocket to listen to upload event on the web

* Added mechanism to check for existing assets before uploading on the web

* Added test workflow

* Update readme
This commit is contained in:
Alex
2022-06-19 08:16:35 -05:00
committed by GitHub
parent b7603fd150
commit 1e3464fe47
33 changed files with 859 additions and 220 deletions

View File

@@ -22,8 +22,8 @@
import { blur } from 'svelte/transition';
import DownloadPanel from '$lib/components/asset-viewer/download-panel.svelte';
import FullScreenModal from '../lib/components/shared/full-screen-modal.svelte';
import AnnouncementBox from '../lib/components/shared/announcement-box.svelte';
import AnnouncementBox from '$lib/components/shared/announcement-box.svelte';
import UploadPanel from '$lib/components/shared/upload-panel.svelte';
export let url: string;
export let shouldShowAnnouncement: boolean;
@@ -36,7 +36,7 @@
<div transition:blur={{ duration: 250 }}>
<slot />
<DownloadPanel />
<UploadPanel />
{#if shouldShowAnnouncement}
<AnnouncementBox {localVersion} {remoteVersion} on:close={() => (shouldShowAnnouncement = false)} />
{/if}

View File

@@ -35,6 +35,7 @@
<script lang="ts">
import { serverEndpoint } from '$lib/constants';
import { goto } from '$app/navigation';
import { onMount } from 'svelte';
export let isAdminUserExist: boolean;

View File

@@ -41,6 +41,8 @@
import AssetViewer from '../../lib/components/asset-viewer/asset-viewer.svelte';
import DownloadPanel from '../../lib/components/asset-viewer/download-panel.svelte';
import StatusBox from '../../lib/components/shared/status-box.svelte';
import { fileUploader } from '../../lib/utils/file-uploader';
import { openWebsocketConnection } from '../../lib/stores/websocket';
export let user: ImmichUser;
let selectedAction: AppSideBarSelection;
@@ -64,6 +66,8 @@
if ($session.user) {
await getAssetsInfo($session.user.accessToken);
openWebsocketConnection($session.user.accessToken);
}
});
@@ -79,7 +83,34 @@
currentViewAssetIndex = $flattenAssetGroupByDate.findIndex((a) => a.id == assetId);
currentSelectedAsset = $flattenAssetGroupByDate[currentViewAssetIndex];
isShowAsset = true;
// pushState(assetId);
};
const uploadClickedHandler = async () => {
if ($session.user) {
try {
let fileSelector = document.createElement('input');
fileSelector.type = 'file';
fileSelector.multiple = true;
fileSelector.accept = 'image/*,video/*,.heic,.heif';
fileSelector.onchange = async (e: any) => {
const files = Array.from<File>(e.target.files);
const acceptedFile = files.filter(
(e) => e.type.split('/')[0] === 'video' || e.type.split('/')[0] === 'image',
);
for (const asset of acceptedFile) {
await fileUploader(asset, $session.user!.accessToken);
}
};
fileSelector.click();
} catch (e) {
console.log('Error seelcting file', e);
}
}
};
</script>
@@ -88,10 +119,10 @@
</svelte:head>
<section>
<NavigationBar {user} />
<NavigationBar {user} on:uploadClicked={uploadClickedHandler} />
</section>
<section class="grid grid-cols-[250px_auto] relative pt-[72px] h-screen">
<section class="grid grid-cols-[250px_auto] relative pt-[72px] h-screen bg-immich-bg">
<!-- Sidebar -->
<section id="sidebar" class="flex flex-col gap-4 pt-8 pr-6">
<SideBarButton
@@ -111,7 +142,7 @@
<!-- Main Section -->
<section class="overflow-y-auto relative">
<section id="assets-content" class="relative pt-8 pl-4">
<section id="assets-content" class="relative pt-8 pl-4 mb-12 bg-immich-bg">
<section id="image-grid" class="flex flex-wrap gap-14">
{#each $assetsGroupByDate as assetsInDateGroup, groupIndex}
<!-- Asset Group By Date -->
@@ -121,7 +152,7 @@
on:mouseleave={() => (isMouseOverGroup = false)}
>
<!-- Date group title -->
<p class="font-medium text-sm text-black mb-2 flex place-items-center h-6">
<p class="font-medium text-sm text-immich-fg mb-2 flex place-items-center h-6">
{#if selectedGroupThumbnail === groupIndex && isMouseOverGroup}
<div
in:fly={{ x: -24, duration: 200, opacity: 0.5 }}
@@ -136,7 +167,7 @@
</p>
<!-- Image grid -->
<div class="flex flex-wrap gap-1">
<div class="flex flex-wrap gap-[2px]">
{#each assetsInDateGroup as asset}
<ImmichThumbnail
{asset}