mirror of
https://github.com/immich-app/immich.git
synced 2025-01-07 00:50:23 -05:00
feat(web): search albums (#7322)
* feat: search albums * pr feedback * fix: comparison * pr feedback * simplify * chore: more compact album padding --------- Co-authored-by: Jason Rasmussen <jrasm91@gmail.com>
This commit is contained in:
parent
e3cccba78c
commit
75947ab6c2
6 changed files with 26 additions and 16 deletions
|
@ -1,12 +1,13 @@
|
|||
<script lang="ts">
|
||||
import { mdiClose, mdiMagnify } from '@mdi/js';
|
||||
import Icon from '../elements/icon.svelte';
|
||||
import Icon from './icon.svelte';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import type { SearchOptions } from '$lib/utils/dipatch';
|
||||
import LoadingSpinner from '../shared-components/loading-spinner.svelte';
|
||||
|
||||
export let name: string;
|
||||
export let isSearchingPeople: boolean;
|
||||
export let isSearching: boolean;
|
||||
export let placeholder: string;
|
||||
|
||||
const dispatch = createEventDispatcher<{ search: SearchOptions; reset: void }>();
|
||||
|
||||
|
@ -27,11 +28,11 @@
|
|||
autofocus
|
||||
class="w-full gap-2 bg-gray-100 dark:bg-gray-700 dark:text-white"
|
||||
type="text"
|
||||
placeholder="Search names"
|
||||
{placeholder}
|
||||
bind:value={name}
|
||||
on:input={() => dispatch('search', { force: false })}
|
||||
/>
|
||||
{#if isSearchingPeople}
|
||||
{#if isSearching}
|
||||
<div class="flex place-items-center">
|
||||
<LoadingSpinner />
|
||||
</div>
|
|
@ -5,7 +5,7 @@
|
|||
import { searchPerson, type PersonResponseDto } from '@immich/sdk';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import FaceThumbnail from './face-thumbnail.svelte';
|
||||
import SearchBar from './search-bar.svelte';
|
||||
import SearchBar from '../elements/search-bar.svelte';
|
||||
|
||||
export let screenHeight: number;
|
||||
export let people: PersonResponseDto[];
|
||||
|
@ -55,7 +55,8 @@
|
|||
<div class=" w-40 sm:w-48 md:w-96 h-14 mb-8">
|
||||
<SearchBar
|
||||
bind:name
|
||||
{isSearchingPeople}
|
||||
isSearching={isSearchingPeople}
|
||||
placeholder="Search people"
|
||||
on:reset={() => {
|
||||
people = peopleCopy;
|
||||
}}
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
export let scrollbar = true;
|
||||
export let admin = false;
|
||||
|
||||
$: scrollbarClass = scrollbar ? 'immich-scrollbar p-4 pb-8' : 'scrollbar-hidden';
|
||||
$: scrollbarClass = scrollbar ? 'immich-scrollbar p-2 pb-8' : 'scrollbar-hidden';
|
||||
$: hasTitleClass = title ? 'top-16 h-[calc(100%-theme(spacing.16))]' : 'top-0 h-full';
|
||||
</script>
|
||||
|
||||
|
|
|
@ -43,11 +43,13 @@
|
|||
import { flip } from 'svelte/animate';
|
||||
import type { PageData } from './$types';
|
||||
import { useAlbums } from './albums.bloc';
|
||||
import SearchBar from '$lib/components/elements/search-bar.svelte';
|
||||
|
||||
export let data: PageData;
|
||||
|
||||
let shouldShowEditUserForm = false;
|
||||
let selectedAlbum: AlbumResponseDto;
|
||||
let searchAlbum = '';
|
||||
|
||||
let sortByOptions: Record<string, Sort> = {
|
||||
albumTitle: {
|
||||
|
@ -180,6 +182,8 @@
|
|||
}
|
||||
}
|
||||
|
||||
$: albumsFiltered = $albums.filter((album) => album.albumName.toLowerCase().includes(searchAlbum.toLowerCase()));
|
||||
|
||||
const searchSort = (searched: string): Sort => {
|
||||
for (const key in sortByOptions) {
|
||||
if (sortByOptions[key].title === searched) {
|
||||
|
@ -243,6 +247,9 @@
|
|||
|
||||
<UserPageLayout title={data.meta.title}>
|
||||
<div class="flex place-items-center gap-2" slot="buttons">
|
||||
<div class="hidden lg:block lg:w-40 xl:w-60 2xl:w-80 h-10">
|
||||
<SearchBar placeholder="Search albums" bind:name={searchAlbum} isSearching={false} />
|
||||
</div>
|
||||
<LinkButton on:click={handleCreateAlbum}>
|
||||
<div class="flex place-items-center gap-2 text-sm">
|
||||
<Icon path={mdiPlusBoxOutline} size="18" />
|
||||
|
@ -285,7 +292,7 @@
|
|||
<!-- Album Card -->
|
||||
{#if $albumViewSettings.view === AlbumViewMode.Cover}
|
||||
<div class="grid grid-cols-[repeat(auto-fill,minmax(14rem,1fr))]">
|
||||
{#each $albums as album, index (album.id)}
|
||||
{#each albumsFiltered as album, index (album.id)}
|
||||
<a data-sveltekit-preload-data="hover" href="{AppRoute.ALBUMS}/{album.id}" animate:flip={{ duration: 200 }}>
|
||||
<AlbumCard
|
||||
preload={index < 20}
|
||||
|
@ -296,7 +303,7 @@
|
|||
{/each}
|
||||
</div>
|
||||
{:else if $albumViewSettings.view === AlbumViewMode.List}
|
||||
<table class="mt-5 w-full text-left">
|
||||
<table class="mt-2 w-full text-left">
|
||||
<thead
|
||||
class="mb-4 flex h-12 w-full rounded-md border bg-gray-50 text-immich-primary dark:border-immich-dark-gray dark:bg-immich-dark-gray dark:text-immich-dark-primary"
|
||||
>
|
||||
|
@ -310,7 +317,7 @@
|
|||
<tbody
|
||||
class="block w-full overflow-y-auto rounded-md border dark:border-immich-dark-gray dark:text-immich-dark-fg"
|
||||
>
|
||||
{#each $albums as album (album.id)}
|
||||
{#each albumsFiltered as album (album.id)}
|
||||
<tr
|
||||
class="flex h-[50px] w-full place-items-center border-[3px] border-transparent p-2 text-center odd:bg-immich-gray even:bg-immich-bg hover:cursor-pointer hover:border-immich-primary/75 odd:dark:bg-immich-dark-gray/75 even:dark:bg-immich-dark-gray/50 dark:hover:border-immich-dark-primary/75 md:p-5"
|
||||
on:click={() => goto(`${AppRoute.ALBUMS}/${album.id}`)}
|
||||
|
|
|
@ -603,7 +603,7 @@
|
|||
<input
|
||||
on:keydown={(e) => e.key === 'Enter' && titleInput.blur()}
|
||||
on:blur={handleUpdateName}
|
||||
class="w-[99%] border-b-2 border-transparent text-6xl text-immich-primary outline-none transition-all dark:text-immich-dark-primary {isOwned
|
||||
class="w-[99%] mb-2 border-b-2 border-transparent text-6xl text-immich-primary outline-none transition-all dark:text-immich-dark-primary {isOwned
|
||||
? 'hover:border-gray-400'
|
||||
: 'hover:border-transparent'} bg-immich-bg focus:border-b-2 focus:border-immich-primary focus:outline-none dark:bg-immich-dark-bg dark:focus:border-immich-dark-primary dark:focus:bg-immich-dark-gray"
|
||||
type="text"
|
||||
|
@ -616,7 +616,7 @@
|
|||
|
||||
<!-- ALBUM SUMMARY -->
|
||||
{#if album.assetCount > 0}
|
||||
<span class="my-4 flex gap-2 text-sm font-medium text-gray-500" data-testid="album-details">
|
||||
<span class="my-2 flex gap-2 text-sm font-medium text-gray-500" data-testid="album-details">
|
||||
<p class="">{getDateRange()}</p>
|
||||
<p>·</p>
|
||||
<p>{album.assetCount} items</p>
|
||||
|
@ -625,7 +625,7 @@
|
|||
|
||||
<!-- ALBUM SHARING -->
|
||||
{#if album.sharedUsers.length > 0 || (album.hasSharedLink && isOwned)}
|
||||
<div class="my-6 flex gap-x-1">
|
||||
<div class="my-3 flex gap-x-1">
|
||||
<!-- link -->
|
||||
{#if album.hasSharedLink && isOwned}
|
||||
<CircleIconButton
|
||||
|
@ -664,7 +664,7 @@
|
|||
<!-- ALBUM DESCRIPTION -->
|
||||
{#if isOwned}
|
||||
<textarea
|
||||
class="w-full resize-none overflow-hidden text-black dark:text-white border-b-2 border-transparent border-gray-500 bg-transparent text-base outline-none transition-all focus:border-b-2 focus:border-immich-primary disabled:border-none dark:focus:border-immich-dark-primary hover:border-gray-400"
|
||||
class="w-full mt-2 resize-none overflow-hidden text-black dark:text-white border-b-2 border-transparent border-gray-500 bg-transparent text-base outline-none transition-all focus:border-b-2 focus:border-immich-primary disabled:border-none dark:focus:border-immich-dark-primary hover:border-gray-400"
|
||||
bind:this={textArea}
|
||||
bind:value={description}
|
||||
on:input={() => autoGrowHeight(textArea)}
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
import MergeSuggestionModal from '$lib/components/faces-page/merge-suggestion-modal.svelte';
|
||||
import PeopleCard from '$lib/components/faces-page/people-card.svelte';
|
||||
import SearchBar from '$lib/components/faces-page/search-bar.svelte';
|
||||
import SearchBar from '$lib/components/elements/search-bar.svelte';
|
||||
import SetBirthDateModal from '$lib/components/faces-page/set-birth-date-modal.svelte';
|
||||
import ShowHide from '$lib/components/faces-page/show-hide.svelte';
|
||||
import UserPageLayout from '$lib/components/layouts/user-page-layout.svelte';
|
||||
|
@ -441,7 +441,8 @@
|
|||
<div class="w-40 lg:w-80 h-10">
|
||||
<SearchBar
|
||||
bind:name={searchName}
|
||||
{isSearchingPeople}
|
||||
isSearching={isSearchingPeople}
|
||||
placeholder="Search people"
|
||||
on:reset={() => {
|
||||
searchedPeople = [];
|
||||
}}
|
||||
|
|
Loading…
Reference in a new issue