Skip to content

Commit

Permalink
feat: google analytics 추가
Browse files Browse the repository at this point in the history
  • Loading branch information
tbvjaos510 committed Oct 23, 2019
1 parent 755f617 commit 29f4f7a
Show file tree
Hide file tree
Showing 29 changed files with 276 additions and 108 deletions.
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"jest.pathToJest": "npm run test:coverage --",
"jest.runAllTestsFirst": true
"jest.runAllTestsFirst": true,
"editor.formatOnSave": true
}
4 changes: 4 additions & 0 deletions @types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,7 @@ declare module NodeJS {
ENV: typeof ENV;
}
}

interface Window {
dataLayer: GoogleAnalyticsCode;
}
3 changes: 3 additions & 0 deletions jestSetup.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,6 @@ const Enzyme = require("enzyme");
const Adapter = require("enzyme-adapter-react-16");
// React 16 Enzyme adapter
Enzyme.configure({ adapter: new Adapter() });

// mock google analytics
window.ga = () => {};
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"license": "MIT",
"devDependencies": {
"@types/enzyme": "^3.9.3",
"@types/google.analytics": "^0.0.40",
"@types/jest": "^24.0.13",
"@types/naver-whale": "^0.0.0",
"@types/react": "^16.0.40",
Expand Down
33 changes: 33 additions & 0 deletions src/analytics/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
(function(i, s, o, g, r, a, m) {
i["GoogleAnalyticsObject"] = r;
(i[r] =
i[r] ||
function() {
(i[r].q = i[r].q || []).push(arguments);
}),
// @ts-ignore
(i[r].l = 1 * new Date());
(a = s.createElement(o)), (m = s.getElementsByTagName(o)[0]);
a.async = 1;
a.src = g;
m.parentNode.insertBefore(a, m);
})(
window,
document,
"script",
`https://www.google-analytics.com/analytics${ENV === "development" ? "_debug" : ""}.js`,
"ga"
);
ga("create", "UA-150779267-1", {
storage: "none",
clientId: ENV === "development" ? "localhost" : localStorage.getItem("_clientId")
});
if (ENV === "development") {
ga("set", "sendHitTask", null);
}
ga(function() {
window.localStorage.setItem("_clientId", ga.getAll()[0].get("clientId"));
});
ga("set", "dimension1", BROWSER);
ga("set", "checkProtocolTask", function() {}); // Removes failing protocol check. @see: http://stackoverflow.com/a/22152353/1958200
ga("require", "displayfeatures");
19 changes: 14 additions & 5 deletions src/background/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import RootStore from "../store";
import history from "./tab/history";
import onInstall from "./runtime/onInstall";
import onMessage from "./runtime/onMessage";
import { addContextClickListener, addLinkContext } from "../tools/contextMenu";
import '../analytics';

import RootStore from '../store';
import { addContextClickListener, addLinkContext } from '../tools/contextMenu';
import onInstall from './runtime/onInstall';
import onMessage from './runtime/onMessage';
import history from './tab/history';

const store = new RootStore(true, () => {
history(store.webtoon, store.option);
Expand All @@ -17,3 +19,10 @@ const store = new RootStore(true, () => {
});

onInstall(store.webtoon, store.option);

// analytics
if (BROWSER === "whale") {
whale.sidebarAction.onClicked.addListener(() => {
ga("send", "event", "extension", "whale-sidebar-clicked");
});
}
12 changes: 9 additions & 3 deletions src/background/runtime/onInstall.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
import WebtoonStore from "../../store/webtoon";
import OptionStore from "../../store/option";
import migration from "./migration";
import OptionStore from '../../store/option';
import WebtoonStore from '../../store/webtoon';
import migration from './migration';

export default function(webtoon: WebtoonStore, option: OptionStore) {
chrome.runtime.onInstalled.addListener(details => {
console.log(details);

if (details.reason === "install") {
console.log("Init Start");
ga("send", "event", "extension", "install", BROWSER);
webtoon.setVisitsFromChrome();
} else if (details.reason === "update") {
const currentVersion = chrome.runtime.getManifest().version;
ga("send", "event", {
eventCategory: "extension",
eventAction: "update",
eventLabel: `${details.previousVersion}>${currentVersion} (${BROWSER})`
});
if (details.previousVersion != currentVersion) {
console.log("update ", details.previousVersion, currentVersion);
if (BROWSER === "whale") {
Expand Down
8 changes: 4 additions & 4 deletions src/background/runtime/onMessage.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import WebtoonStore from "../../store/webtoon";
import OptionStore from "../../store/option";
import Link from "../../tools/link";
import { addContextClickListener } from "../../tools/contextMenu";
import OptionStore from '../../store/option';
import WebtoonStore from '../../store/webtoon';
import { addContextClickListener } from '../../tools/contextMenu';
import Link from '../../tools/link';

export interface ChromeMessage {
command?: "openTab" | "reload" | "addContextMenu";
Expand Down
5 changes: 3 additions & 2 deletions src/background/tab/utility.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { VisitType } from "../../store/webtoon";
import { VisitType } from '../../store/webtoon';

export function hiddenComment(tabId: number, isMobile: boolean) {
const code = `document.getElementById("${
Expand Down Expand Up @@ -105,10 +105,11 @@ export function displayHistory(
}`;
if (!tabId) {
eval(code);
} else
} else {
chrome.tabs.executeScript(tabId, {
code: code
});
}
});
}
}
3 changes: 2 additions & 1 deletion src/manifest.chrome.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,6 @@
"run_at": "document_end",
"all_frames": true
}
]
],
"content_security_policy": "script-src 'self' https://www.googletagmanager.com https://ssl.google-analytics.com https://www.google-analytics.com https://mustsee-earth.firebaseio.com; object-src 'self'"
}
3 changes: 2 additions & 1 deletion src/manifest.whale.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,6 @@
"run_at": "document_end",
"all_frames": true
}
]
],
"content_security_policy": "script-src 'self' https://www.googletagmanager.com https://ssl.google-analytics.com https://www.google-analytics.com https://mustsee-earth.firebaseio.com; object-src 'self'"
}
22 changes: 13 additions & 9 deletions src/popup/Popup.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
import * as React from "react";
import { Provider } from "mobx-react";
// Store Import
import Store from "../store";
import { Provider } from 'mobx-react';
import * as React from 'react';

