Skip to content

Commit

Permalink
webui: fix autoscroll
Browse files Browse the repository at this point in the history
- fix wobbly scrolling on textarea update
- extract logging to method
  • Loading branch information
glwnd committed Dec 13, 2024
1 parent cb4ba55 commit 53b6f22
Showing 1 changed file with 55 additions and 63 deletions.
118 changes: 55 additions & 63 deletions pyglossary/ui/ui_web/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -98,14 +98,17 @@
height: auto;
font-family: 'Fira Mono', 'Jetbrains Mono', monospace;
}

#btnConvert {
font-size: 2em;
height: 2em;
}

pre {
font-size:7px;
font-size: 7px;
font-family: 'Fira Mono', 'Jetbrains Mono', Consolas, Monaco, Lucida Console, monospace;
}

article>textarea {
font-family: 'Fira Mono', 'Jetbrains Mono', Consolas, Monaco, Lucida Console, monospace;
font-size: smaller;
Expand All @@ -125,18 +128,19 @@
<h1>
<a style="text-decoration: none;" data-theme-switcher="auto" href="#" id="theme-switcher"
class="theme-switcher">
<svg height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<path
d="M12,18C11.11,18 10.26,17.8 9.5,17.45C11.56,16.5 13,14.42 13,12C13,9.58 11.56,7.5 9.5,6.55C10.26,6.2 11.11,6 12,6A6,6 0 0,1 18,12A6,6 0 0,1 12,18M20,8.69V4H15.31L12,0.69L8.69,4H4V8.69L0.69,12L4,15.31V20H8.69L12,23.31L15.31,20H20V15.31L23.31,12L20,8.69Z" />
</svg>
<!--noformat-->
<svg height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="M12,18C11.11,18 10.26,17.8 9.5,17.45C11.56,16.5 13,14.42 13,12C13,9.58 11.56,7.5 9.5,6.55C10.26,6.2 11.11,6 12,6A6,6 0 0,1 18,12A6,6 0 0,1 12,18M20,8.69V4H15.31L12,0.69L8.69,4H4V8.69L0.69,12L4,15.31V20H8.69L12,23.31L15.31,20H20V15.31L23.31,12L20,8.69Z"/></svg>
<!--noformat-->
</a> PyGlossary
</h1>
</li>
</ul>
<ul dir="rtl">
<li>
<details id="dropdown" class="dropdown">
<!--noformat-->
<summary role="button" class="outline"><svg height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="M3,6H21V8H3V6M3,11H21V13H3V11M3,16H21V18H3V16Z"/></svg></summary>
<!--noformat-->
<ul>
<li class="primary"><a id="clearDisplay" href="#">&#10006; Clear log</a></li>
<li class="primary"><a target="_blank"
Expand Down Expand Up @@ -241,61 +245,52 @@ <h5></h5>
<!-- Footer -->
<footer class="container">
<small><a target="_blank" href="https://github.com/ilius/pyglossary">
<svg xmlns="http://www.w3.org/2000/svg" height="20" viewBox="0 0 16 16" width="20" aria-hidden="true"
class="d-block">
<path fill="currentColor"
d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z">
</path>
</svg>
<!--noformat-->
<svg xmlns="http://www.w3.org/2000/svg" height="20" viewBox="0 0 16 16" width="20" aria-hidden="true" class="d-block"><path fill="currentColor" d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z"></path></svg>
<!--noformat-->
</a>
</small>
</footer>
<!-- ./ Footer -->
<!-- ConfigDialog -->
<dialog>
<article>
<h2>Conversion Options</h2>
<p>
Please enter valid JSON for custom conversion options.</p>
<p>Example config (See available options in <a target="_blank" href="https://ed-25q.pages.dev/#right=url.https://cdn.jsdelivr.net/gh/ilius/pyglossary/plugins-meta/index.json&left=url.https://y-bad.pages.dev/pyglossary-config.json">plugins options reference</a>):</p>
<section id="configExample">
<details>
<summary>&#x002B; Click for an example</summary>
<p><!--noformat-->
<h2>Conversion Options</h2>
<p>
Please enter valid JSON for custom conversion options.</p>
<p>Example config (See available options in <a target="_blank"
href="https://ed-25q.pages.dev/#right=url.https://cdn.jsdelivr.net/gh/ilius/pyglossary/plugins-meta/index.json&left=url.https://y-bad.pages.dev/pyglossary-config.json">plugins
options reference</a>):</p>
<section id="configExample">
<details>
<summary>&#x002B; Click for an example</summary>
<p><!--noformat-->
<pre>{
"convertOptions": {
"sort": true,
"sortKeyName": "headword_lower:es_ES",
"sortEncoding": "utf-8",
"sqlite": true
},
"readOptions": {
"encoding": "utf-8",
"audio": true,
"example_color": "blue",
"abbrev": "hover"
"example_color": "blue"
},
"writeOptions": {
"compression": "zlib",
"content_type": "text/html; charset=utf-8",
"separate_alternates": true,
"word_title": true,
"version_info": false
"resources": false
}
}</pre><!--noformat-->
</p>
</details>
</section>

<textarea id="allOptions" name="allOptions" id="" cols="30" rows="10"></textarea>
<footer>
<button id="btnOptCancel" class="secondary">
Cancel
</button>
<button id="btnOptOk">Confirm</button>
</footer>
</p>
</details>
</section>

<textarea id="allOptions" name="allOptions" id="" cols="30" rows="10"></textarea>
<footer>
<button id="btnOptCancel" class="secondary">
Cancel
</button>
<button id="btnOptOk">Confirm</button>
</footer>
</article>
</dialog>
</dialog>
<!-- ./ ConfigDialog -->

<script>
Expand Down Expand Up @@ -324,6 +319,11 @@ <h2>Conversion Options</h2>
const progressBar = document.getElementById('progress');
const progressText = document.getElementById('progress-text');

function log(msg) {
consoleArea.value += `${msg}\n`;
consoleArea.scrollTop = consoleArea.scrollHeight;
}

function initWsConnection() {
const socket = new WebSocket('/ws');
window.ws = socket;
Expand All @@ -341,31 +341,28 @@ <h2>Conversion Options</h2>
progressBar.value = message.ratio * 100;
progressText.innerText = message.text;
} else if (message.type == 'info') {
consoleArea.value += `${message.text}\n`;
log(message.text);
}

consoleArea.scrollIntoView({ behavior: "smooth", block: "end", inline: "start" });
});

