diff --git a/src/App.jsx b/src/App.jsx
index 81b5e59c..4135e71d 100644
--- a/src/App.jsx
+++ b/src/App.jsx
@@ -31,7 +31,7 @@ export default class App extends React.PureComponent {
}
});
- window.analytics.tabLoad();
+ window.stats.tabLoad();
}
render() {
diff --git a/src/components/modals/ErrorBoundary.jsx b/src/components/modals/ErrorBoundary.jsx
index f888927a..90fde9fa 100644
--- a/src/components/modals/ErrorBoundary.jsx
+++ b/src/components/modals/ErrorBoundary.jsx
@@ -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
};
diff --git a/src/components/modals/Modals.jsx b/src/components/modals/Modals.jsx
index 439bc207..9948a630 100644
--- a/src/components/modals/Modals.jsx
+++ b/src/components/modals/Modals.jsx
@@ -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', '')}`);
}
}
diff --git a/src/components/modals/main/marketplace/Lightbox.jsx b/src/components/modals/main/marketplace/Lightbox.jsx
index d430bc6f..1a552e1f 100644
--- a/src/components/modals/main/marketplace/Lightbox.jsx
+++ b/src/components/modals/main/marketplace/Lightbox.jsx
@@ -1,5 +1,5 @@
export default function Lightbox(props) {
- window.analytics.postEvent('modal', 'Opened lightbox');
+ window.stats.postEvent('modal', 'Opened lightbox');
return (
<>
diff --git a/src/components/modals/main/marketplace/sections/Added.jsx b/src/components/modals/main/marketplace/sections/Added.jsx
index a85a73bf..71ca2c90 100644
--- a/src/components/modals/main/marketplace/sections/Added.jsx
+++ b/src/components/modals/main/marketplace/sections/Added.jsx
@@ -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');
}
}
diff --git a/src/components/modals/main/marketplace/sections/Marketplace.jsx b/src/components/modals/main/marketplace/sections/Marketplace.jsx
index 699fe3b7..1de2b55d 100644
--- a/src/components/modals/main/marketplace/sections/Marketplace.jsx
+++ b/src/components/modals/main/marketplace/sections/Marketplace.jsx
@@ -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 (
diff --git a/src/components/modals/main/marketplace/sections/Sideload.jsx b/src/components/modals/main/marketplace/sections/Sideload.jsx
index eb6d8904..0586d0cb 100644
--- a/src/components/modals/main/marketplace/sections/Sideload.jsx
+++ b/src/components/modals/main/marketplace/sections/Sideload.jsx
@@ -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 (
diff --git a/src/components/modals/main/settings/Checkbox.jsx b/src/components/modals/main/settings/Checkbox.jsx
index 037a9e5b..0652d563 100644
--- a/src/components/modals/main/settings/Checkbox.jsx
+++ b/src/components/modals/main/settings/Checkbox.jsx
@@ -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)) {
diff --git a/src/components/modals/main/settings/Dropdown.jsx b/src/components/modals/main/settings/Dropdown.jsx
index 7409de91..590d014e 100644
--- a/src/components/modals/main/settings/Dropdown.jsx
+++ b/src/components/modals/main/settings/Dropdown.jsx
@@ -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,
diff --git a/src/components/modals/main/settings/Radio.jsx b/src/components/modals/main/settings/Radio.jsx
index 02ff4d6b..4875a215 100644
--- a/src/components/modals/main/settings/Radio.jsx
+++ b/src/components/modals/main/settings/Radio.jsx
@@ -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)) {
diff --git a/src/components/modals/main/settings/ResetModal.jsx b/src/components/modals/main/settings/ResetModal.jsx
index a247d3ff..bda18039 100644
--- a/src/components/modals/main/settings/ResetModal.jsx
+++ b/src/components/modals/main/settings/ResetModal.jsx
@@ -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();
}
diff --git a/src/components/modals/main/settings/Switch.jsx b/src/components/modals/main/settings/Switch.jsx
index 7b45a6af..f7a295fe 100644
--- a/src/components/modals/main/settings/Switch.jsx
+++ b/src/components/modals/main/settings/Switch.jsx
@@ -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)) {
diff --git a/src/components/modals/main/settings/sections/Advanced.jsx b/src/components/modals/main/settings/sections/Advanced.jsx
index 408f147c..b1683d02 100644
--- a/src/components/modals/main/settings/sections/Advanced.jsx
+++ b/src/components/modals/main/settings/sections/Advanced.jsx
@@ -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() {
diff --git a/src/components/modals/main/settings/sections/Experimental.jsx b/src/components/modals/main/settings/sections/Experimental.jsx
index ae837e75..0503adfd 100644
--- a/src/components/modals/main/settings/sections/Experimental.jsx
+++ b/src/components/modals/main/settings/sections/Experimental.jsx
@@ -10,6 +10,9 @@ export default function ExperimentalSettings() {
{experimental.title}
{experimental.warning}
+ Usage Stats
+ Allows you to see stats such as how many tabs you have opened, quotes favourited etc. It also sends this data anonymously to ourumami instance.
+
{experimental.developer}
diff --git a/src/components/modals/main/settings/sections/Order.jsx b/src/components/modals/main/settings/sections/Order.jsx
index 35d9075f..dc96b893 100644
--- a/src/components/modals/main/settings/sections/Order.jsx
+++ b/src/components/modals/main/settings/sections/Order.jsx
@@ -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');
}
diff --git a/src/components/modals/main/settings/sections/background/Colour.jsx b/src/components/modals/main/settings/sections/background/Colour.jsx
index 2a2779c9..f075738f 100644
--- a/src/components/modals/main/settings/sections/background/Colour.jsx
+++ b/src/components/modals/main/settings/sections/background/Colour.jsx
@@ -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 = () => {
diff --git a/src/components/modals/main/tabs/backend/Tabs.jsx b/src/components/modals/main/tabs/backend/Tabs.jsx
index bcc9c368..089392d0 100644
--- a/src/components/modals/main/tabs/backend/Tabs.jsx
+++ b/src/components/modals/main/tabs/backend/Tabs.jsx
@@ -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({
diff --git a/src/components/widgets/background/Favourite.jsx b/src/components/widgets/background/Favourite.jsx
index 4282acb0..8bb094a3 100644
--- a/src/components/widgets/background/Favourite.jsx
+++ b/src/components/widgets/background/Favourite.jsx
@@ -19,7 +19,7 @@ export default class Favourite extends React.PureComponent {
this.setState({
favourited:
});
- 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:
});
- window.analytics.postEvent('feature', 'Background unfavourite');
+ window.stats.postEvent('feature', 'Background unfavourite');
}
}
diff --git a/src/components/widgets/background/Maximise.jsx b/src/components/widgets/background/Maximise.jsx
index bdf28277..f10028d8 100644
--- a/src/components/widgets/background/Maximise.jsx
+++ b/src/components/widgets/background/Maximise.jsx
@@ -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');
}
}
diff --git a/src/components/widgets/background/PhotoInformation.jsx b/src/components/widgets/background/PhotoInformation.jsx
index 5c061b24..4a2a04d6 100644
--- a/src/components/widgets/background/PhotoInformation.jsx
+++ b/src/components/widgets/background/PhotoInformation.jsx
@@ -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) {
diff --git a/src/components/widgets/navbar/Notes.jsx b/src/components/widgets/navbar/Notes.jsx
index 46a891d9..f221138b 100644
--- a/src/components/widgets/navbar/Notes.jsx
+++ b/src/components/widgets/navbar/Notes.jsx
@@ -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);
diff --git a/src/components/widgets/quicklinks/QuickLinks.jsx b/src/components/widgets/quicklinks/QuickLinks.jsx
index 02f8791c..2fbd6b53 100644
--- a/src/components/widgets/quicklinks/QuickLinks.jsx
+++ b/src/components/widgets/quicklinks/QuickLinks.jsx
@@ -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();
}
diff --git a/src/components/widgets/quote/Quote.jsx b/src/components/widgets/quote/Quote.jsx
index 7f08f34c..3c8024d8 100644
--- a/src/components/widgets/quote/Quote.jsx
+++ b/src/components/widgets/quote/Quote.jsx
@@ -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() {
diff --git a/src/components/widgets/search/Search.jsx b/src/components/widgets/search/Search.jsx
index c22482c6..fc54be27 100644
--- a/src/components/widgets/search/Search.jsx
+++ b/src/components/widgets/search/Search.jsx
@@ -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;
}
diff --git a/src/index.js b/src/index.js
index bd9c64e9..7e921a67 100644
--- a/src/index.js
+++ b/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: () => ''
}
diff --git a/src/modules/default_settings.json b/src/modules/default_settings.json
index 62f787a5..f751f1f6 100644
--- a/src/modules/default_settings.json
+++ b/src/modules/default_settings.json
@@ -234,5 +234,13 @@
{
"name": "backgroundFilterAmount",
"value": 0
+ },
+ {
+ "name": "stats",
+ "value": false
+ },
+ {
+ "name": "statsData",
+ "value": "{}"
}
]
diff --git a/src/modules/helpers/settings.js b/src/modules/helpers/settings.js
index 57e92c9c..441e09c3 100644
--- a/src/modules/helpers/settings.js
+++ b/src/modules/helpers/settings.js
@@ -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) {
diff --git a/src/modules/helpers/analytics.js b/src/modules/helpers/stats.js
similarity index 62%
rename from src/modules/helpers/analytics.js
rename to src/modules/helpers/stats.js
index f3ea767f..d5e182ad 100644
--- a/src/modules/helpers/analytics.js
+++ b/src/modules/helpers/stats.js
@@ -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));
}
}
\ No newline at end of file