This commit is contained in:
@@ -229,14 +229,6 @@ export default {
|
||||
v-model:base-map="baseMap"
|
||||
:terrain-enabled="terrainEnabled"
|
||||
/>
|
||||
<Lightbox
|
||||
ref="lightbox"
|
||||
:always-show-nav-on-touch-devices="true"
|
||||
:position-from-top="0"
|
||||
:has-video="true"
|
||||
@media-change="onLightboxMediaChange"
|
||||
@closing="onLightboxClosing"
|
||||
/>
|
||||
<ProjectSettings
|
||||
:ref="setSettings"
|
||||
:projects="projectOptions"
|
||||
@@ -256,5 +248,13 @@ export default {
|
||||
@new-markers="addNewMarkers"
|
||||
@toggle="(bIsOpen, iAnimDuration) => onPanelToggle('right', bIsOpen, iAnimDuration)"
|
||||
/>
|
||||
<Lightbox
|
||||
ref="lightbox"
|
||||
:always-show-nav-on-touch-devices="true"
|
||||
:position-from-top="0"
|
||||
:has-video="true"
|
||||
@media-change="onLightboxMediaChange"
|
||||
@closing="onLightboxClosing"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
@@ -3,6 +3,7 @@ import Simplebar from 'simplebar-vue';
|
||||
|
||||
import AppIcon from '@components/AppIcon';
|
||||
import ProjectPost from '@components/ProjectPost';
|
||||
import { createSwipeToClose, initialSwipeState } from '@scripts/swipeToClose';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
@@ -26,7 +27,7 @@ export default {
|
||||
isOpen: false,
|
||||
posts: [],
|
||||
refreshRate: 60,
|
||||
swipe: {x: null, y: null}
|
||||
swipe: initialSwipeState()
|
||||
};
|
||||
},
|
||||
emits: ['request-last-update', 'new-markers', 'toggle'],
|
||||
@@ -76,7 +77,6 @@ export default {
|
||||
this.refIdLast = 0;
|
||||
this.firstChunk = true;
|
||||
this.posts = [];
|
||||
this.swipe = {x: null, y: null};
|
||||
|
||||
this.toggle(!this.isMobile(), 0);
|
||||
this.getScrollElement().scrollTop = 0;
|
||||
@@ -162,23 +162,7 @@ export default {
|
||||
|
||||
if((box.scrollTop + box.clientHeight) / (content?.offsetHeight || 1) >= 0.8) this.getNextFeed();
|
||||
},
|
||||
onTouchStart(oEvent) {
|
||||
if(!this.isMobile() || !this.isOpen || oEvent.touches.length != 1) return;
|
||||
|
||||
const oTouch = oEvent.touches[0];
|
||||
this.swipe = {x: oTouch.clientX, y: oTouch.clientY};
|
||||
},
|
||||
onTouchEnd(oEvent) {
|
||||
const oTouch = oEvent.changedTouches[0];
|
||||
if(!oTouch || this.swipe.x === null) return;
|
||||
|
||||
const iDeltaX = oTouch.clientX - this.swipe.x;
|
||||
const iDeltaY = oTouch.clientY - this.swipe.y;
|
||||
|
||||
if(iDeltaX > 80 && Math.abs(iDeltaX) > Math.abs(iDeltaY) * 1.5) this.toggle();
|
||||
|
||||
this.swipe = {x: null, y: null};
|
||||
},
|
||||
...createSwipeToClose(1),
|
||||
setUpdateTimer(iSeconds) {
|
||||
if(typeof this.feedTimer != 'undefined') clearTimeout(this.feedTimer);
|
||||
if(iSeconds >= 0) this.feedTimer = setTimeout(this.onUpdateTimer, iSeconds * 1000);
|
||||
@@ -224,7 +208,7 @@ export default {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div id="feed" class="panel panel-right" @touchstart.passive="onTouchStart" @touchend.passive="onTouchEnd">
|
||||
<div id="feed" class="panel panel-right" @touchstart.passive="onTouchStart" @touchmove.passive="onTouchMove" @touchend.passive="onTouchEnd">
|
||||
<Simplebar id="feed-panel" class="panel-content" ref="feedSimpleBar" :aria-busy="loading">
|
||||
<div id="feed-header">
|
||||
<ProjectPost v-if="modeHisto" :options="{type: 'archived', headerless: true}" />
|
||||
|
||||
@@ -5,6 +5,7 @@ import AppIcon from '@components/AppIcon';
|
||||
import ProjectAccount from '@components/ProjectAccount';
|
||||
import logoIconUrl from '@images/icons/favicon.svg';
|
||||
import logoTitleUrl from '@images/logo_title.svg';
|
||||
import { createSwipeToClose, initialSwipeState } from '@scripts/swipeToClose';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
@@ -26,7 +27,8 @@ export default {
|
||||
isOpen: false,
|
||||
lastUpdate: {unix_time: 0, relative_time: '', formatted_time: ''},
|
||||
logoIconUrl,
|
||||
logoTitleUrl
|
||||
logoTitleUrl,
|
||||
swipe: initialSwipeState()
|
||||
};
|
||||
},
|
||||
emits: ['update:baseMap', 'update:projectCodeName', 'update:terrainEnabled', 'toggle'],
|
||||
@@ -81,13 +83,14 @@ export default {
|
||||
},
|
||||
getWidth() {
|
||||
return this.$el.getBoundingClientRect().width;
|
||||
}
|
||||
},
|
||||
...createSwipeToClose(-1)
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div id="settings" class="panel panel-left">
|
||||
<div id="settings" class="panel panel-left" @touchstart.passive="onTouchStart" @touchmove.passive="onTouchMove" @touchend.passive="onTouchEnd">
|
||||
<div id="settings-panel" class="panel-content">
|
||||
<div class="settings-header settings-box">
|
||||
<img :src="logoIconUrl" class="logo-icon clickable" :title="lang.get('project.overview')" @click="hash.items = []" />
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
/* Swipe-to-close gesture for a slide-in side panel */
|
||||
|
||||
// Initial value for the swipe data field createSwipeToClose()'s handlers expect on the component
|
||||
export function initialSwipeState() {
|
||||
return {x: null, y: null, dragging: false};
|
||||
}
|
||||
|
||||
// Builds touchstart/touchmove/touchend handlers for a panel that closes by
|
||||
// dragging it towards its own off-screen side. iDirection is:
|
||||
// +1 for a panel that opens from the right
|
||||
// -1 for one that opens from the left
|
||||
export function createSwipeToClose(iDirection) {
|
||||
return {
|
||||
onTouchStart(oEvent) {
|
||||
if(!this.isMobile() || !this.isOpen || oEvent.touches.length != 1) return;
|
||||
|
||||
const oTouch = oEvent.touches[0];
|
||||
this.swipe = {...initialSwipeState(), x: oTouch.clientX, y: oTouch.clientY};
|
||||
},
|
||||
onTouchMove(oEvent) {
|
||||
if(this.swipe.x === null || oEvent.touches.length != 1) return;
|
||||
|
||||
const oTouch = oEvent.touches[0];
|
||||
const iDeltaX = oTouch.clientX - this.swipe.x;
|
||||
const iDeltaY = oTouch.clientY - this.swipe.y;
|
||||
|
||||
if(!this.swipe.dragging) {
|
||||
//Only commit to a horizontal drag once the gesture is clearly not a vertical scroll
|
||||
if(iDeltaX * iDirection <= 10 || Math.abs(iDeltaX) <= Math.abs(iDeltaY) * 1.5) return;
|
||||
this.swipe.dragging = true;
|
||||
this.$el.classList.add('moving');
|
||||
}
|
||||
|
||||
const iDragX = iDirection * Math.min(Math.max(iDeltaX * iDirection, 0), this.getWidth());
|
||||
this.$el.style.setProperty('--drag-x', `${iDragX}px`);
|
||||
},
|
||||
onTouchEnd(oEvent) {
|
||||
const oTouch = oEvent.changedTouches[0];
|
||||
if(!oTouch || this.swipe.x === null) return;
|
||||
|
||||
const iDeltaX = oTouch.clientX - this.swipe.x;
|
||||
const iDeltaY = oTouch.clientY - this.swipe.y;
|
||||
|
||||
if(this.swipe.dragging) {
|
||||
this.$el.classList.remove('moving');
|
||||
this.$el.style.removeProperty('--drag-x');
|
||||
}
|
||||
|
||||
if(iDeltaX * iDirection > 80 && Math.abs(iDeltaX) > Math.abs(iDeltaY) * 1.5) this.toggle(false);
|
||||
|
||||
this.swipe = initialSwipeState();
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -52,13 +52,13 @@
|
||||
}
|
||||
|
||||
.panel.panel-right {
|
||||
transform: translateX(calc(var(--button-width) + var.$block-spacing * 2));
|
||||
transform: translateX(calc(var(--button-width) + var.$block-spacing * 2 + var(--drag-x, 0px)));
|
||||
}
|
||||
}
|
||||
|
||||
&.with-left-panel {
|
||||
.panel.panel-left {
|
||||
transform: translateX(0);
|
||||
transform: translateX(var(--drag-x, 0px));
|
||||
}
|
||||
|
||||
.panel.panel-right {
|
||||
|
||||
@@ -19,7 +19,7 @@ $panel-actual-width: min($panel-width, #{$panel-width-max});
|
||||
}
|
||||
|
||||
.panel.panel-left {
|
||||
transform: translateX(0);
|
||||
transform: translateX(var(--drag-x, 0px));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,6 +53,7 @@ $panel-actual-width: min($panel-width, #{$panel-width-max});
|
||||
bottom: 0;
|
||||
z-index: 1;
|
||||
user-select: none;
|
||||
touch-action: pan-y;
|
||||
width: #{$panel-width};
|
||||
max-width: calc(#{$panel-width-max});
|
||||
transition: transform var.$trans-slow;
|
||||
@@ -63,7 +64,7 @@ $panel-actual-width: min($panel-width, #{$panel-width-max});
|
||||
}
|
||||
|
||||
&.panel-left {
|
||||
transform: translateX(-100%);
|
||||
transform: translateX(calc(-100% + var(--drag-x, 0px)));
|
||||
|
||||
.panel-content {
|
||||
width: calc(100% - var.$block-spacing);
|
||||
@@ -81,7 +82,7 @@ $panel-actual-width: min($panel-width, #{$panel-width-max});
|
||||
}
|
||||
|
||||
&.panel-right {
|
||||
transform: translateX(100vw);
|
||||
transform: translateX(calc(100vw + var(--drag-x, 0px)));
|
||||
|
||||
.panel-content {
|
||||
width: 100%;
|
||||
|
||||
Reference in New Issue
Block a user