n0mbers/src/components/OperationsList.vue
2022-02-12 14:12:55 +01:00

104 lines
2.9 KiB
Vue

<template>
<TransitionGroup name="slide_up">
<div
class="mb-2 text-center"
v-for="(op, i) in operations"
:style="{ transitionDelay: `${transDelay * (operations.length - i)}ms` }"
:key="i">
<div class="inline-block relative text-xl">
<!-- OPERATION -->
<div
class="flex items-center"
:class="{ 'text-red-600': isOperationInvalid(op) }">
<!-- LEFT -->
<div class="w-[2.5em] border-b border-stone-600 transition-all">
{{ op.left?.value ?? '&nbsp;' }}
</div>
<!-- RIGHT -->
<div class="w-[2.5em] border-b border-stone-600 transition-all">
{{ op.operator ?? '&nbsp;' }}
</div>
<div class="w-[2.5em] border-b border-stone-600 transition-all">
{{ op.right?.value ?? '&nbsp;' }}
</div>
<!-- EQUALS -->
<div class="mx-4 border-none">
=
</div>
<!-- RESULT -->
<PlaquetteBox
:dynamic-size="true"
class="w-[3.2em] h-8 border-none">
<IconSad v-if="isOperationInvalid(op)" />
<span
v-else-if="
op.operator && op.left && op.right && isOperationResultValid(op)
">
{{ operate(op.operator, op.left.value, op.right.value) }}
</span>
<span v-else>?</span>
</PlaquetteBox>
<!-- UNDO -->
<button
class="ml-8"
@click="undoOperation(i)">
<IconUndo
class="text-stone-400"
:class="{
invisible: !canOperationBeDeleted(op),
}" />
</button>
</div>
</div>
</div>
</TransitionGroup>
</template>
<script setup lang="ts">
import {
getEmptyOperation,
isOperationInvalid,
isOperationResultValid,
operate,
} from '@/algo'
import { GameState, gameState } from '@/globals'
import { operations, plaquettes } from '@/store'
import { Operation } from '@/types'
import IconSad from '~icons/bx/bx-sad'
import IconUndo from '~icons/bx/bx-undo'
import PlaquetteBox from './common/PlaquetteBox.vue'
const transDelay = 100
function canOperationBeDeleted(op: Operation): boolean {
return !!op.left || !!op.right || !!op.operator
}
function undoOperation(index: number): void {
if (gameState.value !== GameState.Playing) return
const l = operations.length
for (let i = operations.length - 1; i >= index; --i) {
let popped: Operation
if (i === index) {
popped = operations[index]
setTimeout(() => {
operations[index] = getEmptyOperation()
}, transDelay * l)
}
else {
popped = operations.pop()!
}
if (popped?.left) popped.left.free = true
if (popped?.right) popped.right.free = true
if (popped.result) {
plaquettes.value = plaquettes.value.filter(p => p !== popped.result)
}
}
}
</script>