feat: Implement image import functionality, restructure control panel layout, and apply glassmorphism styling to controls.
This commit is contained in:
@@ -55,8 +55,11 @@ const { pathname } = Astro.url;
|
|||||||
left: 0;
|
left: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 24px;
|
height: 24px;
|
||||||
background: #000;
|
background: rgba(10, 10, 10, 0.8);
|
||||||
border-bottom: 1px solid var(--text-color);
|
-webkit-backdrop-filter: blur(12px);
|
||||||
|
backdrop-filter: blur(12px);
|
||||||
|
border-bottom: 1px solid rgba(255, 255, 255, 0.15);
|
||||||
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@@ -81,30 +84,32 @@ const { pathname } = Astro.url;
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
color: var(--text-color);
|
color: var(--text-color);
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
border-right: 1px solid rgba(255, 103, 0, 0.2);
|
border-right: 1px solid rgba(255, 255, 255, 0.1);
|
||||||
transition: all 0.1s;
|
transition: all 0.2s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-link:hover {
|
.nav-link:hover {
|
||||||
background: var(--text-color);
|
background: rgba(255, 255, 255, 0.1);
|
||||||
color: #000;
|
color: #fff;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-link:hover .nav-index {
|
.nav-link:hover .nav-index {
|
||||||
color: #000;
|
color: #fff;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.status-item.active {
|
.status-item.active {
|
||||||
background: var(--text-color);
|
background: rgba(255, 255, 255, 0.15);
|
||||||
color: #000;
|
color: #fff;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
box-shadow: inset 0 -2px 0 var(--text-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.status-item.brand {
|
.status-item.brand {
|
||||||
background: rgba(255, 103, 0, 0.1);
|
background: rgba(255, 255, 255, 0.05);
|
||||||
font-weight: 900;
|
font-weight: 900;
|
||||||
|
letter-spacing: 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-index {
|
.nav-index {
|
||||||
@@ -122,7 +127,7 @@ const { pathname } = Astro.url;
|
|||||||
|
|
||||||
.status-right .status-item {
|
.status-right .status-item {
|
||||||
border-right: none;
|
border-right: none;
|
||||||
border-left: 1px solid rgba(255, 103, 0, 0.2);
|
border-left: 1px solid rgba(255, 255, 255, 0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
.prefix {
|
.prefix {
|
||||||
@@ -134,6 +139,7 @@ const { pathname } = Astro.url;
|
|||||||
#system-status {
|
#system-status {
|
||||||
color: #0f0;
|
color: #0f0;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
text-shadow: 0 0 5px rgba(0, 255, 0, 0.5);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|||||||
@@ -174,64 +174,80 @@ import Tooltip from "../components/Tooltip.astro";
|
|||||||
<!-- Divider -->
|
<!-- Divider -->
|
||||||
<div class="control-panel-divider"></div>
|
<div class="control-panel-divider"></div>
|
||||||
|
|
||||||
<!-- Actions Section -->
|
<!-- Right Column: Actions & Export -->
|
||||||
<div class="control-panel-section actions-section">
|
<div class="control-col-right">
|
||||||
<div class="section-header">ACTIONS</div>
|
<div class="control-panel-section actions-section">
|
||||||
<div class="actions-row">
|
<div class="section-header">ACTIONS</div>
|
||||||
<TuiButton
|
<div class="actions-row">
|
||||||
id="btn-reset"
|
<TuiButton
|
||||||
label="RESET"
|
id="btn-reset"
|
||||||
shortcut="R"
|
label="RESET"
|
||||||
title="Reset to Auto-detected Settings"
|
shortcut="R"
|
||||||
description="Resets all sliders and toggles to their default values."
|
title="Reset to Auto-detected Settings"
|
||||||
/>
|
description="Resets all sliders and toggles to their default values."
|
||||||
|
/>
|
||||||
|
|
||||||
<TuiButton
|
<TuiButton
|
||||||
id="btn-next"
|
id="btn-next"
|
||||||
label="NEXT"
|
label="NEXT"
|
||||||
shortcut="N"
|
shortcut="N"
|
||||||
variant="primary"
|
variant="primary"
|
||||||
title="Load Next Image"
|
title="Load Next Image"
|
||||||
description="Discards current image and loads a new one from the queue."
|
description="Discards current image and loads a new one from the queue."
|
||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
class="queue-display"
|
class="queue-display"
|
||||||
data-tooltip-title="Buffered Images"
|
data-tooltip-title="Buffered Images"
|
||||||
data-tooltip-desc="Number of images pre-loaded in background queue."
|
data-tooltip-desc="Number of images pre-loaded in background queue."
|
||||||
>
|
|
||||||
<span class="queue-label">Q:</span>
|
|
||||||
<span id="val-queue" class="queue-value"
|
|
||||||
>0</span
|
|
||||||
>
|
>
|
||||||
|
<span class="queue-label">Q:</span>
|
||||||
|
<span id="val-queue" class="queue-value"
|
||||||
|
>0</span
|
||||||
|
>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Divider -->
|
<!-- Horizontal Divider for inside column -->
|
||||||
<div class="control-panel-divider"></div>
|
<div class="control-panel-divider-h"></div>
|
||||||
|
|
||||||
<!-- Export Section -->
|
<div class="control-panel-section export-section">
|
||||||
<div class="control-panel-section export-section">
|
<div class="section-header">
|
||||||
<div class="section-header">EXPORT</div>
|
IMPORT / EXPORT
|
||||||
<div class="actions-row">
|
</div>
|
||||||
<TuiButton
|
<div class="actions-row">
|
||||||
id="btn-save-png"
|
<!-- Hidden File Input -->
|
||||||
label="PNG"
|
<input
|
||||||
title="Save as Image"
|
type="file"
|
||||||
description="Download high-res PNG capture of the current view."
|
id="file-upload"
|
||||||
/>
|
accept="image/*"
|
||||||
<TuiButton
|
style="display: none;"
|
||||||
id="btn-copy-text"
|
/>
|
||||||
label="TXT"
|
<TuiButton
|
||||||
title="Save as Text"
|
id="btn-import"
|
||||||
description="Download raw ASCII text file."
|
label="IMP"
|
||||||
/>
|
title="Import Image"
|
||||||
<TuiButton
|
description="Upload your own image from your device."
|
||||||
id="btn-copy-html"
|
/>
|
||||||
label="HTML"
|
<TuiButton
|
||||||
title="Save as HTML"
|
id="btn-save-png"
|
||||||
description="Download colored HTML file."
|
label="PNG"
|
||||||
/>
|
title="Save as Image"
|
||||||
|
description="Download high-res PNG capture of the current view."
|
||||||
|
/>
|
||||||
|
<TuiButton
|
||||||
|
id="btn-copy-text"
|
||||||
|
label="TXT"
|
||||||
|
title="Save as Text"
|
||||||
|
description="Download raw ASCII text file."
|
||||||
|
/>
|
||||||
|
<TuiButton
|
||||||
|
id="btn-copy-html"
|
||||||
|
label="HTML"
|
||||||
|
title="Save as HTML"
|
||||||
|
description="Download colored HTML file."
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -405,6 +421,12 @@ import Tooltip from "../components/Tooltip.astro";
|
|||||||
font-size: 1.5rem;
|
font-size: 1.5rem;
|
||||||
display: none;
|
display: none;
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
|
|
||||||
|
text-shadow: 0 0 10px rgba(0, 0, 0, 0.8);
|
||||||
|
background: rgba(0, 0, 0, 0.6);
|
||||||
|
padding: 10px 20px;
|
||||||
|
border-radius: 4px;
|
||||||
|
backdrop-filter: blur(4px);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FOREGROUND LAYER */
|
/* FOREGROUND LAYER */
|
||||||
@@ -474,6 +496,7 @@ import Tooltip from "../components/Tooltip.astro";
|
|||||||
max-width: 400px;
|
max-width: 400px;
|
||||||
background: rgba(0, 0, 0, 0.6);
|
background: rgba(0, 0, 0, 0.6);
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
|
border-radius: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Footer / Controls */
|
/* Footer / Controls */
|
||||||
@@ -484,25 +507,40 @@ import Tooltip from "../components/Tooltip.astro";
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 0.75rem;
|
gap: 0.75rem;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
z-index: 50; /* Ensure on top */
|
||||||
}
|
}
|
||||||
|
|
||||||
#tui-controls {
|
#tui-controls {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: flex-start;
|
align-items: stretch; /* Stretch to same height */
|
||||||
gap: 0;
|
gap: 0;
|
||||||
background: rgba(0, 0, 0, 0.95);
|
|
||||||
border: 1px solid var(--text-color);
|
/* Glassmorphism update */
|
||||||
box-shadow: 0 0 30px rgba(0, 0, 0, 0.8);
|
background: rgba(10, 10, 10, 0.8);
|
||||||
|
backdrop-filter: blur(12px);
|
||||||
|
-webkit-backdrop-filter: blur(12px);
|
||||||
|
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.15);
|
||||||
|
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5);
|
||||||
|
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
|
border-radius: 8px; /* Slightly rounded for premium feel */
|
||||||
|
overflow: hidden; /* For border radius */
|
||||||
}
|
}
|
||||||
|
|
||||||
.control-panel-section {
|
.control-panel-section {
|
||||||
padding: 12px 16px;
|
padding: 16px 20px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 10px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.control-col-right {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 8px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.control-panel-divider {
|
.control-panel-divider {
|
||||||
@@ -510,32 +548,47 @@ import Tooltip from "../components/Tooltip.astro";
|
|||||||
background: linear-gradient(
|
background: linear-gradient(
|
||||||
to bottom,
|
to bottom,
|
||||||
transparent 0%,
|
transparent 0%,
|
||||||
rgba(255, 103, 0, 0.3) 20%,
|
rgba(255, 255, 255, 0.1) 20%,
|
||||||
rgba(255, 103, 0, 0.3) 80%,
|
rgba(255, 255, 255, 0.3) 50%,
|
||||||
|
rgba(255, 255, 255, 0.1) 80%,
|
||||||
transparent 100%
|
transparent 100%
|
||||||
);
|
);
|
||||||
align-self: stretch;
|
align-self: stretch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.control-panel-divider-h {
|
||||||
|
height: 1px;
|
||||||
|
width: 100%;
|
||||||
|
background: linear-gradient(
|
||||||
|
to right,
|
||||||
|
transparent 0%,
|
||||||
|
rgba(255, 255, 255, 0.1) 20%,
|
||||||
|
rgba(255, 255, 255, 0.3) 50%,
|
||||||
|
rgba(255, 255, 255, 0.1) 80%,
|
||||||
|
transparent 100%
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
.section-header {
|
.section-header {
|
||||||
font-size: 9px;
|
font-size: 10px;
|
||||||
font-weight: bold;
|
font-weight: 800;
|
||||||
opacity: 0.5;
|
opacity: 0.6;
|
||||||
letter-spacing: 2px;
|
letter-spacing: 2px;
|
||||||
margin-bottom: 4px;
|
margin-bottom: 2px;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
|
color: var(--text-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.sliders-grid {
|
.sliders-grid {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(2, 1fr);
|
grid-template-columns: repeat(2, 1fr);
|
||||||
gap: 6px 16px;
|
gap: 8px 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.toggles-row {
|
.toggles-row {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
gap: 6px;
|
gap: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.segments-row {
|
.segments-row {
|
||||||
@@ -547,7 +600,8 @@ import Tooltip from "../components/Tooltip.astro";
|
|||||||
.actions-row {
|
.actions-row {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 10px;
|
gap: 8px;
|
||||||
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.queue-display {
|
.queue-display {
|
||||||
@@ -557,7 +611,7 @@ import Tooltip from "../components/Tooltip.astro";
|
|||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
opacity: 0.6;
|
opacity: 0.6;
|
||||||
padding: 0 8px;
|
padding: 0 8px;
|
||||||
border-left: 1px solid rgba(255, 103, 0, 0.2);
|
border-left: 1px solid rgba(255, 255, 255, 0.2);
|
||||||
}
|
}
|
||||||
|
|
||||||
.queue-label {
|
.queue-label {
|
||||||
@@ -575,34 +629,34 @@ import Tooltip from "../components/Tooltip.astro";
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
gap: 12px;
|
gap: 16px;
|
||||||
font-size: 10px;
|
font-size: 11px;
|
||||||
opacity: 0.4;
|
opacity: 0.5;
|
||||||
transition: opacity 0.2s;
|
transition: opacity 0.2s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.shortcuts-hint:hover {
|
.shortcuts-hint:hover {
|
||||||
opacity: 0.7;
|
opacity: 0.8;
|
||||||
}
|
}
|
||||||
|
|
||||||
.shortcuts-hint span {
|
.shortcuts-hint span {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 4px;
|
gap: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.shortcuts-hint kbd {
|
.shortcuts-hint kbd {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
min-width: 16px;
|
min-width: 18px;
|
||||||
height: 16px;
|
height: 18px;
|
||||||
padding: 0 4px;
|
padding: 0 5px;
|
||||||
font-size: 9px;
|
font-size: 10px;
|
||||||
font-family: inherit;
|
font-family: inherit;
|
||||||
border: 1px solid rgba(255, 103, 0, 0.4);
|
border: 1px solid rgba(255, 255, 255, 0.3);
|
||||||
border-radius: 2px;
|
border-radius: 4px;
|
||||||
background: rgba(255, 103, 0, 0.05);
|
background: rgba(255, 255, 255, 0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Legacy styles kept for compatibility */
|
/* Legacy styles kept for compatibility */
|
||||||
@@ -627,7 +681,7 @@ import Tooltip from "../components/Tooltip.astro";
|
|||||||
.tui-btn:hover {
|
.tui-btn:hover {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
border-color: var(--text-color);
|
border-color: var(--text-color);
|
||||||
background: rgba(255, 103, 0, 0.1);
|
background: rgba(255, 255, 255, 0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
.tui-val {
|
.tui-val {
|
||||||
@@ -648,20 +702,45 @@ import Tooltip from "../components/Tooltip.astro";
|
|||||||
align-items: stretch;
|
align-items: stretch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.control-col-right {
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: space-between;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.control-col-right > .control-panel-section {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* New vertical alignment for right col on mobile */
|
||||||
|
.control-panel-divider-h {
|
||||||
|
width: 1px;
|
||||||
|
height: auto;
|
||||||
|
align-self: stretch;
|
||||||
|
background: linear-gradient(
|
||||||
|
to bottom,
|
||||||
|
transparent 0%,
|
||||||
|
rgba(255, 255, 255, 0.2) 20%,
|
||||||
|
rgba(255, 255, 255, 0.2) 80%,
|
||||||
|
transparent 100%
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
.control-panel-divider {
|
.control-panel-divider {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 1px;
|
height: 1px;
|
||||||
background: linear-gradient(
|
background: linear-gradient(
|
||||||
to right,
|
to right,
|
||||||
transparent 0%,
|
transparent 0%,
|
||||||
rgba(255, 103, 0, 0.3) 20%,
|
rgba(255, 255, 255, 0.1) 20%,
|
||||||
rgba(255, 103, 0, 0.3) 80%,
|
rgba(255, 255, 255, 0.3) 50%,
|
||||||
|
rgba(255, 255, 255, 0.1) 80%,
|
||||||
transparent 100%
|
transparent 100%
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
.control-panel-section {
|
.control-panel-section {
|
||||||
padding: 10px 14px;
|
padding: 12px 16px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -670,6 +749,21 @@ import Tooltip from "../components/Tooltip.astro";
|
|||||||
font-size: 3rem;
|
font-size: 3rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.control-col-right {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.control-panel-divider-h {
|
||||||
|
width: 100%;
|
||||||
|
height: 1px;
|
||||||
|
background: linear-gradient(
|
||||||
|
to right,
|
||||||
|
transparent,
|
||||||
|
rgba(255, 255, 255, 0.2),
|
||||||
|
transparent
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
.controls-footer {
|
.controls-footer {
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
}
|
}
|
||||||
@@ -691,11 +785,11 @@ import Tooltip from "../components/Tooltip.astro";
|
|||||||
|
|
||||||
@media (max-width: 480px) {
|
@media (max-width: 480px) {
|
||||||
.control-panel-section {
|
.control-panel-section {
|
||||||
padding: 8px 10px;
|
padding: 10px 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.section-header {
|
.section-header {
|
||||||
font-size: 8px;
|
font-size: 9px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ export class UIBindings {
|
|||||||
this.setupKeyboard();
|
this.setupKeyboard();
|
||||||
this.setupZoom();
|
this.setupZoom();
|
||||||
this.setupResize();
|
this.setupResize();
|
||||||
|
this.setupImport();
|
||||||
|
|
||||||
// Periodic queue update
|
// Periodic queue update
|
||||||
this.queueInterval = window.setInterval(() => this.updateQueueDisplay(), 1000);
|
this.queueInterval = window.setInterval(() => this.updateQueueDisplay(), 1000);
|
||||||
@@ -142,13 +143,20 @@ export class UIBindings {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Cleanup Export Buttons
|
// Cleanup Export Buttons
|
||||||
['btn-save-png', 'btn-copy-text', 'btn-copy-html'].forEach(id => {
|
['btn-save-png', 'btn-copy-text', 'btn-copy-html', 'btn-import'].forEach(id => {
|
||||||
const el = document.getElementById(id);
|
const el = document.getElementById(id);
|
||||||
const handler = this.buttonHandlers.get(id);
|
const handler = this.buttonHandlers.get(id);
|
||||||
if (el && handler) {
|
if (el && handler) {
|
||||||
el.removeEventListener('click', handler);
|
el.removeEventListener('click', handler);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Cleanup File Input
|
||||||
|
const fileInput = document.getElementById('file-upload');
|
||||||
|
const fileHandler = this.buttonHandlers.get('file-upload');
|
||||||
|
if (fileInput && fileHandler) {
|
||||||
|
fileInput.removeEventListener('change', fileHandler);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============= Sliders =============
|
// ============= Sliders =============
|
||||||
@@ -412,6 +420,52 @@ export class UIBindings {
|
|||||||
window.addEventListener('resize', this.resizeHandler);
|
window.addEventListener('resize', this.resizeHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ============= Import =============
|
||||||
|
|
||||||
|
private setupImport(): void {
|
||||||
|
const btnImport = document.getElementById('btn-import');
|
||||||
|
const fileInput = document.getElementById('file-upload') as HTMLInputElement;
|
||||||
|
|
||||||
|
if (btnImport && fileInput) {
|
||||||
|
// Button triggers file input
|
||||||
|
const btnHandler = (e: Event) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
fileInput.click();
|
||||||
|
};
|
||||||
|
this.buttonHandlers.set('btn-import', btnHandler);
|
||||||
|
btnImport.addEventListener('click', btnHandler);
|
||||||
|
|
||||||
|
// File input change
|
||||||
|
const fileHandler = async (e: Event) => {
|
||||||
|
const files = (e.target as HTMLInputElement).files;
|
||||||
|
if (files && files.length > 0) {
|
||||||
|
const file = files[0];
|
||||||
|
const url = URL.createObjectURL(file);
|
||||||
|
|
||||||
|
// Reset value so same file can be selected again
|
||||||
|
fileInput.value = '';
|
||||||
|
|
||||||
|
try {
|
||||||
|
this.controller.showLoading("LOADING IMPORT...");
|
||||||
|
// Use empty suggestions for user imports unless we want to auto-detect?
|
||||||
|
// For now keep existing settings or use defaults.
|
||||||
|
// Let's pass empty object to respect current user settings or controller defaults.
|
||||||
|
this.controller.setCurrentImage(url, {});
|
||||||
|
this.updateUI();
|
||||||
|
await this.controller.generate();
|
||||||
|
this.controller.hideLoading();
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Import failed:", err);
|
||||||
|
this.controller.hideLoading();
|
||||||
|
alert("Failed to load image. Please try another file.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
this.buttonHandlers.set('file-upload', fileHandler);
|
||||||
|
fileInput.addEventListener('change', fileHandler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ============= UI Sync =============
|
// ============= UI Sync =============
|
||||||
|
|
||||||
updateUI(): void {
|
updateUI(): void {
|
||||||
|
|||||||
Reference in New Issue
Block a user