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:
committed by
GitHub
parent
e4d0560d49
commit
f44fa45aa0
@@ -227,11 +227,8 @@
|
||||
};
|
||||
|
||||
const handleChangeListMode = () => {
|
||||
if ($albumViewSettings.view === AlbumViewMode.Cover) {
|
||||
$albumViewSettings.view = AlbumViewMode.List;
|
||||
} else {
|
||||
$albumViewSettings.view = AlbumViewMode.Cover;
|
||||
}
|
||||
$albumViewSettings.view =
|
||||
$albumViewSettings.view === AlbumViewMode.Cover ? AlbumViewMode.List : AlbumViewMode.Cover;
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -285,14 +282,14 @@
|
||||
</div>
|
||||
</LinkButton>
|
||||
</div>
|
||||
{#if $albums.length !== 0}
|
||||
{#if $albums.length > 0}
|
||||
<!-- Album Card -->
|
||||
{#if $albumViewSettings.view === AlbumViewMode.Cover}
|
||||
<div class="grid grid-cols-[repeat(auto-fill,minmax(14rem,1fr))]">
|
||||
{#each $albums as album, idx (album.id)}
|
||||
{#each $albums as album, index (album.id)}
|
||||
<a data-sveltekit-preload-data="hover" href="{AppRoute.ALBUMS}/{album.id}" animate:flip={{ duration: 200 }}>
|
||||
<AlbumCard
|
||||
preload={idx < 20}
|
||||
preload={index < 20}
|
||||
{album}
|
||||
on:showalbumcontextmenu={(e) => showAlbumContextMenu(e.detail, album)}
|
||||
/>
|
||||
|
||||
@@ -111,14 +111,10 @@
|
||||
const { selectedAssets: timelineSelected } = timelineInteractionStore;
|
||||
|
||||
$: isOwned = $user.id == album.ownerId;
|
||||
$: isAllUserOwned = Array.from($selectedAssets).every((asset) => asset.ownerId === $user.id);
|
||||
$: isAllFavorite = Array.from($selectedAssets).every((asset) => asset.isFavorite);
|
||||
$: isAllUserOwned = [...$selectedAssets].every((asset) => asset.ownerId === $user.id);
|
||||
$: isAllFavorite = [...$selectedAssets].every((asset) => asset.isFavorite);
|
||||
$: {
|
||||
if (isShowActivity) {
|
||||
assetGridWidth = globalWidth - (globalWidth < 768 ? 360 : 460);
|
||||
} else {
|
||||
assetGridWidth = globalWidth;
|
||||
}
|
||||
assetGridWidth = isShowActivity ? globalWidth - (globalWidth < 768 ? 360 : 460) : globalWidth;
|
||||
}
|
||||
$: showActivityStatus =
|
||||
album.sharedUsers.length > 0 && !$showAssetViewer && (album.isActivityEnabled || $numberOfComments > 0);
|
||||
@@ -157,7 +153,7 @@
|
||||
message: `Activity is ${album.isActivityEnabled ? 'enabled' : 'disabled'}`,
|
||||
});
|
||||
} catch (error) {
|
||||
handleError(error, `Can't ${!album.isActivityEnabled ? 'enable' : 'disable'} activity`);
|
||||
handleError(error, `Can't ${album.isActivityEnabled ? 'disable' : 'enable'} activity`);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -224,10 +220,11 @@
|
||||
}
|
||||
const ctrl = event.ctrlKey;
|
||||
switch (event.key) {
|
||||
case 'Enter':
|
||||
case 'Enter': {
|
||||
if (ctrl && event.target === textArea) {
|
||||
textArea.blur();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -302,7 +299,7 @@
|
||||
};
|
||||
|
||||
const handleAddAssets = async () => {
|
||||
const assetIds = Array.from($timelineSelected).map((asset) => asset.id);
|
||||
const assetIds = [...$timelineSelected].map((asset) => asset.id);
|
||||
|
||||
try {
|
||||
const { data: results } = await api.albumApi.addAssetsToAlbum({
|
||||
@@ -352,7 +349,7 @@
|
||||
const { data } = await api.albumApi.addUsersToAlbum({
|
||||
id: album.id,
|
||||
addUsersDto: {
|
||||
sharedUserIds: Array.from(users).map(({ id }) => id),
|
||||
sharedUserIds: [...users].map(({ id }) => id),
|
||||
},
|
||||
});
|
||||
|
||||
@@ -373,8 +370,8 @@
|
||||
try {
|
||||
await refreshAlbum();
|
||||
viewMode = album.sharedUsers.length > 1 ? ViewMode.SELECT_USERS : ViewMode.VIEW;
|
||||
} catch (e) {
|
||||
handleError(e, 'Error deleting share users');
|
||||
} catch (error) {
|
||||
handleError(error, 'Error deleting share users');
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -20,7 +20,9 @@ describe('Albums BLoC', () => {
|
||||
afterEach(() => {
|
||||
const notifications = get(notificationController.notificationList);
|
||||
|
||||
notifications.forEach((notification) => notificationController.removeNotificationById(notification.id));
|
||||
for (const notification of notifications) {
|
||||
notificationController.removeNotificationById(notification.id);
|
||||
}
|
||||
});
|
||||
|
||||
it('inits with provided albums', () => {
|
||||
|
||||
@@ -3,10 +3,10 @@ import { notificationController, NotificationType } from '$lib/components/shared
|
||||
import { type AlbumResponseDto, api } from '@api';
|
||||
import { derived, get, writable } from 'svelte/store';
|
||||
|
||||
type AlbumsProps = { albums: AlbumResponseDto[] };
|
||||
type AlbumsProperties = { albums: AlbumResponseDto[] };
|
||||
|
||||
export const useAlbums = (props: AlbumsProps) => {
|
||||
const albums = writable([...props.albums]);
|
||||
export const useAlbums = (properties: AlbumsProperties) => {
|
||||
const albums = writable([...properties.albums]);
|
||||
const contextMenuPosition = writable<OnShowContextMenuDetail>({ x: 0, y: 0 });
|
||||
const contextMenuTargetAlbum = writable<AlbumResponseDto | undefined>();
|
||||
const isShowContextMenu = derived(contextMenuTargetAlbum, ($selectedAlbum) => !!$selectedAlbum);
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
const assetInteractionStore = createAssetInteractionStore();
|
||||
const { isMultiSelectState, selectedAssets } = assetInteractionStore;
|
||||
|
||||
$: isAllFavorite = Array.from($selectedAssets).every((asset) => asset.isFavorite);
|
||||
$: isAllFavorite = [...$selectedAssets].every((asset) => asset.isFavorite);
|
||||
</script>
|
||||
|
||||
{#if $isMultiSelectState}
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
const assetInteractionStore = createAssetInteractionStore();
|
||||
const { isMultiSelectState, selectedAssets } = assetInteractionStore;
|
||||
|
||||
$: isAllArchive = Array.from($selectedAssets).every((asset) => asset.isArchived);
|
||||
$: isAllArchive = [...$selectedAssets].every((asset) => asset.isArchived);
|
||||
</script>
|
||||
|
||||
<!-- Multiselection mode app bar -->
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
const assetStore = new AssetStore({ userId: data.partner.id, isArchived: false, withStacked: true });
|
||||
const assetInteractionStore = createAssetInteractionStore();
|
||||
const { isMultiSelectState, selectedAssets } = assetInteractionStore;
|
||||
const { isMultiSelectState, selectedAssets, clearMultiselect } = assetInteractionStore;
|
||||
|
||||
onDestroy(() => {
|
||||
assetInteractionStore.clearMultiselect();
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
<main class="grid h-screen bg-immich-bg pt-18 dark:bg-immich-dark-bg">
|
||||
{#if $isMultiSelectState}
|
||||
<AssetSelectControlBar assets={$selectedAssets} clearSelect={assetInteractionStore.clearMultiselect}>
|
||||
<AssetSelectControlBar assets={$selectedAssets} clearSelect={clearMultiselect}>
|
||||
<CreateSharedLink />
|
||||
<AssetSelectContextMenu icon={mdiPlus} title="Add">
|
||||
<AddToAlbum />
|
||||
|
||||
@@ -90,9 +90,10 @@
|
||||
return;
|
||||
}
|
||||
switch (event.key) {
|
||||
case 'Escape':
|
||||
case 'Escape': {
|
||||
handleCloseClick();
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -288,10 +289,8 @@
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (!force) {
|
||||
if (people.length < maximumLengthSearchPeople && searchName.startsWith(searchWord)) {
|
||||
return;
|
||||
}
|
||||
if (!force && people.length < maximumLengthSearchPeople && searchName.startsWith(searchWord)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const timeout = setTimeout(() => (isSearchingPeople = true), timeBeforeShowLoadingSpinner);
|
||||
@@ -417,7 +416,7 @@
|
||||
</FullScreenModal>
|
||||
{/if}
|
||||
|
||||
<UserPageLayout title="People" description={countTotalPeople !== 0 ? `(${countTotalPeople.toString()})` : undefined}>
|
||||
<UserPageLayout title="People" description={countTotalPeople === 0 ? undefined : `(${countTotalPeople.toString()})`}>
|
||||
<svelte:fragment slot="buttons">
|
||||
{#if countTotalPeople > 0}
|
||||
<div class="flex gap-2 items-center justify-center">
|
||||
@@ -445,11 +444,11 @@
|
||||
|
||||
{#if countVisiblePeople > 0}
|
||||
<div class="grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-5 xl:grid-cols-7 2xl:grid-cols-9 gap-1">
|
||||
{#each people as person, idx (person.id)}
|
||||
{#each people as person, index (person.id)}
|
||||
{#if !person.isHidden && (searchName ? searchedPeopleLocal.some((searchedPerson) => searchedPerson.id === person.id) : true)}
|
||||
<PeopleCard
|
||||
{person}
|
||||
preload={idx < 20}
|
||||
preload={index < 20}
|
||||
on:change-name={() => handleChangeName(person)}
|
||||
on:set-birth-date={() => handleSetBirthDate(person)}
|
||||
on:merge-people={() => handleMergePeople(person)}
|
||||
@@ -519,7 +518,7 @@
|
||||
screenHeight={innerHeight}
|
||||
>
|
||||
<div class="grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-5 xl:grid-cols-7 2xl:grid-cols-9 gap-1">
|
||||
{#each people as person, idx (person.id)}
|
||||
{#each people as person, index (person.id)}
|
||||
<button
|
||||
class="relative"
|
||||
on:click={() => (person.isHidden = !person.isHidden)}
|
||||
@@ -527,7 +526,7 @@
|
||||
on:mouseleave={() => (eyeColorMap[person.id] = 'white')}
|
||||
>
|
||||
<ImageThumbnail
|
||||
preload={searchName !== '' || idx < 20}
|
||||
preload={searchName !== '' || index < 20}
|
||||
bind:hidden={person.isHidden}
|
||||
shadow
|
||||
url={api.getPeopleThumbnailUrl(person.id)}
|
||||
|
||||
@@ -108,14 +108,14 @@
|
||||
isSearchingPeople = false;
|
||||
};
|
||||
|
||||
$: isAllArchive = Array.from($selectedAssets).every((asset) => asset.isArchived);
|
||||
$: isAllFavorite = Array.from($selectedAssets).every((asset) => asset.isFavorite);
|
||||
$: isAllArchive = [...$selectedAssets].every((asset) => asset.isArchived);
|
||||
$: isAllFavorite = [...$selectedAssets].every((asset) => asset.isFavorite);
|
||||
$: $onPersonThumbnail === data.person.id &&
|
||||
(thumbnailData = api.getPeopleThumbnailUrl(data.person.id) + `?now=${Date.now()}`);
|
||||
|
||||
$: {
|
||||
if (people) {
|
||||
suggestedPeople = !name ? [] : searchNameLocal(name, people, 5, data.person.id);
|
||||
suggestedPeople = name ? searchNameLocal(name, people, 5, data.person.id) : [];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -158,7 +158,7 @@
|
||||
});
|
||||
|
||||
const handleUnmerge = () => {
|
||||
$assetStore.removeAssets(Array.from($selectedAssets).map((a) => a.id));
|
||||
$assetStore.removeAssets([...$selectedAssets].map((a) => a.id));
|
||||
assetInteractionStore.clearMultiselect();
|
||||
viewMode = ViewMode.VIEW_ASSETS;
|
||||
};
|
||||
@@ -352,7 +352,7 @@
|
||||
|
||||
{#if viewMode === ViewMode.UNASSIGN_ASSETS}
|
||||
<UnMergeFaceSelector
|
||||
assetIds={Array.from($selectedAssets).map((a) => a.id)}
|
||||
assetIds={[...$selectedAssets].map((a) => a.id)}
|
||||
personAssets={data.person}
|
||||
on:close={() => (viewMode = ViewMode.VIEW_ASSETS)}
|
||||
on:confirm={handleUnmerge}
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
const assetInteractionStore = createAssetInteractionStore();
|
||||
const { isMultiSelectState, selectedAssets } = assetInteractionStore;
|
||||
|
||||
$: isAllFavorite = Array.from($selectedAssets).every((asset) => asset.isFavorite);
|
||||
$: isAllFavorite = [...$selectedAssets].every((asset) => asset.isFavorite);
|
||||
|
||||
const handleEscape = () => {
|
||||
if ($showAssetViewer) {
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
}
|
||||
if (!$showAssetViewer) {
|
||||
switch (event.key) {
|
||||
case 'Escape':
|
||||
case 'Escape': {
|
||||
if (isMultiSelectionMode) {
|
||||
selectedAssets = new Set();
|
||||
return;
|
||||
@@ -66,6 +66,7 @@
|
||||
}
|
||||
$preventRaceConditionSearchBar = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -96,8 +97,8 @@
|
||||
|
||||
let selectedAssets: Set<AssetResponseDto> = new Set();
|
||||
$: isMultiSelectionMode = selectedAssets.size > 0;
|
||||
$: isAllArchived = Array.from(selectedAssets).every((asset) => asset.isArchived);
|
||||
$: isAllFavorite = Array.from(selectedAssets).every((asset) => asset.isFavorite);
|
||||
$: isAllArchived = [...selectedAssets].every((asset) => asset.isArchived);
|
||||
$: isAllFavorite = [...selectedAssets].every((asset) => asset.isFavorite);
|
||||
$: searchResultAssets = data.results?.assets.items;
|
||||
|
||||
const onAssetDelete = (assetId: string) => {
|
||||
@@ -140,14 +141,14 @@
|
||||
|
||||
<section class="relative mb-12 bg-immich-bg pt-32 dark:bg-immich-dark-bg">
|
||||
<section class="immich-scrollbar relative overflow-y-auto">
|
||||
{#if albums && albums.length}
|
||||
{#if albums && albums.length > 0}
|
||||
<section>
|
||||
<div class="ml-6 text-4xl font-medium text-black/70 dark:text-white/80">ALBUMS</div>
|
||||
<div class="grid grid-cols-[repeat(auto-fill,minmax(14rem,1fr))]">
|
||||
{#each albums as album, idx (album.id)}
|
||||
{#each albums as album, index (album.id)}
|
||||
<a data-sveltekit-preload-data="hover" href={`albums/${album.id}`} animate:flip={{ duration: 200 }}>
|
||||
<AlbumCard
|
||||
preload={idx < 20}
|
||||
preload={index < 20}
|
||||
{album}
|
||||
isSharingView={false}
|
||||
showItemCount={false}
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
import { user } from '$lib/stores/user.store';
|
||||
|
||||
export let data: PageData;
|
||||
let { sharedLink, passwordRequired, sharedLinkKey: key } = data;
|
||||
let { title, description } = data.meta;
|
||||
let { sharedLink, passwordRequired, sharedLinkKey: key, meta } = data;
|
||||
let { title, description } = meta;
|
||||
let isOwned = $user ? $user.id === sharedLink?.userId : false;
|
||||
let password = '';
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { getAuthUser } from '$lib/utils/auth';
|
||||
import { api, ThumbnailFormat } from '@api';
|
||||
import { error } from '@sveltejs/kit';
|
||||
import type { AxiosError } from 'axios';
|
||||
import type { PageLoad } from './$types';
|
||||
import { error as throwError } from '@sveltejs/kit';
|
||||
|
||||
export const load = (async ({ params }) => {
|
||||
const { key } = params;
|
||||
@@ -24,10 +24,10 @@ export const load = (async ({ params }) => {
|
||||
: '/feature-panel.png',
|
||||
},
|
||||
};
|
||||
} catch (e) {
|
||||
} catch (error) {
|
||||
// handle unauthorized error
|
||||
// TODO this doesn't allow for 404 shared links anymore
|
||||
if ((e as AxiosError).response?.status === 401) {
|
||||
if ((error as AxiosError).response?.status === 401) {
|
||||
return {
|
||||
passwordRequired: true,
|
||||
sharedLinkKey: key,
|
||||
@@ -37,7 +37,7 @@ export const load = (async ({ params }) => {
|
||||
};
|
||||
}
|
||||
|
||||
error(404, {
|
||||
throwError(404, {
|
||||
message: 'Invalid shared link',
|
||||
});
|
||||
}
|
||||
|
||||
@@ -28,13 +28,13 @@
|
||||
});
|
||||
|
||||
goto(`${AppRoute.ALBUMS}/${newAlbum.id}`);
|
||||
} catch (e) {
|
||||
} catch (error) {
|
||||
notificationController.show({
|
||||
message: 'Error creating album, check console for more details',
|
||||
type: NotificationType.Error,
|
||||
});
|
||||
|
||||
console.log('Error [createAlbum] ', e);
|
||||
console.log('Error [createAlbum]', error);
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -94,9 +94,9 @@
|
||||
<div>
|
||||
<!-- Share Album List -->
|
||||
<div class="grid grid-cols-[repeat(auto-fill,minmax(14rem,1fr))]">
|
||||
{#each data.sharedAlbums as album, idx (album.id)}
|
||||
{#each data.sharedAlbums as album, index (album.id)}
|
||||
<a data-sveltekit-preload-data="hover" href={`albums/${album.id}`} animate:flip={{ duration: 200 }}>
|
||||
<AlbumCard preload={idx < 20} {album} isSharingView showContextMenu={false} />
|
||||
<AlbumCard preload={index < 20} {album} isSharingView showContextMenu={false} />
|
||||
</a>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
@@ -43,8 +43,8 @@
|
||||
message: `Empty trash initiated. Refresh the page to see the changes`,
|
||||
type: NotificationType.Info,
|
||||
});
|
||||
} catch (e) {
|
||||
handleError(e, 'Error emptying trash');
|
||||
} catch (error) {
|
||||
handleError(error, 'Error emptying trash');
|
||||
}
|
||||
};
|
||||
|
||||
@@ -56,8 +56,8 @@
|
||||
message: `Restore trash initiated. Refresh the page to see the changes`,
|
||||
type: NotificationType.Info,
|
||||
});
|
||||
} catch (e) {
|
||||
handleError(e, 'Error restoring trash');
|
||||
} catch (error) {
|
||||
handleError(error, 'Error restoring trash');
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
onMount(async () => {
|
||||
await load();
|
||||
timer = setInterval(load, 5_000);
|
||||
timer = setInterval(load, 5000);
|
||||
});
|
||||
|
||||
onDestroy(() => {
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
downloadManager.add(downloadKey, blob.size);
|
||||
downloadManager.update(downloadKey, blob.size);
|
||||
downloadBlob(blob, downloadKey);
|
||||
setTimeout(() => downloadManager.clear(downloadKey), 5_000);
|
||||
setTimeout(() => downloadManager.clear(downloadKey), 5000);
|
||||
}
|
||||
|
||||
if (orphans.length > 0) {
|
||||
@@ -53,7 +53,7 @@
|
||||
downloadManager.add(downloadKey, blob.size);
|
||||
downloadManager.update(downloadKey, blob.size);
|
||||
downloadBlob(blob, downloadKey);
|
||||
setTimeout(() => downloadManager.clear(downloadKey), 5_000);
|
||||
setTimeout(() => downloadManager.clear(downloadKey), 5000);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -130,9 +130,9 @@
|
||||
|
||||
try {
|
||||
const chunkSize = 10;
|
||||
const filenames = [...extras.filter(({ checksum }) => !checksum).map(({ filename }) => filename)];
|
||||
for (let i = 0; i < filenames.length; i += chunkSize) {
|
||||
count += await loadAndMatch(filenames.slice(i, i + chunkSize));
|
||||
const filenames = extras.filter(({ checksum }) => !checksum).map(({ filename }) => filename);
|
||||
for (let index = 0; index < filenames.length; index += chunkSize) {
|
||||
count += await loadAndMatch(filenames.slice(index, index + chunkSize));
|
||||
}
|
||||
} catch (error) {
|
||||
handleError(error, 'Unable to check items');
|
||||
@@ -218,7 +218,7 @@
|
||||
<tr class="flex w-full place-items-center p-2 md:p-5">
|
||||
<th class="w-full text-sm place-items-center font-medium flex justify-between" colspan="2">
|
||||
<div class="px-3">
|
||||
<p>MATCHES {matches.length ? `(${matches.length})` : ''}</p>
|
||||
<p>MATCHES {matches.length > 0 ? `(${matches.length})` : ''}</p>
|
||||
<p class="text-gray-600 dark:text-gray-300 mt-1">These files are matched by their checksums</p>
|
||||
</div>
|
||||
</th>
|
||||
@@ -252,7 +252,7 @@
|
||||
<tr class="flex w-full place-items-center p-1 md:p-5">
|
||||
<th class="w-full text-sm font-medium justify-between place-items-center flex" colspan="2">
|
||||
<div class="px-3">
|
||||
<p>OFFLINE PATHS {orphans.length ? `(${orphans.length})` : ''}</p>
|
||||
<p>OFFLINE PATHS {orphans.length > 0 ? `(${orphans.length})` : ''}</p>
|
||||
<p class="text-gray-600 dark:text-gray-300 mt-1">
|
||||
These files are the results of manually deletion of the default upload library
|
||||
</p>
|
||||
@@ -290,7 +290,7 @@
|
||||
<tr class="flex w-full place-items-center p-2 md:p-5">
|
||||
<th class="w-full text-sm font-medium place-items-center flex justify-between" colspan="2">
|
||||
<div class="px-3">
|
||||
<p>UNTRACKS FILES {extras.length ? `(${extras.length})` : ''}</p>
|
||||
<p>UNTRACKS FILES {extras.length > 0 ? `(${extras.length})` : ''}</p>
|
||||
<p class="text-gray-600 dark:text-gray-300 mt-1">
|
||||
These files are not tracked by the application. They can be the results of failed moves,
|
||||
interrupted uploads, or left behind due to a bug
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
downloadManager.add(downloadKey, blob.size);
|
||||
downloadManager.update(downloadKey, blob.size);
|
||||
downloadBlob(blob, downloadKey);
|
||||
setTimeout(() => downloadManager.clear(downloadKey), 5_000);
|
||||
setTimeout(() => downloadManager.clear(downloadKey), 5000);
|
||||
};
|
||||
|
||||
const settings = [
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
});
|
||||
|
||||
const isDeleted = (user: UserResponseDto): boolean => {
|
||||
return user.deletedAt != null;
|
||||
return user.deletedAt != undefined;
|
||||
};
|
||||
|
||||
const deleteDateFormat: Intl.DateTimeFormatOptions = {
|
||||
@@ -41,7 +41,7 @@
|
||||
};
|
||||
|
||||
const getDeleteDate = (user: UserResponseDto): string => {
|
||||
let deletedAt = new Date(user.deletedAt ? user.deletedAt : Date.now());
|
||||
let deletedAt = new Date(user.deletedAt ?? Date.now());
|
||||
deletedAt.setDate(deletedAt.getDate() + 7);
|
||||
return deletedAt.toLocaleString($locale, deleteDateFormat);
|
||||
};
|
||||
@@ -188,13 +188,13 @@
|
||||
</thead>
|
||||
<tbody class="block max-h-[320px] w-full overflow-y-auto rounded-md border dark:border-immich-dark-gray">
|
||||
{#if allUsers}
|
||||
{#each allUsers as immichUser, i}
|
||||
{#each allUsers as immichUser, index}
|
||||
<tr
|
||||
class="flex h-[80px] overflow-hidden w-full place-items-center text-center dark:text-immich-dark-fg {isDeleted(
|
||||
immichUser,
|
||||
)
|
||||
? 'bg-red-300 dark:bg-red-900'
|
||||
: i % 2 == 0
|
||||
: index % 2 == 0
|
||||
? 'bg-immich-gray dark:bg-immich-dark-gray/75'
|
||||
: 'bg-immich-bg dark:bg-immich-dark-gray/50'}"
|
||||
>
|
||||
|
||||
@@ -22,8 +22,8 @@
|
||||
|
||||
$: {
|
||||
const stepState = $page.url.searchParams.get('step');
|
||||
const tempIndex = onboardingSteps.findIndex((step) => step.name === stepState);
|
||||
index = tempIndex >= 0 ? tempIndex : 0;
|
||||
const temporaryIndex = onboardingSteps.findIndex((step) => step.name === stepState);
|
||||
index = temporaryIndex >= 0 ? temporaryIndex : 0;
|
||||
}
|
||||
|
||||
const handleDoneClicked = async () => {
|
||||
|
||||
Reference in New Issue
Block a user