aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMiguel Ángel Moreno <mail@migalmoreno.com>2022-12-31 11:57:10 +0100
committerMiguel Ángel Moreno <mail@migalmoreno.com>2022-12-31 11:57:10 +0100
commit5fc4b8d6edb031cd4a65f788f15832eb659fd2bf (patch)
tree263a62b3ac8fb410797ca3eec0a5e2fb29148157 /src
parenta4da13d078f254621383f455e91c4ce9ff8c9c4e (diff)
feat: Add support for comment replies
Diffstat (limited to 'src')
-rw-r--r--src/backend/tau/api/comments.clj24
-rw-r--r--src/backend/tau/handler.clj4
-rw-r--r--src/frontend/tau/components/comments.cljs39
-rw-r--r--src/frontend/tau/events.cljs12
4 files changed, 57 insertions, 22 deletions
diff --git a/src/backend/tau/api/comments.clj b/src/backend/tau/api/comments.clj
index 477c72d..c0891ea 100644
--- a/src/backend/tau/api/comments.clj
+++ b/src/backend/tau/api/comments.clj
@@ -5,33 +5,41 @@
(:import
org.schabi.newpipe.extractor.NewPipe
org.schabi.newpipe.extractor.Page
+ org.schabi.newpipe.extractor.ListExtractor
org.schabi.newpipe.extractor.comments.CommentsInfoItem
org.schabi.newpipe.extractor.comments.CommentsInfo))
(defn get-comment-item
- [item]
+ [item extractor]
{:id (.getCommentId item)
:text (.getCommentText item)
:uploader-name (.getUploaderName item)
:uploader-avatar (.getUploaderAvatarUrl item)
:uploader-url (.getUploaderUrl item)
:uploader-verified? (.isUploaderVerified item)
- :upload-date (.getTextualUploadDate item)
+ :upload-date (.getTextualUploadDate item)
:like-count (when-not (= (.getLikeCount item) -1) (.getLikeCount item))
+ :reply-count (when-not (= (.getReplyCount item) -1) (.getReplyCount item))
:hearted-by-uploader? (.isHeartedByUploader item)
:pinned? (.isPinned item)
+ :stream-position (when-not (= (.getStreamPosition item) -1) (.getStreamPosition item))
:replies (when (.getReplies item)
- (j/from-java (.getReplies item)))})
+ (if extractor
+ (let [comments-page (.getPage extractor (.getReplies item))]
+ {:next-page (when (.hasNextPage comments-page) (j/from-java (.getNextPage comments-page)))
+ :items (map #(get-comment-item % extractor) (.getItems comments-page))})
+ (j/from-java (.getReplies item))))})
-(defn get-comment
+(defn get-comments
([url]
- (let [info (CommentsInfo/getInfo (url-decode url))]
- {:comments (map get-comment-item (.getRelatedItems info))
+ (let [info (CommentsInfo/getInfo (url-decode url))
+ extractor (.getCommentsExtractor info)]
+ {:comments (map #(get-comment-item % extractor) (.getRelatedItems info))
:next-page (j/from-java (.getNextPage info))
:disabled? (.isCommentsDisabled info)}))
([url page-url]
(let [service (NewPipe/getServiceByUrl (url-decode url))
- info (CommentsInfo/getMoreItems service url (Page. (url-decode page-url)))]
- {:comments (map get-comment-item (.getItems info))
+ info (CommentsInfo/getMoreItems service (url-decode url) (Page. (url-decode page-url)))]
+ {:comments (map #(get-comment-item % nil) (.getItems info))
:next-page (j/from-java (.getNextPage info))
:disabled? false})))
diff --git a/src/backend/tau/handler.clj b/src/backend/tau/handler.clj
index 49b7114..3ec4469 100644
--- a/src/backend/tau/handler.clj
+++ b/src/backend/tau/handler.clj
@@ -48,8 +48,8 @@
(defn comments
[{{:keys [url]} :path-params {:strs [nextPage]} :query-params}]
(response (if nextPage
- (comments/get-comment url nextPage)
- (comments/get-comment url))))
+ (comments/get-comments url nextPage)
+ (comments/get-comments url))))
(defn services
[_]
diff --git a/src/frontend/tau/components/comments.cljs b/src/frontend/tau/components/comments.cljs
index 9802647..6c64339 100644
--- a/src/frontend/tau/components/comments.cljs
+++ b/src/frontend/tau/components/comments.cljs
@@ -9,19 +9,21 @@
(defn comment-item
[{:keys [id text uploader-name uploader-avatar uploader-url
upload-date uploader-verified? like-count hearted-by-uploader?
- pinned? replies key]} author-name author-avatar]
- [:div.flex.my-4
+ pinned? replies reply-count key show-replies author-name author-avatar]}]
+ [:div.flex.my-4 {:key key}
(when uploader-avatar
[:div.flex.items-center.py-3.box-border.h-12
- [:div.w-12
- [:a {:href (rfe/href :tau.routes/channel nil {:url uploader-url}) :title name}
- [:img.rounded-full.object-cover.min-w-full.min-h-full {:src uploader-avatar}]]]])
+ (when uploader-url
+ [:div.w-12
+ [:a {:href (rfe/href :tau.routes/channel nil {:url uploader-url}) :title uploader-name}
+ [:img.rounded-full.object-cover.min-w-full.min-h-full {:src uploader-avatar}]]])])
[:div.ml-4
[:div.flex.items-center
(when pinned?
[:i.fa-solid.fa-thumbtack.mr-2.text-xs])
- [:a {:href (rfe/href :tau.routes/channel nil {:url uploader-url}) :title name}
- [:h1.text-gray-300.font-bold uploader-name]]
+ (when uploader-name
+ [:a {:href (rfe/href :tau.routes/channel nil {:url uploader-url}) :title uploader-name}
+ [:h1.text-gray-300.font-bold uploader-name]])
(when uploader-verified?
[:i.fa-solid.fa-circle-check.ml-2])]
[:div.my-2
@@ -31,7 +33,7 @@
[:p (if (-> upload-date js/Date.parse js/isNaN)
upload-date
(timeago/format upload-date))]]
- (when like-count
+ (when (and like-count (> like-count 0))
[:div.flex.items-center.my-2
[:i.fa-solid.fa-thumbs-up.text-xs]
[:p.mx-1 like-count]])
@@ -39,7 +41,17 @@
[:div.relative.w-4.h-4.mx-2
[:i.fa-solid.fa-heart.absolute.-bottom-1.-right-1.text-xs.text-red-500]
[:img.rounded-full.object-covermax-w-full.min-h-full
- {:src author-avatar :title (str author-name " hearted this comment")}]])]]])
+ {:src author-avatar :title (str author-name " hearted this comment")}]])]
+ [:div.flex.ml-8.items-center.cursor-pointer
+ {:on-click #(rf/dispatch [::events/toggle-comment-replies id])}
+ (when replies
+ (if show-replies
+ [:<>
+ [:p.font-bold "Hide replies"]
+ [:i.fa-solid.fa-turn-up.mx-2.text-xs]]
+ [:<>
+ [:p.font-bold (str reply-count (if (= reply-count 1) " reply" " replies"))]
+ [:i.fa-solid.fa-turn-down.mx-2.text-xs]]))]]])
(defn comments
[{:keys [comments next-page disabled?]} author-name author-avatar url]
@@ -47,8 +59,13 @@
service-color @(rf/subscribe [:service-color])]
[:div.flex.flex-col
[:div
- (for [[i comment] (map-indexed vector comments)]
- [comment-item (assoc comment :key i) author-name author-avatar])]
+ (for [[i {:keys [replies show-replies] :as comment}] (map-indexed vector comments)]
+ [:div.flex.flex-col {:key i}
+ [comment-item (assoc comment :key i :author-name author-name :author-avatar author-avatar)]
+ (when (and replies show-replies)
+ [:div {:style {:marginLeft "32px"}}
+ (for [[i reply] (map-indexed vector (:items replies))]
+ [comment-item (assoc reply :key i :author-name author-name :author-avatar author-avatar)])])])]
(when (:url next-page)
(if pagination-loading?
(loading/loading-icon service-color)
diff --git a/src/frontend/tau/events.cljs b/src/frontend/tau/events.cljs
index d6f9743..12404dc 100644
--- a/src/frontend/tau/events.cljs
+++ b/src/frontend/tau/events.cljs
@@ -210,10 +210,20 @@
(rf/reg-event-db
::toggle-comments
- (fn [db [_ res]]
+ (fn [db _]
(assoc-in db [:stream :show-comments] (not (-> db :stream :show-comments)))))
(rf/reg-event-db
+ ::toggle-comment-replies
+ (fn [db [_ comment-id]]
+ (update-in db [:stream :comments-page :comments]
+ (fn [comments]
+ (map #(if (= (:id %) comment-id)
+ (assoc % :show-replies (not (:show-replies %)))
+ %)
+ comments)))))
+
+(rf/reg-event-db
::load-paginated-comments
(fn [db [_ res]]
(-> db