upload-panel.svelte 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. <script lang="ts">
  2. import { quartInOut } from 'svelte/easing';
  3. import { scale, fade } from 'svelte/transition';
  4. import { uploadAssetsStore } from '$lib/stores/upload';
  5. import CloudUploadOutline from 'svelte-material-icons/CloudUploadOutline.svelte';
  6. import WindowMinimize from 'svelte-material-icons/WindowMinimize.svelte';
  7. import { notificationController, NotificationType } from './notification/notification';
  8. import UploadAssetPreview from './upload-asset-preview.svelte';
  9. let showDetail = true;
  10. let uploadLength = 0;
  11. let isUploading = false;
  12. // Reactive action to update asset uploadLength whenever there is a new one added to the list
  13. $: {
  14. if ($uploadAssetsStore.length != uploadLength) {
  15. uploadLength = $uploadAssetsStore.length;
  16. }
  17. }
  18. uploadAssetsStore.isUploading.subscribe((value) => {
  19. isUploading = value;
  20. });
  21. </script>
  22. {#if isUploading}
  23. <div
  24. in:fade={{ duration: 250 }}
  25. out:fade={{ duration: 250, delay: 1000 }}
  26. on:outroend={() => {
  27. notificationController.show({
  28. message: 'Upload success, refresh the page to see new upload assets',
  29. type: NotificationType.Info,
  30. });
  31. }}
  32. class="absolute bottom-6 right-6 z-[10000]"
  33. >
  34. {#if showDetail}
  35. <div
  36. in:scale={{ duration: 250, easing: quartInOut }}
  37. class="w-[300px] rounded-lg border bg-gray-200 p-4 text-sm shadow-sm"
  38. >
  39. <div class="place-item-center mb-4 flex justify-between">
  40. <p class="text-xs text-gray-500">UPLOADING {$uploadAssetsStore.length}</p>
  41. <button
  42. on:click={() => (showDetail = false)}
  43. class="flex h-[20px] w-[20px] place-content-center place-items-center rounded-full bg-gray-50 transition-colors hover:bg-gray-100"
  44. >
  45. <WindowMinimize />
  46. </button>
  47. </div>
  48. <div class="immich-scrollbar max-h-[400px] overflow-y-auto rounded-lg pr-2">
  49. {#each $uploadAssetsStore as uploadAsset}
  50. {#key uploadAsset.id}
  51. <UploadAssetPreview {uploadAsset} />
  52. {/key}
  53. {/each}
  54. </div>
  55. </div>
  56. {:else}
  57. <div class="rounded-full">
  58. <button
  59. in:scale={{ duration: 250, easing: quartInOut }}
  60. on:click={() => (showDetail = true)}
  61. class="absolute -left-4 -top-4 flex h-10 w-10 place-content-center place-items-center rounded-full bg-immich-primary p-5 text-xs text-gray-200"
  62. >
  63. {$uploadAssetsStore.length}
  64. </button>
  65. <button
  66. in:scale={{ duration: 250, easing: quartInOut }}
  67. on:click={() => (showDetail = true)}
  68. class="flex h-16 w-16 place-content-center place-items-center rounded-full bg-gray-300 p-5 text-sm shadow-lg"
  69. >
  70. <div class="animate-pulse">
  71. <CloudUploadOutline size="30" color="#4250af" />
  72. </div>
  73. </button>
  74. </div>
  75. {/if}
  76. </div>
  77. {/if}