Skip to content

Commit

Permalink
feat(web): show assets without thumbs (#2561)
Browse files Browse the repository at this point in the history
* feat(web): show assets without thumbnails

* chore: open api
  • Loading branch information
jrasm91 authored May 25, 2023
1 parent d827a61 commit 1613ae9
Show file tree
Hide file tree
Showing 10 changed files with 86 additions and 19 deletions.
1 change: 1 addition & 0 deletions mobile/openapi/doc/GetAssetByTimeBucketDto.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 21 additions & 3 deletions mobile/openapi/lib/model/get_asset_by_time_bucket_dto.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions mobile/openapi/test/get_asset_by_time_bucket_dto_test.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 10 additions & 6 deletions server/apps/immich/src/api-v1/asset/asset-repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,19 +104,23 @@ export class AssetRepository implements IAssetRepository {
return this.getAssetCount(items);
}

async getAssetByTimeBucket(userId: string, getAssetByTimeBucketDto: GetAssetByTimeBucketDto): Promise<AssetEntity[]> {
async getAssetByTimeBucket(userId: string, dto: GetAssetByTimeBucketDto): Promise<AssetEntity[]> {
// Get asset entity from a list of time buckets
return await this.assetRepository
let builder = this.assetRepository
.createQueryBuilder('asset')
.where('asset.ownerId = :userId', { userId: userId })
.andWhere(`date_trunc('month', "fileCreatedAt") IN (:...buckets)`, {
buckets: [...getAssetByTimeBucketDto.timeBucket],
buckets: [...dto.timeBucket],
})
.andWhere('asset.resizePath is not NULL')
.andWhere('asset.isVisible = true')
.andWhere('asset.isArchived = false')
.orderBy('asset.fileCreatedAt', 'DESC')
.getMany();
.orderBy('asset.fileCreatedAt', 'DESC');

if (!dto.withoutThumbs) {
builder = builder.andWhere('asset.resizePath is not NULL');
}

return builder.getMany();
}

async getAssetCountByTimeBucket(userId: string, timeBucket: TimeGroupEnum) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsNotEmpty, IsOptional, IsUUID } from 'class-validator';
import { Transform } from 'class-transformer';
import { IsBoolean, IsNotEmpty, IsOptional, IsUUID } from 'class-validator';
import { toBoolean } from '../../../utils/transform.util';

export class GetAssetByTimeBucketDto {
@IsNotEmpty()
Expand All @@ -15,4 +17,12 @@ export class GetAssetByTimeBucketDto {
@IsUUID('4')
@ApiProperty({ format: 'uuid' })
userId?: string;

/**
* Include assets without thumbnails
*/
@IsOptional()
@IsBoolean()
@Transform(toBoolean)
withoutThumbs?: boolean;
}
4 changes: 4 additions & 0 deletions server/immich-openapi-specs.json
Original file line number Diff line number Diff line change
Expand Up @@ -5988,6 +5988,10 @@
"userId": {
"type": "string",
"format": "uuid"
},
"withoutThumbs": {
"type": "boolean",
"description": "Include assets without thumbnails"
}
},
"required": [
Expand Down
6 changes: 6 additions & 0 deletions web/src/api/open-api/api.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 10 additions & 1 deletion web/src/lib/components/asset-viewer/asset-viewer.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import { createEventDispatcher, onDestroy, onMount } from 'svelte';
import ChevronLeft from 'svelte-material-icons/ChevronLeft.svelte';
import ChevronRight from 'svelte-material-icons/ChevronRight.svelte';
import ImageBrokenVariant from 'svelte-material-icons/ImageBrokenVariant.svelte';
import { fly } from 'svelte/transition';
import AlbumSelectionModal from '../shared-components/album-selection-modal.svelte';
import {
Expand Down Expand Up @@ -350,7 +351,15 @@

<div class="row-start-1 row-span-full col-start-1 col-span-4">
{#key asset.id}
{#if asset.type === AssetTypeEnum.Image}
{#if !asset.resizePath}
<div class="h-full w-full flex justify-center">
<div
class="h-full bg-gray-100 dark:bg-immich-dark-gray flex items-center justify-center aspect-square px-auto"
>
<ImageBrokenVariant size="25%" />
</div>
</div>
{:else if asset.type === AssetTypeEnum.Image}
{#if shouldPlayMotionPhoto && asset.livePhotoVideoId}
<VideoViewer
{publicSharedKey}
Expand Down
22 changes: 15 additions & 7 deletions web/src/lib/components/assets/thumbnail/thumbnail.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import ArchiveArrowDownOutline from 'svelte-material-icons/ArchiveArrowDownOutline.svelte';
import ImageThumbnail from './image-thumbnail.svelte';
import VideoThumbnail from './video-thumbnail.svelte';
import ImageBrokenVariant from 'svelte-material-icons/ImageBrokenVariant.svelte';
const dispatch = createEventDispatcher();
Expand Down Expand Up @@ -101,7 +102,7 @@
</div>

<div
class="bg-gray-100 dark:bg-immich-dark-gray absolute select-none transition-transform"
class="h-full w-full bg-gray-100 dark:bg-immich-dark-gray absolute select-none transition-transform"
class:scale-[0.85]={selected}
>
<!-- Gradient overlay on hover -->
Expand All @@ -121,12 +122,19 @@
<ArchiveArrowDownOutline size="24" class="text-white" />
</div>
{/if}
<ImageThumbnail
url={api.getAssetThumbnailUrl(asset.id, format, publicSharedKey)}
altText={asset.originalFileName}
widthStyle="{width}px"
heightStyle="{height}px"
/>

{#if asset.resizePath}
<ImageThumbnail
url={api.getAssetThumbnailUrl(asset.id, format, publicSharedKey)}
altText={asset.originalFileName}
widthStyle="{width}px"
heightStyle="{height}px"
/>
{:else}
<div class="w-full h-full p-4 flex items-center justify-center">
<ImageBrokenVariant size="48" />
</div>
{/if}

{#if asset.type === AssetTypeEnum.Video}
<div class="absolute w-full h-full top-0">
Expand Down
3 changes: 2 additions & 1 deletion web/src/lib/stores/assets.store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@ function createAssetStore() {
const { data: assets } = await api.assetApi.getAssetByTimeBucket(
{
timeBucket: [bucket],
userId: _assetGridState.userId
userId: _assetGridState.userId,
withoutThumbs: true
},
{ signal: currentBucketData?.cancelToken.signal }
);
Expand Down

0 comments on commit 1613ae9

Please sign in to comment.