@@ -11,7 +11,7 @@ import { NavbarService } from '~/services/navbar.service';
11
11
import { useExtensionSettingsStoreRefs } from ' ~/stores/settings/extension.store' ;
12
12
import { Header } from ' ~/styles/layout.style' ;
13
13
import { useI18n } from ' ~/utils/i18n.utils' ;
14
- import { handleSwipe , SwipeDirection } from ' ~/utils/touch.utils' ;
14
+ import { handleSwipe , SwipeDirection , type SwipeDirections } from ' ~/utils/touch.utils' ;
15
15
16
16
const props = defineProps ({
17
17
disabled: {
@@ -76,38 +76,78 @@ const showDrawer = computed(() => {
76
76
});
77
77
78
78
const touchStart = ref <TouchEvent >();
79
+ const drawerStart = ref <{
80
+ scroll: number ;
81
+ width: number ;
82
+ }>();
79
83
84
+ const drawerRef = ref <HTMLElement >();
80
85
const onTouchStart = (e : TouchEvent ) => {
81
86
touchStart .value = e ;
87
+
88
+ const drawer = drawerRef .value ?.firstElementChild ;
89
+ // if there is no drawer we can always navigate
90
+ if (! drawer ) return ;
91
+ drawerStart .value = {
92
+ scroll: drawer .scrollLeft ,
93
+ width: drawer .scrollWidth - drawer .clientWidth ,
94
+ };
82
95
};
83
96
84
- const onTouchEnd = (e : TouchEvent ) => {
85
- const _touchStart = touchStart .value ?.targetTouches ?.[0 ];
86
- const _touchEnd = e .changedTouches ?.[0 ];
87
- if (! _touchStart ) return ;
88
- touchStart .value = undefined ;
89
- const { clientWidth } = navElement .value || {};
90
- const swipe = handleSwipe (_touchStart , _touchEnd , {
91
- vertical: Header .totalHeight ,
92
- up: Header .navbarHeight ,
93
- left: clientWidth ? Math .min (clientWidth / 2 , 200 ) : 200 ,
94
- right: clientWidth ? Math .min (clientWidth / 2 , 200 ) : 200 ,
95
- });
97
+ const isDrawerNotScrollable = (
98
+ direction : typeof SwipeDirection .Right | typeof SwipeDirection .Left ,
99
+ start : Touch | undefined = touchStart .value ?.targetTouches ?.[0 ],
100
+ ) => {
101
+ // if we start the swipe outside the drawer we can always navigate
102
+ if (start && start ?.clientY < Header .navbarHeight ) return true ;
103
+ // if there is no drawer we can always navigate
104
+ if (! drawerStart .value ) return true ;
105
+ const { scroll, width } = drawerStart .value ;
106
+ // if the drawer is already at the end we can navigate right (swipe to the left)
107
+ if (direction === SwipeDirection .Left ) return width === scroll ;
108
+ // if the drawer is already at the start we can navigate left (swipe to the right)
109
+ return scroll === 0 ;
110
+ };
111
+
112
+ const handleSwipeDirection = (swipe : SwipeDirections ) => {
96
113
switch (swipe ) {
97
114
case SwipeDirection .Down :
98
115
isHover .value = true ;
99
- return swipe ;
116
+ break ;
100
117
case SwipeDirection .Up :
101
118
isHover .value = false ;
102
- return swipe ;
119
+ break ;
103
120
case SwipeDirection .Left :
104
- return nextRoute .value ? navigate (nextRoute .value ) : undefined ;
121
+ if (nextRoute .value && isDrawerNotScrollable (swipe )) navigate (nextRoute .value );
122
+ break ;
105
123
case SwipeDirection .Right :
106
- return prevRoute .value ? navigate (prevRoute .value ) : undefined ;
124
+ if (prevRoute .value && isDrawerNotScrollable (swipe )) navigate (prevRoute .value );
125
+ break ;
107
126
default :
108
127
Logger .warn (' Unknown swipe direction:' , swipe );
109
128
}
110
129
};
130
+
131
+ const onTouchEnd = (e : TouchEvent ) => {
132
+ const _start = touchStart .value ?.targetTouches ?.[0 ];
133
+ const _end = e .changedTouches ?.[0 ];
134
+
135
+ if (! _start || ! _end ) return ;
136
+
137
+ const { clientWidth } = navElement .value || {};
138
+ const swipe = handleSwipe (_start , _end , {
139
+ vertical: Header .totalHeight ,
140
+ up: Header .navbarHeight ,
141
+ left: clientWidth ? Math .min (clientWidth / 2 , 200 ) : 200 ,
142
+ right: clientWidth ? Math .min (clientWidth / 2 , 200 ) : 200 ,
143
+ });
144
+
145
+ if (swipe ) handleSwipeDirection (swipe );
146
+
147
+ touchStart .value = undefined ;
148
+ drawerStart .value = undefined ;
149
+ return swipe ;
150
+ };
111
151
</script >
112
152
113
153
<template >
@@ -117,8 +157,8 @@ const onTouchEnd = (e: TouchEvent) => {
117
157
@mouseleave =" isHover = false"
118
158
@focusin =" isFocus = true"
119
159
@focusout =" isFocus = false"
120
- @touchstart =" onTouchStart"
121
160
@touchend =" onTouchEnd"
161
+ @touchstart =" onTouchStart"
122
162
>
123
163
<NTabs
124
164
:key =" enabledRoutes.join('-')"
@@ -163,6 +203,7 @@ const onTouchEnd = (e: TouchEvent) => {
163
203
</NTab >
164
204
</NTabs >
165
205
<div
206
+ ref =" drawerRef"
166
207
class =" drawer"
167
208
:class =" {
168
209
'has-drawer': hasDrawer,
0 commit comments