Skip to content

Commit a1d39f3

Browse files
authored
Merge pull request #95 from medyo/refactor/typescript-analytics
Refactor/typescript analytics
2 parents 0bbb832 + 1c3b354 commit a1d39f3

36 files changed

Lines changed: 4587 additions & 3949 deletions

craco.config.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
1+
const path = require('path')
2+
13
module.exports = {
24
webpack: {
5+
alias: {
6+
'@': path.resolve(__dirname, 'src'),
7+
},
38
configure: {
49
output: {
510
filename: 'static/js/[name].js',

package.json

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
"version": "1.1.0",
44
"private": false,
55
"dependencies": {
6-
"@amplitude/analytics-browser": "^1.5.3",
6+
"@amplitude/analytics-browser": "^1.5.5",
7+
"@craco/craco": "^6.4.5",
78
"@testing-library/jest-dom": "^5.11.4",
89
"@testing-library/react": "^11.1.0",
910
"@testing-library/user-event": "^12.1.10",
@@ -34,7 +35,7 @@
3435
},
3536
"proxy": "https://api.hackertab.dev/",
3637
"scripts": {
37-
"start": "react-scripts start",
38+
"start": "craco start",
3839
"web-build": "REACT_APP_WEB_BUILD=1 CI= react-scripts --max_old_space_size=3072 build",
3940
"build": "./script/build.sh",
4041
"stores-build": "./script/stores_build.sh",
@@ -51,5 +52,13 @@
5152
"last 1 firefox version",
5253
"last 1 safari version"
5354
]
55+
},
56+
"devDependencies": {
57+
"@types/chrome": "^0.0.198",
58+
"@types/jest": "^29.1.2",
59+
"@types/node": "^18.11.0",
60+
"@types/react": "^18.0.21",
61+
"@types/react-dom": "^18.0.6",
62+
"typescript": "^4.8.4"
5463
}
5564
}

public/background.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
}
44
);*/
55

6-
const uninstallUrl = `https://hackertab.dev/uninstall.html`;
6+
const uninstallUrl = `https://hackertab.dev/uninstall.html`
77
if (chrome.runtime.setUninstallURL) {
8-
chrome.runtime.setUninstallURL(uninstallUrl);
8+
chrome.runtime.setUninstallURL(uninstallUrl)
99
}

