Spaces:
Running
Running
NakliTechie commited on
Commit Β·
1338746
1
Parent(s): 3111f03
Sync from GitHub 2026-04-19T10:22:10Z
Browse files- index.html +55 -5
index.html
CHANGED
|
@@ -1023,11 +1023,32 @@
|
|
| 1023 |
width: 0%;
|
| 1024 |
}
|
| 1025 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1026 |
.progress-text {
|
| 1027 |
font-size: 0.72rem;
|
| 1028 |
color: var(--gray-600);
|
| 1029 |
-
|
| 1030 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1031 |
}
|
| 1032 |
|
| 1033 |
/* Settings panel */
|
|
@@ -2163,7 +2184,10 @@
|
|
| 2163 |
<div class="progress-bar">
|
| 2164 |
<div class="progress-fill" id="progressFill"></div>
|
| 2165 |
</div>
|
| 2166 |
-
<div class="progress-text"
|
|
|
|
|
|
|
|
|
|
| 2167 |
</div>
|
| 2168 |
|
| 2169 |
<!-- Progress bar (SAM loading) -->
|
|
@@ -7947,7 +7971,9 @@ self.addEventListener('message', async (e) => {
|
|
| 7947 |
chatInput.disabled = true;
|
| 7948 |
chatInput.placeholder = `Loading ${m.label}...`;
|
| 7949 |
sendBtn.disabled = true; searchSendBtn.disabled = true;
|
| 7950 |
-
modelSelect
|
|
|
|
|
|
|
| 7951 |
updateModelUI();
|
| 7952 |
|
| 7953 |
// Delegate worker creation + load message to the runtime adapter.
|
|
@@ -7982,10 +8008,34 @@ self.addEventListener('message', async (e) => {
|
|
| 7982 |
modelSelect.addEventListener('change', () => {
|
| 7983 |
if (generating) return;
|
| 7984 |
const key = modelSelect.value;
|
| 7985 |
-
if (key === activeModelKey) return;
|
| 7986 |
loadModel(key);
|
| 7987 |
});
|
| 7988 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7989 |
// Attachment preprocessing (audio decode, video frame extraction,
|
| 7990 |
// image blob reads) has moved inside the runtime adapter β see
|
| 7991 |
// _adapterDecodeAudioTo16k / _adapterDecomposeVideo /
|
|
|
|
| 1023 |
width: 0%;
|
| 1024 |
}
|
| 1025 |
|
| 1026 |
+
.progress-text-row {
|
| 1027 |
+
display: flex;
|
| 1028 |
+
align-items: center;
|
| 1029 |
+
justify-content: space-between;
|
| 1030 |
+
gap: 8px;
|
| 1031 |
+
margin-top: 6px;
|
| 1032 |
+
}
|
| 1033 |
.progress-text {
|
| 1034 |
font-size: 0.72rem;
|
| 1035 |
color: var(--gray-600);
|
| 1036 |
+
flex: 1;
|
| 1037 |
+
}
|
| 1038 |
+
.progress-cancel-btn {
|
| 1039 |
+
padding: 2px 10px;
|
| 1040 |
+
font-size: 0.7rem;
|
| 1041 |
+
background: transparent;
|
| 1042 |
+
border: 1px solid var(--gray-200);
|
| 1043 |
+
color: var(--gray-600);
|
| 1044 |
+
border-radius: 4px;
|
| 1045 |
+
cursor: pointer;
|
| 1046 |
+
flex-shrink: 0;
|
| 1047 |
+
transition: border-color 0.15s, color 0.15s;
|
| 1048 |
+
}
|
| 1049 |
+
.progress-cancel-btn:hover {
|
| 1050 |
+
border-color: var(--gray-400);
|
| 1051 |
+
color: var(--gray-800);
|
| 1052 |
}
|
| 1053 |
|
| 1054 |
/* Settings panel */
|
|
|
|
| 2184 |
<div class="progress-bar">
|
| 2185 |
<div class="progress-fill" id="progressFill"></div>
|
| 2186 |
</div>
|
| 2187 |
+
<div class="progress-text-row">
|
| 2188 |
+
<div class="progress-text" id="progressText">Preparing to download model...</div>
|
| 2189 |
+
<button class="progress-cancel-btn" id="progressCancelBtn" title="Cancel download (partial chunks are preserved for resume)">Cancel</button>
|
| 2190 |
+
</div>
|
| 2191 |
</div>
|
| 2192 |
|
| 2193 |
<!-- Progress bar (SAM loading) -->
|
|
|
|
| 7971 |
chatInput.disabled = true;
|
| 7972 |
chatInput.placeholder = `Loading ${m.label}...`;
|
| 7973 |
sendBtn.disabled = true; searchSendBtn.disabled = true;
|
| 7974 |
+
// modelSelect stays enabled so users can hot-swap to a different model
|
| 7975 |
+
// mid-download (runtime.loadModel terminates the existing worker first).
|
| 7976 |
+
// Partial chunks already written to IDB stay available for resume.
|
| 7977 |
updateModelUI();
|
| 7978 |
|
| 7979 |
// Delegate worker creation + load message to the runtime adapter.
|
|
|
|
| 8008 |
modelSelect.addEventListener('change', () => {
|
| 8009 |
if (generating) return;
|
| 8010 |
const key = modelSelect.value;
|
| 8011 |
+
if (key === activeModelKey && modelReady) return;
|
| 8012 |
loadModel(key);
|
| 8013 |
});
|
| 8014 |
|
| 8015 |
+
// ββ Cancel button on the download progress panel ββββββββββββ
|
| 8016 |
+
// Terminates the worker (which aborts in-flight fetches) and returns
|
| 8017 |
+
// the app to an idle state. Partial chunks already saved to IDB stay
|
| 8018 |
+
// there, so reselecting the same model picks up roughly where we left
|
| 8019 |
+
// off via the resumable-fetch path.
|
| 8020 |
+
const progressCancelBtn = document.getElementById('progressCancelBtn');
|
| 8021 |
+
progressCancelBtn.addEventListener('click', () => {
|
| 8022 |
+
try { LocalMind.runtime.unload(); } catch {}
|
| 8023 |
+
worker = null;
|
| 8024 |
+
modelReady = false;
|
| 8025 |
+
activeModelKey = null;
|
| 8026 |
+
progressSection.classList.remove('visible');
|
| 8027 |
+
// Base `.status-badge` class with no state modifier β neutral grey
|
| 8028 |
+
// instead of red (this is user-initiated, not an error).
|
| 8029 |
+
statusBadge.className = 'status-badge';
|
| 8030 |
+
statusSpinner.style.display = 'none';
|
| 8031 |
+
statusText.textContent = 'Cancelled β pick a model';
|
| 8032 |
+
chatInput.disabled = true;
|
| 8033 |
+
chatInput.placeholder = 'Select a model to load';
|
| 8034 |
+
sendBtn.disabled = true;
|
| 8035 |
+
searchSendBtn.disabled = true;
|
| 8036 |
+
showToast('Download cancelled. Partial chunks kept for resume.');
|
| 8037 |
+
});
|
| 8038 |
+
|
| 8039 |
// Attachment preprocessing (audio decode, video frame extraction,
|
| 8040 |
// image blob reads) has moved inside the runtime adapter β see
|
| 8041 |
// _adapterDecodeAudioTo16k / _adapterDecomposeVideo /
|