diff --git a/public/md/about.md b/public/md/about.md index dc51697..c0adda9 100644 --- a/public/md/about.md +++ b/public/md/about.md @@ -4,9 +4,6 @@ Nitter is a free and open source alternative Twitter front-end focused on privacy and performance. The source is available on GitHub at -**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 @@ -22,13 +19,6 @@ Nitter's GitHub wiki contains [browser extensions](https://github.com/zedeus/nitter/wiki/Extensions) maintained by the community. -### 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 @@ -46,12 +36,12 @@ 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). +In the future a simple account system will be added that lets you follow Twitter +users, allowing you to have a clean chronological timeline without needing a +Twitter account. + ## 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 \ @@ -59,23 +49,6 @@ ETH: 0x66d84bc3fd031b62857ad18c62f1ba072b011925 \ LTC: ltc1qhsz5nxw6jw9rdtw9qssjeq2h8hqk2f85rdgpkr \ XMR: 42hKayRoEAw4D6G6t8mQHPJHQcXqofjFuVfavqKeNMNUZfeJLJAcNU19i1bGdDvcdN6romiSscWGWJCczFLe9RFhM3d1zpL -## Credits +## Contact -* 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). +Feel free to join our [Matrix channel](https://matrix.to/#/#nitter:matrix.org). diff --git a/src/parser.nim b/src/parser.nim index ed40d09..10d2866 100644 --- a/src/parser.nim +++ b/src/parser.nim @@ -208,7 +208,6 @@ proc parseTweet(js: JsonNode; jsCard: JsonNode = newJNull()): Tweet = id: js{"id_str"}.getId, threadId: js{"conversation_id_str"}.getId, replyId: js{"in_reply_to_status_id_str"}.getId, - replyHandle: js{"in_reply_to_screen_name"}.getStr, text: js{"full_text"}.getStr, time: js{"created_at"}.getTime, hasThread: js{"self_thread"}.notNull, diff --git a/src/routes/status.nim b/src/routes/status.nim index b780132..66bddb4 100644 --- a/src/routes/status.nim +++ b/src/routes/status.nim @@ -1,5 +1,5 @@ # SPDX-License-Identifier: AGPL-3.0-only -import asyncdispatch, strutils, sequtils, uri, options, sugar, strformat +import asyncdispatch, strutils, sequtils, uri, options, sugar import jester, karax/vdom @@ -64,43 +64,30 @@ proc createStatusRouter*(cfg: Config) = resp Http404, showError(error, cfg) let - tweet = conv.tweet - title = pageTitle(tweet) - ogTitle = pageTitle(tweet.user) - desc = tweet.text - avatar = tweet.user.userPic - time = some(tweet.time) + title = pageTitle(conv.tweet) + ogTitle = pageTitle(conv.tweet.user) + desc = conv.tweet.text + avatar = conv.tweet.user.userPic + time = some(conv.tweet.time) var - images = tweet.photos + images = conv.tweet.photos video = "" - context = "" - contextUrl = "" - if tweet.quote.isSome(): - let - quote = tweet.quote.get() - quoteUser = quote.user - context = &"↘ Quoting: {quoteUser.fullname} (@{quoteUser.username})" - contextUrl = &"{getUrlPrefix(cfg)}/i/status/{quote.id}" - elif tweet.replyId != 0: - context = &"↩ Replying to: @{tweet.replyHandle}" - contextUrl = &"{getUrlPrefix(cfg)}/i/status/{tweet.replyId}" - - if tweet.video.isSome(): - let videoObj = get(tweet.video) + if conv.tweet.video.isSome(): + let videoObj = get(conv.tweet.video) images = @[videoObj.thumb] let vars = videoObj.variants.filterIt(it.contentType == mp4) # idk why this wont sort when it sorts everywhere else #video = vars.sortedByIt(it.bitrate)[^1].url video = vars[^1].url - elif tweet.gif.isSome(): - let gif = get(tweet.gif) + elif conv.tweet.gif.isSome(): + let gif = get(conv.tweet.gif) images = @[gif.thumb] video = getPicUrl(gif.url) - #elif tweet.card.isSome(): - # let card = tweet.card.get() + #elif conv.tweet.card.isSome(): + # let card = conv.tweet.card.get() # if card.image.len > 0: # images = @[card.image] # elif card.video.isSome(): @@ -108,8 +95,7 @@ proc createStatusRouter*(cfg: Config) = let html = renderConversation(conv, prefs, getPath() & "#m") resp renderMain(html, request, cfg, prefs, title, desc, ogTitle, - images=images, video=video, avatar=avatar, time=time, - context=context, contextUrl=contextUrl) + images=images, video=video, avatar=avatar, time=time) get "/@name/@s/@id/@m/?@i?": cond @"s" in ["status", "statuses"] diff --git a/src/types.nim b/src/types.nim index feb06e6..4fdef5a 100644 --- a/src/types.nim +++ b/src/types.nim @@ -211,7 +211,6 @@ type text*: string time*: DateTime reply*: seq[string] - replyHandle*: string pinned*: bool hasThread*: bool available*: bool diff --git a/src/views/about.nim b/src/views/about.nim index 891a610..e7e8de9 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://gitdab.com/Cynosphere/nitter/commit/" & hash + link = "https://github.com/zedeus/nitter/commit/" & hash version = &"{date}-{hash}" var aboutHtml: string diff --git a/src/views/general.nim b/src/views/general.nim index f788d9b..c919d8c 100644 --- a/src/views/general.nim +++ b/src/views/general.nim @@ -38,7 +38,7 @@ proc renderNavbar(cfg: Config; req: Request; rss, canonical: string): VNode = proc renderHead*(prefs: Prefs; cfg: Config; req: Request; titleText=""; desc=""; video=""; images: seq[string] = @[]; banner=""; ogTitle=""; - rss=""; canonical=""; avatar=""; context=""; contextUrl=""; + rss=""; canonical=""; avatar=""; time: Option[DateTime] = none(DateTime)): VNode = var theme = prefs.theme.toTheme if "theme" in req.params: @@ -140,28 +140,16 @@ proc renderHead*(prefs: Prefs; cfg: Config; req: Request; titleText=""; desc=""; meta(property="og:video:url", content=video) meta(property="og:video:secure_url", content=video) meta(property="og:video:type", content="video/mp4") - - var - title = encodeUrl(finalizedDesc) - author = encodeUrl(finalizedTitleText) - url = req.path - + var title = encodeUrl(finalizedDesc) + var author = encodeUrl(finalizedTitleText) if len(finalizedDesc) > 67: title = author author = encodeUrl(finalizedDesc) - if context != "": - author = encodeUrl(context & "\n") & author - - if contextUrl != "": - url = contextUrl - - verbatim &"" - elif context != "" and contextUrl != "": - var - title = encodeUrl(finalizedTitleText) - author = encodeUrl(context) - verbatim &"" + verbatim &"" + #link(rel="alternate", + # href=&"{getUrlPrefix(cfg)}/oembed.json?type=video&title={encodeUrl(stripHtml(desc))}&user={encodeUrl(finalizedTitleText)}&url={encodeUrl(req.path)}", + # `type`="application/json+oembed") # this is last so images are also preloaded # if this is done earlier, Chrome only preloads one image for some reason @@ -170,15 +158,14 @@ proc renderHead*(prefs: Prefs; cfg: Config; req: Request; titleText=""; desc=""; proc renderMain*(body: VNode; req: Request; cfg: Config; prefs=defaultPrefs; titleText=""; desc=""; ogTitle=""; rss=""; video=""; - images: seq[string] = @[]; banner=""; avatar=""; context=""; - contextUrl = ""; time: Option[DateTime] = none(DateTime) - ): string = + images: seq[string] = @[]; banner=""; avatar=""; + time: Option[DateTime] = none(DateTime)): string = let canonical = getTwitterLink(req.path, req.params) let node = buildHtml(html(lang="en")): renderHead(prefs, cfg, req, titleText, desc, video, images, banner, ogTitle, - rss, canonical, avatar, context, contextUrl, time) + rss, canonical, avatar, time) body: renderNavbar(cfg, req, rss, canonical)