chore: enforce strict equality checks (#30718)

This commit is contained in:
Daniel Dietzler 2026-08-11 19:15:51 +02:00 committed by GitHub
parent 00d10dab63
commit a55dc80a56
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
35 changed files with 54 additions and 45 deletions

View file

@ -40,7 +40,7 @@ export function useActions(node: HTMLElement | SVGElement, actions: ActionArray)
return {
update(actions: ActionArray) {
if ((actions?.length || 0) != actionReturns.length) {
if ((actions?.length || 0) !== actionReturns.length) {
throw new Error('You must not change the length of an actions array.');
}

View file

@ -99,7 +99,7 @@
};
$effect(() => {
if (assetId && previousAssetId != assetId) {
if (assetId && previousAssetId !== assetId) {
previousAssetId = assetId;
}
});
@ -168,7 +168,7 @@
{/if}
</div>
{#if (index != activityManager.activities.length - 1 && !shouldGroup(activityManager.activities[index].createdAt, activityManager.activities[index + 1].createdAt)) || index === activityManager.activities.length - 1}
{#if (index !== activityManager.activities.length - 1 && !shouldGroup(activityManager.activities[index].createdAt, activityManager.activities[index + 1].createdAt)) || index === activityManager.activities.length - 1}
<div
class="w-full px-2 pt-1 text-right text-sm text-gray-500 dark:text-gray-300"
title={new Date(reaction.createdAt).toLocaleDateString(undefined, timeOptions)}
@ -217,7 +217,7 @@
</div>
{/if}
</div>
{#if (index != activityManager.activities.length - 1 && isTenMinutesApart(activityManager.activities[index].createdAt, activityManager.activities[index + 1].createdAt)) || index === activityManager.activities.length - 1}
{#if (index !== activityManager.activities.length - 1 && isTenMinutesApart(activityManager.activities[index].createdAt, activityManager.activities[index + 1].createdAt)) || index === activityManager.activities.length - 1}
<div
class="w-full px-2 pt-1 text-right text-sm text-gray-500 dark:text-gray-300"
title={new Date(reaction.createdAt).toLocaleDateString(navigator.language, timeOptions)}

View file

@ -521,7 +521,7 @@
</div>
{/if}
{#if $slideshowState != SlideshowState.None}
{#if $slideshowState !== SlideshowState.None}
<div class="absolute inset-s-0 top-0 flex w-full justify-start">
<SlideshowBar
{isFullScreen}

View file

@ -76,7 +76,7 @@
<img src={poster} alt="poster" class="m-4 rounded-xl" />
<div class="flex place-content-center place-items-center">
{#if castManager.castState == CastState.BUFFERING}
{#if castManager.castState === CastState.BUFFERING}
<div class="p-3">
<LoadingSpinner />
</div>
@ -85,9 +85,9 @@
color="primary"
shape="round"
variant="ghost"
icon={castManager.castState == CastState.PLAYING ? mdiPause : mdiPlay}
icon={castManager.castState === CastState.PLAYING ? mdiPause : mdiPlay}
onclick={() => handlePlayPauseButton()}
aria-label={castManager.castState == CastState.PLAYING ? 'Pause' : 'Play'}
aria-label={castManager.castState === CastState.PLAYING ? 'Pause' : 'Play'}
/>
{/if}

View file

@ -357,7 +357,7 @@
</div>
{/if}
</div>
{#if face.person != null}
{#if face.person !== null}
<div class="absolute inset-e-[-3px] top-8 size-5 rounded-full">
<IconButton
shape="round"

View file

@ -15,7 +15,7 @@
const id = generateId();
const onInput = () => {
if (lat != null && lng != null) {
if (lat !== undefined && lng !== undefined) {
onUpdate(lat, lng);
}
};

View file

@ -287,7 +287,7 @@
if (previousStyle) {
// Preserves the custom map markers from the previous style when the theme is switched
// Required until https://github.com/dimfeld/svelte-maplibre/issues/146 is fixed
const customLayers = previousStyle.layers.filter((l) => l.type == 'fill' && l.source == 'geojson');
const customLayers = previousStyle.layers.filter((l) => l.type === 'fill' && l.source === 'geojson');
const layers = nextStyle.layers.concat(customLayers);
const sources = nextStyle.sources;

View file

@ -23,7 +23,7 @@
let { key, values = {}, children }: Props = $props();
const getLocale = (locale?: string | null) => {
if (locale == null) {
if (!locale) {
throw new Error('Cannot format a message without first setting the initial locale.');
}

View file

@ -6,7 +6,7 @@ describe('i18n', () => {
const languageFiles = readdirSync('../i18n').sort();
for (const filename of languageFiles) {
test(`${filename} should have a loader`, async () => {
if (!filename.endsWith('.json') || filename == 'package.json') {
if (!filename.endsWith('.json') || filename === 'package.json') {
return;
}

View file

@ -55,7 +55,7 @@ export abstract class VirtualScrollManager {
}
#setHeaderHeight(value: number) {
if (this.#headerHeight == value) {
if (this.#headerHeight === value) {
return false;
}
this.#headerHeight = value;
@ -67,7 +67,7 @@ export abstract class VirtualScrollManager {
}
#setGap(value: number) {
if (this.#gap == value) {
if (this.#gap === value) {
return false;
}
this.#gap = value;
@ -79,7 +79,7 @@ export abstract class VirtualScrollManager {
}
#setRowHeight(value: number) {
if (this.#rowHeight == value) {
if (this.#rowHeight === value) {
return false;
}
this.#rowHeight = value;

View file

@ -13,6 +13,7 @@
const { point, assetCount, onClose }: Props = $props();
const hasExistingLocations = $derived(
// eslint-disable-next-line eqeqeq
assetMultiSelectManager.assets.some((asset) => asset.latitude != null || asset.longitude != null),
);
</script>

View file

@ -95,7 +95,7 @@ function zoneOptionForDate(zone: string, date: string) {
function sortTwoZones(zoneA: ZoneOption, zoneB: ZoneOption) {
const offsetDifference = zoneA.offsetMinutes - zoneB.offsetMinutes;
if (offsetDifference != 0) {
if (offsetDifference !== 0) {
return offsetDifference;
}
return zoneA.value.localeCompare(zoneB.value, undefined, { sensitivity: 'base' });

View file

@ -67,7 +67,7 @@ function createUploadStore() {
const updateAssetMap = (id: string, mapper: (assets: UploadAsset) => UploadAsset) => {
uploadAssets.update((uploadingAssets) => {
return uploadingAssets.map((asset) => {
if (asset.id == id) {
if (asset.id === id) {
return mapper(asset);
}
return asset;
@ -111,7 +111,7 @@ function createUploadStore() {
});
}
return uploadingAsset.filter((a) => a.id != id);
return uploadingAsset.filter((a) => a.id !== id);
});
};

View file

@ -68,7 +68,7 @@ const undoDeleteAssets = async (onUndoDelete: OnUndoDelete, assets: TimelineAsse
* @param {StackResponse} stackResponse - The stack response containing the stack and assets to delete.
*/
export function updateStackedAssetInTimeline(timelineManager: TimelineManager, { stack, toDeleteIds }: StackResponse) {
if (stack == undefined) {
if (stack === undefined) {
return;
}

View file

@ -147,6 +147,7 @@ const metadataFields = [
titleKey: 'gps',
keys: ['latitude', 'longitude'],
render: (asset, $t) =>
// eslint-disable-next-line eqeqeq
asset.exifInfo?.latitude != null && asset.exifInfo?.longitude != null
? `${asset.exifInfo.latitude.toFixed(4)}, ${asset.exifInfo.longitude.toFixed(4)}`
: $t('unknown'),
@ -173,18 +174,21 @@ const metadataFields = [
icon: mdiCameraIris,
titleKey: 'f_number',
keys: ['fNumber'],
// eslint-disable-next-line eqeqeq
render: (asset, $t) => (asset.exifInfo?.fNumber == null ? $t('unknown') : `f/${asset.exifInfo.fNumber.toFixed(1)}`),
},
{
icon: mdiRayStartArrow,
titleKey: 'focal_length',
keys: ['focalLength'],
// eslint-disable-next-line eqeqeq
render: (asset, $t) => (asset.exifInfo?.focalLength == null ? $t('unknown') : `${asset.exifInfo.focalLength} mm`),
},
{
icon: mdiBrightness6,
titleKey: 'iso',
keys: ['iso'],
// eslint-disable-next-line eqeqeq
render: (asset, $t) => (asset.exifInfo?.iso == null ? $t('unknown') : `ISO ${asset.exifInfo.iso}`),
},
{
@ -203,6 +207,7 @@ const metadataFields = [
icon: mdiStarOutline,
titleKey: 'rating',
keys: ['rating'],
// eslint-disable-next-line eqeqeq
render: (asset, $t) => (asset.exifInfo?.rating == null ? $t('unknown') : `${asset.exifInfo.rating} stars`),
},
{

View file

@ -44,7 +44,7 @@ export function currentUrlReplaceAssetId(assetId: string) {
// always remove the assetGridScrollTargetParams
params.delete('at');
const paramsString = params.toString();
const searchparams = paramsString == '' ? '' : '?' + params.toString();
const searchparams = paramsString === '' ? '' : '?' + params.toString();
// this contains special casing for the /photos/:assetId photos route, which hangs directly
// off / instead of a subpath, unlike every other asset-containing route.
return isPhotosRoute(page.route.id)

View file

@ -183,8 +183,8 @@ export const toTimelineAsset = (unknownAsset: AssetResponseDto | TimelineAsset):
isFavorite: assetResponse.isFavorite,
visibility: assetResponse.visibility,
isTrashed: assetResponse.isTrashed,
isVideo: assetResponse.type == AssetTypeEnum.Video,
isImage: assetResponse.type == AssetTypeEnum.Image,
isVideo: assetResponse.type === AssetTypeEnum.Video,
isImage: assetResponse.type === AssetTypeEnum.Image,
stack: assetResponse.stack || null,
duration: assetResponse.duration || null,
projectionType: assetResponse.exifInfo?.projectionType || null,

View file

@ -222,7 +222,7 @@
const onNameChangeSubmit = async (name: string, targetPerson: PersonResponseDto) => {
try {
if (name == targetPerson.name) {
if (name === targetPerson.name) {
return;
}

View file

@ -98,7 +98,7 @@
} else if ($page.params.assetId) {
previousRoute = Route.viewPerson(data.person);
}
if (action == 'merge') {
if (action === 'merge') {
viewMode = PersonPageViewMode.MERGE_PEOPLE;
}
@ -180,7 +180,7 @@
const [, personToBeMergedInto] = result;
if (personToBeMergedInto.name != personName && person.id === personToBeMergedInto.id) {
if (personToBeMergedInto.name !== personName && person.id === personToBeMergedInto.id) {
await updateAssetCount();
return { merged: true };
}

View file

@ -201,7 +201,7 @@
personIds.map(async (personId) => {
const person = await getPerson({ id: personId });
if (person.name == '') {
if (person.name === '') {
return $t('no_name');
}

View file

@ -74,7 +74,7 @@
<SettingsLanguageSelector showSettingDescription />
<Field label={$t('use_browser_locale')} description={$t('use_browser_locale_description')}>
<Switch checked={$locale == 'default'} onCheckedChange={handleToggleLocaleBrowser} />
<Switch checked={$locale === 'default'} onCheckedChange={handleToggleLocaleBrowser} />
<Text size="small" class="mt-2 font-mono text-sm">{selectedDate}</Text>
</Field>

View file

@ -38,7 +38,7 @@
};
const preAction = async (payload: Action) => {
if (payload.type == 'trash') {
if (payload.type === 'trash') {
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
(await navigateToAsset(assetCursor?.nextAsset)) ||
(await navigateToAsset(assetCursor?.previousAsset)) ||

View file

@ -66,7 +66,7 @@
description=""
bind:value={configToEdit.job[queueName].concurrency}
required={true}
isEdited={configToEdit.job[queueName].concurrency != config.job[queueName].concurrency}
isEdited={configToEdit.job[queueName].concurrency !== config.job[queueName].concurrency}
/>
{:else}
<SettingInputField

View file

@ -127,7 +127,7 @@
);
const handleNextClicked = async () => {
if (nextStepIndex == -1) {
if (nextStepIndex === -1) {
if (authManager.user.isAdmin) {
await updateAdminOnboarding({ adminOnboardingUpdateDto: { isOnboarded: true } });
await serverConfigManager.loadServerConfig();

View file

@ -16,7 +16,7 @@
{$t('onboarding_welcome_user', { values: { user: authManager.user.name } })}
</p>
<p class="pb-6 text-3xl font-light">
{userRole == OnboardingRole.SERVER
{userRole === OnboardingRole.SERVER
? $t('onboarding_server_welcome_description')
: $t('onboarding_user_welcome_description')}
</p>