T3: Autosample UX - fail reason + toast + pre-warm feedback
vstiAutosample: fail map thanh object {ts, reason} (cooldown check
object-aware), recordFail o API-missing/response loi/catch, export
failReasonFor. soundfontPlayer: toast ly do khi ensure null (throttle
10s) roi fallback oscillator. app.jsx: pre-warm VSTi hien thi toast khi
autosample fail.
This commit is contained in:
@@ -19,6 +19,13 @@ window.SonicVstiAutosample = window.SonicVstiAutosample || {};
|
||||
function readFails() {
|
||||
try { return JSON.parse(localStorage.getItem(LS_FAIL_KEY) || '{}') || {}; } catch (e) { return {}; }
|
||||
}
|
||||
function recordFail(k, reason) {
|
||||
try {
|
||||
var fails2 = readFails();
|
||||
fails2[k] = { ts: Date.now(), reason: reason || 'Autosample that bai' };
|
||||
localStorage.setItem(LS_FAIL_KEY, JSON.stringify(fails2));
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
// Key = plugin + preset → autosample lại khi đổi preset (âm preset mới).
|
||||
function keyFor(synthEngine) {
|
||||
@@ -51,10 +58,13 @@ window.SonicVstiAutosample = window.SonicVstiAutosample || {};
|
||||
if (cached) return Promise.resolve(cached);
|
||||
if (_inFlight[k]) return _inFlight[k];
|
||||
var fails = readFails();
|
||||
if (fails[k] && (Date.now() - fails[k]) < FAIL_COOLDOWN_MS) {
|
||||
var _f = fails[k];
|
||||
var _lastTs = (_f && typeof _f === 'object') ? _f.ts : _f;
|
||||
if (_lastTs && (Date.now() - _lastTs) < FAIL_COOLDOWN_MS) {
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
if (!window.SonicAPI || !window.SonicAPI.autosampleVsti) {
|
||||
recordFail(k, 'API autosample khong kha dung');
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
_inFlight[k] = new Promise(function (resolve) {
|
||||
@@ -72,19 +82,29 @@ window.SonicVstiAutosample = window.SonicVstiAutosample || {};
|
||||
writeMap(map);
|
||||
resolve(res.sf_id);
|
||||
} else {
|
||||
recordFail(k, (res && res.error) ? String(res.error) : 'Server khong tra sf_id');
|
||||
resolve(null);
|
||||
}
|
||||
}).catch(function () {
|
||||
}).catch(function (err) {
|
||||
delete _inFlight[k];
|
||||
var fails2 = readFails();
|
||||
fails2[k] = Date.now();
|
||||
try { localStorage.setItem(LS_FAIL_KEY, JSON.stringify(fails2)); } catch (e) {}
|
||||
recordFail(k, (err && err.message) ? String(err.message) : 'Loi mang / server autosample');
|
||||
resolve(null);
|
||||
});
|
||||
});
|
||||
return _inFlight[k];
|
||||
}
|
||||
|
||||
// Lý do autosample thất bại gần nhất (fail map) — null nếu chưa từng fail
|
||||
// (hoặc entry cũ định dạng number). Dùng cho UI toast khi ensure() trả null.
|
||||
function failReasonFor(synthEngine) {
|
||||
var k = keyFor(synthEngine);
|
||||
if (!k) return null;
|
||||
var fails = readFails();
|
||||
var f = fails[k];
|
||||
if (!f || typeof f !== 'object') return null;
|
||||
return f.reason || null;
|
||||
}
|
||||
|
||||
// Xoá cache + cooldown — cho phép re-sample (đổi preset/plugin hoặc debug).
|
||||
function clearCache() {
|
||||
try { localStorage.removeItem(LS_MAP_KEY); } catch (e) {}
|
||||
@@ -96,6 +116,7 @@ window.SonicVstiAutosample = window.SonicVstiAutosample || {};
|
||||
sfIdFor: sfIdFor,
|
||||
entryFor: entryFor,
|
||||
ensure: ensure,
|
||||
failReasonFor: failReasonFor,
|
||||
clearCache: clearCache
|
||||
};
|
||||
})();
|
||||
|
||||
Reference in New Issue
Block a user