feat(pref): add ability to hide NSFW content

This commit is contained in:
2025-11-19 12:28:26 -03:00
parent 644cda63a0
commit 5a79ec025a
8 changed files with 19 additions and 2 deletions

View File

@@ -40,3 +40,4 @@ replaceSoundCloud = "sc.kuuro.net"
proxyVideos = true proxyVideos = true
hlsPlayback = false hlsPlayback = false
infiniteScroll = false infiniteScroll = false
hideNsfw = true

View File

@@ -23,6 +23,7 @@ proc parseUser(js: JsonNode; id=""): User =
media: js{"media_count"}.getInt, media: js{"media_count"}.getInt,
verifiedType: parseEnum[VerifiedType](js{"verified_type"}.getStr("None")), verifiedType: parseEnum[VerifiedType](js{"verified_type"}.getStr("None")),
protected: js{"protected"}.getBool, protected: js{"protected"}.getBool,
sensitive: "sensitive" in js{"profile_interstitial_type"}.getStr("") or js{"possibly_sensitive"}.getBool,
joinDate: js{"created_at"}.getTime joinDate: js{"created_at"}.getTime
) )
@@ -225,6 +226,7 @@ proc parseTweet(js: JsonNode; jsCard: JsonNode = newJNull()): Tweet =
text: js{"full_text"}.getStr, text: js{"full_text"}.getStr,
time: js{"created_at"}.getTime, time: js{"created_at"}.getTime,
hasThread: js{"self_thread"}.notNull, hasThread: js{"self_thread"}.notNull,
sensitive: js{"possibly_sensitive"}.getBool,
available: true, available: true,
user: User(id: js{"user_id_str"}.getStr), user: User(id: js{"user_id_str"}.getStr),
stats: TweetStats( stats: TweetStats(

View File

@@ -82,6 +82,9 @@ genPrefs:
squareAvatars(checkbox, false): squareAvatars(checkbox, false):
"Square profile pictures" "Square profile pictures"
hideNsfw(checkbox, true):
"Hide NSFW content"
Media: Media:
mp4Playback(checkbox, true): mp4Playback(checkbox, true):
"Enable mp4 video playback (only for gifs)" "Enable mp4 video playback (only for gifs)"

View File

@@ -103,6 +103,7 @@ type
media*: int media*: int
verifiedType*: VerifiedType verifiedType*: VerifiedType
protected*: bool protected*: bool
sensitive*: bool
suspended*: bool suspended*: bool
joinDate*: DateTime joinDate*: DateTime
@@ -214,6 +215,7 @@ type
time*: DateTime time*: DateTime
reply*: seq[string] reply*: seq[string]
pinned*: bool pinned*: bool
sensitive*: bool
hasThread*: bool hasThread*: bool
available*: bool available*: bool
tombstone*: string tombstone*: string

View File

@@ -120,6 +120,10 @@ proc renderHead*(prefs: Prefs; cfg: Config; req: Request; titleText=""; desc="";
link(rel="preload", type="font/woff2", `as`="font", link(rel="preload", type="font/woff2", `as`="font",
href="/fonts/fontello.woff2?61663884", crossorigin="anonymous") href="/fonts/fontello.woff2?61663884", crossorigin="anonymous")
if prefs.hideNsfw:
style:
verbatim ".nsfw { display: none !important; }"
proc renderMain*(body: VNode; req: Request; cfg: Config; prefs=defaultPrefs; proc renderMain*(body: VNode; req: Request; cfg: Config; prefs=defaultPrefs;
titleText=""; desc=""; ogTitle=""; rss=""; video=""; titleText=""; desc=""; ogTitle=""; rss=""; video="";
images: seq[string] = @[]; banner=""): string = images: seq[string] = @[]; banner=""): string =

View File

@@ -13,7 +13,8 @@ proc renderStat(num: int; class: string; text=""): VNode =
text insertSep($num, ',') text insertSep($num, ',')
proc renderUserCard*(user: User; prefs: Prefs): VNode = proc renderUserCard*(user: User; prefs: Prefs): VNode =
buildHtml(tdiv(class="profile-card")): let class = if user.sensitive: "profile-card nsfw" else: "profile-card"
buildHtml(tdiv(class=class)):
tdiv(class="profile-card-info"): tdiv(class="profile-card-info"):
let let
url = getPicUrl(user.getUserPic()) url = getPicUrl(user.getUserPic())

View File

@@ -56,7 +56,8 @@ proc renderThread(thread: Tweets; prefs: Prefs; path: string): VNode =
index=i, last=(i == thread.high), showThread=show) index=i, last=(i == thread.high), showThread=show)
proc renderUser(user: User; prefs: Prefs): VNode = proc renderUser(user: User; prefs: Prefs): VNode =
buildHtml(tdiv(class="timeline-item")): let class = if user.sensitive: "timeline-item nsfw" else: "timeline-item"
buildHtml(tdiv(class=class)):
a(class="tweet-link", href=("/" & user.username)) a(class="tweet-link", href=("/" & user.username))
tdiv(class="tweet-body profile-result"): tdiv(class="tweet-body profile-result"):
tdiv(class="tweet-header"): tdiv(class="tweet-header"):

View File

@@ -277,6 +277,9 @@ proc renderTweet*(tweet: Tweet; prefs: Prefs; path: string; class=""; index=0;
if index == -1 or last: if index == -1 or last:
divClass = "thread-last " & class divClass = "thread-last " & class
if tweet.sensitive:
divClass.add " nsfw"
if not tweet.available: if not tweet.available:
return buildHtml(tdiv(class=divClass & "unavailable timeline-item")): return buildHtml(tdiv(class=divClass & "unavailable timeline-item")):
tdiv(class="unavailable-box"): tdiv(class="unavailable-box"):