mirror of
https://github.com/immich-app/immich.git
synced 2025-01-06 03:46:47 +01:00
fix(web): consistent modal escape behavior (#7677)
* fix(web): consistent modal escape behavior * make onClose optional
This commit is contained in:
parent
3da2b05428
commit
5dd11ca17a
39 changed files with 111 additions and 123 deletions
|
@ -10,6 +10,7 @@
|
||||||
const dispatch = createEventDispatcher<{
|
const dispatch = createEventDispatcher<{
|
||||||
success: void;
|
success: void;
|
||||||
fail: void;
|
fail: void;
|
||||||
|
cancel: void;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const handleDeleteUser = async () => {
|
const handleDeleteUser = async () => {
|
||||||
|
@ -27,7 +28,12 @@
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<ConfirmDialogue title="Delete User" confirmText="Delete" on:confirm={handleDeleteUser} on:cancel>
|
<ConfirmDialogue
|
||||||
|
title="Delete User"
|
||||||
|
confirmText="Delete"
|
||||||
|
onConfirm={handleDeleteUser}
|
||||||
|
onClose={() => dispatch('cancel')}
|
||||||
|
>
|
||||||
<svelte:fragment slot="prompt">
|
<svelte:fragment slot="prompt">
|
||||||
<div class="flex flex-col gap-4">
|
<div class="flex flex-col gap-4">
|
||||||
<p>
|
<p>
|
||||||
|
|
|
@ -148,8 +148,8 @@
|
||||||
{#if confirmJob}
|
{#if confirmJob}
|
||||||
<ConfirmDialogue
|
<ConfirmDialogue
|
||||||
prompt="Are you sure you want to reprocess all faces? This will also clear named people."
|
prompt="Are you sure you want to reprocess all faces? This will also clear named people."
|
||||||
on:confirm={onConfirm}
|
{onConfirm}
|
||||||
on:cancel={() => (confirmJob = null)}
|
onClose={() => (confirmJob = null)}
|
||||||
/>
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
const dispatch = createEventDispatcher<{
|
const dispatch = createEventDispatcher<{
|
||||||
success: void;
|
success: void;
|
||||||
fail: void;
|
fail: void;
|
||||||
|
cancel: void;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const handleRestoreUser = async () => {
|
const handleRestoreUser = async () => {
|
||||||
|
@ -24,8 +25,8 @@
|
||||||
title="Restore User"
|
title="Restore User"
|
||||||
confirmText="Continue"
|
confirmText="Continue"
|
||||||
confirmColor="green"
|
confirmColor="green"
|
||||||
on:confirm={handleRestoreUser}
|
onConfirm={handleRestoreUser}
|
||||||
on:cancel
|
onClose={() => dispatch('cancel')}
|
||||||
>
|
>
|
||||||
<svelte:fragment slot="prompt">
|
<svelte:fragment slot="prompt">
|
||||||
<p><b>{user.name}</b>'s account will be restored.</p>
|
<p><b>{user.name}</b>'s account will be restored.</p>
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import ConfirmDialogue from '$lib/components/shared-components/confirm-dialogue.svelte';
|
import ConfirmDialogue from '$lib/components/shared-components/confirm-dialogue.svelte';
|
||||||
|
|
||||||
|
export let onCancel: () => void;
|
||||||
|
export let onConfirm: () => void;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<ConfirmDialogue title="Disable Login" on:cancel on:confirm>
|
<ConfirmDialogue title="Disable Login" onClose={onCancel} {onConfirm}>
|
||||||
<svelte:fragment slot="prompt">
|
<svelte:fragment slot="prompt">
|
||||||
<div class="flex flex-col gap-4">
|
<div class="flex flex-col gap-4">
|
||||||
<p>Are you sure you want to disable all login methods? Login will be completely disabled.</p>
|
<p>Are you sure you want to disable all login methods? Login will be completely disabled.</p>
|
||||||
|
|
|
@ -56,7 +56,7 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if isConfirmOpen}
|
{#if isConfirmOpen}
|
||||||
<ConfirmDisableLogin on:cancel={() => handleConfirm(false)} on:confirm={() => handleConfirm(true)} />
|
<ConfirmDisableLogin onCancel={() => handleConfirm(false)} onConfirm={() => handleConfirm(true)} />
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<div class="mt-2">
|
<div class="mt-2">
|
||||||
|
|
|
@ -41,7 +41,7 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if isConfirmOpen}
|
{#if isConfirmOpen}
|
||||||
<ConfirmDisableLogin on:cancel={() => handleConfirm(false)} on:confirm={() => handleConfirm(true)} />
|
<ConfirmDisableLogin onCancel={() => handleConfirm(false)} onConfirm={() => handleConfirm(true)} />
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
}>();
|
}>();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<FullScreenModal on:clickOutside={() => dispatch('close')}>
|
<FullScreenModal onClose={() => dispatch('close')}>
|
||||||
<div class="flex h-full w-full place-content-center place-items-center overflow-hidden p-2 md:p-0">
|
<div class="flex h-full w-full place-content-center place-items-center overflow-hidden p-2 md:p-0">
|
||||||
<div
|
<div
|
||||||
class="w-[550px] rounded-3xl border bg-immich-bg shadow-sm dark:border-immich-dark-gray dark:bg-immich-dark-gray dark:text-immich-dark-fg"
|
class="w-[550px] rounded-3xl border bg-immich-bg shadow-sm dark:border-immich-dark-gray dark:bg-immich-dark-gray dark:text-immich-dark-fg"
|
||||||
|
|
|
@ -129,8 +129,8 @@
|
||||||
title="Leave Album?"
|
title="Leave Album?"
|
||||||
prompt="Are you sure you want to leave {album.albumName}?"
|
prompt="Are you sure you want to leave {album.albumName}?"
|
||||||
confirmText="Leave"
|
confirmText="Leave"
|
||||||
on:confirm={handleRemoveUser}
|
onConfirm={handleRemoveUser}
|
||||||
on:cancel={() => (selectedRemoveUser = null)}
|
onClose={() => (selectedRemoveUser = null)}
|
||||||
/>
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
|
@ -139,7 +139,7 @@
|
||||||
title="Remove User?"
|
title="Remove User?"
|
||||||
prompt="Are you sure you want to remove {selectedRemoveUser.name}"
|
prompt="Are you sure you want to remove {selectedRemoveUser.name}"
|
||||||
confirmText="Remove"
|
confirmText="Remove"
|
||||||
on:confirm={handleRemoveUser}
|
onConfirm={handleRemoveUser}
|
||||||
on:cancel={() => (selectedRemoveUser = null)}
|
onClose={() => (selectedRemoveUser = null)}
|
||||||
/>
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
|
@ -158,8 +158,8 @@
|
||||||
<ConfirmDialogue
|
<ConfirmDialogue
|
||||||
title="Merge people"
|
title="Merge people"
|
||||||
confirmText="Merge"
|
confirmText="Merge"
|
||||||
on:confirm={handleMerge}
|
onConfirm={handleMerge}
|
||||||
on:cancel={() => (isShowConfirmation = false)}
|
onClose={() => (isShowConfirmation = false)}
|
||||||
>
|
>
|
||||||
<svelte:fragment slot="prompt">
|
<svelte:fragment slot="prompt">
|
||||||
<p>Are you sure you want merge these people ?</p></svelte:fragment
|
<p>Are you sure you want merge these people ?</p></svelte:fragment
|
||||||
|
|
|
@ -23,15 +23,6 @@
|
||||||
close: void;
|
close: void;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const handleKeyboardPress = (event: KeyboardEvent) => {
|
|
||||||
switch (event.key) {
|
|
||||||
case 'Escape': {
|
|
||||||
dispatch('close');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const changePersonToMerge = (newperson: PersonResponseDto) => {
|
const changePersonToMerge = (newperson: PersonResponseDto) => {
|
||||||
const index = potentialMergePeople.indexOf(newperson);
|
const index = potentialMergePeople.indexOf(newperson);
|
||||||
[potentialMergePeople[index], personMerge2] = [personMerge2, potentialMergePeople[index]];
|
[potentialMergePeople[index], personMerge2] = [personMerge2, potentialMergePeople[index]];
|
||||||
|
@ -39,9 +30,7 @@
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<svelte:document on:keypress={handleKeyboardPress} />
|
<FullScreenModal onClose={() => dispatch('close')}>
|
||||||
|
|
||||||
<FullScreenModal on:clickOutside={() => dispatch('close')}>
|
|
||||||
<div class="flex h-full w-full place-content-center place-items-center overflow-hidden">
|
<div class="flex h-full w-full place-content-center place-items-center overflow-hidden">
|
||||||
<div
|
<div
|
||||||
class="w-[250px] max-w-[125vw] rounded-3xl border bg-immich-bg shadow-sm dark:border-immich-dark-gray dark:bg-immich-dark-gray dark:text-immich-dark-fg md:w-[375px]"
|
class="w-[250px] max-w-[125vw] rounded-3xl border bg-immich-bg shadow-sm dark:border-immich-dark-gray dark:bg-immich-dark-gray dark:text-immich-dark-fg md:w-[375px]"
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<FullScreenModal on:clickOutside={() => handleCancel()}>
|
<FullScreenModal onClose={handleCancel}>
|
||||||
<div
|
<div
|
||||||
class="w-[500px] max-w-[95vw] rounded-3xl border bg-immich-bg p-4 py-8 shadow-sm dark:border-immich-dark-gray dark:bg-immich-dark-gray dark:text-immich-dark-fg"
|
class="w-[500px] max-w-[95vw] rounded-3xl border bg-immich-bg p-4 py-8 shadow-sm dark:border-immich-dark-gray dark:bg-immich-dark-gray dark:text-immich-dark-fg"
|
||||||
>
|
>
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<FullScreenModal on:clickOutside={handleCancel}>
|
<FullScreenModal onClose={handleCancel}>
|
||||||
<div
|
<div
|
||||||
class="w-[500px] max-w-[95vw] rounded-3xl border bg-immich-bg p-4 py-8 shadow-sm dark:border-immich-dark-gray dark:bg-immich-dark-gray dark:text-immich-dark-fg"
|
class="w-[500px] max-w-[95vw] rounded-3xl border bg-immich-bg p-4 py-8 shadow-sm dark:border-immich-dark-gray dark:bg-immich-dark-gray dark:text-immich-dark-fg"
|
||||||
>
|
>
|
||||||
|
|
|
@ -147,8 +147,8 @@
|
||||||
<ConfirmDialogue
|
<ConfirmDialogue
|
||||||
title="Reset Password"
|
title="Reset Password"
|
||||||
confirmText="Reset"
|
confirmText="Reset"
|
||||||
on:confirm={resetPassword}
|
onConfirm={resetPassword}
|
||||||
on:cancel={() => (isShowResetPasswordConfirmation = false)}
|
onClose={() => (isShowResetPasswordConfirmation = false)}
|
||||||
>
|
>
|
||||||
<svelte:fragment slot="prompt">
|
<svelte:fragment slot="prompt">
|
||||||
<p>
|
<p>
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
const handleSubmit = () => dispatch('submit', { excludePattern: exclusionPattern });
|
const handleSubmit = () => dispatch('submit', { excludePattern: exclusionPattern });
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<FullScreenModal on:clickOutside={() => handleCancel()}>
|
<FullScreenModal onClose={handleCancel}>
|
||||||
<div
|
<div
|
||||||
class="w-[500px] max-w-[95vw] rounded-3xl border bg-immich-bg p-4 py-8 shadow-sm dark:border-immich-dark-gray dark:bg-immich-dark-gray dark:text-immich-dark-fg"
|
class="w-[500px] max-w-[95vw] rounded-3xl border bg-immich-bg p-4 py-8 shadow-sm dark:border-immich-dark-gray dark:bg-immich-dark-gray dark:text-immich-dark-fg"
|
||||||
>
|
>
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
const handleSubmit = () => dispatch('submit', { importPath });
|
const handleSubmit = () => dispatch('submit', { importPath });
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<FullScreenModal on:clickOutside={() => handleCancel()}>
|
<FullScreenModal onClose={handleCancel}>
|
||||||
<div
|
<div
|
||||||
class="w-[500px] max-w-[95vw] rounded-3xl border bg-immich-bg p-4 py-8 shadow-sm dark:border-immich-dark-gray dark:bg-immich-dark-gray dark:text-immich-dark-fg"
|
class="w-[500px] max-w-[95vw] rounded-3xl border bg-immich-bg p-4 py-8 shadow-sm dark:border-immich-dark-gray dark:bg-immich-dark-gray dark:text-immich-dark-fg"
|
||||||
>
|
>
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
const handleSubmit = () => dispatch('submit', { ownerId });
|
const handleSubmit = () => dispatch('submit', { ownerId });
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<FullScreenModal on:clickOutside={() => handleCancel()}>
|
<FullScreenModal onClose={handleCancel}>
|
||||||
<div
|
<div
|
||||||
class="w-[500px] max-w-[95vw] rounded-3xl border bg-immich-bg p-4 py-8 shadow-sm dark:border-immich-dark-gray dark:bg-immich-dark-gray dark:text-immich-dark-fg"
|
class="w-[500px] max-w-[95vw] rounded-3xl border bg-immich-bg p-4 py-8 shadow-sm dark:border-immich-dark-gray dark:bg-immich-dark-gray dark:text-immich-dark-fg"
|
||||||
>
|
>
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
const handleClose = () => dispatch('close');
|
const handleClose = () => dispatch('close');
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<FullScreenModal on:clickOutside={handleClose} on:escape={handleClose}>
|
<FullScreenModal onClose={handleClose}>
|
||||||
<div
|
<div
|
||||||
class="flex w-96 max-w-lg flex-col gap-8 rounded-3xl border bg-white p-8 shadow-sm dark:border-immich-dark-gray dark:bg-immich-dark-gray"
|
class="flex w-96 max-w-lg flex-col gap-8 rounded-3xl border bg-white p-8 shadow-sm dark:border-immich-dark-gray dark:bg-immich-dark-gray"
|
||||||
>
|
>
|
||||||
|
|
|
@ -59,8 +59,8 @@
|
||||||
<ConfirmDialogue
|
<ConfirmDialogue
|
||||||
title="Remove from {album.albumName}"
|
title="Remove from {album.albumName}"
|
||||||
confirmText="Remove"
|
confirmText="Remove"
|
||||||
on:confirm={removeFromAlbum}
|
onConfirm={removeFromAlbum}
|
||||||
on:cancel={() => (isShowConfirmation = false)}
|
onClose={() => (isShowConfirmation = false)}
|
||||||
>
|
>
|
||||||
<svelte:fragment slot="prompt">
|
<svelte:fragment slot="prompt">
|
||||||
<p>
|
<p>
|
||||||
|
|
|
@ -53,7 +53,7 @@
|
||||||
title="Remove Assets?"
|
title="Remove Assets?"
|
||||||
prompt="Are you sure you want to remove {getAssets().size} asset(s) from this shared link?"
|
prompt="Are you sure you want to remove {getAssets().size} asset(s) from this shared link?"
|
||||||
confirmText="Remove"
|
confirmText="Remove"
|
||||||
on:confirm={() => handleRemove()}
|
onConfirm={() => handleRemove()}
|
||||||
on:cancel={() => (removing = false)}
|
onClose={() => (removing = false)}
|
||||||
/>
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
|
@ -27,9 +27,8 @@
|
||||||
<ConfirmDialogue
|
<ConfirmDialogue
|
||||||
title="Permanently Delete Asset{size > 1 ? 's' : ''}"
|
title="Permanently Delete Asset{size > 1 ? 's' : ''}"
|
||||||
confirmText="Delete"
|
confirmText="Delete"
|
||||||
on:confirm={handleConfirm}
|
onConfirm={handleConfirm}
|
||||||
on:cancel={() => dispatch('cancel')}
|
onClose={() => dispatch('cancel')}
|
||||||
on:escape={() => dispatch('cancel')}
|
|
||||||
>
|
>
|
||||||
<svelte:fragment slot="prompt">
|
<svelte:fragment slot="prompt">
|
||||||
<p>
|
<p>
|
||||||
|
|
|
@ -68,8 +68,8 @@
|
||||||
title="Edit date & time"
|
title="Edit date & time"
|
||||||
prompt="Please select a new date:"
|
prompt="Please select a new date:"
|
||||||
disabled={!date.isValid}
|
disabled={!date.isValid}
|
||||||
on:confirm={handleConfirm}
|
onConfirm={handleConfirm}
|
||||||
on:cancel={handleCancel}
|
onClose={handleCancel}
|
||||||
>
|
>
|
||||||
<div class="flex flex-col text-md px-4 text-center gap-2" slot="prompt">
|
<div class="flex flex-col text-md px-4 text-center gap-2" slot="prompt">
|
||||||
<div class="mt-2" />
|
<div class="mt-2" />
|
||||||
|
|
|
@ -144,8 +144,8 @@
|
||||||
cancelColor="secondary"
|
cancelColor="secondary"
|
||||||
title="Change Location"
|
title="Change Location"
|
||||||
width={800}
|
width={800}
|
||||||
on:confirm={handleConfirm}
|
onConfirm={handleConfirm}
|
||||||
on:cancel={handleCancel}
|
onClose={handleCancel}
|
||||||
>
|
>
|
||||||
<div slot="prompt" class="flex flex-col w-full h-full gap-2">
|
<div slot="prompt" class="flex flex-col w-full h-full gap-2">
|
||||||
<div class="relative w-64 sm:w-96" use:clickOutside on:outclick={() => (hideSuggestion = true)}>
|
<div class="relative w-64 sm:w-96" use:clickOutside on:outclick={() => (hideSuggestion = true)}>
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { createEventDispatcher } from 'svelte';
|
|
||||||
import FullScreenModal from './full-screen-modal.svelte';
|
import FullScreenModal from './full-screen-modal.svelte';
|
||||||
import Button from '../elements/buttons/button.svelte';
|
import Button from '../elements/buttons/button.svelte';
|
||||||
import type { Color } from '$lib/components/elements/buttons/button.svelte';
|
import type { Color } from '$lib/components/elements/buttons/button.svelte';
|
||||||
|
@ -13,29 +12,18 @@
|
||||||
export let hideCancelButton = false;
|
export let hideCancelButton = false;
|
||||||
export let disabled = false;
|
export let disabled = false;
|
||||||
export let width = 500;
|
export let width = 500;
|
||||||
|
export let onClose: () => void;
|
||||||
const dispatch = createEventDispatcher<{ cancel: void; confirm: void; 'click-outside': void }>();
|
export let onConfirm: () => void;
|
||||||
|
|
||||||
let isConfirmButtonDisabled = false;
|
let isConfirmButtonDisabled = false;
|
||||||
|
|
||||||
const handleCancel = () => dispatch('cancel');
|
|
||||||
const handleEscape = () => {
|
|
||||||
if (!isConfirmButtonDisabled) {
|
|
||||||
dispatch('cancel');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleConfirm = () => {
|
const handleConfirm = () => {
|
||||||
isConfirmButtonDisabled = true;
|
isConfirmButtonDisabled = true;
|
||||||
dispatch('confirm');
|
onConfirm();
|
||||||
};
|
|
||||||
|
|
||||||
const handleClickOutside = () => {
|
|
||||||
dispatch('click-outside');
|
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<FullScreenModal on:clickOutside={handleClickOutside} on:escape={() => handleEscape()}>
|
<FullScreenModal {onClose}>
|
||||||
<div
|
<div
|
||||||
class="max-w-[95vw] rounded-3xl border bg-immich-bg p-4 py-8 shadow-sm dark:border-immich-dark-gray dark:bg-immich-dark-gray dark:text-immich-dark-fg"
|
class="max-w-[95vw] rounded-3xl border bg-immich-bg p-4 py-8 shadow-sm dark:border-immich-dark-gray dark:bg-immich-dark-gray dark:text-immich-dark-fg"
|
||||||
style="width: {width}px"
|
style="width: {width}px"
|
||||||
|
@ -56,7 +44,7 @@
|
||||||
|
|
||||||
<div class="mt-4 flex w-full gap-4 px-4">
|
<div class="mt-4 flex w-full gap-4 px-4">
|
||||||
{#if !hideCancelButton}
|
{#if !hideCancelButton}
|
||||||
<Button color={cancelColor} fullwidth on:click={handleCancel}>
|
<Button color={cancelColor} fullwidth on:click={onClose}>
|
||||||
{cancelText}
|
{cancelText}
|
||||||
</Button>
|
</Button>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
|
@ -1,12 +1,8 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { clickOutside } from '../../utils/click-outside';
|
import { clickOutside } from '../../utils/click-outside';
|
||||||
import { createEventDispatcher } from 'svelte';
|
|
||||||
import { fade } from 'svelte/transition';
|
import { fade } from 'svelte/transition';
|
||||||
|
|
||||||
const dispatch = createEventDispatcher<{
|
export let onClose: (() => void) | undefined = undefined;
|
||||||
clickOutside: void;
|
|
||||||
escape: void;
|
|
||||||
}>();
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<section
|
<section
|
||||||
|
@ -14,12 +10,7 @@
|
||||||
out:fade={{ duration: 100 }}
|
out:fade={{ duration: 100 }}
|
||||||
class="fixed left-0 top-0 z-[9990] flex h-screen w-screen place-content-center place-items-center bg-black/40"
|
class="fixed left-0 top-0 z-[9990] flex h-screen w-screen place-content-center place-items-center bg-black/40"
|
||||||
>
|
>
|
||||||
<div
|
<div class="z-[9999]" use:clickOutside={{ onOutclick: onClose, onEscape: onClose }}>
|
||||||
class="z-[9999]"
|
|
||||||
use:clickOutside
|
|
||||||
on:outclick={() => dispatch('clickOutside')}
|
|
||||||
on:escape={() => dispatch('escape')}
|
|
||||||
>
|
|
||||||
<slot />
|
<slot />
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
const colors: UserAvatarColor[] = Object.values(UserAvatarColor);
|
const colors: UserAvatarColor[] = Object.values(UserAvatarColor);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<FullScreenModal on:clickOutside={() => dispatch('close')} on:escape={() => dispatch('close')}>
|
<FullScreenModal onClose={() => dispatch('close')}>
|
||||||
<div class="flex h-full w-full place-content-center place-items-center overflow-hidden">
|
<div class="flex h-full w-full place-content-center place-items-center overflow-hidden">
|
||||||
<div
|
<div
|
||||||
class=" rounded-3xl border bg-immich-bg shadow-sm dark:border-immich-dark-gray dark:bg-immich-dark-gray dark:text-immich-dark-fg p-4"
|
class=" rounded-3xl border bg-immich-bg shadow-sm dark:border-immich-dark-gray dark:bg-immich-dark-gray dark:text-immich-dark-fg p-4"
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
}>();
|
}>();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<FullScreenModal on:clickOutside={() => dispatch('close')} on:escape={() => dispatch('close')}>
|
<FullScreenModal onClose={() => dispatch('close')}>
|
||||||
<div class="flex h-full w-full place-content-center place-items-center overflow-hidden">
|
<div class="flex h-full w-full place-content-center place-items-center overflow-hidden">
|
||||||
<div
|
<div
|
||||||
class="w-[400px] max-w-[125vw] rounded-3xl border bg-immich-bg shadow-sm dark:border-immich-dark-gray dark:bg-immich-dark-gray dark:text-immich-dark-fg md:w-[650px]"
|
class="w-[400px] max-w-[125vw] rounded-3xl border bg-immich-bg shadow-sm dark:border-immich-dark-gray dark:bg-immich-dark-gray dark:text-immich-dark-fg md:w-[650px]"
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if showModal}
|
{#if showModal}
|
||||||
<FullScreenModal on:clickOutside={() => (showModal = false)}>
|
<FullScreenModal onClose={() => (showModal = false)}>
|
||||||
<div
|
<div
|
||||||
class="max-w-lg rounded-3xl border bg-immich-bg px-8 py-10 shadow-sm dark:border-immich-dark-gray dark:bg-immich-dark-gray dark:text-immich-dark-fg"
|
class="max-w-lg rounded-3xl border bg-immich-bg px-8 py-10 shadow-sm dark:border-immich-dark-gray dark:bg-immich-dark-gray dark:text-immich-dark-fg"
|
||||||
>
|
>
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<FullScreenModal on:clickOutside={onClose} on:escape={onClose}>
|
<FullScreenModal {onClose}>
|
||||||
<div
|
<div
|
||||||
class="flex w-full md:w-96 max-w-lg flex-col gap-8 rounded-3xl border bg-white p-8 shadow-sm dark:border-immich-dark-gray dark:bg-immich-dark-gray"
|
class="flex w-full md:w-96 max-w-lg flex-col gap-8 rounded-3xl border bg-white p-8 shadow-sm dark:border-immich-dark-gray dark:bg-immich-dark-gray"
|
||||||
>
|
>
|
||||||
|
|
|
@ -50,16 +50,16 @@
|
||||||
{#if deleteDevice}
|
{#if deleteDevice}
|
||||||
<ConfirmDialogue
|
<ConfirmDialogue
|
||||||
prompt="Are you sure you want to log out this device?"
|
prompt="Are you sure you want to log out this device?"
|
||||||
on:confirm={() => handleDelete()}
|
onConfirm={() => handleDelete()}
|
||||||
on:cancel={() => (deleteDevice = null)}
|
onClose={() => (deleteDevice = null)}
|
||||||
/>
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{#if deleteAll}
|
{#if deleteAll}
|
||||||
<ConfirmDialogue
|
<ConfirmDialogue
|
||||||
prompt="Are you sure you want to log out all devices?"
|
prompt="Are you sure you want to log out all devices?"
|
||||||
on:confirm={() => handleDeleteAll()}
|
onConfirm={() => handleDeleteAll()}
|
||||||
on:cancel={() => (deleteAll = false)}
|
onClose={() => (deleteAll = false)}
|
||||||
/>
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
|
|
|
@ -190,7 +190,7 @@
|
||||||
<ConfirmDialogue
|
<ConfirmDialogue
|
||||||
title="Stop sharing your photos?"
|
title="Stop sharing your photos?"
|
||||||
prompt="{removePartnerDto.name} will no longer be able to access your photos."
|
prompt="{removePartnerDto.name} will no longer be able to access your photos."
|
||||||
on:cancel={() => (removePartnerDto = null)}
|
onClose={() => (removePartnerDto = null)}
|
||||||
on:confirm={() => handleRemovePartner()}
|
onConfirm={() => handleRemovePartner()}
|
||||||
/>
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
|
@ -105,8 +105,8 @@
|
||||||
{#if deleteKey}
|
{#if deleteKey}
|
||||||
<ConfirmDialogue
|
<ConfirmDialogue
|
||||||
prompt="Are you sure you want to delete this API Key?"
|
prompt="Are you sure you want to delete this API Key?"
|
||||||
on:confirm={() => handleDelete()}
|
onConfirm={() => handleDelete()}
|
||||||
on:cancel={() => (deleteKey = null)}
|
onClose={() => (deleteKey = null)}
|
||||||
/>
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
|
|
|
@ -1,20 +1,42 @@
|
||||||
import type { ActionReturn } from 'svelte/action';
|
import type { ActionReturn } from 'svelte/action';
|
||||||
|
|
||||||
interface Attributes {
|
interface Attributes {
|
||||||
|
/** @deprecated */
|
||||||
'on:outclick'?: (e: CustomEvent) => void;
|
'on:outclick'?: (e: CustomEvent) => void;
|
||||||
|
/** @deprecated **/
|
||||||
'on:escape'?: (e: CustomEvent) => void;
|
'on:escape'?: (e: CustomEvent) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function clickOutside(node: HTMLElement): ActionReturn<void, Attributes> {
|
interface Options {
|
||||||
|
onOutclick?: () => void;
|
||||||
|
onEscape?: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function clickOutside(node: HTMLElement, options: Options = {}): ActionReturn<void, Attributes> {
|
||||||
|
const { onOutclick, onEscape } = options;
|
||||||
|
|
||||||
const handleClick = (event: MouseEvent) => {
|
const handleClick = (event: MouseEvent) => {
|
||||||
const targetNode = event.target as Node | null;
|
const targetNode = event.target as Node | null;
|
||||||
if (!node.contains(targetNode)) {
|
if (node.contains(targetNode)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (onOutclick) {
|
||||||
|
onOutclick();
|
||||||
|
} else {
|
||||||
node.dispatchEvent(new CustomEvent('outclick'));
|
node.dispatchEvent(new CustomEvent('outclick'));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleKey = (event: KeyboardEvent) => {
|
const handleKey = (event: KeyboardEvent) => {
|
||||||
if (event.key === 'Escape') {
|
if (event.key !== 'Escape') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (onEscape) {
|
||||||
|
event.stopPropagation();
|
||||||
|
onEscape();
|
||||||
|
} else {
|
||||||
node.dispatchEvent(new CustomEvent('escape'));
|
node.dispatchEvent(new CustomEvent('escape'));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -236,7 +236,7 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if shouldShowEditUserForm}
|
{#if shouldShowEditUserForm}
|
||||||
<FullScreenModal on:clickOutside={() => (shouldShowEditUserForm = false)}>
|
<FullScreenModal onClose={() => (shouldShowEditUserForm = false)}>
|
||||||
<EditAlbumForm
|
<EditAlbumForm
|
||||||
album={selectedAlbum}
|
album={selectedAlbum}
|
||||||
on:editSuccess={() => successModifyAlbum()}
|
on:editSuccess={() => successModifyAlbum()}
|
||||||
|
@ -399,8 +399,8 @@
|
||||||
<ConfirmDialogue
|
<ConfirmDialogue
|
||||||
title="Delete Album"
|
title="Delete Album"
|
||||||
confirmText="Delete"
|
confirmText="Delete"
|
||||||
on:confirm={deleteSelectedAlbum}
|
onConfirm={deleteSelectedAlbum}
|
||||||
on:cancel={() => (albumToDelete = null)}
|
onClose={() => (albumToDelete = null)}
|
||||||
>
|
>
|
||||||
<svelte:fragment slot="prompt">
|
<svelte:fragment slot="prompt">
|
||||||
<p>Are you sure you want to delete the album <b>{albumToDelete.albumName}</b>?</p>
|
<p>Are you sure you want to delete the album <b>{albumToDelete.albumName}</b>?</p>
|
||||||
|
|
|
@ -692,8 +692,8 @@
|
||||||
<ConfirmDialogue
|
<ConfirmDialogue
|
||||||
title="Delete album"
|
title="Delete album"
|
||||||
confirmText="Delete"
|
confirmText="Delete"
|
||||||
on:confirm={handleRemoveAlbum}
|
onConfirm={handleRemoveAlbum}
|
||||||
on:cancel={() => (viewMode = ViewMode.VIEW)}
|
onClose={() => (viewMode = ViewMode.VIEW)}
|
||||||
>
|
>
|
||||||
<svelte:fragment slot="prompt">
|
<svelte:fragment slot="prompt">
|
||||||
<p>Are you sure you want to delete the album <b>{album.albumName}</b>?</p>
|
<p>Are you sure you want to delete the album <b>{album.albumName}</b>?</p>
|
||||||
|
|
|
@ -420,7 +420,6 @@
|
||||||
<svelte:window bind:innerHeight />
|
<svelte:window bind:innerHeight />
|
||||||
|
|
||||||
{#if showMergeModal}
|
{#if showMergeModal}
|
||||||
<FullScreenModal on:clickOutside={() => (showMergeModal = false)}>
|
|
||||||
<MergeSuggestionModal
|
<MergeSuggestionModal
|
||||||
{personMerge1}
|
{personMerge1}
|
||||||
{personMerge2}
|
{personMerge2}
|
||||||
|
@ -429,7 +428,6 @@
|
||||||
on:reject={() => changeName()}
|
on:reject={() => changeName()}
|
||||||
on:confirm={(event) => handleMergeSamePerson(event.detail)}
|
on:confirm={(event) => handleMergeSamePerson(event.detail)}
|
||||||
/>
|
/>
|
||||||
</FullScreenModal>
|
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<UserPageLayout
|
<UserPageLayout
|
||||||
|
@ -487,7 +485,7 @@
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{#if showChangeNameModal}
|
{#if showChangeNameModal}
|
||||||
<FullScreenModal on:clickOutside={() => (showChangeNameModal = false)}>
|
<FullScreenModal onClose={() => (showChangeNameModal = false)}>
|
||||||
<div
|
<div
|
||||||
class="w-[500px] max-w-[95vw] rounded-3xl border bg-immich-bg p-4 py-8 shadow-sm dark:border-immich-dark-gray dark:bg-immich-dark-gray dark:text-immich-dark-fg"
|
class="w-[500px] max-w-[95vw] rounded-3xl border bg-immich-bg p-4 py-8 shadow-sm dark:border-immich-dark-gray dark:bg-immich-dark-gray dark:text-immich-dark-fg"
|
||||||
>
|
>
|
||||||
|
|
|
@ -91,7 +91,7 @@
|
||||||
title="Delete Shared Link"
|
title="Delete Shared Link"
|
||||||
prompt="Are you sure you want to delete this shared link?"
|
prompt="Are you sure you want to delete this shared link?"
|
||||||
confirmText="Delete"
|
confirmText="Delete"
|
||||||
on:confirm={() => handleDeleteLink()}
|
onConfirm={() => handleDeleteLink()}
|
||||||
on:cancel={() => (deleteLinkId = null)}
|
onClose={() => (deleteLinkId = null)}
|
||||||
/>
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
|
@ -105,8 +105,8 @@
|
||||||
<ConfirmDialogue
|
<ConfirmDialogue
|
||||||
title="Empty Trash"
|
title="Empty Trash"
|
||||||
confirmText="Empty"
|
confirmText="Empty"
|
||||||
on:confirm={handleEmptyTrash}
|
onConfirm={handleEmptyTrash}
|
||||||
on:cancel={() => (isShowEmptyConfirmation = false)}
|
onClose={() => (isShowEmptyConfirmation = false)}
|
||||||
>
|
>
|
||||||
<svelte:fragment slot="prompt">
|
<svelte:fragment slot="prompt">
|
||||||
<p>Are you sure you want to empty the trash? This will remove all the assets in trash permanently from Immich.</p>
|
<p>Are you sure you want to empty the trash? This will remove all the assets in trash permanently from Immich.</p>
|
||||||
|
|
|
@ -307,8 +307,8 @@
|
||||||
<ConfirmDialogue
|
<ConfirmDialogue
|
||||||
title="Warning!"
|
title="Warning!"
|
||||||
prompt="Are you sure you want to delete this library? This will delete all {deleteAssetCount} contained assets from Immich and cannot be undone. Files will remain on disk."
|
prompt="Are you sure you want to delete this library? This will delete all {deleteAssetCount} contained assets from Immich and cannot be undone. Files will remain on disk."
|
||||||
on:confirm={handleDelete}
|
onConfirm={handleDelete}
|
||||||
on:cancel={() => (confirmDeleteLibrary = null)}
|
onClose={() => (confirmDeleteLibrary = null)}
|
||||||
/>
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
|
|
|
@ -103,19 +103,13 @@
|
||||||
<section id="setting-content" class="flex place-content-center sm:mx-4">
|
<section id="setting-content" class="flex place-content-center sm:mx-4">
|
||||||
<section class="w-full pb-28 lg:w-[850px]">
|
<section class="w-full pb-28 lg:w-[850px]">
|
||||||
{#if shouldShowCreateUserForm}
|
{#if shouldShowCreateUserForm}
|
||||||
<FullScreenModal
|
<FullScreenModal onClose={() => (shouldShowCreateUserForm = false)}>
|
||||||
on:clickOutside={() => (shouldShowCreateUserForm = false)}
|
|
||||||
on:escape={() => (shouldShowCreateUserForm = false)}
|
|
||||||
>
|
|
||||||
<CreateUserForm on:submit={onUserCreated} on:cancel={() => (shouldShowCreateUserForm = false)} />
|
<CreateUserForm on:submit={onUserCreated} on:cancel={() => (shouldShowCreateUserForm = false)} />
|
||||||
</FullScreenModal>
|
</FullScreenModal>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{#if shouldShowEditUserForm}
|
{#if shouldShowEditUserForm}
|
||||||
<FullScreenModal
|
<FullScreenModal onClose={() => (shouldShowEditUserForm = false)}>
|
||||||
on:clickOutside={() => (shouldShowEditUserForm = false)}
|
|
||||||
on:escape={() => (shouldShowEditUserForm = false)}
|
|
||||||
>
|
|
||||||
<EditUserForm
|
<EditUserForm
|
||||||
user={selectedUser}
|
user={selectedUser}
|
||||||
canResetPassword={selectedUser?.id !== $user.id}
|
canResetPassword={selectedUser?.id !== $user.id}
|
||||||
|
@ -145,10 +139,7 @@
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{#if shouldShowInfoPanel}
|
{#if shouldShowInfoPanel}
|
||||||
<FullScreenModal
|
<FullScreenModal onClose={() => (shouldShowInfoPanel = false)}>
|
||||||
on:clickOutside={() => (shouldShowInfoPanel = false)}
|
|
||||||
on:escape={() => (shouldShowInfoPanel = false)}
|
|
||||||
>
|
|
||||||
<div class="w-[500px] max-w-[95vw] rounded-3xl border bg-white p-8 text-sm shadow-sm">
|
<div class="w-[500px] max-w-[95vw] rounded-3xl border bg-white p-8 text-sm shadow-sm">
|
||||||
<h1 class="mb-4 text-lg font-medium text-immich-primary">Password reset success</h1>
|
<h1 class="mb-4 text-lg font-medium text-immich-primary">Password reset success</h1>
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue