ASCIInator/src/App.vue

100 lines
2.5 KiB
Vue
Raw Normal View History

<script setup>
import { reactive, ref } from 'vue'
import ImageInput from './components/ImageInput.vue'
import ToolSelector from './components/ToolSelector.vue'
import ShellBridge from './components/ShellBridge.vue'
import OutputDisplay from './components/OutputDisplay.vue'
import ErrorLog from './components/ErrorLog.vue'
const state = reactive({
image: null,
toolConfig: { tool: 'chafa', flags: {} },
result: '',
errors: [],
isConverting: false,
})
const bridge = ref(null)
function addError(message, source = 'error') {
state.errors.push({
timestamp: new Date().toLocaleTimeString(),
source,
message,
})
}
async function runConvert() {
if (!state.image) {
addError('No image selected.', 'warn')
return
}
state.isConverting = true
state.result = ''
try {
await bridge.value.convert()
} finally {
state.isConverting = false
}
}
function onResult(text) {
state.result = text
}
function onError(message) {
addError(message)
}
</script>
<template>
<div class="min-h-screen pb-20" style="background-color: var(--ascii-bg)">
<header class="px-6 py-4 border-b" style="border-color: var(--ascii-border)">
<h1
class="text-lg font-semibold tracking-widest font-mono"
style="color: var(--ascii-green)"
>
ASCIInator
</h1>
</header>
<main class="max-w-5xl mx-auto px-6 py-8 flex flex-col gap-8">
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<section>
<h2 class="text-xs font-medium uppercase tracking-wider mb-3"
style="color: rgba(224,224,224,.35)">Image</h2>
<ImageInput @image-ready="state.image = $event" />
</section>
<section>
<h2 class="text-xs font-medium uppercase tracking-wider mb-3"
style="color: rgba(224,224,224,.35)">Tool &amp; Options</h2>
<ToolSelector @tool-config="state.toolConfig = $event" />
</section>
</div>
<div class="flex justify-center">
<button
class="ascii-btn-primary"
:disabled="state.isConverting || !state.image"
@click="runConvert"
>
{{ state.isConverting ? 'Converting...' : 'Convert' }}
</button>
</div>
<ShellBridge
ref="bridge"
:image="state.image"
:tool-config="state.toolConfig"
@conversion-result="onResult"
@conversion-error="onError"
/>
<OutputDisplay :result="state.result" />
</main>
<ErrorLog :errors="state.errors" @clear="state.errors = []" />
</div>
</template>