Trying to use framework7 components

This commit is contained in:
space-nuko
2023-04-27 16:11:46 -07:00
parent 8dc8755403
commit f2fb491183
17 changed files with 577 additions and 153 deletions

View File

@@ -42,10 +42,12 @@
"@gradio/theme": "workspace:*",
"@gradio/upload": "workspace:*",
"@gradio/utils": "workspace:*",
"@litegraph-ts/tsconfig": "workspace:*",
"@litegraph-ts/core": "workspace:*",
"@litegraph-ts/nodes-basic": "workspace:*",
"@litegraph-ts/tsconfig": "workspace:*",
"events": "^3.3.0",
"framework7": "^8.0.3",
"framework7-svelte": "^8.0.3",
"pollen-css": "^4.6.2",
"radix-icons-svelte": "^1.2.1",
"svelte-preprocess": "^5.0.3",

53
pnpm-lock.yaml generated
View File

@@ -43,6 +43,12 @@ importers:
events:
specifier: ^3.3.0
version: 3.3.0
framework7:
specifier: ^8.0.3
version: 8.0.3
framework7-svelte:
specifier: ^8.0.3
version: 8.0.3
pollen-css:
specifier: ^4.6.2
version: 4.6.2
@@ -3146,6 +3152,12 @@ packages:
esutils: 2.0.3
dev: true
/dom7@4.0.6:
resolution: {integrity: sha512-emjdpPLhpNubapLFdjNL9tP06Sr+GZkrIHEXLWvOGsytACUrkbeIdjO5g77m00BrHTznnlcNqgmn7pCN192TBA==}
dependencies:
ssr-window: 4.0.2
dev: false
/ecc-jsbn@0.1.2:
resolution: {integrity: sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==}
dependencies:
@@ -3801,6 +3813,21 @@ packages:
resolution: {integrity: sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==}
dev: true
/framework7-svelte@8.0.3:
resolution: {integrity: sha512-SHirFqZBvm9E989Gyy59+pdBZdamZmqxLc/hklvorsY8llKpPuPBXbcS+fGvujvuhDq0fHHmN5tbLqYUPJ9Cyg==}
dev: false
/framework7@8.0.3:
resolution: {integrity: sha512-5DGd9J4OdTUn9hfrRaxDXYXF4hx2RAV+xy+9tzq0+R5d6DgjeE/WkqJ5ElDToww9IVAsafZcRwZodd+4a0wr/Q==}
dependencies:
dom7: 4.0.6
htm: 3.1.1
path-to-regexp: 6.2.1
skeleton-elements: 4.0.1
ssr-window: 4.0.2
swiper: 9.2.4
dev: false
/fs-extra@10.1.0:
resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==}
engines: {node: '>=12'}
@@ -3992,6 +4019,10 @@ packages:
dependencies:
function-bind: 1.1.1
/htm@3.1.1:
resolution: {integrity: sha512-983Vyg8NwUE7JkZ6NmOqpCZ+sh1bKv2iYTlUkzlWmA5JD2acKoxd4KVxbMmxX/85mtfdnDmTFoNKcg5DGAvxNQ==}
dev: false
/html-escaper@2.0.2:
resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==}
dev: true
@@ -4096,7 +4127,7 @@ packages:
'@formatjs/ecma402-abstract': 1.11.4
'@formatjs/fast-memoize': 1.2.1
'@formatjs/icu-messageformat-parser': 2.1.0
tslib: 2.3.1
tslib: 2.5.0
dev: false
/is-arrayish@0.2.1:
@@ -5143,6 +5174,10 @@ packages:
/path-parse@1.0.7:
resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
/path-to-regexp@6.2.1:
resolution: {integrity: sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==}
dev: false
/path-type@4.0.0:
resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==}
engines: {node: '>=8'}
@@ -5648,6 +5683,10 @@ packages:
resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==}
dev: true
/skeleton-elements@4.0.1:
resolution: {integrity: sha512-T7YSF/Vu/raUcM6v3HiE4VSY/OvrNflg8Dur3Zza6VVJkq4slxm4pJRpGLNhoOfblIPZLQKh1cu7ADKveyqm/Q==}
dev: false
/slash@3.0.0:
resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==}
engines: {node: '>=8'}
@@ -5716,6 +5755,10 @@ packages:
tweetnacl: 0.14.5
dev: false
/ssr-window@4.0.2:
resolution: {integrity: sha512-ISv/Ch+ig7SOtw7G2+qkwfVASzazUnvlDTwypdLoPoySv+6MqlOV10VwPSE6EWkGjhW50lUmghPmpYZXMu/+AQ==}
dev: false
/stack-utils@2.0.6:
resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==}
engines: {node: '>=10'}
@@ -6134,6 +6177,13 @@ packages:
resolution: {integrity: sha512-brIBNNB76mXFmU/Kerm4wFnkskBbluBDCjx/8TcpYRb298Yh2dztS2kQ6bhtjMcvUhd5ynClfwpz5h2gnzdQ1A==}
engines: {node: '>= 8'}
/swiper@9.2.4:
resolution: {integrity: sha512-L7y3K/iiMXNYQ94FbfcJn7jex4QPnS4+voXGupTdC+UHW4XrR40QDdm4c9hXJ+Br0Il7PP0vP1W3goM9/Ly6Sg==}
engines: {node: '>= 4.7.0'}
dependencies:
ssr-window: 4.0.2
dev: false
/sync-request@6.1.0:
resolution: {integrity: sha512-8fjNkrNlNCrVc/av+Jn+xxqfCjYaBoHqCsDz6mt030UMxJGr+GSfCV1dQt2gRtlL63+VPidwDVLr7V2OcTSdRw==}
engines: {node: '>=8.0.0'}
@@ -6315,6 +6365,7 @@ packages:
/tslib@2.3.1:
resolution: {integrity: sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==}
dev: true
/tslib@2.5.0:
resolution: {integrity: sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==}

