Proper mobile redirection

This commit is contained in:
space-nuko
2023-05-31 11:41:48 -05:00
parent dbef7d0d70
commit c537cb71bf
10 changed files with 80 additions and 24 deletions

View File

@@ -7,17 +7,6 @@
<meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-capable" content="yes">
<meta name="theme-color" content="#2196f3"> <meta name="theme-color" content="#2196f3">
</head> </head>
<script>
if(!window.location.search.substring(1) == "desktop=true") {
if (navigator.userAgent.match(/iPhone/i)
|| navigator.userAgent.match(/iPad/i)
|| navigator.userAgent.match(/Android/i)
|| navigator.userAgent.match(/Blackberry/i)
|| navigator.userAgent.match(/WebOs/i)) {
window.location.href = "/mobile/"
}
}
</script>
<body> <body>
<div id="app-root"/> <div id="app-root"/>
<script type="module" src='/src/main-desktop.ts'></script> <script type="module" src='/src/main-desktop.ts'></script>

View File

@@ -4,12 +4,12 @@
import "@litegraph-ts/core/css/litegraph.css"; import "@litegraph-ts/core/css/litegraph.css";
import "./scss/global.scss"; import "./scss/global.scss";
import { onMount } from 'svelte';
export let app: ComfyAppState; export let app: ComfyAppState;
export let isMobile: boolean
</script> </script>
<ComfyApp {app}/> {#if isMobile}
<div>Redirecting...</div>
<style> {:else}
</style> <ComfyApp {app}/>
{/if}

View File

@@ -333,7 +333,8 @@ export default class ComfyGraphCanvas extends LGraphCanvas {
/** /**
* Handle keypress * Handle keypress
* *
* Ctrl + M mute/unmute selected nodes * Ctrl + M mute/unmute selected nodes
* Ctrl + Space open node searchbox
*/ */
override processKey(e: KeyboardEvent): boolean | undefined { override processKey(e: KeyboardEvent): boolean | undefined {
const res = super.processKey(e); const res = super.processKey(e);
@@ -353,7 +354,7 @@ export default class ComfyGraphCanvas extends LGraphCanvas {
} }
if (e.type == "keydown") { if (e.type == "keydown") {
// Ctrl + M mute/unmute // Ctrl + M - mute/unmute
if (e.keyCode == 77 && e.ctrlKey) { if (e.keyCode == 77 && e.ctrlKey) {
if (this.selected_nodes) { if (this.selected_nodes) {
for (var i in this.selected_nodes) { for (var i in this.selected_nodes) {
@@ -366,6 +367,21 @@ export default class ComfyGraphCanvas extends LGraphCanvas {
} }
block_default = true; block_default = true;
} }
// Ctrl + Space - open node searchbox
else if (e.keyCode == 32 && e.ctrlKey) {
const event = new MouseEvent("click");
const searchBox = this.showSearchBox(event);
const rect = this.canvas.getBoundingClientRect();
const sbRect = searchBox.getBoundingClientRect();
const clientX = rect.left + rect.width / 2 - sbRect.width / 2;
const clientY = rect.top + rect.height / 2 - sbRect.height / 2
searchBox.style.left = `${clientX}px`;
searchBox.style.top = `${clientY}px`;
// TODO better API
event.initMouseEvent("click", true, true, window, 1, clientX, clientY, clientX, clientY, false, false, false, false, 0, null);
this.adjustMouseEvent(event);
block_default = true;
}
} }
this.graph.change(); this.graph.change();

View File

@@ -125,8 +125,17 @@ export default class ComfyAPI {
}, 1000); }, 1000);
} }
private getHostname(): string {
let hostname = this.hostname || location.hostname;
if (hostname === "localhost") {
// For dev use, assume same hostname as connected server
hostname = location.hostname;
}
return hostname;
}
private getBackendUrl(): string { private getBackendUrl(): string {
const hostname = this.hostname || location.hostname; const hostname = this.getHostname()
const port = this.port || location.port; const port = this.port || location.port;
return `${window.location.protocol}//${hostname}:${port}` return `${window.location.protocol}//${hostname}:${port}`
} }
@@ -146,7 +155,7 @@ export default class ComfyAPI {
existingSession = "?clientId=" + existingSession; existingSession = "?clientId=" + existingSession;
} }
const hostname = this.hostname || location.hostname; const hostname = this.getHostname()
const port = this.port || location.port; const port = this.port || location.port;
this.socket = new WebSocket( this.socket = new WebSocket(

View File

@@ -211,7 +211,13 @@ export default class ComfyApp {
this.lCanvas.allow_interaction = uiUnlocked; this.lCanvas.allow_interaction = uiUnlocked;
// await this.#invokeExtensionsAsync("init"); // await this.#invokeExtensionsAsync("init");
const defs = await this.api.getNodeDefs(); let defs;
try {
defs = await this.api.getNodeDefs();
}
catch (error) {
throw new Error(`Could not reach ComfyUI at ${this.api.getBackendUrl()}`);
}
await this.registerNodes(defs); await this.registerNodes(defs);
// Load previous workflow // Load previous workflow

View File

@@ -24,7 +24,12 @@ let changedOptions: Partial<Record<keyof ConfigState, [any, any]>> = {}
function getBackendURL(): string { function getBackendURL(): string {
const state = get(store); const state = get(store);
return `${window.location.protocol}//${state.comfyUIHostname}:${state.comfyUIPort}` let hostname = state.comfyUIHostname
if (hostname === "localhost") {
// For dev use, assume same hostname as connected server
hostname = location.hostname;
}
return `${window.location.protocol}//${hostname}:${state.comfyUIPort}`
} }
function canShowNotificationText(): boolean { function canShowNotificationText(): boolean {

View File

@@ -618,6 +618,9 @@ export async function readFileToText(file: File): Promise<string> {
reader.onload = async () => { reader.onload = async () => {
resolve(reader.result as string); resolve(reader.result as string);
}; };
reader.onerror = async () => {
reject(reader.error);
}
reader.readAsText(file); reader.readAsText(file);
}) })
} }
@@ -709,3 +712,12 @@ export function canvasToBlob(canvas: HTMLCanvasElement): Promise<Blob> {
canvas.toBlob(resolve); canvas.toBlob(resolve);
}); });
} }
export type SafetensorsMetadata = Record<string, string>
export async function getSafetensorsMetadata(folder: string, filename: string): Promise<SafetensorsMetadata> {
const url = configState.getBackendURL();
const params = new URLSearchParams({ filename })
return fetch(new Request(url + `/view_metadata/${folder}?` + params)).then(r => r.json())
}

