From 6989f6b0310418d15296dde2dfe54b9d70d4b12d Mon Sep 17 00:00:00 2001 From: SamTV12345 <40429738+samtv12345@users.noreply.github.com> Date: Wed, 19 Apr 2023 23:07:11 +0200 Subject: [PATCH 1/6] Added crashing code. --- src/controllers/podcast_episode_controller.rs | 25 +++++++++++++++++- src/db.rs | 17 ++++++++++++ src/models/itunes_models.rs | 26 ++++++++++++++++--- ui/src/App.tsx | 4 ++- ui/src/components/SideBar.tsx | 1 + ui/src/language/json/de.json | 3 ++- ui/src/language/json/en.json | 3 ++- ui/src/language/json/fr.json | 3 ++- ui/src/pages/Timeline.tsx | 10 +++++++ ui/src/utils/LazyLoading.ts | 4 +++ ui/src/utils/Utilities.tsx | 4 --- 11 files changed, 88 insertions(+), 12 deletions(-) create mode 100644 ui/src/pages/Timeline.tsx diff --git a/src/controllers/podcast_episode_controller.rs b/src/controllers/podcast_episode_controller.rs index 65149c6a..378f9443 100644 --- a/src/controllers/podcast_episode_controller.rs +++ b/src/controllers/podcast_episode_controller.rs @@ -2,11 +2,13 @@ use crate::db::DB; use crate::service::mapping_service::MappingService; use crate::service::podcast_episode_service::PodcastEpisodeService; use actix_web::web::{Data, Query}; -use actix_web::{get, put}; +use actix_web::{get, HttpRequest, put}; use actix_web::{web, HttpResponse, Responder}; use serde_json::from_str; use std::sync::Mutex; use std::thread; +use crate::constants::constants::{STANDARD_USER, USERNAME}; +use crate::controllers::watch_time_controller::get_username; use crate::DbPool; use crate::mutex::LockResultExt; @@ -45,6 +47,27 @@ pub async fn find_all_podcast_episodes_of_podcast( HttpResponse::Ok().json(mapped_podcasts) } + +#[get("/podcasts/timeline")] +pub async fn get_timeline(conn: Data, req: HttpRequest, mapping_service: +Data>) -> + impl +Responder { + let mapping_service = mapping_service.lock().ignore_poison(); + let username = get_username(req); + if username.is_err(){ + return HttpResponse::BadRequest().json("Username not found"); + } + + let username_to_search = STANDARD_USER; + + /*let res = DB::get_timeline(username_to_search.to_string(),&mut conn.get().unwrap()) + .iter().map(|podcast_episode| mapping_service.map_podcastepisode_to_dto(&podcast_episode)).collect::>(); + + */ + HttpResponse::Ok().json("test") +} + /** * id is the episode id (uuid) */ diff --git a/src/db.rs b/src/db.rs index a1d3e15c..721afbed 100644 --- a/src/db.rs +++ b/src/db.rs @@ -18,6 +18,7 @@ use std::sync::MutexGuard; use std::time::SystemTime; use diesel::sql_types::Text; use crate::models::favorites::Favorite; +use crate::schema::podcast_episodes::dsl::podcast_episodes; use crate::utils::do_retry::do_retry; pub struct DB { @@ -741,4 +742,20 @@ impl DB { .load::(&mut self.conn) .expect("Error loading podcast episode by id") } + + + pub fn get_timeline(username_to_search: String, conn: &mut SqliteConnection) { + let podcast_timeline = sql_query("SELECT podcast_episodes FROM podcasts, podcast_episodes, \ + favorites \ + WHERE podcasts.id = podcast_episodes.podcast_id AND podcasts.id = favorites.podcast_id AND favorites.username=? AND favored=1 ORDER BY podcast_episodes.date_of_recording DESC"); + + let res = podcast_timeline.bind::(&username_to_search); + + + let res1 = res.load::(conn).expect("Error loading \ + podcast \ + episode by id"); + + + } } diff --git a/src/models/itunes_models.rs b/src/models/itunes_models.rs index 0c58c247..2696650f 100644 --- a/src/models/itunes_models.rs +++ b/src/models/itunes_models.rs @@ -1,7 +1,8 @@ use crate::schema::*; use chrono::NaiveDateTime; -use diesel::prelude::{Insertable, Queryable, Identifiable, Selectable}; +use diesel::prelude::{Insertable, Queryable, Identifiable, Selectable, QueryableByName}; use utoipa::ToSchema; +use diesel::sql_types::{Integer, Text, Nullable, Bool, Date}; #[derive(Debug, Serialize, Deserialize, Clone, ToSchema)] #[serde(rename_all = "camelCase", deny_unknown_fields)] @@ -49,7 +50,8 @@ pub struct ResponseModel { pub results: Vec, } -#[derive(Queryable, Identifiable, Selectable, Debug, PartialEq, Clone, ToSchema,Serialize, Deserialize)] +#[derive(Queryable, Identifiable,QueryableByName, Selectable, Debug, PartialEq, Clone, ToSchema, +Serialize, Deserialize)] pub struct Podcast { #[diesel(sql_type = Integer)] pub(crate) id: i32, @@ -73,8 +75,12 @@ pub struct Podcast { pub last_build_date: Option, #[diesel(sql_type = Nullable)] pub author: Option, + #[diesel(sql_type = Bool)] pub active: bool, + #[diesel(sql_type = Text)] pub original_image_url: String, + #[diesel(sql_type = Text)] + pub directory_name:String } @@ -97,19 +103,33 @@ pub struct PodcastDto { } -#[derive(Serialize, Deserialize, Queryable, Insertable, Clone, Debug, ToSchema)] +#[derive(Queryable, Identifiable,QueryableByName, Selectable, Debug, PartialEq, Clone, ToSchema, +Serialize, Deserialize)] pub struct PodcastEpisode { + #[diesel(sql_type = Integer)] pub(crate) id: i32, + #[diesel(sql_type = Integer)] pub(crate) podcast_id: i32, + #[diesel(sql_type = Text)] pub(crate) episode_id: String, + #[diesel(sql_type = Text)] pub(crate) name: String, + #[diesel(sql_type = Text)] pub(crate) url: String, + #[diesel(sql_type = Text)] pub(crate) date_of_recording: String, + #[diesel(sql_type = Text)] pub image_url: String, + #[diesel(sql_type = Integer)] pub total_time: i32, + #[diesel(sql_type = Text)] pub(crate) local_url: String, + #[diesel(sql_type = Text)] pub(crate) local_image_url: String, + #[diesel(sql_type = Text)] pub(crate) description: String, + #[diesel(sql_type = Text)] pub(crate) status: String, + #[diesel(sql_type = Nullable)] pub(crate) download_time: Option } diff --git a/ui/src/App.tsx b/ui/src/App.tsx index 7d7adfae..6647ebea 100644 --- a/ui/src/App.tsx +++ b/ui/src/App.tsx @@ -15,13 +15,14 @@ import { PodcastDetailViewLazyLoad, PodcastInfoViewLazyLoad, PodcastViewLazyLoad, - SettingsViewLazyLoad + SettingsViewLazyLoad, TimeLineViewLazyLoad } from "./utils/LazyLoading"; import {apiURL, configWSUrl, isJsonString} from "./utils/Utilities"; import {LoginComponent} from "./components/LoginComponent"; import {enqueueSnackbar} from "notistack"; import {useTranslation} from "react-i18next"; import {InviteComponent} from "./components/InviteComponent"; +import {Timeline} from "./pages/Timeline"; export const router = createBrowserRouter(createRoutesFromElements( @@ -33,6 +34,7 @@ export const router = createBrowserRouter(createRoutesFromElements( }/> }/> + }/> } index/> }/> diff --git a/ui/src/components/SideBar.tsx b/ui/src/components/SideBar.tsx index 4913d77e..94e2c11a 100644 --- a/ui/src/components/SideBar.tsx +++ b/ui/src/components/SideBar.tsx @@ -14,6 +14,7 @@ export const SideBar = ()=>{ }/> }/> }/> + }/> }/> }/> {(config?.oidcConfig|| config?.basicAuth)&& }/>} diff --git a/ui/src/language/json/de.json b/ui/src/language/json/de.json index c1a95572..8b59ff6d 100644 --- a/ui/src/language/json/de.json +++ b/ui/src/language/json/de.json @@ -96,5 +96,6 @@ "password-too-weak": "Passwort zu schwach. Ein sicheres Passwort hat eine Länge 8 und enthält mindestens eine Zahl, einen Großbuchstaben und einen Kleinbuchstaben.", "not-admin": "Sie sind kein Administrator", "not-admin-or-uploader": "Sie sind weder Administrator noch Uploader", - "stream-podcast-episode": "Podcast-Episode streamen" + "stream-podcast-episode": "Podcast-Episode streamen", + "timeline": "Zeitleiste" } diff --git a/ui/src/language/json/en.json b/ui/src/language/json/en.json index 5bd983f2..8a927db2 100644 --- a/ui/src/language/json/en.json +++ b/ui/src/language/json/en.json @@ -94,5 +94,6 @@ "password-too-weak": "Password too weak. A secure password contains at least 8 characters, a number, a lowercase and an uppercase letter.", "not-admin": "You are not an admin", "not-admin-or-uploader": "You are not an admin or an uploader", - "stream-podcast-episode": "Stream podcast episode" + "stream-podcast-episode": "Stream podcast episode", + "timeline": "Timeline" } diff --git a/ui/src/language/json/fr.json b/ui/src/language/json/fr.json index 56b63195..947f8e20 100644 --- a/ui/src/language/json/fr.json +++ b/ui/src/language/json/fr.json @@ -94,5 +94,6 @@ "password-too-weak": "Le mot de passe est trop faible. Il doit contenir au moins 8 caractères, dont au moins une lettre majuscule, une lettre minuscule et un chiffre.", "not-admin": "Vous n'êtes pas administrateur", "not-admin-or-uploader": "Vous n'êtes pas administrateur ou uploader", - "stream-podcast-episode": "Écouter l'épisode" + "stream-podcast-episode": "Écouter l'épisode", + "timeline": "Chronologie" } diff --git a/ui/src/pages/Timeline.tsx b/ui/src/pages/Timeline.tsx new file mode 100644 index 00000000..1ccf9652 --- /dev/null +++ b/ui/src/pages/Timeline.tsx @@ -0,0 +1,10 @@ +import {useTranslation} from "react-i18next"; + +export const Timeline = ()=>{ + const {t} = useTranslation() + + return
+

