mirror of
				https://github.com/KevinMidboe/immich.git
				synced 2025-10-29 17:40:28 +00:00 
			
		
		
		
	refactor(server,web): time buckets for main timeline, archived, and favorites (1) (#3537)
* refactor: time buckets * feat(web): use new time bucket api * feat(web): use asset grid in archive/favorites * chore: open api * chore: clean up uuid validation * refactor(web): move memory lane to photos page * Update web/src/routes/(user)/archive/+page.svelte Co-authored-by: Sergey Kondrikov <sergey.kondrikov@gmail.com> * fix: hide archived photos on main timeline * fix: select exif info --------- Co-authored-by: Sergey Kondrikov <sergey.kondrikov@gmail.com>
This commit is contained in:
		@@ -6,70 +6,55 @@
 | 
			
		||||
  import DeleteAssets from '$lib/components/photos-page/actions/delete-assets.svelte';
 | 
			
		||||
  import DownloadAction from '$lib/components/photos-page/actions/download-action.svelte';
 | 
			
		||||
  import FavoriteAction from '$lib/components/photos-page/actions/favorite-action.svelte';
 | 
			
		||||
  import SelectAllAssets from '$lib/components/photos-page/actions/select-all-assets.svelte';
 | 
			
		||||
  import AssetGrid from '$lib/components/photos-page/asset-grid.svelte';
 | 
			
		||||
  import AssetSelectContextMenu from '$lib/components/photos-page/asset-select-context-menu.svelte';
 | 
			
		||||
  import AssetSelectControlBar from '$lib/components/photos-page/asset-select-control-bar.svelte';
 | 
			
		||||
  import EmptyPlaceholder from '$lib/components/shared-components/empty-placeholder.svelte';
 | 
			
		||||
  import GalleryViewer from '$lib/components/shared-components/gallery-viewer/gallery-viewer.svelte';
 | 
			
		||||
  import SelectAll from 'svelte-material-icons/SelectAll.svelte';
 | 
			
		||||
  import { archivedAsset } from '$lib/stores/archived-asset.store';
 | 
			
		||||
  import { handleError } from '$lib/utils/handle-error';
 | 
			
		||||
  import { api, AssetResponseDto } from '@api';
 | 
			
		||||
  import { createAssetInteractionStore } from '$lib/stores/asset-interaction.store';
 | 
			
		||||
  import { AssetStore } from '$lib/stores/assets.store';
 | 
			
		||||
  import { api, TimeBucketSize } from '@api';
 | 
			
		||||
  import { onMount } from 'svelte';
 | 
			
		||||
  import DotsVertical from 'svelte-material-icons/DotsVertical.svelte';
 | 
			
		||||
  import Plus from 'svelte-material-icons/Plus.svelte';
 | 
			
		||||
  import type { PageData } from './$types';
 | 
			
		||||
  import CircleIconButton from '$lib/components/elements/buttons/circle-icon-button.svelte';
 | 
			
		||||
 | 
			
		||||
  export let data: PageData;
 | 
			
		||||
  let assetCount = 1;
 | 
			
		||||
 | 
			
		||||
  let selectedAssets: Set<AssetResponseDto> = new Set();
 | 
			
		||||
  $: isMultiSelectionMode = selectedAssets.size > 0;
 | 
			
		||||
  $: isAllFavorite = Array.from(selectedAssets).every((asset) => asset.isFavorite);
 | 
			
		||||
  const assetStore = new AssetStore({ size: TimeBucketSize.Month, isArchived: true });
 | 
			
		||||
  const assetInteractionStore = createAssetInteractionStore();
 | 
			
		||||
  const { isMultiSelectState, selectedAssets } = assetInteractionStore;
 | 
			
		||||
 | 
			
		||||
  $: isAllFavorite = Array.from($selectedAssets).every((asset) => asset.isFavorite);
 | 
			
		||||
 | 
			
		||||
  onMount(async () => {
 | 
			
		||||
    try {
 | 
			
		||||
      const { data: assets } = await api.assetApi.getAllAssets({
 | 
			
		||||
        isArchived: true,
 | 
			
		||||
        withoutThumbs: true,
 | 
			
		||||
      });
 | 
			
		||||
      $archivedAsset = assets;
 | 
			
		||||
    } catch {
 | 
			
		||||
      handleError(Error, 'Unable to load archived assets');
 | 
			
		||||
    }
 | 
			
		||||
    const { data: stats } = await api.assetApi.getAssetStats({ isArchived: true });
 | 
			
		||||
    assetCount = stats.total;
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  const onAssetDelete = (assetId: string) => {
 | 
			
		||||
    $archivedAsset = $archivedAsset.filter((a) => a.id !== assetId);
 | 
			
		||||
  };
 | 
			
		||||
  const handleSelectAll = () => {
 | 
			
		||||
    selectedAssets = new Set($archivedAsset);
 | 
			
		||||
  };
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<UserPageLayout user={data.user} hideNavbar={isMultiSelectionMode} title={data.meta.title}>
 | 
			
		||||
  <!-- Empty Message -->
 | 
			
		||||
  {#if $archivedAsset.length === 0}
 | 
			
		||||
{#if $isMultiSelectState}
 | 
			
		||||
  <AssetSelectControlBar assets={$selectedAssets} clearSelect={() => assetInteractionStore.clearMultiselect()}>
 | 
			
		||||
    <ArchiveAction unarchive onAssetArchive={(asset) => assetStore.removeAsset(asset.id)} />
 | 
			
		||||
    <CreateSharedLink />
 | 
			
		||||
    <SelectAllAssets {assetStore} {assetInteractionStore} />
 | 
			
		||||
    <AssetSelectContextMenu icon={Plus} title="Add">
 | 
			
		||||
      <AddToAlbum />
 | 
			
		||||
      <AddToAlbum shared />
 | 
			
		||||
    </AssetSelectContextMenu>
 | 
			
		||||
    <DeleteAssets onAssetDelete={(assetId) => assetStore.removeAsset(assetId)} />
 | 
			
		||||
    <AssetSelectContextMenu icon={DotsVertical} title="Add">
 | 
			
		||||
      <DownloadAction menuItem />
 | 
			
		||||
      <FavoriteAction menuItem removeFavorite={isAllFavorite} />
 | 
			
		||||
    </AssetSelectContextMenu>
 | 
			
		||||
  </AssetSelectControlBar>
 | 
			
		||||
{/if}
 | 
			
		||||
 | 
			
		||||
<UserPageLayout user={data.user} hideNavbar={$isMultiSelectState} title={data.meta.title} scrollbar={!assetCount}>
 | 
			
		||||
  {#if assetCount}
 | 
			
		||||
    <AssetGrid {assetStore} {assetInteractionStore} />
 | 
			
		||||
  {:else}
 | 
			
		||||
    <EmptyPlaceholder text="Archive photos and videos to hide them from your Photos view" alt="Empty archive" />
 | 
			
		||||
  {/if}
 | 
			
		||||
 | 
			
		||||
  <svelte:fragment slot="header">
 | 
			
		||||
    {#if isMultiSelectionMode}
 | 
			
		||||
      <AssetSelectControlBar assets={selectedAssets} clearSelect={() => (selectedAssets = new Set())}>
 | 
			
		||||
        <ArchiveAction unarchive onAssetArchive={(asset) => onAssetDelete(asset.id)} />
 | 
			
		||||
        <CircleIconButton title="Select all" logo={SelectAll} on:click={handleSelectAll} />
 | 
			
		||||
        <CreateSharedLink />
 | 
			
		||||
        <AssetSelectContextMenu icon={Plus} title="Add">
 | 
			
		||||
          <AddToAlbum />
 | 
			
		||||
          <AddToAlbum shared />
 | 
			
		||||
        </AssetSelectContextMenu>
 | 
			
		||||
        <DeleteAssets {onAssetDelete} />
 | 
			
		||||
        <AssetSelectContextMenu icon={DotsVertical} title="Add">
 | 
			
		||||
          <DownloadAction menuItem />
 | 
			
		||||
          <FavoriteAction menuItem removeFavorite={isAllFavorite} />
 | 
			
		||||
        </AssetSelectContextMenu>
 | 
			
		||||
      </AssetSelectControlBar>
 | 
			
		||||
    {/if}
 | 
			
		||||
  </svelte:fragment>
 | 
			
		||||
 | 
			
		||||
  <GalleryViewer assets={$archivedAsset} bind:selectedAssets viewFrom="archive-page" />
 | 
			
		||||
</UserPageLayout>
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user