Changeset 35255
- Timestamp:
- 2021-08-05T16:55:26+12:00 (3 years ago)
- Location:
- main/trunk/model-interfaces-dev/atea
- Files:
-
- 3 added
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
main/trunk/model-interfaces-dev/atea/js/asr/asr-controller.js
r35253 r35255 3 3 4 4 /** 5 6 5 * The name of the file input that audio files can be uploaded to. 6 */ 7 7 const FILE_UPLOAD_INPUT_NAME = "#fileUpload"; 8 8 9 9 /** 10 11 10 * The name of the container that holds the progress display for the audio upload. 11 */ 12 12 const FILE_UPLOAD_PROGRESS_CONTAINER_NAME = "#prgFileUploadContainer"; 13 13 14 14 /** 15 * The name of the button that triggers the audio upload 16 */ 17 const FILE_UPLOAD_BUTTON_NAME = "#btnFileUpload"; 18 19 /** 20 * @callback loadScriptCallback 21 * @param {Event} ev The event 22 * @returns {void} 23 */ 24 25 /** 26 * Loads a remote script. 27 * Found at https://stackoverflow.com/questions/950087/how-do-i-include-a-javascript-file-in-another-javascript-file 28 * 29 * @param {string} url The URL from which to load the script. 30 * @param {loadScriptCallback} callback Callback performed when the script has been loaded. 31 */ 15 * @callback loadScriptCallback 16 * @param {Event} ev The event 17 * @returns {void} 18 */ 19 20 /** 21 * Loads a remote script. 22 * Found at https://stackoverflow.com/questions/950087/how-do-i-include-a-javascript-file-in-another-javascript-file 23 * 24 * @param {string} url The URL from which to load the script. 25 * @param {loadScriptCallback} callback Callback performed when the script has been loaded. 26 */ 32 27 function loadScript(url, callback = () => {}) 33 28 { … … 39 34 40 35 script.onload = callback; 41 36 42 37 body.appendChild(script); 43 38 } 44 39 45 40 loadScript("./interfaces/atea/js/asr/TranscribeService.js"); 41 42 /** @type {HTMLAudioElement} */ 43 const transcriptionAudioElement = document.getElementById("transcriptionAudio"); 44 45 /** @type {HTMLSourceElement} */ 46 const transcriptionAudioSourceElement = document.getElementById("transcriptionAudioSource"); 46 47 47 48 async function doAudioUpload() … … 49 50 const files = $(FILE_UPLOAD_INPUT_NAME)[0].files; 50 51 const transcribeService = new TranscribeService(); 51 52 53 transcriptionAudioSourceElement.src = URL.createObjectURL(files[0]); 54 transcriptionAudioElement.load(); 55 52 56 $(FILE_UPLOAD_INPUT_NAME).prop("disabled", true); 53 57 $(FILE_UPLOAD_PROGRESS_CONTAINER_NAME).removeClass("asr-hidden"); 54 58 55 59 // Remove old transcriptions 56 const transcriptionsList = document. querySelector("#transcriptionsList");60 const transcriptionsList = document.getElementById("transcriptionsList"); 57 61 if (transcriptionsList == null) 58 62 { … … 60 64 return; 61 65 } 62 66 63 67 while (transcriptionsList.lastChild) { 64 68 transcriptionsList.removeChild(transcriptionsList.lastChild); 65 69 } 66 70 67 71 try 68 72 { … … 85 89 insertError("all", e.statusMessage); 86 90 } 87 91 88 92 $(FILE_UPLOAD_PROGRESS_CONTAINER_NAME).addClass("asr-hidden"); 89 93 $(FILE_UPLOAD_INPUT_NAME).prop("disabled", false); 90 94 } 91 95 92 // Adapted from https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template 93 const transcriptionTemplate = document.querySelector('#transcriptionTemplate'); 94 const metadataTemplate = document.querySelector("#metadataTemplate"); 95 96 /** 97 * Inserts a transcription object into the DOM. 98 * 99 * @param {TranscriptionModel} transcription The transcription to insert. 100 */ 96 /** @type {HTMLTemplateElement} */ 97 const transcriptionTemplate = document.getElementById("transcriptionTemplate"); 98 99 /** @type {HTMLTemplateElement} */ 100 const metadataTemplate = document.getElementById("metadataTemplate"); 101 102 /** 103 * Inserts a transcription object into the DOM. 104 * Adapted from https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template 105 * 106 * @param {TranscriptionModel} transcription The transcription to insert. 107 */ 101 108 function insertTranscription(transcription) 102 109 { 103 110 // Get the transcription list and template 104 let list = document. querySelector("#transcriptionsList");105 111 let list = document.getElementById("transcriptionsList"); 112 106 113 // Insert a new transcription row 107 114 let clone = transcriptionTemplate.content.firstElementChild.cloneNode(true); … … 109 116 spans[0].textContent = transcription.file_name; 110 117 spans[1].textContent = transcription.transcription; 111 118 112 119 // Get the metadata list and template 113 120 let metadataList = clone.querySelector("#metadataList"); 114 121 115 122 if (metadataList == null || metadataTemplate == null) 116 123 { … … 118 125 return; 119 126 } 120 127 121 128 // Insert metadata rows 122 129 for (let metadata of transcription.metadata) 123 130 { 124 let metadataClone = metadataTemplate.content.firstElementChild.cloneNode(true); 125 let metadataSpans = metadataClone.querySelectorAll("td"); 126 127 metadataSpans[0].textContent = metadata.char; 128 metadataSpans[1].textContent = metadata.start_time; 129 131 const metadataClone = metadataTemplate.content.firstElementChild.cloneNode(true); 132 const p = metadataClone.querySelector("p"); 133 134 /** @type {HTMLButtonElement} */ 135 const button = metadataClone.querySelector("button"); 136 137 button.onclick = function() 138 { 139 transcriptionAudioElement.currentTime = metadata.start_time; 140 transcriptionAudioElement.play(); 141 } 142 143 if (metadata.char == ' ') { 144 p.textContent = "\u00A0 " // This helps with formatting, as elements that only contain whitespace are collapsed. 145 } 146 else { 147 p.textContent = metadata.char; 148 } 149 130 150 metadataList.appendChild(metadataClone); 131 151 } 132 152 133 153 list.appendChild(clone); 134 154 } … … 137 157 138 158 /** 139 140 141 142 143 159 * Inserts a transcription error into the DOM. 160 * 161 * @param {String} fileName 162 * @param {String | undefined} statusMessage 163 */ 144 164 function insertError(fileName, statusMessage) 145 165 { 146 166 // Get the transcription list and template 147 167 let list = document.querySelector("#transcriptionsList"); 148 168 149 169 if (list == null || errorTemplate == null) 150 170 { … … 152 172 return; 153 173 } 154 174 155 175 // Insert a new transcription row 156 176 let clone = errorTemplate.content.firstElementChild.cloneNode(true); … … 158 178 spans[0].textContent = statusMessage; 159 179 spans[1].textContent = fileName; 160 180 161 181 list.appendChild(clone); 162 182 } … … 167 187 { 168 188 if (e.target.files.length <= 0) { 169 $( FILE_UPLOAD_BUTTON_NAME).prop("disabled", true);189 $("#btnFileUpload").prop("disabled", true); 170 190 } 171 191 else { 172 $(FILE_UPLOAD_BUTTON_NAME).prop("disabled", false); 173 } 174 } 192 $("#btnFileUpload").prop("disabled", false); 193 } 194 } 195 196 $(function() { 197 // whenever we hover over a menu item that has a submenu 198 $('.tooltip-parent').on('mouseover', function() { 199 var $menuItem = $(this), 200 $submenuWrapper = $('> .tooltip-wrapper', $menuItem); 201 202 // grab the menu item's position relative to its positioned parent 203 var menuItemPos = $menuItem.position(); 204 205 // place the submenu in the correct position relevant to the menu item 206 $submenuWrapper.css({ 207 top: menuItemPos.top, 208 left: menuItemPos.left + Math.round($menuItem.outerWidth() * 0.75) 209 }); 210 }); 211 }); -
main/trunk/model-interfaces-dev/atea/style/asr.css
r35252 r35255 1 1 .asr-hidden { 2 display: none;2 display: none; 3 3 } 4 4 5 5 .transcription-list { 6 padding: 0;6 padding: 0; 7 7 } 8 8 9 9 .transcription-list-item { 10 list-style-type: none;11 border: 1px solid black;12 border-radius: 5px;13 margin-bottom: 5px;14 padding: 1em;10 list-style-type: none; 11 border: 1px solid black; 12 border-radius: 5px; 13 margin-bottom: 5px; 14 padding: 1em; 15 15 } 16 16 17 17 .transcription-list-item:last-child { 18 margin-bottom: 0;18 margin-bottom: 0; 19 19 } 20 20 21 21 .transcription-list-item .spaced-block, .error-list-item .spaced-block { 22 margin-bottom: 8px;22 margin-bottom: 8px; 23 23 } 24 24 25 25 .transcription-list-item .spaced-block:last-child, .error-list-item .spaced-block:last-child { 26 margin-bottom: 0;26 margin-bottom: 0; 27 27 } 28 28 29 29 .error-list-item { 30 list-style-type: none;31 background-color: rgba(255, 0, 0, 0.329);32 border: 1px solid rgba(255, 0, 0, 0.651);33 border-radius: 5px;34 margin-bottom: 5px;35 padding: 1em;30 list-style-type: none; 31 background-color: rgba(255, 0, 0, 0.329); 32 border: 1px solid rgba(255, 0, 0, 0.651); 33 border-radius: 5px; 34 margin-bottom: 5px; 35 padding: 1em; 36 36 } 37 37 38 .metadata-list th { 39 text-align: left; 40 width: 6em; 38 .metadata-list { 39 font-size: 16px; 40 padding: 0; 41 list-style-type: none; 42 overflow-x: auto; 43 overflow-y: hidden; 44 display: flex; 41 45 } 42 46 43 .metadata-list th { 44 border-right: 1px solid black; 45 border-bottom: 1px solid black; 47 .metadata-list-container { 48 position: relative; 46 49 } 47 50 48 .metadata-list td { 49 border-right: 1px solid black; 51 .metadata-list-item { 52 z-index: 1; 53 width: 1.5em; 54 border-right: 1px solid black; 55 text-align: center; 56 vertical-align: middle; 50 57 } 51 58 52 .metadata-list th:last-child, td:last-child{53 border-right: none;59 .metadata-list-item .spaced-block { 60 width: 100%; 54 61 } 55 62 56 .metadata-list tr{57 border-bottom: 1px solid black;63 .metadata-list-item button { 64 padding: 0; 58 65 } 59 66 60 .metadata-list tr:last-child { 61 border-bottom: none; 67 .metadata-list-item pre { 68 margin: 0; 69 padding: 0; 62 70 } 63 71 72 .tooltip-parent { 73 position: static; 74 } 75 76 .tooltip-parent:hover .tooltip-wrapper { 77 display: block; 78 } 79 80 .tooltip-parent .tooltip-wrapper { 81 position: absolute; 82 z-index: 10; 83 display: none; 84 } 85 86 .tooltip { 87 width: 120px; 88 background-color: black; 89 color: #fff; 90 text-align: center; 91 padding: 5px 0; 92 border-radius: 6px; 93 } 64 94 65 95 details { 66 border: 1px solid #aaa;67 border-radius: 4px;68 padding: .5em .5em 0;96 border: 1px solid #aaa; 97 border-radius: 4px; 98 padding: .5em .5em 0; 69 99 } 70 100 71 101 summary { 72 font-weight: bold;73 margin: -.5em -.5em 0;74 padding: .5em;75 cursor: pointer;102 font-weight: bold; 103 margin: -.5em -.5em 0; 104 padding: .5em; 105 cursor: pointer; 76 106 } 77 107 78 108 details[open] { 79 padding: .5em;109 padding: .5em; 80 110 } 81 111 82 112 details[open] summary { 83 border-bottom: 1px solid #aaa;84 margin-bottom: .5em;113 border-bottom: 1px solid #aaa; 114 margin-bottom: .5em; 85 115 } -
main/trunk/model-interfaces-dev/atea/transform/pages/asr.xsl
r35253 r35255 41 41 42 42 <div> 43 <form onSubmit=" doAudioUpload(); return false;" enctype="multipart/form-data">43 <form onSubmit=" doAudioUpload(); return false;" enctype="multipart/form-data"> 44 44 <label for="fileUpload">Audio File:</label> 45 45 <input id="fileUpload" type="file" accept="audio/wav" multiple="multiple" /> … … 54 54 55 55 <div id="transcriptionsDisplayContainer"> 56 <audio id="transcriptionAudio"> 57 <source id="transcriptionAudioSource" src="" /> 58 </audio> 59 56 60 <ul id="transcriptionsList" class="transcription-list"></ul> 57 61 … … 60 64 <div> 61 65 <div class="spaced-block"> 62 66 <b>File: </b><span></span> 63 67 </div> 64 68 <div class="spaced-block"> … … 67 71 <details> 68 72 <summary>Character Information</summary> 69 <table id="metadataList" class="metadata-list"> 70 <thead> 71 <tr> 72 <th>Character</th> 73 <th>Start Time</th> 74 </tr> 75 </thead> 76 <tbody></tbody> 77 </table> 73 <div class="metadata-list-container"> 74 <ul id="metadataList" class="metadata-list"></ul> 75 </div> 78 76 </details> 79 77 </div> … … 95 93 96 94 <template id="metadataTemplate"> 97 <tr> 98 <td></td> 99 <td></td> 100 </tr> 95 <!-- <li class="metadata-list-item tooltip-parent tooltip"> 96 <div class="spaced-block"> 97 <p></p> 98 </div> 99 <div class="spaced-block"> 100 <button type="button"><img src="interfaces/{$interface_name}/assets/play_arrow_black_18dp.svg" /></button> 101 </div> 102 <div class="tooltip-wrapper"> 103 <span class="tooltip">0.02</span> 104 </div> 105 </li> --> 106 <li class="metadata-list-item"> 107 <div class="spaced-block"> 108 <p></p> 109 </div> 110 <div class="spaced-block"> 111 <button type="button"><img src="interfaces/{$interface_name}/assets/play_arrow_black_18dp.svg" /></button> 112 </div> 113 </li> 101 114 </template> 102 115 </div>
Note:
See TracChangeset
for help on using the changeset viewer.