diff options
Diffstat (limited to 'src/frontend/tau/components')
-rw-r--r-- | src/frontend/tau/components/comments.cljs | 59 | ||||
-rw-r--r-- | src/frontend/tau/components/items.cljs | 128 | ||||
-rw-r--r-- | src/frontend/tau/components/loading.cljs | 14 | ||||
-rw-r--r-- | src/frontend/tau/components/navigation.cljs | 15 |
4 files changed, 142 insertions, 74 deletions
diff --git a/src/frontend/tau/components/comments.cljs b/src/frontend/tau/components/comments.cljs new file mode 100644 index 0000000..8f9300b --- /dev/null +++ b/src/frontend/tau/components/comments.cljs @@ -0,0 +1,59 @@ +(ns tau.components.comments + (:require + [re-frame.core :as rf] + [reitit.frontend.easy :as rfe] + [tau.components.loading :as loading] + [tau.events :as events] + ["timeago.js" :as timeago])) + +(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 + (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}]]]]) + [:div.ml-2 + [:div.flex.items-center + (when pinned? + [:i.fa-solid.fa-thumbtack.mr-2]) + [:a {:href (rfe/href :tau.routes/channel nil {:url uploader-url}) :title name} + [:h1.text-gray-300.font-bold uploader-name]] + (when uploader-verified? + [:i.fa-solid.fa-circle-check.ml-2])] + [:div.my-2 + [:p text]] + [:div..flex.items-center.my-2 + [:div.mr-4 + [:p (if (-> upload-date js/Date.parse js/isNaN) + upload-date + (timeago/format upload-date))]] + (when like-count + [:div.flex.items-center.my-2 + [:i.fa-solid.fa-thumbs-up] + [:p.mx-1 like-count]]) + (when hearted-by-uploader? + [: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")}]])]]]) + +(defn comments + [{:keys [comments next-page disabled?]} author-name author-avatar url] + (let [pagination-loading? @(rf/subscribe [:show-pagination-loading]) + 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])] + (when (:url next-page) + (if pagination-loading? + (loading/comments-pagination-loading-icon service-color) + [:div.flex.items-center.justify-center + {:style {:cursor "pointer"} + :on-click #(rf/dispatch [::events/comments-pagination url (:url next-page)])} + [:i.fa-solid.fa-plus] + [:p.px-2 "Show more comments"]]))])) diff --git a/src/frontend/tau/components/items.cljs b/src/frontend/tau/components/items.cljs index 5d26749..0a8bad6 100644 --- a/src/frontend/tau/components/items.cljs +++ b/src/frontend/tau/components/items.cljs @@ -1,74 +1,80 @@ (ns tau.components.items (:require - [reitit.frontend.easy :as rfe])) + [reitit.frontend.easy :as rfe] + [tau.util :as util] + ["timeago.js" :as timeago])) (defn stream-item - [id {:keys [url name thumbnail-url upload-author upload-url - upload-avatar upload-date short-description - duration view-count uploaded verified?]}] - [:div.w-56.h-66.my-2 {:key id} + [{:keys [url name thumbnail-url upload-author upload-url + upload-avatar upload-date short-description + duration view-count uploaded verified? key]}] + [:div.w-56.h-66.my-2 {:key key} [:div.px-5.py-2.m-2.flex.flex-col.max-w-full.min-h-full.max-h-full - [:a.overflow-hidden {:href (rfe/href :tau.routes/stream nil {:url url}) :title name} - [:div.flex.py-3.box-border.h-28 - [:div.relative.min-w-full - [:img.rounded.object-cover.max-h-full.min-w-full {:src thumbnail-url}] - [:div.rounded.p-2.absolute {:style {:bottom 5 :right 5 :background "rgba(0,0,0,.7)"}} - [:p {:style {:fontSize "14px"}} - (let [duration (js/Date. (* duration 1000)) - slice (if (> (.getHours duration) 1) - #(.slice % 11 19) - #(.slice % 14 19))] - (-> duration (.toISOString) slice))]]]] - [:div.my-2 - [:h1.line-clamp-2.my-1 name]] - [:a {:href (rfe/href :tau.routes/channel nil {:url upload-url}) :title upload-author} + [:div.flex.py-2.box-border.h-28 + [:div.relative.min-w-full + [:a.absolute.min-w-full.min-h-full.z-50 {:href (rfe/href :tau.routes/stream nil {:url url}) :title name}] + [:img.rounded.object-cover.max-h-full.min-w-full {:src thumbnail-url}] + [:div.rounded.p-2.absolute {:style {:bottom 5 :right 5 :background "rgba(0,0,0,.7)" :zIndex "0"}} + [:p {:style {:fontSize "14px"}} + (if (= duration 0) + "LIVE" + (util/format-duration duration))]]]] + [:div.my-2 + [:a {:href (rfe/href :tau.routes/stream nil {:url url}) :title name} + [:h1.line-clamp-2.my-1 name]]] + (when-not (empty? upload-author) [:div.flex.items-center.my-2 - [:h1.line-clamp-1.text-gray-300.font-bold.pr-2 upload-author] + [:a {:href (rfe/href :tau.routes/channel nil {:url upload-url}) :title upload-author} + [:h1.line-clamp-1.text-gray-300.font-bold.pr-2 upload-author]] (when verified? - [:i.fa-solid.fa-circle-check])]] - [:div.flex.my-1.justify-between - [:p (if (-> upload-date js/Date.parse js/isNaN) - upload-date - (-> upload-date - js/Date.parse - js/Date. - .toDateString))] - [:div.flex.items-center.h-full.pl-2 - [:i.fa-solid.fa-eye.text-xs] - [:p.pl-1.5 (.toLocaleString view-count)]]]]]]) + [:i.fa-solid.fa-circle-check])]) + [:div.flex.my-1.justify-between + [:p (if (-> upload-date js/Date.parse js/isNaN) + upload-date + (timeago/format upload-date))] + (when view-count + [:div.flex.items-center.h-full.pl-2 + [:i.fa-solid.fa-eye.text-xs] + [:p.pl-1.5 (util/format-quantity view-count)]])]]]) (defn channel-item - [id {:keys [url name thumbnail-url description subscriber-count stream-count verified?]}] - [:div.w-56.h-64.my-2 {:key id} + [{:keys [url name thumbnail-url description subscriber-count + stream-count verified? key]}] + [:div.w-56.h-64.my-2 {:key key} [:div.px-5.py-2.m-2.flex.flex-col.max-w-full.min-h-full.max-h-full - [:a.overflow-hidden {:href (rfe/href :tau.routes/channel nil {:url url}) :title name} - [:div.flex.min-w-full.py-3.box-border.h-28 - [:div.min-w-full - [:img.rounded.object-cover.max-h-full.min-w-full {:src thumbnail-url}]]] - [:div.overflow-hidden - [:div.flex.items-center.my-2 - [:h1.line-clamp-1.text-gray-300.font-bold.pr-2 name] - (when verified? - [:i.fa-solid.fa-circle-check])] - [:div.flex.items-center - [:i.fa-solid.fa-users.text-xs] - [:p.mx-2 subscriber-count]] - [:div.flex.items-center - [:i.fa-solid.fa-video.text-xs] - [:p.mx-2 stream-count]]]]]]) + [:div.flex.min-w-full.py-3.box-border.h-28 + [:div.relative.min-w-full + [:a.absolute.min-w-full.min-h-full {:href (rfe/href :tau.routes/channel nil {:url url}) :title name}] + [:img.rounded.object-cover.max-h-full.min-w-full {:src thumbnail-url}]]] + [:div.overflow-hidden + [:div.flex.items-center.py-2.box-border + [:a {:href (rfe/href :tau.routes/channel nil {:url url}) :title name} + [:h1.line-clamp-1.text-gray-300.font-bold.pr-2 name]] + (when verified? + [:i.fa-solid.fa-circle-check])] + (when subscriber-count + [:div.flex.items-center + [:i.fa-solid.fa-users.text-xs] + [:p.mx-2 subscriber-count]]) + (when stream-count + [:div.flex.items-center + [:i.fa-solid.fa-video.text-xs] + [:p.mx-2 stream-count]])]]]) (defn playlist-item - [id {:keys [url name thumbnail-url upload-author stream-count]}] - [:div.w-56.h-64.my-2 {:key id} + [{:keys [url name thumbnail-url upload-author stream-count key]}] + [:div.w-56.h-64.my-2 {:key key} [:div.px-5.py-2.m-2.flex.flex-col.max-w-full.min-h-full.max-h-full - [:a.overflow-hidden {:href (rfe/href :tau.routes/playlist nil {:url url}) :title name} - [:div.flex.min-w-full.py-3.box-border.h-28 - [:div.min-w-full - [:img.rounded.object-cover.max-h-full.min-w-full {:src thumbnail-url}]]] - [:div.overflow-hidden - [:h1.line-clamp-2 name] - [:h1.text-gray-300.font-bold upload-author] - [:p (condp >= stream-count - 0 "No streams" - 1 (str stream-count " stream") - (str stream-count " streams"))]]]]]) + [:div.flex.min-w-full.py-3.box-border.h-28 + [:div.relative.min-w-full + [:a.absolute.min-w-full.min-h-full.z-50 {:href (rfe/href :tau.routes/playlist nil {:url url}) :title name}] + [:img.rounded.object-cover.max-h-full.min-w-full {:src thumbnail-url}]]] + [:div.overflow-hidden + [:div + [:a {:href (rfe/href :tau.routes/playlist nil {:url url}) :title name} + [:h1.line-clamp-2 name]]] + [:div.my-2 + [:h1.text-gray-300.font-bold upload-author]] + [:div.flex.items-center + [:i.fa-solid.fa-video.text-xs] + [:p.mx-2 stream-count]]]]]) diff --git a/src/frontend/tau/components/loading.cljs b/src/frontend/tau/components/loading.cljs index 66954a1..9b1fee8 100644 --- a/src/frontend/tau/components/loading.cljs +++ b/src/frontend/tau/components/loading.cljs @@ -1,16 +1,20 @@ -(ns tau.components.loading - (:require - [re-frame.core :as rf])) +(ns tau.components.loading) (defn page-loading-icon [service-color] [:div.w-full.flex.justify-center.items-center.flex-auto - [:i.fas.fa-circle-notch.fa-spin.text-8xl + [:i.fas.fa-circle-notch.fa-spin.text-5xl {:style {:color service-color}}]]) -(defn pagination-loading-icon +(defn items-pagination-loading-icon [service-color loading?] [:div.w-full.flex.items-center.justify-center.py-4 {:class (when-not loading? "invisible")} [:i.fas.fa-circle-notch.fa-spin.text-2xl {:style {:color service-color}}]]) + +(defn comments-pagination-loading-icon + [service-color] + [:div.w-full.flex.justify-center.items-center.flex-auto + [:i.fas.fa-circle-notch.fa-spin + {:style {:color service-color}}]]) diff --git a/src/frontend/tau/components/navigation.cljs b/src/frontend/tau/components/navigation.cljs index a0d25e2..c8f0b5a 100644 --- a/src/frontend/tau/components/navigation.cljs +++ b/src/frontend/tau/components/navigation.cljs @@ -3,11 +3,10 @@ [re-frame.core :as rf] [tau.events :as events])) -(defn back-button [] - (let [service-color @(rf/subscribe [:service-color])] - [:div.flex {:class "w-4/5"} - [:button.p-2 - {:on-click #(rf/dispatch [::events/history-back])} - [:i.fa-solid.fa-chevron-left - {:style {:color service-color}}] - [:span " Back"]]])) +(defn back-button [service-color] + [:div.flex {:class "w-4/5"} + [:button.p-2 + {:on-click #(rf/dispatch [::events/history-back])} + [:i.fa-solid.fa-chevron-left + {:style {:color service-color}}] + [:span " Back"]]]) |