feat(client): pausar/continuar envio com auto-retomada após 10 min
- Checkbox "Pausar Envio de Imagens" na bandeja (tray) - Auto-retomada automática após 10 min de pausa (caso usuário esqueça) - client-monitor: comandos IPC pause/resume; processQueue e executarSincronizacaoLocal respeitam a pausa, mantendo imagens na fila sem perdê-las - Estado de pausa reaplicado se o monitor reiniciar - "Forçar Sincronização" retoma o envio automaticamente se estiver pausado - Bump 1.2.7 → 1.2.8 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+14
-1
@@ -1128,6 +1128,10 @@ async function executarSincronizacaoLocal() {
|
|||||||
let processadas = 0;
|
let processadas = 0;
|
||||||
|
|
||||||
for (const file of imagens) {
|
for (const file of imagens) {
|
||||||
|
if (isSendingPaused) {
|
||||||
|
addLog(`⏸️ Envio pausado durante a sincronização — interrompendo. ${processadas} já processadas.`);
|
||||||
|
break;
|
||||||
|
}
|
||||||
const filePath = path.join(pastaImagensSensor, file);
|
const filePath = path.join(pastaImagensSensor, file);
|
||||||
|
|
||||||
const stat = fs.statSync(filePath);
|
const stat = fs.statSync(filePath);
|
||||||
@@ -1156,12 +1160,17 @@ async function executarSincronizacaoLocal() {
|
|||||||
// Fila para processar uploads de forma sequencial
|
// Fila para processar uploads de forma sequencial
|
||||||
const uploadQueue = [];
|
const uploadQueue = [];
|
||||||
let isProcessingQueue = false;
|
let isProcessingQueue = false;
|
||||||
|
let isSendingPaused = false; // Controle de pausa/continuação do envio
|
||||||
|
|
||||||
async function processQueue() {
|
async function processQueue() {
|
||||||
if (isProcessingQueue) return;
|
if (isProcessingQueue) return;
|
||||||
|
if (isSendingPaused) {
|
||||||
|
addLog(`⏸️ Envio pausado — ${uploadQueue.length} imagem(ns) aguardando na fila.`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
isProcessingQueue = true;
|
isProcessingQueue = true;
|
||||||
|
|
||||||
while (uploadQueue.length > 0) {
|
while (uploadQueue.length > 0 && !isSendingPaused) {
|
||||||
const item = uploadQueue.shift();
|
const item = uploadQueue.shift();
|
||||||
const nextPath = item.filePath;
|
const nextPath = item.filePath;
|
||||||
const isBacklog = item.isBacklog;
|
const isBacklog = item.isBacklog;
|
||||||
@@ -1173,6 +1182,10 @@ async function processQueue() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
isProcessingQueue = false;
|
isProcessingQueue = false;
|
||||||
|
|
||||||
|
if (isSendingPaused && uploadQueue.length > 0) {
|
||||||
|
addLog(`⏸️ Envio pausado — ${uploadQueue.length} imagem(ns) permanecem na fila.`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Função de Monitoramento da Pasta de Imagens (Chokidar)
|
// Função de Monitoramento da Pasta de Imagens (Chokidar)
|
||||||
|
|||||||
@@ -11,6 +11,54 @@ let currentStatus = { connected: false, identified: false };
|
|||||||
let downloadProgress = null; // Variável para controlar o progresso de download
|
let downloadProgress = null; // Variável para controlar o progresso de download
|
||||||
const recentLogs = [];
|
const recentLogs = [];
|
||||||
|
|
||||||
|
// ================================================================
|
||||||
|
// CONTROLE DE PAUSA DE ENVIO
|
||||||
|
// ================================================================
|
||||||
|
let isSendingPaused = false; // true = envio de imagens pausado
|
||||||
|
let autoResumeTimer = null; // timer que retoma o envio sozinho
|
||||||
|
const AUTO_RESUME_MS = 10 * 60 * 1000; // 10 minutos
|
||||||
|
|
||||||
|
function pauseSending() {
|
||||||
|
isSendingPaused = true;
|
||||||
|
if (monitorProcess) monitorProcess.send({ command: 'pause' });
|
||||||
|
|
||||||
|
// Agenda retomada automática após 10 min, caso o usuário esqueça de continuar
|
||||||
|
if (autoResumeTimer) clearTimeout(autoResumeTimer);
|
||||||
|
autoResumeTimer = setTimeout(() => {
|
||||||
|
addLog('▶️ Auto-retomada: 10 minutos se passaram, retomando envio automaticamente.');
|
||||||
|
resumeSending(true);
|
||||||
|
}, AUTO_RESUME_MS);
|
||||||
|
|
||||||
|
if (tray) {
|
||||||
|
tray.displayBalloon({
|
||||||
|
title: 'ScoreOdonto - Envio Pausado',
|
||||||
|
content: 'O envio de imagens foi pausado. Ele será retomado automaticamente em 10 minutos se você não continuar antes.',
|
||||||
|
iconType: 'warning'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
updateTrayMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
function resumeSending(isAuto = false) {
|
||||||
|
isSendingPaused = false;
|
||||||
|
if (autoResumeTimer) { clearTimeout(autoResumeTimer); autoResumeTimer = null; }
|
||||||
|
if (monitorProcess) monitorProcess.send({ command: 'resume' });
|
||||||
|
|
||||||
|
if (tray && !isAuto) {
|
||||||
|
tray.displayBalloon({
|
||||||
|
title: 'ScoreOdonto - Envio Retomado',
|
||||||
|
content: 'O envio de imagens foi retomado.',
|
||||||
|
iconType: 'info'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
updateTrayMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleSending() {
|
||||||
|
if (isSendingPaused) resumeSending(false);
|
||||||
|
else pauseSending();
|
||||||
|
}
|
||||||
|
|
||||||
// ================================================================
|
// ================================================================
|
||||||
// AUTO-UPDATER CONFIG
|
// AUTO-UPDATER CONFIG
|
||||||
// ================================================================
|
// ================================================================
|
||||||
@@ -255,9 +303,23 @@ function updateTrayMenu(countdown = null, countdownInterval = null, updateVersio
|
|||||||
}
|
}
|
||||||
|
|
||||||
template.push(
|
template.push(
|
||||||
|
{
|
||||||
|
label: isSendingPaused ? '⏸️ Envio PAUSADO (retoma em ~10 min)' : '▶️ Envio Ativo',
|
||||||
|
enabled: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Pausar Envio de Imagens',
|
||||||
|
type: 'checkbox',
|
||||||
|
checked: isSendingPaused,
|
||||||
|
click: () => toggleSending()
|
||||||
|
},
|
||||||
|
{ type: 'separator' },
|
||||||
{
|
{
|
||||||
label: 'Forçar Sincronização 🔄',
|
label: 'Forçar Sincronização 🔄',
|
||||||
click: () => {
|
click: () => {
|
||||||
|
if (isSendingPaused) {
|
||||||
|
resumeSending(false);
|
||||||
|
}
|
||||||
if (monitorProcess) {
|
if (monitorProcess) {
|
||||||
monitorProcess.send({ command: 'sync' });
|
monitorProcess.send({ command: 'sync' });
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "rx.scoreodonto.com-client",
|
"name": "rx.scoreodonto.com-client",
|
||||||
"version": "1.2.7",
|
"version": "1.2.8",
|
||||||
"author": "ScoreOdonto",
|
"author": "ScoreOdonto",
|
||||||
"description": "Cliente Windows para envio de imagens dentais da ScoreOdonto",
|
"description": "Cliente Windows para envio de imagens dentais da ScoreOdonto",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
|
|||||||
Reference in New Issue
Block a user