Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

T352298: Add custom tooltip #111

Merged
merged 24 commits into from
Apr 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
0239564
Add initial tooltip.js
medied Mar 27, 2024
2e50f7a
Initial computeTooltipPosition
medied Mar 28, 2024
9f475a2
Use Popover component
medied Apr 2, 2024
4e44ddd
Naming update
medied Apr 3, 2024
e24f898
Address warnings
medied Apr 3, 2024
da477e3
Move useEffect logic to a method for consistency
medied Apr 3, 2024
2c8c1f4
Use property to store tooltip count
medied Apr 8, 2024
089406b
Remove className
medied Apr 8, 2024
1c64954
Add guard to prevent displaying tooltip if toolbar is closed
medied Apr 8, 2024
cf59256
Address php linter
medied Apr 9, 2024
c9c1363
Proprogate property
medied Apr 9, 2024
03f74a5
Color popover arrow and add offset
medied Apr 10, 2024
5f28125
Rewrite endpoints set up as a function for consistency
medied Apr 10, 2024
a66986f
Address linter
medied Apr 10, 2024
62b3868
Increment property via window object
medied Apr 10, 2024
f8f3546
Merge branch 'T352298-tooltip-property' into T352298-tooltip
medied Apr 10, 2024
995ab80
Use camelCasing and improve readability
medied Apr 10, 2024
51680af
Concentrate all tooltip logic inside CustomTooltip for better code hy…
medied Apr 12, 2024
8e8b8bc
Disable selector-class-pattern globally
medied Apr 12, 2024
f83aa6d
Track whether the tooltip has been displayed for the full 5 secs
medied Apr 18, 2024
20ed74b
Address linter
medied Apr 18, 2024
afa3625
Clear timeouts if user clicks on W before the tooltip diplays
medied Apr 24, 2024
1661af8
Address linter
medied Apr 24, 2024
0e297c4
Add comments for php properties
medied Apr 29, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"XMLHttpRequest": true
},
"rules": {
"click-events-have-key-events": "off"
"click-events-have-key-events": "off",
"no-shadow": "off"
}
}
5 changes: 5 additions & 0 deletions .stylelintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"rules": {
"selector-class-pattern": null
}
}
11 changes: 9 additions & 2 deletions src/link/edit.js
Original file line number Diff line number Diff line change
@@ -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 {
Expand All @@ -10,6 +10,7 @@
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' );
Expand Down Expand Up @@ -46,6 +47,7 @@
const startViewingPreview = () => setViewingPreview( true );
const stopViewingPreview = () => setViewingPreview( false );
const [ lastValue, setLastValue ] = useState( null );
const toolbarButtonRef = useRef();

const formatButtonClick = () => {
if ( isActive ) {
Expand Down Expand Up @@ -191,7 +193,7 @@
handleTextEdit();
setLastValue( value );
}
}, [ value ] );

Check warning on line 196 in src/link/edit.js

View workflow job for this annotation

GitHub Actions / build

React Hook useEffect has missing dependencies: 'handleTextEdit' and 'lastValue'. Either include them or remove the dependency array

