add scrolling
This commit is contained in:
@@ -22,6 +22,7 @@ const scriptsLink = document.getElementById("scripts-link");
|
||||
const pluginsLink = document.getElementById("plugins-link");
|
||||
const rawServerListCheckbox = document.getElementById("raw-server-list");
|
||||
const serverUrlInput = document.getElementById("server-url");
|
||||
const serverUrlCurrentBtn = document.getElementById("server-url-current-btn");
|
||||
const solMemoCheckbox = document.getElementById("sol-memo");
|
||||
const solSettings = document.getElementById("sol-settings");
|
||||
const profileSelect = document.getElementById("build-profile-select");
|
||||
@@ -70,13 +71,25 @@ async function loadServerVersion() {
|
||||
|
||||
function getDefaultServerUrlPlaceholder(isRawList) {
|
||||
if (isRawList) {
|
||||
const isHttps = window.location.protocol === "https:";
|
||||
const host = window.location.host;
|
||||
return `${isHttps ? "https" : "http"}://${host}/list.txt`;
|
||||
return getCurrentRawServerListUrl();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
function getCurrentServerHost() {
|
||||
return window.location.host || window.location.hostname || "";
|
||||
}
|
||||
|
||||
function getCurrentRawServerListUrl() {
|
||||
const protocol = window.location.protocol === "https:" ? "https" : "http";
|
||||
const host = getCurrentServerHost();
|
||||
return host ? `${protocol}://${host}/list.txt` : "";
|
||||
}
|
||||
|
||||
function getCurrentServerUrlForMode() {
|
||||
return getCurrentServerHost();
|
||||
}
|
||||
|
||||
function stripServerUrlPrefix(value) {
|
||||
return String(value || "").replace(/^\s*(wss?|https?):\/\//i, "").trimStart();
|
||||
}
|
||||
@@ -93,9 +106,17 @@ function updateServerUrlPlaceholder() {
|
||||
if (!serverUrlInput) return;
|
||||
const isRaw = rawServerListCheckbox?.checked ?? false;
|
||||
serverUrlInput.placeholder = getDefaultServerUrlPlaceholder(isRaw);
|
||||
updateServerUrlCurrentButton();
|
||||
updateServerUrlHintMode();
|
||||
}
|
||||
|
||||
function updateServerUrlCurrentButton() {
|
||||
if (!serverUrlCurrentBtn) return;
|
||||
const isRaw = rawServerListCheckbox?.checked ?? false;
|
||||
serverUrlCurrentBtn.classList.toggle("hidden", isRaw);
|
||||
serverUrlCurrentBtn.disabled = isRaw;
|
||||
}
|
||||
|
||||
let isBuilding = false;
|
||||
|
||||
function initAccordions() {
|
||||
@@ -563,8 +584,7 @@ function applyFormSettings(settings) {
|
||||
solSettings.classList.toggle("hidden", !solMemoCheckbox.checked);
|
||||
}
|
||||
if (serverUrlInput && rawServerListCheckbox) {
|
||||
serverUrlInput.placeholder = getDefaultServerUrlPlaceholder(rawServerListCheckbox.checked);
|
||||
updateServerUrlHintMode();
|
||||
updateServerUrlPlaceholder();
|
||||
}
|
||||
applyCryptableMode(document.getElementById("cryptable-mode")?.checked || false);
|
||||
}
|
||||
@@ -836,10 +856,23 @@ if (rawServerListCheckbox && serverUrlInput) {
|
||||
// Non-raw mode: bare domain only. The agent prepends wss:// itself.
|
||||
serverUrlInput.value = stripServerUrlPrefix(current);
|
||||
}
|
||||
serverUrlInput.placeholder = getDefaultServerUrlPlaceholder(isRaw);
|
||||
updateServerUrlHintMode();
|
||||
updateServerUrlPlaceholder();
|
||||
});
|
||||
|
||||
if (serverUrlCurrentBtn) {
|
||||
serverUrlCurrentBtn.addEventListener("click", () => {
|
||||
if (solMemoCheckbox?.checked) {
|
||||
solMemoCheckbox.checked = false;
|
||||
if (solSettings) solSettings.classList.add("hidden");
|
||||
}
|
||||
serverUrlInput.value = getCurrentServerUrlForMode();
|
||||
serverUrlInput.dispatchEvent(new Event("input", { bubbles: true }));
|
||||
serverUrlInput.dispatchEvent(new Event("change", { bubbles: true }));
|
||||
saveFormSettings();
|
||||
serverUrlInput.focus();
|
||||
});
|
||||
}
|
||||
|
||||
// Live-strip protocol prefixes in non-raw mode so the field stays clean and
|
||||
// the user sees their typo corrected immediately.
|
||||
serverUrlInput.addEventListener("input", () => {
|
||||
@@ -891,9 +924,7 @@ if (solMemoCheckbox && solSettings) {
|
||||
|
||||
if (isSol && rawServerListCheckbox) {
|
||||
rawServerListCheckbox.checked = false;
|
||||
if (serverUrlInput) {
|
||||
serverUrlInput.placeholder = getDefaultServerUrlPlaceholder(false);
|
||||
}
|
||||
updateServerUrlPlaceholder();
|
||||
}
|
||||
|
||||
if (isSol) {
|
||||
|
||||
@@ -74,6 +74,10 @@ menuStyle.textContent = `
|
||||
border-radius: 8px;
|
||||
padding: 4px;
|
||||
min-width: 196px;
|
||||
max-height: calc(100vh - 16px);
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
overscroll-behavior: contain;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1px;
|
||||
@@ -92,6 +96,27 @@ menuStyle.textContent = `
|
||||
flex-direction: column;
|
||||
gap: 1px;
|
||||
z-index: 1;
|
||||
max-height: calc(100vh - 16px);
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
overscroll-behavior: contain;
|
||||
}
|
||||
#ctx-main, #ctx-sub {
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: rgba(148,163,184,0.35) transparent;
|
||||
}
|
||||
#ctx-main::-webkit-scrollbar,
|
||||
#ctx-sub::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
}
|
||||
#ctx-main::-webkit-scrollbar-thumb,
|
||||
#ctx-sub::-webkit-scrollbar-thumb {
|
||||
background: rgba(148,163,184,0.28);
|
||||
border-radius: 999px;
|
||||
}
|
||||
#ctx-main::-webkit-scrollbar-thumb:hover,
|
||||
#ctx-sub::-webkit-scrollbar-thumb:hover {
|
||||
background: rgba(148,163,184,0.45);
|
||||
}
|
||||
.ctx-row {
|
||||
display: flex;
|
||||
@@ -221,6 +246,8 @@ menuStyle.textContent = `
|
||||
}
|
||||
#ctx-main, #ctx-sub {
|
||||
box-shadow: 0 8px 40px rgba(0, 0, 0, 0.7);
|
||||
max-height: none;
|
||||
overflow: visible;
|
||||
}
|
||||
#ctx-sub { position: static; margin-top: 0; min-width: 0; width: 100%; border-radius: 0 0 8px 8px; border-top: 1px solid rgba(148,163,184,0.08); left: auto; right: auto; }
|
||||
#ctx-main { border-radius: 8px 8px 0 0; }
|
||||
@@ -290,12 +317,16 @@ function showSubmenu(groupId, rowEl) {
|
||||
const mainRect = ctxMain.getBoundingClientRect();
|
||||
let offsetY = rowRect.top - mainRect.top;
|
||||
|
||||
ctxSub.style.maxHeight = "calc(100vh - 16px)";
|
||||
const subH = ctxSub.offsetHeight;
|
||||
const menuTop = parseFloat(menu.style.top) || 0;
|
||||
if (menuTop + offsetY + subH > window.innerHeight - 8) {
|
||||
offsetY = Math.max(0, window.innerHeight - 8 - subH - menuTop);
|
||||
}
|
||||
ctxSub.style.top = offsetY + "px";
|
||||
const subTop = menuTop + offsetY;
|
||||
ctxSub.style.maxHeight = Math.max(120, window.innerHeight - subTop - 8) + "px";
|
||||
ctxSub.scrollTop = 0;
|
||||
|
||||
// Flip to left if submenu overflows right edge
|
||||
const subW = ctxSub.offsetWidth;
|
||||
@@ -396,6 +427,8 @@ export function openMenu(clientId, x, y, setContext, options = {}) {
|
||||
menu.style.top = "-9999px";
|
||||
menu.style.display = "flex";
|
||||
menu.setAttribute("aria-hidden", "false");
|
||||
ctxMain.scrollTop = 0;
|
||||
ctxSub.scrollTop = 0;
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
const mw = menu.offsetWidth;
|
||||
|
||||
Reference in New Issue
Block a user