Skip to content

Commit 832dd39

Browse files
author
kqlio67
committed
Refactor sidebar toggle and collapsible header animations for smoother UI.
- Extracted toggleSidebar function - Conditional sidebar state on settings - Improved header click animation - Replaced setTimeout with transitionend - Cleaned event listeners on headers
1 parent 6e597c7 commit 832dd39

File tree

1 file changed

+82
-36
lines changed

1 file changed

+82
-36
lines changed

g4f/gui/client/static/js/chat.v1.js

Lines changed: 82 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1888,17 +1888,22 @@ async function hide_settings() {
18881888

18891889
window.addEventListener('popstate', hide_sidebar, false);
18901890

1891+
// Create a reusable function for sidebar toggle logic
1892+
const toggleSidebar = async () => {
1893+
if (sidebar.classList.contains("expanded") ||
1894+
document.querySelector(".sidebar-button.rotated")) {
1895+
await hide_sidebar();
1896+
chat.classList.remove("hidden");
1897+
sidebar_buttons.forEach(btn => btn.classList.remove("rotated"));
1898+
} else {
1899+
await show_menu();
1900+
}
1901+
window.scrollTo(0, 0);
1902+
};
1903+
1904+
// Attach the event listener to each button with the reusable function
18911905
sidebar_buttons.forEach(button => {
1892-
button.addEventListener("click", async () => {
1893-
if (sidebar.classList.contains("expanded") || button.classList.contains("rotated")) {
1894-
await hide_sidebar();
1895-
chat.classList.remove("hidden");
1896-
sidebar_buttons.forEach(btn => btn.classList.remove("rotated"));
1897-
} else {
1898-
await show_menu();
1899-
}
1900-
window.scrollTo(0, 0);
1901-
});
1906+
button.addEventListener("click", toggleSidebar);
19021907
});
19031908

19041909
function add_url_to_history(url) {
@@ -1916,14 +1921,19 @@ async function show_menu() {
19161921

19171922
function open_settings() {
19181923
if (settings.classList.contains("hidden")) {
1924+
// Store current sidebar state before modifying it
1925+
const wasSidebarExpanded = sidebar.classList.contains("expanded");
1926+
19191927
chat.classList.add("hidden");
1920-
sidebar.classList.remove("expanded");
19211928
settings.classList.remove("hidden");
19221929
add_url_to_history("/chat/settings/");
19231930

1924-
// Make sure the sidebar is in collapsed state when settings are open
1925-
sidebar.classList.remove("expanded");
1926-
sidebar_buttons.forEach(btn => btn.classList.remove("rotated"));
1931+
// Only collapse sidebar when appropriate (not during specific UI states)
1932+
if (!document.body.classList.contains("mobile-view") &&
1933+
!document.body.classList.contains("transition-lock")) {
1934+
sidebar.classList.remove("expanded");
1935+
sidebar_buttons.forEach(btn => btn.classList.remove("rotated"));
1936+
}
19271937

19281938
// Show all hidden fields that should be visible
19291939
document.querySelectorAll('.settings .field.box.hidden').forEach(field => {
@@ -1938,34 +1948,70 @@ function open_settings() {
19381948
log_storage.classList.add("hidden");
19391949
}
19401950

1951+
// Store the event handler function as a named function
1952+
function handleCollapsibleHeaderClick(e) {
1953+
e.stopPropagation(); // Prevent event bubbling
1954+
this.classList.toggle('active');
1955+
const content = this.nextElementSibling;
1956+
1957+
if (content.classList.contains('hidden')) {
1958+
content.classList.remove('hidden');
1959+
content.style.display = "block";
1960+
setTimeout(() => {
1961+
content.style.maxHeight = (content.scrollHeight + 100) + "px";
1962+
}, 10);
1963+
} else {
1964+
content.style.maxHeight = "0";
1965+
setTimeout(() => {
1966+
content.classList.add('hidden');
1967+
content.style.display = "none";
1968+
}, 300);
1969+
}
1970+
}
1971+
1972+
// Function to handle collapsible header clicks with improved animation handling
1973+
function handleCollapsibleHeaderClick(e) {
1974+
e.stopPropagation(); // Prevent event bubbling
1975+
this.classList.toggle('active');
1976+
const content = this.nextElementSibling;
1977+
1978+
if (content.classList.contains('hidden')) {
1979+
// Show content immediately but with zero height
1980+
content.classList.remove('hidden');
1981+
content.style.display = "block";
1982+
content.style.maxHeight = "0";
1983+
1984+
// Use requestAnimationFrame to ensure browser has rendered the element
1985+
requestAnimationFrame(() => {
1986+
// Use a second frame to ensure CSS has applied
1987+
requestAnimationFrame(() => {
1988+
content.style.maxHeight = (content.scrollHeight + 100) + "px";
1989+
});
1990+
});
1991+
} else {
1992+
content.style.maxHeight = "0";
1993+
1994+
// Use the transitionend event instead of setTimeout
1995+
const transitionEndHandler = function() {
1996+
content.classList.add('hidden');
1997+
content.style.display = "none";
1998+
content.removeEventListener('transitionend', transitionEndHandler);
1999+
};
2000+
2001+
content.addEventListener('transitionend', transitionEndHandler);
2002+
}
2003+
}
2004+
19412005
// Function to handle collapsible fields
19422006
function setupCollapsibleFields() {
19432007
const collapsibleHeaders = document.querySelectorAll('.collapsible-header');
19442008

19452009
collapsibleHeaders.forEach(header => {
1946-
// Remove existing event listeners
1947-
const newHeader = header.cloneNode(true);
1948-
header.parentNode.replaceChild(newHeader, header);
2010+
// Properly remove existing event listeners
2011+
header.removeEventListener('click', handleCollapsibleHeaderClick);
19492012

1950-
newHeader.addEventListener('click', function(e) {
1951-
e.stopPropagation(); // Prevent event bubbling
1952-
this.classList.toggle('active');
1953-
const content = this.nextElementSibling;
1954-
1955-
if (content.classList.contains('hidden')) {
1956-
content.classList.remove('hidden');
1957-
content.style.display = "block";
1958-
setTimeout(() => {
1959-
content.style.maxHeight = (content.scrollHeight + 100) + "px";
1960-
}, 10);
1961-
} else {
1962-
content.style.maxHeight = "0";
1963-
setTimeout(() => {
1964-
content.classList.add('hidden');
1965-
content.style.display = "none";
1966-
}, 300);
1967-
}
1968-
});
2013+
// Add the event listener
2014+
header.addEventListener('click', handleCollapsibleHeaderClick);
19692015
});
19702016
}
19712017

0 commit comments

Comments
 (0)