diff --git a/src/consts.nim b/src/consts.nim index a16e95b..8132e7e 100644 --- a/src/consts.nim +++ b/src/consts.nim @@ -90,7 +90,7 @@ const "super_follow_tweet_api_enabled": false, "super_follow_user_api_enabled": false, "tweet_awards_web_tipping_enabled": false, - "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": false, + "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": true, "tweetypie_unmention_optimization_enabled": false, "unified_cards_ad_metadata_container_dynamic_card_content_query_enabled": false, "verified_phone_label_enabled": false, diff --git a/src/parser.nim b/src/parser.nim index 8ef9e45..2843236 100644 --- a/src/parser.nim +++ b/src/parser.nim @@ -477,7 +477,17 @@ proc parseGraphTweet(js: JsonNode; isLegacy=false): Tweet = of "TweetPreviewDisplay": return Tweet(text: "You're unable to view this Tweet because it's only available to the Subscribers of the account owner.") of "TweetWithVisibilityResults": - return parseGraphTweet(js{"tweet"}, isLegacy) + result = parseGraphTweet(js{"tweet"}, isLegacy) + if js.hasKey("limitedActionResults"): + for actionRes in js{"limitedActionResults", "limited_actions"}: + let action = LimitedActions( + title: actionRes{"prompt" , "headline", "text"}.getStr, + text: actionRes{"prompt", "subtext", "text"}.getStr + ) + result.limitedActions = some(action) + break + + return result else: discard diff --git a/src/sass/tweet/_base.scss b/src/sass/tweet/_base.scss index e5e8667..580d199 100644 --- a/src/sass/tweet/_base.scss +++ b/src/sass/tweet/_base.scss @@ -8,6 +8,7 @@ @import "poll"; @import "quote"; @import "community_note"; +@import "limited_actions"; .tweet-body { flex: 1; diff --git a/src/sass/tweet/limited_actions.scss b/src/sass/tweet/limited_actions.scss new file mode 100644 index 0000000..3e9a643 --- /dev/null +++ b/src/sass/tweet/limited_actions.scss @@ -0,0 +1,32 @@ +@import "_variables"; + +.limited-actions { + margin-top: 10px; + border: solid 1px var(--dark_grey); + border-radius: 10px; + background-color: var(--bg_overlays); + overflow: hidden; + pointer-events: all; + position: relative; + width: 100%; + + &:hover { + border-color: var(--grey); + } + + .limited-actions-title { + font-weight: bold; + padding: 6px 8px; + padding-bottom: 2px; + margin-top: 1px; + font-size: 16px; + } + + .limited-actions-text { + overflow: hidden; + white-space: pre-wrap; + word-wrap: break-word; + padding: 8px; + padding-top: 2px; + } +} diff --git a/src/types.nim b/src/types.nim index b3c69e2..38df172 100644 --- a/src/types.nim +++ b/src/types.nim @@ -218,6 +218,10 @@ type title*: string text*: string + LimitedActions* = ref object + title*: string + text*: string + Tweet* = ref object id*: string threadId*: string @@ -245,6 +249,7 @@ type video*: Option[Video] photos*: seq[Image] birdwatch*: Option[BirdwatchNote] + limitedActions*: Option[LimitedActions] Tweets* = seq[Tweet] diff --git a/src/views/tweet.nim b/src/views/tweet.nim index 1ad0866..2467dfb 100644 --- a/src/views/tweet.nim +++ b/src/views/tweet.nim @@ -284,6 +284,11 @@ proc renderCommunityNote(note: BirdwatchNote; prefs: Prefs): VNode = tdiv(class="community-note-text", dir="auto"): verbatim replaceUrls(note.text, prefs) +proc renderLimitedActions(action: LimitedActions): VNode = + buildHtml(tdiv(class="limited-actions")): + tdiv(class="limited-actions-title"): text action.title + tdiv(class="limited-actions-text"): text action.text + proc renderLocation*(tweet: Tweet): string = let (place, url) = tweet.getLocation() if place.len == 0: return @@ -378,6 +383,9 @@ proc renderTweet*(tweet: Tweet; prefs: Prefs; path: string; class=""; index=0; a(class="show-thread", href=("/i/status/" & $tweet.threadId)): text "Show this thread" + if mainTweet and tweet.limitedActions.isSome: + renderLimitedActions(tweet.limitedActions.get()) + proc renderTweetEmbed*(tweet: Tweet; path: string; prefs: Prefs; cfg: Config; req: Request): string = let node = buildHtml(html(lang="en")): renderHead(prefs, cfg, req)