public/manifest.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
2-
"name": "Hackertab.dev",
3-
"description": "The Developer’s Homepage",
4-
"version": "1.14.0",
2+
"name": "Hackertab.dev - developer news",
3+
"description": "All developer news in one tab",
4+
"version": "1.14.1",
55
"manifest_version": 2,
66
"chrome_url_overrides": {
77
"newtab": "index.html"

script/stores_build.sh

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,7 @@ firefox_build() {
2727
export INLINE_RUNTIME_CHUNK=false
2828
export GENERATE_SOURCEMAP=false
2929

30-
yarn global add @craco/craco
31-
craco build
30+
yarn build
3231

3332
mkdir -p dist
3433
cp -r build/* dist

src/App.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,13 @@ import './App.css'
33
import ConfigurationContext from './configuration/ConfigurationContext'
44
import Footer from './components/Footer'
55
import Header from './components/Header'
6-
import { trackPageView } from './utils/Analytics'
76
import BookmarksSidebar from './bookmark/BookmarksSidebar'
87
import MarketingBanner from './components/MarketingBanner'
98
import ScrollCardsNavigator from './components/ScrollCardsNavigator'
109
import AppContentLayout from './components/AppContentLayout'
1110
import 'react-contexify/dist/ReactContexify.css'
1211
import PreferencesContext from './preferences/PreferencesContext'
13-
import { initAnalytics } from './utils/Analytics'
12+
import { setupAnalytics, trackPageView, setupIdentification } from 'src/lib/analytics'
1413

1514
function App() {
1615
const { marketingBannerConfig = {}, feedbackWidget } = useContext(ConfigurationContext)
@@ -19,7 +18,8 @@ function App() {
1918
const { dispatcher, ...state } = useContext(PreferencesContext)
2019

2120
useEffect(() => {
22-
initAnalytics()
21+
setupAnalytics()
22+
setupIdentification(state)
2323
trackPageView('home')
2424
}, [])
2525

src/bookmark/BookmarksSidebar.js

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,29 +8,42 @@ import { ProSidebar, Menu, MenuItem, SubMenu, SidebarHeader, SidebarContent } fr
88
import 'react-pro-sidebar/dist/css/styles.css';
99
import PreferencesContext from '../preferences/PreferencesContext';
1010
import CardLink from "../components/CardLink";
11-
import { trackUnbookmarkFrom } from "../utils/Analytics"
12-
11+
import { trackLinkUnBookmark, Attributes } from 'src/lib/analytics'
1312

1413
const BookmarkItem = ({ item, appendRef = true }) => {
1514
const { dispatcher } = useContext(PreferencesContext)
15+
const analyticsAttrs = {
16+
[Attributes.TRIGERED_FROM]: 'bookmarks',
17+
[Attributes.TITLE]: item.title,
18+
[Attributes.LINK]: item.url,
19+
[Attributes.SOURCE]: item.source,
20+
}
1621
const unBookmark = () => {
1722
dispatcher({ type: 'unBookmarkItem', value: item })
18-
trackUnbookmarkFrom(item.source)
23+
trackLinkUnBookmark(analyticsAttrs)
1924
}
2025
return (
2126
<MenuItem
22-
suffix={<span className="unbookmarkBtn" onClick={unBookmark}><TiDelete /></span>}
23-
>
24-
<CardLink link={item.url} appendRef={appendRef}>{`${item.title}`}</CardLink>
27+
suffix={
28+
<span className="unbookmarkBtn" onClick={unBookmark}>
29+
<TiDelete />
30+
</span>
31+
}>
32+
<CardLink
33+
link={item.url}
34+
appendRef={appendRef}
35+
analyticsAttributes={analyticsAttrs}
36+
>
37+
{`${item.title}`}
38+
</CardLink>
2539
</MenuItem>
2640
)
2741
}
2842

2943
function BookmarksSidebar({ showSidebar, onClose }) {
3044

3145
const { userBookmarks = [] } = useContext(PreferencesContext)
32-
const githubBookmarks = userBookmarks.filter(bm => bm.source == "github")
33-
const jobsBookmarks = userBookmarks.filter(bm => bm.source == "jobs")
46+
const githubBookmarks = userBookmarks.filter((bm) => bm.source == 'github')
3447
const newsBookmarks = userBookmarks.filter(
3548
(bm) =>
3649
[

src/cards/ConferencesCard.js

Lines changed: 59 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,56 @@
11
import React, { useContext, useEffect, useState } from 'react'
2-
import { HiTicket } from 'react-icons/hi';
3-
import CardComponent from "../components/CardComponent";
4-
import ListComponent from "../components/ListComponent";
2+
import CardComponent from '../components/CardComponent'
3+
import ListComponent from '../components/ListComponent'
54
import confstechApi from '../services/confstech'
6-
import { MdAccessTime } from "react-icons/md"
7-
import { flag } from 'country-emoji';
8-
import { IoIosPin } from "react-icons/io"
9-
import { RiCalendarEventFill } from "react-icons/ri";
5+
import { MdAccessTime } from 'react-icons/md'
6+
import { flag } from 'country-emoji'
7+
import { IoIosPin } from 'react-icons/io'
8+
import { RiCalendarEventFill } from 'react-icons/ri'
109
import PreferencesContext from '../preferences/PreferencesContext'
11-
import CardLink from "../components/CardLink";
10+
import CardLink from '../components/CardLink'
1211
import CardItemWithActions from '../components/CardItemWithActions'
13-
import ColoredLanguagesBadge from "../components/ColoredLanguagesBadge"
12+
import ColoredLanguagesBadge from '../components/ColoredLanguagesBadge'
13+
import { Attributes } from 'src/lib/analytics'
1414

15-
16-
const ConferenceItem = ({ conf, index, analyticsTag }) => {
17-
15+
const ConferenceItem = ({ conf, index }) => {
1816
const { listingMode } = useContext(PreferencesContext)
1917

2018
const formatConfsDate = (date) => {
21-
const monthNames = ["January", "February", "March", "April", "May", "June",
22-
"July", "August", "September", "October", "November", "December"
23-
];
24-
25-
return `${monthNames[date.getMonth()]} ${("0" + date.getDate()).slice(-2)}`
19+
const monthNames = [
20+
'January',
21+
'February',
22+
'March',
23+
'April',
24+
'May',
25+
'June',
26+
'July',
27+
'August',
28+
'September',
29+
'October',
30+
'November',
31+
'December',
32+
]
2633

34+
return `${monthNames[date.getMonth()]} ${('0' + date.getDate()).slice(-2)}`
2735
}
2836

2937
const ConferenceLocation = () => {
30-
return (
31-
conf.online ?
32-
"🌐 Online" :
33-
`${flag(conf.country.replace(/[^a-zA-Z ]/g, ""))} ${conf.city}`
34-
)
38+
return conf.online
39+
? '🌐 Online'
40+
: `${flag(conf.country.replace(/[^a-zA-Z ]/g, ''))} ${conf.city}`
3541
}
3642

3743
const ConferenceDate = () => {
38-
let value = ""
44+
let value = ''
3945
if (conf.startDate) {
4046
value = `${formatConfsDate(conf.startDate)}`
4147
}
4248
if (conf.endDate && conf.endDate > conf.startDate) {
4349
value = `${value} - ${
44-
conf.endDate.getMonth() === conf.startDate.getMonth() ?
45-
("0" + conf.endDate.getDate()).slice(-2)
50+
conf.endDate.getMonth() === conf.startDate.getMonth()
51+
? ('0' + conf.endDate.getDate()).slice(-2)
4652
: formatConfsDate(conf.endDate)
47-
}`
53+
}`
4854
}
4955
return value
5056
}
@@ -54,36 +60,47 @@ const ConferenceItem = ({ conf, index, analyticsTag }) => {
5460
index={index}
5561
key={index}
5662
item={{ ...conf, title: conf.name }}
57-
cardItem={(
63+
cardItem={
5864
<>
59-
<CardLink link={conf.url} analyticsSource={analyticsTag}>
60-
<RiCalendarEventFill className={"rowTitleIcon"} />
65+
<CardLink
66+
link={conf.url}
67+
analyticsAttributes={{
68+
[Attributes.TRIGERED_FROM]: 'card',
69+
[Attributes.TITLE]: conf.name,
70+
[Attributes.LINK]: conf.url,
71+
[Attributes.SOURCE]: 'conferences',
72+
}}>
73+
<RiCalendarEventFill className={'rowTitleIcon'} />
6174
{conf.name}
6275
</CardLink>
63-
{
64-
listingMode === "normal" ?
76+
{listingMode === 'normal' ? (
6577
<>
6678
<div className="rowDescription">
67-
<span className="rowItem"><IoIosPin className="rowItemIcon" /> {ConferenceLocation()}</span>
68-
<span className="rowItem"><MdAccessTime className="rowItemIcon" /> {ConferenceDate()}</span>
79+
<span className="rowItem">
80+
<IoIosPin className="rowItemIcon" /> {ConferenceLocation()}
81+
</span>
82+
<span className="rowItem">
83+
<MdAccessTime className="rowItemIcon" /> {ConferenceDate()}
84+
</span>
6985
</div>
7086
<div className="rowDetails">
7187
<ColoredLanguagesBadge languages={[conf.tag.value]} />
7288
</div>
73-
</> :
89+
</>
90+
) : (
7491
<div className="rowDescription">
75-
<span className="rowItem"><MdAccessTime className="rowItemIcon" /> {ConferenceDate()}</span>
92+
<span className="rowItem">
93+
<MdAccessTime className="rowItemIcon" /> {ConferenceDate()}
94+
</span>
7695
</div>
77-
}
78-
96+
)}
7997
</>
80-
)}
98+
}
8199
/>
82100
)
83101
}
84102

85-
86-
function ConferencesCard({ label, icon, analyticsTag, withAds }) {
103+
function ConferencesCard({ label, icon, withAds }) {
87104
const preferences = useContext(PreferencesContext)
88105
const { userSelectedTags = [] } = preferences
89106
const [refresh, setRefresh] = useState(true)
@@ -120,7 +137,7 @@ function ConferencesCard({ label, icon, analyticsTag, withAds }) {
120137
}
121138

122139
const renderItem = (item, index) => (
123-
<ConferenceItem conf={item} key={`cf-${index}`} index={index} analyticsTag={analyticsTag} />
140+
<ConferenceItem conf={item} key={`cf-${index}`} index={index} />
124141
)
125142

126143
return (
@@ -138,4 +155,4 @@ function ConferencesCard({ label, icon, analyticsTag, withAds }) {
138155
)
139156
}
140157

141-
export default ConferencesCard
158+
export default ConferencesCard

src/cards/DevToCard.js

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,12 @@ import ColoredLanguagesBadge from '../components/ColoredLanguagesBadge'
1313
import SelectableCard from '../components/SelectableCard'
1414
import { GLOBAL_TAG, MY_LANGUAGES_TAG, MAX_MERGED_ITEMS_PER_LANGUAGE } from '../Constants'
1515
import { mergeMultipleDataSources } from '../utils/DataUtils'
16-
import { trackCardLanguageChange } from '../utils/Analytics'
16+
import { trackCardLanguageSelect } from 'src/lib/analytics'
17+
import { Attributes } from 'src/lib/analytics'
1718

1819
const DT_MENU_LANGUAGE_ID = 'DT_MENU_LANGUAGE_ID'
1920

20-
const ArticleItem = ({ item, index, analyticsTag }) => {
21+
const ArticleItem = ({ item, index, selectedLanguage }) => {
2122
const { listingMode } = useContext(PreferencesContext)
2223

2324
return (
@@ -28,7 +29,16 @@ const ArticleItem = ({ item, index, analyticsTag }) => {
2829
item={item}
2930
cardItem={
3031
<>
31-
<CardLink link={item.url} analyticsSource={analyticsTag}>
32+
<CardLink
33+
link={item.url}
34+
analyticsAttributes={{
35+
[Attributes.TRIGERED_FROM]: 'card',
36+
[Attributes.POINTS]: item.public_reactions_count,
37+
[Attributes.TITLE]: item.title,
38+
[Attributes.LINK]: item.url,
39+
[Attributes.SOURCE]: 'devto',
40+
[Attributes.LANGUAGE]: selectedLanguage?.value,
41+
}}>
3242
{listingMode === 'compact' && (
3343
<div className="counterWrapper">
3444
<AiOutlineLike />
@@ -126,7 +136,12 @@ function DevToCard({ analyticsTag, label, icon, withAds }) {
126136
}
127137

128138
const renderItem = (item, index) => (
129-
<ArticleItem item={item} key={`at-${index}`} index={index} analyticsTag={analyticsTag} />
139+
<ArticleItem
140+
item={item}
141+
key={`at-${index}`}
142+
index={index}
143+
selectedLanguage={selectedLanguage}
144+
/>
130145
)
131146

132147
function HeaderTitle() {
@@ -140,7 +155,7 @@ function DevToCard({ analyticsTag, label, icon, withAds }) {
140155
setSelectedTag={setSelectedLanguage}
141156
fallbackTag={GLOBAL_TAG}
142157
cardSettings={cardsSettings?.devto?.language}
143-
trackEvent={(tag) => trackCardLanguageChange('Devto', tag.value)}
158+
trackEvent={(tag) => trackCardLanguageSelect('Devto', tag.value)}
144159
data={userSelectedTags.map((tag) => ({
145160
label: tag.label,
146161
value: tag.value,

0 commit comments

Comments
 (0)