TopicsWidget.jsx (3573B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 3 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 import React from "react"; 6 import { actionCreators as ac } from "common/Actions.mjs"; 7 import { SafeAnchor } from "../SafeAnchor/SafeAnchor"; 8 import { ImpressionStats } from "../../DiscoveryStreamImpressionStats/ImpressionStats"; 9 import { connect } from "react-redux"; 10 11 export function _TopicsWidget(props) { 12 const { id, source, position, DiscoveryStream, dispatch } = props; 13 14 const { utmCampaign, utmContent, utmSource } = DiscoveryStream.experimentData; 15 16 let queryParams = `?utm_source=${utmSource}`; 17 if (utmCampaign && utmContent) { 18 queryParams += `&utm_content=${utmContent}&utm_campaign=${utmCampaign}`; 19 } 20 21 const topics = [ 22 { label: "Technology", name: "technology" }, 23 { label: "Science", name: "science" }, 24 { label: "Self-Improvement", name: "self-improvement" }, 25 { label: "Travel", name: "travel" }, 26 { label: "Career", name: "career" }, 27 { label: "Entertainment", name: "entertainment" }, 28 { label: "Food", name: "food" }, 29 { label: "Health", name: "health" }, 30 { 31 label: "Must-Reads", 32 name: "must-reads", 33 url: `https://getpocket.com/collections${queryParams}`, 34 }, 35 ]; 36 37 function onLinkClick(topic, positionInCard) { 38 if (dispatch) { 39 dispatch( 40 ac.DiscoveryStreamUserEvent({ 41 event: "CLICK", 42 source, 43 action_position: position, 44 value: { 45 card_type: "topics_widget", 46 topic, 47 ...(positionInCard || positionInCard === 0 48 ? { position_in_card: positionInCard } 49 : {}), 50 section_position: position, 51 }, 52 }) 53 ); 54 dispatch( 55 ac.ImpressionStats({ 56 source, 57 click: 0, 58 window_inner_width: props.windowObj.innerWidth, 59 window_inner_height: props.windowObj.innerHeight, 60 tiles: [ 61 { 62 id, 63 pos: position, 64 }, 65 ], 66 }) 67 ); 68 } 69 } 70 71 function mapTopicItem(topic, index) { 72 return ( 73 <li 74 key={topic.name} 75 className={topic.overflow ? "ds-topics-widget-list-overflow-item" : ""} 76 > 77 <SafeAnchor 78 url={ 79 topic.url || 80 `https://getpocket.com/explore/${topic.name}${queryParams}` 81 } 82 dispatch={dispatch} 83 onLinkClick={() => onLinkClick(topic.name, index)} 84 > 85 {topic.label} 86 </SafeAnchor> 87 </li> 88 ); 89 } 90 91 return ( 92 <div className="ds-topics-widget"> 93 <header className="ds-topics-widget-header">Popular Topics</header> 94 <hr /> 95 <div className="ds-topics-widget-list-container"> 96 <ul>{topics.map(mapTopicItem)}</ul> 97 </div> 98 <SafeAnchor 99 className="ds-topics-widget-button button primary" 100 url={`https://getpocket.com/${queryParams}`} 101 dispatch={dispatch} 102 onLinkClick={() => onLinkClick("more-topics")} 103 > 104 More Topics 105 </SafeAnchor> 106 <ImpressionStats 107 dispatch={dispatch} 108 rows={[ 109 { 110 id, 111 pos: position, 112 }, 113 ]} 114 source={source} 115 /> 116 </div> 117 ); 118 } 119 120 _TopicsWidget.defaultProps = { 121 windowObj: window, // Added to support unit tests 122 }; 123 124 export const TopicsWidget = connect(state => ({ 125 DiscoveryStream: state.DiscoveryStream, 126 }))(_TopicsWidget);