source: main/trunk/model-interfaces-dev/atea/korero-maori-asr/src/components/TranscriptionItem.vue@ 35432

Last change on this file since 35432 was 35431, checked in by cstephen, 3 years ago

Add app bar and basic information

File size: 6.4 KB
Line 
1<template>
2 <div class="card">
3 <!-- Header containing info and actions for the transcription -->
4 <div class="transcription__header">
5 <button class="btn-fab" v-on:click="playAudio(0)" type="button">
6 <span class="material-icons mdi-l">play_arrow</span>
7 </button>
8
9 <span>{{ translations.get("TranscriptionItem_FileName") }}: {{ transcription.fileName }}</span>
10
11 <div style="position: relative;">
12 <button class="btn-primary" @mouseover="showDownloadOptions = true" @mouseout="showDownloadOptions = false" type="button">
13 <span class="material-icons">download</span>
14 <span>{{ translations.get("TranscriptionItem_Download") }}</span>
15 </button>
16
17 <div class="download-popup card" :class="{ 'download-popup-show': showDownloadOptions }"
18 @mouseover="showDownloadOptions = true" @mouseout="showDownloadOptions = false">
19 <button @click="downloadAsText" type="button" class="btn-primary theme-flat">
20 <span class="material-icons">text_snippet</span>
21 <span>{{ translations.get("TranscriptionItem_DownloadAsText") }}</span>
22 </button>
23
24 <button @click="downloadAsJson" type="button" class="btn-primary theme-flat">
25 <span class="material-icons">integration_instructions</span>
26 <span>{{ translations.get("TranscriptionItem_DownloadAsJson") }}</span>
27 </button>
28
29 <button @click="downloadAsWebvtt" type="button" class="btn-primary theme-flat">
30 <span class="material-icons">subtitles</span>
31 <span>{{ translations.get("TranscriptionItem_DownloadAsWebvtt") }}</span>
32 </button>
33 </div>
34 </div>
35
36 <button class="btn-primary theme-error" @click="remove" type="button">
37 <span class="material-icons">delete</span>
38 <span>{{ translations.get("TranscriptionItem_Remove") }}</span>
39 </button>
40 </div>
41
42 <hr />
43
44 <TranscriptionItemEditor :transcription="transcription" style="margin-bottom: 1em" />
45
46 <button @click="toggleEditor" type="button" class="btn-primary theme-flat">
47 <span class="material-icons expander-toggle" :class="{ 'rotate-180': showEditor }">expand_more</span>
48 <span>{{ translations.get("TranscriptionItem_ExpandEditor") }}</span>
49 </button>
50 </div>
51</template>
52
53<style scoped lang="scss">
54.transcription__header {
55 display: grid;
56 gap: 0.5em 0.5em;
57 grid-template-columns: auto 1fr auto auto;
58 align-items: center;
59}
60
61.download-popup {
62 display: flex;
63 flex-direction: column;
64 align-items: stretch;
65
66 position: absolute;
67 top: 97%;
68 z-index: 2;
69
70 padding: 2px;
71 margin: 0;
72 width: 14em;
73
74 transition-duration: var(--transition-duration);
75 visibility: hidden;
76 opacity: 0;
77}
78
79.download-popup-show {
80 visibility: visible;
81 opacity: 1;
82}
83
84.expander-toggle {
85 transition-duration: 0.4s;
86}
87
88.rotate-180 {
89 transform: rotate(180deg);
90}
91</style>
92
93<script>
94import { mapState } from "vuex";
95import { saveAs } from "file-saver"
96import TranscriptionItemEditor, { getWords } from "./TranscriptionItemEditor.vue"
97import { TranscriptionViewModel, PlaybackState } from "../main";
98import Util from "../js/Util"
99
100export default {
101 name: "TranscriptionItem",
102 components: {
103 TranscriptionItemEditor
104 },
105 props: {
106 transcription: TranscriptionViewModel
107 },
108 data() {
109 return {
110 showEditor: false,
111 showDownloadOptions: false
112 }
113 },
114 computed: mapState({
115 translations: state => state.translations
116 }),
117 methods: {
118 toggleEditor() {
119 this.showEditor = !this.showEditor;
120 },
121 playAudio(startTime = 0) {
122 const pState = new PlaybackState(this.transcription.id, true, startTime);
123 this.$store.commit("setPlaybackState", pState);
124 },
125 remove() {
126 this.$store.commit("transcriptionRemove", this.transcription.id);
127 },
128 downloadAsText() {
129 const fileName = buildDownloadableFileName(this.transcription.fileName, "txt");
130
131 const blob = new Blob([ this.transcription.transcription ], { type: "text/plain;charset=utf-8" });
132 saveAs(blob, fileName);
133 },
134 downloadAsJson() {
135 const fileName = buildDownloadableFileName(this.transcription.fileName, "json");
136 const toDownload = (({ fileName, transcription, metadata }) => ({ fileName, transcription, metadata }))(this.transcription);
137
138 const blob = new Blob([ JSON.stringify(toDownload, null, 4) ], { type: "application/json;charset=utf-8" });
139 saveAs(blob, fileName);
140 },
141 downloadAsWebvtt() {
142 const fileName = buildDownloadableFileName(this.transcription.fileName, "vtt");
143 const toDownload = buildWebvttFileContents(this.transcription);
144
145 const blob = new Blob([ toDownload ], { type: "text/vtt;charset=utf-8" });
146 saveAs(blob, fileName);
147 }
148 }
149}
150
151/**
152 * Builds a file name for a download.
153 * @param {String} transcriptionFileName The name of the transcription that will be downloaded.
154 * @param {String} extension The file extension of the download. Do not include a period.
155 * @returns {String} The file name.
156 */
157function buildDownloadableFileName(transcriptionFileName, extension) {
158 const extensionIndex = transcriptionFileName.lastIndexOf(".");
159 let fileName = transcriptionFileName.slice(0, extensionIndex);
160 fileName += "_transcription." + extension;
161
162 return fileName;
163}
164
165/**
166 * Builds a WebVTT file of the given transcription
167 * @param {TranscriptionViewModel} transcription The transcription.
168 * @returns {String} The WebVTT content.
169 */
170function buildWebvttFileContents(transcription) {
171 let contents = "WEBVTT Transcription of " + transcription.fileName + "\n\n";
172
173 for (const word of getWords(transcription)) {
174 const startTime = Util.formatSecondsTimeString(word.startTime, true);
175 const endTime = Util.formatSecondsTimeString(word.endTime, true);
176
177 contents += startTime + " --> " + endTime + "\n";
178 contents += "- " + word.word + "\n\n";
179 }
180
181 return contents;
182}
183</script>
Note: See TracBrowser for help on using the repository browser.