weclome-banner/javascripts/discourse/api-initializers/welcome-banner.js

113 lines
3.2 KiB
JavaScript

import { apiInitializer } from "discourse/lib/api";
export default apiInitializer("1.8.0", (api) => {
api.onPageChange((url) => {
const welcomeCard = document.querySelector(".welcome-card");
if (!welcomeCard) return;
const showOnPages = settings.theme_vars?.show_on_pages || "homepage_only";
if (showOnPages === "all_pages") {
// Show on all pages
welcomeCard.style.display = "block";
} else {
// Show only on homepage
if (url === "/") {
welcomeCard.style.display = "block";
} else {
welcomeCard.style.display = "none";
}
}
});
const isMobileView = () => document.body.classList.contains("mobile-view");
// Render search input with SearchMenu integration
function renderSearchInput() {
// Check if search is enabled in settings
const searchEnabled = settings.theme_vars?.enable_hero_search;
if (!searchEnabled) return;
if (isMobileView()) return;
// Try both possible positions for the banner
const container = document.querySelector(
".welcome-card .search-container"
);
if (!container) return;
// Idempotent: exit if already created
if (container.querySelector(".search-input")) return;
const wrapper = document.createElement("div");
wrapper.className = "search-wrapper";
wrapper.setAttribute("role", "search");
const input = document.createElement("input");
input.type = "text";
input.className = "search-input";
input.placeholder = settings.theme_vars?.search_placeholder || "Search...";
input.setAttribute("aria-label", "Search");
// Open and sync SearchMenu
const openSearchMenu = () => {
try {
api.openSearchMenu({
anchorElement: input,
mobileMode: false,
});
} catch (e) {
// Fallback if method not available
if (console?.debug) {
console.debug("SearchMenu API not available:", e);
}
}
};
const syncMenuQuery = () => {
const menuInput = document.querySelector(".search-menu input.search-query");
if (menuInput && menuInput !== input) {
menuInput.value = input.value;
menuInput.dispatchEvent(new Event("input", { bubbles: true }));
}
};
const handleSearchInteraction = () => {
openSearchMenu();
syncMenuQuery();
};
input.addEventListener("focus", handleSearchInteraction);
input.addEventListener("input", handleSearchInteraction);
input.addEventListener("keydown", (e) => {
if (e.key === "Enter") {
const q = input.value.trim();
if (!q) return;
const form = document.querySelector(".search-menu form");
const menuInput = document.querySelector(".search-menu input.search-query");
if (form && menuInput) {
menuInput.value = q;
form.dispatchEvent(new Event("submit", { bubbles: true }));
} else {
window.location.assign(`/search?q=${encodeURIComponent(q)}`);
}
}
});
wrapper.appendChild(input);
container.appendChild(wrapper);
}
const apply = () => {
renderSearchInput();
};
api.onAppEvent("page:changed", () => {
requestAnimationFrame(apply);
});
// Initial application
requestAnimationFrame(apply);
});