aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiguel Ángel Moreno <mail@migalmoreno.com>2024-12-19 22:48:19 +0100
committerMiguel Ángel Moreno <mail@migalmoreno.com>2024-12-19 22:48:19 +0100
commit71d05e8b950266b6af84d0ff904ad2ef75215eec (patch)
treea0838d6cf4471da27088467fc43cd009a6ad0994
parentd787d6c6139d365f5d7f4fa7b37e5455ecc1dca1 (diff)
feat: add content country setting
-rw-r--r--src/backend/tubo/api.clj48
-rw-r--r--src/backend/tubo/handler.clj3
-rw-r--r--src/backend/tubo/router.clj6
-rw-r--r--src/frontend/tubo/events.cljs68
-rw-r--r--src/frontend/tubo/kiosks/events.cljs39
-rw-r--r--src/frontend/tubo/settings/views.cljs73
6 files changed, 157 insertions, 80 deletions
diff --git a/src/backend/tubo/api.clj b/src/backend/tubo/api.clj
index 802057f..6678567 100644
--- a/src/backend/tubo/api.clj
+++ b/src/backend/tubo/api.clj
@@ -3,10 +3,12 @@
[clojure.java.data :as j]
[ring.util.codec :refer [url-decode]])
(:import
+ java.util.Locale
org.schabi.newpipe.extractor.channel.ChannelInfo
org.schabi.newpipe.extractor.channel.tabs.ChannelTabInfo
org.schabi.newpipe.extractor.channel.tabs.ChannelTabs
org.schabi.newpipe.extractor.comments.CommentsInfo
+ org.schabi.newpipe.extractor.localization.ContentCountry
org.schabi.newpipe.extractor.kiosk.KioskInfo
org.schabi.newpipe.extractor.playlist.PlaylistInfo
org.schabi.newpipe.extractor.search.SearchInfo
@@ -270,9 +272,14 @@
:next-page (j/from-java (.getNextPage info))})))
(defn get-kiosk
- ([service-id]
+ ([{:keys [region]} service-id]
+ (println region)
(let [service (NewPipe/getService service-id)
- extractor (doto (.getDefaultKioskExtractor (.getKioskList service))
+ extractor (doto (.getDefaultKioskExtractor
+ (if region
+ (doto (.getKioskList service)
+ (.forceContentCountry (ContentCountry. region)))
+ (.getKioskList service)))
(.fetchPage))
info (KioskInfo/getInfo extractor)]
{:id (.getId info)
@@ -280,10 +287,16 @@
:service-id service-id
:next-page (j/from-java (.getNextPage info))
:related-streams (get-items (.getRelatedItems info))}))
- ([kiosk-id service-id]
+ ([{:keys [region]} kiosk-id service-id]
(let [service (NewPipe/getService service-id)
extractor
- (doto (.getExtractorById (.getKioskList service) kiosk-id nil)
+ (doto (.getExtractorById
+ (if region
+ (doto (.getKioskList service)
+ (.forceContentCountry (ContentCountry. region)))
+ (.getKioskList service))
+ kiosk-id
+ nil)
(.fetchPage))
info (KioskInfo/getInfo extractor)]
{:id (.getId info)
@@ -291,9 +304,15 @@
:service-id service-id
:next-page (j/from-java (.getNextPage info))
:related-streams (get-items (.getRelatedItems info))}))
- ([kiosk-id service-id page-url]
+ ([{:keys [region]} kiosk-id service-id page-url]
(let [service (NewPipe/getService service-id)
- extractor (.getExtractorById (.getKioskList service) kiosk-id nil)
+ extractor (.getExtractorById
+ (if region
+ (doto (.getKioskList service)
+ (.forceContentCountry (ContentCountry. region)))
+ (.getKioskList service))
+ kiosk-id
+ nil)
url (url-decode page-url)
kiosk-info (KioskInfo/getInfo extractor)
info (KioskInfo/getMoreItems service
@@ -311,9 +330,20 @@
(defn get-service
[service]
- {:id (.getServiceId service)
- :info (j/from-java (.getServiceInfo service))
- :base-url (.getBaseUrl service)})
+ {:id (.getServiceId service)
+ :info (j/from-java (.getServiceInfo service))
+ :base-url (.getBaseUrl service)
+ :supported-languages (map (fn [lang]
+ {:name (.getDisplayLanguage
+ (Locale. (.getLanguageCode lang)
+ (.getCountryCode lang)))
+ :code (.getLocalizationCode lang)})
+ (.getSupportedLocalizations service))
+ :supported-countries (map (fn [country]
+ {:name (.getDisplayCountry
+ (Locale. "" (.toString country)))
+ :code (.toString country)})
+ (.getSupportedCountries service))})
(defn get-services
[]
diff --git a/src/backend/tubo/handler.clj b/src/backend/tubo/handler.clj
index 8a438b8..eff2f85 100644
--- a/src/backend/tubo/handler.clj
+++ b/src/backend/tubo/handler.clj
@@ -45,8 +45,9 @@
(defn kiosk
[{{{:keys [kiosk-id service-id]} :path} :parameters
- {:strs [nextPage]} :query-params}]
+ {:strs [nextPage region]} :query-params}]
(response (apply api/get-kiosk
+ {:region region}
(if kiosk-id
(into
[kiosk-id]
diff --git a/src/backend/tubo/router.clj b/src/backend/tubo/router.clj
index 8a031b5..46be06a 100644
--- a/src/backend/tubo/router.clj
+++ b/src/backend/tubo/router.clj
@@ -28,7 +28,8 @@
{:summary
"returns default kiosk entries for a given service"
:coercion reitit.coercion.malli/coercion
- :parameters {:path {:service-id int?}}
+ :parameters {:path {:service-id int?}
+ :query {:region [:maybe string?]}}
:handler handler/kiosk}}
:api/all-kiosks {:get {:summary
"returns all kiosks supported by a given service"
@@ -39,7 +40,8 @@
{:summary
"returns kiosk entries for a given service and a kiosk ID"
:coercion reitit.coercion.malli/coercion
- :parameters {:path {:service-id int? :kiosk-id string?}}
+ :parameters {:path {:service-id int? :kiosk-id string?}
+ :query {:region [:maybe string?]}}
:handler handler/kiosk}}
:api/stream {:get {:summary "returns stream data for a given URL"
:handler handler/stream}}
diff --git a/src/frontend/tubo/events.cljs b/src/frontend/tubo/events.cljs
index 6365a9b..874af84 100644
--- a/src/frontend/tubo/events.cljs
+++ b/src/frontend/tubo/events.cljs
@@ -32,32 +32,48 @@
(fn [{:keys [store]} _]
(let [if-nil #(if (nil? %1) %2 %1)]
{:db
- {:player/paused true
- :player/muted (:player/muted store)
- :queue (if-nil (:queue store) [])
- :service-id (if-nil (:service-id store) 0)
- :player/loop (if-nil (:player/loop store) :playlist)
- :queue/position (if-nil (:queue/position store) 0)
- :player/volume (if-nil (:player/volume store) 100)
- :bg-player/show (:bg-player/show store)
- :bookmarks (if-nil (:bookmarks store)
- [{:id (nano-id) :name "Liked Streams"}])
- :settings {:theme (if-nil (:theme store) "auto")
- :show-comments (if-nil (:show-comments store)
- true)
- :show-related (if-nil (:show-related store)
- true)
- :show-description (if-nil (:show-description
- store)
- true)
- :items-layout "list"
- :default-service (if-nil
- (:default-service store)
- {:service-id 0
- :id "YouTube"
- :default-kiosk "Trending"
- :available-kiosks
- ["Trending"]})}}})))
+ {:player/paused true
+ :player/muted (:player/muted store)
+ :player/shuffled (:player/shuffled store)
+ :player/loop (if-nil (:player/loop store) :playlist)
+ :player/volume (if-nil (:player/volume store) 100)
+ :bg-player/show (:bg-player/show store)
+ :queue (if-nil (:queue store) [])
+ :queue/position (if-nil (:queue/position store) 0)
+ :queue/unshuffled (:queue/unshuffled store)
+ :service-id (if-nil (:service-id store) 0)
+ :bookmarks (if-nil (:bookmarks store)
+ [{:id (nano-id) :name "Liked Streams"}])
+ :settings {:theme (if-nil (-> store
+ :settings
+ :theme)
+ "auto")
+ :show-comments (if-nil (-> store
+ :settings
+ :show-comments)
+ true)
+ :show-related (if-nil (-> store
+ :settings
+ :show-related)
+ true)
+ :show-description (if-nil (-> store
+ :settings
+ :show-description)
+ true)
+ :items-layout "list"
+ :default-country (if-nil (-> store
+ :settings
+ :default-country)
+ {0 {:name "United States"
+ :code "US"}})
+ :default-service (if-nil (-> store
+ :settings
+ :default-service)
+ {:service-id 0
+ :id "YouTube"
+ :default-kiosk "Trending"
+ :available-kiosks
+ ["Trending"]})}}})))
(rf/reg-fx
:scroll-to-top
diff --git a/src/frontend/tubo/kiosks/events.cljs b/src/frontend/tubo/kiosks/events.cljs
index 75fc9a2..3197daf 100644
--- a/src/frontend/tubo/kiosks/events.cljs
+++ b/src/frontend/tubo/kiosks/events.cljs
@@ -21,10 +21,11 @@
(rf/reg-event-fx
:kiosks/fetch-default
- (fn [_ [_ service-id on-success on-error]]
+ (fn [_ [_ service-id on-success on-error params]]
(api/get-request (str "/services/" service-id "/default-kiosk")
on-success
- on-error)))
+ on-error
+ params)))
(rf/reg-event-fx
:kiosks/fetch-all
@@ -58,15 +59,21 @@
(rf/reg-event-fx
:kiosks/fetch-page
(fn [{:keys [db]} [_ service-id kiosk-id]]
- {:db (assoc db
- :show-page-loading true
- :kiosk nil)
- :fx [[:dispatch
- (if kiosk-id
- [:kiosks/fetch service-id kiosk-id
- [:kiosks/load-page]
- [:kiosks/bad-page-response service-id kiosk-id]]
- [:kiosks/fetch-default-page service-id])]]}))
+ (let [default-country (-> db
+ :settings
+ :default-country
+ (get (js/parseInt service-id))
+ :code)]
+ {:db (assoc db
+ :show-page-loading true
+ :kiosk nil)
+ :fx [[:dispatch
+ (if kiosk-id
+ [:kiosks/fetch service-id kiosk-id
+ [:kiosks/load-page]
+ [:kiosks/bad-page-response service-id kiosk-id]
+ (when default-country {:region default-country})]
+ [:kiosks/fetch-default-page service-id])]]})))
(rf/reg-event-fx
:kiosks/fetch-default-page
@@ -80,13 +87,19 @@
(-> db
:settings
:default-service
- :default-kiosk))]
+ :default-kiosk))
+ default-country (-> db
+ :settings
+ :default-country
+ (get (js/parseInt service-id))
+ :code)]
{:fx [[:dispatch
(if default-kiosk-id
[:kiosks/fetch-page service-id default-kiosk-id]
[:kiosks/fetch-default service-id
[:kiosks/load-page]
- [:kiosks/bad-page-response service-id nil]])]]})))
+ [:kiosks/bad-page-response service-id nil]
+ (when default-country {:region default-country})])]]})))
(rf/reg-event-fx
:kiosks/change-page
diff --git a/src/frontend/tubo/settings/views.cljs b/src/frontend/tubo/settings/views.cljs
index 3afed5e..536d91c 100644
--- a/src/frontend/tubo/settings/views.cljs
+++ b/src/frontend/tubo/settings/views.cljs
@@ -15,45 +15,60 @@
(or on-change
#(rf/dispatch [:settings/change keys (.. % -target -value)]))])
-(defn general-settings
- [{:keys [theme default-service items-layout]}]
- (let [services @(rf/subscribe [:services])]
+(defn appearance-settings
+ [{:keys [theme items-layout]}]
+ [:<>
+ [select-input "Theme" [:theme] theme #{:auto :light :dark}]
+ [select-input "List view mode" [:items-layout] items-layout #{:grid :list}]])
+
+(defn content-settings
+ [{:keys [default-service default-country show-description show-comments
+ show-related]}]
+ (let [services @(rf/subscribe [:services])
+ service-id @(rf/subscribe [:service-id])
+ countries (->> services
+ (filter #(= (:id %) service-id))
+ first
+ :supported-countries)]
[:<>
- [select-input "Theme" :theme theme #{:auto :light :dark}]
- [select-input "Default service" :default-service (:id default-service)
+ [select-input "Default content country" nil
+ (:name (get default-country service-id)) (map :name countries)
+ (fn [e]
+ (rf/dispatch [:settings/change [:default-country service-id]
+ (first (filter #(= (.. e -target -value) (:name %))
+ countries))]))]
+ [select-input "Default service" [:default-service] (:id default-service)
(map #(-> %
:info
:name)
services)
#(rf/dispatch [:settings/change-service (.. % -target -value)])]
- [select-input "Default kiosk" :default-service
- (:default-kiosk default-service) (:available-kiosks default-service)
- #(rf/dispatch [:settings/change-kiosk (.. % -target -value)])]
- [select-input "Items Layout" :items-layout items-layout #{:grid :list}]]))
-
-(defn stream-settings
- [{:keys [show-description show-comments show-related]}]
- [:<>
- [boolean-input "Show description" :show-description show-description]
- [boolean-input "Show comments" :show-comments show-comments]
- [boolean-input "Show related videos" :show-related show-related]])
+ [select-input "Default kiosk" [:default-service :default-kiosk]
+ (:default-kiosk default-service) (:available-kiosks default-service)]
+ [boolean-input "Show comments" [:show-comments] show-comments]
+ [boolean-input "Show description" [:show-description] show-description]
+ [boolean-input "Show 'Next' and 'Similar' videos" [:show-related]
+ show-related]]))
(defn settings
[]
- (let [!active-tab (r/atom :general)]
+ (let [!active-tab (r/atom :content)]
(fn []
(let [settings @(rf/subscribe [:settings])]
[layout/content-container
[layout/content-header "Settings"]
- [layout/tabs
- [{:id :general
- :label "General"}
- {:id :stream
- :label "Stream"}]
- :selected-id @!active-tab
- :on-change #(reset! !active-tab %)]
- [:form.flex.flex-wrap.py-4
- (case @!active-tab
- :general [general-settings settings]
- :stream [stream-settings settings]
- [general-settings settings])]]))))
+ [:div.mt-4
+ [layout/tabs
+ [{:id :appearance
+ :label "Appearance"
+ :left-icon [:i.fa-solid.fa-palette]}
+ {:id :content
+ :label "Content"
+ :left-icon [:i.fa-solid.fa-globe]}]
+ :selected-id @!active-tab
+ :on-change #(reset! !active-tab %)]
+ [:form.flex.flex-wrap.py-4.gap-y-4
+ (case @!active-tab
+ :appearance [appearance-settings settings]
+ :content [content-settings settings]
+ [appearance-settings settings])]]]))))