mirror of
https://github.com/immich-app/immich
synced 2025-11-14 17:36:12 +00:00
feat(web): allow ctrl-click / cmd-click on photos (#9954)
* feat(web): allow ctrl-click / cmd-click on photos * fix: photo opening when deselected bug * fix: consistent naming * remove redundant code * fix: disabled picture is clickable in "add to album" grid * remove unnecessary code * cleanup * fix file permissions * fix: album selection bug * fix: stack slideshow bug & search gallery viewer bug * cleanup * fix dark mode stack slideshow bug * cleanup --------- Co-authored-by: Alex Tran <alex.tran1502@gmail.com>
This commit is contained in:
parent
d8d64ecc45
commit
4d862525bc
5 changed files with 28 additions and 14 deletions
|
|
@ -23,6 +23,7 @@
|
|||
import ImageThumbnail from './image-thumbnail.svelte';
|
||||
import VideoThumbnail from './video-thumbnail.svelte';
|
||||
import { shortcut } from '$lib/actions/shortcut';
|
||||
import { currentUrlReplaceAssetId } from '$lib/utils/navigation';
|
||||
|
||||
const dispatch = createEventDispatcher<{
|
||||
select: { asset: AssetResponseDto };
|
||||
|
|
@ -36,6 +37,8 @@
|
|||
export let thumbnailHeight: number | undefined = undefined;
|
||||
export let selected = false;
|
||||
export let selectionCandidate = false;
|
||||
export let isMultiSelectState = false;
|
||||
export let isStackSlideshow = false;
|
||||
export let disabled = false;
|
||||
export let readonly = false;
|
||||
export let showArchiveIcon = false;
|
||||
|
|
@ -46,7 +49,6 @@
|
|||
export { className as class };
|
||||
|
||||
let mouseOver = false;
|
||||
$: clickable = !disabled && onClick;
|
||||
|
||||
$: dispatch('mouse-event', { isMouseOver: mouseOver, selectedGroupIndex: groupIndex });
|
||||
|
||||
|
|
@ -62,19 +64,30 @@
|
|||
return [235, 235];
|
||||
})();
|
||||
|
||||
const thumbnailClickedHandler = () => {
|
||||
if (clickable) {
|
||||
const thumbnailClickedHandler = (e: Event) => {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
if (!disabled) {
|
||||
onClick?.(asset);
|
||||
}
|
||||
};
|
||||
|
||||
const onIconClickedHandler = (e: MouseEvent) => {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
if (!disabled) {
|
||||
dispatch('select', { asset });
|
||||
}
|
||||
};
|
||||
|
||||
const handleClick = (e: Event) => {
|
||||
if (isMultiSelectState) {
|
||||
onIconClickedHandler(e as MouseEvent);
|
||||
} else if (isStackSlideshow) {
|
||||
thumbnailClickedHandler(e);
|
||||
}
|
||||
};
|
||||
|
||||
const onMouseEnter = () => {
|
||||
mouseOver = true;
|
||||
};
|
||||
|
|
@ -85,24 +98,22 @@
|
|||
</script>
|
||||
|
||||
<IntersectionObserver once={false} on:intersected let:intersecting>
|
||||
<!-- svelte-ignore a11y-no-noninteractive-tabindex -->
|
||||
<div
|
||||
<a
|
||||
href={currentUrlReplaceAssetId(asset.id)}
|
||||
style:width="{width}px"
|
||||
style:height="{height}px"
|
||||
class="group focus-visible:outline-none relative overflow-hidden {disabled
|
||||
class="group focus-visible:outline-none flex overflow-hidden {disabled
|
||||
? 'bg-gray-300'
|
||||
: 'bg-immich-primary/20 dark:bg-immich-dark-primary/20'}"
|
||||
class:cursor-not-allowed={disabled}
|
||||
class:hover:cursor-pointer={clickable}
|
||||
on:mouseenter={onMouseEnter}
|
||||
on:mouseleave={onMouseLeave}
|
||||
role={clickable ? 'button' : undefined}
|
||||
tabindex={clickable ? 0 : undefined}
|
||||
on:click={thumbnailClickedHandler}
|
||||
tabindex={0}
|
||||
on:click={handleClick}
|
||||
use:shortcut={{ shortcut: { key: 'Enter' }, onShortcut: thumbnailClickedHandler }}
|
||||
>
|
||||
{#if intersecting}
|
||||
<div class="absolute z-20 h-full w-full {className}">
|
||||
<div class="absolute z-20 {className}" style:width="{width}px" style:height="{height}px">
|
||||
<!-- Select asset button -->
|
||||
{#if !readonly && (mouseOver || selected || selectionCandidate)}
|
||||
<button
|
||||
|
|
@ -128,7 +139,7 @@
|
|||
</div>
|
||||
|
||||
<div
|
||||
class="absolute h-full w-full select-none bg-gray-100 transition-transform dark:bg-immich-dark-gray"
|
||||
class="absolute h-full w-full select-none bg-transparent transition-transform"
|
||||
class:scale-[0.85]={selected}
|
||||
class:rounded-xl={selected}
|
||||
>
|
||||
|
|
@ -227,5 +238,5 @@
|
|||
/>
|
||||
{/if}
|
||||
{/if}
|
||||
</div>
|
||||
</a>
|
||||
</IntersectionObserver>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue