add gestures on mobile
This commit is contained in:
parent
7692dd0808
commit
b1a4622151
4 changed files with 84 additions and 5 deletions
|
@ -1,6 +1,6 @@
|
|||
<script>
|
||||
import { afterUpdate, beforeUpdate } from "svelte";
|
||||
import { showSidebar, selectedChannel, smallViewport, showChannelView, theme, showPresenceSidebar } from "../stores";
|
||||
import { showSidebar, selectedChannel, smallViewport, showChannelView, theme, showPresenceSidebar, swipeRightEvent, swipeLeftEvent } from "../stores";
|
||||
import { timeline } from "../timeline";
|
||||
import ChannelView from "./ChannelView.svelte";
|
||||
import OverlayProvider from "./overlays/OverlayProvider.svelte";
|
||||
|
@ -14,17 +14,41 @@
|
|||
afterUpdate(() => {
|
||||
timeline.addCheckpoint("Main component update end");
|
||||
});
|
||||
|
||||
$: sidebarEnabled = !($smallViewport && $showPresenceSidebar) && $showSidebar || $selectedChannel.id === -1;
|
||||
$: channelViewEnabled = !($smallViewport && $showSidebar) && !($smallViewport && $showPresenceSidebar) && $showChannelView && $selectedChannel.id !== -1;
|
||||
$: presenceSidebarEnabled = $showPresenceSidebar;
|
||||
|
||||
swipeRightEvent.on(() => {
|
||||
if (smallViewport.value) {
|
||||
if (presenceSidebarEnabled) {
|
||||
showPresenceSidebar.set(false);
|
||||
} else if (channelViewEnabled) {
|
||||
showSidebar.set(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
swipeLeftEvent.on(() => {
|
||||
if (smallViewport.value) {
|
||||
if (sidebarEnabled) {
|
||||
showSidebar.set(false);
|
||||
} else if (channelViewEnabled) {
|
||||
showPresenceSidebar.set(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
<OverlayProvider />
|
||||
|
||||
{#if !($smallViewport && $showPresenceSidebar) && $showSidebar || $selectedChannel.id === -1}
|
||||
{#if sidebarEnabled}
|
||||
<Sidebar />
|
||||
{/if}
|
||||
{#if !($smallViewport && $showSidebar) && !($smallViewport && $showPresenceSidebar) && $showChannelView && $selectedChannel.id !== -1}
|
||||
{#if channelViewEnabled}
|
||||
<ChannelView channel={$selectedChannel} />
|
||||
{/if}
|
||||
{#if $showPresenceSidebar}
|
||||
{#if presenceSidebarEnabled}
|
||||
<PresenceSidebar />
|
||||
{/if}
|
||||
|
|
49
frontend/src/gestures.js
Normal file
49
frontend/src/gestures.js
Normal file
|
@ -0,0 +1,49 @@
|
|||
import { swipeLeftEvent, swipeRightEvent } from "./stores";
|
||||
|
||||
const events = [];
|
||||
|
||||
const SWIPE_RIGHT_THRESHOLD = 35;
|
||||
const SWIPE_LEFT_THRESHOLD = -35;
|
||||
|
||||
function pointerdownHandler(ev) {
|
||||
events.push({
|
||||
pointerId: ev.pointerId,
|
||||
clientX: ev.clientX,
|
||||
clientY: ev.clientY,
|
||||
processed: false
|
||||
});
|
||||
}
|
||||
|
||||
function pointerupHandler(ev) {
|
||||
const index = events.findIndex((e) => e.pointerId === ev.pointerId);
|
||||
if (index === -1) return;
|
||||
events.splice(index, 1);
|
||||
}
|
||||
|
||||
function pointermoveHandler(ev) {
|
||||
const index = events.findIndex((e) => e.pointerId === ev.pointerId);
|
||||
if (index === -1) return;
|
||||
|
||||
const existingEvent = events[index];
|
||||
|
||||
if (existingEvent.processed) return;
|
||||
|
||||
const delta = ev.clientX - existingEvent.clientX;
|
||||
if (delta >= SWIPE_RIGHT_THRESHOLD) {
|
||||
existingEvent.processed = true;
|
||||
swipeRightEvent.emit(true);
|
||||
} else if (delta <= SWIPE_LEFT_THRESHOLD) {
|
||||
existingEvent.processed = true;
|
||||
swipeLeftEvent.emit(true);
|
||||
}
|
||||
}
|
||||
|
||||
export function initGestures() {
|
||||
document.body.addEventListener("pointerdown", pointerdownHandler);
|
||||
document.body.addEventListener("pointerup", pointerupHandler);
|
||||
document.body.addEventListener("pointercancel", pointerupHandler);
|
||||
document.body.addEventListener("pointerleave", pointerupHandler);
|
||||
document.body.addEventListener("pointerout", pointerupHandler);
|
||||
|
||||
document.body.addEventListener("pointermove", pointermoveHandler);
|
||||
}
|
|
@ -10,6 +10,7 @@ import "@fontsource-variable/material-symbols-outlined/opsz.css";
|
|||
import "@fontsource-variable/open-sans";
|
||||
import "./styles/global.css";
|
||||
import { timeline } from './timeline';
|
||||
import { initGestures } from './gestures';
|
||||
|
||||
timeline.start();
|
||||
|
||||
|
@ -34,6 +35,8 @@ function handleGatewaySettlement() {
|
|||
loadingElement.parentElement.removeChild(loadingElement);
|
||||
}
|
||||
|
||||
initGestures();
|
||||
|
||||
const app = new Main({
|
||||
target: document.body
|
||||
});
|
||||
|
|
|
@ -869,6 +869,9 @@ export const totalUnreadsStore = new Store(0, "TotalUnreadsStore");
|
|||
export const statusBarStore = new Store(null, "statusBarStore");
|
||||
|
||||
export const setMessageInputEvent = new Store(null, "event:setMessageInput");
|
||||
export const swipeRightEvent = new Store(null, "event:swipeRight");
|
||||
export const swipeLeftEvent = new Store(null, "event:swipeLeft");
|
||||
|
||||
|
||||
export const allStores = {
|
||||
selectedChannel,
|
||||
|
|
Loading…
Reference in a new issue