view src/chat.js @ 26:d3f5448743bf

add doc links
author Franklin Schmidt <fschmidt@gmail.com>
date Fri, 01 Aug 2025 17:12:03 -0600
parents 3a80ddafe5a4
children 176a182c02cf
line wrap: on
line source

'use strict';

function openRenameChat(name) {
	let dialog = document.querySelector('dialog[rename]');
	dialog.querySelector('input[name=name]').value = name;
	dialog.showModal();
}

function renameChat() {
	ajax(`rename_chat.js?chat=${chatId}`);
}

function saveRenameChat() {
	let dialog = document.querySelector('dialog[rename]');
	let name = dialog.querySelector('input[name=name]').value;
	ajax(`save_rename_chat.js?chat=${chatId}&name=${encodeURIComponent(name)}`);
	dialog.close();
}

function deleteChat() {
	let dialog = document.querySelector('dialog[delete]');
	dialog.showModal();
}

function doDeleteChat(el) {
	closeModal(el);
	ajax(`delete_chat.js?chat=${chatId}`);
}

function systemPrompt() {
	let dialog = document.querySelector('dialog[system_prompt]');
	dialog.showModal();
}

function showWaitingAiIcon() {
	document.querySelector('[waiting-ai-icon]').style.display = 'block';
}

function hideWaitingAiIcon() {
	document.querySelector('[waiting-ai-icon]').style.display = 'none';
}

function playLastMessage() {
	let audios = document.querySelectorAll('audio');
	if( audios.length >= 1 ) {
		let audio = audios[audios.length-1];
		audio.play();
	}
}

function updateAi(html) {
	hideWaitingAiIcon();
	document.querySelector('div[messages]').insertAdjacentHTML('beforeend',html);
	handleMarkdown();
	document.querySelector('textarea').focus();
	window.scrollTo(0, document.body.scrollHeight);
/*
	let scroll = aiDialog.querySelector('[scroll]');
	setTimeout(function(){
		scroll.scrollTo(0,scroll.scrollHeight);
	});
*/
	playLastMessage();
}

const isMobile = 'ontouchstart' in window || navigator.maxTouchPoints > 0 || navigator.msMaxTouchPoints > 0;

function textareaKey(event) {
	if( event.keyCode===13 && !event.shiftKey && !event.ctrlKey && !isMobile ) {
		event.preventDefault();
		askAi();
	}
}

function fixTextarea(textarea) {
	textarea.style.height = 'initial';
	textarea.style.height = (textarea.scrollHeight+2) + 'px';
	textarea.parentNode.scrollIntoViewIfNeeded(false);
}

function askAi() {
	let input = document.querySelector('textarea');
	let url = `ai_ask.js?chat=${chatId}&input=${encodeURIComponent(input.value)}`;
	ajax(url);
	input.value = '';
	fixTextarea(input);
	showWaitingAiIcon();
}


function setText(text) {
	let textarea = document.querySelector('textarea');
	textarea.value = text;
	fixTextarea(textarea);
}

let recorder = null;
let chunks;

function startRecording() {
	chunks = [];
	function record(stream) {
		recorder = new MediaRecorder( stream, { mimeType: 'audio/webm;codecs=opus' } );
		recorder.ondataavailable = function(event) {
			chunks.push(event.data);
		};
		recorder.onstop = function(event) {
			recorder = null;
			let blob = new Blob(chunks, { type: 'audio/webm' });
			let formData = new FormData();
			formData.append('audio', blob, 'recording.webm');
			ajax('stt.js',formData);
			document.querySelector('button[record]').textContent = 'Record';
		};
		recorder.start();
	}
	navigator.mediaDevices.getUserMedia({ audio: { channelCount: 1 } }).then(record);
	document.querySelector('button[record]').textContent = 'Stop Recording';
}

function toggleRecording() {
	if( recorder === null ) {
		startRecording();
	} else {
		recorder.stop();
	}
}