From 8ec2301093e57d23167d9b9e027aa7a6f73efd0f Mon Sep 17 00:00:00 2001 From: space-nuko <24979496+space-nuko@users.noreply.github.com> Date: Sun, 7 May 2023 16:56:16 -0500 Subject: [PATCH] Mobile haptic feedback --- src/AppMobile.svelte | 30 ++++++------ src/lib/components/ComfyApp.svelte | 5 -- src/lib/components/ComfyApp.ts | 2 +- src/lib/widgets/ButtonWidget.svelte | 1 + src/lib/widgets/CheckboxWidget.svelte | 6 ++- src/lib/widgets/ComboWidget.svelte | 6 +++ src/lib/widgets/GalleryWidget.svelte | 70 ++++++++++++++++++++++++++- src/lib/widgets/RangeWidget.svelte | 16 +++++- src/mobile/GenToolbar.svelte | 1 + 9 files changed, 112 insertions(+), 25 deletions(-) diff --git a/src/AppMobile.svelte b/src/AppMobile.svelte index d507691..2ea05ae 100644 --- a/src/AppMobile.svelte +++ b/src/AppMobile.svelte @@ -107,19 +107,19 @@ {#if app} - - - - - - + + + + + + {/if} diff --git a/src/lib/components/ComfyApp.svelte b/src/lib/components/ComfyApp.svelte index 698c4d9..b41deaa 100644 --- a/src/lib/components/ComfyApp.svelte +++ b/src/lib/components/ComfyApp.svelte @@ -25,7 +25,6 @@ import notify from "$lib/notify"; export let app: ComfyApp = undefined; - let imageViewer: ImageViewer; let queue: ComfyQueue = undefined; let mainElem: HTMLDivElement; let uiPane: ComfyUIPane = undefined; @@ -175,10 +174,6 @@ }) } - $: if (app.rootEl && !imageViewer) { - imageViewer = new ImageViewer(app.rootEl); - } - $: if (containerElem) { const canvas = containerElem.querySelector("#graph-canvas") if (canvas) { diff --git a/src/lib/components/ComfyApp.ts b/src/lib/components/ComfyApp.ts index 37aacea..45a55b1 100644 --- a/src/lib/components/ComfyApp.ts +++ b/src/lib/components/ComfyApp.ts @@ -98,7 +98,7 @@ export default class ComfyApp { return; } - this.rootEl = document.getElementById("main") as HTMLDivElement; + this.rootEl = document.getElementById("app") as HTMLDivElement; this.canvasEl = document.getElementById("graph-canvas") as HTMLCanvasElement; this.lGraph = new ComfyGraph(); this.lCanvas = new ComfyGraphCanvas(this, this.canvasEl); diff --git a/src/lib/widgets/ButtonWidget.svelte b/src/lib/widgets/ButtonWidget.svelte index 4d7d0f2..b07ccaf 100644 --- a/src/lib/widgets/ButtonWidget.svelte +++ b/src/lib/widgets/ButtonWidget.svelte @@ -22,6 +22,7 @@ function onClick(e: MouseEvent) { node.onClick(); + navigator.vibrate(20) } const style = { diff --git a/src/lib/widgets/CheckboxWidget.svelte b/src/lib/widgets/CheckboxWidget.svelte index d3619cb..c465f47 100644 --- a/src/lib/widgets/CheckboxWidget.svelte +++ b/src/lib/widgets/CheckboxWidget.svelte @@ -20,6 +20,10 @@ attrsChanged = widget.attrsChanged; } }; + + function onSelect() { + navigator.vibrate(20) + }
@@ -27,7 +31,7 @@ {#key $attrsChanged} {#if node !== null} - + {/if} {/key} diff --git a/src/lib/widgets/ComboWidget.svelte b/src/lib/widgets/ComboWidget.svelte index 940525c..f70b877 100644 --- a/src/lib/widgets/ComboWidget.svelte +++ b/src/lib/widgets/ComboWidget.svelte @@ -55,9 +55,14 @@ return links[0].data } + function onFocus() { + navigator.vibrate(20) + } + function onSelect() { if (input) input.blur(); + navigator.vibrate(20) } let lastPropsChanged: number = 0; @@ -86,6 +91,7 @@ inputAttributes={{ autocomplete: 'off' }} bind:input on:change + on:focus={onFocus} on:select={onSelect} on:filter on:blur diff --git a/src/lib/widgets/GalleryWidget.svelte b/src/lib/widgets/GalleryWidget.svelte index 384cf4f..d5f907c 100644 --- a/src/lib/widgets/GalleryWidget.svelte +++ b/src/lib/widgets/GalleryWidget.svelte @@ -9,6 +9,7 @@ import type { FileData as GradioFileData } from "@gradio/upload"; import type { SelectData as GradioSelectData } from "@gradio/utils"; import { clamp } from "$lib/utils"; + import { f7 } from "framework7-svelte"; export let widget: WidgetLayout | null = null; export let isMobile: boolean = false; @@ -39,14 +40,79 @@ } let element: HTMLDivElement; + let mobileLightbox = null; + + function showMobileLightbox(event: Event) { + if (!f7) + return + + if (mobileLightbox) { + mobileLightbox.destroy(); + mobileLightbox = null; + } + + const source = (event.target || event.srcElement) as HTMLImageElement; + const galleryElem = source.closest("div.block") + console.debug("[ImageViewer] showModal", event, source, galleryElem); + if (!galleryElem || ImageViewer.all_gallery_buttons(galleryElem).length === 0) { + console.error("No buttons found on gallery element!", galleryElem) + return; + } + + const allGalleryButtons = ImageViewer.all_gallery_buttons(galleryElem); + const selectedSource = source.src + + const images = allGalleryButtons.map(button => { + return { + url: (button.children[0] as HTMLImageElement).src, + caption: "Image" + } + }) + + + mobileLightbox = f7.photoBrowser.create({ + photos: images, + thumbs: images.map(i => i.url), + type: 'popup', + }); + mobileLightbox.open() + + event.stopPropagation() + } + + function setupImageForMobileLightbox(e: HTMLImageElement) { + if (e.dataset.modded === "true") + return; + + e.dataset.modded = "true"; + e.style.cursor = "pointer"; + e.style.userSelect = "none"; + + var isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1 + + // For Firefox, listening on click first switched to next image then shows the lightbox. + // If you know how to fix this without switching to mousedown event, please. + // For other browsers the event is click to make it possiblr to drag picture. + var event = isFirefox ? 'mousedown' : 'click' + + e.addEventListener(event, (evt) => { + evt.preventDefault() + showMobileLightbox(evt) + }, true); + } + function onSelect(e: CustomEvent) { // Setup lightbox // Wait for gradio gallery to show the large preview image, if no timeout then // the event might fire too early + + const callback = isMobile ? setupImageForMobileLightbox + : ImageViewer.instance.setupImageForLightbox.bind(ImageViewer.instance) + setTimeout(() => { const images = element.querySelectorAll('div.block div > img') if (images != null) { - images.forEach(ImageViewer.instance.setupImageForLightbox.bind(ImageViewer.instance)); + images.forEach(callback); } ImageViewer.instance.updateOnBackgroundChange(); }, 200) @@ -54,8 +120,8 @@ // Update index node.setProperty("index", e.detail.index as number) } - +