Browse Source

styling the caption table

main
Gwen Pasquarello 11 months ago
parent
commit
d2a87d8597
  1. 20
      src/CaptionList.ts
  2. 60
      src/TimestampDisplay.ts
  3. 3
      src/index.html
  4. 14
      src/index.ts
  5. 38
      src/style.css

20
src/CaptionList.ts

@ -48,6 +48,7 @@ export class Caption {
td(
{
ariaLive: 'off',
class: 'captionText',
},
this.text
)
@ -58,9 +59,10 @@ export class Caption {
}
}
export function UpdateCaptionListing(captions: RBTree, container: HTMLElement) {
export function UpdateCaptionListing(captions: RBTree, holderDiv: HTMLElement) {
const container = holderDiv.children.item(0) as HTMLElement
container.style.display = 'none'
let i = 1
let i = 4
captions.each((cap: Caption) => {
if (i >= container.childNodes.length) {
van.add(container, cap.element)
@ -72,3 +74,17 @@ export function UpdateCaptionListing(captions: RBTree, container: HTMLElement) {
container.style.display = null
//TODO allow removing a caption
}
export function CreateCaptionList() {
const {div, table, tr, th, caption, col} = van.tags
return div(
{id: 'captionListScroll'},
table(
{id: 'captionListing'},
caption('List of Captions'),
col({class: 'captionTimeCode'}),
col({class: 'captionTimeCode'}),
tr(th('Start Time'), th('End Time'), th('Text Content'))
)
)
}

60
src/TimestampDisplay.ts

@ -29,17 +29,61 @@ export function toTimecodeString(time: number): string {
)
}
export function ReactiveTimecodesEditor(id: string) {
const {div, input, label} = van.tags
const editor = div(
{id: id, class: 'timecodeEntry'},
input({type: 'number', class: 'timecodeInput hours'}),
let counter = 0
export function ReactiveTimecodesEditor(id: string, labelText: string) {
const {form, input, label, span} = van.tags
const timecodeID = `TimecodeInput${counter++}`
const editor = form(
{id: id, class: 'timecodeEntry', 'aria-labeledby': timecodeID},
label({id: timecodeID}, labelText),
input({
type: 'number',
id: `${timecodeID}-hours`,
'aria-labeledby': `${timecodeID}-hours-label`,
ariaLabel: 'hours',
class: 'timecodeInput hours',
}),
label({id: `${timecodeID}-hours-label`, for: `${timecodeID}-hours`, hidden: true}, 'hours'),
':',
input({type: 'number', class: 'timecodeInput minutes'}),
input({
type: 'number',
id: `${timecodeID}-minutes`,
class: 'timecodeInput minutes',
'aria-labeledby': `${timecodeID}-minutes-label`,
ariaLabel: 'minutes',
}),
label(
{id: `${timecodeID}-minutes-label`, for: `${timecodeID}-minutes`, hidden: true},
'minutes'
),
':',
input({type: 'number', class: 'timecodeInput seconds'}),
input({
type: 'number',
id: `${timecodeID}-seconds`,
class: 'timecodeInput seconds',
'aria-labeledby': `${timecodeID}-seconds-label`,
ariaLabel: 'seconds',
}),
label(
{id: `${timecodeID}-seconds-label`, for: `${timecodeID}-seconds`, hidden: true},
'seconds'
),
'.',
input({type: 'number', class: 'timecodeInput milliseconds'})
input({
type: 'number',
id: `${timecodeID}-milliseconds`,
class: 'timecodeInput milliseconds',
'aria-labeledby': `${timecodeID}-milliseconds-label`,
ariaLabel: 'milliseconds',
}),
label(
{
id: `${timecodeID}-milliseconds-label`,
for: `${timecodeID}-milliseconds`,
hidden: true,
},
'milliseconds'
)
)
return editor
}

3
src/index.html

@ -5,6 +5,7 @@
<title></title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" type="text/css" href="style.css" />
<title>Captionator</title>
</head>
<body>
<div id="captionDiv">
@ -12,7 +13,7 @@
<div class="controls" id="videoControls">
<button id="back10" disabled>&lt;&lt;</button>
<button id="back1" disabled>&lt;</button>
<button id="play" disabled>Play</button>
<button id="play" disabled>Play/Pause</button>
<button id="forw1" disabled>&gt;</button>
<button id="forw10" disabled>&gt;&gt;</button>
</div>

14
src/index.ts

@ -1,5 +1,5 @@
import van, {State} from 'vanjs-core'
import {Caption, UpdateCaptionListing} from './CaptionList'
import {Caption, CreateCaptionList, UpdateCaptionListing} from './CaptionList'
import {RBTree} from 'bintrees'
import {addCoroutineListener} from './coro'
import {SetupVideoControlFunctions} from './VideoPlaybackControl'
@ -39,11 +39,7 @@ addCoroutineListener(
controls.get('new'),
'click',
function* newCaptionRoutine() {
const {table, tr, th, td} = van.tags
const captionList = table(
{class: 'captionListing'},
tr(th('Start Time'), th('End Time'), th('Text Content'))
)
const captionList = CreateCaptionList()
van.add(captionDiv, captionList)
yield
while (true) {
@ -105,21 +101,21 @@ addCoroutineListener(
const nullState: State<number> = van.state(null)
let currentCaption = van.state(new Caption(null, null, 'THIS SHOULD NEVER GET USED'))
const startEditor = ReactiveTimecodesEditor('captionTimecodeStart')
const startEditor = ReactiveTimecodesEditor('captionTimecodeStart', 'Caption Start Time')
UpdateTimcodeEditor(
startEditor,
currentCaption.val.start,
van.state(-0.0001),
currentCaption.val.end
)
const endEditor = ReactiveTimecodesEditor('captionTimecodeEnd')
const endEditor = ReactiveTimecodesEditor('captionTimecodeEnd', 'Caption End Time')
UpdateTimcodeEditor(
endEditor,
currentCaption.val.end,
currentCaption.val.start,
van.state(video.duration)
)
van.add(titleEditing, 'Start: ', startEditor, ' End: ', endEditor)
van.add(titleEditing, startEditor, endEditor)
while (true) {
if (!currentCaption.val || !currentCaption.val.contains(video.currentTime)) {

38
src/style.css

@ -8,10 +8,9 @@ body {
#captionDiv > video {
display: block;
width: 100%;
/*TODO deal with zoom accessibility*/
max-height: 30vh;
margin: 0;
height: 15em;
margin: 0 auto 0 auto;
}
#captionDiv > svg {
@ -26,31 +25,40 @@ body {
width: fit-content;
}
#captionListScroll {
height: 20em;
overflow-y: scroll;
}
#captionText {
width: 100%;
height: 5em;
}
#titleEditing {
height: 6em;
}
#captionListing {
border: 1px solid grey;
padding: 0.5em;
height: 15em;
max-height: 15em;
width: 100%;
overflow-y: scroll;
table-layout: fixed;
border-collapse: collapse;
}
.captionEntry {
border-bottom: 1px solid lightgray;
height: 1.5em;
.captionTimeCode {
width: 6em;
text-align: center;
}
.captionText {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
td,
th {
text-align: left;
border: 1px solid;
padding: 0.25em;
}
.timecodeEntry {
display: inline;
display: inline-block;
}
.timecodeInput {
width: 2.5em;

Loading…
Cancel
Save