View File

@@ -2,11 +2,13 @@
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
<meta name="viewport" content="width=device-width" />
%sveltekit.head%
</head>
<body data-sveltekit-preload-data="hover">
<div style="display: contents">%sveltekit.body%</div>
</body>
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no, viewport-fit=cover">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="theme-color" content="#2196f3">
%sveltekit.head%
</head>
<body data-sveltekit-preload-data="hover">
<div style="display: contents">%sveltekit.body%</div>
</body>
</html>

View File

@@ -3,7 +3,7 @@ type PromptRequestBody = {
prompt: any,
extra_data: any,
front: boolean,
number: number | null
number: number | undefined
}
export type QueueItemType = "queue" | "history";

View File

@@ -181,8 +181,6 @@
</div>
<style lang="scss">
@import '../../scss/shared.scss';
#container {
height: calc(100vh - 60px);
max-width: 100vw;

View File

@@ -11,7 +11,7 @@ import type TypedEmitter from "typed-emitter";
import * as basic from "@litegraph-ts/nodes-basic"
import * as nodes from "$lib/nodes/index"
import ComfyGraphCanvas from "$lib/ComfyGraphCanvas";
import type ComfyGraphNode from "$lib/ComfyGraphNode";
import type ComfyGraphNode from "$lib/nodes/ComfyGraphNode";
import type { WidgetStateStore, WidgetUIState } from "$lib/stores/widgetState";
import * as widgets from "$lib/widgets/index"
import type ComfyWidget from "$lib/widgets/ComfyWidget";
@@ -423,7 +423,7 @@ export default class ComfyApp {
this.clean();
if (!graphData) {
graphData = structuredClone(defaultGraph) as SerializedLGraph;
graphData = structuredClone(defaultGraph.workflow)
}
// Patch T2IAdapterLoader to ControlNetLoader since they are the same node now

View File

@@ -1,119 +1,401 @@
export default {
last_node_id: 9,
last_link_id: 9,
nodes: [
{
id: 7,
type: "CLIPTextEncode",
pos: [413, 389],
size: { 0: 425.27801513671875, 1: 180.6060791015625 },
flags: {},
order: 3,
mode: 0,
inputs: [{ name: "clip", type: "CLIP", link: 5 }],
outputs: [{ name: "CONDITIONING", type: "CONDITIONING", links: [6], slot_index: 0 }],
properties: {},
widgets_values: ["bad hands"],
},
{
id: 6,
type: "CLIPTextEncode",
pos: [415, 186],
size: { 0: 422.84503173828125, 1: 164.31304931640625 },
flags: {},
order: 2,
mode: 0,
inputs: [{ name: "clip", type: "CLIP", link: 3 }],
outputs: [{ name: "CONDITIONING", type: "CONDITIONING", links: [4], slot_index: 0 }],
properties: {},
widgets_values: ["masterpiece best quality girl"],
},
{
id: 5,
type: "EmptyLatentImage",
pos: [473, 609],
size: { 0: 315, 1: 106 },
flags: {},
order: 1,
mode: 0,
outputs: [{ name: "LATENT", type: "LATENT", links: [2], slot_index: 0 }],
properties: {},
widgets_values: [512, 512, 1],
},
{
id: 3,
type: "KSampler",
pos: [863, 186],
size: { 0: 315, 1: 262 },
flags: {},
order: 4,
mode: 0,
inputs: [
{ name: "model", type: "MODEL", link: 1 },
{ name: "positive", type: "CONDITIONING", link: 4 },
{ name: "negative", type: "CONDITIONING", link: 6 },
{ name: "latent_image", type: "LATENT", link: 2 },
],
outputs: [{ name: "LATENT", type: "LATENT", links: [7], slot_index: 0 }],
properties: {},
widgets_values: [8566257, 20, 8, "euler", "normal", 1],
},
{
id: 8,
type: "VAEDecode",
pos: [1209, 188],
size: { 0: 210, 1: 46 },
flags: {},
order: 5,
mode: 0,
inputs: [
{ name: "samples", type: "LATENT", link: 7 },
{ name: "vae", type: "VAE", link: 8 },
],
outputs: [{ name: "IMAGE", type: "IMAGE", links: [9], slot_index: 0 }],
properties: {},
},
{
id: 9,
type: "SaveImage",
pos: [1451, 189],
size: { 0: 210, 1: 26 },
flags: {},
order: 6,
mode: 0,
inputs: [{ name: "images", type: "IMAGE", link: 9 }],
properties: {},
},
{
id: 4,
type: "CheckpointLoaderSimple",
pos: [26, 474],
size: { 0: 315, 1: 98 },
flags: {},
order: 0,
mode: 0,
outputs: [
{ name: "MODEL", type: "MODEL", links: [1], slot_index: 0 },
{ name: "CLIP", type: "CLIP", links: [3, 5], slot_index: 1 },
{ name: "VAE", type: "VAE", links: [8], slot_index: 2 },
],
properties: {},
widgets_values: ["v1-5-pruned-emaonly.ckpt"],
},
],
links: [
[1, 4, 0, 3, 0, "MODEL"],
[2, 5, 0, 3, 3, "LATENT"],
[3, 4, 1, 6, 0, "CLIP"],
[4, 6, 0, 3, 1, "CONDITIONING"],
[5, 4, 1, 7, 0, "CLIP"],
[6, 7, 0, 3, 2, "CONDITIONING"],
[7, 3, 0, 8, 0, "LATENT"],
[8, 4, 2, 8, 1, "VAE"],
[9, 8, 0, 9, 0, "IMAGE"],
],
groups: [],
config: {},
extra: {},
version: 0.4,
};
import type SerializedAppState from "./ComfyApp"
const defaultGraph: SerializedAppState = {
createdBy: "ComfyBox",
version: 1,
workflow: {
last_node_id: 9,
last_link_id: 9,
nodes: [
{
id: 7,
type: "CLIPTextEncode",
pos: [
413,
389
],
size: [
425.27801513671875,
180.6060791015625
],
flags: {},
order: 3,
mode: 0,
inputs: [
{
name: "clip",
type: "CLIP",
link: 5
}
],
outputs: [
{
name: "CONDITIONING",
type: "CONDITIONING",
links: [
6
],
slot_index: 0
}
],
title: "CLIPTextEncode",
properties: {},
widgets_values: [
"bad hands"
]
},
{
id: 6,
type: "CLIPTextEncode",
pos: [
415,
186
],
size: [
422.84503173828125,
164.31304931640625
],
flags: {},
order: 2,
mode: 0,
inputs: [
{
name: "clip",
type: "CLIP",
link: 3
}
],
outputs: [
{
name: "CONDITIONING",
type: "CONDITIONING",
links: [
4
],
slot_index: 0
}
],
title: "CLIPTextEncode",
properties: {},
widgets_values: [
"masterpiece best quality girl"
]
},
{
id: 5,
type: "EmptyLatentImage",
pos: [
473,
609
],
size: [
315,
106
],
flags: {},
order: 0,
mode: 0,
inputs: [],
outputs: [
{
name: "LATENT",
type: "LATENT",
links: [
2
],
slot_index: 0
}
],
title: "EmptyLatentImage",
properties: {},
widgets_values: [
512,
512,
1
]
},
{
id: 3,
type: "KSampler",
pos: [
863,
186
],
size: [
315,
262
],
flags: {},
order: 4,
mode: 0,
inputs: [
{
name: "model",
type: "MODEL",
link: 1
},
{
name: "positive",
type: "CONDITIONING",
link: 4
},
{
name: "negative",
type: "CONDITIONING",
link: 6
},
{
name: "latent_image",
type: "LATENT",
link: 2
}
],
outputs: [
{
name: "LATENT",
type: "LATENT",
links: [
7
],
slot_index: 0
}
],
title: "KSampler",
properties: {},
widgets_values: [
8566257,
"randomize",
8,
8,
"euler",
"normal",
1
]
},
{
id: 8,
type: "VAEDecode",
pos: [
1209,
188
],
size: [
210,
46
],
flags: {},
order: 5,
mode: 0,
inputs: [
{
name: "samples",
type: "LATENT",
link: 7
},
{
name: "vae",
type: "VAE",
link: 8
}
],
outputs: [
{
name: "IMAGE",
type: "IMAGE",
links: [
9
],
slot_index: 0
}
],
title: "VAEDecode",
properties: {}
},
{
id: 9,
type: "SaveImage",
pos: [
1451,
189
],
size: [
210,
82
],
flags: {},
order: 6,
mode: 0,
inputs: [
{
name: "images",
type: "IMAGE",
link: 9
}
],
outputs: [],
title: "SaveImage",
properties: {},
widgets_values: [
[],
"ComfyUI"
]
},
{
id: 4,
type: "CheckpointLoaderSimple",
pos: [
26,
474
],
size: [
315,
98
],
flags: {},
order: 1,
mode: 0,
inputs: [],
outputs: [
{
name: "MODEL",
type: "MODEL",
links: [
1
],
slot_index: 0
},
{
name: "CLIP",
type: "CLIP",
links: [
3,
5
],
slot_index: 1
},
{
name: "VAE",
type: "VAE",
links: [
8
],
slot_index: 2
}
],
title: "CheckpointLoaderSimple",
properties: {},
widgets_values: [
"v1-5-pruned-emaonly.ckpt"
]
}
],
links: [
[
1,
4,
0,
3,
0,
"MODEL"
],
[
2,
5,
0,
3,
3,
"LATENT"
],
[
3,
4,
1,
6,
0,
"CLIP"
],
[
4,
6,
0,
3,
1,
"CONDITIONING"
],
[
5,
4,
1,
7,
0,
"CLIP"
],
[
6,
7,
0,
3,
2,
"CONDITIONING"
],
[
7,
3,
0,
8,
0,
"LATENT"
],
[
8,
4,
2,
8,
1,
"VAE"
],
[
9,
8,
0,
9,
0,
"IMAGE"
]
],
groups: [],
config: {},
extra: {},
version: 10
},
panes: {
panels: [
[
{
nodeId: 7
},
{
nodeId: 3
}
],
[
{
nodeId: 6
},
{
nodeId: 9
},
{
nodeId: 4
}
],
[
{
nodeId: 5
}
]
]
}
}
export default defaultGraph;

View File

@@ -101,8 +101,7 @@ function configureFinished(graph: LGraph) {
state[node.id][i].value.set(value);
}
else {
console.error("Mismatch in widgets_values!", node.id, node.type, state[node.id].map(i => get(i.value)), node.widgets_values)
break;
console.log("Skip virtual widget", node.id, node.type, state[node.id][i].widget)
}
}
}

