Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 86 additions & 0 deletions css/hyperaudio-lite-editor.css
Original file line number Diff line number Diff line change
Expand Up @@ -867,3 +867,89 @@ label[data-a11y-wired]:focus-visible {
margin-top: 27px;
}
}

/* Transcript/captions view switch: a recessed track with a raised thumb that
slides under the active segment, so the current view reads as a position in
a switch — distinct from the filled action buttons beside it. Colors come
from the daisyUI theme vars (base-200 track, base-100 thumb). */
#view-switch {
position: relative;
display: inline-flex;
padding: 4px;
border-radius: 0.5rem;
background-color: oklch(var(--b3));
margin-right: 16px;
}
#view-switch::before {
content: "";
position: absolute;
top: 4px;
left: 4px;
width: 44px;
height: 40px;
border-radius: 0.375rem;
background-color: oklch(var(--b1));
box-shadow: 0 1px 3px oklch(var(--bc) / 0.25);
transition: transform 0.15s ease-out;
}
#view-switch.captions-active::before {
transform: translateX(44px);
}
@media (prefers-reduced-motion: reduce) {
#view-switch::before { transition: none; }
}
#view-switch .btn {
position: relative; /* sits above the sliding thumb */
width: 44px;
height: 40px;
min-height: 0;
border: none;
background: transparent;
color: oklch(var(--bc) / 0.4);
}
#view-switch .btn:hover {
background: transparent;
color: oklch(var(--bc) / 0.75);
}
#view-switch .btn[aria-pressed="true"] {
color: oklch(var(--bc));
}

/* Soften the navbar's outline buttons to sit in the same family as the view
switch: quiet base-300 borders and a tint hover, instead of daisyUI's
near-black border + black-fill hover inversion, which read heavier than
everything around them. */
.navbar .btn-outline {
border-color: oklch(var(--b3));
color: oklch(var(--bc) / 0.75);
background-color: oklch(var(--b1));
}
.navbar .btn-outline:hover {
border-color: oklch(var(--bc) / 0.3);
background-color: oklch(var(--b2));
color: oklch(var(--bc));
}

/* Align the navbar's left edge with the transcript card: the card sits flush
with .main-panel while the sidebar is open (left offset 0) and floats with a
16px gutter when collapsed, so the navbar's leading padding follows suit —
animated to track the card's 0.5s slide. Desktop two-pane only; the
small-screen layout keeps the default navbar padding. The .main-panel
prefix beats DaisyUI's single-class .navbar padding (tailwind-min.css
loads after this file). */
@media screen and (min-width: 949px) {
.main-panel .navbar {
padding-left: 0;
/* Optically centre the buttons in the full band between the screen top
and the transcript card's top (78px): the borderless navbar reads as
one space with the 8px floating-card gap below it, so geometric
centring in the 70px navbar alone left them sitting 4px high. The
margin shifts the whole centred bar; the card is absolutely
positioned, so nothing else moves. */
margin-top: 4px;
transition: padding-left 0.5s ease;
}
body.sidebar-collapsed .main-panel .navbar {
padding-left: 16px;
}
}
27 changes: 17 additions & 10 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@
}

