chore(server,cli,web): housekeeping and stricter code style (#6751)

* add unicorn to eslint

* fix lint errors for cli

* fix merge

* fix album name extraction

* Update cli/src/commands/upload.command.ts

Co-authored-by: Ben McCann <322311+benmccann@users.noreply.github.com>

* es2k23

* use lowercase os

* return undefined album name

* fix bug in asset response dto

* auto fix issues

* fix server code style

* es2022 and formatting

* fix compilation error

* fix test

* fix config load

* fix last lint errors

* set string type

* bump ts

* start work on web

* web formatting

* Fix UUIDParamDto as UUIDParamDto

* fix library service lint

* fix web errors

* fix errors

* formatting

* wip

* lints fixed

* web can now start

* alphabetical package json

* rename error

* chore: clean up

---------

Co-authored-by: Ben McCann <322311+benmccann@users.noreply.github.com>
Co-authored-by: Jason Rasmussen <jrasm91@gmail.com>
This commit is contained in:
Jonathan Jogenfors 2024-02-02 04:18:00 +01:00 committed by GitHub
parent e4d0560d49
commit f44fa45aa0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
218 changed files with 2471 additions and 1244 deletions

View file

@ -26,7 +26,7 @@
const handleAddToNewAlbum = (albumName: string) => {
showAlbumPicker = false;
const assetIds = Array.from(getAssets()).map((asset) => asset.id);
const assetIds = [...getAssets()].map((asset) => asset.id);
api.albumApi.createAlbum({ createAlbumDto: { albumName, assetIds } }).then((response) => {
const { id, albumName } = response.data;
@ -43,7 +43,7 @@
const handleAddToAlbum = async (album: AlbumResponseDto) => {
showAlbumPicker = false;
const assetIds = Array.from(getAssets()).map((asset) => asset.id);
const assetIds = [...getAssets()].map((asset) => asset.id);
await addAssetsToAlbum(album.id, assetIds);
clearSelect();
};

View file

@ -28,7 +28,7 @@
loading = true;
try {
const assets = Array.from(getOwnedAssets()).filter((asset) => asset.isArchived !== isArchived);
const assets = [...getOwnedAssets()].filter((asset) => asset.isArchived !== isArchived);
const ids = assets.map(({ id }) => id);
if (ids.length > 0) {

View file

@ -16,11 +16,11 @@
const { clearSelect, getOwnedAssets } = getAssetControlContext();
$: isAllVideos = Array.from(getOwnedAssets()).every((asset) => asset.type === AssetTypeEnum.Video);
$: isAllVideos = [...getOwnedAssets()].every((asset) => asset.type === AssetTypeEnum.Video);
const handleRunJob = async (name: AssetJobName) => {
try {
const ids = Array.from(getOwnedAssets()).map(({ id }) => id);
const ids = [...getOwnedAssets()].map(({ id }) => id);
await api.assetApi.runAssetJobs({ assetJobsDto: { assetIds: ids, name } });
notificationController.show({ message: api.getAssetJobMessage(name), type: NotificationType.Info });
clearSelect();

View file

@ -20,7 +20,7 @@
{#if showModal}
<CreateSharedLinkModal
assetIds={Array.from(getAssets()).map(({ id }) => id)}
assetIds={[...getAssets()].map(({ id }) => id)}
on:close={() => (showModal = false)}
on:escape={escape}
/>

View file

@ -32,9 +32,7 @@
const handleDelete = async () => {
loading = true;
const ids = Array.from(getOwnedAssets())
.filter((a) => !a.isExternal)
.map((a) => a.id);
const ids = [...getOwnedAssets()].filter((a) => !a.isExternal).map((a) => a.id);
await deleteAssets(force, onAssetDelete, ids);
clearSelect();
isShowConfirmation = false;

View file

@ -11,7 +11,7 @@
const { getAssets, clearSelect } = getAssetControlContext();
const handleDownloadFiles = async () => {
const assets = Array.from(getAssets());
const assets = [...getAssets()];
if (assets.length === 1) {
clearSelect();
await downloadFile(assets[0]);

View file

@ -28,7 +28,7 @@
loading = true;
try {
const assets = Array.from(getOwnedAssets()).filter((asset) => asset.isFavorite !== isFavorite);
const assets = [...getOwnedAssets()].filter((asset) => asset.isFavorite !== isFavorite);
const ids = assets.map(({ id }) => id);

View file

@ -11,7 +11,7 @@
import { mdiDeleteOutline } from '@mdi/js';
export let album: AlbumResponseDto;
export let onRemove: ((assetIds: string[]) => void) | undefined = undefined;
export let onRemove: ((assetIds: string[]) => void) | undefined;
export let menuItem = false;
const { getAssets, clearSelect } = getAssetControlContext();
@ -20,7 +20,7 @@
const removeFromAlbum = async () => {
try {
const ids = Array.from(getAssets()).map((a) => a.id);
const ids = [...getAssets()].map((a) => a.id);
const { data: results } = await api.albumApi.removeAssetFromAlbum({
id: album.id,
bulkIdsDto: { ids },
@ -38,8 +38,8 @@
});
clearSelect();
} catch (e) {
console.error('Error [album-viewer] [removeAssetFromAlbum]', e);
} catch (error) {
console.error('Error [album-viewer] [removeAssetFromAlbum]', error);
notificationController.show({
type: NotificationType.Error,
message: 'Error removing assets from album, check console for more details',

View file

@ -18,7 +18,7 @@
const { data: results } = await api.sharedLinkApi.removeSharedLinkAssets({
id: sharedLink.id,
assetIdsDto: {
assetIds: Array.from(getAssets()).map((asset) => asset.id),
assetIds: [...getAssets()].map((asset) => asset.id),
},
key: api.getKey(),
});

View file

@ -11,7 +11,7 @@
import { mdiHistory } from '@mdi/js';
import type { OnRestore } from '$lib/utils/actions';
export let onRestore: OnRestore | undefined = undefined;
export let onRestore: OnRestore | undefined;
const { getAssets, clearSelect } = getAssetControlContext();
@ -21,7 +21,7 @@
loading = true;
try {
const ids = Array.from(getAssets()).map((a) => a.id);
const ids = [...getAssets()].map((a) => a.id);
await api.trashApi.restoreAssets({ bulkIdsDto: { ids } });
onRestore?.(ids);
@ -31,8 +31,8 @@
});
clearSelect();
} catch (e) {
handleError(e, 'Error restoring assets');
} catch (error) {
handleError(error, 'Error restoring assets');
} finally {
loading = false;
}

View file

@ -28,8 +28,8 @@
}
selecting = false;
} catch (e) {
handleError(e, 'Error selecting all assets');
} catch (error) {
handleError(error, 'Error selecting all assets');
}
};
</script>

View file

@ -9,13 +9,13 @@
import { handleError } from '$lib/utils/handle-error';
import type { OnStack } from '$lib/utils/actions';
export let onStack: OnStack | undefined = undefined;
export let onStack: OnStack | undefined;
const { clearSelect, getOwnedAssets } = getAssetControlContext();
const handleStack = async () => {
try {
const assets = Array.from(getOwnedAssets());
const assets = [...getOwnedAssets()];
const parent = assets.at(0);
if (parent == undefined) {
@ -33,7 +33,7 @@
for (const asset of children) {
asset.stackParentId = parent?.id;
// Add grand-children's count to new parent
childrenCount += asset.stackCount == null ? 1 : asset.stackCount + 1;
childrenCount += asset.stackCount == undefined ? 1 : asset.stackCount + 1;
// Reset children stack info
asset.stackCount = null;
asset.stack = [];

View file

@ -48,13 +48,16 @@
$: geometry = (() => {
const geometry = [];
for (let group of assetsGroupByDate) {
const justifiedLayoutResult = justifiedLayout(group.map(getAssetRatio), {
boxSpacing: 2,
containerWidth: Math.floor(viewport.width),
containerPadding: 0,
targetRowHeightTolerance: 0.15,
targetRowHeight: 235,
});
const justifiedLayoutResult = justifiedLayout(
group.map((assetGroup) => getAssetRatio(assetGroup)),
{
boxSpacing: 2,
containerWidth: Math.floor(viewport.width),
containerPadding: 0,
targetRowHeightTolerance: 0.15,
targetRowHeight: 235,
},
);
geometry.push({
...justifiedLayoutResult,
containerWidth: calculateWidth(justifiedLayoutResult.boxes),

View file

@ -44,9 +44,7 @@
$: timelineY = element?.scrollTop || 0;
$: isEmpty = $assetStore.initialized && $assetStore.buckets.length === 0;
$: idsSelectedAssets = Array.from($selectedAssets)
.filter((a) => !a.isExternal)
.map((a) => a.id);
$: idsSelectedAssets = [...$selectedAssets].filter((a) => !a.isExternal).map((a) => a.id);
const onKeyboardPress = (event: KeyboardEvent) => handleKeyboardPress(event);
const dispatch = createEventDispatcher<{ select: AssetResponseDto; escape: void }>();
@ -86,20 +84,23 @@
if (!$showAssetViewer) {
switch (key) {
case 'Escape':
case 'Escape': {
dispatch('escape');
return;
case '?':
}
case '?': {
if (event.shiftKey) {
event.preventDefault();
showShortcuts = !showShortcuts;
}
return;
case '/':
}
case '/': {
event.preventDefault();
goto(AppRoute.EXPLORE);
return;
case 'Delete':
}
case 'Delete': {
if ($isMultiSelectState) {
let force = false;
if (shiftKey || !isTrashEnabled) {
@ -113,6 +114,7 @@
trashOrDelete(force);
}
return;
}
}
}
};
@ -124,8 +126,8 @@
};
function intersectedHandler(event: CustomEvent) {
const el = event.detail.container as HTMLElement;
const target = el.firstChild as HTMLElement;
const element_ = event.detail.container as HTMLElement;
const target = element_.firstChild as HTMLElement;
if (target) {
const bucketDate = target.id.split('_')[1];
assetStore.loadBucket(bucketDate, event.detail.position);
@ -160,24 +162,27 @@
switch (action) {
case removeAction:
case AssetAction.TRASH:
case AssetAction.DELETE:
case AssetAction.DELETE: {
// find the next asset to show or close the viewer
(await handleNext()) || (await handlePrevious()) || handleClose();
// delete after find the next one
assetStore.removeAsset(asset.id);
break;
}
case AssetAction.ARCHIVE:
case AssetAction.UNARCHIVE:
case AssetAction.FAVORITE:
case AssetAction.UNFAVORITE:
case AssetAction.UNFAVORITE: {
assetStore.updateAsset(asset);
break;
}
case AssetAction.ADD:
case AssetAction.ADD: {
assetStore.addAsset(asset);
break;
}
}
};
@ -392,7 +397,7 @@
<div class="mt-8 animate-pulse">
<div class="mb-2 h-4 w-24 rounded-full bg-immich-primary/20 dark:bg-immich-dark-primary/20" />
<div class="flex w-[120%] flex-wrap">
{#each Array(100) as _}
{#each Array.from({ length: 100 }) as _}
<div class="m-[1px] h-[10em] w-[16em] bg-immich-primary/20 dark:bg-immich-dark-primary/20" />
{/each}
</div>

View file

@ -25,7 +25,7 @@
setContext({
getAssets: () => assets,
getOwnedAssets: () =>
ownerId !== undefined ? new Set(Array.from(assets).filter((asset) => asset.ownerId === ownerId)) : assets,
ownerId === undefined ? assets : new Set([...assets].filter((asset) => asset.ownerId === ownerId)),
clearSelect,
});
</script>

View file

@ -69,10 +69,10 @@
{/if}
<div class="inline-block" bind:offsetWidth={innerWidth}>
{#each $memoryStore as memory, i (memory.title)}
{#each $memoryStore as memory, index (memory.title)}
<button
class="memory-card relative mr-8 inline-block aspect-video h-[215px] rounded-xl"
on:click={() => goto(`${AppRoute.MEMORY}?${QueryParameter.MEMORY_INDEX}=${i}`)}
on:click={() => goto(`${AppRoute.MEMORY}?${QueryParameter.MEMORY_INDEX}=${index}`)}
>
<img
class="h-full w-full rounded-xl object-cover"