diff options
Diffstat (limited to 'src/assets')
-rw-r--r-- | src/assets/images/chatGpt-icon-light.svg | 10 | ||||
-rw-r--r-- | src/assets/images/chatGpt-icon.svg | 1 | ||||
-rw-r--r-- | src/assets/images/chefkoch-icon.svg | 43 | ||||
-rw-r--r-- | src/assets/javascripts/services.js | 188 | ||||
-rw-r--r-- | src/assets/javascripts/utils.js | 20 |
5 files changed, 219 insertions, 43 deletions
diff --git a/src/assets/images/chatGpt-icon-light.svg b/src/assets/images/chatGpt-icon-light.svg new file mode 100644 index 00000000..b3df81fb --- /dev/null +++ b/src/assets/images/chatGpt-icon-light.svg @@ -0,0 +1,10 @@ +<svg width="320" height="320" viewBox="0 0 320 320" fill="none" xmlns="http://www.w3.org/2000/svg"> +<g clip-path="url(#clip0_10145_290560)"> +<path d="M297.06 130.97C304.32 109.18 301.82 85.31 290.21 65.49C272.75 35.09 237.65 19.45 203.37 26.81C188.12 9.63002 166.21 -0.139981 143.24 1.93887e-05C108.2 -0.0799806 77.11 22.48 66.33 55.82C43.82 60.43 24.39 74.52 13.02 94.49C-4.57001 124.81 -0.560007 163.03 22.94 189.03C15.68 210.82 18.18 234.69 29.79 254.51C47.25 284.91 82.35 300.55 116.63 293.19C131.87 310.37 153.79 320.14 176.76 319.99C211.82 320.08 242.92 297.5 253.7 264.13C276.21 259.52 295.64 245.43 307.01 225.46C324.58 195.14 320.56 156.95 297.07 130.95L297.06 130.97ZM176.78 299.08C162.75 299.1 149.16 294.19 138.39 285.2C138.88 284.94 139.73 284.47 140.28 284.13L204 247.33C207.26 245.48 209.26 242.01 209.24 238.26V148.43L236.17 163.98C236.46 164.12 236.65 164.4 236.69 164.72V239.11C236.65 272.19 209.86 299.01 176.78 299.08ZM47.94 244.05C40.91 231.91 38.38 217.68 40.79 203.87C41.26 204.15 42.09 204.66 42.68 205L106.4 241.8C109.63 243.69 113.63 243.69 116.87 241.8L194.66 196.88V227.98C194.68 228.3 194.53 228.61 194.28 228.81L129.87 266C101.18 282.52 64.54 272.7 47.95 244.05H47.94ZM31.17 104.96C38.17 92.8 49.22 83.5 62.38 78.67C62.38 79.22 62.35 80.19 62.35 80.87V154.48C62.33 158.22 64.33 161.69 67.58 163.54L145.37 208.45L118.44 224C118.17 224.18 117.83 224.21 117.53 224.08L53.11 186.86C24.48 170.28 14.66 133.65 31.16 104.97L31.17 104.96ZM252.43 156.45L174.64 111.53L201.57 95.99C201.84 95.81 202.18 95.78 202.48 95.91L266.9 133.1C295.58 149.67 305.41 186.36 288.84 215.04C281.83 227.18 270.79 236.48 257.64 241.32V165.51C257.67 161.77 255.68 158.31 252.44 156.45H252.43ZM279.23 116.11C278.76 115.82 277.93 115.32 277.34 114.98L213.62 78.18C210.39 76.29 206.39 76.29 203.15 78.18L125.36 123.1V92C125.34 91.68 125.49 91.37 125.74 91.17L190.15 54.01C218.84 37.46 255.52 47.31 272.06 76.01C279.05 88.13 281.58 102.32 279.21 116.11H279.23ZM110.72 171.54L83.78 155.99C83.49 155.85 83.3 155.57 83.26 155.25V80.86C83.28 47.74 110.15 20.9 143.27 20.92C157.28 20.92 170.84 25.84 181.61 34.8C181.12 35.06 180.28 35.53 179.72 35.87L116 72.67C112.74 74.52 110.74 77.98 110.76 81.73L110.72 171.52V171.54ZM125.35 140L160 119.99L194.65 139.99V180L160 200L125.35 180V140Z" fill="white"/> +</g> +<defs> +<clipPath id="clip0_10145_290560"> +<rect width="320" height="320" fill="white"/> +</clipPath> +</defs> +</svg> diff --git a/src/assets/images/chatGpt-icon.svg b/src/assets/images/chatGpt-icon.svg new file mode 100644 index 00000000..e04db75a --- /dev/null +++ b/src/assets/images/chatGpt-icon.svg @@ -0,0 +1 @@ +<svg viewBox="0 0 320 320" xmlns="http://www.w3.org/2000/svg"><path d="m297.06 130.97c7.26-21.79 4.76-45.66-6.85-65.48-17.46-30.4-52.56-46.04-86.84-38.68-15.25-17.18-37.16-26.95-60.13-26.81-35.04-.08-66.13 22.48-76.91 55.82-22.51 4.61-41.94 18.7-53.31 38.67-17.59 30.32-13.58 68.54 9.92 94.54-7.26 21.79-4.76 45.66 6.85 65.48 17.46 30.4 52.56 46.04 86.84 38.68 15.24 17.18 37.16 26.95 60.13 26.8 35.06.09 66.16-22.49 76.94-55.86 22.51-4.61 41.94-18.7 53.31-38.67 17.57-30.32 13.55-68.51-9.94-94.51zm-120.28 168.11c-14.03.02-27.62-4.89-38.39-13.88.49-.26 1.34-.73 1.89-1.07l63.72-36.8c3.26-1.85 5.26-5.32 5.24-9.07v-89.83l26.93 15.55c.29.14.48.42.52.74v74.39c-.04 33.08-26.83 59.9-59.91 59.97zm-128.84-55.03c-7.03-12.14-9.56-26.37-7.15-40.18.47.28 1.3.79 1.89 1.13l63.72 36.8c3.23 1.89 7.23 1.89 10.47 0l77.79-44.92v31.1c.02.32-.13.63-.38.83l-64.41 37.19c-28.69 16.52-65.33 6.7-81.92-21.95zm-16.77-139.09c7-12.16 18.05-21.46 31.21-26.29 0 .55-.03 1.52-.03 2.2v73.61c-.02 3.74 1.98 7.21 5.23 9.06l77.79 44.91-26.93 15.55c-.27.18-.61.21-.91.08l-64.42-37.22c-28.63-16.58-38.45-53.21-21.95-81.89zm221.26 51.49-77.79-44.92 26.93-15.54c.27-.18.61-.21.91-.08l64.42 37.19c28.68 16.57 38.51 53.26 21.94 81.94-7.01 12.14-18.05 21.44-31.2 26.28v-75.81c.03-3.74-1.96-7.2-5.2-9.06zm26.8-40.34c-.47-.29-1.3-.79-1.89-1.13l-63.72-36.8c-3.23-1.89-7.23-1.89-10.47 0l-77.79 44.92v-31.1c-.02-.32.13-.63.38-.83l64.41-37.16c28.69-16.55 65.37-6.7 81.91 22 6.99 12.12 9.52 26.31 7.15 40.1zm-168.51 55.43-26.94-15.55c-.29-.14-.48-.42-.52-.74v-74.39c.02-33.12 26.89-59.96 60.01-59.94 14.01 0 27.57 4.92 38.34 13.88-.49.26-1.33.73-1.89 1.07l-63.72 36.8c-3.26 1.85-5.26 5.31-5.24 9.06l-.04 89.79zm14.63-31.54 34.65-20.01 34.65 20v40.01l-34.65 20-34.65-20z"/></svg> \ No newline at end of file diff --git a/src/assets/images/chefkoch-icon.svg b/src/assets/images/chefkoch-icon.svg new file mode 100644 index 00000000..12e1f3ba --- /dev/null +++ b/src/assets/images/chefkoch-icon.svg @@ -0,0 +1,43 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + class="w-logo" + width="35.532116" + height="35.532116" + viewBox="0 0 35.532115 35.532115" + fill="none" + data-v-73c3726b="" + version="1.1" + id="svg9" + sodipodi:docname="logo.svg" + inkscape:version="1.4 (e7c3feb100, 2024-10-09)" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg"> + <defs + id="defs9" /> + <sodipodi:namedview + id="namedview9" + pagecolor="#ffffff" + bordercolor="#000000" + borderopacity="0.25" + inkscape:showpageshadow="2" + inkscape:pageopacity="0.0" + inkscape:pagecheckerboard="0" + inkscape:deskcolor="#d1d1d1" + inkscape:zoom="5.6568542" + inkscape:cx="10.69499" + inkscape:cy="32.880465" + inkscape:window-width="1888" + inkscape:window-height="1052" + inkscape:window-x="0" + inkscape:window-y="0" + inkscape:window-maximized="1" + inkscape:current-layer="svg9" /> + <path + class="w-logo__hat" + data-testid="logo-hat" + d="m 28.25197,6.8567782 -1.5339,15.1350798 -0.3608,3.3157 c -0.0677,0.3158 -0.2707,0.609 -0.8572,0.7669 -0.1579,0.0451 -0.3158,0.0902 -0.4962,0.1128 -0.3158,0.0677 -0.6316,-0.1805 -0.5865,-0.5188 l 1.3308,-17.3680898 c 0.0452,-0.47368 -0.3157,-0.87969 -0.7894,-0.90224 h -0.0902 c -0.4737,-0.04511 -0.8797,0.31578 -0.9023,0.78946 l -1.3533,17.7740698 c -0.0226,0.3835 -0.3158,0.6767 -0.6993,0.7218 -0.2255,0.0226 -0.4737,0.0451 -0.6992,0.0677 -0.3383,0.0225 -0.6316,-0.2481 -0.6316,-0.5865 l 0.3609,-18.4958598 c 0.0226,-0.47368 -0.3609,-0.85713 -0.812,-0.87968 h -0.0902 c -0.4737,-0.02256 -0.8571,0.36089 -0.8797,0.81201 l -0.3609,18.6312298 c -0.0226,0.3609 -0.3158,0.6541 -0.6541,0.6541 -0.2481,0 -0.4963,0 -0.7444,0 -0.3609,0 -0.6541,-0.2932 -0.6766,-0.6541 L 16.29727,8.9093782 c -0.0226,-0.47368 -0.406,-0.83457 -0.8797,-0.81202 h -0.09022 c -0.47368,0.02256 -0.834569,0.40601 -0.812009,0.87969 L 14.9439,26.164658 c 0,0.3384 -0.270669,0.609 -0.631569,0.5865 -0.22556,-0.0226 -0.45112,-0.0451 -0.67668,-0.0677 -0.38345,-0.0451 -0.67668,-0.3383 -0.69923,-0.7218 L 11.628171,8.3905882 c -0.04511,-0.47367 -0.45112,-0.81201 -0.90224,-0.78946 h -0.09022 c -0.47368,0.04511 -0.8120199,0.45112 -0.7894599,0.90224 L 11.131941,25.668458 c 0.02256,0.3383 -0.27067,0.5865 -0.58646,0.5188 -0.18044,-0.0451 -0.36089,-0.0902 -0.54134,-0.1353 -0.6090098,-0.1805 -0.7894598,-0.4737 -0.8571298,-0.8121 -0.04511,-0.4736 -0.31578,-3.1578 -0.33833,-3.248 -0.33834,-3.2932 -1.51125,-14.8418498 -1.51125,-14.8418498 -0.02256,-1.10524 -0.04512,-1.57892 1.08268,-2.14282 3.0450598,-1.51125 6.9246888,-0.06766 6.9246888,-0.06766 l 2.00747,-0.76691 c 2.6842,-0.9699 6.5638,-0.87968 9.4058,0.76691 0.5414,0.31578 1.6241,0.83457 1.5339,1.91725 z m -2.0752,21.7439798 c 0,0 0,0.7669 -0.0226,1.1503 -0.0225,0.4737 -0.0225,1.0376 -0.9473,1.2632 -4.8721,1.2857 -9.9923,1.2405 -14.886949,0 -0.9473498,-0.2481 -0.9247898,-0.7444 -0.9473498,-1.1955 -0.02255,-0.3834 -0.02255,-1.218 -0.02255,-1.2406 -0.02256,-0.4737 0.3383399,-0.7443 0.8120098,-0.6541 5.007429,0.9925 10.172739,0.9925 15.180139,0 0.4737,-0.0902 0.8572,0.203 0.8346,0.6767 z m 3.5864,-23.7063398 c -0.5865,-0.81202 -2.5037,-1.80448 -3.8571,-2.345826 -3.4961,-1.263135 -7.466,-0.924796 -10.57872,0.496226 l -0.40601,-0.11278 c -2.639039,-0.857123 -5.7743288,-0.406003 -7.5787988,0.5639 -1.127802,0.60901 -1.6465891,1.10525 -1.8270361,1.89471 -0.1127804,0.31578 -0.1804486,0.87968 -0.090225,1.8947 0,0.04511 -4e-7,0.06767 0.022556,0.11278 0.2706721,3.2029498 2.0300352,18.9921298 2.0525952,19.0147298 0.29323,3.1352 -0.15789,4.3984 0.47367,5.2329 0.04512,0.0677 0.09023,0.1128 0.13534,0.1579 0.27067,0.2707 0.65412,0.4963 1.26313,0.7218 0.11278,0.0451 0.24812,0.0902 0.3608998,0.1354 0.4962299,0.1804 1.0375699,0.3383 1.6014699,0.4736 2.12026,0.4963 4.375829,0.6316 6.428429,0.6316 2.0526,0 4.3308,-0.1353 6.4285,-0.6316 0.5639,-0.1353 1.1278,-0.2932 1.6015,-0.4736 0.1127,-0.0452 0.2481,-0.0903 0.3608,-0.1354 0.6091,-0.2481 1.0151,-0.4737 1.2632,-0.7218 0.0451,-0.0451 0.0902,-0.0902 0.1353,-0.1579 0.6316,-0.8345 0.203,-2.0977 0.4737,-5.2329 0,-0.0226 1.7819,-15.81178 2.0526,-19.0147298 0,-0.04511 0,-0.09023 0.0225,-0.11278 0.1579,-1.6917 -0.1127,-2.0526 -0.3383,-2.39093 z" + fill="#3b8047" + id="path1" /> +</svg> diff --git a/src/assets/javascripts/services.js b/src/assets/javascripts/services.js index 7213380f..961759c2 100644 --- a/src/assets/javascripts/services.js +++ b/src/assets/javascripts/services.js @@ -54,9 +54,10 @@ function regexArray(service, url, config, options, frontend) { * @param {URL} url * @param {string} frontend * @param {string} randomInstance + * @param {string} type * @returns {undefined|string} */ -function rewrite(url, originUrl, frontend, randomInstance) { +function rewrite(url, originUrl, frontend, randomInstance, type) { switch (frontend) { case "hyperpipe": for (const key of [...url.searchParams.keys()]) if (key !== "q") url.searchParams.delete(key) @@ -99,6 +100,7 @@ function rewrite(url, originUrl, frontend, randomInstance) { if (/\/@[a-z]+\//.exec(url.pathname)) return randomInstance return `${randomInstance}${url.pathname}${url.search}` } + case "small": case "libMedium": case "scribe": { const regex = url.hostname.match(/^(link|cdn-images-\d+|.*)\.medium\.com/) @@ -220,9 +222,9 @@ function rewrite(url, originUrl, frontend, randomInstance) { return `${randomInstance}${url.pathname}${url.search}` case "redlib": case "libreddit": { - const subdomain = url.hostname.match(/^(?:(?:external-)?preview|i)(?=\.redd\.it)/) + const subdomain = url.hostname.match(/^(?:((?:external-)?preview|i)\.)?redd\.it/) if (!subdomain) return `${randomInstance}${url.pathname}${url.search}` - switch (subdomain[0]) { + switch (subdomain[1]) { case "preview": return `${randomInstance}/preview/pre${url.pathname}${url.search}` case "external-preview": @@ -230,7 +232,7 @@ function rewrite(url, originUrl, frontend, randomInstance) { case "i": return `${randomInstance}/img${url.pathname}` } - return randomInstance + return `${randomInstance}/comments${url.pathname}` } case "teddit": if (/^(?:(?:external-)?preview|i)\.redd\.it/.test(url.hostname)) { @@ -238,6 +240,7 @@ function rewrite(url, originUrl, frontend, randomInstance) { else return `${randomInstance}${url.pathname}${url.search}&teddit_proxy=${url.hostname}` } return `${randomInstance}${url.pathname}${url.search}` + case "troddit": case "eddrit": if (/^(?:(?:external-)?preview|i)\.redd\.it/.test(url.hostname)) return randomInstance return `${randomInstance}${url.pathname}${url.search}` @@ -267,8 +270,11 @@ function rewrite(url, originUrl, frontend, randomInstance) { // https://stackexchange.com or https://superuser.com return `${randomInstance}${url.pathname}${url.search}` } - const regex = url.href.match(/https?:\/{2}(?:([a-zA-Z0-9-]+)\.)?stackexchange\.com\//) + const regex = url.href.match(/https?:\/{2}(?:([a-zA-Z0-9-]+)\.(meta\.)?)?stackexchange\.com\//) if (regex && regex.length > 1) { + if (regex[2]) { + return `${randomInstance}/exchange/${url.hostname}${url.pathname}${url.search}` + } const subdomain = regex[1] return `${randomInstance}/exchange/${subdomain}${url.pathname}${url.search}` } @@ -282,6 +288,15 @@ function rewrite(url, originUrl, frontend, randomInstance) { } case "biblioReads": return `${randomInstance}${url.pathname}${url.search}` + case "wikimore": { + let hostSplit = url.host.split(".") + // wikiless doesn't have mobile view support yet + if (hostSplit[0] != "wikipedia" && hostSplit[0] != "www") { + const lang = url.hostname.split(".")[0] + return `${randomInstance}/wiki/${lang}${url.pathname}${url.search}${url.hash}` + } + return `${randomInstance}${url.pathname}${url.search}${url.hash}` + } case "wikiless": { let hostSplit = url.host.split(".") // wikiless doesn't have mobile view support yet @@ -292,6 +307,7 @@ function rewrite(url, originUrl, frontend, randomInstance) { } return `${randomInstance}${url.pathname}${url.search}${url.hash}` } + case "offtiktok": case "proxiTok": if (url.pathname.startsWith("/email")) return randomInstance return `${randomInstance}${url.pathname}${url.search}` @@ -353,7 +369,10 @@ function rewrite(url, originUrl, frontend, randomInstance) { } } case "binternet": - if (url.hostname == "i.pinimg.com") return `${randomInstance}/image_proxy.php?url=${url.href}` + if (url.hostname == "i.pinimg.com") return `${randomInstance}/image_proxy.php?url=${encodeURIComponent(url.href)}` + return `${randomInstance}${url.pathname}${url.search}` + case "painterest": + if (url.hostname == "i.pinimg.com") return `${randomInstance}/_/proxy?url=${encodeURIComponent(url.href)}` return `${randomInstance}${url.pathname}${url.search}` case "laboratory": { let path = url.pathname @@ -378,11 +397,24 @@ function rewrite(url, originUrl, frontend, randomInstance) { } return `${randomInstance}${url.pathname}${url.search}` } + case "vixipy": { + const regex = /\/[a-z]{1,3}\/(.*)/.exec(url.pathname) + if (regex) { + let path = regex[1] + if (path.startsWith("tags/")) path = path.replace(/tags/, "tag") + return `${randomInstance}/${path}${url.search}` + } + return `${randomInstance}${url.pathname}${url.search}` + } case "invidious": { + // tracker url.searchParams.delete("si") + + if (type == "sub_frame") url.searchParams.append("autoplay", "0") + if (url.hostname == "youtu.be" || (url.hostname.endsWith("youtube.com") && url.pathname.startsWith("/live"))) { const watch = url.pathname.substring(url.pathname.lastIndexOf("/") + 1) - return `${randomInstance}/watch?v=${watch}${url.search.replace("?", "&")}` + return `${randomInstance}/watch?v=${watch}&${url.search.substring(1)}` } if (url.hostname.endsWith("youtube.com") && url.pathname.startsWith("/redirect?")) return url.href return `${randomInstance}${url.pathname}${url.search}` @@ -501,6 +533,7 @@ function rewrite(url, originUrl, frontend, randomInstance) { } return `${randomInstance}${url.pathname}${url.search}` } + case "ultimateTab": case "freetar": if (url.pathname.startsWith("/search.php")) { url.searchParams.set("search_term", url.searchParams.get("value")) @@ -519,16 +552,16 @@ function rewrite(url, originUrl, frontend, randomInstance) { return `${randomInstance}${url.pathname}${url.search}` } case "skunkyArt": { - if (url.pathname.startsWith("/search")) return `${randomInstance}${url.pathname}${url.search}&scope=all` + if (url.pathname.startsWith("/search")) return `${randomInstance}${url.pathname}${url.search}&type=all` - const artReg = /^\/.*?\/art\/(.*)\/?/.exec(url.pathname) - if (artReg) return `${randomInstance}/post/art/${artReg[1]}${url.search}` + const artReg = /^\/(.*?)\/art\/(.*)\/?/.exec(url.pathname) + if (artReg) return `${randomInstance}/post/${artReg[1]}/${artReg[2]}${url.search}` const userReg = /^\/([^\/]+)$/.exec(url.pathname) - if (userReg) return `${randomInstance}/user/${userReg[1]}${url.search}` + if (userReg) return `${randomInstance}/group_user?q=${userReg[1]}&type=about` - const galleryReg = /^\/.*?\/gallery(\/$|$)$/.exec(url.pathname) - if (galleryReg) return `${randomInstance}/user/${userReg[1]}?a=gallery` + const galleryReg = /^\/(.*?)\/gallery(\/$|$)$/.exec(url.pathname) + if (galleryReg) return `${randomInstance}/group_user?q=${galleryReg[1]}&type=gallery` return `${randomInstance}${url.pathname}${url.search}` } @@ -550,6 +583,43 @@ function rewrite(url, originUrl, frontend, randomInstance) { const accountReg = /^\/([^\/]+)\/?$/.exec(url.pathname) if (accountReg) return `${randomInstance}/account${url.pathname}${url.search}` + case "duckDuckGoAiChat": + return "https://duckduckgo.com/?q=DuckDuckGo+AI+Chat&ia=chat&duckai=1" + + case "soundcloak": + if (url.pathname.startsWith("/feed") || url.pathname.startsWith("/stream")) { + // this feature requires authentication and is unsupported, so just redirect to main page + return randomInstance + } + + if (url.pathname.startsWith("/search")) { + if (!url.search) { + return randomInstance + } + + let type = "" + if (url.pathname.startsWith("/search/sounds")) { + type = "tracks" + } else if (url.pathname.startsWith("/search/people")) { + type = "users" + } else if (url.pathname.startsWith("/search/albums") || url.pathname.startsWith("/search/sets")) { + type = "playlists" + } + + if (type) { + type = "&type=" + type + } else { + return randomInstance // fallback for unsupported search types (searching for anything for example) + } + + return `${randomInstance}/search${url.search}${type}` + } + + if (url.host == "on.soundcloud.com") { + return `${randomInstance}/on${url.pathname}` + } + + return `${randomInstance}${url.pathname}${url.search}` case "piped": case "pipedMaterial": case "cloudtube": @@ -627,7 +697,7 @@ function redirect(url, type, originUrl, documentUrl, incognito, forceRedirection } if (!frontend) return - return rewrite(url, originUrl, frontend, randomInstance) + return rewrite(url, originUrl, frontend, randomInstance, type) } /** @@ -647,30 +717,19 @@ async function redirectAsync(url, type, originUrl, documentUrl, incognito, force /** * @param {URL} url */ -function computeService(url) { - return new Promise(async resolve => { - const config = await utils.getConfig() - const options = await utils.getOptions() - for (const service in config.services) { - if (regexArray(service, url, config, options)) { - resolve(service) - return - } else { - for (const frontend in config.services[service].frontends) { - if (all(service, frontend, options, config).findIndex(instance => url.href.startsWith(instance)) >= 0) { - return resolve(service) - } - } - } - } - resolve() - }) -} -export function computeFrontend(url) { +async function computeServiceFrontend(url) { + const config = await utils.getConfig() + const options = await utils.getOptions() for (const service in config.services) { - for (const frontend in config.services[service].frontends) { - if (all(service, frontend, options, config).findIndex(instance => url.href.startsWith(instance)) >= 0) { - return { service, frontend } + if (regexArray(service, url, config, options)) { + return { service, frontend: null } + } else { + for (const frontend in config.services[service].frontends) { + const instances = all(service, frontend, options, config) + const i = instances.findIndex(instance => url.href.startsWith(instance)) + if (i >= 0) { + return { service, frontend } + } } } } @@ -765,6 +824,39 @@ async function reverse(url) { return `${config.services[service].url}/${url.search.slice(1)}` case "goodreads": return `https://goodreads.com${url.pathname}${url.search}` + case "soundcloud": + if (frontend == "soundcloak") { + if (url.pathname.includes("/_/")) { + // soundcloak-specific pages + return `${config.services[service].url}${url.pathname.split("/_/")[0]}` + } + + if (url.pathname == "/search") { + let type = url.searchParams.get("type") + switch (type) { + case "playlists": + type = "sets" + break + case "tracks": + type = "sounds" + break + case "users": + type = "people" + break + default: + type = "" + } + + url.searchParams.delete("type") + if (!type) { + return `${config.services[service].url}/search?${url.searchParams.toString()}` + } else { + return `${config.services[service].url}/search/${type}?${url.searchParams.toString()}` + } + } + + return `${config.services[service].url}${url.pathname}` + } default: return } @@ -783,9 +875,12 @@ const defaultInstances = { poketube: ["https://poketube.fun"], proxiTok: ["https://proxitok.pabloferreiro.es"], redlib: ["https://libreddit.vhack.eu"], + offtiktok: ["https://www.offtiktok.com"], eddrit: ["https://eddrit.com"], + troddit: ["https://www.troddit.com"], scribe: ["https://scribe.rip"], libMedium: ["https://md.vern.cc"], + small: ["https://small.bloat.cat"], quetre: ["https://quetre.iket.me"], libremdb: ["https://libremdb.iket.me"], simplyTranslate: ["https://simplytranslate.org"], @@ -811,27 +906,36 @@ const defaultInstances = { wolfreeAlpha: ["https://gqq.gitlab.io", "https://uqq.gitlab.io"], laboratory: ["https://lab.vern.cc"], binternet: ["https://bn.bloat.cat"], + painterest: ["https://pt.bloat.cat"], pixivFe: ["https://pixivfe.exozy.me"], liteXiv: ["https://litexiv.exozy.me"], + vixipy: ["https://vx.maid.zone"], indestructables: ["https://indestructables.private.coffee"], destructables: ["https://ds.vern.cc"], + structables: ["https://structables.private.coffee"], safetwitch: ["https://safetwitch.drgns.space"], twineo: ["https://twineo.exozy.me"], proxigram: ["https://ig.opnxng.com"], - tuboYoutube: ["https://tubo.migalmoreno.com"], - tuboSoundcloud: ["https://tubo.migalmoreno.com"], + tuboYoutube: ["https://tubo.media"], + tuboSoundcloud: ["https://tubo.media"], tekstoLibre: ["https://davilarek.github.io/TekstoLibre"], skyview: ["https://skyview.social"], priviblur: ["https://pb.bloat.cat"], nitter: ["https://nitter.privacydev.net"], pasted: ["https://pasted.drakeerv.com"], + pasty: ["https://pasty.lus.pm"], freetar: ["https://freetar.de"], + ultimateTab: ["https://ultimate-tab.com"], ratAintTieba: ["https://rat.fis.land"], shoelace: ["https://shoelace.mint.lgbt"], skunkyArt: ["https://skunky.bloat.cat"], - ytify: ["https://ytify.netlify.app"], + ytify: ["https://ytify.us.kg"], nerdsForNerds: ["https://nn.vern.cc"], + ducksForDucks: ["https://ducksforducks.private.coffee"], koub: ["https://koub.clovius.club"], + soundcloak: ["https://soundcloak.fly.dev"], + gocook: ["https://cook.adminforge.de"], + wikimore: ["https://wikimore.private.coffee"], } async function getDefaults() { @@ -942,6 +1046,7 @@ async function copyRaw(url) { * @param {URL} url */ function isException(url) { + if (!options) return false if (!options.exceptions) return false let exceptions = options.exceptions if (exceptions && url) { @@ -968,12 +1073,11 @@ function isException(url) { export default { redirect, redirectAsync, - computeService, + computeServiceFrontend, reverse, initDefaults, processUpdate, copyRaw, switchInstance, isException, - computeFrontend, } diff --git a/src/assets/javascripts/utils.js b/src/assets/javascripts/utils.js index e5b8ba46..f360a15b 100644 --- a/src/assets/javascripts/utils.js +++ b/src/assets/javascripts/utils.js @@ -31,7 +31,8 @@ function protocolHost(url) { if (url.pathname == "/TekstoLibre/" && url.host.endsWith("github.io")) return `${url.protocol}//${url.host}${url.pathname.slice(0, -1)}` - return `${url.protocol}//${url.host}${url.pathname}` + const pathname = url.pathname != "/" ? url.pathname : "" + return `${url.protocol}//${url.host}${pathname}` } /** @@ -221,6 +222,22 @@ export function randomInstances(clearnet, n) { } return instances } + +async function autoPickInstance(clearnet, url) { + if (url) { + const i = clearnet.findIndex(instance => url.href.startsWith(instance)) + if (i >= 0) clearnet.splice(i, 1) + } + const random = randomInstances(clearnet, 5) + const pings = await Promise.all([ + ...random.map(async instance => { + return [instance, await ping(instance)] + }), + ]) + pings.sort((a, b) => a[1] - b[1]) + return pings[0][0] +} + export function style(options, window) { const vars = cssVariables(options, window) return `--text: ${vars.text}; @@ -276,4 +293,5 @@ export default { convertMapCentre, randomInstances, style, + autoPickInstance, } |