{t('timeline')}

+ +
+} diff --git a/ui/src/utils/LazyLoading.ts b/ui/src/utils/LazyLoading.ts index c3852d58..305539f9 100644 --- a/ui/src/utils/LazyLoading.ts +++ b/ui/src/utils/LazyLoading.ts @@ -27,3 +27,7 @@ export const AdministrationUserViewLazyLoad = lazy(()=>import('../pages/Administ export const InviteAdministrationUserViewLazyLoad = lazy(()=>import('../pages/InviteAdministrationUserPage').then(module=> { return{default:module["InviteAdministrationUserPage"]} })) + +export const TimeLineViewLazyLoad = lazy(()=>import('../pages/Timeline').then(module=> { + return{default:module["Timeline"]} +})) diff --git a/ui/src/utils/Utilities.tsx b/ui/src/utils/Utilities.tsx index a22abc81..c7678dc4 100644 --- a/ui/src/utils/Utilities.tsx +++ b/ui/src/utils/Utilities.tsx @@ -103,10 +103,6 @@ export const capitalizeFirstLetter = (string: string|undefined)=> { } } - export const preparePodcastEpisodeForOnline = (episode: PodcastEpisode)=>{ - episode.local_image_url.trim().length - } - export const prepareOnlinePodcastEpisode = (episode: PodcastEpisode, response: PodcastWatchedModel)=>{ const strippedUrl = episode.url.replace(/\?.*$/, ""); From 9d8506b83c9b388752b687216868904e037f3c7e Mon Sep 17 00:00:00 2001 From: SamTV12345 <40429738+samtv12345@users.noreply.github.com> Date: Thu, 20 Apr 2023 11:18:30 +0200 Subject: [PATCH 2/6] Fixed build. --- src/models/itunes_models.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/models/itunes_models.rs b/src/models/itunes_models.rs index 2696650f..dc94da36 100644 --- a/src/models/itunes_models.rs +++ b/src/models/itunes_models.rs @@ -2,7 +2,7 @@ use crate::schema::*; use chrono::NaiveDateTime; use diesel::prelude::{Insertable, Queryable, Identifiable, Selectable, QueryableByName}; use utoipa::ToSchema; -use diesel::sql_types::{Integer, Text, Nullable, Bool, Date}; +use diesel::sql_types::{Integer, Text, Nullable, Bool, Timestamp}; #[derive(Debug, Serialize, Deserialize, Clone, ToSchema)] #[serde(rename_all = "camelCase", deny_unknown_fields)] @@ -130,6 +130,6 @@ pub struct PodcastEpisode { pub(crate) description: String, #[diesel(sql_type = Text)] pub(crate) status: String, - #[diesel(sql_type = Nullable)] + #[diesel(sql_type = Nullable)] pub(crate) download_time: Option } From 043dabe01629ff9f34bd5b94a504b9b71791b371 Mon Sep 17 00:00:00 2001 From: SamTV12345 <40429738+samtv12345@users.noreply.github.com> Date: Thu, 20 Apr 2023 12:45:12 +0200 Subject: [PATCH 3/6] Adds local timeline --- src/controllers/podcast_episode_controller.rs | 23 +++++++--- src/db.rs | 20 ++++----- src/main.rs | 5 +-- src/models/itunes_models.rs | 2 +- ui/src/components/PodcastEpisodeTimeLine.tsx | 41 +++++++++++++++++ ui/src/models/TimeLineModel.ts | 6 +++ ui/src/pages/Homepage.tsx | 34 ++++++++++---- ui/src/pages/Timeline.tsx | 44 ++++++++++++++++++- ui/src/store/CommonSlice.ts | 12 +++-- 9 files changed, 156 insertions(+), 31 deletions(-) create mode 100644 ui/src/components/PodcastEpisodeTimeLine.tsx create mode 100644 ui/src/models/TimeLineModel.ts diff --git a/src/controllers/podcast_episode_controller.rs b/src/controllers/podcast_episode_controller.rs index 378f9443..83bbd99e 100644 --- a/src/controllers/podcast_episode_controller.rs +++ b/src/controllers/podcast_episode_controller.rs @@ -7,9 +7,10 @@ use actix_web::{web, HttpResponse, Responder}; use serde_json::from_str; use std::sync::Mutex; use std::thread; -use crate::constants::constants::{STANDARD_USER, USERNAME}; +use crate::constants::constants::{STANDARD_USER}; use crate::controllers::watch_time_controller::get_username; use crate::DbPool; +use crate::models::itunes_models::{Podcast, PodcastEpisode}; use crate::mutex::LockResultExt; #[derive(Debug, Serialize, Deserialize, Clone)] @@ -47,6 +48,11 @@ pub async fn find_all_podcast_episodes_of_podcast( HttpResponse::Ok().json(mapped_podcasts) } +#[derive(Serialize, Deserialize)] +pub struct TimeLinePodcastEpisode { + podcast_episode: PodcastEpisode, + podcast: Podcast, +} #[get("/podcasts/timeline")] pub async fn get_timeline(conn: Data, req: HttpRequest, mapping_service: @@ -61,11 +67,18 @@ Responder { let username_to_search = STANDARD_USER; - /*let res = DB::get_timeline(username_to_search.to_string(),&mut conn.get().unwrap()) - .iter().map(|podcast_episode| mapping_service.map_podcastepisode_to_dto(&podcast_episode)).collect::>(); + let res = DB::get_timeline(username_to_search.to_string(),&mut conn.get().unwrap()); + + let mapped_timeline = res.iter().map(|podcast_episode| { + let (podcast_episode, podcast) = podcast_episode; + let mapped_podcast_episode = mapping_service.map_podcastepisode_to_dto(podcast_episode); - */ - HttpResponse::Ok().json("test") + TimeLinePodcastEpisode{ + podcast_episode: mapped_podcast_episode, + podcast: podcast.clone() + } + }).collect::>(); + HttpResponse::Ok().json(mapped_timeline) } /** diff --git a/src/db.rs b/src/db.rs index 721afbed..337dda3e 100644 --- a/src/db.rs +++ b/src/db.rs @@ -18,7 +18,6 @@ use std::sync::MutexGuard; use std::time::SystemTime; use diesel::sql_types::Text; use crate::models::favorites::Favorite; -use crate::schema::podcast_episodes::dsl::podcast_episodes; use crate::utils::do_retry::do_retry; pub struct DB { @@ -56,9 +55,11 @@ impl DB { -> Result, String> { use crate::schema::podcasts::dsl::podcasts; use crate::schema::favorites::dsl::favorites as f_db; + use crate::schema::favorites::dsl::podcast_id as f_id; + use crate::schema::podcasts::id as p_id; use crate::schema::favorites::dsl::username; let result = podcasts - .left_join(f_db.on(username.eq(u))) + .left_join(f_db.on(username.eq(u).and(f_id.eq(p_id)))) .load::<(Podcast, Option)>(conn) .expect("Error loading podcasts"); @@ -744,18 +745,17 @@ impl DB { } - pub fn get_timeline(username_to_search: String, conn: &mut SqliteConnection) { - let podcast_timeline = sql_query("SELECT podcast_episodes FROM podcasts, podcast_episodes, \ + pub fn get_timeline(username_to_search: String, conn: &mut SqliteConnection) -> Vec< + (PodcastEpisode, Podcast)> { + let podcast_timeline = sql_query("SELECT * FROM podcast_episodes,podcasts, \ favorites \ - WHERE podcasts.id = podcast_episodes.podcast_id AND podcasts.id = favorites.podcast_id AND favorites.username=? AND favored=1 ORDER BY podcast_episodes.date_of_recording DESC"); + WHERE podcasts.id = podcast_episodes.podcast_id AND podcasts.id = favorites.podcast_id \ + AND favorites.username=? AND favored=1 ORDER BY podcast_episodes.date_of_recording DESC \ + LIMIT 20"); let res = podcast_timeline.bind::(&username_to_search); - let res1 = res.load::(conn).expect("Error loading \ - podcast \ - episode by id"); - - + res.load::<(PodcastEpisode, Podcast)>(conn).expect("Error loading podcast episode by id") } } diff --git a/src/main.rs b/src/main.rs index f40983d6..80fdbc1e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -51,9 +51,7 @@ use crate::controllers::podcast_controller::{ add_podcast_from_podindex, download_podcast, favorite_podcast, get_favored_podcasts, import_podcasts_from_opml, query_for_podcast, update_active_podcast, }; -use crate::controllers::podcast_episode_controller::{ - download_podcast_episodes_of_podcast, find_all_podcast_episodes_of_podcast, -}; +use crate::controllers::podcast_episode_controller::{download_podcast_episodes_of_podcast, find_all_podcast_episodes_of_podcast, get_timeline}; use crate::controllers::settings_controller::{get_opml, get_settings, run_cleanup, update_settings}; use crate::controllers::sys_info_controller::{get_public_config, get_sys_info, login}; use crate::controllers::watch_time_controller::{get_last_watched, get_watchtime, log_watchtime}; @@ -405,6 +403,7 @@ fn get_private_api(db: Pool>) -> Scope = ({podcastEpisode}) => { + const dispatch = useAppDispatch() + + return
+
+ +
+ { + axios.get(apiURL+"/podcast/episode/"+podcastEpisode.podcast_episode.episode_id) + .then((response: AxiosResponse)=>{ + if (podcastEpisode.podcast_episode.local_image_url.trim().length>1){ + store.dispatch(setCurrentPodcastEpisode(preparePodcastEpisode(podcastEpisode.podcast_episode, response.data))) + } + else{ + store.dispatch(setCurrentPodcastEpisode(prepareOnlinePodcastEpisode(podcastEpisode.podcast_episode, response.data))) + } + dispatch(setCurrentPodcast(podcastEpisode.podcast)) + dispatch(setPlaying(true)) + }) + }}/> +
+
+
+} diff --git a/ui/src/models/TimeLineModel.ts b/ui/src/models/TimeLineModel.ts new file mode 100644 index 00000000..4cac8bb2 --- /dev/null +++ b/ui/src/models/TimeLineModel.ts @@ -0,0 +1,6 @@ +import {Podcast, PodcastEpisode} from "../store/CommonSlice"; + +export type TimeLineModel = { + podcast: Podcast, + podcast_episode: PodcastEpisode +} diff --git a/ui/src/pages/Homepage.tsx b/ui/src/pages/Homepage.tsx index cbf032ad..8b98c557 100644 --- a/ui/src/pages/Homepage.tsx +++ b/ui/src/pages/Homepage.tsx @@ -8,7 +8,32 @@ import {store} from "../store/store"; import {setCurrentPodcast, setCurrentPodcastEpisode, setPlaying} from "../store/AudioPlayerSlice"; import {useAppDispatch} from "../store/hooks"; import {useTranslation} from "react-i18next"; +import {PodcastEpisode} from "../store/CommonSlice"; +const isPodcastWatchedEpisodeModel = (podcast: PodcastWatchedEpisodeModel|PodcastEpisode): podcast is PodcastWatchedEpisodeModel => { + return (podcast as PodcastWatchedEpisodeModel).watchedTime !== undefined; +} + +export const selectPodcastImage = (podcast: PodcastWatchedEpisodeModel|PodcastEpisode) => { + if (isPodcastWatchedEpisodeModel(podcast)){ + if(podcast.podcastEpisode.local_image_url.length>1){ + return preparePath(podcast.podcastEpisode.local_image_url) + } + else{ + return podcast.podcastEpisode.image_url + } + } + else{ + console.log(podcast.image_url) + if(podcast.local_image_url.trim().length>1){ + return preparePath(podcast.local_image_url) + } + else{ + return podcast.image_url + } + } + +} export const Homepage = () => { const [podcastWatched, setPodcastWatched] = useState([]) const dispatch = useAppDispatch() @@ -24,14 +49,7 @@ export const Homepage = () => { }, []) - const selectPodcastImage = (podcast: PodcastWatchedEpisodeModel) => { - if(podcast.podcastEpisode.local_image_url.length>1){ - return preparePath(podcast.podcastEpisode.local_image_url) - } - else{ - return podcast.podcastEpisode.image_url - } - } + return