import Wlink from "./components/Wlink";
import Switcher from "./components/Switcher";
import { Tabs } from "./Tabs";
import ErrorHandler from "./components/ErrorHandler";
import UpdateCheck from "./components/UpdateCheck";
import Store from '../store';
import ErrorHandler from './components/ErrorHandler';
import Switcher from './components/Switcher';
import UpdateCheck from './components/UpdateCheck';
import Wlink from './components/Wlink';
import { Tabs } from './Tabs';

// Store Import
const store = new Store(false);

export default class App extends React.Component {
componentDidMount() {
ga("send", "pageview");
}

render() {
return (
<Provider {...store}>
Expand Down
35 changes: 25 additions & 10 deletions src/popup/Tabs/ListDaily.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import * as React from "react";
import { observer, inject } from "mobx-react";
import OptionStore from "../../store/option";
import { weekDay, Week } from "../../tools/request";
import WebtoonStore from "../../store/webtoon";
import DailyItemList, { MovedEvent } from "../components/Daily/DailyItemList";
import { toJS } from "mobx";
import SearchWebtoon from "../components/Daily/SearchWebtoon";
import { toJS } from 'mobx';
import { inject, observer } from 'mobx-react';
import * as React from 'react';

import OptionStore from '../../store/option';
import WebtoonStore from '../../store/webtoon';
import { Week, weekDay } from '../../tools/request';
import DailyItemList, { MovedEvent } from '../components/Daily/DailyItemList';
import SearchWebtoon from '../components/Daily/SearchWebtoon';

export interface IListDailyProps {
option?: OptionStore;
Expand Down Expand Up @@ -105,14 +106,28 @@ export default class ListDaily extends React.Component<IListDailyProps, IListDai
>
{option.saveFavorate ? (
<li>
<a onClick={() => this.changeDay("favo")}></a>
<a
onClick={() => {
ga("send", "event", "ListDaily", "dayChanged", "favorate");
this.changeDay("favo");
}}
>
</a>
</li>
) : null}

{weekDay.map((week, index) => {
return (
<li key={week}>
<a onClick={() => this.changeDay(week)}>{this.day[index]}</a>
<a
onClick={() => {
ga("send", "event", "ListDaily", "dayChanged", week);
this.changeDay(week);
}}
>
{this.day[index]}
</a>
</li>
);
})}
Expand Down
10 changes: 5 additions & 5 deletions src/popup/Tabs/ListHistory.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import * as React from "react";
import { inject, observer } from "mobx-react";
import WebtoonStore from "../../store/webtoon";
import HistoryItem from "../components/History/HistoryItem";
import HistoryItemContext from "../components/History/HistoryItemContext";
import { inject, observer } from 'mobx-react';
import * as React from 'react';

import WebtoonStore from '../../store/webtoon';
import HistoryItem from '../components/History/HistoryItem';

export interface IListHistoryProps {
webtoon?: WebtoonStore;
Expand Down
24 changes: 12 additions & 12 deletions src/popup/Tabs/Option.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import * as React from "react";
import { observer, inject } from "mobx-react";
import OptionStore, { ChromeStore, WebtoonOrder, LinkTarget } from "../../store/option";
import WebtoonStore from "../../store/webtoon";
import Wlink from "../components/Wlink";
import RecentSetting from "../components/Setting/RecentSetting";
import WebtoonSetting from "../components/Setting/WebtoonSetting";
import PageSetting from "../components/Setting/PageSetting";
import SpecialSetting from "../components/Setting/SpecialSetting";
import StorageSetting from "../components/Setting/StorageSetting";
import DevelopInfo from "../components/Setting/DevelopInfo";
import SettingButton from "../components/Setting/Inputs/SettingButton";
import { inject, observer } from 'mobx-react';
import * as React from 'react';

import OptionStore from '../../store/option';
import DevelopInfo from '../components/Setting/DevelopInfo';
import SettingButton from '../components/Setting/Inputs/SettingButton';
import PageSetting from '../components/Setting/PageSetting';
import RecentSetting from '../components/Setting/RecentSetting';
import SpecialSetting from '../components/Setting/SpecialSetting';
import StorageSetting from '../components/Setting/StorageSetting';
import WebtoonSetting from '../components/Setting/WebtoonSetting';
import Wlink from '../components/Wlink';

export interface IOptionProps {
option?: OptionStore;
Expand Down
40 changes: 30 additions & 10 deletions src/popup/components/Daily/DailyItem.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import * as React from "react";
import { WebtoonInfoType } from "../../../tools/request";
import Wlink from "../Wlink";
import OptionStore from "../../../store/option";
import { observer, inject } from "mobx-react";
import WebtoonStore from "../../../store/webtoon";
import * as distance from "date-fns/distance_in_words_to_now";
import * as ko from "date-fns/locale/ko";
import * as distance from 'date-fns/distance_in_words_to_now';
import * as ko from 'date-fns/locale/ko';
import { inject, observer } from 'mobx-react';
import * as React from 'react';

import OptionStore from '../../../store/option';
import WebtoonStore from '../../../store/webtoon';
import { WebtoonInfoType } from '../../../tools/request';
import Wlink from '../Wlink';

export interface IDailyItemProps {
item: WebtoonInfoType;
option?: OptionStore;
Expand All @@ -20,8 +22,10 @@ export default class DailyItem extends React.Component<IDailyItemProps, any> {
const { webtoon, item } = this.props;
const idx = webtoon.starWebtoons.indexOf(item.id);
if (idx != -1) {
ga("send", "event", "DailyItem", "unStarWebtoon", item.id);
webtoon.starWebtoons.splice(idx, 1);
} else {
ga("send", "event", "DailyItem", "starWebtoon", item.id);
webtoon.starWebtoons.push(item.id);
}

Expand All @@ -41,7 +45,18 @@ export default class DailyItem extends React.Component<IDailyItemProps, any> {
addSuffix: true
}) + "에 봄";
return (
<Wlink link={`https://comic.naver.com/webtoon/detail.nhn?titleId=${find.id}&no=${find.no}`}>
<Wlink
link={`https://comic.naver.com/webtoon/detail.nhn?titleId=${find.id}&no=${find.no}`}
onClick={() => {
ga(
"send",
"event",
"DailyItem",
"openRecentWebtoon",
`${item.title}(${find.id}/${find.no})`
);
}}
>
<a className="uk-link-muted webtoon-link" uk-tooltip={timeLocale}>
{find.noname}
</a>
Expand All @@ -63,7 +78,12 @@ export default class DailyItem extends React.Component<IDailyItemProps, any> {
{item.isRest ? <em className="ico break" /> : null}
</div>
<div className="uk-card-body uk-padding-small uk-padding-remove-right uk-padding-remove-left">
<Wlink link={item.link}>
<Wlink
link={item.link}
onClick={() => {
ga("send", "event", "DailyItem", "openWebtoon", `${item.title}(${item.id})`);
}}
>
<a className="uk-link-muted webtoon-link">{item.title}</a>
</Wlink>
<br />
Expand Down
20 changes: 15 additions & 5 deletions src/popup/components/ErrorHandler.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import * as React from "react";
import Wlink from "./Wlink";
import { observer, inject } from "mobx-react";
import OptionStore from "../../store/option";
import { inject, observer } from 'mobx-react';
import * as React from 'react';

import OptionStore from '../../store/option';
import Wlink from './Wlink';

export interface IErrorHandlerProps {
option?: OptionStore;
Expand Down Expand Up @@ -36,6 +37,9 @@ export default class ErrorHandler extends React.Component<IErrorHandlerProps, IE
}

componentDidCatch(error, info) {
ga("send", "exception", {
exDescription: (error && (error.message || error)) || "unknown"
});
this.setState({ hasError: true });
console.log(error, info);
}
Expand Down Expand Up @@ -63,7 +67,13 @@ export default class ErrorHandler extends React.Component<IErrorHandlerProps, IE
<a href="#">오류신고</a>
</Wlink>
{" "}
<a href="#" onClick={() => this.resetStore()}>
<a
href="#"
onClick={() => {
ga("send", "event", "popup", "resetStore");
this.resetStore();
}}
>
데이터 초기화
</a>
를 해주시기 바랍니다.
Expand Down
Loading

0 comments on commit 29f4f7a

Please sign in to comment.