Fix scrolling UX with sticky header controls
This commit is contained in:
parent
191680940b
commit
e4ca2623cb
3 changed files with 91 additions and 53 deletions
|
|
@ -74,10 +74,13 @@
|
||||||
|
|
||||||
body {
|
body {
|
||||||
font-family: ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
|
font-family: ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
|
||||||
margin: 20px;
|
margin: 0;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
background-color: var(--bg);
|
background-color: var(--bg);
|
||||||
color: var(--text);
|
color: var(--text);
|
||||||
|
height: 100vh;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Record button */
|
/* Record button */
|
||||||
|
|
@ -168,9 +171,18 @@ body {
|
||||||
}
|
}
|
||||||
|
|
||||||
#status {
|
#status {
|
||||||
margin-top: 20px;
|
margin-top: 15px;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
color: var(--text);
|
color: var(--text);
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-container {
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
background-color: var(--bg);
|
||||||
|
z-index: 100;
|
||||||
|
padding: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Settings */
|
/* Settings */
|
||||||
|
|
@ -179,7 +191,6 @@ body {
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 15px;
|
gap: 15px;
|
||||||
margin-top: 20px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.settings {
|
.settings {
|
||||||
|
|
@ -297,9 +308,21 @@ label {
|
||||||
border-radius: 999px;
|
border-radius: 999px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.transcript-container {
|
||||||
|
flex: 1;
|
||||||
|
overflow-y: auto;
|
||||||
|
padding: 20px;
|
||||||
|
scrollbar-width: none;
|
||||||
|
-ms-overflow-style: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.transcript-container::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
/* Transcript area */
|
/* Transcript area */
|
||||||
#linesTranscript {
|
#linesTranscript {
|
||||||
margin: 20px auto;
|
margin: 0 auto;
|
||||||
max-width: 700px;
|
max-width: 700px;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
|
|
@ -407,6 +430,10 @@ label {
|
||||||
|
|
||||||
/* for smaller screens */
|
/* for smaller screens */
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
|
.header-container {
|
||||||
|
padding: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
.settings-container {
|
.settings-container {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 10px;
|
gap: 10px;
|
||||||
|
|
@ -430,11 +457,15 @@ label {
|
||||||
.theme-selector-container {
|
.theme-selector-container {
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.transcript-container {
|
||||||
|
padding: 15px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 480px) {
|
@media (max-width: 480px) {
|
||||||
body {
|
.header-container {
|
||||||
margin: 10px;
|
padding: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.settings {
|
.settings {
|
||||||
|
|
@ -457,4 +488,8 @@ label {
|
||||||
width: 14px;
|
width: 14px;
|
||||||
height: 14px;
|
height: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.transcript-container {
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,63 +9,63 @@
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div class="settings-container">
|
<div class="header-container">
|
||||||
<button id="recordButton">
|
<div class="settings-container">
|
||||||
<div class="shape-container">
|
<button id="recordButton">
|
||||||
<div class="shape"></div>
|
<div class="shape-container">
|
||||||
</div>
|
<div class="shape"></div>
|
||||||
<div class="recording-info">
|
|
||||||
<div class="wave-container">
|
|
||||||
<canvas id="waveCanvas"></canvas>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="timer">00:00</div>
|
<div class="recording-info">
|
||||||
</div>
|
<div class="wave-container">
|
||||||
</button>
|
<canvas id="waveCanvas"></canvas>
|
||||||
|
</div>
|
||||||
|
<div class="timer">00:00</div>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
|
||||||
<div class="settings">
|
<div class="settings">
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label for="websocketInput">Websocket URL</label>
|
<label for="websocketInput">Websocket URL</label>
|
||||||
<input id="websocketInput" type="text" placeholder="ws://host:port/asr" />
|
<input id="websocketInput" type="text" placeholder="ws://host:port/asr" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label id="microphoneSelectLabel" for="microphoneSelect">Select Microphone</label>
|
<label id="microphoneSelectLabel" for="microphoneSelect">Select Microphone</label>
|
||||||
<select id="microphoneSelect">
|
<select id="microphoneSelect">
|
||||||
<option value="">Default Microphone</option>
|
<option value="">Default Microphone</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="theme-selector-container">
|
<div class="theme-selector-container">
|
||||||
<div class="segmented" role="radiogroup" aria-label="Theme selector">
|
<div class="segmented" role="radiogroup" aria-label="Theme selector">
|
||||||
<input type="radio" id="theme-system" name="theme" value="system" />
|
<input type="radio" id="theme-system" name="theme" value="system" />
|
||||||
<label for="theme-system" title="System">
|
<label for="theme-system" title="System">
|
||||||
<img src="/web/src/system_mode.svg" alt="" />
|
<img src="/web/src/system_mode.svg" alt="" />
|
||||||
<span>System</span>
|
<span>System</span>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<input type="radio" id="theme-light" name="theme" value="light" />
|
<input type="radio" id="theme-light" name="theme" value="light" />
|
||||||
<label for="theme-light" title="Light">
|
<label for="theme-light" title="Light">
|
||||||
<img src="/web/src/light_mode.svg" alt="" />
|
<img src="/web/src/light_mode.svg" alt="" />
|
||||||
<span>Light</span>
|
<span>Light</span>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<input type="radio" id="theme-dark" name="theme" value="dark" />
|
<input type="radio" id="theme-dark" name="theme" value="dark" />
|
||||||
<label for="theme-dark" title="Dark">
|
<label for="theme-dark" title="Dark">
|
||||||
<img src="/web/src/dark_mode.svg" alt="" />
|
<img src="/web/src/dark_mode.svg" alt="" />
|
||||||
<span>Dark</span>
|
<span>Dark</span>
|
||||||
</label>
|
</label>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
<p id="status"></p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="transcript-container">
|
||||||
|
<div id="linesTranscript"></div>
|
||||||
<p id="status"></p>
|
</div>
|
||||||
|
|
||||||
<div id="linesTranscript"></div>
|
|
||||||
|
|
||||||
<script src="/web/live_transcription.js"></script>
|
<script src="/web/live_transcription.js"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|
|
||||||
|
|
@ -373,7 +373,10 @@ function renderLinesWithBuffer(
|
||||||
.join("");
|
.join("");
|
||||||
|
|
||||||
linesTranscriptDiv.innerHTML = linesHtml;
|
linesTranscriptDiv.innerHTML = linesHtml;
|
||||||
window.scrollTo({ top: document.body.scrollHeight, behavior: "smooth" });
|
const transcriptContainer = document.querySelector('.transcript-container');
|
||||||
|
if (transcriptContainer) {
|
||||||
|
transcriptContainer.scrollTo({ top: transcriptContainer.scrollHeight, behavior: "smooth" });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateTimer() {
|
function updateTimer() {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue