diff --git a/src/api/templates.js b/src/api/templates.js index 0ab5236..63e7c65 100644 --- a/src/api/templates.js +++ b/src/api/templates.js @@ -1,10 +1,25 @@ -const API_BASE = "/api"; +function apiBase() { + const raw = + (import.meta?.env?.VITE_API_BASE_URL || "") + .toString() + .replace(/\/+$/, ""); + if (raw) return raw + "/api"; + try { + if (typeof window !== "undefined") { + const host = window.location.hostname || ""; + if (host.startsWith("www.")) { + return `https://${host.replace(/^www\./, "")}/api`; + } + } + } catch {} + return "/api"; +} const cache = new Map(); // key -> Promise export async function fetchDefaultTemplate(typeKey = "news") { const t = (typeKey || "news").toLowerCase().trim(); - const res = await fetch(`${API_BASE}/templates/default?type=${encodeURIComponent(t)}`, { + const res = await fetch(`${apiBase()}/templates/default?type=${encodeURIComponent(t)}`, { credentials: "include", }); if (!res.ok) { diff --git a/src/components/Filters/TimeFilterButtons.jsx b/src/components/Filters/TimeFilterButtons.jsx index 41d5c57..47e8d80 100644 --- a/src/components/Filters/TimeFilterButtons.jsx +++ b/src/components/Filters/TimeFilterButtons.jsx @@ -5,7 +5,7 @@ export default function TimeFilterButtons({ active, onSelect }) { { code: "NOW", label: "Now", icon: "fa-solid fa-bolt" }, { code: "TODAY", label: "Today", icon: "fa-solid fa-sun" }, { code: "RECENT", label: "Recent", icon: "fa-solid fa-clock-rotate-left" }, - { code: "PAST", label: "Past", icon: "fa-solid fa-hourglass-half" }, + { code: "PAST", label: "Old", icon: "fa-solid fa-hourglass-half" }, ]; return ( diff --git a/src/components/Map/markerManager.js b/src/components/Map/markerManager.js index d02f813..268d4de 100644 --- a/src/components/Map/markerManager.js +++ b/src/components/Map/markerManager.js @@ -813,7 +813,6 @@ export function openCenteredOverlay({ map, post, theme, fullScreen = false }) {
MAIN NEWS
${author ? `
` : ""} - ${author ? `
` : ""} ${metaLeft ? `${escapeHtml(metaLeft)}` : ""} ${metaRight ? `• ${escapeHtml(metaRight)}` : ""} • ${escapeHtml(relTime)} @@ -893,7 +892,6 @@ export function openCenteredOverlay({ map, post, theme, fullScreen = false }) {
${escapeHtml(cat)}
${author ? `
` : ""} - ${author ? `
` : ""} ${metaLeft ? `${escapeHtml(metaLeft)}` : ""} ${metaRight ? `• ${escapeHtml(metaRight)}` : ""} • ${escapeHtml(relTime)} diff --git a/src/components/Map/usePostsEngine.js b/src/components/Map/usePostsEngine.js index 5e6d7b9..d346d39 100644 --- a/src/components/Map/usePostsEngine.js +++ b/src/components/Map/usePostsEngine.js @@ -858,9 +858,8 @@ export function usePostsEngine({ if (pc !== catCode) return false; } if (!matchesSubFilter(p, subFilter)) return false; - const skipTimeFilter = - tf === "RECENT" && lastFetchRef.current?.timeFilter === "RECENT"; - if (!skipTimeFilter && !matchesTimeFilter(effectivePostTime(p), tf)) return false; + const postTf = (p?._swTimeFilter || "").toString(); + if (postTf !== tf && !matchesTimeFilter(effectivePostTime(p), tf)) return false; if (!searchResultsRef.current && !matchesSearch(p, searchQuery)) return false; return true; }); @@ -1075,6 +1074,7 @@ export function usePostsEngine({ const normalized = normalizePostId(p); const key = getPostKey(normalized); if (!key) continue; + if (timeFilter) normalized._swTimeFilter = timeFilter; const prior = byId.get(key); if (prior) { byId.set(key, { ...prior, ...normalized }); diff --git a/src/components/Search/SmartSearchBar.jsx b/src/components/Search/SmartSearchBar.jsx index 39d2195..6a674a7 100644 --- a/src/components/Search/SmartSearchBar.jsx +++ b/src/components/Search/SmartSearchBar.jsx @@ -75,6 +75,7 @@ export default function SmartSearchBar({ const [active, setActive] = useState(-1); const [err, setErr] = useState(""); const [hasSearched, setHasSearched] = useState(false); + const [focused, setFocused] = useState(false); const abortRef = useRef(null); const skipSearchRef = useRef(false); @@ -98,6 +99,7 @@ export default function SmartSearchBar({ abortRef.current = ctrl; setLoading(true); setErr(""); + setOpen(true); try { console.log('[SmartSearchBar] Searching for:', searchQuery); @@ -112,6 +114,7 @@ export default function SmartSearchBar({ console.error('[SmartSearchBar] Search error:', e); setErr((e && e.message) ? e.message : "Search error"); setItems([]); + setOpen(true); } finally { if (!ctrl.signal.aborted) setLoading(false); } @@ -125,6 +128,8 @@ export default function SmartSearchBar({ return; } + if (query) setOpen(true); + if (abortRef.current) abortRef.current.abort(); const t = setTimeout(() => { @@ -137,7 +142,7 @@ export default function SmartSearchBar({ }; }, [q]); - const showList = open && (items.length > 0 || loading || err); + const showList = (open || focused) && (items.length > 0 || loading || err || q.trim()); const clearOnFocusRef = useRef(false); const pick = (it, reason = "click") => { @@ -214,6 +219,7 @@ export default function SmartSearchBar({ } }} onFocus={() => { + setFocused(true); if (clearOnFocusRef.current) { clearOnFocusRef.current = false; setQ(""); @@ -228,6 +234,9 @@ export default function SmartSearchBar({ triggerSearch(""); } }} + onBlur={() => { + setTimeout(() => setFocused(false), 120); + }} onKeyDown={onKeyDown} placeholder={placeholder} aria-label="Search"