fewd/priv/static/js/ts/index.ts
2025-10-24 13:57:37 -07:00

166 lines
4.4 KiB
TypeScript

/**
* Home page ts/js
*
* @module
*/
//------------------------------------------------------------------
// page element stuff
//------------------------------------------------------------------
main();
function
main
()
: void
{
let ielt : HTMLInputElement = document.getElementById('wfc-input') as HTMLInputElement ;
let oelt : HTMLTextAreaElement = document.getElementById('wfc-output') as HTMLTextAreaElement ;
let cb_resize : HTMLInputElement = document.getElementById('auto-resize-output') as HTMLInputElement ;
let cb_scroll : HTMLInputElement = document.getElementById('auto-scroll') as HTMLInputElement ;
let MAX_OELT_HEIGHT : number = 300;
ielt.addEventListener('keydown',
function(e: KeyboardEvent) {
on_input_key(e, ielt, oelt, cb_resize, cb_scroll, MAX_OELT_HEIGHT);
}
);
}
// when user hits any key
async function
on_input_key
(evt : KeyboardEvent,
ielt : HTMLInputElement,
oelt : HTMLTextAreaElement,
cb_resize : HTMLInputElement,
cb_scroll : HTMLInputElement,
max_height : number)
: Promise<void>
{
if (evt.key === 'Enter') {
// don't do default thing
evt.preventDefault();
// grab contents
let contents : string = ielt.value;
let trimmed : string = contents.trim();
let nonempty : boolean = trimmed.length > 0;
// if contents are nonempty
if (nonempty) {
// clear input
ielt.value = '';
// put in output
oelt.value += '> ' + trimmed + '\n';
oelt.hidden = false;
// query backend for result
let result : wfcout = await fetch_wfcin(trimmed);
if (result.ok)
oelt.value += result.result;
else
oelt.value += result.error;
oelt.value += '\n';
// auto-resize
auto_resize_output(cb_resize, oelt, max_height);
auto_scroll_to_bottom(cb_scroll, oelt);
}
}
}
function
auto_resize_output
(checkbox_element : HTMLInputElement,
target_element : HTMLTextAreaElement,
max_height : number)
: void
{
// if the user has manually resized their output, we do nothing
if (checkbox_element.checked) {
let target_height: number = target_element.scrollHeight;
// resize it automagically up to 500px
if (target_height < max_height)
target_element.style.height = String(target_height) + 'px';
else
target_element.style.height = String(max_height) + 'px';
}
}
function
auto_scroll_to_bottom
(checkbox_element : HTMLInputElement,
target_element : HTMLTextAreaElement)
: void
{
if (checkbox_element.checked) {
// scroll to bottom
target_element.scrollTop = target_element.scrollHeight;
}
}
//------------------------------------------------------------------
// wfc api
//------------------------------------------------------------------
type ok_err<t> = {ok: true, result: t}
| {ok: false, error: string};
type wfcin = {wfcin: string};
type wfcout = ok_err<string>;
function
assert
(condition : boolean,
fail_msg : string)
: void
{
if(!condition)
throw new Error(fail_msg);
}
async function
fetch_wfcin
(user_line : string)
: Promise<wfcout>
{
let req_body_obj = {wfcin: user_line};
let req_body_str = JSON.stringify(req_body_obj);
let req_options = {method: 'POST',
headers: {'content-type': 'application/json'},
body: req_body_str};
// default result = somehow neither branch of code below was run(?)
// putting this here so ts doesn't chimp out
let result: wfcout = {ok : false,
error : 'IT DO BE LIKE THAT MISTA STANCIL'};
try {
let response : Response = await fetch('/wfcin', req_options);
if (response.ok)
result = await response.json() as wfcout;
else {
console.log('bad http response:', response);
result = {ok: false, error: 'BAD HTTP RESPONSE'};
}
}
catch (x: any) {
console.log('network error:', x);
result = {ok: false, error: 'NETWORK ERROR'};
}
return result;
}