Changeset 35297 for main


Ignore:
Timestamp:
2021-08-16T17:02:31+12:00 (3 years ago)
Author:
davidb
Message:

Fix words not being listed when the transcription does not end with a space char.
Improve UI.
Add type definitions.

Location:
main/trunk/model-interfaces-dev/atea
Files:
1 added
4 edited

Legend:

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

    r35284 r35297  
    55 */
    66
     7export class TranscriptionMetadata
     8{
     9    /**
     10     * A metadata object held by a {@link TranscriptionModel}.
     11     *
     12     * @param {String} char The character.
     13     * @param {Number} confidence The confidence that the character is corret. Smaller values are more confident.
     14     * @param {Number} start_time The timestamp in the audio at which this character is spoken.
     15     */
     16    constructor(char, confidence, start_time)
     17    {
     18        this.char = char;
     19        this.confidence = confidence;
     20        this.start_time = start_time;
     21    }
     22}
     23
    724export class TranscriptionModel
    825{
     
    1229     * @param {String} file_name The name of the file that was transcribed.
    1330     * @param {String} log A note of how the transcription was processed.
    14      * @param {{char: String, confidence: Number, start_time: Number}[]} metadata The character metadata.
     31     * @param {TranscriptionMetadata[]} metadata The character metadata.
    1532     * @param {boolean} success A value indicating if the transcription was successful or not.
    1633     * @param {String} transcription The transcription.
  • main/trunk/model-interfaces-dev/atea/js/asr/asr-controller.js

    r35296 r35297  
    44 */
    55
    6 import { TranscribeService, TranscriptionError, TranscriptionModel } from "./TranscribeModule.js";
     6import { TranscribeService, TranscriptionError, TranscriptionModel, TranscriptionMetadata } from "./TranscribeModule.js";
    77
    88/** @type {HTMLAudioElement} */
     
    4444window.addEventListener("load", function()
    4545{
    46     const monoCharSizeTestElement = document.querySelector(".monospace-font-size");
     46    const monoCharSizeTestElement = document.querySelector(".monospace-font-sizer");
    4747    if (monoCharSizeTestElement == null || monoCharSizeTestElement.textContent == null)
    4848    {
     
    110110const AudioUploadVM = AudioUploadComponent.mount("#audioUploadContainer");
    111111
     112/**
     113 * @typedef TranscriptionViewModel
     114 * @property {String} id
     115 * @property {String} transcription
     116 * @property {String} fileName
     117 * @property {TranscriptionMetadata} metadata
     118 * @property {File} file
     119 */
     120
    112121// @ts-ignore
    113122const TranscriptionsListComponent = Vue.createApp(
     
    121130            failures: new Map(),
    122131            showCharDisplay: false,
    123             currentAudioTime: 0,
    124             audioDuration: 0,
    125132            showWordList: false
    126133        }
     
    200207            }
    201208
     209            // Push the last word, as most transcriptions will not end in a space (hence breaking the above algorithm)
     210            if (lastWord.length > 0) {
     211                words.push({ word: lastWord, startTime: currStartTime });
     212            }
     213
    202214            return words;
    203215            // console.log(this);
  • main/trunk/model-interfaces-dev/atea/style/asr.scss

    r35296 r35297  
     1@use "./material.scss";
    12@import url('https://fonts.googleapis.com/css2?family=Roboto+Mono&family=Roboto:wght@400;700&display=swap');
    23
    3 /* === Start theme definitions === */
    4 
    54:root {
    6     --primary-bg-color: #2191c0;
    7     --primary-bg-color-d1: #2785ad;
    8     --primary-bg-color-d2: #227497;
    9 
    10     --primary-fg-color: white;
    11 
    12     --primary-box-shadow: 0px 2px 4px 0px #505050;
    13     --primary-box-shadow-thin: 0px 1px 3px 0px #747474;
    14 
    15     --paper-color: #FCFCFC;
    16     --page-bg-color: #f7f4f0;
    17 
    185    --monospace-font: 16px 'Roboto Mono', sans-serif;
    19 
    20     --border-radius: 0.3em;
    21 
    22     --transition-duration: 0.15s;
    23 }
    24 
    25 .theme-error {
    26     --primary-bg-color: #f04848;
    27     --primary-fg-color: white;
    28 }
    29 
    30 .theme-flat {
    31     --primary-bg-color: transparent;
    32     --primary-fg-color: #2191c0;
    33     --primary-box-shadow: none;
    34 
    35     &:hover {
    36         background-color: #EEE;
    37     }
    38 }
    39 
    40 @mixin transition-set {
    41     -webkit-transition-duration: var(--transition-duration);
    42     -moz-transition-duration: var(--transition-duration);
    43     transition-duration: var(--transition-duration);
    44 }
    45 
    46 /* === End theme definitions */
    47 
    48 /* === Start component definitions === */
    49 
    50 .paper {
    51     background-color: var(--paper-color);
    52     padding: 1.2em;
    53     border-radius: var(--border-radius);
    54     box-shadow: var(--primary-box-shadow);
    55 }
    56 
    57 .card {
    58     @extend .paper;
    59     margin: 1em;
    60 
    61     box-shadow: var(--primary-box-shadow-thin);
    62 }
    63 
    64 .card-outlined {
    65     @extend .card;
    66 
    67     box-shadow: none;
    68     border: 1px solid #BBB;
    69 }
    70 
    71 .divider {
    72     height: 1px;
    73     background-color: #0000001F;
    74     border: none;
    75 }
    76 
    77 /* Buttons */
    78 
    79 .btn-fab {
    80     background-color: var(--primary-bg-color);
    81     color: var(--primary-fg-color);
    82     border: none;
    83     box-shadow: var(--primary-box-shadow);
    84    
    85     font-size: 48px;
    86     border-radius: 50%;
    87     padding: 0.2em;
    88     cursor: pointer;
    89     margin: 0 1px 3px 1px; /* Keeps space around the box shadow */
    90 
    91     @include transition-set;
    92 
    93     &:hover {
    94         filter: brightness(92%);
    95     }
    96 
    97     &:disabled {
    98         filter: grayscale(100%);
    99     }
    100 }
    101 
    102 .btn-primary {
    103     background-color: var(--primary-bg-color);
    104     color: var(--primary-fg-color);
    105     border: none;
    106     box-shadow: var(--primary-box-shadow);
    107 
    108     border-radius: var(--border-radius);
    109     padding: 0.5em;
    110     cursor: pointer;
    111     font-family: 'Roboto', sans-serif;
    112     font-size: 16px;
    113     text-align: center;
    114     margin: 0 1px 3px 1px; /* Keeps space around the box shadow */
    115 
    116     @include transition-set;
    117 
    118     span {
    119         text-align: center;
    120         vertical-align: middle;
    121     }
    122 
    123     &:hover {
    124         filter: brightness(92%);
    125     }
    126 
    127     &:disabled {
    128         filter: grayscale(100%);
    129     }
    130 }
    131 
    132 /** Text display/input */
    133 
    134 .text-container {
    135     display: flex;
    136     align-items: center;
    137 
    138     border-radius: var(--border-radius);
    139     //border-bottom: 1px solid #AAA;
    140     background: #DCDCDCDC;
    141     padding: 0.5em;
    142 }
    143 
    144 .text-container-sl {
    145     @extend .text-container;
    146 
    147     overflow-x: auto;
    148     overflow-y: hidden;
    149     white-space: nowrap;
    150 }
    151 
    152 .text-input {
    153     display: flex;
    154     align-items: center;
    155 
    156     border-radius: var(--border-radius) var(--border-radius) 0 0;
    157     border-bottom: 1px solid #AAA;
    158     background: #EEE;
    159     padding: 0.5em;
    160 
    161     @include transition-set;
    162 
    163     &:hover {
    164         background-color: #DDD;
    165     }
    166 
    167     &:active {
    168         border-bottom: 1px solid var(--primary-bg-color);
    169        
    170         .text-input-active {
    171             width: 100%;
    172         }
    173     }
    174 
    175     .text-input-active {
    176         background-color: var(--primary-bg-color);
    177         height: 1px;
    178         margin: 0 auto;
    179         width: 0;
    180 
    181         @include transition-set;
    182     }
    183 }
    184 
    185 .text-placeholder {
    186     color: #666;
    187     cursor: default;
    188     font-style: italic;
    189 }
    190 
    191 /* === End component definitions === */
    192 
    193 /* Material Design Icon sizes */
    194 
    195 .mdi-s {
    196     font-size: 18px;
    197 }
    198 
    199 .mdi-m {
    200     font-size: 24px;
    201 }
    202 
    203 .mdi-l {
    204     font-size: 36px;
    205 }
    206 
    207 .mdi-xl {
    208     font-size: 48px;
    209 }
    210 
    211 /* Font sizes */
    212 
    213 .body1 {
    214     font-size: 16px;
    215 }
    216 
    217 .body2 {
    218     font-size: 14px;
    219 }
    220 
    221 .heading1 {
    222     font-size: 48px;
    223 }
    224 
    225 /* Scrollbar replacement */
    226 
    227 ::-webkit-scrollbar {
    228     width: 6px;
    229     height: 6px;
    230 }
    231 
    232 ::-webkit-scrollbar-track {
    233     background: #f1f1f1;
    234 }
    235 
    236 ::-webkit-scrollbar-thumb {
    237     background: #CCC;
    238     border-radius: 3px;
    239 
    240     @include transition-set;
    241 
    242     &:hover {
    243         background: #666;
    244         height: 8px;
    245         width: 8px;
    246     }
    2476}
    2487
     
    29857}
    29958
    300 .monospace-font-size {
     59.monospace-font-sizer {
    30160    font: var(--monospace-font);
    30261    padding: 0;
     
    33291
    33392.transcription__word-list {
    334     display: grid;
    335     gap: 0.5em 0.5em;
    336     grid-template-columns: 1fr auto;
    337     align-items: start;
     93    display: flex;
    33894
    33995    font: var(--monospace-font);
    34096    padding-top: 1em;
     97
     98    & .transcription__list {
     99        margin-left: 1em;
     100    }
    341101}
    342102
  • main/trunk/model-interfaces-dev/atea/transform/pages/asr.xsl

    r35296 r35297  
    3535    <!-- the page content -->
    3636    <xsl:template match="/page">
    37         <xsl:call-template name="audio-transcription"/>
     37        <xsl:call-template name="audio-transcription" />
    3838    </xsl:template>
    3939   
     
    4545        <section id="audio-transcription-container">
    4646            <!-- Used to calculate the character size of our monospace font -->
    47             <span class="monospace-font-size">ngā tama a rangi</span>
     47            <span class="monospace-font-sizer">ngā tama a rangi</span>
    4848
    4949            <!-- Contains the file input, transcribe button and transcription progress indicator -->
     
    6464
    6565                <button style="float: right;" type="submit"
    66                         v-bind:disabled="!anyFiles" v-on:click="doTranscription">
     66                        v-bind:disabled="!anyFiles || isTranscribing" v-on:click="doTranscription">
    6767                    <span class="material-icons">&#xEA3E;</span> <!-- history_edu -->
    6868                    <span>Transcribe</span>
     
    107107                            </div>
    108108
    109                             <div class="text-container">
     109                            <div class="text-container body0">
    110110                                {{ transcription.transcription }}
    111111                            </div>
    112112
    113                             <div class="transcription__word-list collapse" v-if="showWordList">
     113                            <div class="transcription__word-list" v-if="showWordList">
    114114                                <div class="transcription__word-list__controls">
    115115                                    <button class="btn-fab" v-on:click="playAudioFile(transcription.fileName)" type="button">
     
    122122                                <ul class="transcription__list">
    123123                                    <li v-if="!showCharDisplay">
    124                                         <span v-for="word in getWords(transcription.id)"
    125                                         class="transcription__word"
    126                                         v-on:click="playAudioFile(transcription.fileName, word.startTime)">
    127                                         {{ word.word }}
    128                                     </span>
    129                                 </li>
    130                                 <li v-if="showCharDisplay">
    131                                     <span v-for="char in getChars(transcription.id)"
    132                                     class="transcription__word"
    133                                     v-on:click="playAudioFile(transcription.fileName, char.startTime)">
    134                                     {{ char.char }}
     124                                        <span v-for="word in getWords(transcription.id)" class="transcription__word"
     125                                              v-on:click="playAudioFile(transcription.fileName, word.startTime)">
     126                                            {{ word.word }}
     127                                        </span>
     128                                    </li>
     129                                    <li v-if="showCharDisplay">
     130                                        <span v-for="char in getChars(transcription.id)" class="transcription__word"
     131                                              v-on:click="playAudioFile(transcription.fileName, char.startTime)">
     132                                            {{ char.char }}
    135133                                        </span>
    136134                                    </li>
     
    143141                                <span class="material-icons" v-if="!showWordList">expand_more</span>
    144142                                <span class="material-icons" v-if="showWordList">expand_less</span>
    145                                 <span>Expand</span>
     143                                <span>Playback and Edit</span>
    146144                            </button>
    147145                        </div>
Note: See TracChangeset for help on using the changeset viewer.