feat: implement modern glassmorphism design system with multi-theme support and primary generator components

This commit is contained in:
techjarves committed 2026-06-25 18:27:11 +05:30
1 parent aeeb37770b
commit 35f1ce9783
3 files changed
+96 -96

No files matched your search

-8
View File
@@ -2114,14 +2114,6 @@ html[data-theme^="dark"] .m3-segment-item:hover:not(.active):not(.disabled) {
border-radius: var(--md-shape-corner-full);
font-size: 0.78rem;
font-weight: 550;
cursor: pointer;
transition: all var(--md-transition-duration);
}
.status-chip:hover {
background-color: var(--md-sys-color-primary-container);
border-color: var(--md-sys-color-primary);
color: var(--md-sys-color-primary);
}
.prompt-actions {
+5 -39
View File
@@ -683,28 +683,7 @@ function Generator({
<div className="m3-field-group">
{/* Prompt Textarea */}
<div className="m3-text-field">
<div style={{ display: "flex", justifyContent: "space-between", alignItems: "center" }}>
<label className="m3-text-field-label">Positive Prompt</label>
<button
type="button"
className="m3-btn m3-btn-tonal"
style={{ height: "28px", padding: "0 10px", fontSize: "0.75rem", borderRadius: "14px", display: "flex", alignItems: "center", gap: "4px" }}
onClick={handleEnhancePrompt}
disabled={isGenerating || isEnhancing || !prompt.trim()}
>
{isEnhancing ? (
<>
<span className="progress-spinner" style={{ width: "12px", height: "12px", borderWidth: "2px" }} />
<span>Enhancing...</span>
</>
) : (
<>
<Sparkles size={12} />
<span>Enhance Prompt</span>
</>
)}
</button>
</div>
<label className="m3-text-field-label">Image Prompt</label>
<textarea
className="m3-textarea"
value={prompt}
@@ -714,19 +693,6 @@ function Generator({
/>
</div>
{/* Negative Prompt Text Input */}
<div className="m3-text-field">
<label className="m3-text-field-label">Negative Prompt (Optional)</label>
<input
type="text"
className="m3-input"
value={negativePrompt}
onChange={(e) => setNegativePrompt(e.target.value)}
placeholder="Items to avoid (e.g. 'blurry, low quality, deformed hands, texts')..."
disabled={isGenerating}
/>
</div>
{constraints.backendType !== "apple-npu" && constraints.backendType !== "openvino-npu" && (
<div className="m3-text-field">
<label className="m3-text-field-label">Base Image (Optional)</label>
@@ -789,19 +755,19 @@ function Generator({
<div className="m3-text-field">
<label className="m3-text-field-label">Active Image Constraints</label>
<div className="chips-container">
<div className="status-chip" onClick={() => setActiveTab("constraints")}>
<div className="status-chip">
<Sliders size={14} />
<span>Resolution: {constraints.width}x{constraints.height}</span>
</div>
<div className="status-chip" onClick={() => setActiveTab("constraints")}>
<div className="status-chip">
<RefreshCw size={14} />
<span>Steps: {constraints.steps}</span>
</div>
<div className="status-chip" onClick={() => setActiveTab("constraints")}>
<div className="status-chip">
<Sparkles size={14} />
<span>Sampler: {constraints.sampler}</span>
</div>
<div className="status-chip" onClick={() => setActiveTab("constraints")}>
<div className="status-chip">
<span>Seed: {constraints.seed === -1 ? "Random" : constraints.seed}</span>
</div>
</div>
+91 -49
View File
@@ -423,10 +423,48 @@ function Settings({
};
const updateTextSetting = (key, value) => {
setPendingTextSettings((prev) => ({
...prev,
[key]: value
}));
setPendingTextSettings((prev) => {
const updated = { ...prev, [key]: value };
// If the user selected a preset performance profile, apply its hardware parameters
if (key === "performanceProfile") {
const presets = specs?.recommended_text_settings;
if (presets) {
let preset = null;
if (value === "potato") preset = presets.low;
else if (value === "balanced") preset = presets.mid;
else if (value === "high") preset = presets.high;
if (preset) {
Object.assign(updated, {
contextSize: preset.contextSize,
threads: preset.threads,
gpuLayers: preset.gpuLayers,
cacheTypeK: preset.cacheTypeK,
cacheTypeV: preset.cacheTypeV,
flashAttn: preset.flashAttn,
mlock: preset.mlock,
mmap: preset.mmap,
cachePrompt: preset.cachePrompt,
batchSize: preset.batchSize,
ubatchSize: preset.ubatchSize,
});
}
}
} else {
// If the user manually overrides any performance-related setting, auto-switch profile to "custom"
const isPerformanceKey = [
"contextSize", "threads", "gpuLayers", "cacheTypeK", "cacheTypeV",
"flashAttn", "mlock", "mmap", "cachePrompt", "batchSize", "ubatchSize"
].includes(key);
if (isPerformanceKey) {
updated.performanceProfile = "custom";
}
}
return updated;
});
};
const updateSpeechSetting = (key, value) => {
@@ -1093,6 +1131,8 @@ function Settings({
</div>
</div>
{llmBackends.available?.length > 1 && (
<div className="m3-slider-group">
<div className="m3-slider-header">
@@ -1186,57 +1226,59 @@ function Settings({
))}
</div>
</div>
{hasPendingChanges && (
<div className="settings-save-bar" style={{
display: "flex",
alignItems: "center",
justifyContent: "space-between",
padding: "16px 20px",
background: "color-mix(in srgb, var(--md-sys-color-primary) 10%, var(--bg-card))",
border: "1px solid color-mix(in srgb, var(--md-sys-color-primary) 30%, transparent)",
borderRadius: "14px",
marginTop: "20px",
gap: "16px",
flexWrap: "wrap",
animation: "fadeIn 0.2s ease",
width: "100%",
boxSizing: "border-box"
}}>
<div style={{ display: "flex", alignItems: "center", gap: "10px" }}>
<Brain size={18} style={{ color: "var(--md-sys-color-primary)" }} />
<div>
<div style={{ fontWeight: 600, fontSize: "0.9rem" }}>Unsaved Text Generation Settings</div>
<div style={{ fontSize: "0.85rem", opacity: 0.8, marginTop: "2px" }}>
{llmStatus.ready
? "Saving will unload the active text model to apply changes."
: "Changes will be applied on the next model load."}
</div>
</div>
</div>
<button
className="m3-btn m3-btn-filled"
onClick={handleSaveTextSettings}
style={{
background: "var(--md-sys-color-primary)",
color: "var(--md-sys-color-on-primary)",
border: "none",
borderRadius: "10px",
padding: "10px 18px",
fontWeight: 600,
fontSize: "0.85rem",
cursor: "pointer",
boxShadow: "0 2px 8px color-mix(in srgb, var(--md-sys-color-primary) 30%, transparent)",
}}
>
Save & Apply Changes
</button>
</div>
)}
</div>
</div>
</div>
</div>
{hasPendingChanges && (
<div className="settings-save-bar" style={{
display: "flex",
alignItems: "center",
justifyContent: "space-between",
padding: "16px 20px",
background: "color-mix(in srgb, var(--md-sys-color-primary) 10%, var(--bg-card))",
border: "1px solid color-mix(in srgb, var(--md-sys-color-primary) 30%, transparent)",
borderRadius: "14px",
marginTop: "20px",
gap: "16px",
flexWrap: "wrap",
animation: "fadeIn 0.2s ease",
}}>
<div style={{ display: "flex", alignItems: "center", gap: "10px" }}>
<Brain size={18} style={{ color: "var(--md-sys-color-primary)" }} />
<div>
<div style={{ fontWeight: 600, fontSize: "0.9rem" }}>Unsaved Text Generation Settings</div>
<div style={{ fontSize: "0.85rem", opacity: 0.8, marginTop: "2px" }}>
{llmStatus.ready
? "Saving will unload the active text model to apply changes."
: "Changes will be applied on the next model load."}
</div>
</div>
</div>
<button
className="m3-btn m3-btn-filled"
onClick={handleSaveTextSettings}
style={{
background: "var(--md-sys-color-primary)",
color: "var(--md-sys-color-on-primary)",
border: "none",
borderRadius: "10px",
padding: "10px 18px",
fontWeight: 600,
fontSize: "0.85rem",
cursor: "pointer",
boxShadow: "0 2px 8px color-mix(in srgb, var(--md-sys-color-primary) 30%, transparent)",
}}
>
Save & Apply Changes
</button>
</div>
)}
</div>
)}
</>