From bc01b74cb8dae177b801f95081df0b43f6042669 Mon Sep 17 00:00:00 2001 From: Martin Mouritzen Date: Sun, 20 Dec 2020 18:17:52 +0100 Subject: [PATCH] changes yup --- app/components/Episode/EpisodePane.jsx | 17 ++++- app/components/Lists/LatestEpisodes.jsx | 57 +++++++++++++++ .../Lists/LatestVisitedPodcasts.jsx | 2 +- app/components/Lists/PodcastMatrix.jsx | 3 +- app/components/Pages/ForPodcasters.jsx | 22 +++--- app/components/Player.jsx | 19 +++++ app/components/Player.scss | 2 + app/components/Player/PlayerUI.jsx | 34 +++++---- app/components/Player/ShareModal.jsx | 72 +++++++++++++++++++ app/components/Player/ShareModal.scss | 39 ++++++++++ app/components/PodCastClient.jsx | 17 +++-- app/components/PodCastClient.scss | 2 +- app/components/Podcast/ShareButtons.css | 12 ++-- app/components/Podcast/ShareButtons.jsx | 44 +++++++++--- app/components/SideBar.jsx | 10 +-- .../UI/PodcastMatrix/PodcastMatrixUI.jsx | 31 +++++++- app/components/Welcome.jsx | 6 ++ app/library/TimeUtil.js | 14 ++++ app/redux/actions/podcastActions.js | 5 +- app/redux/actions/uiActions.js | 16 ++++- app/redux/constants/ui-types.js | 2 + app/redux/reducers/podcastReducer.js | 25 ++++++- app/redux/reducers/uiReducer.js | 7 ++ app/web/assets/manifest.webmanifest | 2 +- package.json | 5 +- yarn.lock | 5 ++ 26 files changed, 407 insertions(+), 63 deletions(-) create mode 100644 app/components/Lists/LatestEpisodes.jsx create mode 100644 app/components/Player/ShareModal.jsx create mode 100644 app/components/Player/ShareModal.scss diff --git a/app/components/Episode/EpisodePane.jsx b/app/components/Episode/EpisodePane.jsx index fb235199..86f63ef6 100644 --- a/app/components/Episode/EpisodePane.jsx +++ b/app/components/Episode/EpisodePane.jsx @@ -6,7 +6,7 @@ import styles from './EpisodePane.scss'; // import Wave from 'podfriend-approot/images/design/blue-wave-1.svg'; -import { Link, useParams, useHistory } from "react-router-dom"; +import { Link, useParams, useHistory, useLocation } from "react-router-dom"; import ChatPane from 'podfriend-approot/components/Chat/ChatPane.jsx'; @@ -28,10 +28,18 @@ import PodcastSubtitles from './Subtitles/PodcastSubtitles.jsx'; import DOMPurify from 'dompurify'; +function useQuery() { + return new URLSearchParams(useLocation().search); +} + const EpisodePane = () => { const dispatch = useDispatch(); let { podcastName, episodeId } = useParams(); + // http://localhost:8080/podcast/someone-knows-something/499651292?t=60 + let query = useQuery(); + var timeStamp = query.get('t'); + const [episode,setEpisode] = useState(false); const [description,setDescription] = useState(false); const [chapters,setChapters] = useState(false); @@ -58,7 +66,7 @@ const EpisodePane = () => { } } if (foundEpisode) { - dispatch(playEpisode(selectedPodcast,foundEpisode)); + dispatch(playEpisode(selectedPodcast,foundEpisode,timeStamp ? timeStamp : false)); dispatch(showFullPlayer(true)); } }; @@ -205,6 +213,11 @@ const EpisodePane = () => { Play this episode } + { isActiveEpisode && +
+ Resume this episode +
+ } } diff --git a/app/components/Lists/LatestEpisodes.jsx b/app/components/Lists/LatestEpisodes.jsx new file mode 100644 index 00000000..6c280f01 --- /dev/null +++ b/app/components/Lists/LatestEpisodes.jsx @@ -0,0 +1,57 @@ +import React, { useState, useEffect } from 'react'; + +import { useSelector } from 'react-redux'; + +import PodcastMatrix from './PodcastMatrix.jsx'; + +const LatestVisitedPodcasts = () => { + const subscribedPodcasts = useSelector((state) => state.podcast.subscribedPodcasts); + const [latestEpisodes,setLatestEpisodes] = useState(false); + const [error,setError] = useState(false); + + const retrieveLatestEpisodes = async () => { + // console.log(subscribedPodcasts); + var feedPaths = []; + for(var i=0;i { + retrieveLatestEpisodes(); + },[]); + + if (error) { + return null; + } + return ( +
+
+
Your
+
Latest episodes
+
+ { latestEpisodes !== false && + + } +
+ ); +} + +export default React.memo(LatestVisitedPodcasts); \ No newline at end of file diff --git a/app/components/Lists/LatestVisitedPodcasts.jsx b/app/components/Lists/LatestVisitedPodcasts.jsx index c1cf8d86..e8772763 100644 --- a/app/components/Lists/LatestVisitedPodcasts.jsx +++ b/app/components/Lists/LatestVisitedPodcasts.jsx @@ -12,7 +12,7 @@ const LatestVisitedPodcasts = () => {
Your
-
latest podcasts
+
Latest podcasts
diff --git a/app/components/Lists/PodcastMatrix.jsx b/app/components/Lists/PodcastMatrix.jsx index 90781247..eabab7ee 100644 --- a/app/components/Lists/PodcastMatrix.jsx +++ b/app/components/Lists/PodcastMatrix.jsx @@ -5,11 +5,12 @@ import PodcastMatrixUI from 'podfriend-ui/PodcastMatrix/PodcastMatrixUI.jsx'; /** * */ -const PodcastMatrix = React.memo(({type,podcasts}) => { +const PodcastMatrix = React.memo(({type,podcasts,episodes}) => { return ( ); }) diff --git a/app/components/Pages/ForPodcasters.jsx b/app/components/Pages/ForPodcasters.jsx index 8651d472..f6f888f4 100644 --- a/app/components/Pages/ForPodcasters.jsx +++ b/app/components/Pages/ForPodcasters.jsx @@ -10,17 +10,17 @@ const ForPodcasters = () => {
- - -

Widgets

-

Show your potential listeners what they can expect from your podcast

-

Grow your listenerbase by giving them an easy way to preview your podcast

- - https://business.trustpilot.com/features/product-reviews -
- - - + + +

Website widgets

+

Show your potential listeners what they can expect from your podcast

+

Grow your listenerbase by giving them an easy way to preview your podcast

+ + https://business.trustpilot.com/features/product-reviews +
+ + +
diff --git a/app/components/Player.jsx b/app/components/Player.jsx index 641106ac..b8db0880 100644 --- a/app/components/Player.jsx +++ b/app/components/Player.jsx @@ -56,6 +56,7 @@ class Player extends Component { this.onProgressSliderChange = this.onProgressSliderChange.bind(this); this.onLoadedMetadata = this.onLoadedMetadata.bind(this); + this.onLoadedData = this.onLoadedData.bind(this); this.onTimeUpdate = this.onTimeUpdate.bind(this); this.onEnded = this.onEnded.bind(this); this.onNextEpisode = this.onNextEpisode.bind(this); @@ -220,6 +221,9 @@ class Player extends Component { * */ onCanPlay(event) { + // alert('set time: ' + this.props.activeEpisode.currentTime); + // this.setCurrentTime(this.props.activeEpisode.currentTime); + this.props.audioCanPlay(); } /** @@ -246,6 +250,14 @@ class Player extends Component { onLoadedMetadata(event) { let newDuration = this.props.audioController.getDuration(); console.log('OnloadedMetaData. duration: ' + newDuration + ', episodeid: ' + this.props.activeEpisode.id); + + // alert(this.props.audioController.audioElement.current.currentTime); + + // alert('set time: ' + this.props.activeEpisode.currentTime); + this.setCurrentTime(this.props.activeEpisode.currentTime); + + // alert(this.props.audioController.audioElement.current.currentTime); + this.props.updateEpisodeDuration(newDuration); this.setState({ duration: newDuration @@ -256,6 +268,12 @@ class Player extends Component { /** * */ + onLoadedData(event) { + // this.setCurrentTime(this.props.activeEpisode.currentTime); + } + /** + * + */ onTimeUpdate() { var currentTime = this.props.audioController.getCurrentTime(); @@ -460,6 +478,7 @@ class Player extends Component { onCanPlay={this.onCanPlay} onBuffering={this.onBuffering} onLoadedMetadata={this.onLoadedMetadata} + onLoadedData={this.onLoadedData} isBuffering={this.props.isBuffering} diff --git a/app/components/Player.scss b/app/components/Player.scss index 9bcb317d..7030dc15 100644 --- a/app/components/Player.scss +++ b/app/components/Player.scss @@ -478,6 +478,7 @@ .controls { width: 100%; margin-bottom: 20px; + flex: 0 1 auto; } .progressText { margin-left: 10px; @@ -494,6 +495,7 @@ width: 100%; background-color: #FFFFFF; padding-bottom: 60px; + flex: 2; } .coverContainer { position: relative; diff --git a/app/components/Player/PlayerUI.jsx b/app/components/Player/PlayerUI.jsx index 3743f245..28eb4d45 100644 --- a/app/components/Player/PlayerUI.jsx +++ b/app/components/Player/PlayerUI.jsx @@ -4,7 +4,7 @@ import { useSelector, useDispatch } from 'react-redux'; import { showFullPlayer } from "podfriend-approot/redux/actions/uiActions"; -import { Link, useHistory } from 'react-router-dom'; +import { Link, useHistory, useLocation } from 'react-router-dom'; import { Range } from 'react-range'; @@ -42,7 +42,7 @@ import EpisodeChapterList from 'podfriend-approot/components/Episode/Chapters/Ep import EpisodeChapters from 'podfriend-approot/components/Episode/Chapters/EpisodeChapters.jsx'; import PodcastSubtitles from 'podfriend-approot/components/Episode/Subtitles/PodcastSubtitles.jsx'; -import { showSpeedSettingWindow } from 'podfriend-approot/redux/actions/uiActions'; +import { showSpeedSettingWindow, showShareWindow } from 'podfriend-approot/redux/actions/uiActions'; import { Tabs, Tab } from 'podfriend-approot/components/wwt/Tabs/Tabs.jsx'; @@ -51,7 +51,8 @@ import DraggablePane from 'podfriend-approot/components/UI/common/DraggablePane. /** * */ -const PlayerUI = ({ audioController, activePodcast, activeEpisode, title, progress, duration, playing, hasEpisode, pause, play, canPlay, isBuffering, onCanPlay, onBuffering, onLoadedMetadata, onPlay, onPause, onSeek, onTimeUpdate, onEnded, onPrevEpisode, onBackward, onNextEpisode, onForward, onProgressSliderChange, onAudioElementReady }) => { + +const PlayerUI = ({ audioController, activePodcast, activeEpisode, title, progress, duration, playing, hasEpisode, pause, play, canPlay, isBuffering, onCanPlay, onBuffering, onLoadedMetadata, onLoadedData, onPlay, onPause, onSeek, onTimeUpdate, onEnded, onPrevEpisode, onBackward, onNextEpisode, onForward, onProgressSliderChange, onAudioElementReady }) => { const dispatch = useDispatch(); const history = useHistory(); const audioElement = useRef(null); @@ -122,6 +123,7 @@ const PlayerUI = ({ audioController, activePodcast, activeEpisode, title, progre const resourceUrl = new URL(fileUrl); resourceUrl.searchParams.delete('_from'); resourceUrl.searchParams.append('_from','podfriend.com'); + resourceUrl.searchParams.append('_guid',activeEpisode.statsId); return resourceUrl.toString(); } catch (exception) { @@ -130,11 +132,12 @@ const PlayerUI = ({ audioController, activePodcast, activeEpisode, title, progre try { var fallbackUrl = fileUrl; if (fallbackUrl.includes('?')) { - fallbackUrl += '&_from=podfriend.com'; + fallbackUrl += '&_from=podfriend.com&_guid=' + activeEpisode.statsId; } else { - fallbackUrl += '?_from=podfriend.com'; + fallbackUrl += '?_from=podfriend.com&_guid=' + activeEpisode.statsId; } + return fallbackUrl; } catch (exception2) { return fileUrl; @@ -168,6 +171,7 @@ const PlayerUI = ({ audioController, activePodcast, activeEpisode, title, progre onSeeked: onSeek, onTimeUpdate: onTimeUpdate, onEnded: onEnded, + onLoadedData: () => { onLoadedData }, preload: "auto", disableremoteplayback: "true", @@ -284,6 +288,10 @@ const PlayerUI = ({ audioController, activePodcast, activeEpisode, title, progre dispatch(showFullPlayer(false)); }; + const generateTimeHash = () => { + return '#t=' + Math.round(activeEpisode.currentTime ? activeEpisode.currentTime : 0); + }; + return ( <>
{ dispatch(showFullPlayer(false)); }} /> @@ -297,14 +305,14 @@ const PlayerUI = ({ audioController, activePodcast, activeEpisode, title, progre <>
} { isVideo === false && <> { chapters !== false && @@ -456,12 +464,10 @@ const PlayerUI = ({ audioController, activePodcast, activeEpisode, title, progre
{ fullPlayerOpen &&
-
-
- - - -
+
+ + +
{ chapters !== false &&
@@ -482,8 +488,8 @@ const PlayerUI = ({ audioController, activePodcast, activeEpisode, title, progre } { dispatch(showSpeedSettingWindow()); }}> Set audio speed + { dispatch(showShareWindow()); }}> Share episode {/* - Share episode Set sleep timer Chromecast */} diff --git a/app/components/Player/ShareModal.jsx b/app/components/Player/ShareModal.jsx new file mode 100644 index 00000000..db8173db --- /dev/null +++ b/app/components/Player/ShareModal.jsx @@ -0,0 +1,72 @@ +import React, { useState, useEffect } from 'react'; + +import { useDispatch, useSelector } from 'react-redux'; + +import Modal from 'podfriend-approot/components/Window/Modal'; + +import TimeUtil from 'podfriend-approot/library/TimeUtil.js'; + +import ShareButtons from 'podfriend-approot/components/Podcast/ShareButtons.jsx'; + +import styles from './ShareModal.scss'; + +const ShareModal = ({ onClose }) => { + const activePodcast = useSelector((state) => state.podcast.activePodcast); + const activeEpisode = useSelector((state) => state.podcast.activeEpisode); + const [shareMessage,setShareMessage] = useState(''); + const [shareUrl,setShareUrl] = useState(false); + const [includeTime,setIncludeTime] = useState(false); + const [timeStamp,setTimeStamp] = useState(TimeUtil.formatPrettyDurationText(Math.round(activeEpisode.currentTime))); + + useEffect(() => { + var newShareUrl = 'https://web.podfriend.com/podcast/' + activePodcast.path + '/' + activeEpisode.id; + + if (includeTime) { + newShareUrl += '?t=' + TimeUtil.HmsToSeconds(timeStamp) + } + setShareUrl(newShareUrl); + },[includeTime,timeStamp]); + + useEffect(() => { + setShareMessage('Check out this episode: ' + activeEpisode.title + ', from the podcast ' + activePodcast.name + ': ' + shareUrl); + },[shareUrl]); + + const changeIncludeTime = (event) => { + const target = event.target; + + setIncludeTime(target.checked); + }; + + const changeTimeStamp = (event) => { + setTimeStamp(event.target.value); + }; + + return ( + +
+
+
{activeEpisode.title}
+
Link:
+
+
+ Start at +
+
Easy text to copy & paste:
+