add gestures on mobile

This commit is contained in:
hippoz 2023-08-12 20:32:18 +03:00
parent 7692dd0808
commit b1a4622151
Signed by: hippoz
GPG key ID: 56C4E02A85F2FBED
4 changed files with 84 additions and 5 deletions

View file

@ -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
View 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);
}

View file

@ -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();
@ -33,7 +34,9 @@ function handleGatewaySettlement() {
if (loadingElement) {
loadingElement.parentElement.removeChild(loadingElement);
}
initGestures();
const app = new Main({
target: document.body
});

View file

@ -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,