Files
STARTLINER/src/components/FileEditor.vue
2025-04-18 15:00:52 +00:00

122 lines
2.8 KiB
Vue

<script setup lang="ts">
import { ref } from 'vue';
import Button from 'primevue/button';
import * as path from '@tauri-apps/api/path';
import { open } from '@tauri-apps/plugin-dialog';
import { readTextFile, writeTextFile } from '@tauri-apps/plugin-fs';
import { usePrfStore } from '../stores';
const prf = usePrfStore();
const props = defineProps({
filename: String,
promptname: String,
extension: String,
});
const exists = ref(false);
const contents = ref('');
const enabled = ref(false);
const target_path = ref('');
const load = async (p: string) => {
try {
contents.value = await readTextFile(p);
exists.value = true;
} catch (_) {
exists.value = false;
}
};
const save = async () => {
if (target_path.value.length > 0) {
await writeTextFile(target_path.value, contents.value);
}
};
const filePick = async () => {
const p = await open({
multiple: false,
directory: false,
filters:
props.promptname && props.extension
? [
{
name: props.promptname,
extensions: [props.extension],
},
]
: [],
});
if (p != null) {
await load(p);
await save();
}
};
(async () => {
if (props.filename === undefined) {
throw new Error('FileEditor without a filename');
}
target_path.value = await path.join(await prf.configDir, props.filename);
await load(target_path.value);
})();
</script>
<template>
<Button v-if="!exists" icon="pi pi-plus" size="small" @click="filePick" />
<div class="primitive-base" v-else>
<Button
v-if="exists"
icon="pi pi-pen-to-square"
size="small"
@click="enabled = true"
/>
<div v-if="enabled" class="backdrop">
<textarea
class="primitive-editor"
@vue:mounted="$event.el.focus()"
@input="(event) => (contents = (event.target as any).value)"
@focusout="
save();
enabled = false;
"
>{{ contents }}</textarea
>
</div>
</div>
</template>
<style lang="css">
.backdrop {
position: fixed;
left: 0;
top: 0;
z-index: 900;
width: 100vw;
background-color: rgba(1, 1, 1, 0.7);
height: 100vh;
}
.primitive-editor {
font-family: monospace;
white-space: nowrap;
position: fixed;
top: 50%;
left: 50%;
height: 500px;
width: 800px;
margin-left: -400px;
margin-top: -250px;
z-index: 1000;
padding: 20px;
border-radius: 20px;
background-color: #151515;
color: #ddd;
}
.primitive-base ::-webkit-scrollbar {
display: none;
}
</style>