source: main/trunk/model-interfaces-dev/atea/macron-restoration/src/components/DirectInput.vue@ 35726

Last change on this file since 35726 was 35726, checked in by cstephen, 13 months ago

Allow PowerPoint files to be submitted

File size: 4.1 KB
Line 
1<template>
2<div class="root">
3 <textarea class="text-input input-area" @input="onTextInput"
4 v-model="input" :placeholder="translations.get('DirectInput_InputPlaceholder')" />
5
6 <div class="text-container">
7 <span v-if="errorState" class="material-icons mdi-m error-text">error</span>
8 <span v-if="errorState" class="error-text">Something went wrong! Please try modifying your input text.</span>
9
10 <!-- eslint-disable-next-line vue/require-v-for-key -->
11 <span v-for="word in validRestored" :class="{ 'highlight': word.macronised && this.showMacronisedWords }">{{ word.w }}&nbsp;</span>
12 </div>
13
14 <div class="flex">
15 <input type="checkbox" id="i-preserve-existing-macrons" v-model="preserveExistingMacrons" />
16 <label for="i-preserve-existing-macrons">{{ translations.get('DirectInput_PreserveExistingMacrons') }}</label>
17 </div>
18
19 <div class="flex">
20 <input type="checkbox" id="i-show-macronised-words" v-model="showMacronisedWords" />
21 <label for="i-show-macronised-words">{{ translations.get('DirectInput_ShowMacronisedWords') }}</label>
22 </div>
23
24 <button class="btn-primary right-column" :disabled="!canDownload" @click="downloadAsText">{{ translations.get('DirectInput_Download') }}</button>
25</div>
26</template>
27
28<style scoped lang="scss">
29.root {
30 display: grid;
31 grid-template-columns: 1fr 1fr;
32 gap: 1em;
33}
34
35.input-area {
36 resize: none;
37 min-height: 4em;
38 overflow: hidden;
39}
40
41.flex {
42 display: flex;
43 align-items: center;
44 gap: 0.5em;
45}
46
47.right-column {
48 grid-column: 2;
49}
50
51.highlight {
52 background-color: var(--highlighted-word-bg);
53}
54
55.error-text {
56 color: rgb(185, 3, 3);
57}
58</style>
59
60<script>
61import { mapState } from "vuex";
62import { saveAs } from "file-saver"
63import { log } from "../js/Util"
64import MacronRestorationModule from "../js/MacronRestorationModule"
65
66const macroniser = new MacronRestorationModule();
67
68export default {
69 name: "DirectInput",
70 data() {
71 return {
72 preserveExistingMacrons: true,
73 showMacronisedWords: false,
74 transcribeTimeout: null,
75 waitingOnTranscribe: false,
76 errorState: false
77 }
78 },
79 computed: {
80 canDownload() {
81 return this.restored !== null && !this.waitingOnTranscribe;
82 },
83 input: {
84 get() {
85 return this.$store.state.directInput;
86 },
87 set(newValue) {
88 this.$store.commit("setDirectInput", newValue);
89 }
90 },
91 restored: {
92 get() {
93 return this.$store.state.directOutput;
94 },
95 set(newValue) {
96 this.$store.commit("setDirectOutput", newValue);
97 }
98 },
99 validRestored() {
100 return this.restored.filter(w => w.w !== "");
101 },
102 ...mapState({
103 translations: state => state.translations
104 })
105 },
106 watch: {
107 input() {
108 this.waitingOnTranscribe = true;
109
110 if (this.transcribeTimeout !== null) {
111 clearTimeout(this.transcribeTimeout);
112 }
113
114 this.transcribeTimeout = setTimeout(this.updateMacronisedText, 1000);
115 }
116 },
117 methods: {
118 /**
119 * Handles input on an element, and grows its height so that the text is always visible.
120 * @param {InputEvent} event The input event.
121 */
122 onTextInput(event) {
123 event.target.height = "auto";
124 event.target.height = event.target.scrollHeight;
125 },
126 async updateMacronisedText() {
127 this.errorState = false;
128
129 try {
130 this.restored = await macroniser.directMacronisation(this.input, this.preserveExistingMacrons);
131 this.waitingOnTranscribe = false;
132 }
133 catch (ex) {
134 this.errorState = true;
135 log(ex, "warn");
136 }
137 },
138 downloadAsText() {
139 const blob = new Blob([ this.restored ], { type: "text/plain;charset=utf-8" });
140 saveAs(blob, "restored.txt");
141 }
142 }
143}
144</script>
Note: See TracBrowser for help on using the repository browser.