View File

@@ -8,6 +8,7 @@
import { type WidgetLayout } from "$lib/stores/layoutStates"; import { type WidgetLayout } from "$lib/stores/layoutStates";
import { get, writable, type Writable } from "svelte/store"; import { get, writable, type Writable } from "svelte/store";
import { isDisabled } from "./utils" import { isDisabled } from "./utils"
import { getSafetensorsMetadata } from '$lib/utils';
export let widget: WidgetLayout | null = null; export let widget: WidgetLayout | null = null;
export let isMobile: boolean = false; export let isMobile: boolean = false;
let node: ComfyComboNode | null = null; let node: ComfyComboNode | null = null;

View File

@@ -1,3 +1,20 @@
const params = new URLSearchParams(window.location.search)
const MOBILE_USER_AGENTS = ["iPhone", "iPad", "Android", "BlackBerry", "WebOs"].map(a => new RegExp(a, "i"))
function isMobileBrowser(userAgent: string): boolean {
return MOBILE_USER_AGENTS.some(a => userAgent.match(a))
}
const isMobile = isMobileBrowser(navigator.userAgent);
if (params.get("desktop") !== "true") {
if (isMobile) {
window.location.href = "/mobile/"
}
}
// Run node registration before anthing else, in the proper order // Run node registration before anthing else, in the proper order
import "$lib/nodeImports"; import "$lib/nodeImports";
@@ -12,7 +29,7 @@ const comfyApp = new ComfyApp();
const app = new App({ const app = new App({
target: document.getElementById("app-root"), target: document.getElementById("app-root"),
props: { app: comfyApp } props: { app: comfyApp, isMobile }
}) })
export default app; export default app;

View File

@@ -55,6 +55,7 @@ export default defineConfig({
}, },
}, },
build: { build: {
minify: isProduction,
sourcemap: true, sourcemap: true,
rollupOptions: { rollupOptions: {
input: { input: {