Ajustes gerais #64
@@ -9,12 +9,21 @@
|
|||||||
|
|
||||||
let tempoAtual = $state<Date>(new Date());
|
let tempoAtual = $state<Date>(new Date());
|
||||||
let sincronizado = $state(false);
|
let sincronizado = $state(false);
|
||||||
|
let sincronizando = $state(false);
|
||||||
let usandoServidorExterno = $state(false);
|
let usandoServidorExterno = $state(false);
|
||||||
let offsetSegundos = $state(0);
|
let offsetSegundos = $state(0);
|
||||||
let erro = $state<string | null>(null);
|
let erro = $state<string | null>(null);
|
||||||
let intervalId: ReturnType<typeof setInterval> | null = null;
|
let intervalId: ReturnType<typeof setInterval> | null = null;
|
||||||
|
let intervaloSincronizacao: ReturnType<typeof setInterval> | null = null;
|
||||||
|
let sincronizacaoEmAndamento = $state(false); // Flag para evitar múltiplas sincronizações simultâneas
|
||||||
|
|
||||||
async function atualizarTempo() {
|
async function atualizarTempo() {
|
||||||
|
// Evitar múltiplas sincronizações simultâneas
|
||||||
|
if (sincronizacaoEmAndamento) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sincronizacaoEmAndamento = true;
|
||||||
|
sincronizando = true;
|
||||||
try {
|
try {
|
||||||
const config = await client.query(api.configuracaoRelogio.obterConfiguracao, {});
|
const config = await client.query(api.configuracaoRelogio.obterConfiguracao, {});
|
||||||
// Usar gmtOffset da configuração, sem valor padrão, pois 0 é um valor válido
|
// Usar gmtOffset da configuração, sem valor padrão, pois 0 é um valor válido
|
||||||
@@ -25,7 +34,12 @@
|
|||||||
|
|
||||||
if (config.usarServidorExterno) {
|
if (config.usarServidorExterno) {
|
||||||
try {
|
try {
|
||||||
const resultado = await client.action(api.configuracaoRelogio.sincronizarTempo, {});
|
// Adicionar timeout de 10 segundos para sincronização
|
||||||
|
const sincronizacaoPromise = client.action(api.configuracaoRelogio.sincronizarTempo, {});
|
||||||
|
const timeoutPromise = new Promise<never>((_, reject) =>
|
||||||
|
setTimeout(() => reject(new Error('Timeout na sincronização (10s)')), 10000)
|
||||||
|
);
|
||||||
|
const resultado = await Promise.race([sincronizacaoPromise, timeoutPromise]);
|
||||||
if (resultado.sucesso && resultado.timestamp) {
|
if (resultado.sucesso && resultado.timestamp) {
|
||||||
timestampBase = resultado.timestamp;
|
timestampBase = resultado.timestamp;
|
||||||
sincronizado = true;
|
sincronizado = true;
|
||||||
@@ -43,7 +57,11 @@
|
|||||||
usandoServidorExterno = false;
|
usandoServidorExterno = false;
|
||||||
erro = 'Usando relógio do PC (falha na sincronização)';
|
erro = 'Usando relógio do PC (falha na sincronização)';
|
||||||
} else {
|
} else {
|
||||||
throw error;
|
// Mesmo sem fallback configurado, usar PC como última opção
|
||||||
|
timestampBase = obterTempoPC();
|
||||||
|
sincronizado = false;
|
||||||
|
usandoServidorExterno = false;
|
||||||
|
erro = 'Usando relógio do PC (servidor indisponível)';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -71,6 +89,9 @@
|
|||||||
tempoAtual = new Date(obterTempoPC());
|
tempoAtual = new Date(obterTempoPC());
|
||||||
sincronizado = false;
|
sincronizado = false;
|
||||||
erro = 'Erro ao obter tempo do servidor';
|
erro = 'Erro ao obter tempo do servidor';
|
||||||
|
} finally {
|
||||||
|
sincronizando = false;
|
||||||
|
sincronizacaoEmAndamento = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,17 +102,34 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
await atualizarTempo();
|
// Inicializar com relógio do PC imediatamente para não bloquear a interface
|
||||||
// Sincronizar a cada 30 segundos
|
tempoAtual = new Date(obterTempoPC());
|
||||||
setInterval(atualizarTempo, 30000);
|
sincronizado = false;
|
||||||
|
erro = 'Usando relógio do PC';
|
||||||
// Atualizar display a cada segundo
|
// Atualizar display a cada segundo
|
||||||
intervalId = setInterval(atualizarRelogio, 1000);
|
intervalId = setInterval(atualizarRelogio, 1000);
|
||||||
|
// Sincronizar em background (não bloquear) após um pequeno delay para garantir que a UI está renderizada
|
||||||
|
setTimeout(() => {
|
||||||
|
atualizarTempo().catch((error) => {
|
||||||
|
console.error('Erro ao sincronizar tempo em background:', error);
|
||||||
|
});
|
||||||
|
}, 100);
|
||||||
|
// Sincronizar a cada 30 segundos
|
||||||
|
intervaloSincronizacao = setInterval(() => {
|
||||||
|
atualizarTempo().catch((error) => {
|
||||||
|
console.error('Erro ao sincronizar tempo periódico:', error);
|
||||||
|
});
|
||||||
|
}, 30000);
|
||||||
});
|
});
|
||||||
|
|
||||||
onDestroy(() => {
|
onDestroy(() => {
|
||||||
if (intervalId) {
|
if (intervalId) {
|
||||||
clearInterval(intervalId);
|
clearInterval(intervalId);
|
||||||
}
|
}
|
||||||
|
if (intervaloSincronizacao) {
|
||||||
|
clearInterval(intervaloSincronizacao);
|
||||||
|
}
|
||||||
|
sincronizacaoEmAndamento = false;
|
||||||
});
|
});
|
||||||
|
|
||||||
const horaFormatada = $derived.by(() => {
|
const horaFormatada = $derived.by(() => {
|
||||||
@@ -131,13 +169,18 @@
|
|||||||
|
|
||||||
<!-- Status de Sincronização -->
|
<!-- Status de Sincronização -->
|
||||||
<div
|
<div
|
||||||
class="flex items-center gap-2 rounded-full px-4 py-2 {sincronizado
|
class="flex items-center gap-2 rounded-full px-4 py-2 {sincronizando
|
||||||
|
? 'bg-info/20 text-info border-info/30 border animate-pulse'
|
||||||
|
: sincronizado
|
||||||
? 'bg-success/20 text-success border-success/30 border'
|
? 'bg-success/20 text-success border-success/30 border'
|
||||||
: erro
|
: erro
|
||||||
? 'bg-warning/20 text-warning border-warning/30 border'
|
? 'bg-warning/20 text-warning border-warning/30 border'
|
||||||
: 'bg-base-300/50 text-base-content/60 border-base-300 border'}"
|
: 'bg-base-300/50 text-base-content/60 border-base-300 border'}"
|
||||||
>
|
>
|
||||||
{#if sincronizado}
|
{#if sincronizando}
|
||||||
|
<span class="loading loading-spinner loading-sm text-info"></span>
|
||||||
|
<span class="text-sm font-semibold">Sincronizando com servidor...</span>
|
||||||
|
{:else if sincronizado}
|
||||||
<CheckCircle2 class="h-4 w-4" strokeWidth={2.5} />
|
<CheckCircle2 class="h-4 w-4" strokeWidth={2.5} />
|
||||||
<span class="text-sm font-semibold">
|
<span class="text-sm font-semibold">
|
||||||
{#if usandoServidorExterno}
|
{#if usandoServidorExterno}
|
||||||
|
|||||||
Reference in New Issue
Block a user