diff options
author | Miguel Ángel Moreno <mail@migalmoreno.com> | 2024-12-19 22:48:19 +0100 |
---|---|---|
committer | Miguel Ángel Moreno <mail@migalmoreno.com> | 2024-12-19 22:48:19 +0100 |
commit | 71d05e8b950266b6af84d0ff904ad2ef75215eec (patch) | |
tree | a0838d6cf4471da27088467fc43cd009a6ad0994 | |
parent | d787d6c6139d365f5d7f4fa7b37e5455ecc1dca1 (diff) |
feat: add content country setting
-rw-r--r-- | src/backend/tubo/api.clj | 48 | ||||
-rw-r--r-- | src/backend/tubo/handler.clj | 3 | ||||
-rw-r--r-- | src/backend/tubo/router.clj | 6 | ||||
-rw-r--r-- | src/frontend/tubo/events.cljs | 68 | ||||
-rw-r--r-- | src/frontend/tubo/kiosks/events.cljs | 39 | ||||
-rw-r--r-- | src/frontend/tubo/settings/views.cljs | 73 |
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])]]])))) |