From f78a14b79cf38753e0290e78b47bb73717f5d967 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=F0=93=8D=BC?= <143974574+xojw@users.noreply.github.com> Date: Thu, 5 Jun 2025 22:49:17 -0500 Subject: [PATCH] Something --- public/!!.html | 41 +- public/!.html | 38 +- public/$.html | 38 +- public/assets/js/$.js | 761 ++++++++++++++++++------------ public/assets/js/greetings.js | 143 +++--- public/assets/js/latest-commit.js | 13 - public/assets/js/load.js | 21 - public/assets/js/navbar.js | 183 ------- 8 files changed, 614 insertions(+), 624 deletions(-) delete mode 100644 public/assets/js/latest-commit.js delete mode 100644 public/assets/js/load.js delete mode 100644 public/assets/js/navbar.js diff --git a/public/!!.html b/public/!!.html index c11d8c6d..a0a431d4 100644 --- a/public/!!.html +++ b/public/!!.html @@ -14,19 +14,39 @@ + - - - + + - - @@ -34,7 +54,6 @@ -
@@ -99,15 +118,5 @@ - - \ No newline at end of file diff --git a/public/!.html b/public/!.html index 7a08b973..4692002b 100644 --- a/public/!.html +++ b/public/!.html @@ -18,15 +18,37 @@ - + + + - - @@ -98,15 +120,5 @@ - - \ No newline at end of file diff --git a/public/$.html b/public/$.html index f3c8035e..cbc397a7 100644 --- a/public/$.html +++ b/public/$.html @@ -16,22 +16,42 @@ - + + - - - @@ -109,15 +129,5 @@ - - \ No newline at end of file diff --git a/public/assets/js/$.js b/public/assets/js/$.js index b4045c8c..62ec0deb 100644 --- a/public/assets/js/$.js +++ b/public/assets/js/$.js @@ -1,293 +1,470 @@ document.addEventListener('DOMContentLoaded', () => { - const historyStack = [] - let currentIndex = -1 - const refreshIcon = document.getElementById('refreshIcon') - const fullscreenIcon = document.getElementById('fullscreenIcon') - const backIcon = document.getElementById('backIcon') - const forwardIcon = document.getElementById('forwardIcon') - const iframe = document.getElementById('cool-iframe') - const erudaLoadingScreen = document.getElementById('erudaLoadingScreen') - if (!refreshIcon || !fullscreenIcon || !backIcon || !forwardIcon || !iframe) return - const originalTitle = document.title - let loadingHidden = false - function showLoadingScreen(withToast = true, showEruda = false) { - loadingHidden = false - NProgress.start() - document.title = 'Loading... <3' - if (withToast) { - showToast( - 'Consider joining our Discord <3', - 'success', - 'heart' - ) - } - } - function hideLoadingScreen() { - if (loadingHidden) return - loadingHidden = true - NProgress.done() - document.title = originalTitle - } - refreshIcon.addEventListener('click', () => { - refreshIcon.classList.add('spin') - if (iframe.tagName === 'IFRAME') { - const currentUrl = iframe.contentWindow.location.href - if (normalizeUrl(currentUrl) !== normalizeUrl(historyStack[currentIndex] || '')) { - addToHistory(currentUrl) - } - iframe.contentWindow.location.reload(true) - } - setTimeout(() => refreshIcon.classList.remove('spin'), 300) - }) - fullscreenIcon.addEventListener('click', () => { - if (iframe.requestFullscreen) iframe.requestFullscreen() - else if (iframe.mozRequestFullScreen) iframe.mozRequestFullScreen() - else if (iframe.webkitRequestFullscreen) iframe.webkitRequestFullscreen() - else if (iframe.msRequestFullscreen) iframe.msRequestFullscreen() - }) - backIcon.addEventListener('click', () => { - if (currentIndex > 0) { - currentIndex-- - iframe.src = historyStack[currentIndex] - showLoadingScreen(false, false) - updateNavButtons() - updateDecodedSearchInput() - } - }) - forwardIcon.addEventListener('click', () => { - if (currentIndex < historyStack.length - 1) { - currentIndex++ - iframe.src = historyStack[currentIndex] - showLoadingScreen(false, false) - updateNavButtons() - updateDecodedSearchInput() - } - }) - function normalizeUrl(urlStr) { - try { - const url = new URL(urlStr) - url.searchParams.delete('ia') - return url.toString() - } catch { - return urlStr - } - } - function addToHistory(url) { - const normalized = normalizeUrl(url) - if (currentIndex >= 0 && normalizeUrl(historyStack[currentIndex]) === normalized) return - if (currentIndex < historyStack.length - 1) historyStack.splice(currentIndex + 1) - historyStack.push(url) - currentIndex++ - updateNavButtons() - updateDecodedSearchInput() - } - function updateNavButtons() { - backIcon.disabled = currentIndex <= 0 - forwardIcon.disabled = currentIndex >= historyStack.length - 1 - backIcon.classList.toggle('disabled', currentIndex <= 0) - forwardIcon.classList.toggle('disabled', currentIndex >= historyStack.length - 1) - } - function updateDecodedSearchInput() { - const searchInput2 = document.getElementById('searchInputt') - if (!searchInput2) return - let url = '' - if (currentIndex >= 0 && historyStack[currentIndex]) { - url = historyStack[currentIndex] - } else if (iframe.src) { - url = iframe.src - } - searchInput2.value = decodeUrl(url) - const lockIcon = document.getElementById('lockIcon') - if (lockIcon) { - lockIcon.className = decodeUrl(url).startsWith('https://') ? - 'fa-regular fa-lock' : - 'fa-regular fa-lock-open' - lockIcon.style.color = '' - } - } - iframe.addEventListener('load', () => { - try { - hideLoadingScreen() - } catch { - hideLoadingScreen() - } finally { - if (erudaLoadingScreen) erudaLoadingScreen.style.display = 'none' - } - }) - iframe.addEventListener('error', () => { - hideLoadingScreen() - }) - iframe.addEventListener('loadstart', () => { - const navBar = document.querySelector('.navbar') - const navbarToggle = document.getElementById('navbar-toggle') - if (navbarToggle && navbarToggle.checked && navBar) navBar.style.display = 'block' - showLoadingScreen(false, false) - }) - const navBar = document.querySelector('.navbar') - const topBar = document.querySelector('.topbar') - const searchInput1 = document.getElementById('searchInput') - const searchInput2 = document.getElementById('searchInputt') - const movies = document.getElementById('movies') - const ai = document.getElementById('ai') - const navbarToggle = document.getElementById('navbar-toggle') - if (navbarToggle && navBar) { - const savedNavbarState = localStorage.getItem('navbarToggled') - navbarToggle.checked = savedNavbarState === null ? true : savedNavbarState === 'true' - navBar.style.display = iframe.style.display === 'block' && navbarToggle.checked ? 'block' : 'none' - navbarToggle.addEventListener('change', () => { - localStorage.setItem('navbarToggled', navbarToggle.checked) - navBar.style.display = iframe.style.display === 'block' && navbarToggle.checked ? 'block' : 'none' - }) - } - iframe.style.display = 'none' - window.addEventListener('load', hideLoadingScreen) - ;[searchInput1, searchInput2].forEach(input => { - if (input) { - input.addEventListener('keyup', e => { - if (e.key === 'Enter') { - const val = input.value.trim() - if (val) handleSearch(val) - else showToast('Please enter something in the Search Bar.', 'error', 'warning') - } - }) - } - }) - if (movies) movies.addEventListener('click', e => { - e.preventDefault() - handleSearch('https://movies.usewaves.site/') - }) - if (ai) ai.addEventListener('click', e => { - e.preventDefault() - handleSearch('https://ai.usewaves.site/') - }) - function clearBackground() { - const preserved = [ - document.querySelector('.navbar'), - document.getElementById('cool-iframe'), - document.querySelector('.loading-screen'), - erudaLoadingScreen - ] - Array.from(document.body.children).forEach(child => { - if (!preserved.includes(child)) child.remove() - }) - } - async function handleSearch(query) { - if (!query || !query.trim()) { - showToast('Please enter something in the Search Bar.', 'error', 'warning') - return - } - clearBackground() - let searchURL - if ( - query.startsWith('/assets/g/') || - query.startsWith(window.location.origin + '/assets/g/') - ) { - searchURL = query - } else { - searchURL = generateSearchUrl(query) - } - if (searchInput2) searchInput2.value = searchURL - historyStack.length = 0 - currentIndex = -1 - showLoadingScreen(true, false) - iframe.style.display = 'block' - if (topBar) topBar.style.display = 'none' - backIcon.disabled = forwardIcon.disabled = true - let finalUrl - try { - const u = new URL(searchURL, window.location.origin) - if (u.origin === window.location.origin && u.pathname.startsWith('/assets/g/')) { - finalUrl = u.href - } else { - finalUrl = await getUrl(searchURL) - } - } catch { - finalUrl = await getUrl(searchURL) - } - iframe.src = finalUrl - iframe.onload = () => { - hideLoadingScreen() - if (navbarToggle && navbarToggle.checked && navBar) navBar.style.display = 'block' - generateSubject() - updateDecodedSearchInput() - } - iframe.onerror = () => { - hideLoadingScreen() - } - } - window.handleSearch = handleSearch - function generateSearchUrl(query) { - try { - return new URL(query).toString() - } catch { - try { - const u = new URL(`https://${query}`) - if (u.hostname.includes('.')) return u.toString() - } catch {} - } - return `https://duckduckgo.com/search?q=${encodeURIComponent(query)}&ia=web` - } - function showToast(message, type = 'success', iconType = 'check') { - const toast = document.createElement('div') - toast.className = `toast show ${type}` - const icons = { - success: '', - error: '', - info: '', - warning: '', - heart: '' - } - const icon = icons[iconType] || icons.heart - toast.innerHTML = `${icon}${message} ` - const progressBar = document.createElement('div') - progressBar.className = 'progress-bar' - toast.appendChild(progressBar) - const closeBtn = document.createElement('button') - closeBtn.className = 'toast-close' - closeBtn.innerHTML = '' - closeBtn.addEventListener('click', () => { - toast.classList.add('hide') - setTimeout(() => toast.remove(), 500) - }) - toast.appendChild(closeBtn) - document.body.appendChild(toast) - setTimeout(() => { - toast.classList.add('hide') - setTimeout(() => toast.remove(), 500) - }, 3000) - } - function preloadResources(url) { - if (!url) return - try { - const link = document.createElement('link') - link.rel = 'preload' - link.href = url - link.as = 'fetch' - link.crossOrigin = 'anonymous' - document.head.appendChild(link) - } catch {} - } - function getUrl(url) { - return Promise.resolve(__uv$config.prefix + __uv$config.encodeUrl(url)) - } - function generateSubject() { - const subjects = ['math', 'science', 'history', 'art', 'programming', 'philosophy'] - const random = subjects[Math.floor(Math.random() * subjects.length)] - history.replaceState({}, '', '/learning?subject=' + random) - } - function decodeUrl(enc) { - try { - const o = new URL(enc, window.location.origin) - const p = (__uv$config && __uv$config.prefix) || '/wa/a/' - if (o.pathname.startsWith(p)) { - const part = o.pathname.slice(p.length) - return (__uv$config.decodeUrl ? __uv$config.decodeUrl(part) : decodeURIComponent(part)) - } - } catch {} - return enc - } - window.decodeUrl = decodeUrl - window.addToHistory = addToHistory - window.updateDecodedSearchInput = updateDecodedSearchInput - window.normalizeUrl = normalizeUrl -}) \ No newline at end of file + window.APP = {}; + + const iframe = document.getElementById('cool-iframe'); + const erudaLoadingScreen = document.getElementById('erudaLoadingScreen'); + const searchInput1 = document.getElementById('searchInput'); + const movies = document.getElementById('movies'); + const ai = document.getElementById('ai'); + const topBar = document.querySelector('.topbar'); + const refreshIcon = document.getElementById('refreshIcon'); + const fullscreenIcon = document.getElementById('fullscreenIcon'); + const backIcon = document.getElementById('backIcon'); + const forwardIcon = document.getElementById('forwardIcon'); + const searchInput2 = document.getElementById('searchInputt'); + const lockIcon = document.getElementById('lockIcon'); + const navbarToggle = document.getElementById('navbar-toggle'); + const navBar = document.querySelector('.navbar'); + + const historyStack = []; + let currentIndex = -1; + const originalTitle = document.title; + let isLoading = false; + + if (!iframe || !refreshIcon || !fullscreenIcon || !backIcon || !forwardIcon) { + return; + } + + const animationStyle = document.createElement('style'); + animationStyle.textContent = ` + @keyframes slideLeft {0% { transform: translateX(0); } 50% { transform: translateX(-5px); } 100% { transform: translateX(0); }} + @keyframes slideRight {0% { transform: translateX(0); } 50% { transform: translateX(5px); } 100% { transform: translateX(0); }} + .button-animate-back { animation: slideLeft 0.3s ease-in-out; } + .button-animate-forward { animation: slideRight 0.3s ease-in-out; } + .spin { animation: spinAnimation 0.3s linear; } + @keyframes spinAnimation { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } + `; + document.head.appendChild(animationStyle); + + function showLoadingScreen(withToast = true) { + if (isLoading) return; + isLoading = true; + if (typeof NProgress !== 'undefined') NProgress.start(); + + if (withToast) { + showToast( + 'Consider joining our Discord <3', + 'success', + 'heart' + ); + } + } + + function hideLoadingScreen() { + if (!isLoading) return; + if (typeof NProgress !== 'undefined') NProgress.done(); + document.title = originalTitle; + isLoading = false; + if (erudaLoadingScreen) erudaLoadingScreen.style.display = 'none'; + } + + function normalizeUrl(urlStr) { + if (!urlStr || urlStr === 'about:blank') return urlStr; + try { + const url = new URL(urlStr); + url.searchParams.delete('ia'); + return url.toString(); + } catch { + return urlStr; + } + } + + function decodeUrl(encodedUrl) { + if (!encodedUrl) return ''; + try { + const prefix = (typeof __uv$config !== 'undefined' && __uv$config.prefix) ? __uv$config.prefix : '/wa/a/'; + const decodeFunction = (typeof __uv$config !== 'undefined' && __uv$config.decodeUrl) ? __uv$config.decodeUrl : decodeURIComponent; + const urlObject = new URL(encodedUrl, window.location.origin); + if (urlObject.pathname.startsWith(prefix)) { + const encodedPart = urlObject.pathname.slice(prefix.length); + return decodeFunction(encodedPart) + urlObject.search + urlObject.hash; + } + } catch {} + try { + return decodeURIComponent(encodedUrl); + } catch { + return encodedUrl; + } + } + + function updateNavButtons() { + if (!backIcon || !forwardIcon) return; + const canGoBack = currentIndex > 0; + const canGoForward = currentIndex < historyStack.length - 1; + backIcon.disabled = !canGoBack; + forwardIcon.disabled = !canGoForward; + backIcon.classList.toggle('disabled', !canGoBack); + forwardIcon.classList.toggle('disabled', !canGoForward); + } + + function updateDecodedSearchInput() { + if (!searchInput2) return; + let currentUrl = ''; + if (currentIndex >= 0 && historyStack[currentIndex]) { + currentUrl = historyStack[currentIndex]; + } else if (iframe.src && iframe.src !== 'about:blank') { + currentUrl = iframe.src; + } + const decoded = decodeUrl(currentUrl); + searchInput2.value = decoded; + + if (lockIcon) { + const isSecure = decoded.startsWith('https://'); + lockIcon.className = isSecure ? 'fa-regular fa-lock' : 'fa-regular fa-lock-open'; + } + } + + function addToHistory(url, isReplacingCurrent = false) { + if (!url || url === 'about:blank') return; + + const normalizedNewUrl = normalizeUrl(url); + const currentHistoryEntry = historyStack[currentIndex]; + const normalizedCurrentHistoryEntry = currentIndex >= 0 ? normalizeUrl(currentHistoryEntry) : null; + + if (isReplacingCurrent && currentIndex >= 0) { + if (normalizedCurrentHistoryEntry !== normalizedNewUrl || currentHistoryEntry !== url) { + historyStack[currentIndex] = url; + } else { + return; + } + } else { + if (normalizedCurrentHistoryEntry === normalizedNewUrl && currentHistoryEntry === url) { + return; + } + if (currentIndex < historyStack.length - 1) { + historyStack.splice(currentIndex + 1); + } + historyStack.push(url); + currentIndex++; + } + updateNavButtons(); + updateDecodedSearchInput(); + } + + function generateSubject() { + const subjects = ['math', 'science', 'history', 'art', 'programming', 'philosophy']; + const randomSubject = subjects[Math.floor(Math.random() * subjects.length)]; + try { + history.replaceState({}, '', `/learning?subject=${randomSubject}`); + } catch(e) {} + } + + function setupIframeNavigationListeners() { + try { + const iframeWindow = iframe.contentWindow; + if (!iframeWindow || iframeWindow === window || iframeWindow.location.href === 'about:blank') return; + + const handleNav = (isReplace = false) => { + setTimeout(() => { + try { + const newUrlInIframe = iframeWindow.location.href; + if (newUrlInIframe === 'about:blank' && historyStack[currentIndex] === 'about:blank') return; + addToHistory(newUrlInIframe, isReplace); + } catch (e) {} + }, 0); + }; + + if (!iframeWindow.history.pushState.__isPatched) { + const originalPushState = iframeWindow.history.pushState; + iframeWindow.history.pushState = function(...args) { + originalPushState.apply(this, args); + handleNav(false); + }; + iframeWindow.history.pushState.__isPatched = true; + } + if (!iframeWindow.history.replaceState.__isPatched) { + const originalReplaceState = iframeWindow.history.replaceState; + iframeWindow.history.replaceState = function(...args) { + originalReplaceState.apply(this, args); + handleNav(true); + }; + iframeWindow.history.replaceState.__isPatched = true; + } + + iframeWindow.removeEventListener('popstate', iframeWindow.__popstateHandler); + iframeWindow.__popstateHandler = () => handleNav(false); + iframeWindow.addEventListener('popstate', iframeWindow.__popstateHandler); + + iframeWindow.removeEventListener('hashchange', iframeWindow.__hashchangeHandler); + iframeWindow.__hashchangeHandler = () => handleNav(false); + iframeWindow.addEventListener('hashchange', iframeWindow.__hashchangeHandler); + } catch (error) {} + } + + iframe.addEventListener('loadstart', () => { + showLoadingScreen(false); + if (navbarToggle && navbarToggle.checked && navBar) { + navBar.style.display = 'block'; + } + }); + + iframe.addEventListener('load', () => { + hideLoadingScreen(); + try { + const newUrl = iframe.contentWindow ? iframe.contentWindow.location.href : iframe.src; + if (newUrl && newUrl !== 'about:blank') { + if (currentIndex === -1 || normalizeUrl(historyStack[currentIndex]) !== normalizeUrl(newUrl) || historyStack[currentIndex] !== newUrl ) { + addToHistory(newUrl); + } else if (historyStack[currentIndex] !== newUrl) { + addToHistory(newUrl, true); + } + } else if (newUrl === 'about:blank' && historyStack.length > 0 && historyStack[currentIndex] !== 'about:blank') { + if (currentIndex > 0) { + const previousUrl = historyStack[currentIndex -1]; + currentIndex--; + iframe.src = previousUrl; + return; + } + } + setupIframeNavigationListeners(); + generateSubject(); + if (navbarToggle && navbarToggle.checked && navBar) { + navBar.style.display = 'block'; + } + } catch (error) { + } finally { + updateNavButtons(); + updateDecodedSearchInput(); + } + }); + + iframe.addEventListener('error', () => { + hideLoadingScreen(); + showToast('Error: Could not load page content.', 'error', 'times-circle'); + updateNavButtons(); + updateDecodedSearchInput(); + }); + + function toggleButtonAnimation(button, animationClass) { + if (button) { + button.classList.add(animationClass); + setTimeout(() => button.classList.remove(animationClass), 200); + } + } + + backIcon.addEventListener('click', () => { + toggleButtonAnimation(backIcon, 'button-animate-back'); + if (currentIndex > 0) { + currentIndex--; + showLoadingScreen(false); + iframe.src = historyStack[currentIndex]; + updateNavButtons(); + updateDecodedSearchInput(); + } + }); + + forwardIcon.addEventListener('click', () => { + toggleButtonAnimation(forwardIcon, 'button-animate-forward'); + if (currentIndex < historyStack.length - 1) { + currentIndex++; + showLoadingScreen(false); + iframe.src = historyStack[currentIndex]; + updateNavButtons(); + updateDecodedSearchInput(); + } + }); + + refreshIcon.addEventListener('click', () => { + if (refreshIcon) refreshIcon.classList.add('spin'); + if (iframe.contentWindow) { + showLoadingScreen(false); + const currentIframeUrl = iframe.contentWindow.location.href; + if (normalizeUrl(currentIframeUrl) !== normalizeUrl(historyStack[currentIndex] || '')) { + addToHistory(currentIframeUrl); + } + iframe.contentWindow.location.reload(true); + } + if (refreshIcon) setTimeout(() => refreshIcon.classList.remove('spin'), 300); + }); + + fullscreenIcon.addEventListener('click', () => { + if (iframe.requestFullscreen) iframe.requestFullscreen(); + else if (iframe.mozRequestFullScreen) iframe.mozRequestFullScreen(); + else if (iframe.webkitRequestFullscreen) iframe.webkitRequestFullscreen(); + else if (iframe.msRequestFullscreen) iframe.msRequestFullscreen(); + }); + + function generateSearchUrl(query) { + query = query.trim(); + if (!query) return `https://duckduckgo.com/?q=&ia=web`; + + if (/^[a-zA-Z]+:\/\//.test(query)) { + try { + new URL(query); + return query; + } catch (e) {} + } + + if (/^(localhost|(\d{1,3}\.){3}\d{1,3})(:\d+)?(\/.*)?$/.test(query) || query.toLowerCase() === "localhost") { + if (!query.toLowerCase().startsWith("http:") && !query.toLowerCase().startsWith("https:")) { + return `http://${query}`; + } + return query; + } + + try { + const urlWithHttps = new URL(`https://${query}`); + if (urlWithHttps.hostname && + urlWithHttps.hostname.includes('.') && + !urlWithHttps.hostname.endsWith('.') && + urlWithHttps.hostname !== '.' && + urlWithHttps.hostname.split('.').pop().length >= 2 && + !/^\d+$/.test(urlWithHttps.hostname.split('.').pop()) + ) { + return urlWithHttps.toString(); + } + } catch (e) {} + + return `https://duckduckgo.com/?q=${encodeURIComponent(query)}&ia=web`; + } + + async function getUrl(url) { + if (typeof __uv$config !== 'undefined' && __uv$config.encodeUrl) { + return Promise.resolve(__uv$config.prefix + __uv$config.encodeUrl(url)); + } + return Promise.resolve(url); + } + + function clearBackground() { + const preservedElements = [ + navBar, iframe, document.querySelector('.loading-screen'), + erudaLoadingScreen, topBar + ].filter(el => el != null); + Array.from(document.body.children).forEach(child => { + if (!preservedElements.includes(child) && child.tagName !== 'SCRIPT' && child.tagName !== 'STYLE' && !child.classList.contains('toast')) { + child.remove(); + } + }); + } + + async function handleSearch(query) { + if (!query || !query.trim()) { + showToast('Please enter something in the Search Bar.', 'error', 'warning'); + return; + } + clearBackground(); + let searchURL = generateSearchUrl(query); + + historyStack.length = 0; + currentIndex = -1; + updateNavButtons(); + showLoadingScreen(true); + iframe.style.display = 'block'; + if (topBar) topBar.style.display = 'flex'; + if (navBar && navbarToggle && navbarToggle.checked) navBar.style.display = 'block'; + + let finalUrlToLoad; + if (searchURL.startsWith(window.location.origin + '/assets/g/')) { + finalUrlToLoad = searchURL; + } else if (searchURL.startsWith('/assets/g/')) { + finalUrlToLoad = new URL(searchURL, window.location.origin).href; + } + else { + try { + const tempUrl = new URL(searchURL); + if (tempUrl.origin === window.location.origin && tempUrl.pathname.startsWith('/assets/g/')) { + finalUrlToLoad = tempUrl.href; + } else { finalUrlToLoad = await getUrl(searchURL); } + } catch (e) { finalUrlToLoad = await getUrl(searchURL); } + } + + if (searchInput2) searchInput2.value = decodeUrl(finalUrlToLoad); + iframe.src = finalUrlToLoad; + } + window.APP.handleSearch = handleSearch; + + [searchInput1, searchInput2].forEach(input => { + if (input) { + input.addEventListener('keyup', e => { + if (e.key === 'Enter') { + const queryValue = input.value.trim(); + if (queryValue) { + APP.handleSearch(queryValue); + if (input === searchInput1) searchInput1.value = ''; + } else { + showToast('Please enter something in the Search Bar.', 'error', 'warning'); + } + } + }); + if (input === searchInput2) { + input.addEventListener('focus', updateDecodedSearchInput); + } + } + }); + + if (movies) movies.addEventListener('click', e => { e.preventDefault(); APP.handleSearch('https://movies.usewaves.site/'); }); + if (ai) ai.addEventListener('click', e => { e.preventDefault(); APP.handleSearch('https://ai.usewaves.site/'); }); + + function showToast(message, type = 'success', iconType = 'check') { + const toast = document.createElement('div'); + toast.className = `toast show ${type}`; + const icons = { 'check': 'fa-regular fa-check-circle', 'times-circle': 'fa-regular fa-times-circle', 'info': 'fa-regular fa-info-circle', 'warning': 'fa-regular fa-exclamation-triangle', 'heart': 'fa-solid fa-heart' }; + toast.innerHTML = `${message}`; + const progressBar = document.createElement('div'); progressBar.className = 'progress-bar'; toast.appendChild(progressBar); + const closeBtn = document.createElement('button'); closeBtn.className = 'toast-close'; + closeBtn.innerHTML = ''; + closeBtn.onclick = () => { toast.classList.add('hide'); setTimeout(() => toast.remove(), 500); }; + toast.appendChild(closeBtn); + document.body.appendChild(toast); + setTimeout(() => { toast.classList.add('hide'); setTimeout(() => toast.remove(), 500); }, 3000); + } + + if (navbarToggle && navBar && iframe) { + const savedNavbarState = localStorage.getItem('navbarToggled'); + const defaultChecked = iframe.style.display !== 'block' ? true : (savedNavbarState === null ? false : savedNavbarState === 'true'); + navbarToggle.checked = defaultChecked; + + const updateNavbarDisplayBasedOnToggle = () => { + if (iframe.style.display === 'block') { + navBar.style.display = navbarToggle.checked ? 'block' : 'none'; + } else { + navBar.style.display = 'none'; + } + }; + updateNavbarDisplayBasedOnToggle(); + + navbarToggle.addEventListener('change', () => { + localStorage.setItem('navbarToggled', navbarToggle.checked.toString()); + updateNavbarDisplayBasedOnToggle(); + }); + + window.APP.updateNavbarDisplay = updateNavbarDisplayBasedOnToggle; + } + + window.addEventListener('load', () => { + let iframeInitiallyHidden = true; + if (iframe.src && iframe.src !== 'about:blank') { + iframeInitiallyHidden = false; + } + + if (iframeInitiallyHidden) { + hideLoadingScreen(); + if (topBar) topBar.style.display = 'flex'; + iframe.style.display = 'none'; + } else { + if (topBar) topBar.style.display = 'flex'; + iframe.style.display = 'block'; + } + + if(window.APP.updateNavbarDisplay) window.APP.updateNavbarDisplay(); + updateNavButtons(); + updateDecodedSearchInput(); + }); + + window.APP.decodeUrl = decodeUrl; + window.APP.normalizeUrl = normalizeUrl; +}); + +(async () => { + try { + const res = await fetch('/api/github-updates'); + const { updates } = await res.json(); + const u = updates[0]; + const commitUrl = `https://github.com/xojw/waves/commit/${u.sha}`; + document.getElementById('lastest-commit').innerHTML = + ` ${u.sha}`; + } catch { + document.getElementById('lastest-commit').textContent = + 'Failed to load lastest commit'; + } +})(); \ No newline at end of file diff --git a/public/assets/js/greetings.js b/public/assets/js/greetings.js index 38687fa3..c2354c7a 100644 --- a/public/assets/js/greetings.js +++ b/public/assets/js/greetings.js @@ -28,7 +28,6 @@ function submitName() { updateGreeting(name); document.getElementById('namePrompt').classList.add('fade-out'); showToast(`Hey, ${name}! Welcome to Waves!`, 'success', 'wave'); - setTimeout(() => { document.getElementById('namePrompt').style.display = 'none'; document.getElementById('overlay').style.display = 'none'; @@ -52,40 +51,92 @@ function getIconType(path) { return 'wave'; } -function updateGreeting(name) { - const { text, icon } = getGreeting(); +const generalGreetings = [ + { text: 'Welcome aboard', icon: '', suffix: '!' }, + { text: 'Hii', icon: '', suffix: '!!' }, + { text: 'Hope you enjoy Waves', icon: '', suffix: ' <3' }, + { text: 'Consider joining our Discord (discord.gg/ire)', icon: '', suffix: '!' }, + { text: 'How you doing today', icon: '', suffix: '?' } +]; - const el = document.getElementById('greeting'); - if (el) { - if (text === 'Hope you enjoy Waves') { - el.innerHTML = `${icon} ${text}, ${name} <3`; - } else { - el.innerHTML = `${icon} ${text}, ${name}!`; - } - el.style.opacity = 1; +const timeGreetings = []; + +timeGreetings.push( + { text: 'Good morning, sunshine', icon: '', suffix: ' :D' }, + { text: 'Here’s to a bright morning', icon: '', suffix: '.' }, + { text: 'Enjoy your morning', icon: '', suffix: '!' }, + { text: 'Your day starts here', icon: '', suffix: ' !' } +); + +timeGreetings.push( + { text: 'Good afternoon', icon: '', suffix: '!' }, + { text: 'Hope your day is going well', icon: '', suffix: '.' }, + { text: 'Keep up the pace', icon: '', suffix: '!' }, + { text: 'Stay on track today', icon: '', suffix: '.' } +); + +timeGreetings.push( + { text: 'Good evening', icon: '', suffix: '!' }, + { text: 'Time to unwind', icon: '', suffix: '.' }, + { text: 'Evening’s here—relax', icon: '', suffix: '.' }, + { text: 'Breathe and recharge', icon: '', suffix: '…' } +); + +timeGreetings.push( + { text: 'Good night', icon: '', suffix: '!' }, + { text: 'Rest well', icon: '', suffix: '.' }, + { text: 'Sweet dreams', icon: '', suffix: '!' }, + { text: 'See you tomorrow', icon: '', suffix: '!' } +); + +function getGreeting() { + const now = new Date(); + const hour = now.getHours(); + let pool = []; + if (hour >= 5 && hour < 12) { + pool = timeGreetings.slice(0, 4); + } else if (hour < 17) { + pool = timeGreetings.slice(4, 8); + } else if (hour < 21) { + pool = timeGreetings.slice(8, 12); + } else { + pool = timeGreetings.slice(12, 16); } + if (Math.random() < 0.5) { + pool = generalGreetings; + } + const choice = pool[Math.floor(Math.random() * pool.length)]; + return { text: choice.text, icon: choice.icon, suffix: choice.suffix }; +} + +function updateGreeting(name) { + const { text, icon, suffix } = getGreeting(); + const el = document.getElementById('greeting'); + if (!el) return; + if (text === 'Hope you enjoy Waves') { + el.innerHTML = `${icon} ${text}, ${name}${suffix}`; + } else { + el.innerHTML = `${icon} ${text}, ${name}${suffix}`; + } + el.style.opacity = 1; } function showToast(message, type = 'success', iconType = 'wave') { const toast = document.createElement('div'); toast.className = `toast show ${type}`; - const icons = { success: '', - error: '', - info: '', + error: '', + info: '', warning: '', - wave: '', - game: '', - apps: '', + wave: '', + game: '', + apps: '' }; - toast.innerHTML = `${icons[iconType] || icons.wave}${message}`; - const progressBar = document.createElement('div'); progressBar.className = 'progress-bar'; toast.appendChild(progressBar); - const closeBtn = document.createElement('button'); closeBtn.className = 'toast-close'; closeBtn.innerHTML = ''; @@ -94,61 +145,9 @@ function showToast(message, type = 'success', iconType = 'wave') { setTimeout(() => toast.remove(), 500); }); toast.appendChild(closeBtn); - document.body.appendChild(toast); setTimeout(() => { toast.classList.add('hide'); setTimeout(() => toast.remove(), 500); }, 3000); -} - -function getGreeting() { - const now = new Date(); - const hour = now.getHours(); - - const timeGreetings = []; - const generalGreetings = [ - { text: 'Welcome aboard', icon: '' }, - { text: 'Let’s do something great', icon: '' }, - { text: 'Hope you enjoy Waves', icon: '' }, - { text: 'Time to explore', icon: '' }, - { text: 'Let’s roll', icon: '' }, - { text: 'Consider joining our Discord (discord.gg/ire)', icon: '' }, - { text: 'The adventure continues', icon: '' } - ]; - - if (hour >= 5 && hour < 12) { - timeGreetings.push( - { text: 'Good morning, sunshine', icon: '' }, - { text: 'Here’s to a bright morning', icon: '' }, - { text: 'Enjoy your morning', icon: '' }, - { text: 'Your day starts here', icon: '' } - ); - } else if (hour < 17) { - timeGreetings.push( - { text: 'Good afternoon', icon: '' }, - { text: 'Hope your day is going well', icon: '' }, - { text: 'Keep up the pace', icon: '' }, - { text: 'Stay on track today', icon: '' } - ); - } else if (hour < 21) { - timeGreetings.push( - { text: 'Good evening', icon: '' }, - { text: 'Time to unwind', icon: '' }, - { text: 'Evening’s here—relax', icon: '' }, - { text: 'Breathe and recharge', icon: '' } - ); - } else { - timeGreetings.push( - { text: 'Good night', icon: '' }, - { text: 'Rest well', icon: '' }, - { text: 'Sweet dreams', icon: '' }, - { text: 'See you tomorrow', icon: '' } - ); - } - - const useGeneral = Math.random() < 0.5; - const pool = useGeneral ? generalGreetings : timeGreetings; - - return pool[Math.floor(Math.random() * pool.length)]; } \ No newline at end of file diff --git a/public/assets/js/latest-commit.js b/public/assets/js/latest-commit.js deleted file mode 100644 index f6a06255..00000000 --- a/public/assets/js/latest-commit.js +++ /dev/null @@ -1,13 +0,0 @@ -(async () => { - try { - const res = await fetch('/api/latest-commit'); - const { updates } = await res.json(); - const u = updates[0]; - const commitUrl = `https://github.com/xojw/waves/commit/${u.sha}`; - document.getElementById('lastest-commit').innerHTML = - ` ${u.sha}`; - } catch { - document.getElementById('lastest-commit').textContent = - 'Failed to load lastest commit'; - } -})(); \ No newline at end of file diff --git a/public/assets/js/load.js b/public/assets/js/load.js deleted file mode 100644 index 6f9f171a..00000000 --- a/public/assets/js/load.js +++ /dev/null @@ -1,21 +0,0 @@ -document.addEventListener('DOMContentLoaded', function () { - - NProgress.configure({ showSpinner: false }); - NProgress.start(); - - const titleElement = document.querySelector('.search-title'); - if (titleElement) { - const text = titleElement.textContent.trim(); - titleElement.textContent = ''; - text.split('').forEach((letter, i) => { - const span = document.createElement('span'); - span.textContent = letter; - span.style.animationDelay = `${i * 0.05}s`; - titleElement.appendChild(span); - }); - } - - window.addEventListener('load', function () { - NProgress.done(); - }); -}); \ No newline at end of file diff --git a/public/assets/js/navbar.js b/public/assets/js/navbar.js deleted file mode 100644 index 4964034e..00000000 --- a/public/assets/js/navbar.js +++ /dev/null @@ -1,183 +0,0 @@ -const style = document.createElement('style'); -style.textContent = ` -@keyframes slideLeft {0% { transform: translateX(0); } 50% { transform: translateX(-5px); } 100% { transform: translateX(0); }} -@keyframes slideRight {0% { transform: translateX(0); } 50% { transform: translateX(5px); } 100% { transform: translateX(0); }} -.button-animate-back { animation: slideLeft 0.3s ease-in-out; } -.button-animate-forward { animation: slideRight 0.3s ease-in-out; } -`; -document.head.appendChild(style); - -const historyStack = []; -let currentIndex = -1; -const elements = { - refreshIcon: document.getElementById('refreshIcon'), - fullscreenIcon: document.getElementById('fullscreenIcon'), - backIcon: document.getElementById('backIcon'), - forwardIcon: document.getElementById('forwardIcon'), - searchInput2: document.getElementById('searchInputt'), - iframe: document.getElementById('cool-iframe') -}; -const originalTitle = document.title; -let loadingFallbackTimeout; - -elements.refreshIcon.addEventListener('click', handleRefresh); -elements.fullscreenIcon.addEventListener('click', handleFullscreen); -elements.backIcon.addEventListener('click', handleBack); -elements.forwardIcon.addEventListener('click', handleForward); - -function showLoadingScreen() { - if (typeof NProgress !== 'undefined') { - NProgress.start(); - document.title = 'Loading... <3'; - setTimeout(() => { - if (typeof NProgress !== 'undefined') NProgress.done(); - }, 10000); - } -} - -function hideLoadingScreen() { - if (typeof NProgress !== 'undefined') NProgress.done(); - document.title = originalTitle; -} - -function handleRefresh() { - elements.refreshIcon.classList.add('spin'); - const iframe = elements.iframe; - const currentUrl = iframe.contentWindow.location.href; - if (normalizeUrl(currentUrl) !== normalizeUrl(historyStack[currentIndex] || '')) { - addToHistory(currentUrl); - } - iframe.contentWindow.location.reload(true); - setTimeout(() => elements.refreshIcon.classList.remove('spin'), 300); -} - -function handleFullscreen() { - const iframe = elements.iframe; - if (iframe && iframe.tagName === 'IFRAME') iframe.requestFullscreen(); -} - -function handleBack() { - toggleButtonAnimation(elements.backIcon, 'button-animate-back'); - if (currentIndex > 0) { - currentIndex--; - updateIframeSrc(); - } -} - -function handleForward() { - toggleButtonAnimation(elements.forwardIcon, 'button-animate-forward'); - if (currentIndex < historyStack.length - 1) { - currentIndex++; - updateIframeSrc(); - } -} - -function toggleButtonAnimation(button, animationClass) { - button.classList.add(animationClass); - setTimeout(() => button.classList.remove(animationClass), 200); -} - -function normalizeUrl(urlStr) { - try { - const url = new URL(urlStr); - url.searchParams.delete('ia'); - return url.toString(); - } catch (e) { - return urlStr; - } -} - -function addToHistory(url) { - const normalized = normalizeUrl(url); - if (currentIndex >= 0 && normalizeUrl(historyStack[currentIndex]) === normalized) return; - if (currentIndex < historyStack.length - 1) historyStack.splice(currentIndex + 1); - historyStack.push(url); - currentIndex++; - updateNavButtons(); - updateDecodedSearchInput(); -} - -function updateIframeSrc() { - showLoadingScreen(); - elements.iframe.src = historyStack[currentIndex]; - updateNavButtons(); - updateDecodedSearchInput(); -} - -function updateNavButtons() { - const isAtStart = currentIndex <= 0; - const isAtEnd = currentIndex >= historyStack.length - 1; - elements.backIcon.disabled = isAtStart; - elements.forwardIcon.disabled = isAtEnd; - elements.backIcon.classList.toggle('disabled', isAtStart); - elements.forwardIcon.classList.toggle('disabled', isAtEnd); -} - -function updateDecodedSearchInput() { - if (elements.searchInput2) { - const url = historyStack[currentIndex] || elements.iframe.src; - elements.searchInput2.value = decodeUrl(url); - } -} - -function decodeUrl(url) { - try { - return decodeURIComponent(url); - } catch (e) { - return url; - } -} - -window.addToHistory = addToHistory; -window.updateDecodedSearchInput = updateDecodedSearchInput; -window.normalizeUrl = normalizeUrl; - -function detectIframeNavigation() { - try { - const iframeWindow = elements.iframe.contentWindow; - const pushState = iframeWindow.history.pushState; - const replaceState = iframeWindow.history.replaceState; - iframeWindow.history.pushState = function() { - pushState.apply(this, arguments); - handleIframeNavigation(iframeWindow.location.href); - }; - iframeWindow.history.replaceState = function() { - replaceState.apply(this, arguments); - handleIframeNavigation(iframeWindow.location.href); - }; - iframeWindow.addEventListener('popstate', () => handleIframeNavigation(iframeWindow.location.href)); - iframeWindow.addEventListener('hashchange', () => handleIframeNavigation(iframeWindow.location.href)); - } catch (error) {} -} - -function handleIframeNavigation(rawUrl) { - let urlStr = rawUrl; - try { - urlStr = decodeUrl(rawUrl); - } catch {} - try { - const u = new URL(urlStr); - if (u.hostname.endsWith('duckduckgo.com')) { - if (typeof NProgress !== 'undefined') NProgress.done(); - return; - } - } catch (e) {} - if (normalizeUrl(urlStr) !== normalizeUrl(historyStack[currentIndex] || '')) { - showLoadingScreen(); - addToHistory(urlStr); - } else { - hideLoadingScreen(); - } -} - -elements.iframe.addEventListener('load', () => { - try { - detectIframeNavigation(); - if (historyStack.length === 0) { - addToHistory(elements.iframe.contentWindow.location.href); - } else { - handleIframeNavigation(elements.iframe.contentWindow.location.href); - } - } catch (error) {} - hideLoadingScreen(); -}); \ No newline at end of file