socket.addEventListener('error', (error) => {
msg = `WebSocket error: ${error}\n`;
consoleArea.value += `${msg}\n`;
console.log(msg);
log(msg);
});

socket.addEventListener('close', () => {
console.log('WebSocket connection closed');
log('WebSocket connection closed');
});
}

function loadConfig() {
fetch("/config")
.then(response => {
if (!response.ok) {
consoleArea.value += `Failed to fetch configuration: ${response.status} ${response.text()}\n`;
log(`Failed to fetch configuration: ${response.status} ${response.text()}`);
return Promise.reject(`Failed to fetch configuration: ${response.statusText}`);
} else {
consoleArea.value += `config load ✔️\n`;
log('config load ✔️');
}
return response.json();
})
Expand Down Expand Up @@ -397,8 +394,7 @@ <h2>Conversion Options</h2>
attachListenersPostInit();
})
.catch(error => {
console.error("Error populating dropdowns:", error);
consoleArea.value += `Error populating dropdowns: ${error}\n`;
log(`Error populating dropdowns: ${error}`);
});
}

Expand All @@ -418,12 +414,12 @@ <h2>Conversion Options</h2>
document.querySelector('input[type="submit"]').addEventListener('click', async (event) => {

progressBar.value = 0;
consoleArea.value = 'Starting new conversion job. Please wait... ⏳\n';
log('Starting new conversion job. Please wait... ⏳');
const form = event.target.form;

if (form.checkValidity()) {
event.preventDefault();
consoleArea.value += '\nConversion started, please wait...\n';
log('Conversion started, please wait...');

const inputFilename = form.inputFilename.value;
const inputFormat = form.inputFormat.value;
Expand Down Expand Up @@ -451,16 +447,12 @@ <h2>Conversion Options</h2>
});

if (!response.ok) {
const msg = `Failed to start conversion: ${response.statusText} ${response.json()}\n`
consoleArea.value += `${msg}\n`;
throw new Error(msg);

log(`Failed to start conversion: ${response.statusText} ${response.json()}`);
}
toggleConvertButton();

} catch (error) {
console.error('Error during conversion:', error);
consoleArea.value += `${error}\n`;
log(`Error during conversion: ${error}`);
toggleConvertButton();
}
}
Expand All @@ -478,7 +470,7 @@ <h2>Conversion Options</h2>
ws.send('exit');
}
document.getElementById('dropdown').removeAttribute('open')
consoleArea.value = 'Server stopped! Window can now be closed.\n\n';
log('Server stopped! Window can now be closed.');
});

document.getElementById('btnOptions').addEventListener('click', (evt) => {
Expand All @@ -503,10 +495,10 @@ <h2>Conversion Options</h2>
try {
const allOptionsObj = JSON.parse(allOptions);
localStorage.setItem(KEY_PG_OPTIONS, JSON.stringify(allOptionsObj))
consoleArea.value += `options saved ✔️\n${allOptions}\n`;
log(`options saved ✔️\n${allOptions}`);
} catch (error) {
console.error('Invalid JSON string:', error.message);
consoleArea.value += `invalid options ${error.message} JSON\n`;
log(`invalid options ${error.message} JSON\n`);
}

toggleAttr(optionsDialog, 'open');
Expand All @@ -518,7 +510,7 @@ <h2>Conversion Options</h2>
evt.stopImmediatePropagation();
const optionsDialog = document.querySelector('dialog');
toggleAttr(optionsDialog, 'open');
consoleArea.value += 'options dialog cancelled without saving\n';
log('options dialog cancelled without saving');
});

FIELD_IDS_PERSISTABLE.forEach(fieldId => {
Expand Down

0 comments on commit 53b6f22

Please sign in to comment.