[35716] | 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 | <div class="text-container">
|
---|
| 6 | {{ output }}
|
---|
| 7 | </div>
|
---|
[35718] | 8 |
|
---|
| 9 | <button class="btn-primary right-column" :disabled="!canDownload" @click="downloadAsText">Download</button>
|
---|
[35716] | 10 | </div>
|
---|
| 11 | </template>
|
---|
| 12 |
|
---|
| 13 | <style scoped lang="scss">
|
---|
| 14 | .root {
|
---|
| 15 | display: grid;
|
---|
| 16 | grid-template-columns: 1fr 1fr;
|
---|
[35718] | 17 | grid-template-rows: auto auto;
|
---|
[35716] | 18 | gap: 1em;
|
---|
| 19 | }
|
---|
| 20 |
|
---|
| 21 | .input-area {
|
---|
| 22 | resize: none;
|
---|
| 23 | min-height: 4em;
|
---|
| 24 | overflow: hidden;
|
---|
| 25 | }
|
---|
[35718] | 26 |
|
---|
| 27 | .right-column {
|
---|
| 28 | grid-column: 2;
|
---|
| 29 | }
|
---|
[35716] | 30 | </style>
|
---|
| 31 |
|
---|
| 32 | <script>
|
---|
| 33 | import { mapState } from "vuex";
|
---|
[35718] | 34 | import { saveAs } from "file-saver"
|
---|
[35716] | 35 | import MacronRestorationModule from "../js/MacronRestorationModule"
|
---|
| 36 |
|
---|
| 37 | const macroniser = new MacronRestorationModule();
|
---|
| 38 |
|
---|
| 39 | export default {
|
---|
| 40 | name: "DirectInput",
|
---|
| 41 | data() {
|
---|
| 42 | return {
|
---|
| 43 | input: "",
|
---|
| 44 | output: "",
|
---|
[35718] | 45 | transcribeTimeout: null,
|
---|
| 46 | waitingOnTranscribe: false
|
---|
[35716] | 47 | }
|
---|
| 48 | },
|
---|
| 49 | computed: {
|
---|
[35718] | 50 | canDownload() {
|
---|
| 51 | return this.output.length > 0 && !this.waitingOnTranscribe;
|
---|
| 52 | },
|
---|
[35716] | 53 | ...mapState({
|
---|
| 54 | translations: state => state.translations
|
---|
| 55 | })
|
---|
| 56 | },
|
---|
| 57 | watch: {
|
---|
| 58 | input() {
|
---|
[35718] | 59 | this.waitingOnTranscribe = true;
|
---|
| 60 |
|
---|
[35716] | 61 | if (this.transcribeTimeout !== null) {
|
---|
| 62 | clearTimeout(this.transcribeTimeout);
|
---|
| 63 | }
|
---|
| 64 |
|
---|
| 65 | this.transcribeTimeout = setTimeout(this.updateMacronisedText, 1000);
|
---|
| 66 | }
|
---|
| 67 | },
|
---|
| 68 | methods: {
|
---|
| 69 | /**
|
---|
| 70 | * Handles input on an element, and grows its height so that the text is always visible.
|
---|
| 71 | * @param {InputEvent} event The input event.
|
---|
| 72 | */
|
---|
| 73 | onTextInput(event) {
|
---|
| 74 | event.target.height = event.target.scrollHeight;
|
---|
| 75 | },
|
---|
| 76 | async updateMacronisedText() {
|
---|
[35718] | 77 | // TODO: Handle error
|
---|
[35716] | 78 | const response = await macroniser.directMacronisation(this.input);
|
---|
| 79 | this.output = response.fragment2;
|
---|
[35718] | 80 | this.waitingOnTranscribe = false;
|
---|
| 81 | },
|
---|
| 82 | downloadAsText() {
|
---|
| 83 | const blob = new Blob([ this.output ], { type: "text/plain;charset=utf-8" });
|
---|
| 84 | saveAs(blob, "output.txt");
|
---|
[35716] | 85 | }
|
---|
| 86 | }
|
---|
| 87 | }
|
---|
| 88 | </script>
|
---|