Add swipe controls to move back and forth in albums

This commit is contained in:
2024-04-11 18:40:26 +02:00
parent 089fa3ad84
commit c5432c7541
9 changed files with 169 additions and 40 deletions

View File

@@ -59,7 +59,7 @@ export const set_file = async file => {
{:else if viewer_type === "rate_limit"}
<RateLimit bind:this={viewer} on:download></RateLimit>
{:else if viewer_type === "image"}
<Image bind:this={viewer} on:loading></Image>
<Image bind:this={viewer} is_list={is_list} on:prev on:next on:loading></Image>
{:else if viewer_type === "video"}
<Video bind:this={viewer} is_list={is_list} on:loading on:download on:prev on:next on:reload></Video>
{:else if viewer_type === "audio"}

View File

@@ -1,20 +1,36 @@
<script>
import { createEventDispatcher } from "svelte"
import { swipe_nav } from "./SwipeNavigate.svelte";
let dispatch = createEventDispatcher()
export const set_file = f => file = f
export const set_file = f => {
file = f
dispatch("loading", true)
}
let file = {
id: "",
name: "",
mime_type: "",
get_href: "",
}
export let is_list = false
let container
let zoom = false
let x, y = 0
let dragging = false
// For some reason the dblclick event is firing twice during testing.. So here's
// an event debouncer
let last_dblclick = 0
const double_click = e => {
let now = Date.now()
if (now - last_dblclick > 500) {
zoom = !zoom
}
last_dblclick = now
}
const mousedown = (e) => {
if (!dragging && e.which === 1 && zoom) {
x = e.pageX
@@ -48,20 +64,35 @@ const mouseup = (e) => {
return false
}
}
let container_style = ""
const on_load = () => {
dispatch("loading", false)
container_style = ""
}
</script>
<svelte:window on:mousemove={mousemove} on:mouseup={mouseup} />
<div bind:this={container} class="container" class:zoom>
<div
bind:this={container}
class="container"
class:zoom
use:swipe_nav={!zoom && is_list}
on:style={e => container_style = e.detail}
on:prev
on:next
style={container_style}
>
<!-- svelte-ignore a11y-no-noninteractive-element-interactions -->
<img
on:loadstart={() => {dispatch("loading", true)}}
on:load={() => {dispatch("loading", false)}}
on:error={() => {dispatch("loading", false)}}
on:dblclick={() => {zoom = !zoom}}
on:doubletap={() => {zoom = !zoom}}
on:load={on_load}
on:error={on_load}
on:dblclick={double_click}
on:doubletap={double_click}
on:mousedown={mousedown}
class="image" class:zoom
class="image"
class:zoom
src={file.get_href}
alt={file.name} />
</div>

View File

@@ -0,0 +1,76 @@
<script context="module">
export const swipe_nav = (node, swipe_enabled) => {
let start_x = 0
let start_y = 0
let render_offset = 0
let enabled = swipe_enabled
const touchstart = e => {
start_x = e.touches[0].clientX
start_y = e.touches[0].clientY
render_offset = 0
}
const touchmove = e => {
if (!enabled) {
return
}
let offset_x = e.touches[0].clientX - start_x
let abs_x = Math.abs(offset_x)
let abs_y = Math.abs(e.touches[0].clientY - start_y)
let neg = offset_x < 0 ? -1 : 1
if (abs_x > 100 && abs_y < abs_x/3) {
set_offset((abs_x-100)*neg, false)
} else {
set_offset(0, true)
}
}
const touchend = e => {
if (!enabled) {
return
}
if (render_offset > 100) {
set_offset(1000, true)
node.dispatchEvent(new CustomEvent("prev"))
} else if (render_offset < -100) {
set_offset(-1000, true)
node.dispatchEvent(new CustomEvent("next"))
} else {
set_offset(0, true)
}
}
const set_offset = (off, animate) => {
render_offset = off
let detail = "transform: translateX("+off+"px);"
if (animate) {
detail += "transition: transform 500ms;"
}
node.dispatchEvent(new CustomEvent("style", {detail: detail}))
}
node.addEventListener("touchstart", touchstart)
node.addEventListener("touchmove", touchmove)
node.addEventListener("touchend", touchend)
return {
update(swipe_enabled) {
enabled = swipe_enabled
if (!enabled) {
render_offset = 0
}
},
destroy() {
node.removeEventListener("touchstart", touchstart)
node.removeEventListener("touchmove", touchmove)
node.removeEventListener("touchend", touchend)
}
}
}
</script>