From dc27ba6f036c15ff94aaa76b3a6928e97c934fe7 Mon Sep 17 00:00:00 2001
From: syuilo <Syuilotan@yahoo.co.jp>
Date: Sat, 24 Jun 2023 12:58:26 +0900
Subject: [PATCH] enhance(frontend): improve ux of deck scroll

Resolve #11007
---
 packages/frontend/src/ui/deck.vue        | 17 +++++++++--------
 packages/frontend/src/ui/deck/column.vue |  5 +++++
 2 files changed, 14 insertions(+), 8 deletions(-)

diff --git a/packages/frontend/src/ui/deck.vue b/packages/frontend/src/ui/deck.vue
index bd5d5beb84..988fda1c2f 100644
--- a/packages/frontend/src/ui/deck.vue
+++ b/packages/frontend/src/ui/deck.vue
@@ -4,12 +4,13 @@
 
 	<div :class="$style.main">
 		<XStatusBars/>
-		<div ref="columnsEl" :class="[$style.sections, { [$style.center]: deckStore.reactiveState.columnAlign.value === 'center', [$style.snapScroll]: snapScroll }]" @contextmenu.self.prevent="onContextmenu">
+		<div ref="columnsEl" :class="[$style.sections, { [$style.center]: deckStore.reactiveState.columnAlign.value === 'center', [$style.snapScroll]: snapScroll }]" @contextmenu.self.prevent="onContextmenu" @wheel.self="onWheel">
 			<!-- sectionを利用しているのは、deck.vue側でcolumnに対してfirst-of-typeを効かせるため -->
 			<section
 				v-for="ids in layout"
 				:class="$style.section"
 				:style="columns.filter(c => ids.includes(c.id)).some(c => c.flexible) ? { flex: 1, minWidth: '350px' } : { width: Math.max(...columns.filter(c => ids.includes(c.id)).map(c => c.width)) + 'px' }"
+				@wheel.self="onWheel"
 			>
 				<component
 					:is="columnComponents[columns.find(c => c.id === id)!.type] ?? XTlColumn"
@@ -19,6 +20,7 @@
 					:class="$style.column"
 					:column="columns.find(c => c.id === id)"
 					:isStacked="ids.length > 1"
+					@headerWheel="onWheel"
 				/>
 			</section>
 			<div v-if="layout.length === 0" class="_panel" :class="$style.onboarding">
@@ -196,15 +198,14 @@ const onContextmenu = (ev) => {
 	}], ev);
 };
 
-document.documentElement.style.overflowY = 'hidden';
-document.documentElement.style.scrollBehavior = 'auto';
-window.addEventListener('wheel', (ev) => {
-	if (ev.target === columnsEl && ev.deltaX === 0) {
-		columnsEl.scrollLeft += ev.deltaY;
-	} else if (getScrollContainer(ev.target as HTMLElement) == null && ev.deltaX === 0) {
+function onWheel(ev: WheelEvent) {
+	if (ev.deltaX === 0) {
 		columnsEl.scrollLeft += ev.deltaY;
 	}
-});
+}
+
+document.documentElement.style.overflowY = 'hidden';
+document.documentElement.style.scrollBehavior = 'auto';
 
 loadDeck();
 
diff --git a/packages/frontend/src/ui/deck/column.vue b/packages/frontend/src/ui/deck/column.vue
index c8d6744a37..f6c5c8de46 100644
--- a/packages/frontend/src/ui/deck/column.vue
+++ b/packages/frontend/src/ui/deck/column.vue
@@ -12,6 +12,7 @@
 		@dragstart="onDragstart"
 		@dragend="onDragend"
 		@contextmenu.prevent.stop="onContextmenu"
+		@wheel="emit('headerWheel', $event)"
 	>
 		<svg viewBox="0 0 256 128" :class="$style.tabShape">
 			<g transform="matrix(6.2431,0,0,6.2431,-677.417,-29.3839)">
@@ -56,6 +57,10 @@ const props = withDefaults(defineProps<{
 	naked: false,
 });
 
+const emit = defineEmits<{
+	(ev: 'headerWheel', ctx: WheelEvent): void;
+}>();
+
 let body = $shallowRef<HTMLDivElement | null>();
 
 let dragging = $ref(false);