diff --git a/src/components/generics/Timing.jsx b/src/components/generics/Timing.jsx new file mode 100644 index 00000000..269d6d0a --- /dev/null +++ b/src/components/generics/Timing.jsx @@ -0,0 +1,80 @@ +import PropTypes from 'prop-types' + +import { + formatDuration, + formatTime, + formatDateTime, + formatTimeRelative, +} from 'utils' + +export function Duration({ duration }) { + const [iso, hhmm, ss] = formatDuration(duration) + + return ( + + ) +} + +Duration.propTypes = { + duration: PropTypes.string.isRequired, +} + +export function Time({ iso }) { + const date = formatTime(iso) + + return ( + + ) +} + +Time.propTypes = { + iso: PropTypes.string.isRequired, +} + +export function DateTime({ iso, showSeconds = false }) { + const [date, ss] = formatDateTime(iso, showSeconds) + + return ( + + ) +} + +DateTime.propTypes = { + iso: PropTypes.string.isRequired, + showSeconds: PropTypes.bool, +} + +export function TimeRelative({ + iso, + relativeToIso, + withoutSuffix = false, + withoutTimeTruncate = false, +}) { + const date = formatTimeRelative( + iso, + relativeToIso, + withoutSuffix, + withoutTimeTruncate + ) + + return ( + + ) +} + +TimeRelative.propTypes = { + iso: PropTypes.string.isRequired, + relativeToIso: PropTypes.string, + withoutSuffix: PropTypes.bool, + withoutTimeTruncate: PropTypes.bool, +} diff --git a/src/components/karaoke/player/Carousel.jsx b/src/components/karaoke/player/Carousel.jsx index ab45711e..e0f3f4d6 100644 --- a/src/components/karaoke/player/Carousel.jsx +++ b/src/components/karaoke/player/Carousel.jsx @@ -1,14 +1,11 @@ import dayjs from 'dayjs' -import relativeTime from 'dayjs/plugin/relativeTime' import queryString from 'query-string' import { useSelector } from 'react-redux' import { Link } from 'react-router' import { CarouselEntry } from 'components/generics/Carousel' +import { Duration, Time, TimeRelative } from 'components/generics/Timing' import PlaylistEntryWidget from 'components/playlist/widgets/PlaylistEntry' -import { formatDate, formatDuration } from 'utils' - -dayjs.extend(relativeTime) export function CarouselEntryCurrentSong() { const { data: playerStatus } = useSelector( @@ -39,9 +36,13 @@ export function CarouselEntryCurrentSong() { truncatable /> -
-
{formatDuration(timing)}
-
{formatDuration(entry.song.duration)}
+
+
+ +
+
+ +
) @@ -77,9 +78,11 @@ export function CarouselEntryNextSong() { } export function CarouselEntryStats() { - const { queuingEntries, playedEntries, dateEnd } = useSelector( - (state) => state.playlist.digest.entries.data - ) + const { + queuingEntries, + playedEntries, + dateEnd: playlistDateEnd, + } = useSelector((state) => state.playlist.digest.entries.data) const { data: playerStatus } = useSelector( (state) => state.playlist.playerStatus ) @@ -136,57 +139,86 @@ export function CarouselEntryStats() { * well together. At least, the code is easy to understand. */ - const playlistEndDate = - dateEnd && (countQueuingEntries || playerStatus.playlist_entry) - ? dayjs(dateEnd) - : null - const karaokeEndDate = karaokeDateStop ? dayjs(karaokeDateStop) : null + const karaokeHasDateStop = !!karaokeDateStop + + // the playlist has a date end if a date end is calculated and either there + // are songs queuing or there is one song playing + const playlistHasDateEnd = + playlistDateEnd && (countQueuingEntries || playerStatus.playlist_entry) let end // only playlist date end - if (playlistEndDate && !karaokeEndDate) { + if (playlistHasDateEnd && !karaokeHasDateStop) { end = (
  • - Playlist ends at {formatDate(playlistEndDate)} + Playlist ends at{' '} + +
  • ) - // only karaoke date end - } else if (!playlistEndDate && karaokeEndDate) { - if (karaokeEndDate.isAfter()) { + // only karaoke date stop + } else if (!playlistHasDateEnd && karaokeHasDateStop) { + // if the the karaoke date stop is not passed + if (dayjs().isBefore(karaokeDateStop)) { end = ( <>
  • - Karaoke ends at {formatDate(karaokeEndDate)} + Karaoke ends at{' '} + +
  • - {dayjs().to(karaokeEndDate, true)} remaining + + + {' '} + remaining
  • ) + // otherwise the karaoke is finished } else { end =
  • Karaoke ended
  • } - // both playlist date end and karaoke date end - } else if (playlistEndDate && karaokeEndDate) { - // karaoke date end is after playlist date end - if (karaokeEndDate.isAfter(playlistEndDate)) { + // both playlist date end and karaoke date stop + } else if (playlistHasDateEnd && karaokeHasDateStop) { + // karaoke date stop is after playlist date end + if (dayjs(playlistDateEnd).isBefore(karaokeDateStop)) { end = ( <>
  • - Karaoke ends at {formatDate(karaokeEndDate)} + Karaoke ends at{' '} + +
  • - {dayjs().to(karaokeEndDate, true)} remaining + + + {' '} + remaining in playlist
  • ) - // playlist date end is after karaoke date end + // playlist date end is after karaoke date stop } else { end = ( <>
  • Playlist should end after karaoke at{' '} - {formatDate(playlistEndDate)} + +
  • Playlist exceeds karaoke scheduled end!
  • diff --git a/src/components/library/status/InPlaylist.jsx b/src/components/library/status/InPlaylist.jsx index 3a8718af..9fbb39e5 100644 --- a/src/components/library/status/InPlaylist.jsx +++ b/src/components/library/status/InPlaylist.jsx @@ -6,7 +6,8 @@ import { Link } from 'react-router' import UserWidget from 'components/user/widgets/User' import { playlistEntryPropType } from 'serverPropTypes/playlist' -import { formatDate, formatDateRelative, getMostPertinentEntry } from 'utils' +import { getMostPertinentEntry } from 'utils' +import { Time, TimeRelative } from 'components/generics/Timing' function Playing({ entry }) { const playerStatus = useSelector((state) => state.playlist.playerStatus.data) @@ -35,7 +36,7 @@ function Queuing({ entry }) { - +
    ) } @@ -50,7 +51,7 @@ function Played({ entry }) { - +