chore: tailwindcss v4 and z-war clean up (#18358)

* chore: styling tweak

* replace full-screen-modal, update docs

* scrubber

* fix: control app bar in memory viewer

* face lift

* pr feedback

* clean up
This commit is contained in:
Alex 2025-05-19 09:32:23 -05:00 committed by GitHub
parent 2431e04a09
commit c8641d24f6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
42 changed files with 871 additions and 928 deletions

View file

@ -1,7 +1,6 @@
<script lang="ts">
import { clickOutside } from '$lib/actions/click-outside';
import CircleIconButton from '$lib/components/elements/buttons/circle-icon-button.svelte';
import FullScreenModal from '$lib/components/shared-components/full-screen-modal.svelte';
import type Map from '$lib/components/shared-components/map/map.svelte';
import Portal from '$lib/components/shared-components/portal/portal.svelte';
import { timeToLoadTheMap } from '$lib/constants';
@ -11,7 +10,7 @@
import { delay } from '$lib/utils/asset-utils';
import { navigate } from '$lib/utils/navigation';
import { getAlbumInfo, type AlbumResponseDto, type MapMarkerResponseDto } from '@immich/sdk';
import { LoadingSpinner } from '@immich/ui';
import { LoadingSpinner, Modal, ModalBody } from '@immich/ui';
import { mdiMapOutline } from '@mdi/js';
import { onDestroy, onMount } from 'svelte';
import { t } from 'svelte-i18n';
@ -112,31 +111,33 @@
{#if albumMapViewManager.isInMapView}
<div use:clickOutside={{ onOutclick: closeMap }}>
<FullScreenModal title={$t('map')} width="wide" onClose={closeMap}>
<div class="flex flex-col w-full h-full gap-2">
<div class="h-[500px] min-h-[300px] w-full">
{#await import('../shared-components/map/map.svelte')}
{#await delay(timeToLoadTheMap) then}
<!-- show the loading spinner only if loading the map takes too much time -->
<div class="flex items-center justify-center h-full w-full">
<LoadingSpinner />
</div>
<Modal title={$t('map')} size="medium" onClose={closeMap}>
<ModalBody>
<div class="flex flex-col w-full h-full gap-2 border border-gray-300 dark:border-light rounded-2xl">
<div class="h-[500px] min-h-[300px] w-full">
{#await import('../shared-components/map/map.svelte')}
{#await delay(timeToLoadTheMap) then}
<!-- show the loading spinner only if loading the map takes too much time -->
<div class="flex items-center justify-center h-full w-full">
<LoadingSpinner />
</div>
{/await}
{:then { default: Map }}
<Map
bind:this={mapElement}
center={undefined}
{zoom}
clickable={false}
bind:mapMarkers
onSelect={onViewAssets}
showSettings={false}
rounded
/>
{/await}
{:then { default: Map }}
<Map
bind:this={mapElement}
center={undefined}
{zoom}
clickable={false}
bind:mapMarkers
onSelect={onViewAssets}
showSettings={false}
rounded
/>
{/await}
</div>
</div>
</div>
</FullScreenModal>
</ModalBody>
</Modal>
</div>
<Portal target="body">

View file

@ -2,7 +2,6 @@
import Icon from '$lib/components/elements/icon.svelte';
import ButtonContextMenu from '$lib/components/shared-components/context-menu/button-context-menu.svelte';
import MenuOption from '$lib/components/shared-components/context-menu/menu-option.svelte';
import FullScreenModal from '$lib/components/shared-components/full-screen-modal.svelte';
import SettingSwitch from '$lib/components/shared-components/settings/setting-switch.svelte';
import UserAvatar from '$lib/components/shared-components/user-avatar.svelte';
import ConfirmModal from '$lib/modals/ConfirmModal.svelte';
@ -16,6 +15,7 @@
type AlbumResponseDto,
type UserResponseDto,
} from '@immich/sdk';
import { Modal, ModalBody } from '@immich/ui';
import { mdiArrowDownThin, mdiArrowUpThin, mdiDotsVertical, mdiPlus } from '@mdi/js';
import { findKey } from 'lodash-es';
import { t } from 'svelte-i18n';
@ -115,79 +115,81 @@
</script>
{#if !selectedRemoveUser}
<FullScreenModal title={$t('options')} {onClose}>
<div class="items-center justify-center">
<div class="py-2">
<h2 class="text-gray text-sm mb-2">{$t('settings').toUpperCase()}</h2>
<div class="grid p-2 gap-y-2">
{#if order}
<SettingDropdown
title={$t('display_order')}
options={Object.values(options)}
selectedOption={options[order]}
onToggle={handleToggle}
<Modal title={$t('options')} {onClose} size="small">
<ModalBody>
<div class="items-center justify-center">
<div class="py-2">
<h2 class="text-gray text-sm mb-2">{$t('settings').toUpperCase()}</h2>
<div class="grid p-2 gap-y-2">
{#if order}
<SettingDropdown
title={$t('display_order')}
options={Object.values(options)}
selectedOption={options[order]}
onToggle={handleToggle}
/>
{/if}
<SettingSwitch
title={$t('comments_and_likes')}
subtitle={$t('let_others_respond')}
checked={album.isActivityEnabled}
onToggle={onToggleEnabledActivity}
/>
{/if}
<SettingSwitch
title={$t('comments_and_likes')}
subtitle={$t('let_others_respond')}
checked={album.isActivityEnabled}
onToggle={onToggleEnabledActivity}
/>
</div>
</div>
<div class="py-2">
<div class="text-gray text-sm mb-3">{$t('people').toUpperCase()}</div>
<div class="p-2">
<button type="button" class="flex items-center gap-2" onclick={onShowSelectSharedUser}>
<div class="rounded-full w-10 h-10 border border-gray-500 flex items-center justify-center">
<div><Icon path={mdiPlus} size="25" /></div>
</div>
<div>{$t('invite_people')}</div>
</button>
<div class="flex items-center gap-2 py-2 mt-2">
<div>
<UserAvatar {user} size="md" />
</div>
<div class="w-full">{user.name}</div>
<div>{$t('owner')}</div>
</div>
</div>
<div class="py-2">
<div class="text-gray text-sm mb-3">{$t('people').toUpperCase()}</div>
<div class="p-2">
<button type="button" class="flex items-center gap-2" onclick={onShowSelectSharedUser}>
<div class="rounded-full w-10 h-10 border border-gray-500 flex items-center justify-center">
<div><Icon path={mdiPlus} size="25" /></div>
</div>
<div>{$t('invite_people')}</div>
</button>
{#each album.albumUsers as { user, role } (user.id)}
<div class="flex items-center gap-2 py-2">
<div class="flex items-center gap-2 py-2 mt-2">
<div>
<UserAvatar {user} size="md" />
</div>
<div class="w-full">{user.name}</div>
{#if role === AlbumUserRole.Viewer}
{$t('role_viewer')}
{:else}
{$t('role_editor')}
{/if}
{#if user.id !== album.ownerId}
<ButtonContextMenu icon={mdiDotsVertical} size="20" title={$t('options')}>
{#if role === AlbumUserRole.Viewer}
<MenuOption
onClick={() => handleUpdateSharedUserRole(user, AlbumUserRole.Editor)}
text={$t('allow_edits')}
/>
{:else}
<MenuOption
onClick={() => handleUpdateSharedUserRole(user, AlbumUserRole.Viewer)}
text={$t('disallow_edits')}
/>
{/if}
<!-- Allow deletion for non-owners -->
<MenuOption onClick={() => handleMenuRemove(user)} text={$t('remove')} />
</ButtonContextMenu>
{/if}
<div>{$t('owner')}</div>
</div>
{/each}
{#each album.albumUsers as { user, role } (user.id)}
<div class="flex items-center gap-2 py-2">
<div>
<UserAvatar {user} size="md" />
</div>
<div class="w-full">{user.name}</div>
{#if role === AlbumUserRole.Viewer}
{$t('role_viewer')}
{:else}
{$t('role_editor')}
{/if}
{#if user.id !== album.ownerId}
<ButtonContextMenu icon={mdiDotsVertical} size="20" title={$t('options')}>
{#if role === AlbumUserRole.Viewer}
<MenuOption
onClick={() => handleUpdateSharedUserRole(user, AlbumUserRole.Editor)}
text={$t('allow_edits')}
/>
{:else}
<MenuOption
onClick={() => handleUpdateSharedUserRole(user, AlbumUserRole.Viewer)}
text={$t('disallow_edits')}
/>
{/if}
<!-- Allow deletion for non-owners -->
<MenuOption onClick={() => handleMenuRemove(user)} text={$t('remove')} />
</ButtonContextMenu>
{/if}
</div>
{/each}
</div>
</div>
</div>
</div>
</FullScreenModal>
</ModalBody>
</Modal>
{/if}
{#if selectedRemoveUser}

View file

@ -40,7 +40,7 @@
onblur={handleUpdateName}
class="w-[99%] mb-2 border-b-2 border-transparent text-2xl md:text-4xl lg:text-6xl text-immich-primary outline-none transition-all dark:text-immich-dark-primary {isOwned
? 'hover:border-gray-400'
: 'hover:border-transparent'} focus:border-b-2 focus:border-immich-primary focus:outline-none bg-light dark:focus:border-immich-dark-primary dark:focus:bg-immich-dark-gray"
: 'hover:border-transparent'} focus:border-b-2 focus:border-immich-primary focus:outline-none bg-light dark:focus:border-immich-dark-primary dark:focus:bg-immich-dark-gray placeholder:text-primary/90"
type="text"
bind:value={newAlbumName}
disabled={!isOwned}