diff --git a/block-languages/benenson-blocks.pot b/block-languages/benenson-blocks.pot index 2b8927e..225ab7f 100644 --- a/block-languages/benenson-blocks.pot +++ b/block-languages/benenson-blocks.pot @@ -88,6 +88,7 @@ msgstr "" #: src/scripts/blocks/appearance-options/index.js:39 #: src/scripts/blocks/blockquote/index.js:232 +#: src/scripts/blocks/countdown-timer/DisplayComponent.js:46 #: src/scripts/blocks/header/DisplayComponent.js:95 #: src/scripts/blocks/menu/DisplayComponent.js:12 #: src/scripts/blocks/section/DisplayComponent.js:49 @@ -96,6 +97,7 @@ msgstr "" #: src/scripts/blocks/appearance-options/index.js:42 #: src/scripts/blocks/blockquote/index.js:226 +#: src/scripts/blocks/countdown-timer/DisplayComponent.js:49 #: src/scripts/blocks/header/DisplayComponent.js:98 msgid "Black" msgstr "" @@ -125,6 +127,7 @@ msgstr "" #: src/scripts/blocks/call-to-action/DisplayComponent.js:46 #: src/scripts/blocks/category-list/DisplayComponent.js:62 #: src/scripts/blocks/columns/DisplayComponent.js:28 +#: src/scripts/blocks/countdown-timer/DisplayComponent.js:65 #: src/scripts/blocks/header/DisplayComponent.js:120 #: src/scripts/blocks/iframe/DisplayComponent.js:89 #: src/scripts/blocks/link/DisplayComponent.js:53 @@ -242,6 +245,7 @@ msgid "Alignment" msgstr "" #: src/scripts/blocks/blockquote/index.js:252 +#: src/scripts/blocks/countdown-timer/DisplayComponent.js:73 msgid "Text Colour" msgstr "" @@ -403,6 +407,77 @@ msgstr "" msgid "Row Column" msgstr "" +#: src/scripts/blocks/countdown-timer/DisplayComponent.js:114 +#: src/scripts/blocks/key-facts/fact.js:30 +#: src/scripts/blocks/key-facts/index.js:79 +#: src/scripts/blocks/links-with-icons/InnerBlockEdit.js:268 +#: src/scripts/blocks/media-aside/DisplayComponent.js:83 +#: src/scripts/blocks/post-list/components/editable/GridItem.js:30 +#: src/scripts/blocks/post-list/components/editable/LinkList.js:29 +#: src/scripts/blocks/post-list/components/editable/PostItem.js:55 +#: src/scripts/blocks/post-list/components/editable/SplitGridItem.js:38 +msgid "(Insert Title)" +msgstr "" + +#: src/scripts/blocks/countdown-timer/DisplayComponent.js:121 +msgid "Days" +msgstr "" + +#: src/scripts/blocks/countdown-timer/DisplayComponent.js:124 +msgid "Hours" +msgstr "" + +#: src/scripts/blocks/countdown-timer/DisplayComponent.js:127 +msgid "Minutes" +msgstr "" + +#: src/scripts/blocks/countdown-timer/DisplayComponent.js:130 +msgid "Seconds" +msgstr "" + +#: src/scripts/blocks/countdown-timer/DisplayComponent.js:139 +msgid "(Insert Reveal Title)" +msgstr "" + +#: src/scripts/blocks/countdown-timer/DisplayComponent.js:149 +msgid "(Insert Reveal Content)" +msgstr "" + +#: src/scripts/blocks/countdown-timer/DisplayComponent.js:159 +#: src/scripts/blocks/media-aside/DisplayComponent.js:103 +msgid "(Insert Link text)" +msgstr "" + +#: src/scripts/blocks/countdown-timer/DisplayComponent.js:67 +msgid "Hide timer" +msgstr "" + +#: src/scripts/blocks/countdown-timer/DisplayComponent.js:68 +msgid "Hide the timer from users when the countdown has completed." +msgstr "" + +#: src/scripts/blocks/countdown-timer/DisplayComponent.js:83 +msgid "Background colour" +msgstr "" + +#: src/scripts/blocks/countdown-timer/DisplayComponent.js:93 +msgid "Remove background colour" +msgstr "" + +#: src/scripts/blocks/countdown-timer/DisplayComponent.js:96 +#: src/scripts/blocks/header/DisplayComponent.js:152 +#: src/scripts/blocks/section/DisplayComponent.js:105 +msgid "Background Image" +msgstr "" + +#: src/scripts/blocks/countdown-timer/index.js:17 +msgid "Countdown Timer" +msgstr "" + +#: src/scripts/blocks/countdown-timer/index.js:18 +msgid "Set a future date to countdown to." +msgstr "" + #: src/scripts/blocks/download/index.js:12 msgid "Resource Download" msgstr "" @@ -471,11 +546,6 @@ msgid "" "embed in the hero." msgstr "" -#: src/scripts/blocks/header/DisplayComponent.js:152 -#: src/scripts/blocks/section/DisplayComponent.js:105 -msgid "Background Image" -msgstr "" - #: src/scripts/blocks/header/DisplayComponent.js:152 msgid "Featured Image" msgstr "" @@ -646,17 +716,6 @@ msgstr "" msgid "Add a flexible image block with optional overlay" msgstr "" -#: src/scripts/blocks/key-facts/fact.js:30 -#: src/scripts/blocks/key-facts/index.js:79 -#: src/scripts/blocks/links-with-icons/InnerBlockEdit.js:268 -#: src/scripts/blocks/media-aside/DisplayComponent.js:83 -#: src/scripts/blocks/post-list/components/editable/GridItem.js:30 -#: src/scripts/blocks/post-list/components/editable/LinkList.js:29 -#: src/scripts/blocks/post-list/components/editable/PostItem.js:55 -#: src/scripts/blocks/post-list/components/editable/SplitGridItem.js:38 -msgid "(Insert Title)" -msgstr "" - #: src/scripts/blocks/key-facts/fact.js:39 #: src/scripts/blocks/media-aside/DisplayComponent.js:93 #: src/scripts/blocks/post-list/components/editable/GridItem.js:46 @@ -831,10 +890,6 @@ msgstr "" msgid "Add a repeatable logo block" msgstr "" -#: src/scripts/blocks/media-aside/DisplayComponent.js:103 -msgid "(Insert Link text)" -msgstr "" - #: src/scripts/blocks/media-aside/DisplayComponent.js:57 msgid "Display in modal" msgstr "" diff --git a/functions.php b/functions.php index 3418989..7e0da8d 100644 --- a/functions.php +++ b/functions.php @@ -32,6 +32,7 @@ require_once realpath( get_template_directory() . '/includes/blocks/meta.php' ); require_once realpath( get_template_directory() . '/includes/blocks/register.php' ); require_once realpath( get_template_directory() . '/includes/blocks/templates.php' ); +require_once realpath( get_template_directory() . '/includes/blocks/countdown-timer/reveal-content.php' ); require_once realpath( get_template_directory() . '/includes/rest-api/category-list.php' ); require_once realpath( get_template_directory() . '/includes/rest-api/fetch-menu.php' ); diff --git a/includes/block-translations.php b/includes/block-translations.php index 7c928b8..fef0833 100644 --- a/includes/block-translations.php +++ b/includes/block-translations.php @@ -12,7 +12,7 @@ __( 'Standard', 'benenson' ), // Reference: src/scripts/blocks/action/BlockEdit.js:37 - // Reference: src/scripts/blocks/section/DisplayComponent.js:62 + // Reference: src/scripts/blocks/section/DisplayComponent.js:74 __( 'Wide', 'benenson' ), // Reference: src/scripts/blocks/action/BlockEdit.js:62 @@ -68,13 +68,15 @@ // Reference: src/scripts/blocks/appearance-options/index.js:39 // Reference: src/scripts/blocks/blockquote/index.js:232 + // Reference: src/scripts/blocks/countdown-timer/DisplayComponent.js:46 // Reference: src/scripts/blocks/header/DisplayComponent.js:95 // Reference: src/scripts/blocks/menu/DisplayComponent.js:12 - // Reference: src/scripts/blocks/section/DisplayComponent.js:37 + // Reference: src/scripts/blocks/section/DisplayComponent.js:49 __( 'White', 'benenson' ), // Reference: src/scripts/blocks/appearance-options/index.js:42 // Reference: src/scripts/blocks/blockquote/index.js:226 + // Reference: src/scripts/blocks/countdown-timer/DisplayComponent.js:49 // Reference: src/scripts/blocks/header/DisplayComponent.js:98 __( 'Black', 'benenson' ), @@ -98,12 +100,14 @@ // Reference: src/scripts/blocks/call-to-action/DisplayComponent.js:46 // Reference: src/scripts/blocks/category-list/DisplayComponent.js:62 // Reference: src/scripts/blocks/columns/DisplayComponent.js:28 + // Reference: src/scripts/blocks/countdown-timer/DisplayComponent.js:65 // Reference: src/scripts/blocks/header/DisplayComponent.js:120 // Reference: src/scripts/blocks/iframe/DisplayComponent.js:89 // Reference: src/scripts/blocks/link/DisplayComponent.js:53 // Reference: src/scripts/blocks/menu/DisplayComponent.js:96 // Reference: src/scripts/blocks/post-list/DisplayComponent.js:91 - // Reference: src/scripts/blocks/section/DisplayComponent.js:68 + // Reference: src/scripts/blocks/countdown-timer/DisplayComponent.js:64 + // Reference: src/scripts/blocks/section/DisplayComponent.js:80 // Reference: src/scripts/blocks/slider/DisplayComponent.js:215 __( 'Options', 'benenson' ), @@ -144,6 +148,7 @@ // Reference: src/scripts/blocks/blockquote/index.js:165 // Reference: src/scripts/blocks/image/BlockEdit.js:197 + // Reference: src/scripts/blocks/section/index.js:53 // Reference: src/scripts/blocks/tweet/index.js:26 __( 'Default', 'benenson' ), @@ -159,7 +164,7 @@ // Reference: src/scripts/blocks/header/DisplayComponent.js:114 // Reference: src/scripts/blocks/links-with-icons/InnerBlockEdit.js:223 // Reference: src/scripts/blocks/logo-list/InnerBlockEdit.js:139 - // Reference: src/scripts/blocks/section/DisplayComponent.js:48 + // Reference: src/scripts/blocks/section/DisplayComponent.js:60 __( 'Small', 'benenson' ), // Reference: src/scripts/blocks/blockquote/index.js:217 @@ -181,7 +186,7 @@ // Reference: src/scripts/blocks/links-with-icons/BlockEdit.js:60 // Reference: src/scripts/blocks/logo-list/BlockEdit.js:52 // Reference: src/scripts/blocks/menu/DisplayComponent.js:15 - // Reference: src/scripts/blocks/section/DisplayComponent.js:40 + // Reference: src/scripts/blocks/section/DisplayComponent.js:52 // Reference: src/scripts/blocks/section/index.js:27 __( 'Grey', 'benenson' ), @@ -194,6 +199,7 @@ __( 'Alignment', 'benenson' ), // Reference: src/scripts/blocks/blockquote/index.js:252 + // Reference: src/scripts/blocks/countdown-timer/DisplayComponent.js:73 __( 'Text Colour', 'benenson' ), // Reference: src/scripts/blocks/blockquote/index.js:258 @@ -316,25 +322,83 @@ // Reference: src/scripts/blocks/columns/row-column.js:9 __( 'Row Column', 'benenson' ), + // Reference: src/scripts/blocks/countdown-timer/DisplayComponent.js:115 + // Reference: src/scripts/blocks/key-facts/fact.js:30 + // Reference: src/scripts/blocks/key-facts/index.js:79 + // Reference: src/scripts/blocks/links-with-icons/InnerBlockEdit.js:268 + // Reference: src/scripts/blocks/countdown-timer/DisplayComponent.js:114 + // Reference: src/scripts/blocks/media-aside/DisplayComponent.js:83 + // Reference: src/scripts/blocks/post-list/components/editable/GridItem.js:30 + // Reference: src/scripts/blocks/post-list/components/editable/LinkList.js:29 + // Reference: src/scripts/blocks/countdown-timer/DisplayComponent.js:108 + // Reference: src/scripts/blocks/post-list/components/editable/PostItem.js:55 + // Reference: src/scripts/blocks/post-list/components/editable/SplitGridItem.js:38 + __( '(Insert Title)', 'benenson' ), + + // Reference: src/scripts/blocks/countdown-timer/DisplayComponent.js:122 + __( 'Days', 'benenson' ), + + // Reference: src/scripts/blocks/countdown-timer/DisplayComponent.js:125 + __( 'Hours', 'benenson' ), + + // Reference: src/scripts/blocks/countdown-timer/DisplayComponent.js:128 + __( 'Minutes', 'benenson' ), + + // Reference: src/scripts/blocks/countdown-timer/DisplayComponent.js:131 + __( 'Seconds', 'benenson' ), + + // Reference: src/scripts/blocks/countdown-timer/DisplayComponent.js:140 + __( '(Insert Reveal Title)', 'benenson' ), + + // Reference: src/scripts/blocks/countdown-timer/DisplayComponent.js:150 + __( '(Insert Reveal Content)', 'benenson' ), + + // Reference: src/scripts/blocks/countdown-timer/DisplayComponent.js:160 + // Reference: src/scripts/blocks/media-aside/DisplayComponent.js:103 + __( '(Insert Link text)', 'benenson' ), + + // Reference: src/scripts/blocks/countdown-timer/DisplayComponent.js:67 + __( 'Hide timer', 'benenson' ), + + // Reference: src/scripts/blocks/countdown-timer/DisplayComponent.js:68 + __( 'When the timer has finished hide it from users.', 'benenson' ), + + // Reference: src/scripts/blocks/countdown-timer/DisplayComponent.js:83 + __( 'Background colour', 'benenson' ), + + // Reference: src/scripts/blocks/countdown-timer/DisplayComponent.js:93 + __( 'Remove background colour', 'benenson' ), + + // Reference: src/scripts/blocks/countdown-timer/DisplayComponent.js:96 + // Reference: src/scripts/blocks/header/DisplayComponent.js:152 + // Reference: src/scripts/blocks/section/DisplayComponent.js:105 + __( 'Background Image', 'benenson' ), + + // Reference: src/scripts/blocks/countdown-timer/index.js:17 + __( 'Countdown Timer', 'benenson' ), + + // Reference: src/scripts/blocks/countdown-timer/index.js:18 + __( 'Set a future date to countdown to.', 'benenson' ), + // Reference: src/scripts/blocks/download/index.js:12 __( 'Resource Download', 'benenson' ), // Reference: src/scripts/blocks/download/index.js:13 __( 'Add a button to download a resource', 'benenson' ), - // Reference: src/scripts/blocks/download/index.js:44 + // Reference: src/scripts/blocks/download/index.js:43 __( 'File', 'benenson' ), - // Reference: src/scripts/blocks/download/index.js:45 + // Reference: src/scripts/blocks/download/index.js:44 __( 'A File', 'benenson' ), - // Reference: src/scripts/blocks/download/index.js:67 + // Reference: src/scripts/blocks/download/index.js:66 __( '[Download Resource]', 'benenson' ), - // Reference: src/scripts/blocks/download/index.js:75 + // Reference: src/scripts/blocks/download/index.js:74 __( 'Remove Resource', 'benenson' ), - // Reference: src/scripts/blocks/download/index.js:85 + // Reference: src/scripts/blocks/download/index.js:84 __( 'Edit File', 'benenson' ), // Reference: src/scripts/blocks/header/DisplayComponent.js:103 @@ -346,7 +410,7 @@ __( 'Video', 'benenson' ), // Reference: src/scripts/blocks/header/DisplayComponent.js:111 - // Reference: src/scripts/blocks/section/DisplayComponent.js:56 + // Reference: src/scripts/blocks/section/DisplayComponent.js:68 __( 'Normal', 'benenson' ), // Reference: src/scripts/blocks/header/DisplayComponent.js:128 @@ -354,7 +418,7 @@ // Reference: src/scripts/blocks/links-with-icons/BlockEdit.js:81 // Reference: src/scripts/blocks/logo-list/BlockEdit.js:67 // Reference: src/scripts/blocks/menu/DisplayComponent.js:107 - // Reference: src/scripts/blocks/section/DisplayComponent.js:70 + // Reference: src/scripts/blocks/section/DisplayComponent.js:82 __( 'Background Colour', 'benenson' ), // Reference: src/scripts/blocks/header/DisplayComponent.js:140 @@ -368,10 +432,6 @@ // Reference: src/scripts/blocks/header/DisplayComponent.js:150 __( 'Setting this will override the cta link and will now open a modal with the embed in the hero.', 'benenson' ), - // Reference: src/scripts/blocks/header/DisplayComponent.js:152 - // Reference: src/scripts/blocks/section/DisplayComponent.js:93 - __( 'Background Image', 'benenson' ), - // Reference: src/scripts/blocks/header/DisplayComponent.js:152 __( 'Featured Image', 'benenson' ), @@ -400,7 +460,7 @@ // Reference: src/scripts/blocks/link/DisplayComponent.js:30 // Reference: src/scripts/blocks/links-with-icons/BlockEdit.js:57 // Reference: src/scripts/blocks/logo-list/BlockEdit.js:49 - // Reference: src/scripts/blocks/section/DisplayComponent.js:51 + // Reference: src/scripts/blocks/section/DisplayComponent.js:63 __( 'None', 'benenson' ), // Reference: src/scripts/blocks/header/PostFeaturedVideo.js:6 @@ -438,7 +498,7 @@ __( 'Write caption…', 'benenson' ), // Reference: src/scripts/blocks/iframe/DisplayComponent.js:91 - // Reference: src/scripts/blocks/section/DisplayComponent.js:82 + // Reference: src/scripts/blocks/section/DisplayComponent.js:94 __( 'Width', 'benenson' ), // Reference: src/scripts/blocks/iframe/DisplayComponent.js:95 @@ -502,18 +562,8 @@ // Reference: src/scripts/blocks/image/index.js:76 __( 'Add a flexible image block with optional overlay', 'benenson' ), - // Reference: src/scripts/blocks/key-facts/fact.js:30 - // Reference: src/scripts/blocks/key-facts/index.js:79 - // Reference: src/scripts/blocks/links-with-icons/InnerBlockEdit.js:268 - // Reference: src/scripts/blocks/media-aside/DisplayComponent.js:83 - // Reference: src/scripts/blocks/post-list/components/editable/GridItem.js:30 - // Reference: src/scripts/blocks/post-list/components/editable/LinkList.js:27 - // Reference: src/scripts/blocks/post-list/components/editable/PostItem.js:55 - // Reference: src/scripts/blocks/post-list/components/editable/SplitGridItem.js:38 - __( '(Insert Title)', 'benenson' ), - // Reference: src/scripts/blocks/key-facts/fact.js:39 - // Reference: src/scripts/blocks/media-aside/DisplayComponent.js:94 + // Reference: src/scripts/blocks/media-aside/DisplayComponent.js:93 // Reference: src/scripts/blocks/post-list/components/editable/GridItem.js:46 // Reference: src/scripts/blocks/post-list/components/editable/PostItem.js:71 // Reference: src/scripts/blocks/post-list/components/editable/SplitGridItem.js:54 @@ -645,9 +695,6 @@ // Reference: src/scripts/blocks/logo-list/index.js:21 __( 'Add a repeatable logo block', 'benenson' ), - // Reference: src/scripts/blocks/media-aside/DisplayComponent.js:104 - __( '(Insert Link text)', 'benenson' ), - // Reference: src/scripts/blocks/media-aside/DisplayComponent.js:57 __( 'Display in modal', 'benenson' ), @@ -760,7 +807,7 @@ // Reference: src/scripts/blocks/post-list/components/editable/SplitGridItem.js:22 __( '(Insert Tag)', 'benenson' ), - // Reference: src/scripts/blocks/post-list/components/editable/LinkList.js:12 + // Reference: src/scripts/blocks/post-list/components/editable/LinkList.js:13 __( '(Tag Name)', 'benenson' ), // Reference: src/scripts/blocks/post-list/components/post-selector/PostList.js:21 @@ -790,15 +837,15 @@ // Reference: src/scripts/blocks/post-list/index.js:49 __( 'Posts', 'benenson' ), - // Reference: src/scripts/blocks/section/DisplayComponent.js:59 + // Reference: src/scripts/blocks/section/DisplayComponent.js:100 + __( 'Id (scroll location)', 'benenson' ), + + // Reference: src/scripts/blocks/section/DisplayComponent.js:71 // Reference: src/scripts/blocks/tweet/index.js:27 __( 'Narrow', 'benenson' ), - // Reference: src/scripts/blocks/section/DisplayComponent.js:76 - __( 'Padding', 'benenson' ), - // Reference: src/scripts/blocks/section/DisplayComponent.js:88 - __( 'Id (scroll location)', 'benenson' ), + __( 'Padding', 'benenson' ), // Reference: src/scripts/blocks/section/index.js:26 __( 'Section', 'benenson' ), diff --git a/includes/blocks/countdown-timer/render.php b/includes/blocks/countdown-timer/render.php new file mode 100644 index 0000000..2724ed6 --- /dev/null +++ b/includes/blocks/countdown-timer/render.php @@ -0,0 +1,96 @@ + 0 ) { + $days = intval( $time_remaining / 86400 ); + $time_remaining %= 86400; + + $hours = str_pad( intval( $time_remaining / 3600 ), 2, '0', STR_PAD_LEFT ); + $time_remaining %= 3600; + + $minutes = str_pad( intval( $time_remaining / 60 ), 2, '0', STR_PAD_LEFT ); + $time_remaining %= 60; + + $seconds = str_pad( $time_remaining, 2, '0', STR_PAD_LEFT ); + } + } + + $finished = $time_remaining > 0 ? '' : 'is-finished'; + $hide_timer = ! empty( $attributes['hideTimer'] ) && $attributes['hideTimer'] ? sprintf( 'data-hide-show="%s"', esc_attr( $attributes['hideTimer'] ) ) : ''; + $background_color = ! empty( $attributes['backgroundColor'] ) ? sprintf( 'background-color:%s', esc_attr( $attributes['backgroundColor'] ) ) : ''; + $background_image = ! empty( $attributes['backgroundUrl'] ) ? sprintf( 'background-image: url(\'%s\');', esc_attr( $attributes['backgroundUrl'] ) ) : ''; + + spaceless(); + ?> + +
data-ref="" data-date=""> + 0 ) : ?> +
+ %s', wp_kses_post( $attributes['title'] ) ); + } + ?> +
+
+ %s%s

