Skip to content
This repository has been archived by the owner on Apr 29, 2022. It is now read-only.

Commit

Permalink
Integrate with Amplitude (#257)
Browse files Browse the repository at this point in the history
  • Loading branch information
quanglam2807 authored Nov 18, 2020
1 parent 7c47a5e commit 3408a69
Show file tree
Hide file tree
Showing 18 changed files with 317 additions and 183 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,5 +50,5 @@ jobs:
CI: true
CI_PULL_REQUEST: ${{ github.event_name == 'pull_request' }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
REACT_APP_LICENSE_SECRET: ${{ secrets.REACT_APP_LICENSE_SECRET }}
REACT_APP_AMPLITUDE_API_KEY: ${{ secrets.REACT_APP_AMPLITUDE_API_KEY }}
REACT_APP_OCR_SPACE_API_KEY: ${{ secrets.REACT_APP_OCR_SPACE_API_KEY }}
2 changes: 1 addition & 1 deletion .github/workflows/macos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,5 +52,5 @@ jobs:
CSC_KEY_PASSWORD: ${{ secrets.CSC_KEY_PASSWORD }}
CSC_LINK: ${{ secrets.CSC_LINK }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
REACT_APP_LICENSE_SECRET: ${{ secrets.REACT_APP_LICENSE_SECRET }}
REACT_APP_AMPLITUDE_API_KEY: ${{ secrets.REACT_APP_AMPLITUDE_API_KEY }}
REACT_APP_OCR_SPACE_API_KEY: ${{ secrets.REACT_APP_OCR_SPACE_API_KEY }}
2 changes: 1 addition & 1 deletion .github/workflows/windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,5 +49,5 @@ jobs:
CI: true
CI_PULL_REQUEST: ${{ github.event_name == 'pull_request' }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
REACT_APP_LICENSE_SECRET: ${{ secrets.REACT_APP_LICENSE_SECRET }}
REACT_APP_AMPLITUDE_API_KEY: ${{ secrets.REACT_APP_AMPLITUDE_API_KEY }}
REACT_APP_OCR_SPACE_API_KEY: ${{ secrets.REACT_APP_OCR_SPACE_API_KEY }}
11 changes: 7 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"repository": "https://github.com/translatium/translatium",
"author": {
"name": "Quang Lam",
"email": "quang.[email protected]"
"email": "quang.[email protected]"
},
"license": "MPL-2.0",
"engines": {
Expand All @@ -20,7 +20,7 @@
"test-ui": "react-scripts test --env=jsdom",
"eject": "react-scripts eject",
"dist": "yarn run build && babel-node dist.js",
"dist:no-sign": "cross-env CSC_IDENTITY_AUTO_DISCOVERY=false yarn dist",
"dist-dev": "cross-env CSC_IDENTITY_AUTO_DISCOVERY=false yarn dist",
"lint": "eslint ./src ./public ./*.js ./test --ext js",
"test": "mocha"
},
Expand All @@ -34,11 +34,13 @@
"fs-extra": "9.0.1",
"menubar": "8.0.2",
"node-fetch": "2.6.1",
"node-mac-permissions": "2.2.0"
"node-mac-permissions": "2.2.0",
"node-machine-id": "1.1.12"
},
"devDependencies": {
"@material-ui/core": "4.11.0",
"@material-ui/icons": "4.9.1",
"amplitude-js": "7.3.3",
"babel-cli": "6.26.0",
"babel-preset-env": "1.7.0",
"babel-preset-react": "6.24.1",
Expand All @@ -49,7 +51,7 @@
"cross-env": "7.0.2",
"del": "5.1.0",
"dotenv": "8.2.0",
"electron": "8.5.3",
"electron": "8.5.4",
"electron-builder": "22.9.1",
"electron-notarize": "1.0.0",
"eslint": "6.8.0",
Expand All @@ -74,6 +76,7 @@
"react-scripts": "3.4.4",
"redux": "4.0.5",
"redux-thunk": "2.3.0",
"uuid": "8.3.1",
"wait-on": "5.2.0"
},
"homepage": "./",
Expand Down
2 changes: 1 addition & 1 deletion public/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
const path = require('path');

const APP_NAME = 'Translatium';
const APP_TEAM = 'Quang Lam';
const APP_TEAM = 'WebCatalog Ltd';
const APP_URL = 'https://translatium.app';

const IMAGE_PATH = path.join(__dirname, '..', 'images');
Expand Down
2 changes: 2 additions & 0 deletions public/electron.js
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,8 @@ if (!gotTheLock) {
});
mainWindowState.manage(mainWindow);

mainWindow.webContents.openDevTools({ mode: 'detach' });

mainWindow.on('enter-full-screen', () => {
mainWindow.webContents.send('set-is-full-screen', true);
});
Expand Down
19 changes: 9 additions & 10 deletions public/index.html
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="Content-Security-Policy" content="default-src 'self' 'unsafe-inline' data: gap: https://translate.google.com https://translate.googleapis.com http://clients1.google.com http://clients2.google.com http://clients3.google.com http://clients4.google.com http://clients5.google.com https://api.ocr.space 'unsafe-eval' ws: ms-appx: filesystem blob:; style-src 'self' 'unsafe-inline'; media-src blob:; img-src 'self' data: content: blob:;">
<meta name="format-detection" content="telephone=no">
<meta name="msapplication-tap-highlight" content="no">
<head>
<meta charset="utf-8">
<meta name="format-detection" content="telephone=no">
<meta name="msapplication-tap-highlight" content="no">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<title>Translatium</title>
</head>
<body>
<div id="app"></div>
</body>
<title>Translatium</title>
</head>
<body>
<div id="app"></div>
</body>
</html>
5 changes: 4 additions & 1 deletion public/preload/shared.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,18 @@ const {
desktopCapturer,
} = require('electron');
const isDev = require('electron-is-dev');
const machineId = require('node-machine-id');

// Activate the Sentry Electron SDK as early as possible in every process.
if (!isDev) {
// eslint-disable-next-line global-require
require('../libs/sentry');
}

webFrame.setVisualZoomLevelLimits(1, 1);

window.remote = remote;
window.ipcRenderer = ipcRenderer;
window.desktopCapturer = desktopCapturer;

webFrame.setVisualZoomLevelLimits(1, 1);
window.machineId = machineId.machineIdSync();
19 changes: 19 additions & 0 deletions src/amplitude.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
import amplitude from 'amplitude-js';
import { v5 as uuidv5 } from 'uuid';

amplitude.getInstance().init(process.env.REACT_APP_AMPLITUDE_API_KEY);
amplitude.getInstance().setVersionName(window.remote.app.getVersion());

// custom device id based on WebCatalog code
// to have some control over device id
if (window.machineId) {
// unique namespace for translatium
const DEVICE_ID_NAMESPACE = '0a641322-b40e-4a51-aa9f-3c16e91f4db2';
const deviceId = uuidv5(window.machineId, DEVICE_ID_NAMESPACE);
amplitude.getInstance().setDeviceId(deviceId);
}

export default amplitude;
2 changes: 2 additions & 0 deletions src/components/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import WindowsTitleBar from './shared/windows-title-bar';

import Alert from './root/alert';
import DialogAbout from './root/dialog-about';
import TelemetryManager from './root/telemetry-manager';

import Home from './pages/home';
import History from './pages/history';
Expand Down Expand Up @@ -183,6 +184,7 @@ class App extends React.Component {
)}
<Alert />
<DialogAbout />
<TelemetryManager />
<Snackbar
open={snackbarOpen}
message={snackbarMessage || ''}
Expand Down
6 changes: 3 additions & 3 deletions src/components/root/dialog-about.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ const About = (props) => {
</Button>

<Button
onClick={() => requestOpenInBrowser('https://translatium.app/support?utm_source=translatium_app')}
onClick={() => requestOpenInBrowser('https://translatium.app/help?utm_source=translatium_app')}
>
{getLocale('support')}
</Button>
Expand All @@ -102,10 +102,10 @@ const About = (props) => {
<MLink
component="button"
variant="body2"
onClick={() => requestOpenInBrowser('https://github.com/quanglam2807')}
onClick={() => requestOpenInBrowser('https://webcatalog.app/about?utm_source=translatium_app')}
className={classes.link}
>
Quang Lam
WebCatalog Ltd
</MLink>
</Typography>
</DialogContent>
Expand Down
39 changes: 39 additions & 0 deletions src/components/root/telemetry-manager.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
import { useEffect } from 'react';
import PropTypes from 'prop-types';

import connectComponent from '../../helpers/connect-component';

import amplitude from '../../amplitude';

const TelemetryManager = ({ displayLanguage }) => {
useEffect(() => {
amplitude.getInstance().setUserProperties({
displayLanguage,
});
}, [displayLanguage]);

// run after setUserProperties
// https://blog.logrocket.com/post-hooks-guide-react-call-order
useEffect(() => {
amplitude.getInstance().logEvent('start app');
}, []);

return null;
};

TelemetryManager.propTypes = {
displayLanguage: PropTypes.string.isRequired,
};

const mapStateToProps = (state) => ({
displayLanguage: state.preferences.displayLanguage,
});

export default connectComponent(
TelemetryManager,
mapStateToProps,
null,
);
22 changes: 0 additions & 22 deletions src/helpers/is-valid-license-key.js

This file was deleted.

7 changes: 0 additions & 7 deletions src/helpers/validate.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
import isUrl from './is-url';
import isValidLicenseKey from './is-valid-license-key';
import getLocale from './get-locale';

const kits = {
Expand All @@ -19,12 +18,6 @@ const kits = {
}
return null;
},
licenseKey: (val, ruleVal, fieldName) => {
if (!isValidLicenseKey(val)) {
return getLocale('isNotValid').replace('{fieldName}', fieldName);
}
return null;
},
};

const validate = (changes, rules) => {
Expand Down
5 changes: 5 additions & 0 deletions src/state/pages/home/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import {
UPDATE_OUTPUT,
} from '../../../constants/actions';

import amplitude from '../../../amplitude';

import translateText from '../../../helpers/translate-text';
import phrasebookDb from '../../../helpers/phrasebook-db';
import { isInputLanguage, isOutputLanguage } from '../../../helpers/language-utils';
Expand Down Expand Up @@ -49,6 +51,9 @@ export const translate = (

translateText(inputLang, outputLang, inputText)
.then((result) => {
// only log when the action is successful
amplitude.getInstance().logEvent('translate text');

// Prevent slow request to display outdated info
const currentOutput = getState().pages.home.output;
if (currentOutput && currentOutput.identifier === identifier) {
Expand Down
9 changes: 9 additions & 0 deletions src/state/pages/ocr/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
/* global fetch FormData document Image */
import { UPDATE_OCR } from '../../../constants/actions';

import amplitude from '../../../amplitude';

import translateArray from '../../../helpers/translate-array';
import openFileToBlobAsync from '../../../helpers/open-file-to-blob-async';
import takeScreenshotToBlobAsync from '../../../helpers/take-screenshot-to-blob-async';
Expand Down Expand Up @@ -134,6 +136,13 @@ export const loadImage = (type = 'file') => (dispatch, getState) => {
? Math.max(Math.round((visibleWidth / maxWidth) * 1e2) / 1e2, 0.1)
: 1;

// only log when the action is successful
if (type === 'screenshot') {
amplitude.getInstance().logEvent('translate screenshot');
} else {
amplitude.getInstance().logEvent('translate image file');
}

dispatch({
type: UPDATE_OCR,
ocr: {
Expand Down
23 changes: 19 additions & 4 deletions src/state/root/router/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,22 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
import { CHANGE_ROUTE } from '../../../constants/actions';

export const changeRoute = (route) => ({
type: CHANGE_ROUTE,
route,
});
import amplitude from '../../../amplitude';

import {
ROUTE_HISTORY,
ROUTE_PHRASEBOOK,
} from '../../../constants/routes';

export const changeRoute = (route) => (dispatch) => {
if (route === ROUTE_HISTORY) {
amplitude.getInstance().logEvent('go to history page');
} else if (route === ROUTE_PHRASEBOOK) {
amplitude.getInstance().logEvent('go to phrasebook page');
}

dispatch({
type: CHANGE_ROUTE,
route,
});
};
Loading

0 comments on commit 3408a69

Please sign in to comment.