mirror of
https://github.com/immich-app/immich.git
synced 2024-11-28 09:33:27 +02:00
feat(web) dark mode (#867)
This commit is contained in:
parent
ae96508e15
commit
f94176a910
@ -59,15 +59,15 @@ input:focus-visible {
|
|||||||
|
|
||||||
@layer utilities {
|
@layer utilities {
|
||||||
.immich-form-input {
|
.immich-form-input {
|
||||||
@apply bg-slate-100 p-2 rounded-md focus:border-immich-primary text-sm;
|
@apply bg-slate-100 p-2 rounded-md dark:text-immich-dark-bg focus:border-immich-primary text-sm;
|
||||||
}
|
}
|
||||||
|
|
||||||
.immich-form-label {
|
.immich-form-label {
|
||||||
@apply font-medium text-sm text-gray-500;
|
@apply font-medium text-sm text-gray-500 dark:text-gray-300;
|
||||||
}
|
}
|
||||||
|
|
||||||
.immich-btn-primary {
|
.immich-btn-primary {
|
||||||
@apply bg-immich-primary text-gray-100 border rounded-xl py-2 px-4 transition-all duration-150 hover:bg-immich-primary hover:shadow-lg text-sm font-medium;
|
@apply bg-immich-primary dark:bg-immich-dark-primary dark:text-immich-dark-gray text-gray-100 border dark:border-immich-dark-gray rounded-xl py-2 px-4 transition-all duration-150 hover:bg-immich-primary dark:hover:bg-immich-dark-primary/90 hover:shadow-lg text-sm font-medium;
|
||||||
}
|
}
|
||||||
|
|
||||||
.immich-text-button {
|
.immich-text-button {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en" class="dark">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
|
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
|
||||||
@ -7,7 +7,7 @@
|
|||||||
%sveltekit.head%
|
%sveltekit.head%
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body class="bg-immich-bg dark:bg-immich-dark-bg">
|
||||||
<div>%sveltekit.body%</div>
|
<div>%sveltekit.body%</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -11,17 +11,17 @@
|
|||||||
const dispatch = createEventDispatcher();
|
const dispatch = createEventDispatcher();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="flex border-b pb-5">
|
<div class="flex border-b pb-5 dark:border-b-immich-dark-gray">
|
||||||
<div class="w-[70%]">
|
<div class="w-[70%]">
|
||||||
<h1 class="text-immich-primary text-sm">{title.toUpperCase()}</h1>
|
<h1 class="text-immich-primary dark:text-immich-dark-primary text-sm">{title.toUpperCase()}</h1>
|
||||||
<p class="text-sm mt-1">{subtitle}</p>
|
<p class="text-sm mt-1 dark:text-immich-dark-fg">{subtitle}</p>
|
||||||
<p class="text-sm">
|
<p class="text-sm dark:text-immich-dark-fg">
|
||||||
<slot />
|
<slot />
|
||||||
</p>
|
</p>
|
||||||
<table class="text-left w-full mt-5">
|
<table class="text-left w-full mt-5">
|
||||||
<!-- table header -->
|
<!-- table header -->
|
||||||
<thead
|
<thead
|
||||||
class="border rounded-md mb-2 bg-immich-primary/10 flex text-immich-primary w-full h-12"
|
class="border rounded-md mb-2 dark:bg-immich-dark-gray dark:border-immich-dark-gray bg-immich-primary/10 flex text-immich-primary dark:text-immich-dark-primary w-full h-12"
|
||||||
>
|
>
|
||||||
<tr class="flex w-full place-items-center">
|
<tr class="flex w-full place-items-center">
|
||||||
<th class="text-center w-1/3 font-medium text-sm">Status</th>
|
<th class="text-center w-1/3 font-medium text-sm">Status</th>
|
||||||
@ -29,8 +29,10 @@
|
|||||||
<th class="text-center w-1/3 font-medium text-sm">Waiting</th>
|
<th class="text-center w-1/3 font-medium text-sm">Waiting</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody class="overflow-y-auto rounded-md w-full max-h-[320px] block border bg-white">
|
<tbody
|
||||||
<tr class="text-center flex place-items-center w-full h-[40px]">
|
class="overflow-y-auto rounded-md w-full max-h-[320px] block border bg-white dark:border-immich-dark-gray dark:bg-[#e5e5e5] dark:text-immich-dark-bg"
|
||||||
|
>
|
||||||
|
<tr class="text-center flex place-items-center w-full h-[60px]">
|
||||||
<td class="text-sm px-2 w-1/3 text-ellipsis">{jobStatus ? 'Active' : 'Idle'}</td>
|
<td class="text-sm px-2 w-1/3 text-ellipsis">{jobStatus ? 'Active' : 'Idle'}</td>
|
||||||
<td class="text-sm px-2 w-1/3 text-ellipsis">{activeJobCount}</td>
|
<td class="text-sm px-2 w-1/3 text-ellipsis">{activeJobCount}</td>
|
||||||
<td class="text-sm px-2 w-1/3 text-ellipsis">{waitingJobCount}</td>
|
<td class="text-sm px-2 w-1/3 text-ellipsis">{waitingJobCount}</td>
|
||||||
@ -41,7 +43,7 @@
|
|||||||
<div class="w-[30%] flex place-items-center place-content-end">
|
<div class="w-[30%] flex place-items-center place-content-end">
|
||||||
<button
|
<button
|
||||||
on:click={() => dispatch('click')}
|
on:click={() => dispatch('click')}
|
||||||
class="px-6 py-3 text-sm bg-immich-primary font-medium rounded-2xl hover:bg-immich-primary/50 transition-all hover:cursor-pointer disabled:cursor-not-allowed shadow-sm text-immich-bg"
|
class="px-6 py-3 text-sm bg-immich-primary dark:bg-immich-dark-primary font-medium rounded-2xl hover:bg-immich-primary/50 transition-all hover:cursor-pointer disabled:cursor-not-allowed shadow-sm text-immich-bg dark:text-immich-dark-gray"
|
||||||
disabled={jobStatus}
|
disabled={jobStatus}
|
||||||
>
|
>
|
||||||
{#if jobStatus}
|
{#if jobStatus}
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
<div class="flex flex-col gap-5">
|
<div class="flex flex-col gap-5">
|
||||||
<div>
|
<div>
|
||||||
<p class="text-sm">TOTAL USAGE</p>
|
<p class="text-sm dark:text-immich-dark-fg">TOTAL USAGE</p>
|
||||||
|
|
||||||
<div class="flex mt-5 justify-between">
|
<div class="flex mt-5 justify-between">
|
||||||
<StatsCard logo={CameraIris} title={'PHOTOS'} value={stats.photos.toString()} />
|
<StatsCard logo={CameraIris} title={'PHOTOS'} value={stats.photos.toString()} />
|
||||||
@ -33,9 +33,11 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<p class="text-sm">USER USAGE DETAIL</p>
|
<p class="text-sm dark:text-immich-dark-fg">USER USAGE DETAIL</p>
|
||||||
<table class="text-left w-full mt-5">
|
<table class="text-left w-full mt-5">
|
||||||
<thead class="border rounded-md mb-4 bg-gray-50 flex text-immich-primary w-full h-12">
|
<thead
|
||||||
|
class="border rounded-md mb-4 bg-gray-50 dark:bg-immich-dark-gray dark:border-immich-dark-gray flex text-immich-primary dark:text-immich-dark-primary w-full h-12"
|
||||||
|
>
|
||||||
<tr class="flex w-full place-items-center">
|
<tr class="flex w-full place-items-center">
|
||||||
<th class="text-center w-1/5 font-medium text-sm">User</th>
|
<th class="text-center w-1/5 font-medium text-sm">User</th>
|
||||||
<th class="text-center w-1/5 font-medium text-sm">Photos</th>
|
<th class="text-center w-1/5 font-medium text-sm">Photos</th>
|
||||||
@ -44,11 +46,13 @@
|
|||||||
<th class="text-center w-1/5 font-medium text-sm">Size</th>
|
<th class="text-center w-1/5 font-medium text-sm">Size</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody class="overflow-y-auto rounded-md w-full max-h-[320px] block border">
|
<tbody
|
||||||
|
class="overflow-y-auto rounded-md w-full max-h-[320px] block border dark:border-immich-dark-gray dark:text-immich-dark-bg"
|
||||||
|
>
|
||||||
{#each stats.usageByUser as user, i}
|
{#each stats.usageByUser as user, i}
|
||||||
<tr
|
<tr
|
||||||
class={`text-center flex place-items-center w-full h-[50px] ${
|
class={`text-center flex place-items-center w-full h-[50px] ${
|
||||||
i % 2 == 0 ? 'bg-immich-gray' : 'bg-immich-bg'
|
i % 2 == 0 ? 'bg-immich-gray dark:bg-[#e5e5e5]' : 'bg-immich-bg dark:bg-[#eeeeee]'
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<td class="text-sm px-2 w-1/5 text-ellipsis">{getFullName(user.userId)}</td>
|
<td class="text-sm px-2 w-1/5 text-ellipsis">{getFullName(user.userId)}</td>
|
||||||
|
@ -17,15 +17,17 @@
|
|||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="w-[180px] h-[140px] bg-immich-gray rounded-3xl p-5 flex flex-col justify-between">
|
<div
|
||||||
<div class="flex place-items-center gap-4">
|
class="w-[180px] h-[140px] bg-immich-gray dark:bg-immich-dark-gray rounded-3xl p-5 flex flex-col justify-between"
|
||||||
<svelte:component this={logo} size="40" color={'#4250af'} />
|
>
|
||||||
<p class="text-immich-primary">{title}</p>
|
<div class="flex place-items-center gap-4 text-immich-primary dark:text-immich-dark-primary">
|
||||||
|
<svelte:component this={logo} size="40" />
|
||||||
|
<p>{title}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="relative text-center font-mono font-semibold text-2xl">
|
<div class="relative text-center font-mono font-semibold text-2xl">
|
||||||
<span class="text-[#DCDADA]">{zeros()}</span><span class="text-immich-primary"
|
<span class="text-[#DCDADA] dark:text-[#525252]">{zeros()}</span><span
|
||||||
>{parseInt(value)}</span
|
class="text-immich-primary dark:text-immich-dark-primary">{parseInt(value)}</span
|
||||||
>
|
>
|
||||||
{#if unit}
|
{#if unit}
|
||||||
<span class="absolute -top-5 right-2 text-base font-light text-gray-400">{unit}</span>
|
<span class="absolute -top-5 right-2 text-base font-light text-gray-400">{unit}</span>
|
||||||
|
@ -9,7 +9,9 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<table class="text-left w-full my-5">
|
<table class="text-left w-full my-5">
|
||||||
<thead class="border rounded-md mb-4 bg-gray-50 flex text-immich-primary w-full h-12 ">
|
<thead
|
||||||
|
class="border rounded-md mb-4 bg-gray-50 flex text-immich-primary w-full h-12 dark:bg-immich-dark-gray dark:text-immich-dark-primary dark:border-immich-dark-gray"
|
||||||
|
>
|
||||||
<tr class="flex w-full place-items-center">
|
<tr class="flex w-full place-items-center">
|
||||||
<th class="text-center w-1/4 font-medium text-sm">Email</th>
|
<th class="text-center w-1/4 font-medium text-sm">Email</th>
|
||||||
<th class="text-center w-1/4 font-medium text-sm">First name</th>
|
<th class="text-center w-1/4 font-medium text-sm">First name</th>
|
||||||
@ -17,11 +19,13 @@
|
|||||||
<th class="text-center w-1/4 font-medium text-sm">Edit</th>
|
<th class="text-center w-1/4 font-medium text-sm">Edit</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody class="overflow-y-auto rounded-md w-full max-h-[320px] block border">
|
<tbody
|
||||||
|
class="overflow-y-auto rounded-md w-full max-h-[320px] block border dark:border-immich-dark-gray"
|
||||||
|
>
|
||||||
{#each allUsers as user, i}
|
{#each allUsers as user, i}
|
||||||
<tr
|
<tr
|
||||||
class={`text-center flex place-items-center w-full h-[80px] ${
|
class={`text-center flex place-items-center w-full h-[80px] dark:text-immich-dark-bg ${
|
||||||
i % 2 == 0 ? 'bg-gray-100' : 'bg-immich-bg'
|
i % 2 == 0 ? 'bg-immich-gray dark:bg-[#e5e5e5]' : 'bg-immich-bg dark:bg-[#eeeeee]'
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<td class="text-sm px-4 w-1/4 text-ellipsis">{user.email}</td>
|
<td class="text-sm px-4 w-1/4 text-ellipsis">{user.email}</td>
|
||||||
@ -32,7 +36,7 @@
|
|||||||
on:click={() => {
|
on:click={() => {
|
||||||
dispatch('edit-user', { user });
|
dispatch('edit-user', { user });
|
||||||
}}
|
}}
|
||||||
class="bg-immich-primary text-gray-100 rounded-full p-3 transition-all duration-150 hover:bg-immich-primary/75"
|
class="bg-immich-primary dark:bg-immich-dark-primary text-gray-100 dark:text-gray-700 rounded-full p-3 transition-all duration-150 hover:bg-immich-primary/75"
|
||||||
><PencilOutline size="20" /></button
|
><PencilOutline size="20" /></button
|
||||||
></td
|
></td
|
||||||
>
|
>
|
||||||
|
@ -60,12 +60,7 @@
|
|||||||
on:click|stopPropagation|preventDefault={showAlbumContextMenu}
|
on:click|stopPropagation|preventDefault={showAlbumContextMenu}
|
||||||
data-testid="context-button-parent"
|
data-testid="context-button-parent"
|
||||||
>
|
>
|
||||||
<CircleIconButton
|
<CircleIconButton logo={DotsVertical} size={'20'} hoverColor={'rgba(95,99,104, 0.5)'} />
|
||||||
logo={DotsVertical}
|
|
||||||
size={'20'}
|
|
||||||
hoverColor={'rgba(95,99,104, 0.5)'}
|
|
||||||
logoColor={'#fdf8ec'}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class={`h-[275px] w-[275px] z-[-1]`}>
|
<div class={`h-[275px] w-[275px] z-[-1]`}>
|
||||||
@ -78,11 +73,14 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mt-4">
|
<div class="mt-4">
|
||||||
<p class="text-sm font-medium text-gray-800" data-testid="album-name">
|
<p
|
||||||
|
class="text-sm font-medium text-gray-800 dark:text-immich-dark-primary"
|
||||||
|
data-testid="album-name"
|
||||||
|
>
|
||||||
{album.albumName}
|
{album.albumName}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<span class="text-xs flex gap-2" data-testid="album-details">
|
<span class="text-xs flex gap-2 dark:text-immich-dark-fg" data-testid="album-details">
|
||||||
<p>{album.assetCount} items</p>
|
<p>{album.assetCount} items</p>
|
||||||
|
|
||||||
{#if album.shared}
|
{#if album.shared}
|
||||||
|
@ -331,7 +331,7 @@
|
|||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<section class="bg-immich-bg">
|
<section class="bg-immich-bg dark:bg-immich-dark-bg">
|
||||||
<!-- Multiselection mode app bar -->
|
<!-- Multiselection mode app bar -->
|
||||||
{#if isMultiSelectionMode}
|
{#if isMultiSelectionMode}
|
||||||
<ControlAppBar
|
<ControlAppBar
|
||||||
@ -340,7 +340,9 @@
|
|||||||
tailwindClasses={'bg-white shadow-md'}
|
tailwindClasses={'bg-white shadow-md'}
|
||||||
>
|
>
|
||||||
<svelte:fragment slot="leading">
|
<svelte:fragment slot="leading">
|
||||||
<p class="font-medium text-immich-primary">Selected {multiSelectAsset.size}</p>
|
<p class="font-medium text-immich-primary dark:text-immich-dark-primary">
|
||||||
|
Selected {multiSelectAsset.size}
|
||||||
|
</p>
|
||||||
</svelte:fragment>
|
</svelte:fragment>
|
||||||
<svelte:fragment slot="trailing">
|
<svelte:fragment slot="trailing">
|
||||||
{#if isOwned}
|
{#if isOwned}
|
||||||
@ -386,7 +388,7 @@
|
|||||||
<button
|
<button
|
||||||
disabled={album.assetCount == 0}
|
disabled={album.assetCount == 0}
|
||||||
on:click={() => (isShowShareUserSelection = true)}
|
on:click={() => (isShowShareUserSelection = true)}
|
||||||
class="immich-text-button border bg-immich-primary text-gray-50 hover:bg-immich-primary/75 px-6 text-sm disabled:opacity-25 disabled:bg-gray-500 disabled:cursor-not-allowed"
|
class="immich-text-button border bg-immich-primary dark:bg-immich-dark-primary text-gray-50 hover:bg-immich-primary/75 px-6 text-sm disabled:opacity-25 disabled:bg-gray-500 disabled:cursor-not-allowed dark:text-immich-dark-bg dark:border-immich-dark-gray"
|
||||||
><span class="px-2">Share</span></button
|
><span class="px-2">Share</span></button
|
||||||
>
|
>
|
||||||
{/if}
|
{/if}
|
||||||
@ -404,9 +406,9 @@
|
|||||||
}}
|
}}
|
||||||
on:focus={() => (isEditingTitle = true)}
|
on:focus={() => (isEditingTitle = true)}
|
||||||
on:blur={() => (isEditingTitle = false)}
|
on:blur={() => (isEditingTitle = false)}
|
||||||
class={`transition-all text-6xl text-immich-primary w-[99%] border-b-2 border-transparent outline-none ${
|
class={`transition-all text-6xl text-immich-primary dark:text-immich-dark-primary w-[99%] border-b-2 border-transparent outline-none ${
|
||||||
isOwned ? 'hover:border-gray-400' : 'hover:border-transparent'
|
isOwned ? 'hover:border-gray-400' : 'hover:border-transparent'
|
||||||
} focus:outline-none focus:border-b-2 focus:border-immich-primary bg-immich-bg`}
|
} focus:outline-none focus:border-b-2 focus:border-immich-primary dark:focus:border-immich-dark-primary bg-immich-bg dark:bg-immich-dark-bg dark:focus:bg-immich-dark-gray`}
|
||||||
type="text"
|
type="text"
|
||||||
bind:value={album.albumName}
|
bind:value={album.albumName}
|
||||||
disabled={!isOwned}
|
disabled={!isOwned}
|
||||||
@ -468,13 +470,15 @@
|
|||||||
<!-- Album is empty - Show asset selectection buttons -->
|
<!-- Album is empty - Show asset selectection buttons -->
|
||||||
<section id="empty-album" class=" mt-[200px] flex place-content-center place-items-center">
|
<section id="empty-album" class=" mt-[200px] flex place-content-center place-items-center">
|
||||||
<div class="w-[300px]">
|
<div class="w-[300px]">
|
||||||
<p class="text-xs">ADD PHOTOS</p>
|
<p class="text-xs dark:text-immich-dark-fg">ADD PHOTOS</p>
|
||||||
<button
|
<button
|
||||||
on:click={() => (isShowAssetSelection = true)}
|
on:click={() => (isShowAssetSelection = true)}
|
||||||
class="w-full py-8 border bg-white rounded-md mt-5 flex place-items-center gap-6 px-8 transition-all hover:bg-gray-100 hover:text-immich-primary"
|
class="w-full py-8 border bg-immich-bg dark:bg-immich-dark-gray text-immich-fg dark:text-immich-dark-fg dark:hover:text-immich-dark-primary rounded-md mt-5 flex place-items-center gap-6 px-8 transition-all hover:bg-gray-100 hover:text-immich-primary dark:border-none"
|
||||||
>
|
>
|
||||||
<span><Plus color="#4250af" size="24" /> </span>
|
<span class="text-text-immich-primary dark:text-immich-dark-primary"
|
||||||
<span class="text-lg text-immich-fg">Select photos</span>
|
><Plus size="24" />
|
||||||
|
</span>
|
||||||
|
<span class="text-lg">Select photos</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
@ -70,7 +70,7 @@
|
|||||||
|
|
||||||
<section
|
<section
|
||||||
transition:fly={{ y: 500, duration: 100, easing: quintOut }}
|
transition:fly={{ y: 500, duration: 100, easing: quintOut }}
|
||||||
class="absolute top-0 left-0 w-full h-full bg-immich-bg z-[9999]"
|
class="absolute top-0 left-0 w-full h-full bg-immich-bg dark:bg-immich-dark-bg z-[9999]"
|
||||||
>
|
>
|
||||||
<ControlAppBar
|
<ControlAppBar
|
||||||
on:close-button-click={() => {
|
on:close-button-click={() => {
|
||||||
@ -80,28 +80,28 @@
|
|||||||
>
|
>
|
||||||
<svelte:fragment slot="leading">
|
<svelte:fragment slot="leading">
|
||||||
{#if $selectedAssets.size == 0}
|
{#if $selectedAssets.size == 0}
|
||||||
<p class="text-lg">Add to album</p>
|
<p class="text-lg dark:text-immich-dark-fg">Add to album</p>
|
||||||
{:else}
|
{:else}
|
||||||
<p class="text-lg">{$selectedAssets.size} selected</p>
|
<p class="text-lg dark:text-immich-dark-fg">{$selectedAssets.size} selected</p>
|
||||||
{/if}
|
{/if}
|
||||||
</svelte:fragment>
|
</svelte:fragment>
|
||||||
|
|
||||||
<svelte:fragment slot="trailing">
|
<svelte:fragment slot="trailing">
|
||||||
<button
|
<button
|
||||||
on:click={() => openFileUploadDialog(UploadType.ALBUM)}
|
on:click={() => openFileUploadDialog(UploadType.ALBUM)}
|
||||||
class="text-immich-primary text-sm hover:bg-immich-primary/10 transition-all px-6 py-2 rounded-lg font-medium"
|
class="text-immich-primary dark:text-immich-dark-primary text-sm hover:bg-immich-primary/10 dark:hover:bg-immich-dark-primary/25 transition-all px-6 py-2 rounded-lg font-medium"
|
||||||
>
|
>
|
||||||
Select from computer
|
Select from computer
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
disabled={$selectedAssets.size === 0}
|
disabled={$selectedAssets.size === 0}
|
||||||
on:click={addSelectedAssets}
|
on:click={addSelectedAssets}
|
||||||
class="immich-text-button border bg-immich-primary text-gray-50 hover:bg-immich-primary/75 px-6 text-sm disabled:opacity-25 disabled:bg-gray-500 disabled:cursor-not-allowed"
|
class="immich-text-button border bg-immich-primary dark:bg-immich-dark-primary text-gray-50 hover:bg-immich-primary/75 px-6 text-sm disabled:opacity-25 disabled:bg-gray-500 disabled:cursor-not-allowed dark:text-immich-dark-bg dark:border-immich-dark-gray"
|
||||||
><span class="px-2">Done</span></button
|
><span class="px-2">Done</span></button
|
||||||
>
|
>
|
||||||
</svelte:fragment>
|
</svelte:fragment>
|
||||||
</ControlAppBar>
|
</ControlAppBar>
|
||||||
<section class="pt-[100px] pl-[70px] grid h-screen bg-immich-bg">
|
<section class="pt-[100px] pl-[70px] grid h-screen bg-immich-bg dark:bg-immich-dark-bg">
|
||||||
<AssetGrid isAlbumSelectionMode={true} />
|
<AssetGrid isAlbumSelectionMode={true} />
|
||||||
</section>
|
</section>
|
||||||
</section>
|
</section>
|
||||||
|
@ -68,14 +68,14 @@
|
|||||||
<BaseModal on:close={() => dispatch('close')}>
|
<BaseModal on:close={() => dispatch('close')}>
|
||||||
<svelte:fragment slot="title">
|
<svelte:fragment slot="title">
|
||||||
<span class="flex gap-2 place-items-center">
|
<span class="flex gap-2 place-items-center">
|
||||||
<p class="font-medium text-immich-fg">Options</p>
|
<p class="font-medium text-immich-fg dark:text-immich-dark-fg">Options</p>
|
||||||
</span>
|
</span>
|
||||||
</svelte:fragment>
|
</svelte:fragment>
|
||||||
|
|
||||||
<section class="max-h-[400px] overflow-y-auto immich-scrollbar pb-4">
|
<section class="max-h-[400px] overflow-y-auto immich-scrollbar pb-4">
|
||||||
{#each album.sharedUsers as user}
|
{#each album.sharedUsers as user}
|
||||||
<div
|
<div
|
||||||
class="flex gap-4 p-5 place-items-center justify-between w-full transition-colors hover:bg-gray-50"
|
class="flex gap-4 p-5 place-items-center justify-between w-full transition-colors hover:bg-gray-50 dark:hover:bg-gray-700"
|
||||||
>
|
>
|
||||||
<div class="flex gap-4 place-items-center">
|
<div class="flex gap-4 place-items-center">
|
||||||
<CircleAvatar {user} />
|
<CircleAvatar {user} />
|
||||||
@ -88,14 +88,13 @@
|
|||||||
on:click={() => showContextMenu(user.id)}
|
on:click={() => showContextMenu(user.id)}
|
||||||
logo={DotsVertical}
|
logo={DotsVertical}
|
||||||
backgroundColor={'transparent'}
|
backgroundColor={'transparent'}
|
||||||
logoColor={'#5f6368'}
|
|
||||||
hoverColor={'#e2e7e9'}
|
hoverColor={'#e2e7e9'}
|
||||||
size={'20'}
|
size={'20'}
|
||||||
/>
|
/>
|
||||||
{:else if user.id == currentUser?.id}
|
{:else if user.id == currentUser?.id}
|
||||||
<button
|
<button
|
||||||
on:click={() => removeUser('me')}
|
on:click={() => removeUser('me')}
|
||||||
class="text-sm text-immich-primary font-medium transition-colors hover:text-immich-primary/75"
|
class="text-sm text-immich-primary dark:text-immich-dark-primary font-medium transition-colors hover:text-immich-primary/75"
|
||||||
>Leave</button
|
>Leave</button
|
||||||
>
|
>
|
||||||
{/if}
|
{/if}
|
||||||
|
@ -38,7 +38,7 @@
|
|||||||
<svelte:fragment slot="title">
|
<svelte:fragment slot="title">
|
||||||
<span class="flex gap-2 place-items-center">
|
<span class="flex gap-2 place-items-center">
|
||||||
<img src="/immich-logo.svg" width="24" alt="Immich" />
|
<img src="/immich-logo.svg" width="24" alt="Immich" />
|
||||||
<p class="font-medium text-immich-fg">Invite to album</p>
|
<p class="font-medium">Invite to album</p>
|
||||||
</span>
|
</span>
|
||||||
</svelte:fragment>
|
</svelte:fragment>
|
||||||
|
|
||||||
@ -51,7 +51,7 @@
|
|||||||
{#key user.id}
|
{#key user.id}
|
||||||
<button
|
<button
|
||||||
on:click={() => deselectUser(user)}
|
on:click={() => deselectUser(user)}
|
||||||
class="flex gap-1 place-items-center border border-gray-400 rounded-full p-1 hover:bg-gray-200 transition-colors"
|
class="flex gap-1 place-items-center border border-gray-400 rounded-full p-1 hover:bg-gray-200 dark:hover:bg-gray-700 transition-colors"
|
||||||
>
|
>
|
||||||
<CircleAvatar size={28} {user} />
|
<CircleAvatar size={28} {user} />
|
||||||
<p class="text-xs font-medium">{user.firstName} {user.lastName}</p>
|
<p class="text-xs font-medium">{user.firstName} {user.lastName}</p>
|
||||||
@ -68,11 +68,11 @@
|
|||||||
{#each users as user}
|
{#each users as user}
|
||||||
<button
|
<button
|
||||||
on:click={() => selectUser(user)}
|
on:click={() => selectUser(user)}
|
||||||
class="w-full flex place-items-center gap-4 py-4 px-5 hover:bg-gray-200 transition-all"
|
class="w-full flex place-items-center gap-4 py-4 px-5 hover:bg-gray-200 dark:hover:bg-gray-700 transition-all"
|
||||||
>
|
>
|
||||||
{#if selectedUsers.includes(user)}
|
{#if selectedUsers.includes(user)}
|
||||||
<span
|
<span
|
||||||
class="bg-immich-primary text-white rounded-full w-12 h-12 border flex place-items-center place-content-center text-3xl"
|
class="bg-immich-primary dark:bg-immich-dark-primary text-white dark:text-immich-dark-bg rounded-full w-12 h-12 border flex place-items-center place-content-center text-3xl dark:border-immich-dark-gray"
|
||||||
>✓</span
|
>✓</span
|
||||||
>
|
>
|
||||||
{:else}
|
{:else}
|
||||||
@ -80,7 +80,7 @@
|
|||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<div class="text-left">
|
<div class="text-left">
|
||||||
<p class="text-immich-fg">
|
<p class="text-immich-fg dark:text-immich-dark-fg">
|
||||||
{user.firstName}
|
{user.firstName}
|
||||||
{user.lastName}
|
{user.lastName}
|
||||||
</p>
|
</p>
|
||||||
|
@ -207,7 +207,7 @@
|
|||||||
<div
|
<div
|
||||||
transition:fly={{ duration: 150 }}
|
transition:fly={{ duration: 150 }}
|
||||||
id="detail-panel"
|
id="detail-panel"
|
||||||
class="bg-immich-bg w-[360px] row-span-full transition-all overflow-y-auto"
|
class="bg-immich-bg w-[360px] row-span-full transition-all overflow-y-auto dark:bg-immich-dark-bg dark:border-l dark:border-l-immich-dark-gray"
|
||||||
translate="yes"
|
translate="yes"
|
||||||
>
|
>
|
||||||
<DetailPanel {asset} albums={appearsInAlbums} on:close={() => (isShowDetail = false)} />
|
<DetailPanel {asset} albums={appearsInAlbums} on:close={() => (isShowDetail = false)} />
|
||||||
|
@ -97,16 +97,16 @@
|
|||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<section class="p-2">
|
<section class="p-2 dark:bg-immich-dark-bg dark:text-immich-dark-fg">
|
||||||
<div class="flex place-items-center gap-2">
|
<div class="flex place-items-center gap-2">
|
||||||
<button
|
<button
|
||||||
class="rounded-full p-3 flex place-items-center place-content-center hover:bg-gray-200 transition-colors"
|
class="rounded-full p-3 flex place-items-center place-content-center hover:bg-gray-200 transition-colors dark:text-immich-dark-fg dark:hover:bg-gray-900"
|
||||||
on:click={() => dispatch('close')}
|
on:click={() => dispatch('close')}
|
||||||
>
|
>
|
||||||
<Close size="24" color="#232323" />
|
<Close size="24" />
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<p class="text-immich-fg text-lg">Info</p>
|
<p class="text-immich-fg dark:text-immich-dark-fg text-lg">Info</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="px-4 py-4">
|
<div class="px-4 py-4">
|
||||||
@ -202,10 +202,10 @@
|
|||||||
<div class="h-[360px] w-full" id="map" />
|
<div class="h-[360px] w-full" id="map" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<section class="p-2">
|
<section class="p-2 dark:text-immich-dark-fg">
|
||||||
<div class="px-4 py-4">
|
<div class="px-4 py-4">
|
||||||
{#if albums.length > 0}
|
{#if albums.length > 0}
|
||||||
<p class="text-sm pb-4">APPEARS IN</p>
|
<p class="text-sm pb-4 ">APPEARS IN</p>
|
||||||
{/if}
|
{/if}
|
||||||
{#each albums as album}
|
{#each albums as album}
|
||||||
<a data-sveltekit-prefetch href={`/albums/${album.id}`}>
|
<a data-sveltekit-prefetch href={`/albums/${album.id}`}>
|
||||||
@ -219,7 +219,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mt-auto mb-auto">
|
<div class="mt-auto mb-auto">
|
||||||
<p>{album.albumName}</p>
|
<p class="dark:text-immich-dark-primary">{album.albumName}</p>
|
||||||
<div class="flex gap-2 text-sm">
|
<div class="flex gap-2 text-sm">
|
||||||
<p>{album.assetCount} items</p>
|
<p>{album.assetCount} items</p>
|
||||||
{#if album.shared}
|
{#if album.shared}
|
||||||
|
@ -51,11 +51,17 @@
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="border bg-white p-4 shadow-sm w-[500px] rounded-md py-8">
|
<div
|
||||||
|
class="border bg-immich-bg dark:bg-immich-dark-gray dark:border-immich-dark-gray p-4 shadow-sm w-[500px] rounded-3xl py-8 dark:text-immich-dark-fg"
|
||||||
|
>
|
||||||
<div class="flex flex-col place-items-center place-content-center gap-4 px-4">
|
<div class="flex flex-col place-items-center place-content-center gap-4 px-4">
|
||||||
<img class="text-center" src="/immich-logo.svg" height="100" width="100" alt="immich-logo" />
|
<img class="text-center" src="/immich-logo.svg" height="100" width="100" alt="immich-logo" />
|
||||||
<h1 class="text-2xl text-immich-primary font-medium">Admin Registration</h1>
|
<h1 class="text-2xl text-immich-primary dark:text-immich-dark-primary font-medium">
|
||||||
<p class="text-sm border rounded-md p-4 font-mono text-gray-600">
|
Admin Registration
|
||||||
|
</h1>
|
||||||
|
<p
|
||||||
|
class="text-sm border rounded-md p-4 font-mono text-gray-600 dark:border-immich-dark-bg dark:text-gray-300"
|
||||||
|
>
|
||||||
Since you are the first user on the system, you will be assigned as the Admin and are
|
Since you are the first user on the system, you will be assigned as the Admin and are
|
||||||
responsible for administrative tasks, and additional users will be created by you.
|
responsible for administrative tasks, and additional users will be created by you.
|
||||||
</p>
|
</p>
|
||||||
@ -117,7 +123,7 @@
|
|||||||
<div class="flex w-full">
|
<div class="flex w-full">
|
||||||
<button
|
<button
|
||||||
type="submit"
|
type="submit"
|
||||||
class="m-4 p-2 bg-immich-primary hover:bg-immich-primary/75 px-6 py-4 text-white rounded-md shadow-md w-full"
|
class="m-4 p-2 bg-immich-primary dark:bg-immich-dark-primary hover:bg-immich-primary/75 dark:hover:bg-immich-dark-primary/80 dark:text-immich-dark-gray px-6 py-4 text-white rounded-md shadow-md w-full"
|
||||||
>Sign Up</button
|
>Sign Up</button
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
@ -43,12 +43,18 @@
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="border bg-white p-4 shadow-sm w-[500px] rounded-md py-8">
|
<div
|
||||||
|
class="border bg-immich-bg dark:bg-immich-dark-gray dark:border-immich-dark-gray p-4 shadow-sm w-[500px] rounded-3xl py-8 dark:text-immich-dark-fg"
|
||||||
|
>
|
||||||
<div class="flex flex-col place-items-center place-content-center gap-4 px-4">
|
<div class="flex flex-col place-items-center place-content-center gap-4 px-4">
|
||||||
<img class="text-center" src="/immich-logo.svg" height="100" width="100" alt="immich-logo" />
|
<img class="text-center" src="/immich-logo.svg" height="100" width="100" alt="immich-logo" />
|
||||||
<h1 class="text-2xl text-immich-primary font-medium">Change Password</h1>
|
<h1 class="text-2xl text-immich-primary dark:text-immich-dark-primary font-medium">
|
||||||
|
Change Password
|
||||||
|
</h1>
|
||||||
|
|
||||||
<p class="text-sm border rounded-md p-4 font-mono text-gray-600">
|
<p
|
||||||
|
class="text-sm border rounded-md p-4 font-mono text-gray-600 dark:border-immich-dark-bg dark:text-gray-300"
|
||||||
|
>
|
||||||
Hi {user.firstName}
|
Hi {user.firstName}
|
||||||
{user.lastName} ({user.email}),
|
{user.lastName} ({user.email}),
|
||||||
<br />
|
<br />
|
||||||
@ -93,7 +99,7 @@
|
|||||||
<div class="flex w-full">
|
<div class="flex w-full">
|
||||||
<button
|
<button
|
||||||
type="submit"
|
type="submit"
|
||||||
class="m-4 p-2 bg-immich-primary hover:bg-immich-primary/75 px-6 py-4 text-white rounded-md shadow-md w-full"
|
class="m-4 p-2 bg-immich-primary dark:bg-immich-dark-primary hover:bg-immich-primary/75 dark:hover:bg-immich-dark-primary/80 dark:text-immich-dark-gray px-6 py-4 text-white rounded-md shadow-md w-full"
|
||||||
>Change Password</button
|
>Change Password</button
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
@ -53,11 +53,17 @@
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="border bg-white p-4 shadow-sm w-[500px] rounded-3xl py-8">
|
<div
|
||||||
|
class="border bg-immich-bg dark:bg-immich-dark-gray dark:border-immich-dark-gray p-4 shadow-sm w-[500px] rounded-3xl py-8 dark:text-immich-dark-fg"
|
||||||
|
>
|
||||||
<div class="flex flex-col place-items-center place-content-center gap-4 px-4">
|
<div class="flex flex-col place-items-center place-content-center gap-4 px-4">
|
||||||
<img class="text-center" src="/immich-logo.svg" height="100" width="100" alt="immich-logo" />
|
<img class="text-center" src="/immich-logo.svg" height="100" width="100" alt="immich-logo" />
|
||||||
<h1 class="text-2xl text-immich-primary font-medium">Create new user</h1>
|
<h1 class="text-2xl text-immich-primary dark:text-immich-dark-primary font-medium">
|
||||||
<p class="text-sm border rounded-md p-4 font-mono text-gray-600">
|
Create new user
|
||||||
|
</h1>
|
||||||
|
<p
|
||||||
|
class="text-sm border rounded-md p-4 font-mono text-gray-600 dark:border-immich-dark-bg dark:text-gray-300"
|
||||||
|
>
|
||||||
Please provide your user with the password, they will have to change it on their first sign
|
Please provide your user with the password, they will have to change it on their first sign
|
||||||
in.
|
in.
|
||||||
</p>
|
</p>
|
||||||
@ -113,7 +119,7 @@
|
|||||||
<div class="flex w-full">
|
<div class="flex w-full">
|
||||||
<button
|
<button
|
||||||
type="submit"
|
type="submit"
|
||||||
class="m-4 bg-immich-primary hover:bg-immich-primary/75 px-6 py-3 text-white rounded-full shadow-md w-full font-medium"
|
class="m-4 bg-immich-primary dark:bg-immich-dark-primary hover:bg-immich-primary/75 dark:hover:bg-immich-dark-primary/80 px-6 py-3 text-white dark:text-immich-dark-gray rounded-full shadow-md w-full font-medium"
|
||||||
>Create
|
>Create
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -65,11 +65,16 @@
|
|||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="border bg-white p-4 shadow-sm w-[500px] rounded-3xl py-8">
|
<div
|
||||||
<div class="flex flex-col place-items-center place-content-center gap-4 px-4">
|
class="border bg-immich-bg dark:bg-immich-dark-gray dark:border-immich-dark-gray p-4 shadow-sm w-[500px] rounded-3xl py-8 dark:text-immich-dark-fg"
|
||||||
<!-- <img class="text-center" src="/immich-logo.svg" height="100" width="100" alt="immich-logo"/>-->
|
>
|
||||||
<AccountEditOutline size="4em" color="#4250affe" />
|
<div
|
||||||
<h1 class="text-2xl text-immich-primary font-medium">Edit user</h1>
|
class="flex flex-col place-items-center place-content-center gap-4 px-4 text-immich-primary dark:text-immich-dark-primary"
|
||||||
|
>
|
||||||
|
<AccountEditOutline size="4em" />
|
||||||
|
<h1 class="text-2xl text-immich-primary dark:text-immich-dark-primary font-medium">
|
||||||
|
Edit user
|
||||||
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form on:submit|preventDefault={editUser} autocomplete="off">
|
<form on:submit|preventDefault={editUser} autocomplete="off">
|
||||||
@ -124,7 +129,7 @@
|
|||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
type="submit"
|
type="submit"
|
||||||
class="flex-1 transition-colors bg-immich-primary hover:bg-immich-primary/75 px-6 py-3 text-white rounded-full shadow-md w-full font-medium"
|
class="flex-1 transition-colors bg-immich-primary dark:bg-immich-dark-primary hover:bg-immich-primary/75 dark:hover:bg-immich-dark-primary/80 dark:text-immich-dark-gray px-6 py-3 text-white rounded-full shadow-md w-full font-medium"
|
||||||
>Confirm
|
>Confirm
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -32,15 +32,17 @@
|
|||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="border bg-white p-4 shadow-sm w-[500px] rounded-md py-8">
|
<div
|
||||||
|
class="border bg-white dark:bg-immich-dark-gray dark:border-immich-dark-gray p-4 shadow-sm w-[500px] rounded-md py-8"
|
||||||
|
>
|
||||||
<div class="flex flex-col place-items-center place-content-center gap-4 px-4">
|
<div class="flex flex-col place-items-center place-content-center gap-4 px-4">
|
||||||
<img class="text-center" src="/immich-logo.svg" height="100" width="100" alt="immich-logo" />
|
<img class="text-center" src="/immich-logo.svg" height="100" width="100" alt="immich-logo" />
|
||||||
<h1 class="text-2xl text-immich-primary font-medium">Login</h1>
|
<h1 class="text-2xl text-immich-primary dark:text-immich-dark-primary font-medium">Login</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{#if loginPageMessage}
|
{#if loginPageMessage}
|
||||||
<p
|
<p
|
||||||
class="text-sm border rounded-md m-4 p-4 text-immich-primary font-medium bg-immich-primary/5"
|
class="text-sm border rounded-md m-4 p-4 text-immich-primary dark:text-immich-dark-primary font-medium bg-immich-primary/5 dark:border-immich-dark-bg"
|
||||||
>
|
>
|
||||||
{@html loginPageMessage}
|
{@html loginPageMessage}
|
||||||
</p>
|
</p>
|
||||||
@ -78,7 +80,7 @@
|
|||||||
<div class="flex w-full">
|
<div class="flex w-full">
|
||||||
<button
|
<button
|
||||||
type="submit"
|
type="submit"
|
||||||
class="m-4 p-2 bg-immich-primary hover:bg-immich-primary/75 px-6 py-4 text-white rounded-md shadow-md w-full font-semibold"
|
class="m-4 p-2 bg-immich-primary dark:bg-immich-dark-primary dark:text-immich-dark-gray dark:hover:bg-immich-dark-primary/80 hover:bg-immich-primary/75 px-6 py-4 text-white rounded-md shadow-md w-full font-semibold"
|
||||||
>Login</button
|
>Login</button
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
@ -115,7 +115,9 @@
|
|||||||
on:mouseleave={() => (isMouseOverGroup = false)}
|
on:mouseleave={() => (isMouseOverGroup = false)}
|
||||||
>
|
>
|
||||||
<!-- Date group title -->
|
<!-- Date group title -->
|
||||||
<p class="font-medium text-sm text-immich-fg mb-2 flex place-items-center h-6">
|
<p
|
||||||
|
class="font-medium text-sm text-immich-fg dark:text-immich-dark-fg mb-2 flex place-items-center h-6"
|
||||||
|
>
|
||||||
{#if (hoveredDateGroup == dateGroupTitle && isMouseOverGroup) || $selectedGroup.has(dateGroupTitle)}
|
{#if (hoveredDateGroup == dateGroupTitle && isMouseOverGroup) || $selectedGroup.has(dateGroupTitle)}
|
||||||
<div
|
<div
|
||||||
transition:fly={{ x: -24, duration: 200, opacity: 0.5 }}
|
transition:fly={{ x: -24, duration: 200, opacity: 0.5 }}
|
||||||
|
@ -36,7 +36,7 @@
|
|||||||
<div
|
<div
|
||||||
use:clickOutside
|
use:clickOutside
|
||||||
on:out-click={() => dispatch('close')}
|
on:out-click={() => dispatch('close')}
|
||||||
class="bg-white w-[450px] min-h-[200px] max-h-[500px] rounded-lg shadow-md"
|
class="bg-immich-bg dark:bg-immich-dark-gray dark:text-immich-dark-fg w-[450px] min-h-[200px] max-h-[500px] rounded-lg shadow-md"
|
||||||
>
|
>
|
||||||
<div class="flex justify-between place-items-center p-5">
|
<div class="flex justify-between place-items-center p-5">
|
||||||
<div>
|
<div>
|
||||||
|
@ -9,7 +9,6 @@
|
|||||||
export let logo: any;
|
export let logo: any;
|
||||||
export let backgroundColor = 'transparent';
|
export let backgroundColor = 'transparent';
|
||||||
export let hoverColor = '#e2e7e9';
|
export let hoverColor = '#e2e7e9';
|
||||||
export let logoColor = '#5f6368';
|
|
||||||
export let size = '24';
|
export let size = '24';
|
||||||
export let title = '';
|
export let title = '';
|
||||||
let iconButton: HTMLButtonElement;
|
let iconButton: HTMLButtonElement;
|
||||||
@ -26,10 +25,10 @@
|
|||||||
<button
|
<button
|
||||||
{title}
|
{title}
|
||||||
bind:this={iconButton}
|
bind:this={iconButton}
|
||||||
class={`immich-circle-icon-button rounded-full p-3 flex place-items-center place-content-center transition-all`}
|
class={`immich-circle-icon-button dark:text-immich-dark-fg hover:dark:text-immich-dark-gray rounded-full p-3 flex place-items-center place-content-center transition-all`}
|
||||||
on:click={(mouseEvent) => dispatch('click', { mouseEvent })}
|
on:click={(mouseEvent) => dispatch('click', { mouseEvent })}
|
||||||
>
|
>
|
||||||
<svelte:component this={logo} {size} color={logoColor} />
|
<svelte:component this={logo} {size} />
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
<div
|
<div
|
||||||
transition:slide={{ duration: 200, easing: quintOut }}
|
transition:slide={{ duration: 200, easing: quintOut }}
|
||||||
bind:this={menuEl}
|
bind:this={menuEl}
|
||||||
class="absolute bg-white w-[175px] z-[99999] rounded-lg shadow-md"
|
class="absolute w-[175px] z-[99999] rounded-lg shadow-md"
|
||||||
style={`top: ${y}px; left: ${x}px;`}
|
style={`top: ${y}px; left: ${x}px;`}
|
||||||
use:clickOutside
|
use:clickOutside
|
||||||
on:out-click={() => dispatch('clickoutside')}
|
on:out-click={() => dispatch('clickoutside')}
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
<button
|
<button
|
||||||
class:disabled={isDisabled}
|
class:disabled={isDisabled}
|
||||||
on:click={handleClick}
|
on:click={handleClick}
|
||||||
class="bg-white hover:bg-immich-bg transition-all p-4 w-full text-left rounded-lg text-sm"
|
class="bg-white hover:bg-gray-300 dark:text-immich-dark-bg transition-all p-4 w-full text-left rounded-lg text-sm"
|
||||||
>
|
>
|
||||||
{#if text}
|
{#if text}
|
||||||
{text}
|
{text}
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
const onScroll = () => {
|
const onScroll = () => {
|
||||||
if (window.pageYOffset > 80) {
|
if (window.pageYOffset > 80) {
|
||||||
appBarBorder = 'border border-gray-200 bg-gray-50';
|
appBarBorder = 'border border-gray-200 bg-gray-50 dark:border-gray-600';
|
||||||
} else {
|
} else {
|
||||||
appBarBorder = 'bg-immich-bg border border-transparent';
|
appBarBorder = 'bg-immich-bg border border-transparent';
|
||||||
}
|
}
|
||||||
@ -39,14 +39,13 @@
|
|||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
id="asset-selection-app-bar"
|
id="asset-selection-app-bar"
|
||||||
class={`flex justify-between ${appBarBorder} rounded-lg p-2 mx-2 mt-2 transition-all place-items-center ${tailwindClasses}`}
|
class={`flex justify-between ${appBarBorder} rounded-lg p-2 mx-2 mt-2 transition-all place-items-center ${tailwindClasses} dark:bg-immich-dark-gray`}
|
||||||
>
|
>
|
||||||
<div class="flex place-items-center gap-6">
|
<div class="flex place-items-center gap-6 dark:text-immich-dark-fg">
|
||||||
<CircleIconButton
|
<CircleIconButton
|
||||||
on:click={() => dispatch('close-button-click')}
|
on:click={() => dispatch('close-button-click')}
|
||||||
logo={backIcon}
|
logo={backIcon}
|
||||||
backgroundColor={'transparent'}
|
backgroundColor={'transparent'}
|
||||||
logoColor={'rgb(75 85 99)'}
|
|
||||||
hoverColor={'#e2e7e9'}
|
hoverColor={'#e2e7e9'}
|
||||||
size={'24'}
|
size={'24'}
|
||||||
/>
|
/>
|
||||||
@ -54,7 +53,7 @@
|
|||||||
<slot name="leading" />
|
<slot name="leading" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex place-items-center gap-1 mr-4">
|
<div class="flex place-items-center gap-1 mr-4 ">
|
||||||
<slot name="trailing" />
|
<slot name="trailing" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -136,7 +136,7 @@
|
|||||||
<div
|
<div
|
||||||
style:width={`${thumbnailSize}px`}
|
style:width={`${thumbnailSize}px`}
|
||||||
style:height={`${thumbnailSize}px`}
|
style:height={`${thumbnailSize}px`}
|
||||||
class={`bg-gray-100 relative select-none ${getSize()} ${
|
class={`bg-gray-100 dark:bg-immich-dark-gray relative select-none ${getSize()} ${
|
||||||
disabled ? 'cursor-not-allowed' : 'hover:cursor-pointer'
|
disabled ? 'cursor-not-allowed' : 'hover:cursor-pointer'
|
||||||
}`}
|
}`}
|
||||||
on:mouseenter={handleMouseOverThumbnail}
|
on:mouseenter={handleMouseOverThumbnail}
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
import TrayArrowUp from 'svelte-material-icons/TrayArrowUp.svelte';
|
import TrayArrowUp from 'svelte-material-icons/TrayArrowUp.svelte';
|
||||||
import { clickOutside } from '../../utils/click-outside';
|
import { clickOutside } from '../../utils/click-outside';
|
||||||
import { api, UserResponseDto } from '@api';
|
import { api, UserResponseDto } from '@api';
|
||||||
|
import ThemeButton from './theme-button.svelte';
|
||||||
|
|
||||||
export let user: UserResponseDto;
|
export let user: UserResponseDto;
|
||||||
export let shouldShowUploadButton = true;
|
export let shouldShowUploadButton = true;
|
||||||
@ -42,28 +43,35 @@
|
|||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<section id="dashboard-navbar" class="fixed w-screen z-[100] bg-immich-bg text-sm">
|
<section
|
||||||
<div class="flex border-b place-items-center px-6 py-2 ">
|
id="dashboard-navbar"
|
||||||
|
class="fixed w-screen z-[100] bg-immich-bg dark:bg-immich-dark-bg text-sm"
|
||||||
|
>
|
||||||
|
<div class="flex border-b dark:border-b-immich-dark-gray place-items-center px-6 py-2 ">
|
||||||
<a
|
<a
|
||||||
data-sveltekit-prefetch
|
data-sveltekit-prefetch
|
||||||
class="flex gap-2 place-items-center hover:cursor-pointer"
|
class="flex gap-2 place-items-center hover:cursor-pointer"
|
||||||
href="/photos"
|
href="/photos"
|
||||||
>
|
>
|
||||||
<img src="/immich-logo.svg" alt="immich logo" height="35" width="35" />
|
<img src="/immich-logo.svg" alt="immich logo" height="35" width="35" />
|
||||||
<h1 class="font-immich-title text-2xl text-immich-primary">IMMICH</h1>
|
<h1 class="font-immich-title text-2xl text-immich-primary dark:text-immich-dark-primary">
|
||||||
|
IMMICH
|
||||||
|
</h1>
|
||||||
</a>
|
</a>
|
||||||
<div class="flex-1 ml-24">
|
<div class="flex-1 ml-24">
|
||||||
<input
|
<input
|
||||||
class="w-[50%] border rounded-md bg-gray-200 px-8 py-4"
|
class="w-[50%] rounded-md bg-gray-200 dark:bg-immich-dark-gray px-8 py-4"
|
||||||
placeholder="Search - Coming soon"
|
placeholder="Search - Coming soon"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<section class="flex gap-4 place-items-center">
|
<section class="flex gap-4 place-items-center">
|
||||||
|
<ThemeButton />
|
||||||
|
|
||||||
{#if $page.url.pathname !== '/admin' && shouldShowUploadButton}
|
{#if $page.url.pathname !== '/admin' && shouldShowUploadButton}
|
||||||
<button
|
<button
|
||||||
in:fly={{ x: 50, duration: 250 }}
|
in:fly={{ x: 50, duration: 250 }}
|
||||||
on:click={() => dispatch('uploadClicked')}
|
on:click={() => dispatch('uploadClicked')}
|
||||||
class="immich-text-button"
|
class="immich-text-button dark:hover:bg-immich-dark-primary/25 dark:text-immich-dark-fg"
|
||||||
>
|
>
|
||||||
<TrayArrowUp size="20" />
|
<TrayArrowUp size="20" />
|
||||||
<span> Upload </span>
|
<span> Upload </span>
|
||||||
@ -73,8 +81,9 @@
|
|||||||
{#if user.isAdmin}
|
{#if user.isAdmin}
|
||||||
<a data-sveltekit-prefetch href={`admin`}>
|
<a data-sveltekit-prefetch href={`admin`}>
|
||||||
<button
|
<button
|
||||||
class={`flex place-items-center place-content-center gap-2 hover:bg-immich-primary/5 p-2 rounded-lg font-medium ${
|
class={`flex place-items-center place-content-center gap-2 hover:bg-immich-primary/5 dark:hover:bg-immich-dark-primary/25 dark:text-immich-dark-fg p-2 rounded-lg font-medium ${
|
||||||
$page.url.pathname == '/admin' && 'text-immich-primary underline'
|
$page.url.pathname == '/admin' &&
|
||||||
|
'text-immich-primary dark:immich-dark-primary underline'
|
||||||
}`}>Administration</button
|
}`}>Administration</button
|
||||||
>
|
>
|
||||||
</a>
|
</a>
|
||||||
@ -87,7 +96,7 @@
|
|||||||
on:click={showAccountInfoPanel}
|
on:click={showAccountInfoPanel}
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
class="flex place-items-center place-content-center rounded-full bg-immich-primary/80 h-12 w-12 text-gray-100 hover:bg-immich-primary"
|
class="flex place-items-center place-content-center rounded-full bg-immich-primary hover:bg-immich-primary/80 h-12 w-12 text-gray-100 dark:text-immich-dark-bg dark:bg-immich-dark-primary"
|
||||||
>
|
>
|
||||||
{#if shouldShowProfileImage}
|
{#if shouldShowProfileImage}
|
||||||
<img
|
<img
|
||||||
@ -104,7 +113,7 @@
|
|||||||
<div
|
<div
|
||||||
in:fade={{ delay: 500, duration: 150 }}
|
in:fade={{ delay: 500, duration: 150 }}
|
||||||
out:fade={{ delay: 200, duration: 150 }}
|
out:fade={{ delay: 200, duration: 150 }}
|
||||||
class="absolute -bottom-12 right-5 border bg-gray-500 text-[12px] text-gray-100 p-2 rounded-md shadow-md"
|
class="absolute -bottom-12 right-5 border bg-gray-500 dark:bg-immich-dark-gray text-[12px] text-gray-100 p-2 rounded-md shadow-md dark:border-immich-dark-gray"
|
||||||
>
|
>
|
||||||
<p>{user.firstName} {user.lastName}</p>
|
<p>{user.firstName} {user.lastName}</p>
|
||||||
<p>{user.email}</p>
|
<p>{user.email}</p>
|
||||||
@ -119,13 +128,13 @@
|
|||||||
in:fade={{ duration: 100 }}
|
in:fade={{ duration: 100 }}
|
||||||
out:fade={{ duration: 100 }}
|
out:fade={{ duration: 100 }}
|
||||||
id="account-info-panel"
|
id="account-info-panel"
|
||||||
class="absolute right-[25px] top-[75px] bg-white shadow-lg rounded-2xl w-[360px] text-center z-[100]"
|
class="absolute right-[25px] top-[75px] bg-immich-bg dark:bg-immich-dark-gray dark:border dark:border-immich-dark-gray shadow-lg rounded-2xl w-[360px] text-center z-[100]"
|
||||||
use:clickOutside
|
use:clickOutside
|
||||||
on:out-click={() => (shouldShowAccountInfoPanel = false)}
|
on:out-click={() => (shouldShowAccountInfoPanel = false)}
|
||||||
>
|
>
|
||||||
<div class="flex place-items-center place-content-center mt-6">
|
<div class="flex place-items-center place-content-center mt-6">
|
||||||
<button
|
<button
|
||||||
class="flex place-items-center place-content-center rounded-full bg-immich-primary/80 h-20 w-20 text-gray-100 hover:bg-immich-primary"
|
class="flex place-items-center place-content-center rounded-full bg-immich-primary dark:bg-immich-dark-primary dark:immich-dark-primary/80 h-20 w-20 text-gray-100 hover:bg-immich-primary dark:text-immich-dark-bg"
|
||||||
>
|
>
|
||||||
{#if shouldShowProfileImage}
|
{#if shouldShowProfileImage}
|
||||||
<img
|
<img
|
||||||
@ -141,20 +150,21 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p class="text-lg text-immich-primary font-medium mt-4">
|
<p class="text-lg text-immich-primary dark:text-immich-dark-primary font-medium mt-4">
|
||||||
{user.firstName}
|
{user.firstName}
|
||||||
{user.lastName}
|
{user.lastName}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p class="text-sm text-gray-500">{user.email}</p>
|
<p class="text-sm text-gray-500 dark:text-immich-dark-fg">{user.email}</p>
|
||||||
|
|
||||||
<div class="my-4">
|
<div class="my-4">
|
||||||
<hr />
|
<hr class="dark:border-immich-dark-bg" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-6">
|
<div class="mb-6">
|
||||||
<button class="border rounded-3xl px-6 py-2 hover:bg-gray-50" on:click={logOut}
|
<button
|
||||||
>Sign Out</button
|
class="border rounded-3xl px-6 py-2 hover:bg-gray-50 dark:border-immich-dark-gray dark:bg-gray-300 dark:hover:bg-immich-dark-primary"
|
||||||
|
on:click={logOut}>Sign Out</button
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -109,7 +109,7 @@
|
|||||||
>
|
>
|
||||||
{#if isHover}
|
{#if isHover}
|
||||||
<div
|
<div
|
||||||
class="border-b-2 border-immich-primary w-[100px] right-0 pr-6 py-1 text-sm pl-1 font-medium absolute bg-white z-50 pointer-events-none rounded-tl-md shadow-lg"
|
class="border-b-2 border-immich-primary dark:border-immich-dark-primary w-[100px] right-0 pr-6 py-1 text-sm pl-1 font-medium absolute bg-immich-bg dark:bg-immich-dark-gray z-50 pointer-events-none rounded-tl-md shadow-lg dark:text-immich-dark-fg"
|
||||||
style:top={currentMouseYLocation + 'px'}
|
style:top={currentMouseYLocation + 'px'}
|
||||||
>
|
>
|
||||||
{hoveredDate?.toLocaleString('default', { month: 'short' })}
|
{hoveredDate?.toLocaleString('default', { month: 'short' })}
|
||||||
@ -120,7 +120,7 @@
|
|||||||
<!-- Scroll Position Indicator Line -->
|
<!-- Scroll Position Indicator Line -->
|
||||||
{#if !isDragging}
|
{#if !isDragging}
|
||||||
<div
|
<div
|
||||||
class="absolute right-0 w-10 h-[2px] bg-immich-primary"
|
class="absolute right-0 w-10 h-[2px] bg-immich-primary dark:bg-immich-dark-primary"
|
||||||
style:top={scrollbarPosition + 'px'}
|
style:top={scrollbarPosition + 'px'}
|
||||||
/>
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
@ -139,7 +139,7 @@
|
|||||||
{#if segment.height > 8}
|
{#if segment.height > 8}
|
||||||
<div
|
<div
|
||||||
aria-label={segment.timeGroup + ' ' + segment.count}
|
aria-label={segment.timeGroup + ' ' + segment.count}
|
||||||
class="absolute right-0 pr-5 z-10 text-xs font-medium"
|
class="absolute right-0 pr-5 z-10 text-xs font-medium dark:text-immich-dark-fg"
|
||||||
>
|
>
|
||||||
{groupDate.getFullYear()}
|
{groupDate.getFullYear()}
|
||||||
</div>
|
</div>
|
||||||
|
@ -23,10 +23,13 @@
|
|||||||
|
|
||||||
<div
|
<div
|
||||||
on:click={onButtonClicked}
|
on:click={onButtonClicked}
|
||||||
class={`flex gap-4 place-items-center pl-5 py-3 rounded-tr-full rounded-br-full hover:bg-gray-200 hover:text-immich-primary hover:cursor-pointer
|
class={`flex gap-4 place-items-center pl-5 py-3 rounded-tr-full rounded-br-full hover:bg-immich-gray dark:hover:bg-immich-dark-gray hover:text-immich-primary dark:text-immich-dark-fg dark:hover:text-immich-dark-primary hover:cursor-pointer
|
||||||
${isSelected && 'bg-immich-primary/10 text-immich-primary hover:bg-immich-primary/25'}
|
${
|
||||||
|
isSelected &&
|
||||||
|
'bg-immich-primary/10 dark:bg-immich-dark-primary/10 text-immich-primary dark:text-[#adcbfa] hover:bg-immich-primary/25'
|
||||||
|
}
|
||||||
`}
|
`}
|
||||||
>
|
>
|
||||||
<svelte:component this={logo} size="24" />
|
<svelte:component this={logo} size="24" />
|
||||||
<p class="font-medium text-sm">{title}</p>
|
<p class="font-medium text-sm ">{title}</p>
|
||||||
</div>
|
</div>
|
||||||
|
@ -52,8 +52,7 @@
|
|||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<section id="sidebar" class="flex flex-col gap-1 pt-8 pr-6">
|
<section id="sidebar" class="flex flex-col gap-1 pt-8 pr-6 bg-immich-bg dark:bg-immich-dark-bg">
|
||||||
<!-- {domCount} -->
|
|
||||||
<a
|
<a
|
||||||
data-sveltekit-prefetch
|
data-sveltekit-prefetch
|
||||||
data-sveltekit-noscroll
|
data-sveltekit-noscroll
|
||||||
@ -127,7 +126,7 @@
|
|||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
<div class="text-xs ml-5 my-4">
|
<div class="text-xs ml-5 my-4 dark:text-immich-dark-fg">
|
||||||
<p>LIBRARY</p>
|
<p>LIBRARY</p>
|
||||||
</div>
|
</div>
|
||||||
<a data-sveltekit-prefetch href={$page.routeId !== 'albums' ? `/albums` : null} class="relative">
|
<a data-sveltekit-prefetch href={$page.routeId !== 'albums' ? `/albums` : null} class="relative">
|
||||||
|
@ -46,18 +46,18 @@
|
|||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div>
|
<div class="dark:text-immich-dark-fg">
|
||||||
<div class="storage-status grid grid-cols-[64px_auto]">
|
<div class="storage-status grid grid-cols-[64px_auto]">
|
||||||
<div class="pl-5 pr-6 text-immich-primary">
|
<div class="pl-5 pr-6 text-immich-primary dark:text-immich-dark-primary">
|
||||||
<Cloud size={'24'} />
|
<Cloud size={'24'} />
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p class="text-sm font-medium text-immich-primary">Storage</p>
|
<p class="text-sm font-medium text-immich-primary dark:text-immich-dark-primary">Storage</p>
|
||||||
{#if serverInfo}
|
{#if serverInfo}
|
||||||
<div class="w-full bg-gray-200 rounded-full h-[7px] dark:bg-gray-700 my-2">
|
<div class="w-full bg-gray-200 rounded-full h-[7px] dark:bg-gray-700 my-2">
|
||||||
<!-- style={`width: ${$downloadAssets[fileName]}%`} -->
|
<!-- style={`width: ${$downloadAssets[fileName]}%`} -->
|
||||||
<div
|
<div
|
||||||
class="bg-immich-primary h-[7px] rounded-full"
|
class="bg-immich-primary dark:bg-immich-dark-primary h-[7px] rounded-full"
|
||||||
style={`width: ${getStorageUsagePercentage()}%`}
|
style={`width: ${getStorageUsagePercentage()}%`}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@ -70,29 +70,29 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<hr class="ml-5 my-4" />
|
<hr class="ml-5 my-4 dark:border-immich-dark-gray" />
|
||||||
</div>
|
</div>
|
||||||
<div class="server-status grid grid-cols-[64px_auto]">
|
<div class="server-status grid grid-cols-[64px_auto]">
|
||||||
<div class="pl-5 pr-6 text-immich-primary">
|
<div class="pl-5 pr-6 text-immich-primary dark:text-immich-dark-primary">
|
||||||
<Dns size={'24'} />
|
<Dns size={'24'} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="text-xs">
|
<div class="text-xs ">
|
||||||
<p class="text-sm font-medium text-immich-primary">Server</p>
|
<p class="text-sm font-medium text-immich-primary dark:text-immich-dark-primary">Server</p>
|
||||||
|
|
||||||
<div class="flex justify-items-center justify-between mt-2">
|
<div class="flex justify-items-center justify-between mt-2 ">
|
||||||
<p>Status</p>
|
<p>Status</p>
|
||||||
|
|
||||||
{#if isServerOk}
|
{#if isServerOk}
|
||||||
<p class="font-medium text-immich-primary">Online</p>
|
<p class="font-medium text-immich-primary dark:text-immich-dark-primary">Online</p>
|
||||||
{:else}
|
{:else}
|
||||||
<p class="font-medium text-red-500">Offline</p>
|
<p class="font-medium text-red-500">Offline</p>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex justify-items-center justify-between mt-2">
|
<div class="flex justify-items-center justify-between mt-2 ">
|
||||||
<p>Version</p>
|
<p>Version</p>
|
||||||
<p class="font-medium text-immich-primary">{serverVersion}</p>
|
<p class="font-medium text-immich-primary dark:text-immich-dark-primary">{serverVersion}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
77
web/src/lib/components/shared-components/theme-button.svelte
Normal file
77
web/src/lib/components/shared-components/theme-button.svelte
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { onMount } from 'svelte';
|
||||||
|
|
||||||
|
let toggleButton: HTMLElement;
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
var themeToggleDarkIcon = document.getElementById('theme-toggle-dark-icon');
|
||||||
|
var themeToggleLightIcon = document.getElementById('theme-toggle-light-icon');
|
||||||
|
|
||||||
|
// Change the icons inside the button based on previous settings
|
||||||
|
if (
|
||||||
|
localStorage.getItem('color-theme') === 'dark' ||
|
||||||
|
(!('color-theme' in localStorage) &&
|
||||||
|
window.matchMedia('(prefers-color-scheme: dark)').matches)
|
||||||
|
) {
|
||||||
|
themeToggleLightIcon?.classList.remove('hidden');
|
||||||
|
} else {
|
||||||
|
themeToggleDarkIcon?.classList.remove('hidden');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const toggleTheme = () => {
|
||||||
|
var themeToggleDarkIcon = document.getElementById('theme-toggle-dark-icon');
|
||||||
|
var themeToggleLightIcon = document.getElementById('theme-toggle-light-icon');
|
||||||
|
// toggle icons inside button
|
||||||
|
themeToggleDarkIcon?.classList.toggle('hidden');
|
||||||
|
themeToggleLightIcon?.classList.toggle('hidden');
|
||||||
|
|
||||||
|
// if set via local storage previously
|
||||||
|
if (localStorage.getItem('color-theme')) {
|
||||||
|
if (localStorage.getItem('color-theme') === 'light') {
|
||||||
|
document.documentElement.classList.add('dark');
|
||||||
|
localStorage.setItem('color-theme', 'dark');
|
||||||
|
} else {
|
||||||
|
document.documentElement.classList.remove('dark');
|
||||||
|
localStorage.setItem('color-theme', 'light');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (document.documentElement.classList.contains('dark')) {
|
||||||
|
document.documentElement.classList.remove('dark');
|
||||||
|
localStorage.setItem('color-theme', 'light');
|
||||||
|
} else {
|
||||||
|
document.documentElement.classList.add('dark');
|
||||||
|
localStorage.setItem('color-theme', 'dark');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<button
|
||||||
|
bind:this={toggleButton}
|
||||||
|
on:click={toggleTheme}
|
||||||
|
id="theme-toggle"
|
||||||
|
type="button"
|
||||||
|
class="text-gray-500 dark:text-immich-dark-primary hover:bg-gray-100 dark:hover:bg-gray-700 focus:outline-none rounded-lg text-sm p-2.5"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
id="theme-toggle-dark-icon"
|
||||||
|
class="hidden w-6 h-6"
|
||||||
|
fill="currentColor"
|
||||||
|
viewBox="0 0 20 20"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
><path d="M17.293 13.293A8 8 0 016.707 2.707a8.001 8.001 0 1010.586 10.586z" /></svg
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
id="theme-toggle-light-icon"
|
||||||
|
class="hidden w-6 h-6"
|
||||||
|
fill="currentColor"
|
||||||
|
viewBox="0 0 20 20"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
><path
|
||||||
|
d="M10 2a1 1 0 011 1v1a1 1 0 11-2 0V3a1 1 0 011-1zm4 8a4 4 0 11-8 0 4 4 0 018 0zm-.464 4.95l.707.707a1 1 0 001.414-1.414l-.707-.707a1 1 0 00-1.414 1.414zm2.12-10.607a1 1 0 010 1.414l-.706.707a1 1 0 11-1.414-1.414l.707-.707a1 1 0 011.414 0zM17 11a1 1 0 100-2h-1a1 1 0 100 2h1zm-7 4a1 1 0 011 1v1a1 1 0 11-2 0v-1a1 1 0 011-1zM5.05 6.464A1 1 0 106.465 5.05l-.708-.707a1 1 0 00-1.414 1.414l.707.707zm1.414 8.486l-.707.707a1 1 0 01-1.414-1.414l.707-.707a1 1 0 011.414 1.414zM4 11a1 1 0 100-2H3a1 1 0 000 2h1z"
|
||||||
|
fill-rule="evenodd"
|
||||||
|
clip-rule="evenodd"
|
||||||
|
/></svg
|
||||||
|
>
|
||||||
|
</button>
|
@ -26,7 +26,7 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="flex min-w-[550px] border-b border-gray-300 place-items-center py-4 gap-6 transition-all hover:border-immich-primary"
|
class="flex min-w-[550px] border-b border-gray-300 dark:border-immich-dark-gray place-items-center py-4 gap-6 transition-all hover:border-immich-primary dark:hover:border-immich-dark-primary"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
{#await loadImageData(album.albumThumbnailAssetId)}
|
{#await loadImageData(album.albumThumbnailAssetId)}
|
||||||
@ -46,13 +46,16 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<p class="font-medium text-gray-800">{album.albumName}</p>
|
<p class="font-medium text-gray-800 dark:text-immich-dark-primary">{album.albumName}</p>
|
||||||
|
|
||||||
{#await getAlbumOwnerInfo() then albumOwner}
|
{#await getAlbumOwnerInfo() then albumOwner}
|
||||||
{#if user.email == albumOwner.email}
|
{#if user.email == albumOwner.email}
|
||||||
<p class="text-xs text-gray-600">Owned</p>
|
<p class="text-xs text-gray-600 dark:text-immich-dark-fg">Owned</p>
|
||||||
{:else}
|
{:else}
|
||||||
<p class="text-xs text-gray-600">Shared by {albumOwner.firstName} {albumOwner.lastName}</p>
|
<p class="text-xs text-gray-600 dark:text-immich-dark-fg">
|
||||||
|
Shared by {albumOwner.firstName}
|
||||||
|
{albumOwner.lastName}
|
||||||
|
</p>
|
||||||
{/if}
|
{/if}
|
||||||
{/await}
|
{/await}
|
||||||
</div>
|
</div>
|
||||||
|
@ -15,8 +15,10 @@
|
|||||||
let localVersion: string;
|
let localVersion: string;
|
||||||
let remoteVersion: string;
|
let remoteVersion: string;
|
||||||
let showNavigationLoadingBar = false;
|
let showNavigationLoadingBar = false;
|
||||||
|
let canShow = false;
|
||||||
|
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
|
checkUserTheme();
|
||||||
const res = await checkAppVersion();
|
const res = await checkAppVersion();
|
||||||
|
|
||||||
shouldShowAnnouncement = res.shouldShowAnnouncement;
|
shouldShowAnnouncement = res.shouldShowAnnouncement;
|
||||||
@ -24,6 +26,21 @@
|
|||||||
remoteVersion = res.remoteVersion ?? 'unknown';
|
remoteVersion = res.remoteVersion ?? 'unknown';
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const checkUserTheme = () => {
|
||||||
|
// On page load or when changing themes, best to add inline in `head` to avoid FOUC
|
||||||
|
if (
|
||||||
|
localStorage.getItem('color-theme') === 'dark' ||
|
||||||
|
(!('color-theme' in localStorage) &&
|
||||||
|
window.matchMedia('(prefers-color-scheme: dark)').matches)
|
||||||
|
) {
|
||||||
|
document.documentElement.classList.add('dark');
|
||||||
|
} else {
|
||||||
|
document.documentElement.classList.remove('dark');
|
||||||
|
}
|
||||||
|
|
||||||
|
canShow = true;
|
||||||
|
};
|
||||||
|
|
||||||
beforeNavigate(() => {
|
beforeNavigate(() => {
|
||||||
showNavigationLoadingBar = true;
|
showNavigationLoadingBar = true;
|
||||||
});
|
});
|
||||||
@ -34,24 +51,24 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<main>
|
<main>
|
||||||
<!-- {#key $page.url} -->
|
{#if canShow}
|
||||||
<div in:fade={{ duration: 100 }}>
|
<div in:fade={{ duration: 100 }}>
|
||||||
{#if showNavigationLoadingBar}
|
{#if showNavigationLoadingBar}
|
||||||
<NavigationLoadingBar />
|
<NavigationLoadingBar />
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<slot />
|
<slot />
|
||||||
|
|
||||||
<DownloadPanel />
|
<DownloadPanel />
|
||||||
<UploadPanel />
|
<UploadPanel />
|
||||||
<NotificationList />
|
<NotificationList />
|
||||||
{#if shouldShowAnnouncement}
|
{#if shouldShowAnnouncement}
|
||||||
<AnnouncementBox
|
<AnnouncementBox
|
||||||
{localVersion}
|
{localVersion}
|
||||||
{remoteVersion}
|
{remoteVersion}
|
||||||
on:close={() => (shouldShowAnnouncement = false)}
|
on:close={() => (shouldShowAnnouncement = false)}
|
||||||
/>
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
<!-- {/key} -->
|
{/if}
|
||||||
</main>
|
</main>
|
||||||
|
@ -19,9 +19,13 @@
|
|||||||
<div class="flex place-items-center place-content-center ">
|
<div class="flex place-items-center place-content-center ">
|
||||||
<img class="text-center" src="immich-logo.svg" height="200" width="200" alt="immich-logo" />
|
<img class="text-center" src="immich-logo.svg" height="200" width="200" alt="immich-logo" />
|
||||||
</div>
|
</div>
|
||||||
<h1 class="text-4xl text-immich-primary font-bold font-immich-title">Welcome to IMMICH Web</h1>
|
<h1
|
||||||
|
class="text-4xl text-immich-primary dark:text-immich-dark-primary font-bold font-immich-title"
|
||||||
|
>
|
||||||
|
Welcome to IMMICH Web
|
||||||
|
</h1>
|
||||||
<button
|
<button
|
||||||
class="border px-4 py-2 rounded-md bg-immich-primary hover:bg-immich-primary/75 text-white font-bold w-[200px]"
|
class="border px-4 py-4 rounded-md bg-immich-primary dark:bg-immich-dark-primary dark:text-immich-dark-gray dark:border-immich-dark-gray hover:bg-immich-primary/75 text-white font-bold w-[200px]"
|
||||||
on:click={onGettingStartedClicked}
|
on:click={onGettingStartedClicked}
|
||||||
>Getting Started
|
>Getting Started
|
||||||
</button>
|
</button>
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
selectedAction = AdminSideBarSelection.JOBS;
|
selectedAction = AdminSideBarSelection.USER_MANAGEMENT;
|
||||||
getServerStats();
|
getServerStats();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -147,8 +147,10 @@
|
|||||||
</section>
|
</section>
|
||||||
<section class="overflow-y-auto relative">
|
<section class="overflow-y-auto relative">
|
||||||
<div id="setting-title" class="pt-10 fixed w-full z-50">
|
<div id="setting-title" class="pt-10 fixed w-full z-50">
|
||||||
<h1 class="text-lg ml-8 mb-4 text-immich-primary font-medium">{selectedAction}</h1>
|
<h1 class="text-lg ml-8 mb-4 text-immich-primary dark:text-immich-dark-primary font-medium">
|
||||||
<hr />
|
{selectedAction}
|
||||||
|
</h1>
|
||||||
|
<hr class="dark:border-immich-dark-gray" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<section id="setting-content" class="relative pt-[85px] flex place-content-center">
|
<section id="setting-content" class="relative pt-[85px] flex place-content-center">
|
||||||
|
@ -42,20 +42,28 @@
|
|||||||
<NavigationBar user={data.user} shouldShowUploadButton={false} />
|
<NavigationBar user={data.user} shouldShowUploadButton={false} />
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class="grid grid-cols-[250px_auto] relative pt-[72px] h-screen bg-immich-bg ">
|
<section
|
||||||
|
class="grid grid-cols-[250px_auto] relative pt-[72px] h-screen bg-immich-bg dark:bg-immich-dark-bg"
|
||||||
|
>
|
||||||
<SideBar />
|
<SideBar />
|
||||||
|
|
||||||
<!-- Main Section -->
|
<!-- Main Section -->
|
||||||
|
|
||||||
<section class="overflow-y-auto relative immich-scrollbar">
|
<section class="overflow-y-auto relative immich-scrollbar">
|
||||||
<section id="album-content" class="relative pt-8 pl-4 mb-12 bg-immich-bg">
|
<section
|
||||||
<div class="px-4 flex justify-between place-items-center">
|
id="album-content"
|
||||||
|
class="relative pt-8 pl-4 mb-12 bg-immich-bg dark:bg-immich-dark-bg"
|
||||||
|
>
|
||||||
|
<div class="px-4 flex justify-between place-items-center dark:text-immich-dark-fg">
|
||||||
<div>
|
<div>
|
||||||
<p class="font-medium">Albums</p>
|
<p class="font-medium">Albums</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<button on:click={handleCreateAlbum} class="immich-text-button text-sm">
|
<button
|
||||||
|
on:click={handleCreateAlbum}
|
||||||
|
class="immich-text-button text-sm dark:hover:bg-immich-dark-primary/25 dark:text-immich-dark-fg"
|
||||||
|
>
|
||||||
<span>
|
<span>
|
||||||
<PlusBoxOutline size="18" />
|
<PlusBoxOutline size="18" />
|
||||||
</span>
|
</span>
|
||||||
@ -65,7 +73,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="my-4">
|
<div class="my-4">
|
||||||
<hr />
|
<hr class="dark:border-immich-dark-gray" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Album Card -->
|
<!-- Album Card -->
|
||||||
@ -85,11 +93,11 @@
|
|||||||
<!-- Empty Message -->
|
<!-- Empty Message -->
|
||||||
{#if $albums.length === 0}
|
{#if $albums.length === 0}
|
||||||
<div
|
<div
|
||||||
class="border p-5 w-[50%] m-auto mt-10 bg-gray-50 rounded-3xl flex flex-col place-content-center place-items-center"
|
class="border dark:border-immich-dark-gray p-5 w-[50%] m-auto mt-10 bg-gray-50 dark:bg-immich-dark-gray rounded-3xl flex flex-col place-content-center place-items-center"
|
||||||
>
|
>
|
||||||
<img src="/empty-1.svg" alt="Empty shared album" width="500" />
|
<img src="/empty-1.svg" alt="Empty shared album" width="500" />
|
||||||
|
|
||||||
<p class="text-center text-immich-text-gray-500">
|
<p class="text-center text-immich-text-gray-500 dark:text-immich-dark-fg">
|
||||||
Create an album to organize your photos and videos
|
Create an album to organize your photos and videos
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
@ -65,7 +65,9 @@
|
|||||||
tailwindClasses={'bg-white shadow-md'}
|
tailwindClasses={'bg-white shadow-md'}
|
||||||
>
|
>
|
||||||
<svelte:fragment slot="leading">
|
<svelte:fragment slot="leading">
|
||||||
<p class="font-medium text-immich-primary">Selected {$selectedAssets.size}</p>
|
<p class="font-medium text-immich-primary dark:text-immich-dark-primary">
|
||||||
|
Selected {$selectedAssets.size}
|
||||||
|
</p>
|
||||||
</svelte:fragment>
|
</svelte:fragment>
|
||||||
<svelte:fragment slot="trailing">
|
<svelte:fragment slot="trailing">
|
||||||
<CircleIconButton
|
<CircleIconButton
|
||||||
@ -83,7 +85,9 @@
|
|||||||
{/if}
|
{/if}
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class="grid grid-cols-[250px_auto] relative pt-[72px] h-screen bg-immich-bg">
|
<section
|
||||||
|
class="grid grid-cols-[250px_auto] relative pt-[72px] h-screen bg-immich-bg dark:bg-immich-dark-bg"
|
||||||
|
>
|
||||||
<SideBar />
|
<SideBar />
|
||||||
<AssetGrid />
|
<AssetGrid />
|
||||||
</section>
|
</section>
|
||||||
|
@ -39,13 +39,18 @@
|
|||||||
<NavigationBar user={data.user} shouldShowUploadButton={false} />
|
<NavigationBar user={data.user} shouldShowUploadButton={false} />
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class="grid grid-cols-[250px_auto] relative pt-[72px] h-screen bg-immich-bg">
|
<section
|
||||||
|
class="grid grid-cols-[250px_auto] relative pt-[72px] h-screen bg-immich-bg dark:bg-immich-dark-bg"
|
||||||
|
>
|
||||||
<SideBar />
|
<SideBar />
|
||||||
|
|
||||||
<section class="overflow-y-auto relative">
|
<section class="overflow-y-auto relative">
|
||||||
<section id="album-content" class="relative pt-8 pl-4 mb-12 bg-immich-bg">
|
<section
|
||||||
|
id="album-content"
|
||||||
|
class="relative pt-8 pl-4 mb-12 bg-immich-bg dark:bg-immich-dark-bg"
|
||||||
|
>
|
||||||
<!-- Main Section -->
|
<!-- Main Section -->
|
||||||
<div class="px-4 flex justify-between place-items-center">
|
<div class="px-4 flex justify-between place-items-center dark:text-immich-dark-fg">
|
||||||
<div>
|
<div>
|
||||||
<p class="font-medium">Sharing</p>
|
<p class="font-medium">Sharing</p>
|
||||||
</div>
|
</div>
|
||||||
@ -53,7 +58,7 @@
|
|||||||
<div>
|
<div>
|
||||||
<button
|
<button
|
||||||
on:click={createSharedAlbum}
|
on:click={createSharedAlbum}
|
||||||
class="flex place-items-center gap-1 text-sm hover:bg-immich-primary/5 p-2 rounded-lg font-medium hover:text-gray-700"
|
class="flex place-items-center gap-1 text-sm hover:bg-immich-primary/5 p-2 rounded-lg font-medium hover:text-gray-700 dark:hover:bg-immich-dark-primary/25 dark:text-immich-dark-fg"
|
||||||
>
|
>
|
||||||
<span>
|
<span>
|
||||||
<PlusBoxOutline size="18" />
|
<PlusBoxOutline size="18" />
|
||||||
@ -64,7 +69,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="my-4">
|
<div class="my-4">
|
||||||
<hr />
|
<hr class="dark:border-immich-dark-gray" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Share Album List -->
|
<!-- Share Album List -->
|
||||||
@ -79,7 +84,7 @@
|
|||||||
<!-- Empty List -->
|
<!-- Empty List -->
|
||||||
{#if data.sharedAlbums.length === 0}
|
{#if data.sharedAlbums.length === 0}
|
||||||
<div
|
<div
|
||||||
class="border p-5 w-[50%] m-auto mt-10 bg-gray-50 rounded-3xl flex flex-col place-content-center place-items-center"
|
class="border dark:border-immich-dark-gray p-5 w-[50%] m-auto mt-10 bg-gray-50 dark:bg-immich-dark-gray rounded-3xl flex flex-col place-content-center place-items-center dark:text-immich-dark-fg"
|
||||||
>
|
>
|
||||||
<img src="/empty-2.svg" alt="Empty shared album" width="500" />
|
<img src="/empty-2.svg" alt="Empty shared album" width="500" />
|
||||||
<p class="text-center text-immich-text-gray-500">
|
<p class="text-center text-immich-text-gray-500">
|
||||||
|
@ -1,14 +1,20 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
content: ['./src/**/*.{html,js,svelte,ts}'],
|
content: ['./src/**/*.{html,js,svelte,ts}'],
|
||||||
|
darkMode: 'class',
|
||||||
theme: {
|
theme: {
|
||||||
extend: {
|
extend: {
|
||||||
colors: {
|
colors: {
|
||||||
|
// Light Theme
|
||||||
'immich-primary': '#4250af',
|
'immich-primary': '#4250af',
|
||||||
'immich-bg': 'white',
|
'immich-bg': 'white',
|
||||||
'immich-fg': 'black',
|
'immich-fg': 'black',
|
||||||
'immich-gray': '#F6F6F4'
|
'immich-gray': '#F6F6F4',
|
||||||
// 'immich-bg': '#121212',
|
|
||||||
// 'immich-fg': '#D0D0D0',
|
// Dark Theme
|
||||||
|
'immich-dark-primary': '#adcbfa',
|
||||||
|
'immich-dark-bg': 'black',
|
||||||
|
'immich-dark-fg': '#e5e7eb',
|
||||||
|
'immich-dark-gray': '#212121'
|
||||||
},
|
},
|
||||||
fontFamily: {
|
fontFamily: {
|
||||||
'immich-title': ['Snowburst One', 'cursive']
|
'immich-title': ['Snowburst One', 'cursive']
|
||||||
|
Loading…
Reference in New Issue
Block a user