</style>
<link rel="stylesheet" href="css/hyperaudio-lite-editor.css?v=0.8.3">
<link rel="stylesheet" href="css/hyperaudio-lite-editor.css?v=0.8.11">
<!-- DaisyUI / Tailwind - must be loaded last -->
<link rel="stylesheet" href="css/tailwind-min.css">
</head>
Expand Down Expand Up @@ -386,7 +386,7 @@ <h2 id="recents-title">Recents</h2>
<div class="main-panel" style="z-index: 2">
<div class="navbar bg-base-100" style="background-color: #f5f5f5; min-height:70px;">
<div class="navbar-start">
<button id="sidebar-toggle" class="btn btn-square btn-outline tooltip" data-tip="Toggle sidebar" style="margin-right:4px" aria-label="Toggle Sidebar">
<button id="sidebar-toggle" class="btn btn-square btn-ghost tooltip" data-tip="Toggle sidebar" style="margin-right:4px" aria-label="Toggle sidebar" aria-pressed="true">
<svg id="sidebar-close-icon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-sidebar-close"><rect width="18" height="18" x="3" y="3" rx="2" ry="2"></rect><path d="M9 3v18"></path><path d="m16 15-3-3 3-3"></path></svg>
<svg id="sidebar-open-icon" style="display: none" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-sidebar-open"><rect width="18" height="18" x="3" y="3" rx="2" ry="2"></rect><path d="M9 3v18"></path><path d="m14 9 3 3-3 3"></path></svg>
</button>
Expand Down Expand Up @@ -487,12 +487,19 @@ <h3 class="text-lg font-bold">Topics</h3>
<!--<label for="captions-modal" class="btn btn-outline gap-2" style="margin-right:4px">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-subtitles"><path d="M7 13h4"></path><path d="M15 13h2"></path><path d="M7 9h2"></path><path d="M13 9h4"></path><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v10Z"></path></svg>
</label>-->
<button id="caption-editor-btn" class="btn btn-square btn-outline tooltip" data-tip="Edit captions" style="margin-right:4px" aria-label="Edit captions">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-subtitles"><path d="M7 13h4"></path><path d="M15 13h2"></path><path d="M7 9h2"></path><path d="M13 9h4"></path><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v10Z"></path></svg>
</button>
<button id="transcript-editor-btn" class="btn btn-square btn-outline tooltip" data-tip="Edit transcript" style="margin-right:4px" aria-label="Edit transcript" disabled>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-file-text"><path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z"/><path d="M14 2v4a2 2 0 0 0 2 2h4"/><path d="M10 9H8"/><path d="M16 13H8"/><path d="M16 17H8"/></svg>
</button>
<!-- Transcript/captions view switch: a recessed track whose raised thumb
slides under the active segment (styles in hyperaudio-lite-editor.css).
The active view is marked by the thumb and aria-pressed, never by
disabled — disabled reads as "unavailable", not "current view".
editor-core.js keeps the state in sync. -->
<div id="view-switch" role="group" aria-label="Editor view">
<button id="transcript-editor-btn" class="btn btn-square tooltip" data-tip="Transcript view" aria-label="Transcript view" aria-pressed="true">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-file-text"><path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z"/><path d="M14 2v4a2 2 0 0 0 2 2h4"/><path d="M10 9H8"/><path d="M16 13H8"/><path d="M16 17H8"/></svg>
</button>
<button id="caption-editor-btn" class="btn btn-square tooltip" data-tip="Captions view" aria-label="Captions view" aria-pressed="false">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-subtitles"><path d="M7 13h4"></path><path d="M15 13h2"></path><path d="M7 9h2"></path><path d="M13 9h4"></path><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v10Z"></path></svg>
</button>
</div>
<input type="checkbox" id="captions-modal" class="modal-toggle" tabindex="-1" aria-hidden="true" />
<div class="modal" style="content-visibility: hidden;">
<div class="modal-box relative">
Expand Down Expand Up @@ -963,7 +970,7 @@ <h3 class="font-bold text-lg">Caption Regeneration </h3>
<script src="js/hyperaudio-lite-extension.js?v=0.7.2"></script>
<script src="js/caption.js?v=0.8.6"></script>
<script src="js/transcript-serializer.js?v=0.8.5"></script>
<script src="js/editor-core.js?v=0.8.10"></script>
<script src="js/editor-core.js?v=0.8.11"></script>


<import-deepgram-json></import-deepgram-json>
Expand Down Expand Up @@ -1051,7 +1058,7 @@ <h3 class="font-bold text-lg">Load from Local Storage</h3>
<!-- end of caption editor additions -->

