Compare commits

...

10 Commits

Author SHA1 Message Date
gib 991fd13184 Update README.md 2025-02-27 11:21:38 -06:00
gib 3032a81915 Make it my own to self host 2025-02-27 11:19:34 -06:00
Theo Browne cea48a6584 * the name 2025-02-19 03:58:47 -08:00
Theo Browne f96ce5706d Merge pull request #5 from samyakbardiya/fix/handle-non-alphanumeric-chars
fix: Handle non-alphanumeric characters in bangs
2025-02-15 18:16:14 -08:00
Theo Browne 5cf34e3467 Merge pull request #7 from irsyadpage/main
Add padding to .content-container
2025-02-15 18:08:35 -08:00
Theo Browne 34f64869c0 pwa because why not 2025-02-15 18:03:21 -08:00
Irsyad Aminuddin b9763e2124 Add padding to .content-container 2025-02-15 22:22:03 +08:00
Samyak Bardiya 001e48129b fix: update regex to handle non-alphanumeric chars 2025-02-15 18:33:21 +05:30
Theo Browne 3165c3dccb default bang in localstorage 2025-02-14 23:33:45 -08:00
Theo Browne 0b569d2b86 hack to handle slashes 2025-02-14 23:27:00 -08:00
7 changed files with 3281 additions and 40 deletions
+5 -3
View File
@@ -1,13 +1,15 @@
# Unduck
# Bang
*This is a fork of [unduck](https://unduck.link) by [Theo](https://github.com/t3dotgg/unduck).*
DuckDuckGo's bang redirects are too slow. Add the following URL as a custom search engine to your browser. Enables all of DuckDuckGo's bangs to work, but much faster.
```
https://unduck.link?q=%s
https://bang.gbrown.org?q=%s
```
## How is it that much faster?
DuckDuckGo does their redirects server side. Their DNS is...not always great. Result is that it often takes ages.
I solved this by doing all of the work client side. Once you've went to https://unduck.link once, the JS is all cache'd and will never need to be downloaded again. Your device does the redirects, not me.
Theo solved this by doing all of the work client side. Once you've went to https://unduck.link once, the JS is all cache'd and will never need to be downloaded again. Your device does the redirects, not me.
+9
View File
@@ -11,5 +11,14 @@
"devDependencies": {
"typescript": "~5.7.2",
"vite": "^6.1.0"
},
"dependencies": {
"vite-plugin-pwa": "^0.21.1"
},
"packageManager": "pnpm@10.5.2+sha512.da9dc28cd3ff40d0592188235ab25d3202add8a207afbedc682220e4a0029ffbff4562102b9e6e46b4e3f9e8bd53e6d05de48544b0c57d4b0179e22c76d1199b",
"pnpm": {
"onlyBuiltDependencies": [
"esbuild"
]
}
}
+3235 -2
View File
File diff suppressed because it is too large Load Diff
+10 -19
View File
@@ -1,6 +1,15 @@
// This file was (mostly) ripped from https://duckduckgo.com/bang.js
export const bangs = [
{
c: "Online Services",
d: "search.gibbyb.com",
r: 0,
s: "GibbyB",
sc: "Search",
t: "sg",
u: "https://search.gibbyb.com/?q={{{s}}}",
},
{
c: "AI",
d: "www.t3.chat",
@@ -10,24 +19,6 @@ export const bangs = [
t: "t3",
u: "https://www.t3.chat/new?q={{{s}}}",
},
{
c: "Tech",
d: "www.01net.com",
r: 4,
s: "01net",
sc: "Downloads (apps)",
t: "01net",
u: "http://www.01net.com/recherche/recherche.php?searchstring={{{s}}}&chaine=home",
},
{
c: "Entertainment",
d: "www.bmw2002faq.com",
r: 0,
s: "BMW 2002 FAQ",
sc: "Forum",
t: "02faq",
u: "https://www.bmw2002faq.com/search/?q={{{s}}}",
},
{
c: "Entertainment",
d: "boxofficemojo.com",
@@ -93872,7 +93863,7 @@ export const bangs = [
r: 46,
s: "Sourcegraph",
sc: "Programming",
t: "sg",
t: "srcg",
u: "https://sourcegraph.com/search?q={{{s}}}",
},
{
+2
View File
@@ -89,6 +89,7 @@ textarea {
.content-container {
max-width: 36rem;
text-align: center;
padding: 0 8px;
}
/* Update url-input width to be 100% since container will control max width */
@@ -98,6 +99,7 @@ textarea {
border-radius: 4px;
width: 100%;
background: #f5f5f5;
text-align: center;
}
.copy-button {
+10 -16
View File
@@ -1,20 +1,17 @@
import { bangs } from "./bang";
import "./global.css";
const defaultBang = bangs.find((b) => b.t === "g");
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;">
<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>
<h1>Bang</h1>
<div class="url-container">
<input
type="text"
class="url-input"
value="https://unduck.link?q=%s"
value="bang.gbrown.org?q=%s"
readonly
/>
<button class="copy-button">
@@ -22,13 +19,6 @@ function noSearchDefaultPageRender() {
</button>
</div>
</div>
<footer class="footer">
<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>
</footer>
</div>
`;
@@ -37,7 +27,7 @@ function noSearchDefaultPageRender() {
const urlInput = app.querySelector<HTMLInputElement>(".url-input")!;
copyButton.addEventListener("click", async () => {
await navigator.clipboard.writeText(urlInput.value);
await navigator.clipboard.writeText("https://" + urlInput.value);
copyIcon.src = "/clipboard-check.svg";
setTimeout(() => {
@@ -46,6 +36,9 @@ function noSearchDefaultPageRender() {
});
}
const LS_DEFAULT_BANG = localStorage.getItem("default-bang") ?? "sg";
const defaultBang = bangs.find((b) => b.t === LS_DEFAULT_BANG);
function getBangredirectUrl() {
const url = new URL(window.location.href);
const query = url.searchParams.get("q")?.trim() ?? "";
@@ -54,19 +47,20 @@ function getBangredirectUrl() {
return null;
}
const match = query.match(/!([a-z0-9]+)/i);
const match = query.match(/!(\S+)/i);
const bangCandidate = match?.[1]?.toLowerCase();
const selectedBang = bangs.find((b) => b.t === bangCandidate) ?? defaultBang;
// Remove the first bang from the query
const cleanQuery = query.replace(/![a-z0-9]+\s*/i, "").trim();
const cleanQuery = query.replace(/!\S+\s*/i, "").trim();
// Format of the url is:
// https://www.google.com/search?q={{{s}}}
const searchUrl = selectedBang?.u.replace(
"{{{s}}}",
encodeURIComponent(cleanQuery)
// Replace %2F with / to fix formats like "!ghr+t3dotgg/unduck"
encodeURIComponent(cleanQuery).replace(/%2F/g, "/")
);
if (!searchUrl) return null;
+10
View File
@@ -0,0 +1,10 @@
import { defineConfig } from "vite";
import { VitePWA } from "vite-plugin-pwa";
export default defineConfig({
plugins: [
VitePWA({
registerType: "autoUpdate",
}),
],
});