Skip to content

Instantly share code, notes, and snippets.

@cmj
Created December 11, 2025 16:07
Show Gist options
  • Select an option

  • Save cmj/a6d08fc50c10e50fd2e6e058c20eef0d to your computer and use it in GitHub Desktop.

Select an option

Save cmj/a6d08fc50c10e50fd2e6e058c20eef0d to your computer and use it in GitHub Desktop.
[PATCH] Add source to stats row
From e425ccc59fa7caa1e00346350f8da096a46599b1 Mon Sep 17 00:00:00 2001
From: cmj <129799+cmj@users.noreply.github.com>
Date: Thu, 11 Dec 2025 06:41:15 -0800
Subject: [PATCH] Add source to stats row
---
src/api.nim | 21 ++++++++++++---------
src/parser.nim | 6 +++++-
src/sass/tweet/_base.scss | 6 ++++++
src/types.nim | 1 +
src/views/tweet.nim | 3 ++-
5 files changed, 26 insertions(+), 11 deletions(-)
diff --git a/src/api.nim b/src/api.nim
index acd25f1..259b387 100644
--- a/src/api.nim
+++ b/src/api.nim
@@ -21,38 +21,41 @@ proc apiReq(endpoint, variables: string; fieldToggles = ""): ApiReq =
proc mediaUrl(id: string; cursor: string): ApiReq =
result = ApiReq(
cookie: apiUrl(graphUserMedia, userMediaVars % [id, cursor]),
- oauth: apiUrl(graphUserMediaV2, restIdVars % [id, cursor])
+ #oauth: apiUrl(graphUserMediaV2, restIdVars % [id, cursor])
)
+ result.oauth = result.cookie
proc userTweetsUrl(id: string; cursor: string): ApiReq =
result = ApiReq(
- # cookie: apiUrl(graphUserTweets, userTweetsVars % [id, cursor], userTweetsFieldToggles),
- oauth: apiUrl(graphUserTweetsV2, restIdVars % [id, cursor])
+ cookie: apiUrl(graphUserTweets, userTweetsVars % [id, cursor], userTweetsFieldToggles),
+ #oauth: apiUrl(graphUserTweetsV2, restIdVars % [id, cursor])
)
# might change this in the future pending testing
- result.cookie = result.oauth
+ result.oauth = result.cookie
proc userTweetsAndRepliesUrl(id: string; cursor: string): ApiReq =
let cookieVars = userTweetsAndRepliesVars % [id, cursor]
result = ApiReq(
cookie: apiUrl(graphUserTweetsAndReplies, cookieVars, userTweetsFieldToggles),
- oauth: apiUrl(graphUserTweetsAndRepliesV2, restIdVars % [id, cursor])
+ #oauth: apiUrl(graphUserTweetsAndRepliesV2, restIdVars % [id, cursor])
)
+ result.oauth = result.cookie
proc tweetDetailUrl(id: string; cursor: string): ApiReq =
let cookieVars = tweetDetailVars % [id, cursor]
result = ApiReq(
- # cookie: apiUrl(graphTweetDetail, cookieVars, tweetDetailFieldToggles),
- cookie: apiUrl(graphTweet, tweetVars % [id, cursor]),
- oauth: apiUrl(graphTweet, tweetVars % [id, cursor])
+ cookie: apiUrl(graphTweetDetail, cookieVars, tweetDetailFieldToggles),
+ #oauth: apiUrl(graphTweet, tweetVars % [id, cursor])
)
+ result.oauth = result.cookie
proc userUrl(username: string): ApiReq =
let cookieVars = """{"screen_name":"$1","withGrokTranslatedBio":false}""" % username
result = ApiReq(
cookie: apiUrl(graphUser, cookieVars, tweetDetailFieldToggles),
- oauth: apiUrl(graphUserV2, """{"screen_name": "$1"}""" % username)
+ #oauth: apiUrl(graphUserV2, """{"screen_name": "$1"}""" % username)
)
+ result.oauth = result.cookie
proc getGraphUser*(username: string): Future[User] {.async.} =
if username.len == 0: return
diff --git a/src/parser.nim b/src/parser.nim
index 9b4dc2f..549176f 100644
--- a/src/parser.nim
+++ b/src/parser.nim
@@ -297,7 +297,8 @@ proc parseTweet(js: JsonNode; jsCard: JsonNode = newJNull()): Tweet =
replies: js{"reply_count"}.getInt,
retweets: js{"retweet_count"}.getInt,
likes: js{"favorite_count"}.getInt,
- views: js{"views_count"}.getInt
+ views: js{"views_count"}.getInt,
+ source: js{"source"}.getStr
)
)
@@ -404,6 +405,9 @@ proc parseGraphTweet(js: JsonNode): Tweet =
with count, js{"views", "count"}:
result.stats.views = count.getStr("0").parseInt
+ with source, js{"source"}:
+ result.stats.source = source.getStr
+
with noteTweet, js{"note_tweet", "note_tweet_results", "result"}:
result.expandNoteTweetEntities(noteTweet)
diff --git a/src/sass/tweet/_base.scss b/src/sass/tweet/_base.scss
index 7f2d931..9b620f9 100644
--- a/src/sass/tweet/_base.scss
+++ b/src/sass/tweet/_base.scss
@@ -213,6 +213,12 @@
margin-right: 0.8em;
}
+.source {
+ margin-left: auto;
+ font-size: xx-small;
+ font-weight: normal;
+}
+
.show-thread {
display: block;
pointer-events: all;
diff --git a/src/types.nim b/src/types.nim
index 90487ab..e37f11c 100644
--- a/src/types.nim
+++ b/src/types.nim
@@ -192,6 +192,7 @@ type
retweets*: int
likes*: int
views*: int
+ source*: string
Tweet* = ref object
id*: int64
diff --git a/src/views/tweet.nim b/src/views/tweet.nim
index 58d03a9..3ff3fa5 100644
--- a/src/views/tweet.nim
+++ b/src/views/tweet.nim
@@ -1,5 +1,5 @@
# SPDX-License-Identifier: AGPL-3.0-only
-import strutils, sequtils, strformat, options, algorithm
+import strutils, sequtils, strformat, options, algorithm, re
import karax/[karaxdsl, vdom, vstyles]
from jester import Request
@@ -185,6 +185,7 @@ proc renderStats(stats: TweetStats): VNode =
span(class="tweet-stat"): icon "retweet", formatStat(stats.retweets)
span(class="tweet-stat"): icon "heart", formatStat(stats.likes)
span(class="tweet-stat"): icon "views", formatStat(stats.views)
+ span(class="tweet-stat source"): icon "", stripHtml(stats.source.replace(re"(Twitter for |Twitter )", ""))
proc renderReply(tweet: Tweet): VNode =
buildHtml(tdiv(class="replying-to")):
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment