refactor(web): admin settings (#6177)

* refactor admin settings

* use slots to render buttons in simplified template settings

* remove more boilerplate by looping over components

* fix: onboarding

* fix: reset/reset to default

* remove lodash since it is unecessary

* chore: standardize padding and margins

---------

Co-authored-by: Jason Rasmussen <jrasm91@gmail.com>
This commit is contained in:
Daniel Dietzler 2024-01-12 18:44:11 +01:00 committed by GitHub
parent 2439c5ab57
commit a4f49d197e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
20 changed files with 1192 additions and 1971 deletions

View file

@ -1,154 +1,84 @@
<script lang="ts">
import SettingSelect from '$lib/components/admin-page/settings/setting-select.svelte';
import { api, Colorspace, SystemConfigThumbnailDto } from '@api';
import { Colorspace, SystemConfigDto } from '@api';
import { fade } from 'svelte/transition';
import { isEqual } from 'lodash-es';
import SettingButtonsRow from '$lib/components/admin-page/settings/setting-buttons-row.svelte';
import {
notificationController,
NotificationType,
} from '$lib/components/shared-components/notification/notification';
import SettingInputField, { SettingInputFieldType } from '../setting-input-field.svelte';
import SettingSwitch from '../setting-switch.svelte';
import type { ResetOptions } from '$lib/utils/dipatch';
import { createEventDispatcher } from 'svelte';
import type { SettingsEventType } from '../admin-settings';
export let thumbnailConfig: SystemConfigThumbnailDto; // this is the config that is being edited
export let savedConfig: SystemConfigDto;
export let defaultConfig: SystemConfigDto;
export let config: SystemConfigDto; // this is the config that is being edited
export let disabled = false;
let savedConfig: SystemConfigThumbnailDto;
let defaultConfig: SystemConfigThumbnailDto;
const handleReset = (detail: ResetOptions) => {
if (detail.default) {
resetToDefault();
} else {
reset();
}
};
async function getConfigs() {
[savedConfig, defaultConfig] = await Promise.all([
api.systemConfigApi.getConfig().then((res) => res.data.thumbnail),
api.systemConfigApi.getConfigDefaults().then((res) => res.data.thumbnail),
]);
}
async function reset() {
const { data: resetConfig } = await api.systemConfigApi.getConfig();
thumbnailConfig = { ...resetConfig.thumbnail };
savedConfig = { ...resetConfig.thumbnail };
notificationController.show({
message: 'Reset thumbnail settings to the recent saved settings',
type: NotificationType.Info,
});
}
async function resetToDefault() {
const { data: configs } = await api.systemConfigApi.getConfigDefaults();
thumbnailConfig = { ...configs.thumbnail };
defaultConfig = { ...configs.thumbnail };
notificationController.show({
message: 'Reset thumbnail settings to default',
type: NotificationType.Info,
});
}
async function saveSetting() {
try {
const { data: configs } = await api.systemConfigApi.getConfig();
const result = await api.systemConfigApi.updateConfig({
systemConfigDto: {
...configs,
thumbnail: thumbnailConfig,
},
});
thumbnailConfig = { ...result.data.thumbnail };
savedConfig = { ...result.data.thumbnail };
notificationController.show({
message: 'Thumbnail settings saved',
type: NotificationType.Info,
});
} catch (e) {
console.error('Error [thumbnail-settings] [saveSetting]', e);
notificationController.show({
message: 'Unable to save settings',
type: NotificationType.Error,
});
}
}
const dispatch = createEventDispatcher<SettingsEventType>();
</script>
<div>
{#await getConfigs() then}
<div in:fade={{ duration: 500 }}>
<form autocomplete="off" on:submit|preventDefault>
<div class="ml-4 mt-4 flex flex-col gap-4">
<SettingSelect
label="SMALL THUMBNAIL RESOLUTION"
desc="Used when viewing groups of photos (main timeline, album view, etc.). Higher resolutions can preserve more detail but take longer to encode, have larger file sizes, and can reduce app responsiveness."
number
bind:value={thumbnailConfig.webpSize}
options={[
{ value: 1080, text: '1080p' },
{ value: 720, text: '720p' },
{ value: 480, text: '480p' },
{ value: 250, text: '250p' },
{ value: 200, text: '200p' },
]}
name="resolution"
isEdited={thumbnailConfig.webpSize !== savedConfig.webpSize}
{disabled}
/>
<div in:fade={{ duration: 500 }}>
<form autocomplete="off" on:submit|preventDefault>
<div class="ml-4 mt-4 flex flex-col gap-4">
<SettingSelect
label="SMALL THUMBNAIL RESOLUTION"
desc="Used when viewing groups of photos (main timeline, album view, etc.). Higher resolutions can preserve more detail but take longer to encode, have larger file sizes, and can reduce app responsiveness."
number
bind:value={config.thumbnail.webpSize}
options={[
{ value: 1080, text: '1080p' },
{ value: 720, text: '720p' },
{ value: 480, text: '480p' },
{ value: 250, text: '250p' },
{ value: 200, text: '200p' },
]}
name="resolution"
isEdited={config.thumbnail.webpSize !== savedConfig.thumbnail.webpSize}
{disabled}
/>
<SettingSelect
label="LARGE THUMBNAIL RESOLUTION"
desc="Used when viewing a single photo and for machine learning. Higher resolutions can preserve more detail but take longer to encode, have larger file sizes, and can reduce app responsiveness."
number
bind:value={thumbnailConfig.jpegSize}
options={[
{ value: 2160, text: '4K' },
{ value: 1440, text: '1440p' },
{ value: 1080, text: '1080p' },
{ value: 720, text: '720p' },
]}
name="resolution"
isEdited={thumbnailConfig.jpegSize !== savedConfig.jpegSize}
{disabled}
/>
<SettingSelect
label="LARGE THUMBNAIL RESOLUTION"
desc="Used when viewing a single photo and for machine learning. Higher resolutions can preserve more detail but take longer to encode, have larger file sizes, and can reduce app responsiveness."
number
bind:value={config.thumbnail.jpegSize}
options={[
{ value: 2160, text: '4K' },
{ value: 1440, text: '1440p' },
{ value: 1080, text: '1080p' },
{ value: 720, text: '720p' },
]}
name="resolution"
isEdited={config.thumbnail.jpegSize !== savedConfig.thumbnail.jpegSize}
{disabled}
/>
<SettingInputField
inputType={SettingInputFieldType.NUMBER}
label="QUALITY"
desc="Thumbnail quality from 1-100. Higher is better for quality but produces larger files."
bind:value={thumbnailConfig.quality}
isEdited={thumbnailConfig.quality !== savedConfig.quality}
/>
<SettingInputField
inputType={SettingInputFieldType.NUMBER}
label="QUALITY"
desc="Thumbnail quality from 1-100. Higher is better for quality but produces larger files."
bind:value={config.thumbnail.quality}
isEdited={config.thumbnail.quality !== savedConfig.thumbnail.quality}
/>
<SettingSwitch
title="PREFER WIDE GAMUT"
subtitle="Use Display P3 for thumbnails. This better preserves the vibrance of images with wide colorspaces, but images may appear differently on old devices with an old browser version. sRGB images are kept as sRGB to avoid color shifts."
checked={thumbnailConfig.colorspace === Colorspace.P3}
on:toggle={(e) => (thumbnailConfig.colorspace = e.detail ? Colorspace.P3 : Colorspace.Srgb)}
isEdited={thumbnailConfig.colorspace !== savedConfig.colorspace}
/>
</div>
<SettingSwitch
title="PREFER WIDE GAMUT"
subtitle="Use Display P3 for thumbnails. This better preserves the vibrance of images with wide colorspaces, but images may appear differently on old devices with an old browser version. sRGB images are kept as sRGB to avoid color shifts."
checked={config.thumbnail.colorspace === Colorspace.P3}
on:toggle={(e) => (config.thumbnail.colorspace = e.detail ? Colorspace.P3 : Colorspace.Srgb)}
isEdited={config.thumbnail.colorspace !== savedConfig.thumbnail.colorspace}
/>
</div>
<div class="ml-4">
<SettingButtonsRow
on:reset={({ detail }) => handleReset(detail)}
on:save={saveSetting}
showResetToDefault={!isEqual(savedConfig, defaultConfig)}
{disabled}
/>
</div>
</form>
</div>
{/await}
<div class="ml-4">
<SettingButtonsRow
on:reset={({ detail }) => dispatch('reset', { ...detail, configKeys: ['thumbnail'] })}
on:save={() => dispatch('save', { thumbnail: config.thumbnail })}
showResetToDefault={!isEqual(savedConfig, defaultConfig)}
{disabled}
/>
</div>
</form>
</div>
</div>