{t('last-listened')}

diff --git a/ui/src/pages/Timeline.tsx b/ui/src/pages/Timeline.tsx index 1ccf9652..d83ecc12 100644 --- a/ui/src/pages/Timeline.tsx +++ b/ui/src/pages/Timeline.tsx @@ -1,10 +1,52 @@ import {useTranslation} from "react-i18next"; +import {useAppDispatch, useAppSelector} from "../store/hooks"; +import {useEffect, useMemo} from "react"; +import axios, {AxiosResponse} from "axios"; +import {apiURL, formatTime} from "../utils/Utilities"; +import {PodcastEpisode, setTimeLineEpisodes} from "../store/CommonSlice"; +import {PodcastEpisodeTimeLine} from "../components/PodcastEpisodeTimeLine"; +import {TimeLineModel} from "../models/TimeLineModel"; + +const convertToTimeLineEpisodes = (podcastEpisodes: TimeLineModel[]) => { + return podcastEpisodes.reduce((groups, game) => { + const date = game.podcast_episode.date_of_recording.split('T')[0]; + // @ts-ignore + if (!groups[date]) { + // @ts-ignore + groups[date] = []; + } + // @ts-ignore + groups[date].push(game); + return groups; + }, {}); +} export const Timeline = ()=>{ const {t} = useTranslation() + const dispatch = useAppDispatch() + const timeLineEpisodes = useAppSelector(state=>state.common.timeLineEpisodes) + const mappedEpisodes = useMemo(()=>convertToTimeLineEpisodes(timeLineEpisodes),[timeLineEpisodes]) + + useEffect(()=>{ + axios.get(apiURL+"/podcasts/timeline") + .then((c:AxiosResponse)=>{ + dispatch(setTimeLineEpisodes(c.data)) + }) + }, + []) + + console.log(convertToTimeLineEpisodes(timeLineEpisodes)) return
-

{t('timeline')}

+

{t('timeline')}

+ { + Object.keys(mappedEpisodes).map((e)=> { + // @ts-ignore + let episodesOnDate = mappedEpisodes[e] as TimeLineModel[] + return

{formatTime(e)}

{episodesOnDate.map((v)=>)}
+ } + ) + }
} diff --git a/ui/src/store/CommonSlice.ts b/ui/src/store/CommonSlice.ts index af8d4001..c810f520 100644 --- a/ui/src/store/CommonSlice.ts +++ b/ui/src/store/CommonSlice.ts @@ -6,6 +6,7 @@ import {LoginData} from "../components/LoginComponent"; import {User} from "../models/User"; import {ConfirmModalProps} from "../components/ConfirmModal"; import {Invite} from "../pages/InviteAdministrationUserPage"; +import {TimeLineModel} from "../models/TimeLineModel"; export type Podcast = { directory: string, @@ -55,7 +56,8 @@ interface CommonProps { selectedUser: User|undefined, users: User[], addInviteModalOpen: boolean, - invites: Invite[] + invites: Invite[], + timeLineEpisodes: TimeLineModel[] } // Define the initial state using that type @@ -75,7 +77,8 @@ const initialState: CommonProps = { selectedUser: undefined, users: [], addInviteModalOpen: false, - invites: [] + invites: [], + timeLineEpisodes:[] } export const commonSlice = createSlice({ @@ -155,10 +158,13 @@ export const commonSlice = createSlice({ }, setInvites: (state, action:PayloadAction) => { state.invites = action.payload + }, + setTimeLineEpisodes: (state, action:PayloadAction) => { + state.timeLineEpisodes = action.payload } }}) -export const {setSideBarCollapsed,setInvites,setAddInviteModalOpen, setUsers, setSelectedUser, setConfirmModalData,setLoginData, addPodcast, setCurrentDetailedPodcastId, setConfigModel, setPodcasts,setSelectedEpisodes, setSearchedPodcasts,updateLikePodcast, setInfoModalDownloaded, +export const {setSideBarCollapsed, setTimeLineEpisodes,setInvites,setAddInviteModalOpen, setUsers, setSelectedUser, setConfirmModalData,setLoginData, addPodcast, setCurrentDetailedPodcastId, setConfigModel, setPodcasts,setSelectedEpisodes, setSearchedPodcasts,updateLikePodcast, setInfoModalDownloaded, setNotifications, removeNotification, setInfoModalPodcast, setInfoModalPodcastOpen, setDetailedAudioPlayerOpen} = commonSlice.actions export default commonSlice.reducer From d2df966c758ab1cfe2c9446ecb66cfa405b4a13a Mon Sep 17 00:00:00 2001 From: SamTV12345 <40429738+samtv12345@users.noreply.github.com> Date: Thu, 20 Apr 2023 14:30:54 +0200 Subject: [PATCH 4/6] Added name to timeline. --- ui/src/components/PodcastEpisodeTimeLine.tsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ui/src/components/PodcastEpisodeTimeLine.tsx b/ui/src/components/PodcastEpisodeTimeLine.tsx index 38ec251c..e7ff4765 100644 --- a/ui/src/components/PodcastEpisodeTimeLine.tsx +++ b/ui/src/components/PodcastEpisodeTimeLine.tsx @@ -37,5 +37,8 @@ export const PodcastEpisodeTimeLine:FC = ({podcastE }}/>
+
+
{podcastEpisode.podcast_episode.name}
+
} From 8d6814a1e62096d3db04e5c36f354beac305a056 Mon Sep 17 00:00:00 2001 From: SamTV12345 <40429738+samtv12345@users.noreply.github.com> Date: Thu, 20 Apr 2023 14:56:24 +0200 Subject: [PATCH 5/6] Fix replace directories. --- src/service/file_service.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/service/file_service.rs b/src/service/file_service.rs index ab232ccf..7d3082bd 100644 --- a/src/service/file_service.rs +++ b/src/service/file_service.rs @@ -106,5 +106,6 @@ impl FileService { pub fn prepare_podcast_title_to_directory(title: &str) ->String { let re = Regex::new(r"[^a-zA-Z0-9_./]").unwrap(); - re.replace_all(title, "").to_string() + let res = re.replace_all(title, "").to_string(); + res.replace("..","") } \ No newline at end of file From 710399c8f70514931b3aa722c0a3cf9032231d2f Mon Sep 17 00:00:00 2001 From: SamTV12345 <40429738+samtv12345@users.noreply.github.com> Date: Thu, 20 Apr 2023 15:03:14 +0200 Subject: [PATCH 6/6] Fixed protected timeline. --- src/controllers/podcast_episode_controller.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/controllers/podcast_episode_controller.rs b/src/controllers/podcast_episode_controller.rs index 83bbd99e..6cf0360c 100644 --- a/src/controllers/podcast_episode_controller.rs +++ b/src/controllers/podcast_episode_controller.rs @@ -7,7 +7,6 @@ use actix_web::{web, HttpResponse, Responder}; use serde_json::from_str; use std::sync::Mutex; use std::thread; -use crate::constants::constants::{STANDARD_USER}; use crate::controllers::watch_time_controller::get_username; use crate::DbPool; use crate::models::itunes_models::{Podcast, PodcastEpisode}; @@ -65,9 +64,8 @@ Responder { return HttpResponse::BadRequest().json("Username not found"); } - let username_to_search = STANDARD_USER; - let res = DB::get_timeline(username_to_search.to_string(),&mut conn.get().unwrap()); + let res = DB::get_timeline(username.unwrap(),&mut conn.get().unwrap()); let mapped_timeline = res.iter().map(|podcast_episode| { let (podcast_episode, podcast) = podcast_episode;