Prechádzať zdrojové kódy

feat(web): improve page header + scrolling (#2453)

* fix: line to edge of screen

* refactor: user layout page
Jason Rasmussen 2 rokov pred
rodič
commit
4a0052026f

+ 12 - 11
web/src/lib/components/layouts/user-page-layout.svelte

@@ -22,24 +22,25 @@
 </header>
 
 <main
-	class="grid md:grid-cols-[theme(spacing.64)_auto] grid-cols-[theme(spacing.18)_auto] relative pt-[var(--navbar-height)] h-screen bg-immich-bg dark:bg-immich-dark-bg immich-scrollbar"
+	class="grid md:grid-cols-[theme(spacing.64)_auto] grid-cols-[theme(spacing.18)_auto] relative pt-[var(--navbar-height)] h-screen overflow-hidden bg-immich-bg dark:bg-immich-dark-bg"
 >
 	<SideBar />
 	<slot name="content">
-		<section class="overflow-y-auto my-8 mx-4 bg-immich-bg dark:bg-immich-dark-bg">
-			{#if title}
-				<div class="flex justify-between place-items-center dark:text-immich-dark-fg px-4 h-10">
+		{#if title}
+			<section class="relative">
+				<div
+					class="absolute border-b dark:border-immich-dark-gray flex justify-between place-items-center dark:text-immich-dark-fg w-full p-4 h-16"
+				>
 					<p class="font-medium">{title}</p>
-
 					<slot name="buttons" />
 				</div>
 
-				<div class="my-4">
-					<hr class="dark:border-immich-dark-gray" />
+				<div
+					class="absolute overflow-y-auto top-16 h-[calc(100%-theme(spacing.16))] w-full immich-scrollbar p-4 pb-8"
+				>
+					<slot />
 				</div>
-			{/if}
-
-			<slot />
-		</section>
+			</section>
+		{/if}
 	</slot>
 </main>

+ 1 - 1
web/src/lib/components/shared-components/side-bar/side-bar-section.svelte

@@ -3,7 +3,7 @@
 
 <section
 	id="sidebar"
-	class="group flex flex-col gap-1 pt-8 bg-immich-bg dark:bg-immich-dark-bg transition-all duration-200 z-10 w-18 md:w-64 hover:sm:pr-6 md:pr-6 hover:sm:w-64 hover:sm:shadow-2xl hover:md:shadow-none hover:md:border-none hover:sm:border-r hover:sm:dark:border-r-immich-dark-gray"
+	class="group flex flex-col gap-1 pt-8 bg-immich-bg dark:bg-immich-dark-bg transition-all duration-200 z-10 w-18 md:w-64 hover:sm:pr-6 md:pr-6 hover:sm:w-64 hover:sm:shadow-2xl hover:md:shadow-none hover:md:border-none hover:sm:border-r hover:sm:dark:border-r-immich-dark-gray relative overflow-y-auto immich-scrollbar"
 >
 	<slot />
 </section>

+ 1 - 1
web/src/routes/(user)/archive/+page.svelte

@@ -36,7 +36,7 @@
 	};
 </script>
 
-<UserPageLayout user={data.user} hideNavbar={isMultiSelectionMode}>
+<UserPageLayout user={data.user} hideNavbar={isMultiSelectionMode} title={data.meta.title}>
 	<!-- Empty Message -->
 	{#if $archivedAsset.length === 0}
 		<EmptyPlaceholder

+ 107 - 111
web/src/routes/(user)/explore/+page.svelte

@@ -31,129 +31,125 @@
 </script>
 
 <UserPageLayout user={data.user} title={data.meta.title}>
-	<div class="mx-4">
-		{#if people.length > 0}
-			<div class="mb-6 mt-2">
-				<div class="flex justify-between">
-					<p class="mb-4 dark:text-immich-dark-fg font-medium">People</p>
-					{#if data.people.length > MAX_ITEMS}
-						<a
-							href={AppRoute.PEOPLE}
-							class="font-medium hover:text-immich-primary dark:hover:text-immich-dark-primary dark:text-immich-dark-fg"
-							draggable="false">View All</a
-						>
-					{/if}
-				</div>
-				<div class="flex flex-row flex-wrap gap-4">
-					{#each people as person (person.id)}
-						<a href="/people/{person.id}" class="w-24 text-center">
-							<ImageThumbnail
-								circle
-								shadow
-								url={api.getPeopleThumbnailUrl(person.id)}
-								altText={person.name}
-								widthStyle="100%"
-							/>
-							<p class="font-medium mt-2 text-ellipsis text-sm dark:text-white">{person.name}</p>
-						</a>
-					{/each}
-				</div>
+	{#if people.length > 0}
+		<div class="mb-6 mt-2">
+			<div class="flex justify-between">
+				<p class="mb-4 dark:text-immich-dark-fg font-medium">People</p>
+				{#if data.people.length > MAX_ITEMS}
+					<a
+						href={AppRoute.PEOPLE}
+						class="font-medium hover:text-immich-primary dark:hover:text-immich-dark-primary dark:text-immich-dark-fg"
+						draggable="false">View All</a
+					>
+				{/if}
 			</div>
-		{/if}
+			<div class="flex flex-row flex-wrap gap-4">
+				{#each people as person (person.id)}
+					<a href="/people/{person.id}" class="w-24 text-center">
+						<ImageThumbnail
+							circle
+							shadow
+							url={api.getPeopleThumbnailUrl(person.id)}
+							altText={person.name}
+							widthStyle="100%"
+						/>
+						<p class="font-medium mt-2 text-ellipsis text-sm dark:text-white">{person.name}</p>
+					</a>
+				{/each}
+			</div>
+		</div>
+	{/if}
 
-		{#if places.length > 0}
-			<div class="mb-6 mt-2">
-				<div>
-					<p class="mb-4 dark:text-immich-dark-fg font-medium">Places</p>
-				</div>
-				<div class="flex flex-row flex-wrap gap-4">
-					{#each places as item}
-						<a class="relative" href="/search?{Field.CITY}={item.value}" draggable="false">
-							<div
-								class="filter brightness-75 rounded-xl overflow-hidden w-[calc((100vw-(72px+5rem))/2)] max-w-[156px] flex justify-center"
-							>
-								<Thumbnail thumbnailSize={156} asset={item.data} readonly />
-							</div>
-							<span
-								class="capitalize absolute bottom-2 w-full text-center text-sm font-medium text-white text-ellipsis w-100 px-1 hover:cursor-pointer backdrop-blur-[1px]"
-							>
-								{item.value}
-							</span>
-						</a>
-					{/each}
-				</div>
+	{#if places.length > 0}
+		<div class="mb-6 mt-2">
+			<div>
+				<p class="mb-4 dark:text-immich-dark-fg font-medium">Places</p>
+			</div>
+			<div class="flex flex-row flex-wrap gap-4">
+				{#each places as item}
+					<a class="relative" href="/search?{Field.CITY}={item.value}" draggable="false">
+						<div
+							class="filter brightness-75 rounded-xl overflow-hidden w-[calc((100vw-(72px+5rem))/2)] max-w-[156px] flex justify-center"
+						>
+							<Thumbnail thumbnailSize={156} asset={item.data} readonly />
+						</div>
+						<span
+							class="capitalize absolute bottom-2 w-full text-center text-sm font-medium text-white text-ellipsis w-100 px-1 hover:cursor-pointer backdrop-blur-[1px]"
+						>
+							{item.value}
+						</span>
+					</a>
+				{/each}
 			</div>
-		{/if}
+		</div>
+	{/if}
 
-		{#if things.length > 0}
-			<div class="mb-6 mt-2">
-				<div>
-					<p class="mb-4 dark:text-immich-dark-fg font-medium">Things</p>
-				</div>
-				<div class="flex flex-row flex-wrap gap-4">
-					{#each things as item}
-						<a class="relative" href="/search?{Field.OBJECTS}={item.value}" draggable="false">
-							<div
-								class="filter brightness-75 rounded-xl overflow-hidden w-[calc((100vw-(72px+5rem))/2)] max-w-[156px] justify-center flex"
-							>
-								<Thumbnail thumbnailSize={156} asset={item.data} readonly />
-							</div>
-							<span
-								class="capitalize absolute bottom-2 w-full text-center text-sm font-medium text-white text-ellipsis w-100 px-1 hover:cursor-pointer backdrop-blur-[1px]"
-							>
-								{item.value}
-							</span>
-						</a>
-					{/each}
-				</div>
+	{#if things.length > 0}
+		<div class="mb-6 mt-2">
+			<div>
+				<p class="mb-4 dark:text-immich-dark-fg font-medium">Things</p>
 			</div>
-		{/if}
+			<div class="flex flex-row flex-wrap gap-4">
+				{#each things as item}
+					<a class="relative" href="/search?{Field.OBJECTS}={item.value}" draggable="false">
+						<div
+							class="filter brightness-75 rounded-xl overflow-hidden w-[calc((100vw-(72px+5rem))/2)] max-w-[156px] justify-center flex"
+						>
+							<Thumbnail thumbnailSize={156} asset={item.data} readonly />
+						</div>
+						<span
+							class="capitalize absolute bottom-2 w-full text-center text-sm font-medium text-white text-ellipsis w-100 px-1 hover:cursor-pointer backdrop-blur-[1px]"
+						>
+							{item.value}
+						</span>
+					</a>
+				{/each}
+			</div>
+		</div>
+	{/if}
 
-		<hr class="dark:border-immich-dark-gray mb-4" />
+	<hr class="dark:border-immich-dark-gray mb-4" />
 
-		<div
-			class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-5 gap-8"
-		>
-			<div class="flex flex-col gap-6 dark:text-immich-dark-fg">
-				<p class="text-sm">YOUR ACTIVITY</p>
-				<div class="flex flex-col gap-4 dark:text-immich-dark-fg/80">
-					<a
-						href={AppRoute.FAVORITES}
-						class="w-full flex text-sm font-medium hover:text-immich-primary dark:hover:text-immich-dark-primary content-center gap-2"
-						draggable="false"
-					>
-						<HeartMultipleOutline size={24} />
-						<span>Favorites</span>
-					</a>
-					<a
-						href="/search?recent=true"
-						class="w-full flex text-sm font-medium hover:text-immich-primary dark:hover:text-immich-dark-primary content-center gap-2"
-						draggable="false"
-					>
-						<ClockOutline size={24} />
-						<span>Recently added</span>
-					</a>
-				</div>
+	<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-5 gap-8">
+		<div class="flex flex-col gap-6 dark:text-immich-dark-fg">
+			<p class="text-sm">YOUR ACTIVITY</p>
+			<div class="flex flex-col gap-4 dark:text-immich-dark-fg/80">
+				<a
+					href={AppRoute.FAVORITES}
+					class="w-full flex text-sm font-medium hover:text-immich-primary dark:hover:text-immich-dark-primary content-center gap-2"
+					draggable="false"
+				>
+					<HeartMultipleOutline size={24} />
+					<span>Favorites</span>
+				</a>
+				<a
+					href="/search?recent=true"
+					class="w-full flex text-sm font-medium hover:text-immich-primary dark:hover:text-immich-dark-primary content-center gap-2"
+					draggable="false"
+				>
+					<ClockOutline size={24} />
+					<span>Recently added</span>
+				</a>
 			</div>
-			<div class="flex flex-col gap-6 dark:text-immich-dark-fg">
-				<p class="text-sm">CATEGORIES</p>
-				<div class="flex flex-col gap-4 dark:text-immich-dark-fg/80">
+		</div>
+		<div class="flex flex-col gap-6 dark:text-immich-dark-fg">
+			<p class="text-sm">CATEGORIES</p>
+			<div class="flex flex-col gap-4 dark:text-immich-dark-fg/80">
+				<a
+					href="/search?type={AssetTypeEnum.Video}"
+					class="w-full flex text-sm font-medium hover:text-immich-primary dark:hover:text-immich-dark-primary items-center gap-2"
+				>
+					<PlayCircleOutline size={24} />
+					<span>Videos</span>
+				</a>
+				<div>
 					<a
-						href="/search?type={AssetTypeEnum.Video}"
+						href="/search?motion=true"
 						class="w-full flex text-sm font-medium hover:text-immich-primary dark:hover:text-immich-dark-primary items-center gap-2"
 					>
-						<PlayCircleOutline size={24} />
-						<span>Videos</span>
+						<MotionPlayOutline size={24} />
+						<span>Motion photos</span>
 					</a>
-					<div>
-						<a
-							href="/search?motion=true"
-							class="w-full flex text-sm font-medium hover:text-immich-primary dark:hover:text-immich-dark-primary items-center gap-2"
-						>
-							<MotionPlayOutline size={24} />
-							<span>Motion photos</span>
-						</a>
-					</div>
 				</div>
 			</div>
 		</div>

+ 1 - 1
web/src/routes/(user)/favorites/+page.svelte

@@ -40,7 +40,7 @@
 	</AssetSelectControlBar>
 {/if}
 
-<UserPageLayout user={data.user} hideNavbar={isMultiSelectionMode}>
+<UserPageLayout user={data.user} hideNavbar={isMultiSelectionMode} title={data.meta.title}>
 	<section>
 		<!-- Empty Message -->
 		{#if favorites.length === 0}

+ 1 - 1
web/src/routes/(user)/map/+page.svelte

@@ -45,7 +45,7 @@
 <UserPageLayout user={data.user} title={data.meta.title}>
 	<div slot="buttons" />
 
-	<div class="h-[90%] w-full relative z-0">
+	<div class="h-full w-full relative z-0">
 		{#await import('$lib/components/shared-components/leaflet') then { Map, TileLayer, AssetMarkerCluster }}
 			<Map latlng={initialMapCenter} zoom={7}>
 				<TileLayer

+ 1 - 1
web/src/routes/(user)/sharing/+page.svelte

@@ -53,7 +53,7 @@
 		</LinkButton>
 	</div>
 
-	<div class="mx-4 flex flex-col">
+	<div class="flex flex-col">
 		{#if data.partners.length > 0}
 			<div class="mb-6 mt-2">
 				<div>