Image size for history list view
This commit is contained in:
@@ -48,6 +48,8 @@
|
|||||||
|
|
||||||
let mode: QueueItemType = "queue";
|
let mode: QueueItemType = "queue";
|
||||||
let displayMode: DisplayModeType = "list";
|
let displayMode: DisplayModeType = "list";
|
||||||
|
let imageSize: number = 40;
|
||||||
|
let gridColumns: number = 3;
|
||||||
let changed = true;
|
let changed = true;
|
||||||
|
|
||||||
function switchMode(newMode: QueueItemType) {
|
function switchMode(newMode: QueueItemType) {
|
||||||
@@ -256,9 +258,9 @@
|
|||||||
<div class="queue-entries" bind:this={queueList}>
|
<div class="queue-entries" bind:this={queueList}>
|
||||||
{#if _entries.length > 0}
|
{#if _entries.length > 0}
|
||||||
{#if mode === "history" && displayMode === "grid"}
|
{#if mode === "history" && displayMode === "grid"}
|
||||||
<ComfyQueueGridDisplay entries={_entries} {showPrompt} {clearQueue} {mode} />
|
<ComfyQueueGridDisplay entries={_entries} {showPrompt} {clearQueue} {mode} bind:gridColumns />
|
||||||
{:else}
|
{:else}
|
||||||
<ComfyQueueListDisplay entries={_entries} {showPrompt} {clearQueue} {mode} />
|
<ComfyQueueListDisplay entries={_entries} {showPrompt} {clearQueue} {mode} bind:imageSize />
|
||||||
{/if}
|
{/if}
|
||||||
{:else}
|
{:else}
|
||||||
<div class="queue-empty">
|
<div class="queue-empty">
|
||||||
|
|||||||
@@ -8,10 +8,10 @@
|
|||||||
export let showPrompt: (entry: QueueUIEntry) => void;
|
export let showPrompt: (entry: QueueUIEntry) => void;
|
||||||
export let clearQueue: () => Promise<void>;
|
export let clearQueue: () => Promise<void>;
|
||||||
export let mode: QueueItemType = "queue";
|
export let mode: QueueItemType = "queue";
|
||||||
|
export let gridColumns: number = 3;
|
||||||
|
|
||||||
let allEntries: [QueueUIEntry, string][] = []
|
let allEntries: [QueueUIEntry, string][] = []
|
||||||
let allImages: string[] = []
|
let allImages: string[] = []
|
||||||
let gridColumns: number = 3;
|
|
||||||
|
|
||||||
$: buildImageList(entries);
|
$: buildImageList(entries);
|
||||||
|
|
||||||
@@ -36,7 +36,7 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="grid-wrapper {mode}-mode">
|
<div class="grid-wrapper {mode}-mode">
|
||||||
<div class="grid-columns">
|
<div class="grid-controls">
|
||||||
<div>
|
<div>
|
||||||
<input type="range" bind:value={gridColumns} min={1} max={8} step={1} />
|
<input type="range" bind:value={gridColumns} min={1} max={8} step={1} />
|
||||||
<div class="button-wrapper">
|
<div class="button-wrapper">
|
||||||
@@ -64,18 +64,19 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
$grid-columns-control-height: 3rem;
|
$grid-controls-height: 3rem;
|
||||||
|
$grid-controls-margin: 0.25rem;
|
||||||
|
|
||||||
.grid-wrapper {
|
.grid-wrapper {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.grid-columns {
|
.grid-controls {
|
||||||
height: $grid-columns-control-height;
|
height: $grid-controls-height;
|
||||||
position: relative;
|
position: relative;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
margin: 0.25rem 1rem;
|
margin: $grid-controls-margin 1rem;
|
||||||
|
|
||||||
> div {
|
> div {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@@ -89,7 +90,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.button-wrapper {
|
.button-wrapper {
|
||||||
padding: 0.25rem;
|
padding: $grid-controls-margin;
|
||||||
.clear-queue-button {
|
.clear-queue-button {
|
||||||
@include square-button;
|
@include square-button;
|
||||||
|
|
||||||
@@ -102,7 +103,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.grid-entries {
|
.grid-entries {
|
||||||
height: calc(100% - #{$grid-columns-control-height});
|
height: calc(100% - #{$grid-controls-height} - #{$grid-controls-margin} * 2);
|
||||||
padding: 0 var(--spacing-lg) var(--spacing-lg) var(--spacing-lg);
|
padding: 0 var(--spacing-lg) var(--spacing-lg) var(--spacing-lg);
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,23 +2,40 @@
|
|||||||
import type { QueueItemType } from "$lib/api";
|
import type { QueueItemType } from "$lib/api";
|
||||||
import { showLightbox, truncateString } from "$lib/utils";
|
import { showLightbox, truncateString } from "$lib/utils";
|
||||||
import type { QueueUIEntry } from "./ComfyQueue.svelte";
|
import type { QueueUIEntry } from "./ComfyQueue.svelte";
|
||||||
|
import queueState from "$lib/stores/queueState";
|
||||||
|
|
||||||
export let entries: QueueUIEntry[] = [];
|
export let entries: QueueUIEntry[] = [];
|
||||||
export let showPrompt: (entry: QueueUIEntry) => void;
|
export let showPrompt: (entry: QueueUIEntry) => void;
|
||||||
export let clearQueue: () => void;
|
export let clearQueue: () => void;
|
||||||
export let mode: QueueItemType = "queue";
|
export let mode: QueueItemType = "queue";
|
||||||
|
export let imageSize: number = 40;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="queue-wrapper {mode}-mode">
|
<div class="list-wrapper {mode}-mode">
|
||||||
|
{#if mode === "history"}
|
||||||
|
<div class="list-controls">
|
||||||
|
<div>
|
||||||
|
<input type="range" bind:value={imageSize} min={10} max={100} step={0.1} />
|
||||||
|
<div class="button-wrapper">
|
||||||
|
<button class="clear-queue-button secondary"
|
||||||
|
on:click={clearQueue}
|
||||||
|
disabled={$queueState.isInterrupting}>
|
||||||
|
🗑️
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
<div class="list-entries {mode}-mode" style:--imageSize={imageSize}>
|
||||||
{#each entries as entry}
|
{#each entries as entry}
|
||||||
<div class="queue-entry {entry.status}" on:click={(e) => showPrompt(entry, e)}>
|
<div class="list-entry {entry.status}" on:click={(e) => showPrompt(entry, e)}>
|
||||||
{#if entry.images.length > 0}
|
{#if entry.images.length > 0}
|
||||||
<div class="queue-entry-images"
|
<div class="list-entry-images"
|
||||||
style="--cols: {Math.ceil(Math.sqrt(Math.min(entry.images.length, 4)))}" >
|
style="--cols: {Math.ceil(Math.sqrt(Math.min(entry.images.length, 4)))}" >
|
||||||
{#each entry.images.slice(0, 4) as image, i}
|
{#each entry.images.slice(0, 4) as image, i}
|
||||||
<div>
|
<div>
|
||||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||||
<img class="queue-entry-image"
|
<img class="list-entry-image"
|
||||||
on:click={(e) => showLightbox(entry.images, i, e)}
|
on:click={(e) => showLightbox(entry.images, i, e)}
|
||||||
src={image}
|
src={image}
|
||||||
alt="thumbnail" />
|
alt="thumbnail" />
|
||||||
@@ -26,40 +43,81 @@
|
|||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
<div class="queue-entry-details">
|
<div class="list-entry-details">
|
||||||
<div class="queue-entry-message">
|
<div class="list-entry-message">
|
||||||
{truncateString(entry.message, 20)}
|
{truncateString(entry.message, 20)}
|
||||||
</div>
|
</div>
|
||||||
<div class="queue-entry-submessage">
|
<div class="list-entry-submessage">
|
||||||
{entry.submessage}
|
{entry.submessage}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="queue-entry-rest {entry.status}">
|
<div class="list-entry-rest {entry.status}">
|
||||||
{#if entry.date != null}
|
{#if entry.date != null}
|
||||||
<span class="queue-entry-queued-at">
|
<span class="list-entry-queued-at">
|
||||||
{entry.date}
|
{entry.date}
|
||||||
</span>
|
</span>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
.queue-wrapper {
|
$list-controls-height: 3rem;
|
||||||
height: 100%;
|
$list-controls-margin: 0.25rem;
|
||||||
display: flex;
|
|
||||||
overflow-y: auto;
|
|
||||||
flex-flow: column nowrap;
|
|
||||||
|
|
||||||
&.queue-mode > :global(:first-child) {
|
.list-wrapper {
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
&.queue-mode .list-entries > :global(:first-child) {
|
||||||
// elements stick to bottom in queue mode only
|
// elements stick to bottom in queue mode only
|
||||||
// next element in queue is on the bottom
|
// next element in queue is on the bottom
|
||||||
margin-top: auto !important;
|
margin-top: auto !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.queue-entry {
|
.list-entries {
|
||||||
|
--imageSize: 40;
|
||||||
|
height: calc(100% - #{$list-controls-height} - #{$list-controls-margin});
|
||||||
|
overflow-y: auto;
|
||||||
|
display: flex;
|
||||||
|
flex-flow: column nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list-controls {
|
||||||
|
height: $list-controls-height;
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
margin: $list-controls-margin 1rem;
|
||||||
|
|
||||||
|
> div {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
input {
|
||||||
|
width: 100%;
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-wrapper {
|
||||||
|
padding: 0.25rem;
|
||||||
|
.clear-queue-button {
|
||||||
|
@include square-button;
|
||||||
|
|
||||||
|
aspect-ratio: 1/1;
|
||||||
|
height: 100%;
|
||||||
|
padding: 0.25rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.list-entry {
|
||||||
padding: 1.0rem;
|
padding: 1.0rem;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
@@ -96,7 +154,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.queue-entry-rest {
|
.list-entry-rest {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
@@ -108,7 +166,7 @@
|
|||||||
|
|
||||||
$thumbnails-size: 12rem;
|
$thumbnails-size: 12rem;
|
||||||
|
|
||||||
.queue-entry-images {
|
.list-entry-images {
|
||||||
--cols: 1;
|
--cols: 1;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
width: calc($thumbnails-size * 2);
|
width: calc($thumbnails-size * 2);
|
||||||
@@ -119,7 +177,9 @@
|
|||||||
column-gap: 1px;
|
column-gap: 1px;
|
||||||
row-gap: 1px;
|
row-gap: 1px;
|
||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
flex: 1 1 40%;
|
flex-grow: 1;
|
||||||
|
flex-shrink: 1;
|
||||||
|
flex-basis: calc(var(--imageSize) * 1%);
|
||||||
|
|
||||||
img {
|
img {
|
||||||
aspect-ratio: 1 / 1;
|
aspect-ratio: 1 / 1;
|
||||||
@@ -132,7 +192,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.queue-entry-details {
|
.list-entry-details {
|
||||||
position: relative;
|
position: relative;
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@@ -142,15 +202,15 @@
|
|||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.queue-entry-message {
|
.list-entry-message {
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.queue-entry-submessage {
|
.list-entry-submessage {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.queue-entry-queued-at {
|
.list-entry-queued-at {
|
||||||
width: auto;
|
width: auto;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
position:absolute;
|
position:absolute;
|
||||||
|
|||||||
@@ -115,7 +115,7 @@
|
|||||||
> button {
|
> button {
|
||||||
width: 4rem;
|
width: 4rem;
|
||||||
height: 4rem;
|
height: 4rem;
|
||||||
padding: 0.5rem;
|
padding: 0.75rem;
|
||||||
color: var(--neutral-600);
|
color: var(--neutral-600);
|
||||||
border-right: 3px solid transparent;
|
border-right: 3px solid transparent;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user