mirror of https://github.com/mue/mue.git
feat: locally store stats so users can see them (no ui yet)
This commit is contained in:
parent
1d44b2792e
commit
2dcaa5270d
|
@ -31,7 +31,7 @@ export default class App extends React.PureComponent {
|
|||
}
|
||||
});
|
||||
|
||||
window.analytics.tabLoad();
|
||||
window.stats.tabLoad();
|
||||
}
|
||||
|
||||
render() {
|
||||
|
|
|
@ -13,7 +13,7 @@ export default class ErrorBoundary extends React.PureComponent {
|
|||
|
||||
static getDerivedStateFromError(error) {
|
||||
console.log(error);
|
||||
window.analytics.postEvent('modal', 'Error occurred');
|
||||
window.stats.postEvent('modal', 'Error occurred');
|
||||
return {
|
||||
error: true
|
||||
};
|
||||
|
|
|
@ -27,7 +27,7 @@ export default class Modals extends React.PureComponent {
|
|||
this.setState({
|
||||
welcomeModal: true
|
||||
});
|
||||
window.analytics.postEvent('modal', 'Opened welcome');
|
||||
window.stats.postEvent('modal', 'Opened welcome');
|
||||
}
|
||||
|
||||
// hide refresh reminder once the user has refreshed the page
|
||||
|
@ -47,7 +47,7 @@ export default class Modals extends React.PureComponent {
|
|||
});
|
||||
|
||||
if (action !== false) {
|
||||
window.analytics.postEvent('modal', `Opened ${type.replace('Modal', '')}`);
|
||||
window.stats.postEvent('modal', `Opened ${type.replace('Modal', '')}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
export default function Lightbox(props) {
|
||||
window.analytics.postEvent('modal', 'Opened lightbox');
|
||||
window.stats.postEvent('modal', 'Opened lightbox');
|
||||
|
||||
return (
|
||||
<>
|
||||
|
|
|
@ -42,7 +42,7 @@ export default class Added extends React.PureComponent {
|
|||
},
|
||||
button: this.buttons.uninstall
|
||||
});
|
||||
window.analytics.postEvent('marketplace', 'Item viewed');
|
||||
window.stats.postEvent('marketplace', 'Item viewed');
|
||||
} else {
|
||||
this.setState({
|
||||
item: {}
|
||||
|
@ -60,7 +60,7 @@ export default class Added extends React.PureComponent {
|
|||
installed: JSON.parse(localStorage.getItem('installed'))
|
||||
});
|
||||
|
||||
window.analytics.postEvent('marketplace', 'Uninstall');
|
||||
window.stats.postEvent('marketplace', 'Uninstall');
|
||||
}
|
||||
|
||||
sortAddons(value, sendEvent) {
|
||||
|
@ -87,7 +87,7 @@ export default class Added extends React.PureComponent {
|
|||
});
|
||||
|
||||
if (sendEvent) {
|
||||
window.analytics.postEvent('marketplace', 'Sort');
|
||||
window.stats.postEvent('marketplace', 'Sort');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -68,7 +68,7 @@ export default class Marketplace extends React.PureComponent {
|
|||
button: button
|
||||
});
|
||||
|
||||
window.analytics.postEvent('marketplace-item', `${this.state.item.display_name} viewed`);
|
||||
window.stats.postEvent('marketplace-item', `${this.state.item.display_name} viewed`);
|
||||
} else {
|
||||
this.setState({
|
||||
item: {}
|
||||
|
@ -106,8 +106,8 @@ export default class Marketplace extends React.PureComponent {
|
|||
button: (type === 'install') ? this.buttons.uninstall : this.buttons.install
|
||||
});
|
||||
|
||||
window.analytics.postEvent('marketplace-item', `${this.state.item.display_name} ${(type === 'install' ? 'installed': 'uninstalled')}`);
|
||||
window.analytics.postEvent('marketplace', (type === 'install' ? 'Install': 'Uninstall'));
|
||||
window.stats.postEvent('marketplace-item', `${this.state.item.display_name} ${(type === 'install' ? 'installed': 'uninstalled')}`);
|
||||
window.stats.postEvent('marketplace', (type === 'install' ? 'Install': 'Uninstall'));
|
||||
}
|
||||
|
||||
sortMarketplace(value, sendEvent) {
|
||||
|
@ -134,7 +134,7 @@ export default class Marketplace extends React.PureComponent {
|
|||
});
|
||||
|
||||
if (sendEvent) {
|
||||
window.analytics.postEvent('marketplace', 'Sort');
|
||||
window.stats.postEvent('marketplace', 'Sort');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -164,7 +164,7 @@ export default class Marketplace extends React.PureComponent {
|
|||
|
||||
const featured = () => {
|
||||
const openFeatured = () => {
|
||||
window.analytics.postEvent('marketplace', 'Featured clicked');
|
||||
window.stats.postEvent('marketplace', 'Featured clicked');
|
||||
window.open(this.state.featured.buttonLink);
|
||||
}
|
||||
return (
|
||||
|
|
|
@ -10,7 +10,7 @@ export default function Sideload() {
|
|||
const install = (input) => {
|
||||
MarketplaceFunctions.install(input.type, input);
|
||||
toast(window.language.toasts.installed);
|
||||
window.analytics.postEvent('marketplace', 'Sideload');
|
||||
window.stats.postEvent('marketplace', 'Sideload');
|
||||
};
|
||||
|
||||
return (
|
||||
|
|
|
@ -21,7 +21,7 @@ export default class Checkbox extends React.PureComponent {
|
|||
checked: (this.state.checked === true) ? false : true
|
||||
});
|
||||
|
||||
window.analytics.postEvent('setting', `${this.props.name} ${(this.state.checked === true) ? 'enabled' : 'disabled'}`);
|
||||
window.stats.postEvent('setting', `${this.props.name} ${(this.state.checked === true) ? 'enabled' : 'disabled'}`);
|
||||
|
||||
if (this.props.element) {
|
||||
if (!document.querySelector(this.props.element)) {
|
||||
|
|
|
@ -22,7 +22,7 @@ export default class Dropdown extends React.PureComponent {
|
|||
return;
|
||||
}
|
||||
|
||||
window.analytics.postEvent('setting', `${this.props.name} from ${this.state.value} to ${value}`);
|
||||
window.stats.postEvent('setting', `${this.props.name} from ${this.state.value} to ${value}`);
|
||||
|
||||
this.setState({
|
||||
value: value,
|
||||
|
|
|
@ -29,7 +29,7 @@ export default class Radio extends React.PureComponent {
|
|||
value: value
|
||||
});
|
||||
|
||||
window.analytics.postEvent('setting', `${this.props.name} from ${this.state.value} to ${value}`);
|
||||
window.stats.postEvent('setting', `${this.props.name} from ${this.state.value} to ${value}`);
|
||||
|
||||
if (this.props.element) {
|
||||
if (!document.querySelector(this.props.element)) {
|
||||
|
|
|
@ -4,7 +4,7 @@ export default function ResetModal(props) {
|
|||
const language = window.language.modals.main.settings.sections.advanced.reset_modal;
|
||||
|
||||
const reset = () => {
|
||||
window.analytics.postEvent('setting', 'Reset');
|
||||
window.stats.postEvent('setting', 'Reset');
|
||||
SettingsFunctions.setDefaultSettings('reset');
|
||||
window.location.reload();
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ export default class Switch extends React.PureComponent {
|
|||
checked: (this.state.checked === true) ? false : true
|
||||
});
|
||||
|
||||
window.analytics.postEvent('setting', `${this.props.name} ${(this.state.checked === true) ? 'enabled' : 'disabled'}`);
|
||||
window.stats.postEvent('setting', `${this.props.name} ${(this.state.checked === true) ? 'enabled' : 'disabled'}`);
|
||||
|
||||
if (this.props.element) {
|
||||
if (!document.querySelector(this.props.element)) {
|
||||
|
|
|
@ -28,7 +28,7 @@ export default class AdvancedSettings extends React.PureComponent {
|
|||
});
|
||||
|
||||
toast(window.language.toasts.imported);
|
||||
window.analytics.postEvent('tab', 'Settings imported');
|
||||
window.stats.postEvent('tab', 'Settings imported');
|
||||
}
|
||||
|
||||
render() {
|
||||
|
|
|
@ -10,6 +10,9 @@ export default function ExperimentalSettings() {
|
|||
<h2>{experimental.title}</h2>
|
||||
<p>{experimental.warning}</p>
|
||||
<Checkbox name='animations' text={window.language.modals.main.settings.sections.appearance.animations} element='.other'/>
|
||||
<h3>Usage Stats</h3>
|
||||
<p>Allows you to see stats such as how many tabs you have opened, quotes favourited etc. It also sends this data anonymously to our<a className='modalLink' href='https://github.com/mue/umami'>umami</a> instance.</p>
|
||||
<Checkbox name='stats' text='Enable Usage Stats' element='.other'/>
|
||||
<h3>{experimental.developer}</h3>
|
||||
<Checkbox name='debug' text='Debug hotkey (Ctrl + #)' element='.other'/>
|
||||
<Slider title='Debug timeout' name='debugtimeout' min='0' max='5000' default='0' step='100' display=' miliseconds' element='.other' />
|
||||
|
|
|
@ -83,7 +83,7 @@ export default class OrderSettings extends React.PureComponent {
|
|||
|
||||
componentDidUpdate() {
|
||||
localStorage.setItem('order', JSON.stringify(this.state.items));
|
||||
window.analytics.postEvent('setting', 'Widget order');
|
||||
window.stats.postEvent('setting', 'Widget order');
|
||||
EventBus.dispatch('refresh', 'widgets');
|
||||
}
|
||||
|
||||
|
|
|
@ -104,7 +104,7 @@ export default class ColourSettings extends React.PureComponent {
|
|||
return newState;
|
||||
});
|
||||
|
||||
window.analytics.postEvent('setting', 'Changed backgroundtype from colour to gradient');
|
||||
window.stats.postEvent('setting', 'Changed backgroundtype from colour to gradient');
|
||||
}
|
||||
|
||||
currentGradientSettings = () => {
|
||||
|
|
|
@ -14,7 +14,7 @@ export default class Tabs extends React.PureComponent {
|
|||
|
||||
onClick = (tab) => {
|
||||
if (tab !== this.state.currentTab) {
|
||||
window.analytics.postEvent('tab', `Changed ${this.state.currentTab} to ${tab}`);
|
||||
window.stats.postEvent('tab', `Changed ${this.state.currentTab} to ${tab}`);
|
||||
}
|
||||
|
||||
this.setState({
|
||||
|
|
|
@ -19,7 +19,7 @@ export default class Favourite extends React.PureComponent {
|
|||
this.setState({
|
||||
favourited: <StarIcon2 onClick={this.favourite} className='topicons' />
|
||||
});
|
||||
window.analytics.postEvent('feature', 'Background favourite');
|
||||
window.stats.postEvent('feature', 'Background favourite');
|
||||
} else {
|
||||
const url = document.getElementById('backgroundImage').style.backgroundImage.replace('url("', '').replace('")', '');
|
||||
|
||||
|
@ -38,7 +38,7 @@ export default class Favourite extends React.PureComponent {
|
|||
this.setState({
|
||||
favourited: <StarIcon onClick={this.favourite} className='topicons' />
|
||||
});
|
||||
window.analytics.postEvent('feature', 'Background unfavourite');
|
||||
window.stats.postEvent('feature', 'Background unfavourite');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -44,14 +44,14 @@ export default class Maximise extends React.PureComponent {
|
|||
});
|
||||
|
||||
this.setAttribute(0, 100);
|
||||
window.analytics.postEvent('feature', 'Background maximise');
|
||||
window.stats.postEvent('feature', 'Background maximise');
|
||||
} else {
|
||||
this.setState({
|
||||
hidden: false
|
||||
});
|
||||
|
||||
this.setAttribute(localStorage.getItem('blur'), localStorage.getItem('brightness'), true);
|
||||
window.analytics.postEvent('feature', 'Background unmaximise');
|
||||
window.stats.postEvent('feature', 'Background unmaximise');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ const downloadImage = async (info) => {
|
|||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
window.analytics.postEvent('feature', 'Background download');
|
||||
window.stats.postEvent('feature', 'Background download');
|
||||
};
|
||||
|
||||
export default function PhotoInformation(props) {
|
||||
|
|
|
@ -25,7 +25,7 @@ export default class Notes extends React.PureComponent {
|
|||
};
|
||||
|
||||
pin() {
|
||||
window.analytics.postEvent('feature', 'Notes pin');
|
||||
window.stats.postEvent('feature', 'Notes pin');
|
||||
document.getElementById('noteContainer').classList.toggle('visibilityshow');
|
||||
|
||||
if (localStorage.getItem('notesPinned') === 'true') {
|
||||
|
@ -36,7 +36,7 @@ export default class Notes extends React.PureComponent {
|
|||
}
|
||||
|
||||
copy() {
|
||||
window.analytics.postEvent('feature', 'Notes copied');
|
||||
window.stats.postEvent('feature', 'Notes copied');
|
||||
// this.state.notes doesnt work for some reason
|
||||
navigator.clipboard.writeText(localStorage.getItem('notes'));
|
||||
toast(window.language.toasts.notes);
|
||||
|
|
|
@ -32,7 +32,7 @@ export default class QuickLinks extends React.PureComponent {
|
|||
items: data
|
||||
});
|
||||
|
||||
window.analytics.postEvent('feature', 'Quicklink delete');
|
||||
window.stats.postEvent('feature', 'Quicklink delete');
|
||||
}
|
||||
|
||||
addLink = () => {
|
||||
|
@ -75,7 +75,7 @@ export default class QuickLinks extends React.PureComponent {
|
|||
url: ''
|
||||
});
|
||||
|
||||
window.analytics.postEvent('feature', 'Quicklink add');
|
||||
window.stats.postEvent('feature', 'Quicklink add');
|
||||
|
||||
this.toggleAdd();
|
||||
}
|
||||
|
|
|
@ -150,13 +150,13 @@ export default class Quote extends React.PureComponent {
|
|||
}
|
||||
|
||||
copyQuote = () => {
|
||||
window.analytics.postEvent('feature', 'Quote copied');
|
||||
window.stats.postEvent('feature', 'Quote copied');
|
||||
navigator.clipboard.writeText(`${this.state.quote} - ${this.state.author}`);
|
||||
toast(window.language.toasts.quote);
|
||||
}
|
||||
|
||||
tweetQuote = () => {
|
||||
window.analytics.postEvent('feature', 'Quote tweet');
|
||||
window.stats.postEvent('feature', 'Quote tweet');
|
||||
window.open(`https://twitter.com/intent/tweet?text=${this.state.quote} - ${this.state.author} on @getmue`, '_blank').focus();
|
||||
}
|
||||
|
||||
|
@ -173,7 +173,7 @@ export default class Quote extends React.PureComponent {
|
|||
});
|
||||
}
|
||||
|
||||
window.analytics.postEvent('feature', 'Quote favourite');
|
||||
window.stats.postEvent('feature', 'Quote favourite');
|
||||
}
|
||||
|
||||
init() {
|
||||
|
|
|
@ -44,7 +44,7 @@ export default class Search extends React.PureComponent {
|
|||
}
|
||||
|
||||
setTimeout(() => {
|
||||
window.analytics.postEvent('feature', 'Voice search');
|
||||
window.stats.postEvent('feature', 'Voice search');
|
||||
window.location.href = this.state.url + `?${this.state.query}=` + searchText.value;
|
||||
}, 1000);
|
||||
};
|
||||
|
@ -59,7 +59,7 @@ export default class Search extends React.PureComponent {
|
|||
value = document.getElementById('searchtext').value || 'mue fast';
|
||||
}
|
||||
|
||||
window.analytics.postEvent('feature', 'Search');
|
||||
window.stats.postEvent('feature', 'Search');
|
||||
window.location.href = this.state.url + `?${this.state.query}=` + value;
|
||||
}
|
||||
|
||||
|
|
10
src/index.js
10
src/index.js
|
@ -10,8 +10,8 @@ import 'react-toastify/dist/ReactToastify.min.css';
|
|||
|
||||
import '@fontsource/lexend-deca/400.css';
|
||||
|
||||
// this is opt-in btw
|
||||
import Analytics from './modules/helpers/analytics';
|
||||
// this is opt-in btw, allows you to see your stats etc
|
||||
import Stats from './modules/helpers/stats';
|
||||
|
||||
// language
|
||||
import merge from '@material-ui/utils/esm/deepmerge';
|
||||
|
@ -39,10 +39,10 @@ if (window.languagecode !== 'en_GB' || window.languagecode !== 'en_US') {
|
|||
}
|
||||
|
||||
window.constants = Constants;
|
||||
if (localStorage.getItem('analytics') === 'true' && localStorage.getItem('offlineMode') !== 'true') {
|
||||
window.analytics = new Analytics(window.constants.UMAMI_ID);
|
||||
if (localStorage.getItem('stats') === 'true' && localStorage.getItem('offlineMode') !== 'true') {
|
||||
window.stats = new Stats(window.constants.UMAMI_ID);
|
||||
} else {
|
||||
window.analytics = {
|
||||
window.stats = {
|
||||
tabLoad: () => '',
|
||||
postEvent: () => ''
|
||||
}
|
||||
|
|
|
@ -234,5 +234,13 @@
|
|||
{
|
||||
"name": "backgroundFilterAmount",
|
||||
"value": 0
|
||||
},
|
||||
{
|
||||
"name": "stats",
|
||||
"value": false
|
||||
},
|
||||
{
|
||||
"name": "statsData",
|
||||
"value": "{}"
|
||||
}
|
||||
]
|
||||
|
|
|
@ -27,7 +27,7 @@ export default class SettingsFunctions {
|
|||
settings[key] = localStorage.getItem(key);
|
||||
});
|
||||
saveFile(settings, 'mue-settings.json');
|
||||
window.analytics.postEvent('tab', 'Settings exported');
|
||||
window.stats.postEvent('tab', 'Settings exported');
|
||||
}
|
||||
|
||||
static setItem(key, value) {
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
export default class Analytics {
|
||||
export default class Stats {
|
||||
constructor(id) {
|
||||
this.id = id;
|
||||
this.domain = window.constants.UMAMI_DOMAIN;
|
||||
}
|
||||
|
||||
async postEvent(type, name) {
|
||||
const value = name.toLowerCase().replaceAll(' ', '-');
|
||||
|
||||
await fetch(this.domain + '/api/collect', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
|
@ -17,13 +19,29 @@ export default class Analytics {
|
|||
website: this.id,
|
||||
url: '/',
|
||||
event_type: type,
|
||||
event_value: name.toLowerCase().replaceAll(' ', '-'),
|
||||
event_value: value,
|
||||
hostname: 'localhost',
|
||||
language: localStorage.getItem('language').replace('_', '-'),
|
||||
screen: `${window.screen.width}x${window.screen.height}`
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
let data = JSON.parse(localStorage.getItem('statsData'));
|
||||
// tl;dr this creates the objects if they don't exist
|
||||
// this really needs a cleanup at some point
|
||||
if (!data[type] || !data[type][value]) {
|
||||
if (!data[type]) {
|
||||
data[type] = {};
|
||||
}
|
||||
|
||||
if (!data[type][value]) {
|
||||
data[type][value] = 1;
|
||||
}
|
||||
} else {
|
||||
data[type][value] = data[type][value] + 1;
|
||||
}
|
||||
localStorage.setItem('statsData', JSON.stringify(data));
|
||||
}
|
||||
|
||||
async tabLoad() {
|
||||
|
@ -45,5 +63,9 @@ export default class Analytics {
|
|||
}
|
||||
})
|
||||
});
|
||||
|
||||
let data = JSON.parse(localStorage.getItem('statsData'));
|
||||
data['tabs-opened'] = data['tabs-opened'] + 1 || 1;
|
||||
localStorage.setItem('statsData', JSON.stringify(data));
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue