mirror of
https://github.com/immich-app/immich.git
synced 2025-01-04 02:46:47 +01:00
feat: move full-size preview config to standalone entry
This commit is contained in:
parent
cb0831364d
commit
6160790dc8
5 changed files with 79 additions and 20 deletions
|
@ -12,7 +12,7 @@ import {
|
||||||
VideoContainer,
|
VideoContainer,
|
||||||
} from 'src/enum';
|
} from 'src/enum';
|
||||||
import { ConcurrentQueueName, QueueName } from 'src/interfaces/job.interface';
|
import { ConcurrentQueueName, QueueName } from 'src/interfaces/job.interface';
|
||||||
import { ImageOptions } from 'src/interfaces/media.interface';
|
import { FullsizeImageOptions, ImageOptions } from 'src/interfaces/media.interface';
|
||||||
|
|
||||||
export interface SystemConfig {
|
export interface SystemConfig {
|
||||||
backup: {
|
backup: {
|
||||||
|
@ -112,7 +112,7 @@ export interface SystemConfig {
|
||||||
preview: ImageOptions;
|
preview: ImageOptions;
|
||||||
colorspace: Colorspace;
|
colorspace: Colorspace;
|
||||||
extractEmbedded: boolean;
|
extractEmbedded: boolean;
|
||||||
fullsizePreview: boolean;
|
fullsize: FullsizeImageOptions;
|
||||||
};
|
};
|
||||||
newVersionCheck: {
|
newVersionCheck: {
|
||||||
enabled: boolean;
|
enabled: boolean;
|
||||||
|
@ -282,7 +282,11 @@ export const defaults = Object.freeze<SystemConfig>({
|
||||||
},
|
},
|
||||||
colorspace: Colorspace.P3,
|
colorspace: Colorspace.P3,
|
||||||
extractEmbedded: false,
|
extractEmbedded: false,
|
||||||
fullsizePreview: false,
|
fullsize: {
|
||||||
|
enabled: false,
|
||||||
|
format: ImageFormat.JPEG,
|
||||||
|
quality: 80,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
newVersionCheck: {
|
newVersionCheck: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
|
|
|
@ -530,6 +530,24 @@ class SystemConfigGeneratedImageDto {
|
||||||
size!: number;
|
size!: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class SystemConfigGeneratedFullsizeImageDto {
|
||||||
|
@IsBoolean()
|
||||||
|
@Type(() => Boolean)
|
||||||
|
@ApiProperty({ type: 'boolean' })
|
||||||
|
enabled!: boolean;
|
||||||
|
|
||||||
|
@IsEnum(ImageFormat)
|
||||||
|
@ApiProperty({ enumName: 'ImageFormat', enum: ImageFormat })
|
||||||
|
format!: ImageFormat;
|
||||||
|
|
||||||
|
@IsInt()
|
||||||
|
@Min(1)
|
||||||
|
@Max(100)
|
||||||
|
@Type(() => Number)
|
||||||
|
@ApiProperty({ type: 'integer' })
|
||||||
|
quality!: number;
|
||||||
|
}
|
||||||
|
|
||||||
export class SystemConfigImageDto {
|
export class SystemConfigImageDto {
|
||||||
@Type(() => SystemConfigGeneratedImageDto)
|
@Type(() => SystemConfigGeneratedImageDto)
|
||||||
@ValidateNested()
|
@ValidateNested()
|
||||||
|
@ -541,15 +559,17 @@ export class SystemConfigImageDto {
|
||||||
@IsObject()
|
@IsObject()
|
||||||
preview!: SystemConfigGeneratedImageDto;
|
preview!: SystemConfigGeneratedImageDto;
|
||||||
|
|
||||||
|
@Type(() => SystemConfigGeneratedFullsizeImageDto)
|
||||||
|
@ValidateNested()
|
||||||
|
@IsObject()
|
||||||
|
fullsize!: SystemConfigGeneratedFullsizeImageDto;
|
||||||
|
|
||||||
@IsEnum(Colorspace)
|
@IsEnum(Colorspace)
|
||||||
@ApiProperty({ enumName: 'Colorspace', enum: Colorspace })
|
@ApiProperty({ enumName: 'Colorspace', enum: Colorspace })
|
||||||
colorspace!: Colorspace;
|
colorspace!: Colorspace;
|
||||||
|
|
||||||
@ValidateBoolean()
|
@ValidateBoolean()
|
||||||
extractEmbedded!: boolean;
|
extractEmbedded!: boolean;
|
||||||
|
|
||||||
@ValidateBoolean()
|
|
||||||
fullsizePreview!: boolean;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class SystemConfigTrashDto {
|
class SystemConfigTrashDto {
|
||||||
|
|
|
@ -11,6 +11,12 @@ export interface CropOptions {
|
||||||
height: number;
|
height: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface FullsizeImageOptions {
|
||||||
|
format: ImageFormat;
|
||||||
|
quality: number;
|
||||||
|
enabled: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
export interface ImageOptions {
|
export interface ImageOptions {
|
||||||
format: ImageFormat;
|
format: ImageFormat;
|
||||||
quality: number;
|
quality: number;
|
||||||
|
|
|
@ -235,7 +235,8 @@ export class MediaService extends BaseService {
|
||||||
const imageIsWebSupported = mimeTypes.isWebSupportedImage(asset.originalFileName);
|
const imageIsWebSupported = mimeTypes.isWebSupportedImage(asset.originalFileName);
|
||||||
const imageIsRaw = mimeTypes.isRaw(asset.originalFileName);
|
const imageIsRaw = mimeTypes.isRaw(asset.originalFileName);
|
||||||
|
|
||||||
const shouldConvertFullsize = !imageIsWebSupported && image.fullsizePreview;
|
const { enabled: enableFullsizeImage, ...fullsizeImageOptions } = image.fullsize;
|
||||||
|
const shouldConvertFullsize = !imageIsWebSupported && enableFullsizeImage;
|
||||||
const shouldExtractEmbedded = imageIsRaw && image.extractEmbedded;
|
const shouldExtractEmbedded = imageIsRaw && image.extractEmbedded;
|
||||||
const decodeOptions: DecodeToBufferOptions = {
|
const decodeOptions: DecodeToBufferOptions = {
|
||||||
colorspace,
|
colorspace,
|
||||||
|
@ -246,7 +247,8 @@ export class MediaService extends BaseService {
|
||||||
let useExtracted = false;
|
let useExtracted = false;
|
||||||
let decodeInputPath: string = asset.originalPath;
|
let decodeInputPath: string = asset.originalPath;
|
||||||
// Converted or extracted image from non-web-supported formats (e.g. RAW)
|
// Converted or extracted image from non-web-supported formats (e.g. RAW)
|
||||||
let fullsizePath: string | undefined;
|
let fullsizePath: string = StorageCore.getImagePath(asset, AssetPathType.FULLSIZE, image.preview.format);
|
||||||
|
|
||||||
if (shouldConvertFullsize) {
|
if (shouldConvertFullsize) {
|
||||||
// unset size to decode fullsize image
|
// unset size to decode fullsize image
|
||||||
decodeOptions.size = undefined;
|
decodeOptions.size = undefined;
|
||||||
|
@ -275,8 +277,6 @@ export class MediaService extends BaseService {
|
||||||
extractedPath,
|
extractedPath,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
fullsizePath = StorageCore.getImagePath(asset, AssetPathType.FULLSIZE, image.preview.format);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -291,7 +291,7 @@ export class MediaService extends BaseService {
|
||||||
!useExtracted && // did not extract a usable image from RAW
|
!useExtracted && // did not extract a usable image from RAW
|
||||||
this.mediaRepository.generateThumbnail(
|
this.mediaRepository.generateThumbnail(
|
||||||
data,
|
data,
|
||||||
{ ...image.preview, ...thumbnailOptions, size: undefined },
|
{ ...fullsizeImageOptions, ...thumbnailOptions, size: undefined },
|
||||||
fullsizePath,
|
fullsizePath,
|
||||||
),
|
),
|
||||||
]);
|
]);
|
||||||
|
|
|
@ -132,6 +132,44 @@
|
||||||
/>
|
/>
|
||||||
</SettingAccordion>
|
</SettingAccordion>
|
||||||
|
|
||||||
|
<SettingAccordion
|
||||||
|
key="fullsize-settings"
|
||||||
|
title={$t('admin.image_fullsize_title')}
|
||||||
|
subtitle={$t('admin.image_fullsize_description')}
|
||||||
|
isOpen={openByDefault}
|
||||||
|
>
|
||||||
|
<SettingSwitch
|
||||||
|
title={$t('admin.image_fullsize_enabled')}
|
||||||
|
subtitle={$t('admin.image_fullsize_enabled_description')}
|
||||||
|
checked={config.image.fullsize.enabled}
|
||||||
|
onToggle={(isChecked) => (config.image.fullsize.enabled = isChecked)}
|
||||||
|
isEdited={config.image.fullsize.enabled !== savedConfig.image.fullsize.enabled}
|
||||||
|
{disabled}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<SettingSelect
|
||||||
|
label={$t('admin.image_format')}
|
||||||
|
desc={$t('admin.image_format_description')}
|
||||||
|
bind:value={config.image.fullsize.format}
|
||||||
|
options={[
|
||||||
|
{ value: ImageFormat.Jpeg, text: 'JPEG' },
|
||||||
|
{ value: ImageFormat.Webp, text: 'WebP' },
|
||||||
|
]}
|
||||||
|
name="format"
|
||||||
|
isEdited={config.image.fullsize.format !== savedConfig.image.fullsize.format}
|
||||||
|
disabled={disabled || !config.image.fullsize.enabled}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<SettingInputField
|
||||||
|
inputType={SettingInputFieldType.NUMBER}
|
||||||
|
label={$t('admin.image_quality')}
|
||||||
|
description={$t('admin.image_fullsize_quality_description')}
|
||||||
|
bind:value={config.image.fullsize.quality}
|
||||||
|
isEdited={config.image.fullsize.quality !== savedConfig.image.fullsize.quality}
|
||||||
|
disabled={disabled || !config.image.fullsize.enabled}
|
||||||
|
/>
|
||||||
|
</SettingAccordion>
|
||||||
|
|
||||||
<SettingSwitch
|
<SettingSwitch
|
||||||
title={$t('admin.image_prefer_wide_gamut')}
|
title={$t('admin.image_prefer_wide_gamut')}
|
||||||
subtitle={$t('admin.image_prefer_wide_gamut_setting_description')}
|
subtitle={$t('admin.image_prefer_wide_gamut_setting_description')}
|
||||||
|
@ -149,15 +187,6 @@
|
||||||
isEdited={config.image.extractEmbedded !== savedConfig.image.extractEmbedded}
|
isEdited={config.image.extractEmbedded !== savedConfig.image.extractEmbedded}
|
||||||
{disabled}
|
{disabled}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<SettingSwitch
|
|
||||||
title={$t('admin.image_enable_original_size_preview')}
|
|
||||||
subtitle={$t('admin.image_enable_original_size_preview_setting_description')}
|
|
||||||
checked={config.image.fullsizePreview}
|
|
||||||
onToggle={(isChecked) => (config.image.fullsizePreview = isChecked)}
|
|
||||||
isEdited={config.image.fullsizePreview !== savedConfig.image.fullsizePreview}
|
|
||||||
{disabled}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="ml-4">
|
<div class="ml-4">
|
||||||
|
|
Loading…
Reference in a new issue