return (
<>
Expand All @@ -199,12 +201,17 @@
<ToolbarGroup>
<ToolbarButton
icon={ generateWikipediaLogo( isActive ? 'white' : 'black' ) }
title={ formatTitle }
title={ __( 'Add Wikipedia Preview', 'wikipedia-preview' ) }
isActive={ isActive }
onClick={ formatButtonClick }
ref={ toolbarButtonRef }
/>
</ToolbarGroup>
</BlockControls>
<CustomTooltip
anchorRef={ toolbarButtonRef }
addingPreview={ addingPreview }
/>
{ addingPreview && (
<InlineEditUI
contentRef={ contentRef }
Expand Down
29 changes: 27 additions & 2 deletions src/link/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -303,9 +303,35 @@ body {
}
}

.wikipediapreview-edit-tooltip-popover {

&-content {
width: 190px;
height: 40px;
background: #36c;
color: #fff;
display: flex;
justify-content: center;
}

&-text {
align-self: center;
}

.components-popover__arrow {

&::before {
background-color: unset;
}
}
hueitan marked this conversation as resolved.
Show resolved Hide resolved
hueitan marked this conversation as resolved.
Show resolved Hide resolved

.components-popover__triangle-bg {
fill: #36c;
}
}

.wikipediapreview-edit-preview-popover {

/* stylelint-disable-next-line selector-class-pattern */
.components-popover__content {
background: unset;
border: unset;
Expand Down Expand Up @@ -392,7 +418,6 @@ body {
&.is-expanded {
background-color: rgba(0, 0, 0, 0.7);

/* stylelint-disable-next-line selector-class-pattern */
.components-popover__header {
visibility: hidden;
}
Expand Down
95 changes: 95 additions & 0 deletions src/link/tooltip.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/* global wikipediapreviewCustomTooltip */
import { __ } from '@wordpress/i18n';
import { Popover } from '@wordpress/components';
import { useEffect, useState } from '@wordpress/element';

export const CustomTooltip = ( {
anchorRef,
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();
}
}, [] );

Check warning on line 62 in src/link/tooltip.js

View workflow job for this annotation

GitHub Actions / build

React Hook useEffect has missing dependencies: 'tooltipDisplayedCount', 'tooltipDisplayedFullDuration', and 'waitOneSecThenDisplayTooltip'. Either include them or remove the dependency array

useEffect( () => {
// Clear all timeouts when unmounting
return () => {
clearTimeouts();
};
}, [ timeoutIds ] );

Check warning on line 69 in src/link/tooltip.js

View workflow job for this annotation

GitHub Actions / build

React Hook useEffect has a missing dependency: 'clearTimeouts'. Either include it or remove the dependency array

useEffect( () => {
if ( addingPreview ) {
clearTimeouts();
finishDisplayingTooltip();
}
}, [ addingPreview ] );

Check warning on line 76 in src/link/tooltip.js

View workflow job for this annotation

GitHub Actions / build

React Hook useEffect has missing dependencies: 'clearTimeouts' and 'finishDisplayingTooltip'. Either include them or remove the dependency array

return (
<div>
{ displayTooltip && (
<Popover
anchor={ anchorRef.current }
placement={ 'top' }
noArrow={ false }
offset={ 10 }
className="wikipediapreview-edit-tooltip-popover"
>
<div className="wikipediapreview-edit-tooltip-popover-content">
<p className="wikipediapreview-edit-tooltip-popover-text">{ __( 'Add Wikipedia Preview' ) }</p>
</div>
</Popover>
) }
</div>
);
};
100 changes: 100 additions & 0 deletions tooltip.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
<?php

/*
* The number of times the tooltip has been displayed, whether in full duration or not.
* This count can be incremented until we hit a limit (set on the client side).
*/
DEFINE( 'WIKIPEDIA_PREVIEW_TOOLTIP_DISPLAYED_COUNT', 'wikipediapreview_tooltip_count' );

/*
* Whether or not the tooltip has been displayed in full duration at least once,
* this acts as a boolean that's either 0 or 1. When set to 1, we infer the
* Wikipedia Preview plugin has been 'discovered' and hence we do not display it again
*/
DEFINE( 'WIKIPEDIA_PREVIEW_TOOLTIP_DISPLAYED_DURATION', 'wikipediapreview_tooltip_duration' );

function wikipediapreview_get_tooltip_count() {
return get_option(
WIKIPEDIA_PREVIEW_TOOLTIP_DISPLAYED_COUNT,
0
);
}

function wikipediapreview_increment_tooltip_count() {
$count = wikipediapreview_get_tooltip_count();
update_option(
WIKIPEDIA_PREVIEW_TOOLTIP_DISPLAYED_COUNT,
$count + 1
);
}

function wikipediapreview_update_tooltip_duration() {
update_option(
WIKIPEDIA_PREVIEW_TOOLTIP_DISPLAYED_DURATION,
1
);
}

// For debugging purposes
function wikipediapreview_reset_tooltip_properties() {
update_option(
WIKIPEDIA_PREVIEW_TOOLTIP_DISPLAYED_COUNT,
0
);
update_option(
WIKIPEDIA_PREVIEW_TOOLTIP_DISPLAYED_DURATION,
0
);
}


function wikipediapreview_set_rest_endpoint() {
register_rest_route(
'wikipediapreview/v1',
'/count/',
array(
'methods' => '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' );
1 change: 1 addition & 0 deletions wikipediapreview.php
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Loading