aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/frontend/tubo/components/layout.cljs34
-rw-r--r--src/frontend/tubo/views/channel.cljs58
-rw-r--r--src/frontend/tubo/views/stream.cljs21
3 files changed, 73 insertions, 40 deletions
diff --git a/src/frontend/tubo/components/layout.cljs b/src/frontend/tubo/components/layout.cljs
index 0595ab5..0bcfac0 100644
--- a/src/frontend/tubo/components/layout.cljs
+++ b/src/frontend/tubo/components/layout.cljs
@@ -1,5 +1,6 @@
(ns tubo.components.layout
(:require
+ [reagent.core :as r]
[re-frame.core :as rf]))
(defn logo []
@@ -87,3 +88,36 @@
right-button]
(when open?
(map-indexed #(with-meta %2 {:key %1}) content))])
+
+(defn show-more-container
+ [open? text on-open]
+ (let [!text-container (atom nil)
+ !resize-observer (atom nil)
+ text-clamped? (r/atom nil)]
+ (r/create-class
+ {:display-name "ShowMoreContainer"
+ :component-did-mount
+ (fn [_]
+ (when @!text-container
+ (.observe
+ (reset! !resize-observer
+ (js/ResizeObserver.
+ #(let [target (.-target (first %))]
+ (reset! text-clamped?
+ (> (.-scrollHeight target)
+ (.-clientHeight target))))))
+ @!text-container)))
+ :component-will-unmount
+ #(when (and @!resize-observer @!text-container)
+ (.unobserve @!resize-observer @!text-container))
+ :reagent-render
+ (fn [open? text on-open]
+ [:div.py-3.flex.flex-wrap.min-w-full
+ [:div {:dangerouslySetInnerHTML {:__html text}
+ :class (when-not open? "line-clamp-2")
+ :ref #(reset! !text-container %)}]
+ (when (or @text-clamped? open?)
+ [:div.flex.justify-center.min-w-full.py-4
+ [secondary-button
+ (if (not open?) "Show More" "Show Less")
+ on-open]])])})))
diff --git a/src/frontend/tubo/views/channel.cljs b/src/frontend/tubo/views/channel.cljs
index 00dc12f..1278828 100644
--- a/src/frontend/tubo/views/channel.cljs
+++ b/src/frontend/tubo/views/channel.cljs
@@ -1,35 +1,39 @@
(ns tubo.views.channel
(:require
+ [reagent.core :as r]
[re-frame.core :as rf]
[tubo.components.items :as items]
[tubo.components.layout :as layout]
[tubo.events :as events]))
(defn channel
- [{{:keys [url]} :query-params}]
- (let [{:keys [banner avatar name description subscriber-count
- related-streams next-page]} @(rf/subscribe [:channel])
- next-page-url (:url next-page)
- service-color @(rf/subscribe [:service-color])
- scrolled-to-bottom? @(rf/subscribe [:scrolled-to-bottom])]
- (when scrolled-to-bottom?
- (rf/dispatch [::events/channel-pagination url next-page-url]))
- [layout/content-container
- (when banner
- [:div.flex.justify-center
- [:img.min-w-full {:src banner}]])
- [:div.flex.items-center.justify-between
- [:div.flex.items-center.my-4.mx-2
- [layout/uploader-avatar avatar name]
- [:div.m-4
- [:h1.text-xl name]
- (when subscriber-count
- [:div.flex.my-2.items-center
- [:i.fa-solid.fa-users.text-xs]
- [:span.mx-2 (.toLocaleString subscriber-count)]])]]
- [layout/primary-button "Enqueue"
- #(rf/dispatch [::events/enqueue-related-streams related-streams service-color])
- "fa-solid fa-headphones"]]
- [:div.my-2
- [:p description]]
- [items/related-streams related-streams next-page-url]]))
+ [query-params]
+ (let [!show-description? (r/atom false)]
+ (fn [{{:keys [url]} :query-params}]
+ (let [{:keys [banner avatar name description subscriber-count
+ related-streams next-page
+ donation-links] :as channel} @(rf/subscribe [:channel])
+ next-page-url (:url next-page)
+ service-color @(rf/subscribe [:service-color])
+ scrolled-to-bottom? @(rf/subscribe [:scrolled-to-bottom])]
+ (when scrolled-to-bottom?
+ (rf/dispatch [::events/channel-pagination url next-page-url]))
+ [layout/content-container
+ (when banner
+ [:div.flex.justify-center.h-24
+ [:img.min-w-full.min-h-full.object-cover {:src banner}]])
+ [:div.flex.items-center.justify-between
+ [:div.flex.items-center.my-4.mx-2
+ [layout/uploader-avatar avatar name]
+ [:div.m-4
+ [:h1.text-xl name]
+ (when subscriber-count
+ [:div.flex.my-2.items-center
+ [:i.fa-solid.fa-users.text-xs]
+ [:span.mx-2 (.toLocaleString subscriber-count)]])]]
+ [layout/primary-button "Enqueue"
+ #(rf/dispatch [::events/enqueue-related-streams related-streams service-color])
+ "fa-solid fa-headphones"]]
+ [layout/show-more-container @!show-description? description
+ #(reset! !show-description? (not @!show-description?))]
+ [items/related-streams related-streams next-page-url]]))))
diff --git a/src/frontend/tubo/views/stream.cljs b/src/frontend/tubo/views/stream.cljs
index 232d134..b609511 100644
--- a/src/frontend/tubo/views/stream.cljs
+++ b/src/frontend/tubo/views/stream.cljs
@@ -99,22 +99,17 @@
[:i.fa-solid.fa-calendar]
[:span.ml-2 (util/format-date-string upload-date)]])]]
(when (and show-description? (not (empty? description)))
- [:div.py-3.flex.flex-wrap.min-w-full
- [:div {:dangerouslySetInnerHTML {:__html description}
- :class (when (not show-description) "line-clamp-2")}]
- [:div.flex.justify-center.font-bold.min-w-full.py-4.cursor-pointer
- [layout/secondary-button
- (if (not show-description) "Show More" "Show Less")
- #(rf/dispatch [::events/toggle-stream-layout :show-description])]]])
+ [layout/show-more-container show-description description
+ #(rf/dispatch [::events/toggle-stream-layout :show-description])])
(when (and comments-page (not (empty? (:comments comments-page))) show-comments?)
[layout/accordeon
- {:label "Comments"
- :on-open #(if show-comments
- (rf/dispatch [::events/toggle-stream-layout :show-comments])
- (if comments-page
+ {:label "Comments"
+ :on-open #(if show-comments
(rf/dispatch [::events/toggle-stream-layout :show-comments])
- (rf/dispatch [::events/get-comments url])))
- :open? show-comments
+ (if comments-page
+ (rf/dispatch [::events/toggle-stream-layout :show-comments])
+ (rf/dispatch [::events/get-comments url])))
+ :open? show-comments
:left-icon "fa-solid fa-comments"}
(if show-comments-loading
[layout/loading-icon service-color "text-2xl"]