<!-- responsive small-screen UI toggles (#349) -->
<script src="js/responsive.js?v=0.7.2"></script>
<script src="js/responsive.js?v=0.8.11"></script>

<!-- keyboard operability for modal label-buttons (#402) -->
<script src="js/a11y.js?v=0.8.3"></script>
Expand Down
43 changes: 35 additions & 8 deletions js/editor-core.js
Original file line number Diff line number Diff line change
Expand Up @@ -175,25 +175,38 @@
// edits otherwise persist; localStorage load manages its own cache.
window.document.addEventListener('hyperaudioInit', () => { captionCache = null; }, false);

document.querySelector('#caption-editor-btn').addEventListener('click', (e) => {
// Segmented view switch (transcript/captions): both segments stay clickable
// and the active one is marked by the track's thumb + aria-pressed rather
// than disabled.
// Clicking the active segment is a no-op — the transcription engines rely on
// that when they force transcript view by clicking #transcript-editor-btn.
const transcriptViewBtn = document.querySelector('#transcript-editor-btn');
const captionViewBtn = document.querySelector('#caption-editor-btn');

function reflectViewSwitch() {
document.querySelector('#view-switch').classList.toggle('captions-active', captionMode === true);
captionViewBtn.setAttribute('aria-pressed', String(captionMode === true));
transcriptViewBtn.setAttribute('aria-pressed', String(captionMode !== true));
}

captionViewBtn.addEventListener('click', () => {
if (captionMode === true) return;
let holder = document.querySelector('.transcript-holder');
transcriptCache = holder.cloneNode(true);
captionMode = true;
hyperaudioGenerateCaptionsFromTranscript();
document.querySelector('#caption-editor-btn').disabled = true;
document.querySelector('#transcript-editor-btn').disabled = false;
reflectViewSwitch();
});

document.querySelector('#transcript-editor-btn').addEventListener('click', (e) => {
transcriptViewBtn.addEventListener('click', () => {
if (captionMode !== true) return;
restoreTranscript();
captionMode = false;
if (transcriptRequiresInit === true) {
hyperaudio();
transcriptRequiresInit = false;
}

document.querySelector('#caption-editor-btn').disabled = false;
document.querySelector('#transcript-editor-btn').disabled = true;
reflectViewSwitch();
});


Expand Down Expand Up @@ -766,6 +779,11 @@
sidebarOpen = true;
}

document.querySelector('#sidebar-toggle').setAttribute('aria-pressed', String(sidebarOpen));
// lets the CSS align the navbar's leading edge with the transcript card,
// whose left gutter differs between the open and collapsed layouts
document.body.classList.toggle('sidebar-collapsed', sidebarOpen === false);

if(
document.pictureInPictureEnabled &&
!videoElement.disablePictureInPicture) {
Expand All @@ -780,7 +798,16 @@
}
}
});


// On small screens the same button opens the Recents drawer instead
// (responsive.js intercepts the click), so when the layout returns to
// desktop restore aria-pressed to the desktop sidebar state.
window.matchMedia('(max-width: 948px)').addEventListener('change', (ev) => {
if (!ev.matches) {
document.querySelector('#sidebar-toggle').setAttribute('aria-pressed', String(sidebarOpen));
}
});

let showSpeakers = document.querySelector('#show-speakers');

showSpeakers.addEventListener('change', function(e) {
Expand Down
4 changes: 2 additions & 2 deletions js/hyperaudio-lite-editor-assemblyai.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,8 @@ class AssemblyAIService extends HTMLElement {

getData() {
// If in caption mode, switch back to transcript view so the loader shows and
// the result lands in the right place (#transcript-editor-btn no-ops when
// already in transcript mode).
// the result lands in the right place (#transcript-editor-btn's handler
// no-ops when already in transcript mode).
document.querySelector('#transcript-editor-btn')?.click();
document.querySelector('#hypertranscript').innerHTML =
'<div class="vertically-centre"><center>Transcribing….</center><br/><img src="' + transcribingSvg + '" width="50" alt="transcribing" style="margin: auto; display: block;"></div>';
Expand Down
2 changes: 1 addition & 1 deletion js/hyperaudio-lite-editor-deepgram.js
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ class DeepgramService extends HTMLElement {
getData(event) {
// If the user is in caption mode, switch back to transcript view so the
// transcribing loader is visible and the result lands in the right place.
// #transcript-editor-btn is disabled in transcript mode, so this no-ops.
// #transcript-editor-btn's handler no-ops when already in transcript mode.
document.querySelector('#transcript-editor-btn')?.click();
document.querySelector('#hypertranscript').innerHTML = '<div class="vertically-centre"><center>Transcribing....</center><br/><img src="'+transcribingSvg+'" width="50" alt="transcribing" style="margin: auto; display: block;"></div>';
if (typeof setTranscriptBusy === 'function') {
Expand Down
2 changes: 1 addition & 1 deletion js/hyperaudio-lite-editor-whisper.js
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ function loadWhisperClient(modal, workerBaseUrl) {

// If the user is in caption mode, switch back to transcript view so the
// transcribing loader is visible and the result lands in the right place.
// #transcript-editor-btn is disabled in transcript mode, so this no-ops.
// #transcript-editor-btn's handler no-ops when already in transcript mode.
document.querySelector('#transcript-editor-btn')?.click();

const size = modelNameSelectionInput.value;
Expand Down
21 changes: 17 additions & 4 deletions js/responsive.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,18 @@
const mobile = window.matchMedia('(max-width: 948px)');

// --- Recents drawer --------------------------------------------------------
const openDrawer = () => body.classList.add('drawer-open');
const closeDrawer = () => body.classList.remove('drawer-open');
// Keep #sidebar-toggle's aria-pressed tracking the drawer while in the
// small-screen layout (editor-core.js owns it on desktop, where the same
// button collapses the sidebar instead).
const syncTogglePressed = () => {
const toggle = document.getElementById('sidebar-toggle');
if (toggle !== null && mobile.matches) {
toggle.setAttribute('aria-pressed', String(body.classList.contains('drawer-open')));
}
};

const openDrawer = () => { body.classList.add('drawer-open'); syncTogglePressed(); };
const closeDrawer = () => { body.classList.remove('drawer-open'); syncTogglePressed(); };

// Intercept #sidebar-toggle at the document capture phase so the desktop
// sidebar-collapse handler (in editor-core.js) does not also fire on mobile.
Expand All @@ -29,6 +39,7 @@
event.stopImmediatePropagation();
event.preventDefault();
body.classList.toggle('drawer-open');
syncTogglePressed();
}
}, true);

Expand All @@ -43,6 +54,8 @@
filePicker.addEventListener('click', () => { if (mobile.matches) closeDrawer(); });
}

// Leaving the small-screen layout clears any drawer state.
mobile.addEventListener('change', (ev) => { if (!ev.matches) closeDrawer(); });
// Leaving the small-screen layout clears any drawer state; entering it
// starts with the drawer closed.
mobile.addEventListener('change', (ev) => { if (!ev.matches) closeDrawer(); else syncTogglePressed(); });
syncTogglePressed();
})();
Loading