|
|
@ -54,160 +54,152 @@ |
|
|
</template> |
|
|
</template> |
|
|
|
|
|
|
|
|
<script> |
|
|
<script> |
|
|
import { mapState } from 'pinia'; |
|
|
import { mapState } from 'pinia' |
|
|
import { usePainelStore } from '@/__apps/painel/store/painelStore'; |
|
|
import { usePainelStore } from '@/__apps/painel/store/painelStore' |
|
|
import Cronometro from './Cronometro.vue'; |
|
|
import Cronometro from './Cronometro.vue' |
|
|
|
|
|
|
|
|
// Mapa: key do cronômetro → ref do componente filho |
|
|
export default { |
|
|
const CRONOMETRO_REFS = [ |
|
|
name: 'CronometroList', |
|
|
{ key: 'discurso', ref: 'childRef_0' }, |
|
|
components: { |
|
|
{ key: 'aparte', ref: 'childRef_1' }, |
|
|
Cronometro |
|
|
{ key: 'ordem', ref: 'childRef_2' }, |
|
|
}, |
|
|
{ key: 'consideracoes', ref: 'childRef_3' }, |
|
|
data () { |
|
|
]; |
|
|
return { |
|
|
|
|
|
// Qual cronômetro está visível no momento. |
|
|
|
|
|
// Regra de prioridade ao rodar: ordem > aparte > consideracoes > discurso. |
|
|
|
|
|
// Quando nenhum está rodando: mantém o último visível (para mostrar |
|
|
|
|
|
// o tempo "parado" do cronômetro que acabou de ser parado). |
|
|
|
|
|
visibleCronometro: 'discurso', |
|
|
|
|
|
childrenMounted: 0, |
|
|
|
|
|
allChildrenMounted: false |
|
|
|
|
|
} |
|
|
|
|
|
}, |
|
|
|
|
|
mounted () { |
|
|
|
|
|
console.log('CronometroList mounted') |
|
|
|
|
|
// Os filhos podem não ter montado ainda — aplica via nextTick após |
|
|
|
|
|
// todos os filhos emitirem 'child-mounted' (ver handleChildMounted). |
|
|
|
|
|
}, |
|
|
|
|
|
computed: { |
|
|
|
|
|
...mapState(usePainelStore, [ |
|
|
|
|
|
'canRender', |
|
|
|
|
|
'cronometro_ativo', |
|
|
|
|
|
'cronometro_discurso', 'cronometro_aparte', |
|
|
|
|
|
'cronometro_ordem', 'cronometro_consideracoes' |
|
|
|
|
|
]) |
|
|
|
|
|
}, |
|
|
|
|
|
watch: { |
|
|
|
|
|
// Quando o painel abre (canRender muda para true), os filhos |
|
|
|
|
|
// acabam de montar — aplica o estado inicial de todos. |
|
|
|
|
|
canRender (newVal) { |
|
|
|
|
|
if (newVal) { |
|
|
|
|
|
this.$nextTick(() => this.applyAllStates()) |
|
|
|
|
|
} |
|
|
|
|
|
}, |
|
|
|
|
|
|
|
|
export default { |
|
|
cronometro_ativo (newVal) { |
|
|
name: 'CronometroList', |
|
|
if (newVal) { |
|
|
components: { |
|
|
this.updateVisibility() |
|
|
Cronometro, |
|
|
} |
|
|
}, |
|
|
}, |
|
|
data() { |
|
|
|
|
|
return { |
|
|
|
|
|
// Qual cronômetro está visível no momento. |
|
|
|
|
|
// Regra de prioridade ao rodar: ordem > aparte > consideracoes > discurso. |
|
|
|
|
|
// Quando nenhum está rodando: mantém o último visível (para mostrar |
|
|
|
|
|
// o tempo "parado" do cronômetro que acabou de ser parado). |
|
|
|
|
|
visibleCronometro: 'discurso', |
|
|
|
|
|
childrenMounted: 0, |
|
|
|
|
|
allChildrenMounted: false, |
|
|
|
|
|
} |
|
|
|
|
|
}, |
|
|
|
|
|
mounted() { |
|
|
|
|
|
console.log('CronometroList mounted'); |
|
|
|
|
|
// Os filhos podem não ter montado ainda — aplica via nextTick após |
|
|
|
|
|
// todos os filhos emitirem 'child-mounted' (ver handleChildMounted). |
|
|
|
|
|
}, |
|
|
|
|
|
computed: { |
|
|
|
|
|
...mapState(usePainelStore, [ |
|
|
|
|
|
"canRender", |
|
|
|
|
|
"cronometro_ativo", |
|
|
|
|
|
"cronometro_discurso", "cronometro_aparte", |
|
|
|
|
|
"cronometro_ordem", "cronometro_consideracoes" |
|
|
|
|
|
]) |
|
|
|
|
|
}, |
|
|
|
|
|
watch: { |
|
|
|
|
|
// Quando o painel abre (canRender muda para true), os filhos |
|
|
|
|
|
// acabam de montar — aplica o estado inicial de todos. |
|
|
|
|
|
canRender(newVal) { |
|
|
|
|
|
if (newVal) { |
|
|
|
|
|
this.$nextTick(() => this.applyAllStates()); |
|
|
|
|
|
} |
|
|
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
cronometro_ativo(newVal) { |
|
|
// Watchers profundos para cada cronômetro: disparam quando o objeto |
|
|
if (newVal) { |
|
|
// mudar (nova action, duration, etc.) mas NÃO quando o broadcast |
|
|
this.updateVisibility(); |
|
|
// chega com o mesmo valor (deep watch compara referência, mas o |
|
|
} |
|
|
// store substitui o objeto inteiro — a comparação de ação é feita |
|
|
}, |
|
|
// dentro de applyState do filho para ser idempotente). |
|
|
|
|
|
cronometro_discurso (newVal) { |
|
|
// Watchers profundos para cada cronômetro: disparam quando o objeto |
|
|
this.applyOneState('childRef_0', newVal) |
|
|
// mudar (nova action, duration, etc.) mas NÃO quando o broadcast |
|
|
}, |
|
|
// chega com o mesmo valor (deep watch compara referência, mas o |
|
|
cronometro_aparte (newVal) { |
|
|
// store substitui o objeto inteiro — a comparação de ação é feita |
|
|
this.applyOneState('childRef_1', newVal) |
|
|
// dentro de applyState do filho para ser idempotente). |
|
|
}, |
|
|
cronometro_discurso(newVal) { |
|
|
cronometro_ordem (newVal) { |
|
|
this.applyOneState('childRef_0', newVal); |
|
|
this.applyOneState('childRef_2', newVal) |
|
|
}, |
|
|
}, |
|
|
cronometro_aparte(newVal) { |
|
|
cronometro_consideracoes (newVal) { |
|
|
this.applyOneState('childRef_1', newVal); |
|
|
this.applyOneState('childRef_3', newVal) |
|
|
}, |
|
|
} |
|
|
cronometro_ordem(newVal) { |
|
|
}, |
|
|
this.applyOneState('childRef_2', newVal); |
|
|
methods: { |
|
|
}, |
|
|
/** |
|
|
cronometro_consideracoes(newVal) { |
|
|
|
|
|
this.applyOneState('childRef_3', newVal); |
|
|
|
|
|
}, |
|
|
|
|
|
}, |
|
|
|
|
|
methods: { |
|
|
|
|
|
/** |
|
|
|
|
|
* Aplica o estado de todos os cronômetros de uma vez. |
|
|
* Aplica o estado de todos os cronômetros de uma vez. |
|
|
* Usado na montagem e quando o painel é aberto. |
|
|
* Usado na montagem e quando o painel é aberto. |
|
|
*/ |
|
|
*/ |
|
|
applyAllStates() { |
|
|
applyAllStates () { |
|
|
this.applyOneState('childRef_0', this.cronometro_discurso); |
|
|
this.applyOneState('childRef_0', this.cronometro_discurso) |
|
|
this.applyOneState('childRef_1', this.cronometro_aparte); |
|
|
this.applyOneState('childRef_1', this.cronometro_aparte) |
|
|
this.applyOneState('childRef_2', this.cronometro_ordem); |
|
|
this.applyOneState('childRef_2', this.cronometro_ordem) |
|
|
this.applyOneState('childRef_3', this.cronometro_consideracoes); |
|
|
this.applyOneState('childRef_3', this.cronometro_consideracoes) |
|
|
this.updateVisibility(); |
|
|
this.updateVisibility() |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* Aplica o estado de um único cronômetro chamando applyState() no filho. |
|
|
* Aplica o estado de um único cronômetro chamando applyState() no filho. |
|
|
* @param {string} refName - nome do ref ('childRef_0' etc.) |
|
|
* @param {string} refName - nome do ref ('childRef_0' etc.) |
|
|
* @param {Object|null} state - { action, duration, start_ts?, remaining_at_stop? } |
|
|
* @param {Object|null} state - { action, duration, start_ts?, remaining_at_stop? } |
|
|
*/ |
|
|
*/ |
|
|
applyOneState(refName, state) { |
|
|
applyOneState (refName, state) { |
|
|
const comp = this.$refs[refName]; |
|
|
const comp = this.$refs[refName] |
|
|
if (!comp) return; |
|
|
if (!comp) return |
|
|
comp.applyState(state); |
|
|
comp.applyState(state) |
|
|
this.updateVisibility(); |
|
|
this.updateVisibility() |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* Chamado quando um filho monta. Quando todos os 4 filhos |
|
|
* Chamado quando um filho monta. Quando todos os 4 filhos |
|
|
* montaram, aplica o estado inicial. |
|
|
* montaram, aplica o estado inicial. |
|
|
*/ |
|
|
*/ |
|
|
handleChildMounted() { |
|
|
handleChildMounted () { |
|
|
this.childrenMounted++; |
|
|
this.childrenMounted++ |
|
|
console.log(`Cronometro child mounted (${this.childrenMounted}/4)`); |
|
|
console.log(`Cronometro child mounted (${this.childrenMounted}/4)`) |
|
|
if (this.childrenMounted >= 4) { |
|
|
if (this.childrenMounted >= 4) { |
|
|
this.allChildrenMounted = true; |
|
|
this.allChildrenMounted = true |
|
|
this.applyAllStates(); |
|
|
this.applyAllStates() |
|
|
} |
|
|
} |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* Chamado quando um filho muda de estado (start/stop). |
|
|
* Chamado quando um filho muda de estado (start/stop). |
|
|
* Atualiza a visibilidade. |
|
|
* Atualiza a visibilidade. |
|
|
*/ |
|
|
*/ |
|
|
handleStateChanged() { |
|
|
handleStateChanged () { |
|
|
this.updateVisibility(); |
|
|
this.updateVisibility() |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* Decide qual cronômetro mostrar. |
|
|
* Decide qual cronômetro mostrar. |
|
|
* |
|
|
* |
|
|
* Prioridade ao rodar: ordem > aparte > consideracoes > discurso. |
|
|
* Prioridade ao rodar: ordem > aparte > consideracoes > discurso. |
|
|
* Se nenhum estiver rodando, mantém o último visível para exibir |
|
|
* Se nenhum estiver rodando, mantém o último visível para exibir |
|
|
* o tempo no momento em que foi parado (comportamento igual ao discurso). |
|
|
* o tempo no momento em que foi parado (comportamento igual ao discurso). |
|
|
*/ |
|
|
*/ |
|
|
updateVisibility() { |
|
|
updateVisibility () { |
|
|
// Prioridade 1: se algum cronômetro estiver rodando, mostra o que está rodando |
|
|
// Prioridade 1: se algum cronômetro estiver rodando, mostra o que está rodando |
|
|
const priority = [ |
|
|
const priority = [ |
|
|
{ key: 'ordem', ref: 'childRef_2' }, |
|
|
{ key: 'ordem', ref: 'childRef_2' }, |
|
|
{ key: 'aparte', ref: 'childRef_1' }, |
|
|
{ key: 'aparte', ref: 'childRef_1' }, |
|
|
{ key: 'consideracoes', ref: 'childRef_3' }, |
|
|
{ key: 'consideracoes', ref: 'childRef_3' }, |
|
|
{ key: 'discurso', ref: 'childRef_0' }, |
|
|
{ key: 'discurso', ref: 'childRef_0' } |
|
|
]; |
|
|
] |
|
|
for (const item of priority) { |
|
|
for (const item of priority) { |
|
|
const comp = this.$refs[item.ref]; |
|
|
const comp = this.$refs[item.ref] |
|
|
if (comp && comp.isRunning) { |
|
|
if (comp && comp.isRunning) { |
|
|
this.visibleCronometro = item.key; |
|
|
this.visibleCronometro = item.key |
|
|
return; |
|
|
return |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Prioridade 2: nenhum rodando. Mostra o último cronômetro operado pelo operador |
|
|
// Prioridade 2: nenhum rodando. Mostra o último cronômetro operado pelo operador |
|
|
if (this.cronometro_ativo) { |
|
|
if (this.cronometro_ativo) { |
|
|
this.visibleCronometro = this.cronometro_ativo; |
|
|
this.visibleCronometro = this.cronometro_ativo |
|
|
return; |
|
|
return |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Fallback padrão |
|
|
// Fallback padrão |
|
|
this.visibleCronometro = 'discurso'; |
|
|
this.visibleCronometro = 'discurso' |
|
|
} |
|
|
} |
|
|
}, |
|
|
} |
|
|
}; |
|
|
} |
|
|
</script> |
|
|
</script> |
|
|
|
|
|
|
|
|
<style scoped> |
|
|
<style scoped> |
|
|
|