diff --git a/public/css/fonts/Hack-Bold.ttf b/public/css/fonts/Hack-Bold.ttf new file mode 100755 index 0000000..7ff4975 Binary files /dev/null and b/public/css/fonts/Hack-Bold.ttf differ diff --git a/public/css/fonts/Hack-BoldItalic.ttf b/public/css/fonts/Hack-BoldItalic.ttf new file mode 100755 index 0000000..3b137d9 Binary files /dev/null and b/public/css/fonts/Hack-BoldItalic.ttf differ diff --git a/public/css/fonts/Hack-Italic.ttf b/public/css/fonts/Hack-Italic.ttf new file mode 100755 index 0000000..d26198a Binary files /dev/null and b/public/css/fonts/Hack-Italic.ttf differ diff --git a/public/css/fonts/Hack-Regular.ttf b/public/css/fonts/Hack-Regular.ttf new file mode 100755 index 0000000..92a90cb Binary files /dev/null and b/public/css/fonts/Hack-Regular.ttf differ diff --git a/public/css/fonts/TerminessNerdFontMono-Bold.ttf b/public/css/fonts/TerminessNerdFontMono-Bold.ttf new file mode 100755 index 0000000..c3e5513 Binary files /dev/null and b/public/css/fonts/TerminessNerdFontMono-Bold.ttf differ diff --git a/public/css/fonts/TerminessNerdFontMono-BoldItalic.ttf b/public/css/fonts/TerminessNerdFontMono-BoldItalic.ttf new file mode 100755 index 0000000..5e3ffda Binary files /dev/null and b/public/css/fonts/TerminessNerdFontMono-BoldItalic.ttf differ diff --git a/public/css/fonts/TerminessNerdFontMono-Italic.ttf b/public/css/fonts/TerminessNerdFontMono-Italic.ttf new file mode 100755 index 0000000..bc9e2ed Binary files /dev/null and b/public/css/fonts/TerminessNerdFontMono-Italic.ttf differ diff --git a/public/css/fonts/TerminessNerdFontMono-Regular.ttf b/public/css/fonts/TerminessNerdFontMono-Regular.ttf new file mode 100755 index 0000000..7d56730 Binary files /dev/null and b/public/css/fonts/TerminessNerdFontMono-Regular.ttf differ diff --git a/public/css/themes/eir.css b/public/css/themes/eir.css new file mode 100755 index 0000000..8677a29 --- /dev/null +++ b/public/css/themes/eir.css @@ -0,0 +1,99 @@ +@font-face { + font-family: hack; + src: url("../fonts/Hack-Regular.ttf"); +} +@font-face { + font-family: hack; + src: url("../fonts/Hack-Bold.ttf"); + font-weight: bold; +} +@font-face { + font-family: hack; + src: url("../fonts/Hack-Italic.ttf"); + font-style: italic; +} +@font-face { + font-family: hack; + src: url("../fonts/Hack-BoldItalic.ttf"); + font-weight: bold; + font-style: italic; +} + +@font-face { + font-family: Terminess; + src: url("../fonts/TerminessNerdFontMono-Regular.ttf"); +} +@font-face { + font-family: Terminess; + src: url("../fonts/TerminessNerdFontMono-Bold.ttf"); + font-weight: bold; +} +@font-face { + font-family: Terminess; + src: url("../fonts/TerminessNerdFontMono-Italic.ttf"); + font-style: italic; +} +@font-face { + font-family: Terminess; + src: url("../fonts/TerminessNerdFontMono-BoldItalic.ttf"); + font-weight: bold; + font-style: italic; +} + +body { + background: linear-gradient(rgba(130, 88, 88, 0.875), rgba(130, 88, 88, 0.5)), url("https://eir-nya.gay/res/images/cubes.png"); + background: -webkit-linear-gradient(rgba(130, 88, 88, 0.875), rgba(130, 88, 88, 0.5)), url("https://eir-nya.gay/res/images/cubes.png"); + background: -moz-linear-gradient(rgba(130, 88, 88, 0.875), rgba(130, 88, 88, 0.5)), url("https://eir-nya.gay/res/images/cubes.png"); + background: -o-linear-gradient(rgba(130, 88, 88, 0.875), rgba(130, 88, 88, 0.5)), url("https://eir-nya.gay/res/images/cubes.png"); + background: -ms-linear-gradient(rgba(130, 88, 88, 0.875), rgba(130, 88, 88, 0.5)), url("https://eir-nya.gay/res/images/cubes.png"); + background-attachment: fixed; + + font-family: Terminess, hack, 'Courier New', courier, monospace; +} +.tweet-content { + font-family: hack, 'Courier New', courier, monospace; +} +.show-more { + background-color: transparent; +} +body { + --bg_color: transparent; /*#282a36;*/ + --fg_color: #f8f8f2; + --fg_faded: #818eb6; + --fg_dark: var(--fg_faded); + --fg_nav: var(--accent); + + --bg_panel: rgba(0.9803921568627451, 0.6666666666666666, 0.6705882352941176, 0.875); /*#343746;*/ + --bg_elements: #292b36; + --bg_overlays: #20202080; /*#44475a;*/ + --bg_hover: #2f323f; + + --grey: var(--fg_faded); + --dark_grey: #44475a; + --darker_grey: #3d4051; + --darkest_grey: #363948; + --border_grey: #44475a; + + --accent: #faaaab; + --accent_light: #facdce; + --accent_dark: #ab7475; + --accent_border: #e36f7196; + + --play_button: #ffb86c; + --play_button_hover: #ffc689; + + --more_replies_dots: #bd93f9; + --error_red: #ff5555; + + --verified_blue: var(--accent); + --icon_text: ##F8F8F2; + + --tab: #6272a4; + --tab_selected: var(--accent); + + --profile_stat: #919cbf; +} + +.search-bar > form input::placeholder{ + color: var(--fg_faded); +} diff --git a/public/js/eirResources.js b/public/js/eirResources.js new file mode 100755 index 0000000..946231f --- /dev/null +++ b/public/js/eirResources.js @@ -0,0 +1,7 @@ +let eirTheme = document.querySelector("link[href='/css/themes/eir.css']"); +if (eirTheme != null) { + let cursorScr = document.createElement("script"); + cursorScr.src = "/res/js/cursors.js"; + cursorScr.defer = ""; + document.getElementsByTagName("head")[0].appendChild(cursorScr); +} diff --git a/public/js/hls.min.js b/public/js/hls.light.min.js old mode 100644 new mode 100755 similarity index 100% rename from public/js/hls.min.js rename to public/js/hls.light.min.js diff --git a/public/md/about.md b/public/md/about.md index b0d8e50..22d4780 100644 --- a/public/md/about.md +++ b/public/md/about.md @@ -1,81 +1,89 @@ -# About - -Nitter is a free and open source alternative Twitter front-end focused on -privacy and performance. The source is available on GitHub at - +# My instance **This instance is running a fork, whose source can be found at** - +. -* No JavaScript or ads -* All requests go through the backend, client never talks to Twitter -* Prevents Twitter from tracking your IP or JavaScript fingerprint -* Uses Twitter's unofficial API (no rate limits or developer account required) -* Lightweight (for [@nim_lang](/nim_lang), 60KB vs 784KB from twitter.com) -* RSS feeds -* Themes -* Mobile support (responsive design) -* AGPLv3 licensed, no proprietary instances permitted +My fork is based on [Cynthia Foxwell's fork](https://gitlab.com/Cynosphere/nitter). +Nitter is created by Zedeus, whose source can be found at . -Nitter's GitHub wiki contains -[instances](https://github.com/zedeus/nitter/wiki/Instances) and -[browser extensions](https://github.com/zedeus/nitter/wiki/Extensions) -maintained by the community. +The rest of this page is copied from Cynthia's fork: -### Fork features - -* Localized following via cookies (list exportable and editable in preferences) -* Image zooming/carousel (requires JavaScript) -* Up to date Twitter features, e.g. Community Notes -* Embeds for chat services on-par with services like [FxTwitter](https://github.com/FixTweet/FxTwitter) and [vxTwitter](https://github.com/dylanpdx/BetterTwitFix) - -## Why use Nitter? - -It's impossible to use Twitter without JavaScript enabled. For privacy-minded -folks, preventing JavaScript analytics and IP-based tracking is important, but -apart from using a VPN and uBlock/uMatrix, it's impossible. Despite being behind -a VPN and using heavy-duty adblockers, you can get accurately tracked with your -[browser's fingerprint](https://restoreprivacy.com/browser-fingerprinting/), -[no JavaScript required](https://noscriptfingerprint.com/). This all became -particularly important after Twitter [removed the -ability](https://www.eff.org/deeplinks/2020/04/twitter-removes-privacy-option-and-shows-why-we-need-strong-privacy-laws) -for users to control whether their data gets sent to advertisers. - -Using an instance of Nitter (hosted on a VPS for example), you can browse -Twitter without JavaScript while retaining your privacy. In addition to -respecting your privacy, Nitter is on average around 15 times lighter than -Twitter, and in most cases serves pages faster (eg. timelines load 2-4x faster). - -## Donating - -Even though I could be selfish and point people to donate to me instead of -Zedeus, it would be disrespectful. - -GitHub Sponsors: \ -Liberapay: \ -Patreon: \ -BTC: bc1qp7q4qz0fgfvftm5hwz3vy284nue6jedt44kxya \ -ETH: 0x66d84bc3fd031b62857ad18c62f1ba072b011925 \ -LTC: ltc1qhsz5nxw6jw9rdtw9qssjeq2h8hqk2f85rdgpkr \ -XMR: 42hKayRoEAw4D6G6t8mQHPJHQcXqofjFuVfavqKeNMNUZfeJLJAcNU19i1bGdDvcdN6romiSscWGWJCczFLe9RFhM3d1zpL - -## Credits - -* Zedeus for this project -* PrivacyDevel, cmj, and taskylizard for keeping this project alive with forks after the main repo went inactive -* Every other contributors who've committed to the main repo in the past - -## To any law enforcement agencies and copyright holders - -**All illegal content should be reported to Twitter directly.** This service is -merely a proxy of Twitter and no content is hosted on this server. Do not waste -your time contacting internet service providers, hosting providers and/or domain -registrars. - -If you would like more context, you can read about this exact issue happening to -[PussTheCat.org's instance](https://pussthecat.org/nitter/). - -I emplore all Nitter instance hosts to not enable media proxying, even if it -"phones home" to Twitter's CDN (which doesn't really pose a tracking risk and -breaks videos anyways), as it [has been used as an attack vector to take down -nitter.net](https://github.com/zedeus/nitter/issues/1150#issuecomment-1890855255). +> # About +> +> Nitter is a free and open source alternative Twitter front-end focused on +> privacy and performance. +> +> * No JavaScript or ads +> * All requests go through the backend, client never talks to Twitter +> * Prevents Twitter from tracking your IP or JavaScript fingerprint +> * Uses Twitter's unofficial API (no rate limits or developer account required) +> * Lightweight (for [@nim_lang](/nim_lang), 60KB vs 784KB from twitter.com) +> * RSS feeds +> * Themes +> * Mobile support (responsive design) +> * AGPLv3 licensed, no proprietary instances permitted (source code below) +> +> Nitter's GitHub wiki contains +> [instances](https://github.com/zedeus/nitter/wiki/Instances) and +> [browser extensions](https://github.com/zedeus/nitter/wiki/Extensions) +> maintained by the community. +> +> ### Fork features by Cynthia Foxwell +> +> * Localized following via cookies (list exportable and editable in preferences) +> * Image zooming/carousel (requires JavaScript) +> * Up to date Twitter features, e.g. Community Notes +> * Embeds for chat services on-par with services like [FxTwitter](https://github.com/FixTweet/FxTwitter) and [vxTwitter](https://github.com/dylanpdx/BetterTwitFix) +> +> ## Why use Nitter? +> +> It's impossible to use Twitter without JavaScript enabled. For privacy-minded +> folks, preventing JavaScript analytics and IP-based tracking is important, but +> apart from using a VPN and uBlock/uMatrix, it's impossible. Despite being behind +> a VPN and using heavy-duty adblockers, you can get accurately tracked with your +> [browser's fingerprint](https://restoreprivacy.com/browser-fingerprinting/), +> [no JavaScript required](https://noscriptfingerprint.com/). This all became +> particularly important after Twitter [removed the +> ability](https://www.eff.org/deeplinks/2020/04/twitter-removes-privacy-option-and-shows-why-we-need-strong-privacy-laws) +> for users to control whether their data gets sent to advertisers. +> +> Using an instance of Nitter (hosted on a VPS for example), you can browse +> Twitter without JavaScript while retaining your privacy. In addition to +> respecting your privacy, Nitter is on average around 15 times lighter than +> Twitter, and in most cases serves pages faster (eg. timelines load 2-4x faster). +> +> ## Donating +> +> Even though I could be selfish and point people to donate to me instead of +> Zedeus, it would be disrespectful. +> +> GitHub Sponsors: \ +> Donations go to zedeus, original creator of Nitter. +> +> Liberapay: \ +> Patreon: \ +> BTC: bc1qp7q4qz0fgfvftm5hwz3vy284nue6jedt44kxya \ +> ETH: 0x66d84bc3fd031b62857ad18c62f1ba072b011925 \ +> LTC: ltc1qhsz5nxw6jw9rdtw9qssjeq2h8hqk2f85rdgpkr \ +> XMR: 42hKayRoEAw4D6G6t8mQHPJHQcXqofjFuVfavqKeNMNUZfeJLJAcNU19i1bGdDvcdN6romiSscWGWJCczFLe9RFhM3d1zpL +> +> ## Credits +> +> * Zedeus for this project +> * PrivacyDevel, cmj, and taskylizard for keeping this project alive with forks after the main repo went inactive +> * Every other contributors who've committed to the main repo in the past +> +> ## To any law enforcement agencies and copyright holders +> +> **All illegal content should be reported to Twitter directly.** This service is +> merely a proxy of Twitter and no content is hosted on this server. Do not waste +> your time contacting internet service providers, hosting providers and/or domain +> registrars. +> +> If you would like more context, you can read about this exact issue happening to +> [PussTheCat.org's instance](https://pussthecat.org/nitter/). +> +> I emplore all Nitter instance hosts to not enable media proxying, even if it +> "phones home" to Twitter's CDN (which doesn't really pose a tracking risk and +> breaks videos anyways), as it [has been used as an attack vector to take down +> nitter.net](https://github.com/zedeus/nitter/issues/1150#issuecomment-1890855255). diff --git a/public/site.webmanifest b/public/site.webmanifest index 5ee0906..29c0d95 100644 --- a/public/site.webmanifest +++ b/public/site.webmanifest @@ -1,6 +1,6 @@ { - "name": "Nitter", - "short_name": "Nitter", + "name": "Kitter", + "short_name": "Kitter", "icons": [ { "src": "/android-chrome-192x192.png", @@ -18,7 +18,7 @@ "type": "image/png" } ], - "theme_color": "#333333", - "background_color": "#333333", + "theme_color": "#faaaab", + "background_color": "#faaaab", "display": "standalone" } diff --git a/src/config.nim b/src/config.nim index 7fdf83d..074dfb3 100644 --- a/src/config.nim +++ b/src/config.nim @@ -22,6 +22,7 @@ proc getConfig*(path: string): (Config, parseCfg.Config) = httpMaxConns: cfg.get("Server", "httpMaxConnections", 100), staticDir: cfg.get("Server", "staticDir", "./public"), title: cfg.get("Server", "title", "Nitter"), + oembedColor: cfg.get("Server", "oembedColor", "#1F1F1F"), hostname: cfg.get("Server", "hostname", "nitter.net"), # Cache diff --git a/src/nitter.nim b/src/nitter.nim index 0db3980..e5e9dca 100644 --- a/src/nitter.nim +++ b/src/nitter.nim @@ -14,7 +14,7 @@ import routes/[ activityspoof] const instancesUrl = "https://github.com/zedeus/nitter/wiki/Instances" -const issuesUrl = "https://gitlab.com/Cynosphere/nitter/issues" +const issuesUrl = "https://git.eir-nya.gay/eir/nitter/issues" #let accountsPath = getEnv("NITTER_ACCOUNTS_FILE", "./guest_accounts.json") diff --git a/src/prefs_impl.nim b/src/prefs_impl.nim index 88c4e1e..e02847a 100644 --- a/src/prefs_impl.nim +++ b/src/prefs_impl.nim @@ -59,6 +59,9 @@ genPrefs: theme(select, "Nitter"): "Theme" + eirResources(checkbox, true): + "Some extra silly js I added, like cursors :3" + infiniteScroll(checkbox, false): "Infinite scrolling (experimental, requires JavaScript)" diff --git a/src/routes/activityspoof.nim b/src/routes/activityspoof.nim index 08f7e04..7849985 100644 --- a/src/routes/activityspoof.nim +++ b/src/routes/activityspoof.nim @@ -110,7 +110,7 @@ proc createActivityPubRouter*(cfg: Config) = let image = getUrlPrefix(cfg) & getPicUrl(imageObj.url) var mediaObj = newJObject() - mediaObj["id"] = %"150745989836308480" # idk if discord even parses this snowflake, but its my user id why not + mediaObj["id"] = %"138733266285887488" # idk if discord even parses this snowflake, but its my user id why not mediaObj["type"] = %"image" mediaObj["url"] = %image mediaObj["preview_url"] = %image @@ -134,7 +134,7 @@ proc createActivityPubRouter*(cfg: Config) = if videoObj.description.len > 0: description = videoObj.description - mediaObj["id"] = %"150745989836308480" + mediaObj["id"] = %"138733266285887488" mediaObj["type"] = %"video" mediaObj["url"] = %videoUrl mediaObj["preview_url"] = %videoPreview @@ -153,7 +153,7 @@ proc createActivityPubRouter*(cfg: Config) = gifPreview = getUrlPrefix(cfg) & getPicUrl(gif.thumb) var mediaObj = newJObject() - mediaObj["id"] = %"150745989836308480" + mediaObj["id"] = %"138733266285887488" mediaObj["type"] = %"video" mediaObj["url"] = %gifUrl mediaObj["preview_url"] = %gifPreview @@ -321,19 +321,19 @@ proc createActivityPubRouter*(cfg: Config) = var nodeinfo = newJObject() nodeinfo["version"] = %"2.1" nodeinfo["software"] = %*{ - "name": "Nitter", - "repository": "https://gitlab.com/Cynosphere/nitter" + "name": cfg.title, + "repository": "https://git.eir-nya.gay/eir/nitter" } var metadata = newJObject() metadata["features"] = newJArray() metadata["federation"] = newJObject() metadata["nodeDescription"] = %"Alternative Twitter front-end (ActivityPub support added for Discord)" - metadata["nodeName"] = %"Nitter" + metadata["nodeName"] = %cfg.title metadata["private"] = %true metadata["maintainer"] = %*{ - "name": "Cynthia", - "email": "gamers@riseup.net" + "name": "Eir", + "email": "eir@eir-nya.gay" } nodeinfo["metadata"] = metadata diff --git a/src/types.nim b/src/types.nim index 34e61e8..fbca8ee 100644 --- a/src/types.nim +++ b/src/types.nim @@ -286,6 +286,7 @@ type useHttps*: bool httpMaxConns*: int title*: string + oembedColor*: string hostname*: string staticDir*: string diff --git a/src/views/about.nim b/src/views/about.nim index 4eb3a71..575a0f3 100644 --- a/src/views/about.nim +++ b/src/views/about.nim @@ -5,7 +5,7 @@ import karax/[karaxdsl, vdom] const date = staticExec("git show -s --format=\"%cd\" --date=format:\"%Y.%m.%d\"") hash = staticExec("git show -s --format=\"%h\"") - link = "https://gitlab.com/Cynosphere/nitter/commit/" & hash + link = "https://git.eir-nya.gay/eir/nitter/commit/" & hash version = &"{date}-{hash}" var aboutHtml: string diff --git a/src/views/embed.nim b/src/views/embed.nim index bfe0b1f..0234c78 100644 --- a/src/views/embed.nim +++ b/src/views/embed.nim @@ -23,11 +23,11 @@ proc renderVideoEmbed*(tweet: Tweet; cfg: Config; req: Request): string = result = doctype & $node -proc generateOembed*(cfg: Config; typ, title, user, url, provider: string): JsonNode = +proc generateOembed*(cfg: Config; typ, title, user, url: string, provider: string): JsonNode = %*{ "type": typ, "version": "1.0", - "provider_name": provider, + "provider_name": provider, #cfg.title, "provider_url": getUrlPrefix(cfg), "title": title, "author_name": user, diff --git a/src/views/general.nim b/src/views/general.nim index d9a60b3..dc35204 100644 --- a/src/views/general.nim +++ b/src/views/general.nim @@ -86,6 +86,10 @@ proc renderHead*(prefs: Prefs; cfg: Config; req: Request; titleText=""; desc=""; if prefs.infiniteScroll: script(src="/js/infiniteScroll.js", `defer`="") + # Eir: load custom js + if prefs.eirResources: + script(src="/js/eirResources.js", `defer`="") + title: if titleText.len > 0: text titleText & " | " & cfg.title @@ -96,7 +100,7 @@ proc renderHead*(prefs: Prefs; cfg: Config; req: Request; titleText=""; desc=""; let finalizedDesc = stripHtml(desc) meta(name="viewport", content="width=device-width, initial-scale=1.0") - meta(name="theme-color", content="#1F1F1F") + meta(name="theme-color", content=cfg.oembedColor) meta(property="og:type", content=ogType) if video.len > 0 and len(finalizedDesc) <= 67: meta(property="og:title", content=finalizedDesc) @@ -106,7 +110,7 @@ proc renderHead*(prefs: Prefs; cfg: Config; req: Request; titleText=""; desc=""; meta(property="og:locale", content="en_US") meta(name="referrer", content="no-referrer") - var siteName = "Nitter" + var siteName = cfg.title if time.isSome: let timeObj = time.get let timeStr = $timeObj @@ -114,7 +118,7 @@ proc renderHead*(prefs: Prefs; cfg: Config; req: Request; titleText=""; desc=""; if not isDiscord: let formattedTime = timeObj.format("yyyy/MM/dd HH:mm:ss") - siteName &= &" • {formattedTime}" + siteName = &"{siteName} • {formattedTime}" if stats.len > 0: siteName &= "\n" & stats