Ignore:
Timestamp:
2021-08-06T10:14:47+12:00 (3 years ago)
Author:
davidb
Message:

Refactor controller code and improve char playback layout

Location:
main/trunk/model-interfaces-dev/atea
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • main/trunk/model-interfaces-dev/atea/js/asr/asr-controller.js

    r35255 r35258  
    2323*
    2424* @param {string} url The URL from which to load the script.
    25 * @param {loadScriptCallback} callback Callback performed when the script has been loaded.
    2625*/
    2726function loadScript(url, callback = () => {})
    2827{
    29     // Append the script to the body element
    3028    var body = document.body;
     29
    3130    var script = document.createElement('script');
    3231    script.type = 'text/javascript';
     
    3433   
    3534    script.onload = callback;
    36    
     35
    3736    body.appendChild(script);
    3837}
    3938
    40 loadScript("./interfaces/atea/js/asr/TranscribeService.js");
     39var transcribeService;
     40loadScript("./interfaces/atea/js/asr/TranscribeService.js", () => {
     41    transcribeService = new TranscribeService();
     42});
    4143
    4244/** @type {HTMLAudioElement} */
     
    4951{
    5052    const files = $(FILE_UPLOAD_INPUT_NAME)[0].files;
    51     const transcribeService = new TranscribeService();
    5253   
    5354    transcriptionAudioSourceElement.src = URL.createObjectURL(files[0]);
     
    5758    $(FILE_UPLOAD_PROGRESS_CONTAINER_NAME).removeClass("asr-hidden");
    5859   
    59     // Remove old transcriptions
    60     const transcriptionsList = document.getElementById("transcriptionsList");
    61     if (transcriptionsList == null)
    62     {
    63         console.error("Cannot find transcriptions list");
    64         return;
    65     }
    66    
    67     while (transcriptionsList.lastChild) {
    68         transcriptionsList.removeChild(transcriptionsList.lastChild);
    69     }
     60    clearTranscriptions();
    7061   
    7162    try
     
    9485}
    9586
     87/** @type {HTMLUListElement} */
     88const transcriptionsList = document.getElementById("transcriptionsList");
     89
     90/**
     91 * Removes any transcriptions from the UI list.
     92 */
     93function clearTranscriptions()
     94{
     95    while (transcriptionsList.lastChild) {
     96        transcriptionsList.removeChild(transcriptionsList.lastChild);
     97    }
     98}
     99
    96100/** @type {HTMLTemplateElement} */
    97101const transcriptionTemplate = document.getElementById("transcriptionTemplate");
    98 
    99 /** @type {HTMLTemplateElement} */
    100 const metadataTemplate = document.getElementById("metadataTemplate");
    101102
    102103/**
     
    108109function insertTranscription(transcription)
    109110{
    110     // Get the transcription list and template
    111     let list = document.getElementById("transcriptionsList");
    112    
    113111    // Insert a new transcription row
    114     let clone = transcriptionTemplate.content.firstElementChild.cloneNode(true);
    115     let spans = clone.querySelectorAll("span");
     112    const clone = transcriptionTemplate.content.firstElementChild.cloneNode(true);
     113
     114    /** @type {HTMLSpanElement[]} */
     115    const spans = clone.querySelectorAll("span");
    116116    spans[0].textContent = transcription.file_name;
    117117    spans[1].textContent = transcription.transcription;
    118118   
    119119    // Get the metadata list and template
    120     let metadataList = clone.querySelector("#metadataList");
    121    
    122     if (metadataList == null || metadataTemplate == null)
     120    /** @type {HTMLUListElement} */
     121    const metadataList = clone.querySelector("#metadataList");
     122   
     123    // Insert metadata rows
     124    for (const metadata of transcription.metadata) {
     125        metadataList.appendChild(buildMetadataNode(metadata));
     126    }
     127   
     128    transcriptionsList.appendChild(clone);
     129}
     130
     131/** @type {HTMLTemplateElement} */
     132const metadataTemplate = document.getElementById("metadataTemplate");
     133
     134/**
     135 * Builds a metadata node.
     136 *
     137 * @param {{char: string, confidence: number, start_time: number}} metadata The metadata used to create the node.
     138 * @param {String} fileName The file that this metadata was generated from.
     139 * @returns {Node} The constructed DOM node.
     140 */
     141function buildMetadataNode(metadata, fileName)
     142{
     143    const metadataClone = metadataTemplate.content.firstElementChild.cloneNode(true);
     144
     145    /** @type {HTMLParagraphElement} */
     146    const p = metadataClone.querySelector("p");
     147   
     148    /** @type {HTMLButtonElement} */
     149    const button = metadataClone.querySelector("button");
     150   
     151    button.dataset.fileName = fileName;
     152    button.onclick = function()
    123153    {
    124         console.error("Could not find metadata list and/or template.");
    125         return;
    126     }
    127    
    128     // Insert metadata rows
    129     for (let metadata of transcription.metadata)
    130     {
    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        
    150         metadataList.appendChild(metadataClone);
    151     }
    152    
    153     list.appendChild(clone);
    154 }
    155 
     154        transcriptionAudioElement.currentTime = metadata.start_time;
     155        transcriptionAudioElement.play();
     156    }
     157   
     158    if (metadata.char == ' ') {
     159        p.textContent = "\u00A0 " // This helps with formatting, as elements that only contain whitespace are collapsed.
     160    }
     161    else {
     162        p.textContent = metadata.char;
     163    }
     164
     165    return metadataClone;
     166}
     167
     168/** @type {HTMLTemplateElement} */
    156169const errorTemplate = document.querySelector("#errorTemplate");
    157170
     
    159172* Inserts a transcription error into the DOM.
    160173*
    161 * @param {String} fileName
    162 * @param {String | undefined} statusMessage
     174* @param {String} fileName The file for which an error occured.
     175* @param {String | undefined} statusMessage An informative error message to display.
    163176*/
    164177function insertError(fileName, statusMessage)
    165178{
    166     // Get the transcription list and template
    167     let list = document.querySelector("#transcriptionsList");
    168    
    169     if (list == null || errorTemplate == null)
    170     {
    171         console.error("Could not find transcription list and/or error template");
    172         return;
    173     }
    174    
    175     // Insert a new transcription row
    176     let clone = errorTemplate.content.firstElementChild.cloneNode(true);
    177     let spans = clone.querySelectorAll("span");
     179    const clone = errorTemplate.content.firstElementChild.cloneNode(true);
     180
     181    /** @type {HTMLSpanElement[]} */
     182    const spans = clone.querySelectorAll("span");
    178183    spans[0].textContent = statusMessage;
    179184    spans[1].textContent = fileName;
    180185   
    181     list.appendChild(clone);
    182 }
    183 
    184 $(FILE_UPLOAD_INPUT_NAME).on("input", toggleUploadButtonState);
    185 
    186 function toggleUploadButtonState(e)
     186    transcriptionsList.appendChild(clone);
     187}
     188
     189// Ensure the transcribe button is disabled when there are no files selected.
     190$(FILE_UPLOAD_INPUT_NAME).on("input", e =>
    187191{
    188192    if (e.target.files.length <= 0) {
     
    192196        $("#btnFileUpload").prop("disabled", false);
    193197    }
    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         });
     198});
     199
     200// whenever we hover over a menu item that has a submenu
     201$('.tooltip-parent').on('mouseover', function() {
     202    var $menuItem = $(this),
     203    $submenuWrapper = $('> .tooltip-wrapper', $menuItem);
     204   
     205    var menuItemPos = $menuItem.position();
     206   
     207    $submenuWrapper.css({
     208        top: menuItemPos.top,
     209        left: menuItemPos.left + Math.round($menuItem.outerWidth() * 0.75)
    210210    });
    211211});
     212
     213// $(function() {
     214   
     215// });
  • main/trunk/model-interfaces-dev/atea/style/asr.css

    r35255 r35258  
    5252    z-index: 1;
    5353    width: 1.5em;
    54     border-right: 1px solid black;
    5554    text-align: center;
    5655    vertical-align: middle;
     
    5958.metadata-list-item .spaced-block {
    6059    width: 100%;
     60    border-right: 1px solid black;
     61}
     62
     63.metadata-list-item .spaced-block:last-child {
     64    margin-top: -10%;
     65    margin-bottom: 20%;
     66    border-right: none;
     67}
     68
     69.metadata-list-item p {
     70    margin: 0;
    6171}
    6272
    6373.metadata-list-item button {
    6474    padding: 0;
    65 }
    66 
    67 .metadata-list-item pre {
    6875    margin: 0;
    69     padding: 0;
    7076}
    7177
  • main/trunk/model-interfaces-dev/atea/transform/pages/asr.xsl

    r35255 r35258  
    5454
    5555        <div id="transcriptionsDisplayContainer">
    56             <audio id="transcriptionAudio">
     56            <audio id="transcriptionAudio" controls="controls">
    5757                <source id="transcriptionAudioSource" src="" />
    5858            </audio>
Note: See TracChangeset for help on using the changeset viewer.