diff options
author | Miguel Ángel Moreno <mail@migalmoreno.com> | 2022-12-31 11:57:10 +0100 |
---|---|---|
committer | Miguel Ángel Moreno <mail@migalmoreno.com> | 2022-12-31 11:57:10 +0100 |
commit | 5fc4b8d6edb031cd4a65f788f15832eb659fd2bf (patch) | |
tree | 263a62b3ac8fb410797ca3eec0a5e2fb29148157 /src | |
parent | a4da13d078f254621383f455e91c4ce9ff8c9c4e (diff) |
feat: Add support for comment replies
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/tau/api/comments.clj | 24 | ||||
-rw-r--r-- | src/backend/tau/handler.clj | 4 | ||||
-rw-r--r-- | src/frontend/tau/components/comments.cljs | 39 | ||||
-rw-r--r-- | src/frontend/tau/events.cljs | 12 |
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 |