2025-02-14 21:48:15 -08:00
import { bangs } from "./bang" ;
2025-02-14 22:25:23 -08:00
import "./global.css" ;
2025-02-14 21:30:33 -08:00
2025-02-14 21:48:15 -08:00
const defaultBang = bangs . find ( ( b ) = > b . t === "g" ) ;
2025-02-14 22:18:05 -08:00
function noSearchDefaultPageRender() {
const app = document . querySelector < HTMLDivElement > ( "#app" ) ! ;
app . innerHTML = `
< div style = "display: flex; flex-direction: column; align-items: center; justify-content: center; height: 100vh;" >
2025-02-14 22:25:23 -08:00
< div class = "content-container" >
< h1 > Unduck < / h1 >
< p > DuckDuckGo 's bang redirects are too slow. Add the following URL as a custom search engine to your browser. Enables <a href="https://duckduckgo.com/bang.html" target="_blank">all of DuckDuckGo' s bangs . < / a > < / p >
< div class = "url-container" >
< input
type = "text"
class = "url-input"
2025-02-14 22:40:43 -08:00
value = "https://unduck.link?q=%s"
2025-02-14 22:25:23 -08:00
readonly
/ >
< button class = "copy-button" >
< img src = "/clipboard.svg" alt = "Copy" / >
< / button >
< / div >
< / div >
2025-02-14 22:26:53 -08:00
< footer class = "footer" >
2025-02-14 22:57:50 -08:00
< a href = "https://t3.chat" target = "_blank" > t3 . chat < / a >
•
< a href = "https://x.com/theo" target = "_blank" > theo < / a >
•
< a href = "https://github.com/t3dotgg/unduck" target = "_blank" > github < / a >
2025-02-14 22:26:53 -08:00
< / footer >
2025-02-14 22:18:05 -08:00
< / div >
` ;
2025-02-14 22:25:23 -08:00
const copyButton = app . querySelector < HTMLButtonElement > ( ".copy-button" ) ! ;
const copyIcon = copyButton . querySelector ( "img" ) ! ;
const urlInput = app . querySelector < HTMLInputElement > ( ".url-input" ) ! ;
copyButton . addEventListener ( "click" , async ( ) = > {
await navigator . clipboard . writeText ( urlInput . value ) ;
copyIcon . src = "/clipboard-check.svg" ;
setTimeout ( ( ) = > {
copyIcon . src = "/clipboard.svg" ;
} , 2000 ) ;
} ) ;
2025-02-14 22:18:05 -08:00
}
2025-02-14 22:03:20 -08:00
function getBangredirectUrl() {
2025-02-14 21:48:15 -08:00
const url = new URL ( window . location . href ) ;
const query = url . searchParams . get ( "q" ) ? . trim ( ) ? ? "" ;
2025-02-14 22:18:05 -08:00
if ( ! query ) {
noSearchDefaultPageRender ( ) ;
return null ;
}
2025-02-14 22:03:20 -08:00
2025-02-14 22:33:22 -08:00
const match = query . match ( /!([a-z0-9]+)/i ) ;
2025-02-14 22:03:20 -08:00
2025-02-14 22:16:04 -08:00
const bangCandidate = match ? . [ 1 ] ? . toLowerCase ( ) ;
2025-02-14 21:48:15 -08:00
const selectedBang = bangs . find ( ( b ) = > b . t === bangCandidate ) ? ? defaultBang ;
2025-02-14 22:03:20 -08:00
// Remove the first bang from the query
2025-02-14 22:31:14 -08:00
const cleanQuery = query . replace ( /![a-z0-9]+\s*/i , "" ) . trim ( ) ;
2025-02-14 21:48:15 -08:00
2025-02-14 22:03:20 -08:00
// Format of the url is:
// https://www.google.com/search?q={{{s}}}
const searchUrl = selectedBang ? . u . replace (
"{{{s}}}" ,
2025-02-14 23:26:36 -08:00
// Replace %2F with / to fix formats like "!ghr+t3dotgg/unduck"
encodeURIComponent ( cleanQuery ) . replace ( /%2F/g , "/" )
2025-02-14 22:03:20 -08:00
) ;
if ( ! searchUrl ) return null ;
2025-02-14 21:48:15 -08:00
2025-02-14 22:03:20 -08:00
return searchUrl ;
2025-02-14 21:48:15 -08:00
}
2025-02-14 22:18:05 -08:00
function doRedirect() {
const searchUrl = getBangredirectUrl ( ) ;
if ( ! searchUrl ) return ;
window . location . replace ( searchUrl ) ;
}
2025-02-14 21:30:33 -08:00
2025-02-14 22:18:05 -08:00
doRedirect ( ) ;