Añadir manejo de eventos de base de datos y mejorar la carga de precios del café

This commit is contained in:
Naiel
2026-02-12 14:30:59 +00:00
parent dc4ba25b20
commit eb6a956cdc
4 changed files with 51 additions and 52 deletions

View File

@@ -19,6 +19,8 @@ function open_page(params) {
EventListeners.QRScanner = []; EventListeners.QRScanner = [];
EventListeners.Custom.forEach((ev) => ev()); EventListeners.Custom.forEach((ev) => ev());
EventListeners.Custom = []; EventListeners.Custom = [];
EventListeners.DB.forEach((ev) => DB.unlisten(ev));
EventListeners.DB = [];
if (SUB_LOGGED_IN != true && params != 'login,setup' && !params.startsWith('login,onboarding')) { if (SUB_LOGGED_IN != true && params != 'login,setup' && !params.startsWith('login,onboarding')) {
PAGES['login'].index(); PAGES['login'].index();

View File

@@ -15,11 +15,13 @@ window.PRECIOS_CAFE = {
// Cargar precios desde la base de datos al iniciar // Cargar precios desde la base de datos al iniciar
if (typeof DB !== 'undefined') { if (typeof DB !== 'undefined') {
DB.get('config', 'precios_cafe').then((precios) => { DB.get('config', 'precios_cafe').then((raw) => {
TS_decrypt(raw, SECRET, (precios) => {
if (precios) { if (precios) {
Object.assign(window.PRECIOS_CAFE, precios); Object.assign(window.PRECIOS_CAFE, precios);
console.log('Precios del café cargados:', window.PRECIOS_CAFE); console.log('Precios del café cargados:', window.PRECIOS_CAFE);
} }
});
}).catch(() => { }).catch(() => {
console.log('Usando precios por defecto'); console.log('Usando precios por defecto');
}); });
@@ -1259,7 +1261,7 @@ function TS_IndexElement(
} }
// Subscribe to dataset updates using DB.map (PouchDB) when `ref` is a table name string // Subscribe to dataset updates using DB.map (PouchDB) when `ref` is a table name string
if (typeof ref === 'string') { if (typeof ref === 'string') {
DB.map(ref, (data, key) => { EventListeners.DB.push(DB.map(ref, (data, key) => {
function add_row(data, key) { function add_row(data, key) {
if (data != null) { if (data != null) {
data['_key'] = key; data['_key'] = key;
@@ -1274,49 +1276,21 @@ function TS_IndexElement(
data, data,
SECRET, SECRET,
(data, wasEncrypted) => { (data, wasEncrypted) => {
if (data != null && typeof data === 'object') {
data['_encrypted__'] = wasEncrypted; data['_encrypted__'] = wasEncrypted;
add_row(data, key); add_row(data, key);
}
}, },
ref, ref,
key key
); );
} else { } else {
if (data != null && typeof data === 'object') {
data['_encrypted__'] = false; data['_encrypted__'] = false;
}
add_row(data, key); add_row(data, key);
} }
}); }));
} else if (ref && typeof ref.map === 'function') {
// Legacy: try to use ref.map().on if available (for backwards compatibility)
try {
ref.map().on((data, key, _msg, _ev) => {
function add_row(data, key) {
if (data != null) {
data['_key'] = key;
rows[key] = data;
} else {
delete rows[key];
}
debounce(debounce_load, render, 200, [rows]);
}
if (typeof data == 'string') {
TS_decrypt(
data,
SECRET,
(data, wasEncrypted) => {
data['_encrypted__'] = wasEncrypted;
add_row(data, key);
},
undefined,
undefined
);
} else {
data['_encrypted__'] = false;
add_row(data, key);
}
});
} catch (e) {
console.warn('TS_IndexElement: cannot subscribe to ref', e);
}
} }
} }
@@ -1326,7 +1300,7 @@ function BuildQR(mid, label) {
dim: 150, dim: 150,
pad: 0, pad: 0,
mtx: -1, mtx: -1,
ecl: 'L', ecl: 'S',
ecb: 0, ecb: 0,
pal: ['#000000', '#ffffff'], pal: ['#000000', '#ffffff'],
vrb: 0, vrb: 0,

View File

@@ -8,6 +8,7 @@ var EventListeners = {
Interval: [], Interval: [],
QRScanner: [], QRScanner: [],
Custom: [], Custom: [],
DB: [],
}; };
// Safe UUID for html element IDs: generates a unique identifier with a specified prefix, ensuring it is safe for use in HTML element IDs. It uses crypto.randomUUID if available, with a fallback to a random string generation method for environments that do not support it. The generated ID is prefixed to avoid collisions and ensure uniqueness across the application. // Safe UUID for html element IDs: generates a unique identifier with a specified prefix, ensuring it is safe for use in HTML element IDs. It uses crypto.randomUUID if available, with a fallback to a random string generation method for environments that do not support it. The generated ID is prefixed to avoid collisions and ensure uniqueness across the application.
@@ -131,7 +132,7 @@ var TTS_RATE = parseFloat(urlParams.get('tts_rate')) || 0.75;
function TS_SayTTS(msg) { function TS_SayTTS(msg) {
try { try {
if (window.speechSynthesis) { if (window.speechSynthesis) {
let utterance = new SpeechSynthesisUtterance(tts_msg); let utterance = new SpeechSynthesisUtterance(msg);
utterance.rate = TTS_RATE; utterance.rate = TTS_RATE;
speechSynthesis.speak(utterance); speechSynthesis.speak(utterance);
} }

View File

@@ -9,7 +9,8 @@ var DB = (function () {
let changes = null; let changes = null;
let repPush = null; let repPush = null;
let repPull = null; let repPull = null;
let callbacks = {}; // table -> [cb] let callbacks = {}; // table -> [{ id, cb }]
let callbackSeq = 0;
let docCache = {}; // _id -> last data snapshot (stringified) let docCache = {}; // _id -> last data snapshot (stringified)
function ensureLocal() { function ensureLocal() {
@@ -34,6 +35,11 @@ var DB = (function () {
return table + ':' + id; return table + ':' + id;
} }
function makeCallbackId(table) {
callbackSeq += 1;
return table + '#' + callbackSeq;
}
function init(opts) { function init(opts) {
const localName = 'telesec'; const localName = 'telesec';
try { try {
@@ -126,7 +132,8 @@ var DB = (function () {
if (change.deleted || doc._deleted) { if (change.deleted || doc._deleted) {
delete docCache[doc._id]; delete docCache[doc._id];
if (callbacks[table]) { if (callbacks[table]) {
callbacks[table].forEach((cb) => { callbacks[table].forEach((listener) => {
const cb = listener.cb;
try { try {
cb(null, id); cb(null, id);
} catch (e) { } catch (e) {
@@ -148,7 +155,8 @@ var DB = (function () {
} }
if (callbacks[table]) { if (callbacks[table]) {
callbacks[table].forEach((cb) => { callbacks[table].forEach((listener) => {
const cb = listener.cb;
try { try {
cb(doc.data, id); cb(doc.data, id);
} catch (e) { } catch (e) {
@@ -348,12 +356,25 @@ var DB = (function () {
function map(table, cb) { function map(table, cb) {
ensureLocal(); ensureLocal();
const callbackId = makeCallbackId(table);
callbacks[table] = callbacks[table] || []; callbacks[table] = callbacks[table] || [];
callbacks[table].push(cb); callbacks[table].push({ id: callbackId, cb: cb });
list(table).then((rows) => rows.forEach((r) => cb(r.data, r.id))); list(table).then((rows) => {
return () => { const stillListening = (callbacks[table] || []).some((listener) => listener.id === callbackId);
callbacks[table] = callbacks[table].filter((x) => x !== cb); if (!stillListening) return;
}; rows.forEach((r) => cb(r.data, r.id));
});
return callbackId;
}
function unlisten(callbackId) {
if (!callbackId) return false;
for (const table of Object.keys(callbacks)) {
const before = callbacks[table].length;
callbacks[table] = callbacks[table].filter((listener) => listener.id !== callbackId);
if (callbacks[table].length !== before) return true;
}
return false;
} }
return { return {
@@ -363,6 +384,7 @@ var DB = (function () {
del, del,
list, list,
map, map,
unlisten,
replicateToRemote, replicateToRemote,
listAttachments, listAttachments,
deleteAttachment, deleteAttachment,