fix more stuff and improve styling immensely
This commit is contained in:
+14
-1
@@ -2,6 +2,7 @@ export async function request(url, data, method = "POST") {
|
||||
try {
|
||||
const res = await fetch(url, {
|
||||
method,
|
||||
credentials: "same-origin",
|
||||
headers: {"Content-Type": "application/json"},
|
||||
body: data ? JSON.stringify(data) : undefined
|
||||
});
|
||||
@@ -19,12 +20,24 @@ export const del = (url) => request(url, null, "DELETE");
|
||||
export async function stream(url, data, handlers = {}) {
|
||||
const response = await fetch(url, {
|
||||
method: "POST",
|
||||
credentials: "same-origin",
|
||||
headers: {"Content-Type": "application/json"},
|
||||
body: JSON.stringify(data || {})
|
||||
});
|
||||
|
||||
if (!response.ok || !response.body) {
|
||||
throw new Error("Streaming request failed");
|
||||
let error = "Streaming request failed";
|
||||
try {
|
||||
const payload = await response.json();
|
||||
error = payload.error || error;
|
||||
} catch {
|
||||
// Keep the generic error if the server did not send JSON.
|
||||
}
|
||||
if (handlers.onError) {
|
||||
handlers.onError({error});
|
||||
return;
|
||||
}
|
||||
throw new Error(error);
|
||||
}
|
||||
|
||||
const reader = response.body.getReader();
|
||||
|
||||
@@ -1,11 +1,41 @@
|
||||
import {chatDrawer, chatDrawerButton, chatDrawerCloseBtn} from "./dom.js";
|
||||
|
||||
let lastFocusedElement = null;
|
||||
|
||||
const focusableSelector = [
|
||||
"a[href]",
|
||||
"button:not([disabled])",
|
||||
"textarea:not([disabled])",
|
||||
"input:not([disabled])",
|
||||
"select:not([disabled])",
|
||||
"summary",
|
||||
"[tabindex]:not([tabindex='-1'])"
|
||||
].join(",");
|
||||
|
||||
function getFocusableElements() {
|
||||
if (!chatDrawer) return [];
|
||||
return Array.from(chatDrawer.querySelectorAll(focusableSelector))
|
||||
.filter((element) => element instanceof HTMLElement && element.offsetParent !== null);
|
||||
}
|
||||
|
||||
function syncChatDrawerState(isOpen) {
|
||||
if (!chatDrawer || !chatDrawerButton) return;
|
||||
if (isOpen) document.body.classList.remove("sidebar-open");
|
||||
if (isOpen) {
|
||||
lastFocusedElement = document.activeElement instanceof HTMLElement ? document.activeElement : null;
|
||||
document.body.classList.remove("sidebar-open");
|
||||
}
|
||||
chatDrawer.classList.toggle("hidden", !isOpen);
|
||||
chatDrawerButton.setAttribute("aria-expanded", String(isOpen));
|
||||
document.body.classList.toggle("chat-drawer-open", isOpen);
|
||||
if (isOpen) {
|
||||
window.requestAnimationFrame(() => {
|
||||
const firstFocusable = getFocusableElements()[0];
|
||||
(chatDrawerCloseBtn || firstFocusable)?.focus();
|
||||
});
|
||||
} else if (lastFocusedElement) {
|
||||
lastFocusedElement.focus();
|
||||
lastFocusedElement = null;
|
||||
}
|
||||
}
|
||||
|
||||
function isChatDrawerOpen() {
|
||||
@@ -34,7 +64,27 @@ function handleDocumentClick(event) {
|
||||
}
|
||||
|
||||
function handleDocumentKeydown(event) {
|
||||
if (event.key === "Escape") closeChatDrawer();
|
||||
if (!isChatDrawerOpen()) return;
|
||||
if (event.key === "Escape") {
|
||||
closeChatDrawer();
|
||||
return;
|
||||
}
|
||||
if (event.key !== "Tab") return;
|
||||
|
||||
const focusableElements = getFocusableElements();
|
||||
if (!focusableElements.length) return;
|
||||
|
||||
const first = focusableElements[0];
|
||||
const last = focusableElements[focusableElements.length - 1];
|
||||
if (event.shiftKey && document.activeElement === first) {
|
||||
event.preventDefault();
|
||||
last.focus();
|
||||
return;
|
||||
}
|
||||
if (!event.shiftKey && document.activeElement === last) {
|
||||
event.preventDefault();
|
||||
first.focus();
|
||||
}
|
||||
}
|
||||
|
||||
if (chatDrawerButton && chatDrawer) {
|
||||
|
||||
@@ -26,6 +26,7 @@ const registerSubmit = $("registerSubmit");
|
||||
const chatList = $("chatList");
|
||||
const chatSearchInput = $("chatSearch");
|
||||
const chatSidebar = $("chatSidebar");
|
||||
const chatSidebarToggle = $("chatSidebarToggle");
|
||||
const chatDrawerCloseBtn = $("chatDrawerClose");
|
||||
const chatDrawerButton = $("chatDrawerButton");
|
||||
const chatDrawer = $("chatDrawer");
|
||||
@@ -123,6 +124,7 @@ export {
|
||||
chatListLoading,
|
||||
chatListLoadingText,
|
||||
chatSidebar,
|
||||
chatSidebarToggle,
|
||||
chatDrawerCloseBtn,
|
||||
chatSearchInput,
|
||||
chatUserPersonaPill,
|
||||
|
||||
Reference in New Issue
Block a user