diff --git a/.eslintrc b/.eslintrc index 706e95f..25be9d5 100644 --- a/.eslintrc +++ b/.eslintrc @@ -5,6 +5,7 @@ "XMLHttpRequest": true }, "rules": { - "click-events-have-key-events": "off" + "click-events-have-key-events": "off", + "no-shadow": "off" } } diff --git a/.stylelintrc.json b/.stylelintrc.json new file mode 100644 index 0000000..f290422 --- /dev/null +++ b/.stylelintrc.json @@ -0,0 +1,5 @@ +{ + "rules": { + "selector-class-pattern": null + } +} diff --git a/src/link/edit.js b/src/link/edit.js index 08ea968..dc295fc 100644 --- a/src/link/edit.js +++ b/src/link/edit.js @@ -1,4 +1,4 @@ -import { useEffect, useState } from '@wordpress/element'; +import { useEffect, useState, useRef } from '@wordpress/element'; import { BlockControls } from '@wordpress/block-editor'; import { ToolbarGroup, ToolbarButton } from '@wordpress/components'; import { @@ -10,6 +10,7 @@ import { import { __ } from '@wordpress/i18n'; import { InlineEditUI } from './inline'; import { PreviewEditUI } from './preview'; +import { CustomTooltip } from './tooltip'; const formatType = 'wikipediapreview/link'; const formatTitle = __( 'Wikipedia Preview', 'wikipedia-preview' ); @@ -46,6 +47,7 @@ const Edit = ( { const startViewingPreview = () => setViewingPreview( true ); const stopViewingPreview = () => setViewingPreview( false ); const [ lastValue, setLastValue ] = useState( null ); + const toolbarButtonRef = useRef(); const formatButtonClick = () => { if ( isActive ) { @@ -199,12 +201,17 @@ const Edit = ( { + { addingPreview && ( { + const [ displayTooltip, setDisplayTooltip ] = useState( false ); + const [ timeoutIds, setTimeoutIds ] = useState( [] ); + const tooltipDisplayedFullDuration = useState( parseInt( wikipediapreviewCustomTooltip.tooltipDuration ) )[ 0 ]; + const tooltipDisplayedCount = useState( parseInt( wikipediapreviewCustomTooltip.tooltipCount ) )[ 0 ]; + const tooltipDisplayedLimit = 2; + + const updateStoredProperty = ( prop ) => { + fetch( `/wp-json/wikipediapreview/v1/${ prop }/`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + } ); + }; + + const finishDisplayingTooltip = () => { + setDisplayTooltip( false ); + wikipediapreviewCustomTooltip.tooltipDuration = 1; + updateStoredProperty( 'duration' ); + }; + + const clearTimeouts = () => { + timeoutIds.forEach( ( id ) => { + clearTimeout( id ); + } ); + }; + + const waitOneSecThenDisplayTooltip = () => { + const oneSecId = setTimeout( () => { + if ( anchorRef.current ) { + setDisplayTooltip( true ); + updateStoredProperty( 'count' ); + // Increment global tooltip count directly as well + // to ensure count is up to date in between page reloads + wikipediapreviewCustomTooltip.tooltipCount = tooltipDisplayedCount + 1; + waitFiveSecsThenHideTooltip(); + } + }, 1000 ); + setTimeoutIds( ( timeoutIds ) => [ ...timeoutIds, oneSecId ] ); + }; + + const waitFiveSecsThenHideTooltip = () => { + const fiveSecId = setTimeout( () => { + finishDisplayingTooltip(); + }, 5000 ); + setTimeoutIds( ( timeoutIds ) => [ ...timeoutIds, fiveSecId ] ); + }; + + useEffect( () => { + if ( tooltipDisplayedCount < tooltipDisplayedLimit && tooltipDisplayedFullDuration < 1 ) { + waitOneSecThenDisplayTooltip(); + } + }, [] ); + + useEffect( () => { + // Clear all timeouts when unmounting + return () => { + clearTimeouts(); + }; + }, [ timeoutIds ] ); + + useEffect( () => { + if ( addingPreview ) { + clearTimeouts(); + finishDisplayingTooltip(); + } + }, [ addingPreview ] ); + + return ( +
+ { displayTooltip && ( + +
+

{ __( 'Add Wikipedia Preview' ) }

+
+
+ ) } +
+ ); +}; diff --git a/tooltip.php b/tooltip.php new file mode 100644 index 0000000..f8788e1 --- /dev/null +++ b/tooltip.php @@ -0,0 +1,100 @@ + 'POST', + 'callback' => 'wikipediapreview_increment_tooltip_count', + ) + ); + register_rest_route( + 'wikipediapreview/v1', + '/duration/', + array( + 'methods' => 'POST', + 'callback' => 'wikipediapreview_update_tooltip_duration', + ) + ); + register_rest_route( + 'wikipediapreview/v1', + '/reset/', + array( + 'methods' => 'POST', + 'callback' => 'wikipediapreview_reset_tooltip_properties', + ) + ); +} + +function wikipediapreview_tooltip_enqueue_script() { + $src_link_dir = plugin_dir_url( __FILE__ ) . 'src/link'; + $no_dependencies = array(); + $in_footer = true; + + wp_enqueue_script( + 'wikipedia-preview-tooltip', + $src_link_dir . 'tooltip.js', + $no_dependencies, + WIKIPEDIA_PREVIEW_PLUGIN_VERSION, + $in_footer + ); + + $options = array( + 'tooltipCount' => wikipediapreview_get_tooltip_count(), + 'tooltipDuration' => get_option( WIKIPEDIA_PREVIEW_TOOLTIP_DISPLAYED_DURATION, 0 ), + ); + + wp_localize_script( 'wikipedia-preview-tooltip', 'wikipediapreviewCustomTooltip', $options ); +} + +add_action( 'enqueue_block_editor_assets', 'wikipediapreview_tooltip_enqueue_script' ); +add_action( 'rest_api_init', 'wikipediapreview_set_rest_endpoint' ); diff --git a/wikipediapreview.php b/wikipediapreview.php index e273e2c..2d94fef 100644 --- a/wikipediapreview.php +++ b/wikipediapreview.php @@ -166,5 +166,6 @@ function add_meta_links( $links_array, $plugin_file_name, $plugin_data, $status add_action( 'init', 'myguten_set_script_translations' ); add_action( 'init', 'register_detectlinks_postmeta' ); +require __DIR__ . '/tooltip.php'; require __DIR__ . '/banner.php'; require __DIR__ . '/intro.php';