From c43ffd95c0989c4eed483214f0255d2748365831 Mon Sep 17 00:00:00 2001 From: wadebekker Date: Thu, 2 Jan 2025 15:15:23 +0200 Subject: [PATCH] Implements initial ability to dock the player to top or bottom of page --- assets/js/blocks.js | 7 +- assets/js/blocks/podcast/index.scss | 75 +++++++++ assets/js/edit.js | 241 ++++++++++++++++++++-------- includes/blocks/podcast/markup.php | 134 +++++++++++----- simple-podcasting.php | 23 +++ 5 files changed, 372 insertions(+), 108 deletions(-) mode change 100755 => 100644 assets/js/blocks.js diff --git a/assets/js/blocks.js b/assets/js/blocks.js old mode 100755 new mode 100644 index 0f30003..f853b92 --- a/assets/js/blocks.js +++ b/assets/js/blocks.js @@ -120,7 +120,12 @@ export default registerBlockType( displayEpisodeType: { type: 'boolean', default: false, - } + }, + isDocked: { + type: 'string', + default: 'none', + enum: ['none', 'top', 'bottom'], + }, }, transforms, diff --git a/assets/js/blocks/podcast/index.scss b/assets/js/blocks/podcast/index.scss index 3c321f2..813d867 100644 --- a/assets/js/blocks/podcast/index.scss +++ b/assets/js/blocks/podcast/index.scss @@ -1,7 +1,80 @@ +body.has-docked-bottom { + padding-bottom: 150px; + &.docked-in-editor .docked-bottom { + bottom: 24px; + } +} +body.has-docked-top { + padding-top: 150px; + &.docked-in-editor { + padding-top: 0px; + } + &.docked-in-editor .editor-styles-wrapper { + padding-top: 150px; + } + &.docked-in-editor .docked-top { + top: 60px; + } + + &.logged-in.admin-bar { + padding-top: 182px; + } + + &.logged-in.admin-bar .docked-top { + top: 32px; + } +} + + .wp-block-podcasting-podcast-outer { border: 1px solid #707070; border-radius: 4px; padding: 20px; + + &.docked-bottom { + margin: 0; + background-color: var(--wp--preset--color--base); + position: fixed; + bottom: 0; + left: 0; + right: 0; + z-index: 34; + border-radius: 4px 4px 0px 0px; + max-width: initial; + .wp-block-podcasting-podcast__container { + margin-bottom: 0px; + } + + .wp-block-podcasting-podcast__details { + width: 100%; + } + + #toggle-details-button { + margin-bottom: 20px; + } + } + &.docked-top { + margin: 0; + background-color: var(--wp--preset--color--base); + position: fixed; + top: 0; + left: 0; + right: 0; + z-index: 34; + border-radius: 0px 0px 4px 4px; + max-width: initial; + .wp-block-podcasting-podcast__container { + margin-bottom: 0px; + } + + .wp-block-podcasting-podcast__details { + width: 100%; + } + + #toggle-details-button { + margin-bottom: 20px; + } + } } .wp-block-podcasting-podcast__container { @@ -13,9 +86,11 @@ } .wp-block-podcasting-podcast__show-art { + display: none; margin-bottom: 20px; @media (min-width: 768px) { + display: block; flex-basis: 100px; margin-bottom: 0; margin-right: 20px; diff --git a/assets/js/edit.js b/assets/js/edit.js index b7e4e0d..6e30779 100644 --- a/assets/js/edit.js +++ b/assets/js/edit.js @@ -70,7 +70,8 @@ function Edit( props ) { displayExplicitBadge, displaySeasonNumber, displayEpisodeNumber, - displayEpisodeType + displayEpisodeType, + isDocked, } = attributes; const duration = attributes.duration || ''; @@ -185,6 +186,53 @@ function Edit( props ) { setFeaturedImage(image.id); }; + // Docked Player + const dockedClass = isDocked !== 'none' ? `docked-${isDocked}` : ''; + const [showPodcastMeta, setShowPodcastMeta] = useState(false); + const [isDisplayingSettings, setIsDisplayingSettings] = useState(false); + + const checkDisplaySettings = () => { + if (displayDuration || displayShowTitle || + // displayEpisodeTitle || + // displayArt || + displayExplicitBadge || displaySeasonNumber || displayEpisodeNumber || displayEpisodeType) { + setIsDisplayingSettings(true); + } + else { + setIsDisplayingSettings(false); + } + } + + // If the user changes one of the toggles, the checkDisplaySettings function will be called to check if any of the display settings are enabled. + // If at least one of the display settings are enabled, then we want to show the More/Less button. + useEffect(() => { + checkDisplaySettings(); + }, [displayDuration, + displayShowTitle, + // displayEpisodeTitle, + // displayArt, + displayExplicitBadge, + displaySeasonNumber, + displayEpisodeNumber, + displayEpisodeType]) + + // Reset the More/Less button when the user docks or undocks the player. + useEffect(() => { + setShowPodcastMeta(false) + }, [isDocked]) + + useEffect(() => { + // Remove any existing classes + document.body.classList.remove('has-docked-top', 'has-docked-bottom', 'docked-in-editor'); + + // Add the appropriate class based on the isDocked value + if (isDocked === 'top') { + document.body.classList.add('has-docked-top', 'docked-in-editor'); + } else if (isDocked === 'bottom') { + document.body.classList.add('has-docked-bottom', 'docked-in-editor'); + } + }, [isDocked]); // Run this effect when isDocked changes + return ( {controls} @@ -285,7 +333,33 @@ function Edit( props ) { 'simple-podcasting' )} checked={displayEpisodeType} - onChange={() => setAttributes({ displayEpisodeType: !displayEpisodeType})} + onChange={() => setAttributes({ displayEpisodeType: !displayEpisodeType })} + /> + + + + setAttributes({ isDocked }) + } /> @@ -420,7 +494,7 @@ function Edit( props ) { -
+
{src ? ( <>
@@ -448,76 +522,109 @@ function Edit( props ) { )} -
- {displayShowTitle && ( - - {showName} - - )} - {displaySeasonNumber && seasonNumber && ( - - {__( - 'Season: ', - 'simple-podcasting' + {(isDocked === 'none' || showPodcastMeta) && ( + <> +
+ {displayShowTitle && ( + + {showName} + )} - {seasonNumber} - - )} - {displayEpisodeNumber && episodeNumber && ( - - {__('Episode: ', 'simple-podcasting')} - {episodeNumber} - - )} -
- -
- {displayDuration && duration && ( - - {__('Listen Time: ', 'simple-podcasting')} - {duration} - - )} - {displayEpisodeType && (episodeType !== 'none') && ( - - {__( - 'Episode type: ', - 'simple-podcasting' + {displaySeasonNumber && seasonNumber && ( + + {__( + 'Season: ', + 'simple-podcasting' + )} + {seasonNumber} + )} - {episodeType} - - )} - {displayExplicitBadge && ( - - {__( - 'Explicit: ', - 'simple-podcasting' + {displayEpisodeNumber && episodeNumber && ( + + {__('Episode: ', 'simple-podcasting')} + {episodeNumber} + )} - {explicit} - - )} -
+
+ +
+ {displayDuration && duration && ( + + {__('Listen Time: ', 'simple-podcasting')} + {duration} + + )} + {displayEpisodeType && (episodeType !== 'none') && ( + + {__( + 'Episode type: ', + 'simple-podcasting' + )} + {episodeType} + + )} + {displayExplicitBadge && ( + + {__( + 'Explicit: ', + 'simple-podcasting' + )} + {explicit} + + )} +
+ + )} + + {isDocked !== 'none' && isDisplayingSettings && ( + + )} + + {isDocked !== 'none' && ( +
+ {((caption && caption.length) || !!isSelected) && ( + + setAttributes({ caption: value }) + } + isSelected={isSelected} + /> + )} +
+ )}
-
- {((caption && caption.length) || !!isSelected) && ( - - setAttributes({ caption: value }) - } - isSelected={isSelected} - /> - )} -
+ {isDocked === 'none' && ( +
+ {((caption && caption.length) || !!isSelected) && ( + + setAttributes({ caption: value }) + } + isSelected={isSelected} + /> + )} +
+ )} ) : ( false, 'displayEpisodeNumber' => false, 'displayEpisodeType' => false, + 'isDocked' => 'none', ] ); @@ -46,8 +47,17 @@ $term_image_id = ''; } +// Output the body class based on isDocked value +$body_class = ''; +if ( $attributes['isDocked'] === 'top' ) { + $body_class = 'has-docked-top'; +} elseif ( $attributes['isDocked'] === 'bottom' ) { + $body_class = 'has-docked-bottom'; +} + ?> -
+ +
@@ -74,46 +84,90 @@ -
- - - - - - - - - - - - - - - - - -
-
- - - - - - - - - - - - - - - - - - + +
+ +
+
- + +
+ + diff --git a/simple-podcasting.php b/simple-podcasting.php index a4f9035..5e5c1c6 100644 --- a/simple-podcasting.php +++ b/simple-podcasting.php @@ -343,3 +343,26 @@ function register_latest_episode_assets_admin() { wp_enqueue_style( 'latest-episode-block' ); } add_action( 'admin_enqueue_scripts', __NAMESPACE__ . '\register_latest_episode_assets_admin' ); + + +function add_custom_admin_body_class( $classes ) { + global $post; + + if ( $post ) { + $blocks = parse_blocks( $post->post_content ); + + foreach ( $blocks as $block ) { + if ( 'podcasting/podcast' === $block['blockName'] && isset( $block['attrs']['isDocked'] ) ) { + $is_docked = $block['attrs']['isDocked']; + if ( 'top' === $is_docked ) { + $classes .= ' has-docked-top docked-in-editor'; + } elseif ( 'bottom' === $is_docked ) { + $classes .= ' has-docked-bottom docked-in-editor'; + } + } + } + } + + return $classes; +} +add_filter( 'admin_body_class', __NAMESPACE__ . '\add_custom_admin_body_class' );