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>
|
<script>
|
||||||
import { afterUpdate, beforeUpdate } from "svelte";
|
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 { timeline } from "../timeline";
|
||||||
import ChannelView from "./ChannelView.svelte";
|
import ChannelView from "./ChannelView.svelte";
|
||||||
import OverlayProvider from "./overlays/OverlayProvider.svelte";
|
import OverlayProvider from "./overlays/OverlayProvider.svelte";
|
||||||
|
@ -14,17 +14,41 @@
|
||||||
afterUpdate(() => {
|
afterUpdate(() => {
|
||||||
timeline.addCheckpoint("Main component update end");
|
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>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
<OverlayProvider />
|
<OverlayProvider />
|
||||||
|
|
||||||
{#if !($smallViewport && $showPresenceSidebar) && $showSidebar || $selectedChannel.id === -1}
|
{#if sidebarEnabled}
|
||||||
<Sidebar />
|
<Sidebar />
|
||||||
{/if}
|
{/if}
|
||||||
{#if !($smallViewport && $showSidebar) && !($smallViewport && $showPresenceSidebar) && $showChannelView && $selectedChannel.id !== -1}
|
{#if channelViewEnabled}
|
||||||
<ChannelView channel={$selectedChannel} />
|
<ChannelView channel={$selectedChannel} />
|
||||||
{/if}
|
{/if}
|
||||||
{#if $showPresenceSidebar}
|
{#if presenceSidebarEnabled}
|
||||||
<PresenceSidebar />
|
<PresenceSidebar />
|
||||||
{/if}
|
{/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 "@fontsource-variable/open-sans";
|
||||||
import "./styles/global.css";
|
import "./styles/global.css";
|
||||||
import { timeline } from './timeline';
|
import { timeline } from './timeline';
|
||||||
|
import { initGestures } from './gestures';
|
||||||
|
|
||||||
timeline.start();
|
timeline.start();
|
||||||
|
|
||||||
|
@ -34,6 +35,8 @@ function handleGatewaySettlement() {
|
||||||
loadingElement.parentElement.removeChild(loadingElement);
|
loadingElement.parentElement.removeChild(loadingElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
initGestures();
|
||||||
|
|
||||||
const app = new Main({
|
const app = new Main({
|
||||||
target: document.body
|
target: document.body
|
||||||
});
|
});
|
||||||
|
|
|
@ -869,6 +869,9 @@ export const totalUnreadsStore = new Store(0, "TotalUnreadsStore");
|
||||||
export const statusBarStore = new Store(null, "statusBarStore");
|
export const statusBarStore = new Store(null, "statusBarStore");
|
||||||
|
|
||||||
export const setMessageInputEvent = new Store(null, "event:setMessageInput");
|
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 = {
|
export const allStores = {
|
||||||
selectedChannel,
|
selectedChannel,
|
||||||
|
|
Loading…
Reference in a new issue