View File

@@ -21,7 +21,7 @@
</script>
<div class="wrapper">
{#if item && option}
{#if item !== null && option !== undefined}
<label>
<BlockTitle show_label={true}>{item.widget.name}</BlockTitle>
<Select

View File

@@ -1,11 +1,15 @@
<script lang="ts">
import type { WidgetUIState, WidgetUIStateStore } from "$lib/stores/widgetState";
import { Range } from "@gradio/form";
import { Range } from "framework7-svelte";
import { BlockTitle } from "@gradio/atoms";
import { createEventDispatcher } from "svelte"
import { get } from "svelte/store";
export let item: WidgetUIState | null = null;
let itemValue: WidgetUIStateStore | null = null;
let option: number | null = null;
const dispatch = createEventDispatcher();
$: if (item) {
itemValue = item.value;
updateOption(); // don't react on option
@@ -15,29 +19,89 @@
option = get(itemValue);
}
function onRelease(e: Event) {
if (itemValue && option) {
$itemValue = option
}
function onMouseup(value: number) {
$itemValue = option
}
function onChange(e: Event) {
option = e.detail[0]
}
function onRelease(e: Event) {
option = e.detail[0]
$itemValue = option
}
const clamp = () => {
if (itemValue && option) {
onMouseup();
option = Math.min(Math.max(option, item.widget.options.min), item.widget.options.max);
}
};
</script>
<div class="wrapper">
{#if item && option}
{#if item !== null && option !== undefined}
<div class="wrap">
<div class="head">
<BlockTitle>{item.widget.name}</BlockTitle>
<input
type="number"
bind:value={option}
min={item.widget.options.min}
max={item.widget.options.max}
step={item.widget.options.step}
on:blur={clamp}
on:mouseup={onMouseup}
/>
</div>
</div>
<Range
bind:value={option}
minimum={item.widget.options.min}
maximum={item.widget.options.max}
min={item.widget.options.min}
max={item.widget.options.max}
step={item.widget.options.step}
label={item.widget.name}
show_label={true}
on:release={onRelease}
on:change
label={false}
on:rangeChanged={onRelease}
on:rangeChange={onChange}
/>
{/if}
</div>
<style>
.wrap {
display: flex;
flex-direction: column;
width: 100%;
}
.head {
display: flex;
justify-content: space-between;
}
input[type="number"] {
display: block;
position: relative;
outline: none !important;
box-shadow: var(--input-shadow);
border: var(--input-border-width) solid var(--input-border-color);
border-radius: var(--input-radius);
background: var(--input-background-fill);
padding: var(--size-2) var(--size-2);
height: var(--size-6);
color: var(--body-text-color);
font-size: var(--input-text-size);
line-height: var(--line-sm);
text-align: center;
}
input::placeholder {
color: var(--input-placeholder-color);
}
input[type="number"]:focus {
box-shadow: var(--input-shadow-focus);
border-color: var(--input-border-color-focus);
}
.wrapper {
padding: 2px;
width: 100%;

View File

@@ -7,7 +7,7 @@
</script>
<div class="wrapper">
{#if item && itemValue}
{#if item !== null && itemValue !== null}
<TextBox
bind:value={$itemValue}
label={item.widget.name}

View File

@@ -1,9 +1,22 @@
<script lang="ts">
import ComfyApp from "$lib/components/ComfyApp.svelte"
import "@litegraph-ts/core/css/litegraph.css";
import "framework7/css/bundle";
import "../scss/global.scss";
import { onMount } from 'svelte';
import { f7, f7ready, App } from 'framework7-svelte';
onMount(() => {
f7ready(() => {
// Framework7 initialized
f7.theme = "ios";
})
})
</script>
<ComfyApp/>
<App>
<ComfyApp/>
</App>
<style>
:root {

View File

@@ -1,5 +1,10 @@
import type { PageLoad } from "./$types"
import Framework7 from 'framework7/lite-bundle';
import Framework7Svelte from 'framework7-svelte';
Framework7.use(Framework7Svelte)
// `PageServerData` will contain everything from the layouts and also the
// `data` from the `+page.server.ts` file.
type OutputProps = {}

8
src/scss/global.scss Normal file
View File

@@ -0,0 +1,8 @@
button {
width: auto !important;
}
:root {
--f7-block-margin-vertical: 10px;
--f7-block-padding-horizontal: 0px;
}

View File

View File

@@ -14,7 +14,7 @@ const config = {
compilerOptions: {
debug: true,
}
}
},
})
]
};

View File

@@ -8,10 +8,10 @@ export default defineConfig({
plugins: [
// tsconfigPaths({ loose: true }),
sveltekit(),
FullReload(["src/**/*.{js,ts,svelte}"])
// FullReload(["src/**/*.{js,ts,svelte}"])
],
build: {
sourcemap: true,
sourcemap: true,
},
server: {
port: 3000,