', esc_attr( $days ), esc_html__( 'Days', 'benenson' ) ); ?> +
+
+ %s%s

', esc_attr( $hours ), esc_html__( 'Hours', 'benenson' ) ); ?> +
+
+ %s%s

', esc_attr( $minutes ), esc_html__( 'Minutes', 'benenson' ) ); ?> +
+
+ %s%s

', esc_attr( $seconds ), esc_html__( 'Seconds', 'benenson' ) ); ?> +
+
+
+ +
+ %s', esc_attr( $attributes['revealTitle'] ) ); + } + + if ( ! empty( $attributes['revealContent'] ) ) { + printf( '

%s

', esc_attr( $attributes['revealContent'] ) ); + } + + if ( ! empty( $attributes['revealBtnUrl'] ) && ! empty( $attributes['revealBtnText'] ) ) { + printf( '%s', esc_url( $attributes['revealBtnUrl'] ), esc_attr( $attributes['revealBtnText'] ) ); + } + ?> +
+ +
+ + namespace, '/reveal-content/(?P\d+)/(?P\w+)', [ + 'callback' => [ $this, 'get_item' ], + 'methods' => 'GET', + 'args' => [ + 'id' => [ + 'validate_callback' => function ( $value ) { + return is_numeric( $value ); + }, + ], + ], + ] ); + } + + /** + * Return an array containing the menu object and its rendered html. + * + * @param WP_REST_Request $request - Current Request. + * @return array|mixed|WP_REST_Response + */ + public function get_item( WP_REST_Request $request ) { + $object = get_post_field( 'post_content', $request->get_param( 'id' ) ); + + if ( ! $object ) { + return rest_ensure_response( + new WP_Error( 'rest_invalid_param', 'Content not found', [ 'status' => 404 ] ) + ); + } + + $blocks = parse_blocks( $object ); + $block_attrs = $this->get_block( $blocks, $request->get_param( 'ref' ) ); + + return [ + 'attrs' => $block_attrs, + ]; + } + + public function get_block( array $blocks, string $ref ) { + $value = false; + + foreach ( $blocks as $block ) { + if ( isset( $block['attrs']['countdownId'] ) && $block['attrs']['countdownId'] === $ref ) { + $value = $block['attrs']; + } + + if ( ! empty( $block['innerBlocks'] ) ) { + $value = $this->get_block( $block['innerBlocks'], $ref ); + } + } + + return $value; + } +} diff --git a/includes/blocks/register.php b/includes/blocks/register.php index 48a619d..cc1b9ec 100644 --- a/includes/blocks/register.php +++ b/includes/blocks/register.php @@ -12,6 +12,7 @@ require_once __DIR__ . '/header/render.php'; require_once __DIR__ . '/category-list/render.php'; require_once __DIR__ . '/media-aside/render.php'; +require_once __DIR__ . '/countdown-timer/render.php'; /** @@ -56,6 +57,11 @@ function benenson_register_php_rendered_blocks() { 'render_callback' => 'benenson_render_media_aside_block', 'editor_script' => 'benenson-blocks-js', ] ); + + register_block_type( 'benenson/block-countdown', [ + 'render_callback' => 'benenson_render_countdown_timer_block', + 'editor_script' => 'benenson-blocks-js', + ] ); } } diff --git a/includes/scripts-and-styles.php b/includes/scripts-and-styles.php index ce957db..7828e44 100644 --- a/includes/scripts-and-styles.php +++ b/includes/scripts-and-styles.php @@ -84,6 +84,11 @@ function benenson_scripts() { wp_enqueue_script( 'comment-reply' ); } + wp_localize_script( 'global-scripts', 'benenson_data', [ + 'post_id' => get_the_ID(), + 'rest_base' => get_rest_url(), + ] ); + if ( ! is_home() && ! is_archive() && ! is_search() ) { return; } diff --git a/src/scripts/app.js b/src/scripts/app.js index 22a140f..4309de7 100755 --- a/src/scripts/app.js +++ b/src/scripts/app.js @@ -15,6 +15,7 @@ import subcatDrops from './modules/subcategory-dropdown'; import categoryExpander from './modules/category-expander'; import fluidText from './modules/fluid-text'; import scrollTo from './modules/scrollTo'; +import countdownTimer from './modules/countdown-timer'; import './polyfills'; @@ -34,6 +35,7 @@ const App = () => { subcatDrops(); categoryExpander(); scrollTo(); + countdownTimer(); fluidText(document.getElementsByClassName('article-shareTitle'), 0.9); diff --git a/src/scripts/blocks.js b/src/scripts/blocks.js index a99adc8..ce781a3 100755 --- a/src/scripts/blocks.js +++ b/src/scripts/blocks.js @@ -28,6 +28,7 @@ import './blocks/category-list'; import './blocks/logo-list'; import './blocks/link'; import './blocks/media-aside'; +import './blocks/countdown-timer'; wp.blocks.registerBlockStyle('core/table', { name: 'responsive', diff --git a/src/scripts/blocks/countdown-timer/DisplayComponent.js b/src/scripts/blocks/countdown-timer/DisplayComponent.js new file mode 100644 index 0000000..9acbac3 --- /dev/null +++ b/src/scripts/blocks/countdown-timer/DisplayComponent.js @@ -0,0 +1,176 @@ +import classnames from 'classnames'; + +const randId = () => Math.random().toString(36).replace(/[^a-z]+/g, '').substr(2, 10); + +const { __ } = wp.i18n; +const { Component, Fragment } = wp.element; +const { + InspectorControls, RichText, URLInputButton, +} = wp.editor; +const { + PanelBody, Button, DateTimePicker, ColorPicker, SelectControl, ToggleControl, +} = wp.components; +const { applyFilters } = wp.hooks; +const { PostMediaSelector } = benenson.components; + +class DisplayComponent extends Component { + componentDidMount() { + const { attributes, setAttributes } = this.props; + + if (!attributes.countdownId) { + setAttributes({ + countdownId: randId(), + }); + } + } + + render() { + const { attributes, setAttributes } = this.props; + const { + countdownId = '', + date = new Date(), + title = '', + revealTitle = '', + revealContent = '', + revealBtnText = '', + revealBtnUrl = '', + backgroundColor = '', + backgroundId = null, + backgroundUrl = '', + textColor = '', + hideTimer = false, + } = attributes; + + // Note: US English spelling. + const colourOptions = applyFilters('benenson.block.blockCountdown.colorOptions', [{ + label: __('White', 'benenson'), + value: '', + }, { + label: __('Black', 'benenson'), + value: 'black', + }]); + + const styles = { + backgroundImage: `url('${backgroundUrl}')`, + backgroundColor, + }; + + const classes = classnames('countdownTimer', { + [`is-${textColor}`]: !!textColor, + }); + + return ( + + + + setAttributes({ hideTimer: hideShow }) } + /> + setAttributes({ textColor: color }) } + options={ colourOptions } + /> + setAttributes({ date: newDate }) } + /> + + + setAttributes({ backgroundColor: color.hex }) } + disableAlpha={ true } + /> + + + + { + setAttributes({ + backgroundUrl: media ? media.source_url : '', + backgroundId: media ? media.id : null, + }); + } } + mediaId={ backgroundId } + /> + + +
+ setAttributes({ title: newTitle }) } + value={ title } + placeholder={ __('(Insert Title)', 'benenson') } + keepPlaceholderOnFocus={ true } + formattingControls={ [] } + format="string" + /> +
+
+

00{ __('Days', 'benenson') }

+
+
+

00{ __('Hours', 'benenson') }

+
+
+

00{ __('Minutes', 'benenson') }

+
+
+

00{ __('Seconds', 'benenson') }

+
+
+
+ setAttributes({ revealTitle: newTitle }) } + value={ revealTitle } + placeholder={ __('(Insert Reveal Title)', 'benenson') } + keepPlaceholderOnFocus={ true } + formattingControls={ [] } + format="string" + /> + setAttributes({ revealContent: newContent }) } + value={ revealContent } + placeholder={ __('(Insert Reveal Content)', 'benenson') } + keepPlaceholderOnFocus={ true } + formattingControls={ [] } + format="string" + /> +
+ setAttributes({ revealBtnText: newCtaText }) } + value={ revealBtnText } + placeholder={ __('(Insert Link text)', 'benenson') } + keepPlaceholderOnFocus={ true } + formattingControls={ [] } + format="string" + /> + setAttributes({ revealBtnUrl: newCtaLink }) } + /> +
+
+
+
+ ); + } +} + +export default DisplayComponent; diff --git a/src/scripts/blocks/countdown-timer/index.js b/src/scripts/blocks/countdown-timer/index.js new file mode 100644 index 0000000..ea5b55e --- /dev/null +++ b/src/scripts/blocks/countdown-timer/index.js @@ -0,0 +1,66 @@ +import classnames from 'classnames'; +import DisplayComponent from './DisplayComponent'; + +const { __ } = wp.i18n; +const { registerBlockType } = wp.blocks; +const { Component, Fragment } = wp.element; +const { + InspectorControls, RichText, +} = wp.editor; +const { + PanelBody, Button, DateTimePicker, ColorPicker, +} = wp.components; + +const { PostMediaSelector } = benenson.components; + +registerBlockType('benenson/block-countdown', { + title: __('Countdown Timer', 'benenson'), + description: __('Set a future date to countdown to.', 'benenson'), + icon: 'clock', + category: 'benenson', + supports: { + }, + + attributes: { + countdownId: { + type: 'string', + }, + title: { + type: 'string', + }, + date: { + type: 'string', + }, + revealTitle: { + type: 'string', + }, + revealContent: { + type: 'string', + }, + revealBtnText: { + type: 'string', + }, + revealBtnUrl: { + type: 'string', + }, + backgroundColor: { + type: 'string', + }, + backgroundId: { + type: 'interger', + }, + backgroundUrl: { + type: 'string', + }, + textColor: { + type: 'string', + }, + hideTimer: { + type: 'boolean', + }, + }, + edit: DisplayComponent, + + // Returns null due to the component being rendered server side + save: () => null, +}); diff --git a/src/scripts/modules/countdown-timer.js b/src/scripts/modules/countdown-timer.js new file mode 100644 index 0000000..14f56c9 --- /dev/null +++ b/src/scripts/modules/countdown-timer.js @@ -0,0 +1,111 @@ +const { benenson_data: benensonData } = window; + +const init = () => { + Array.from(document.querySelectorAll('.countdownTimer')) + .forEach((timer) => { + // return if timer has already finished + if (timer.classList.contains('is-finished')) { + return; + } + + let finished = false; + let days = 0; + let hours = 0; + let minutes = 0; + let seconds = 0; + + const daysElement = timer.querySelector('.countdownTimer-days span'); + const hoursElement = timer.querySelector('.countdownTimer-hours span'); + const minutesElement = timer.querySelector('.countdownTimer-mins span'); + const secondsElement = timer.querySelector('.countdownTimer-secs span'); + const endDate = new Date(timer.dataset.date).getTime(); + const timerRef = timer.dataset.ref; + + if (typeof endDate !== 'number') { + return; + } + + const calculate = () => { + let startDate = new Date(); + startDate = startDate.getTime(); + + // turn milliseconds into seconds to make calculations easier + let timeRemaining = parseInt((endDate - startDate) / 1000, 10); + + if (timeRemaining < 0) { + finished = true; + return; + } + + // divide time remaining by number of seconds in a day & remove days from timeRemaining + days = parseInt(timeRemaining / 86400, 10); + timeRemaining %= 86400; + + // divide time remaining by number of seconds in an hour & remove hours from timeRemaining + hours = parseInt(timeRemaining / 3600, 10); + timeRemaining %= 3600; + + // divide time remaining by number of seconds in a min & remove mins from timeRemaining. + minutes = parseInt(timeRemaining / 60, 10); + timeRemaining %= 60; + + seconds = parseInt(timeRemaining, 10); + + daysElement.innerHTML = parseInt(days, 10); + hoursElement.innerHTML = (`0${hours}`).slice(-2); + minutesElement.innerHTML = (`0${minutes}`).slice(-2); + secondsElement.innerHTML = (`0${seconds}`).slice(-2); + }; + + const timerFinished = () => { + // HTTP request for retreiving reveal information + const xhr = new XMLHttpRequest(); + xhr.onreadystatechange = function revealContent() { + if (this.readyState === 4) { + const jsonResponse = JSON.parse(this.responseText); + + const wrapper = document.createElement('div'); + wrapper.classList.add('coutdownTimer-revealContainer'); + + if (jsonResponse.attrs.revealTitle !== '') { + const title = document.createElement('h2'); + title.innerText = jsonResponse.attrs.revealTitle; + title.classList.add('countdownTimer-title'); + wrapper.append(title); + } + + if (jsonResponse.attrs.revealContent !== '') { + const content = document.createElement('p'); + content.innerText = jsonResponse.attrs.revealContent; + content.classList.add('countdownTimer-content'); + wrapper.append(content); + } + + if (jsonResponse.attrs.revealBtnUrl !== '' && jsonResponse.attrs.revealBtnText !== '') { + const button = document.createElement('a'); + button.href = jsonResponse.attrs.revealBtnUrl; + button.innerText = jsonResponse.attrs.revealBtnText; + button.classList.add('btn', 'countdownTimer-btn'); + wrapper.append(button); + } + + timer.classList.add('is-finished'); + document.querySelector(`.countdownTimer[data-ref="${timerRef}"]`).append(wrapper); + } + }; + + xhr.open('GET', `${benensonData.rest_base}benenson/v1/reveal-content/${benensonData.post_id}/${timerRef}`); + xhr.send(); + }; + + const start = setInterval(() => { + calculate(); + if (finished) { + timerFinished(); + clearInterval(start); + } + }, 1000); + }); +}; + +export default init; diff --git a/src/styles/components/countdown-timer/_editor.scss b/src/styles/components/countdown-timer/_editor.scss new file mode 100644 index 0000000..007199c --- /dev/null +++ b/src/styles/components/countdown-timer/_editor.scss @@ -0,0 +1,9 @@ +.countdownTimer-title { + @include font-size(28px); +} + +.countdownTimer-reveal { + background-color: rgba($color-white, .5); + margin-top: 40px; + padding: 20px; +} diff --git a/src/styles/components/countdown-timer/_main.scss b/src/styles/components/countdown-timer/_main.scss new file mode 100644 index 0000000..17fc7da --- /dev/null +++ b/src/styles/components/countdown-timer/_main.scss @@ -0,0 +1,57 @@ +.countdownTimer { + padding: 50px 30px; + text-align: center; + background-color: $color-black; + background-repeat: no-repeat; + background-size: cover; + background-position: center; + color: $color-white; +} + +.countdownTimer-title { + color: $color-white; + margin-bottom: 5px; +} + +.countdownTimer-items { + display: flex; + max-width: 450px; + margin: 0 auto; +} + +.countdownTimer-items .countdownTimer-item { + flex-grow: 1; + text-align: center; +} + +.countdownTimer-items .countdownTimer-item p { + margin: 30px 0 0 0; +} + +.countdownTimer-items .countdownTimer-item p span { + @include font-size(28px); + display: block; + margin-right: 5px; + + @include mq(small) { + @include font-size(38px); + display: initial; + } +} + +.countdownTimer-items .countdownTimer-item + .countdownTimer-item { + margin-left: 10px; +} + +.countdownTimer.is-black, +.countdownTimer.is-black .countdownTimer-title { + color: $color-black; +} + +.countdownTimer.is-finished .countdownTimer-container { + display: none; +} + +.countdownTimer.is-finished[data-hide-show="1"] { + display: none; +} diff --git a/src/styles/style-editor.scss b/src/styles/style-editor.scss index 3e2601c..49cd13e 100755 --- a/src/styles/style-editor.scss +++ b/src/styles/style-editor.scss @@ -86,6 +86,8 @@ @import "components/split-grid/main"; @import "components/media-aside/main"; @import "components/media-aside/editor"; +@import "components/countdown-timer/main"; +@import "components/countdown-timer/editor"; // helpers @import "utils/helpers/type"; diff --git a/src/styles/style.scss b/src/styles/style.scss index 5294582..231276b 100755 --- a/src/styles/style.scss +++ b/src/styles/style.scss @@ -99,6 +99,7 @@ @import "components/logo-list/main"; @import "components/post-grid/main"; @import "components/media-aside/main"; +@import "components/countdown-timer/main"; // Pages @import "pages/home";