mirror of
https://github.com/immich-app/immich.git
synced 2024-12-31 00:43:56 -05:00
fix: reduce the number of API requests when changing route (#14666)
* fix: reduce the number of API requests when changing route * fix: reset `userInteraction` after sign out
This commit is contained in:
parent
6b0f9ec46c
commit
8945a5d862
9 changed files with 63 additions and 20 deletions
|
@ -1,7 +1,7 @@
|
|||
<script lang="ts">
|
||||
import FullScreenModal from '$lib/components/shared-components/full-screen-modal.svelte';
|
||||
import { featureFlags } from '$lib/stores/server-config.store';
|
||||
import { serverInfo } from '$lib/stores/server-info.store';
|
||||
import { userInteraction } from '$lib/stores/user.svelte';
|
||||
import { ByteUnit, convertToBytes } from '$lib/utils/byte-units';
|
||||
import { handleError } from '$lib/utils/handle-error';
|
||||
import { createUserAdmin } from '@immich/sdk';
|
||||
|
@ -34,7 +34,9 @@
|
|||
let isCreatingUser = $state(false);
|
||||
|
||||
let quotaSizeInBytes = $derived(quotaSize ? convertToBytes(quotaSize, ByteUnit.GiB) : null);
|
||||
let quotaSizeWarning = $derived(quotaSizeInBytes && quotaSizeInBytes > $serverInfo.diskSizeRaw);
|
||||
let quotaSizeWarning = $derived(
|
||||
quotaSizeInBytes && userInteraction.serverInfo && quotaSizeInBytes > userInteraction.serverInfo.diskSizeRaw,
|
||||
);
|
||||
|
||||
$effect(() => {
|
||||
if (password !== confirmPassword && confirmPassword.length > 0) {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<script lang="ts">
|
||||
import FullScreenModal from '$lib/components/shared-components/full-screen-modal.svelte';
|
||||
import { AppRoute } from '$lib/constants';
|
||||
import { serverInfo } from '$lib/stores/server-info.store';
|
||||
import { userInteraction } from '$lib/stores/user.svelte';
|
||||
import { handleError } from '$lib/utils/handle-error';
|
||||
import { updateUserAdmin, type UserAdminResponseDto } from '@immich/sdk';
|
||||
import { mdiAccountEditOutline } from '@mdi/js';
|
||||
|
@ -37,7 +37,8 @@
|
|||
let quotaSizeWarning = $derived(
|
||||
previousQutoa !== convertToBytes(Number(quotaSize), ByteUnit.GiB) &&
|
||||
!!quotaSize &&
|
||||
convertToBytes(Number(quotaSize), ByteUnit.GiB) > $serverInfo.diskSizeRaw,
|
||||
userInteraction.serverInfo &&
|
||||
convertToBytes(Number(quotaSize), ByteUnit.GiB) > userInteraction.serverInfo.diskSizeRaw,
|
||||
);
|
||||
|
||||
const editUser = async () => {
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
import { featureFlags } from '$lib/stores/server-config.store';
|
||||
import { user } from '$lib/stores/user.store';
|
||||
import { userInteraction } from '$lib/stores/user.svelte';
|
||||
import { handleLogout } from '$lib/utils/auth';
|
||||
import { getAboutInfo, logout, type ServerAboutResponseDto } from '@immich/sdk';
|
||||
import { mdiHelpCircleOutline, mdiMagnify, mdiTrayArrowUp } from '@mdi/js';
|
||||
|
@ -38,17 +39,17 @@
|
|||
await handleLogout(redirectUri);
|
||||
};
|
||||
|
||||
let aboutInfo: ServerAboutResponseDto | undefined = $state();
|
||||
let info: ServerAboutResponseDto | undefined = $state();
|
||||
|
||||
onMount(async () => {
|
||||
aboutInfo = await getAboutInfo();
|
||||
info = userInteraction.aboutInfo ?? (await getAboutInfo());
|
||||
});
|
||||
</script>
|
||||
|
||||
<svelte:window bind:innerWidth />
|
||||
|
||||
{#if shouldShowHelpPanel && aboutInfo}
|
||||
<HelpAndFeedbackModal onClose={() => (shouldShowHelpPanel = false)} info={aboutInfo} />
|
||||
{#if shouldShowHelpPanel && info}
|
||||
<HelpAndFeedbackModal onClose={() => (shouldShowHelpPanel = false)} {info} />
|
||||
{/if}
|
||||
|
||||
<section id="dashboard-navbar" class="fixed z-[900] h-[var(--navbar-height)] w-screen text-sm">
|
||||
|
|
|
@ -4,13 +4,19 @@
|
|||
import { getAllAlbums, type AlbumResponseDto } from '@immich/sdk';
|
||||
import { handleError } from '$lib/utils/handle-error';
|
||||
import { t } from 'svelte-i18n';
|
||||
import { userInteraction } from '$lib/stores/user.svelte';
|
||||
|
||||
let albums: AlbumResponseDto[] = $state([]);
|
||||
|
||||
onMount(async () => {
|
||||
if (userInteraction.recentAlbums) {
|
||||
albums = userInteraction.recentAlbums;
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const allAlbums = await getAllAlbums({});
|
||||
albums = allAlbums.sort((a, b) => (a.updatedAt > b.updatedAt ? -1 : 1)).slice(0, 3);
|
||||
userInteraction.recentAlbums = albums;
|
||||
} catch (error) {
|
||||
handleError(error, $t('failed_to_load_assets'));
|
||||
}
|
||||
|
|
|
@ -12,17 +12,24 @@
|
|||
} from '@immich/sdk';
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
import { mdiAlert } from '@mdi/js';
|
||||
import { userInteraction } from '$lib/stores/user.svelte';
|
||||
|
||||
const { serverVersion, connected } = websocketStore;
|
||||
|
||||
let isOpen = $state(false);
|
||||
|
||||
let info: ServerAboutResponseDto | undefined = $state();
|
||||
let versions: ServerVersionHistoryResponseDto[] = $state([]);
|
||||
|
||||
onMount(async () => {
|
||||
if (userInteraction.aboutInfo && userInteraction.versions && $serverVersion) {
|
||||
info = userInteraction.aboutInfo;
|
||||
versions = userInteraction.versions;
|
||||
return;
|
||||
}
|
||||
await requestServerInfo();
|
||||
[info, versions] = await Promise.all([getAboutInfo(), getVersionHistory()]);
|
||||
userInteraction.aboutInfo = info;
|
||||
userInteraction.versions = versions;
|
||||
});
|
||||
let isMain = $derived(info?.sourceRef === 'main' && info.repository === 'immich-app/immich');
|
||||
let version = $derived(
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
<script lang="ts">
|
||||
import { locale } from '$lib/stores/preferences.store';
|
||||
import { serverInfo } from '$lib/stores/server-info.store';
|
||||
import { user } from '$lib/stores/user.store';
|
||||
import { requestServerInfo } from '$lib/utils/auth';
|
||||
import { onMount } from 'svelte';
|
||||
import { t } from 'svelte-i18n';
|
||||
import { getByteUnitString } from '../../../utils/byte-units';
|
||||
import { getByteUnitString } from '$lib/utils/byte-units';
|
||||
import LoadingSpinner from '../loading-spinner.svelte';
|
||||
import { userInteraction } from '$lib/stores/user.svelte';
|
||||
|
||||
let usageClasses = $state('');
|
||||
|
||||
let hasQuota = $derived($user?.quotaSizeInBytes !== null);
|
||||
let availableBytes = $derived((hasQuota ? $user?.quotaSizeInBytes : $serverInfo?.diskSizeRaw) || 0);
|
||||
let usedBytes = $derived((hasQuota ? $user?.quotaUsageInBytes : $serverInfo?.diskUseRaw) || 0);
|
||||
let availableBytes = $derived((hasQuota ? $user?.quotaSizeInBytes : userInteraction.serverInfo?.diskSizeRaw) || 0);
|
||||
let usedBytes = $derived((hasQuota ? $user?.quotaUsageInBytes : userInteraction.serverInfo?.diskUseRaw) || 0);
|
||||
let usedPercentage = $derived(Math.min(Math.round((usedBytes / availableBytes) * 100), 100));
|
||||
|
||||
const onUpdate = () => {
|
||||
|
@ -38,6 +38,9 @@
|
|||
});
|
||||
|
||||
onMount(async () => {
|
||||
if (userInteraction.serverInfo && $user) {
|
||||
return;
|
||||
}
|
||||
await requestServerInfo();
|
||||
});
|
||||
</script>
|
||||
|
@ -54,7 +57,7 @@
|
|||
<div class="hidden group-hover:sm:block md:block">
|
||||
<p class="font-medium text-immich-dark-gray dark:text-white mb-2">{$t('storage')}</p>
|
||||
|
||||
{#if $serverInfo}
|
||||
{#if userInteraction.serverInfo}
|
||||
<p class="text-gray-500 dark:text-gray-300">
|
||||
{$t('storage_usage', {
|
||||
values: {
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
import type { ServerStorageResponseDto } from '@immich/sdk';
|
||||
import { writable } from 'svelte/store';
|
||||
|
||||
export const serverInfo = writable<ServerStorageResponseDto>();
|
26
web/src/lib/stores/user.svelte.ts
Normal file
26
web/src/lib/stores/user.svelte.ts
Normal file
|
@ -0,0 +1,26 @@
|
|||
import type {
|
||||
AlbumResponseDto,
|
||||
ServerAboutResponseDto,
|
||||
ServerStorageResponseDto,
|
||||
ServerVersionHistoryResponseDto,
|
||||
} from '@immich/sdk';
|
||||
|
||||
interface UserInteractions {
|
||||
recentAlbums?: AlbumResponseDto[];
|
||||
versions?: ServerVersionHistoryResponseDto[];
|
||||
aboutInfo?: ServerAboutResponseDto;
|
||||
serverInfo?: ServerStorageResponseDto;
|
||||
}
|
||||
|
||||
const defaultUserInteraction: UserInteractions = {
|
||||
recentAlbums: undefined,
|
||||
versions: undefined,
|
||||
aboutInfo: undefined,
|
||||
serverInfo: undefined,
|
||||
};
|
||||
|
||||
export const resetUserInteraction = () => {
|
||||
Object.assign(userInteraction, defaultUserInteraction);
|
||||
};
|
||||
|
||||
export const userInteraction = $state<UserInteractions>(defaultUserInteraction);
|
|
@ -2,8 +2,8 @@ import { browser } from '$app/environment';
|
|||
import { goto } from '$app/navigation';
|
||||
import { foldersStore } from '$lib/stores/folders.svelte';
|
||||
import { purchaseStore } from '$lib/stores/purchase.store';
|
||||
import { serverInfo } from '$lib/stores/server-info.store';
|
||||
import { preferences as preferences$, resetSavedUser, user as user$ } from '$lib/stores/user.store';
|
||||
import { resetUserInteraction, userInteraction } from '$lib/stores/user.svelte';
|
||||
import { getAboutInfo, getMyPreferences, getMyUser, getStorage } from '@immich/sdk';
|
||||
import { redirect } from '@sveltejs/kit';
|
||||
import { DateTime } from 'luxon';
|
||||
|
@ -72,7 +72,7 @@ export const authenticate = async (options?: AuthOptions) => {
|
|||
export const requestServerInfo = async () => {
|
||||
if (get(user$)) {
|
||||
const data = await getStorage();
|
||||
serverInfo.set(data);
|
||||
userInteraction.serverInfo = data;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -99,6 +99,7 @@ export const handleLogout = async (redirectUri: string) => {
|
|||
}
|
||||
} finally {
|
||||
resetSavedUser();
|
||||
resetUserInteraction();
|
||||
foldersStore.clearCache();
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue