LocalStorage used bar
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
<script lang="ts">
|
||||
import { embedTemplateInSvg, type SerializedComfyBoxTemplate } from "$lib/ComfyBoxTemplate";
|
||||
import templateState, { type TemplateState, type WritableTemplateStateStore } from "$lib/stores/templateState";
|
||||
import { BoxSeam } from "svelte-bootstrap-icons";
|
||||
import { BoxSeam, Hdd } from "svelte-bootstrap-icons";
|
||||
import uiState from "$lib/stores/uiState";
|
||||
import { download, truncateString } from "$lib/utils";
|
||||
import { download, getLocalStorageUsedMB, MAX_LOCAL_STORAGE_MB, truncateString } from "$lib/utils";
|
||||
import type ComfyApp from "./ComfyApp";
|
||||
import { flip } from 'svelte/animate';
|
||||
import {fade} from 'svelte/transition';
|
||||
@@ -27,6 +27,20 @@
|
||||
source?: string
|
||||
}
|
||||
|
||||
let storageUsedPercent = 0;
|
||||
let storageUsedMB = 0;
|
||||
|
||||
$: {
|
||||
if ($templateState) {
|
||||
storageUsedMB = getLocalStorageUsedMB()
|
||||
storageUsedPercent = (storageUsedMB / MAX_LOCAL_STORAGE_MB) * 100;
|
||||
}
|
||||
else {
|
||||
storageUsedPercent = 0;
|
||||
storageUsedMB = 0;
|
||||
}
|
||||
}
|
||||
|
||||
let _sorted: TemplateLayout[] = []
|
||||
|
||||
$: $templateState && rebuildTemplates(templateState.getAllTemplates());
|
||||
@@ -149,8 +163,7 @@
|
||||
{
|
||||
name: "Close",
|
||||
variant: "secondary",
|
||||
onClick: () => {
|
||||
}
|
||||
onClick: () => {}
|
||||
},
|
||||
]
|
||||
})
|
||||
@@ -161,30 +174,42 @@
|
||||
<div class="template-entries">
|
||||
{#if _sorted.length > 0}
|
||||
{@const draggable = $uiState.uiUnlocked}
|
||||
<div class="template-category-group">
|
||||
<div class="template-category-header">
|
||||
General
|
||||
<div class="template-list">
|
||||
<div class="template-category-group">
|
||||
<div class="template-category-header">
|
||||
General
|
||||
</div>
|
||||
<div class="template-entries-wrapper"
|
||||
use:dndzone={{
|
||||
type: "layout",
|
||||
items: _sorted,
|
||||
flipDurationMs,
|
||||
dragDisabled: !draggable,
|
||||
dropFromOthersDisabled: true
|
||||
}}
|
||||
on:consider={handleDndConsider}
|
||||
on:finalize={handleDndFinalize}>
|
||||
{#each _sorted.filter(i => i.id !== SHADOW_PLACEHOLDER_ITEM_ID) as item(item.id)}
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
<div class="template-entry" class:built-in={item.template.isBuiltIn} class:draggable on:click={() => handleClick(item)}>
|
||||
<div class="template-name">{item.template.metadata.title}</div>
|
||||
<div class="template-desc">{item.template.metadata.description}</div>
|
||||
</div>
|
||||
{#if item[SHADOW_ITEM_MARKER_PROPERTY_NAME]}
|
||||
<div in:fade={{duration:200, easing: cubicIn}} class='template-drag-item-shadow'/>
|
||||
{/if}
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
<div class="template-entries-wrapper"
|
||||
use:dndzone={{
|
||||
type: "layout",
|
||||
items: _sorted,
|
||||
flipDurationMs,
|
||||
dragDisabled: !draggable,
|
||||
dropFromOthersDisabled: true
|
||||
}}
|
||||
on:consider={handleDndConsider}
|
||||
on:finalize={handleDndFinalize}>
|
||||
{#each _sorted.filter(i => i.id !== SHADOW_PLACEHOLDER_ITEM_ID) as item(item.id)}
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
<div class="template-entry" class:built-in={item.template.isBuiltIn} class:draggable on:click={() => handleClick(item)}>
|
||||
<div class="template-name">{item.template.metadata.title}</div>
|
||||
<div class="template-desc">{item.template.metadata.description}</div>
|
||||
</div>
|
||||
{#if item[SHADOW_ITEM_MARKER_PROPERTY_NAME]}
|
||||
<div in:fade={{duration:200, easing: cubicIn}} class='template-drag-item-shadow'/>
|
||||
{/if}
|
||||
{/each}
|
||||
</div>
|
||||
<div class="storage-used">
|
||||
<div class="storage-used-icon">
|
||||
<Hdd width="100%" height="2rem" />
|
||||
</div>
|
||||
<div class="storage-used-bar-wrapper">
|
||||
<div class="storage-used-bar" style="width: {storageUsedPercent}%;">
|
||||
<span class="storage-used-label">{storageUsedMB.toFixed(2)} / {MAX_LOCAL_STORAGE_MB} MB</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{:else}
|
||||
@@ -207,9 +232,13 @@
|
||||
|
||||
.template-entries {
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.template-list {
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.template-category-header {
|
||||
@@ -234,6 +263,16 @@
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
|
||||
&.built-in {
|
||||
background: repeating-linear-gradient(
|
||||
45deg,
|
||||
var(--neutral-900),
|
||||
var(--neutral-900) 5px,
|
||||
var(--neutral-800) 5px,
|
||||
var(--neutral-800) 10px
|
||||
);
|
||||
}
|
||||
|
||||
font-size: 13pt;
|
||||
.template-desc {
|
||||
opacity: 65%;
|
||||
@@ -288,4 +327,45 @@
|
||||
opacity: 0.5;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.storage-used {
|
||||
height: 2.5rem;
|
||||
margin: 5px;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
padding: 0.1rem 0.5rem;
|
||||
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: var(--spacing-lg);
|
||||
|
||||
.storage-used-icon {
|
||||
color: var(--neutral-500);
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.storage-used-bar-wrapper {
|
||||
width: 100%;
|
||||
background: var(--panel-background-fill);
|
||||
border: 1px solid var(--neutral-700);
|
||||
position: relative;
|
||||
|
||||
.storage-used-bar {
|
||||
height: 100%;
|
||||
background: var(--neutral-700);
|
||||
|
||||
.storage-used-label {
|
||||
width: 100%;
|
||||
color: var(--neutral-200);
|
||||
font-size: 12pt;
|
||||
position: absolute;
|
||||
margin: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user