Files
signalk-plugin/plugin/telegram/utility/live.js
Giuseppe Raffa bb8d267cd4 Aggiunta stili CSS per Kiosk, struttura HTML per la Mappa e Riferimenti ai Sensori
• Creato un nuovo file CSS per gli stili del chiosco (kiosk) con variabili, stili per le schede (card) e animazioni.
• Aggiunto un file HTML per l'interfaccia della mappa utilizzando Mapbox, inclusi gli stili e il JavaScript per le funzionalità della mappa.
• Introdotto un file JSON per i riferimenti ai sensori, definendo percorsi ed elementi per i dati di temperatura, vento, onde, posizione, batteria, motore e sistema.

Co-authored-by: Copilot <copilot@github.com>
2026-04-23 16:19:11 +02:00

131 lines
3.8 KiB
JavaScript

const MAX_LIVE_DURATION = 2 * 60 * 1000; // 2 minuti
const UPDATE_INTERVAL = 2000; // 2 secondi
// Mappa delle sessioni live attive: chiave = `chatId:botMessageId`
const activeSessions = new Map();
/**
* Restituisce il markup con i bottoni "Live" e "Chiudi"
* @param {Number} userMessageId
* @param {String} dataType - tipo di dati (logs, marine, weather, data)
*/
function liveMarkup(userMessageId, dataType) {
return {
inline_keyboard: [
[
{ text: 'Live', callback_data: `live:${dataType}:${userMessageId}` },
{ text: '<- Chiudi', callback_data: `close:${userMessageId}` }
]
]
};
}
/**
* Restituisce il markup con il bottone "Stop"
* @param {Number} userMessageId
*/
function stopMarkup(userMessageId) {
return {
inline_keyboard: [
[{ text: 'Stop', callback_data: `livestop:${userMessageId}` }]
]
};
}
/**
* Formatta il tempo rimanente in MM:SS
*/
function formatTime(ms) {
const totalSec = Math.ceil(ms / 1000);
const min = Math.floor(totalSec / 60);
const sec = totalSec % 60;
return `${min}:${sec.toString().padStart(2, '0')}`;
}
/**
* Avvia una sessione live
* @param {Object} bot - istanza del bot
* @param {Number} chatId
* @param {Number} botMessageId - ID del messaggio del bot da aggiornare
* @param {Number} userMessageId - ID del messaggio dell'utente
* @param {Function} getTextFn - funzione che restituisce il testo aggiornato (senza timer)
*/
function startSession(bot, chatId, botMessageId, userMessageId, getTextFn) {
const key = `${chatId}:${botMessageId}`;
// Se esiste già una sessione, non avviarne una nuova
if (activeSessions.has(key)) return;
const startTime = Date.now();
// Pinna il messaggio
bot.pinChatMessage(chatId, botMessageId, { disable_notification: true }).catch(() => {});
const interval = setInterval(async () => {
const elapsed = Date.now() - startTime;
const remaining = MAX_LIVE_DURATION - elapsed;
if (remaining <= 0) {
stopSession(bot, chatId, botMessageId, userMessageId);
return;
}
try {
const freshText = getTextFn();
const textWithTimer = freshText + `\n_Live: ${formatTime(remaining)} rimanenti_`;
await bot.editMessageText(textWithTimer, {
chat_id: chatId,
message_id: botMessageId,
parse_mode: 'Markdown',
reply_markup: stopMarkup(userMessageId)
});
} catch (error) {
// Ignora errori di "message not modified"
if (!error.message?.includes('message is not modified')) {
console.error('[LIVE] Errore aggiornamento:', error.message);
}
}
}, UPDATE_INTERVAL);
activeSessions.set(key, { interval, userMessageId });
}
/**
* Ferma una sessione live, toglie il pin, elimina i messaggi
*/
async function stopSession(bot, chatId, botMessageId, userMessageId) {
const key = `${chatId}:${botMessageId}`;
const session = activeSessions.get(key);
if (session) {
clearInterval(session.interval);
activeSessions.delete(key);
}
try {
await bot.unpinChatMessage(chatId, { message_id: botMessageId }).catch(() => {});
await bot.deleteMessage(chatId, botMessageId);
if (userMessageId) {
await bot.deleteMessage(chatId, parseInt(userMessageId));
}
} catch (error) {
console.error('[LIVE] Errore chiusura sessione:', error.message);
}
}
/**
* Cerca una sessione attiva dal botMessageId
*/
function getSession(chatId, botMessageId) {
return activeSessions.get(`${chatId}:${botMessageId}`);
}
module.exports = {
liveMarkup,
stopMarkup,
startSession,
stopSession,
getSession
};