diff --git a/modules/search/class.jetpack-search.php b/modules/search/class.jetpack-search.php index f2b468d0aa652..b4f701673f276 100644 --- a/modules/search/class.jetpack-search.php +++ b/modules/search/class.jetpack-search.php @@ -204,6 +204,7 @@ public function load_assets() { $script_version = self::get_asset_version( $script_relative_path ); $script_path = plugins_url( $script_relative_path, JETPACK__PLUGIN_FILE ); wp_enqueue_script( 'jetpack-instant-search', $script_path, array(), $script_version, true ); + $this->load_and_initialize_tracks(); $widget_options = Jetpack_Search_Helpers::get_widgets_from_option(); if ( is_array( $widget_options ) ) { @@ -232,13 +233,13 @@ public function load_assets() { } // This is probably a temporary filter for testing the prototype. $options = array( - 'postTypes' => $post_type_labels, - 'siteId' => Jetpack::get_option( 'id' ), - 'widgets' => array_values( $widgets ), - 'sort' => $widget_options['sort'], - 'postTypeFilters' => $widget_options['post_types'], 'enableLoadOnScroll' => false, - 'locale' => str_replace( '_', '-', get_locale() ), + 'locale' => str_replace( '_', '-', get_locale() ), + 'postTypeFilters' => $widget_options['post_types'], + 'postTypes' => $post_type_labels, + 'siteId' => Jetpack::get_option( 'id' ), + 'sort' => $widget_options['sort'], + 'widgets' => array_values( $widgets ), ); /** * Customize Instant Search Options. @@ -265,6 +266,10 @@ public function load_assets() { } } + public function load_and_initialize_tracks() { + wp_enqueue_script( 'jp-tracks', '//stats.wp.com/w.js', array(), null, true ); + } + /** * Get the version number to use when loading the file. Allows us to bypass cache when developing. * diff --git a/modules/search/instant-search/components/search-result-minimal.jsx b/modules/search/instant-search/components/search-result-minimal.jsx index 0c4f2283668cf..dc2f4007f2bf0 100644 --- a/modules/search/instant-search/components/search-result-minimal.jsx +++ b/modules/search/instant-search/components/search-result-minimal.jsx @@ -9,6 +9,8 @@ import { h, Component } from 'preact'; * Internal dependencies */ import Gridicon from './gridicon'; +import arrayOverlap from '../lib/array-overlap'; +import { recordTrainTracksRender, recordTrainTracksInteract } from '../lib/tracks'; const ShortcodeTypes = { video: [ @@ -29,14 +31,28 @@ const ShortcodeTypes = { }; class SearchResultMinimal extends Component { - arrayOverlap( a1, a2 ) { - if ( ! Array.isArray( a1 ) ) { - a1 = [ a1 ]; - } - const intersection = a1.filter( value => a2.includes( value ) ); - return intersection.length !== 0; + componentDidMount() { + recordTrainTracksRender( this.getCommonTrainTracksProps() ); + } + + getCommonTrainTracksProps() { + return { + fetch_algo: this.props.result.railcar.fetch_algo, + fetch_position: this.props.result.railcar.fetch_position, + fetch_query: this.props.result.railcar.fetch_query, + railcar: this.props.result.railcar.railcar, + rec_blog_id: this.props.result.railcar.rec_blog_id, + rec_post_id: this.props.result.railcar.rec_post_id, + ui_algo: 'jetpack-instant-search-ui/v1', + ui_position: this.props.index, + }; } + onClick = () => { + // Send out analytics call + recordTrainTracksInteract( { ...this.getCommonTrainTracksProps(), action: 'click' } ); + }; + render() { const { result_type, fields, highlight } = this.props.result; const { locale = 'en-US' } = this.props; @@ -65,9 +81,9 @@ class SearchResultMinimal extends Component { } const noTags = tags.length === 0 && cats.length === 0; - const hasVideo = this.arrayOverlap( fields.shortcode_types, ShortcodeTypes.video ); - const hasAudio = this.arrayOverlap( fields.shortcode_types, ShortcodeTypes.audio ); - const hasGallery = this.arrayOverlap( fields.shortcode_types, ShortcodeTypes.gallery ); + const hasVideo = arrayOverlap( fields.shortcode_types, ShortcodeTypes.video ); + const hasAudio = arrayOverlap( fields.shortcode_types, ShortcodeTypes.audio ); + const hasGallery = arrayOverlap( fields.shortcode_types, ShortcodeTypes.gallery ); let postTypeIcon = null; switch ( fields.post_type ) { @@ -114,11 +130,10 @@ class SearchResultMinimal extends Component { { postTypeIcon } diff --git a/modules/search/instant-search/components/search-results.jsx b/modules/search/instant-search/components/search-results.jsx index c581af638e26b..ae1514b0d3b82 100644 --- a/modules/search/instant-search/components/search-results.jsx +++ b/modules/search/instant-search/components/search-results.jsx @@ -14,15 +14,22 @@ import { hasFilter } from '../lib/query-string'; import ScrollButton from './scroll-button'; class SearchResults extends Component { - render_result( result ) { + renderResult = ( result, index ) => { switch ( this.props.resultFormat ) { case 'engagement': case 'product': case 'minimal': default: - return ; + return ( + + ); } - } + }; render() { const { query } = this.props; @@ -63,7 +70,7 @@ class SearchResults extends Component { return (

{ headerText }

@@ -72,7 +79,7 @@ class SearchResults extends Component { { sprintf( __( 'No results for "%s"', 'jetpack' ), query ) }

) } - { results.map( result => this.render_result( result ) ) } + { results.map( this.renderResult ) } { this.props.hasNextPage && ( { render( @@ -29,6 +30,8 @@ const injectSearchApp = grabFocus => { document.addEventListener( 'DOMContentLoaded', function() { if ( !! window[ SERVER_OBJECT_NAME ] && 'siteId' in window[ SERVER_OBJECT_NAME ] ) { + initializeTracks(); + identifySite( window[ SERVER_OBJECT_NAME ].siteId ); injectSearchApp(); } } ); diff --git a/modules/search/instant-search/lib/array-overlap.js b/modules/search/instant-search/lib/array-overlap.js new file mode 100644 index 0000000000000..ecbeb861a25d0 --- /dev/null +++ b/modules/search/instant-search/lib/array-overlap.js @@ -0,0 +1,7 @@ +export default function arrayOverlap( a1, a2 ) { + if ( ! Array.isArray( a1 ) ) { + a1 = [ a1 ]; + } + const intersection = a1.filter( value => a2.includes( value ) ); + return intersection.length !== 0; +} diff --git a/modules/search/instant-search/lib/tracks.js b/modules/search/instant-search/lib/tracks.js new file mode 100644 index 0000000000000..c6ae157a2760f --- /dev/null +++ b/modules/search/instant-search/lib/tracks.js @@ -0,0 +1,21 @@ +const globalProperties = {}; + +export function initializeTracks() { + window._tkq = window._tkq || []; +} + +export function identifySite( siteId ) { + globalProperties.blog_id = siteId; +} + +export function recordEvent( eventName, properties ) { + window._tkq.push( [ 'recordEvent', eventName, { ...globalProperties, ...properties } ] ); +} + +export function recordTrainTracksRender( properties ) { + recordEvent( 'jetpack_instant_search_traintracks_render', properties ); +} + +export function recordTrainTracksInteract( properties ) { + recordEvent( 'jetpack_instant_search_traintracks_interact', properties ); +}