CinePlex/js/utils.js
2025-07-02 14:16:25 +02:00

137 lines
4.6 KiB
JavaScript

export class TimeoutError extends Error {
constructor(message) {
super(message);
this.name = 'TimeoutError';
}
}
export function _(key, substitutions) {
try {
return chrome.i18n.getMessage(key, substitutions);
} catch (e) {
return key;
}
}
export function showNotification(message, type = 'info', duration = 3000) {
const notificationContainer = document.getElementById('notification-container');
const template = document.getElementById('notification-template');
if (!notificationContainer || !template) {
alert(`${type.toUpperCase()}: ${message}`);
return;
}
const notificationClone = template.querySelector('.notification').cloneNode(true);
notificationClone.className = `notification ${type}`;
const icon = notificationClone.querySelector('i');
const span = notificationClone.querySelector('span');
span.textContent = message;
let iconClass = 'fa-info-circle';
if (type === 'success') iconClass = 'fa-check-circle';
else if (type === 'error') iconClass = 'fa-exclamation-triangle';
else if (type === 'warning') iconClass = 'fa-exclamation-circle';
icon.className = `fas ${iconClass}`;
notificationContainer.prepend(notificationClone);
setTimeout(() => {
notificationClone.classList.add('show');
}, 50);
setTimeout(() => {
notificationClone.classList.remove('show');
notificationClone.addEventListener('transitionend', () => notificationClone.remove(), { once: true });
}, duration);
}
export function debounce(func, wait) {
let timeout;
return function executedFunction(...args) {
const later = () => {
clearTimeout(timeout);
func.apply(this, args);
};
clearTimeout(timeout);
timeout = setTimeout(later, wait);
};
}
export function getRelativeTime(timestamp) {
const now = Date.now();
const diffSeconds = Math.round((now - timestamp) / 1000);
const diffMinutes = Math.round(diffSeconds / 60);
const diffHours = Math.round(diffMinutes / 60);
const diffDays = Math.round(diffHours / 24);
if (diffSeconds < 60) return _('relativeTime_justNow');
if (diffMinutes < 60) return _('relativeTime_minutesAgo', String(diffMinutes));
if (diffHours < 24) return _('relativeTime_hoursAgo', String(diffHours));
if (diffDays === 1) return _('relativeTime_yesterday');
if (diffDays < 7) return _('relativeTime_daysAgo', String(diffDays));
return (new Date(timestamp)).toLocaleDateString(_('appLocaleCode'), { day: 'numeric', month: 'short' });
}
export function mostrarSpinner() {
const spinner = document.getElementById('spinner');
if (spinner) spinner.style.display = 'block';
}
export function ocultarSpinner() {
const spinner = document.getElementById('spinner');
if (spinner) spinner.style.display = 'none';
}
export function logToConsole(message) {
const consoleOutput = document.getElementById('consoleOutput');
if (!consoleOutput) return;
const logEntry = document.createElement('div');
logEntry.className = 'console-log-entry';
const time = new Date().toLocaleTimeString(_('appLocaleCode'), { hour12: false });
const timeSpan = document.createElement('span');
timeSpan.className = 'log-time';
timeSpan.textContent = `[${time}]`;
const messageSpan = document.createElement('span');
messageSpan.className = 'log-message';
messageSpan.textContent = message;
logEntry.appendChild(timeSpan);
logEntry.appendChild(document.createTextNode(' '));
logEntry.appendChild(messageSpan);
consoleOutput.appendChild(logEntry);
consoleOutput.scrollTop = consoleOutput.scrollHeight;
}
export function emitirEventoActualizacion() {
const event = new CustomEvent('indexedDBUpdated');
window.dispatchEvent(event);
}
export async function fetchWithTimeout(url, options, timeout = 7000) {
return new Promise((resolve, reject) => {
const controller = new AbortController();
const signal = controller.signal;
const timer = setTimeout(() => {
controller.abort();
reject(new TimeoutError(`Timeout(${timeout}ms)`));
}, timeout);
fetch(url, { ...options, signal })
.then(response => { clearTimeout(timer); resolve(response); })
.catch(err => {
clearTimeout(timer);
if (err.name === 'AbortError') {
reject(new TimeoutError(`Timeout(${timeout}ms)`));
} else {
reject(err);
}
});
});
}