From ed6f660099be42c3b81af80b6bef2bb775bc5952 Mon Sep 17 00:00:00 2001 From: David Ralph Date: Tue, 3 Sep 2024 14:06:13 +0100 Subject: [PATCH] feat: rewrite stats backend --- src/App.jsx | 2 +- .../Elements/MainModal/backend/Tabs.jsx | 2 +- .../Elements/ResetModal/ResetModal.jsx | 2 +- .../Form/Settings/Checkbox/Checkbox.jsx | 2 +- src/components/Form/Settings/Radio/Radio.jsx | 6 ++- .../Layout/Settings/Header/Header.jsx | 2 +- src/components/Layout/Settings/Hero/Hero.jsx | 2 +- .../background/components/Favourite.jsx | 4 +- .../components/PhotoInformation.jsx | 2 +- .../components/Elements/Lightbox/Lightbox.jsx | 2 +- src/features/marketplace/views/Browse.jsx | 2 +- src/features/misc/modals/Modals.jsx | 4 +- src/features/misc/sections/Overview.jsx | 2 +- src/features/navbar/components/Maximise.jsx | 4 +- src/features/navbar/components/Notes.jsx | 6 +-- src/features/navbar/components/Todo.jsx | 2 +- src/features/navbar/options/AppsOptions.jsx | 4 +- src/features/navbar/options/NavbarOptions.jsx | 2 +- .../quicklinks/options/QuickLinksOptions.jsx | 4 +- src/features/quote/Quote.jsx | 4 +- src/features/search/Search.jsx | 4 +- src/features/stats/api/stats.js | 38 +++++++------------ 22 files changed, 48 insertions(+), 54 deletions(-) diff --git a/src/App.jsx b/src/App.jsx index e3a093ad..9b0cad5f 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -28,7 +28,7 @@ const useAppSetup = () => { EventBus.on('refresh', refreshHandler); - variables.stats.tabLoad(); + variables.stats.postEvent('tabs-opened'); return () => { EventBus.off('refresh', refreshHandler); diff --git a/src/components/Elements/MainModal/backend/Tabs.jsx b/src/components/Elements/MainModal/backend/Tabs.jsx index 4713add4..7941cbab 100644 --- a/src/components/Elements/MainModal/backend/Tabs.jsx +++ b/src/components/Elements/MainModal/backend/Tabs.jsx @@ -18,7 +18,7 @@ const Tabs = (props) => { const onClick = (tab, name) => { if (name !== currentName) { - variables.stats.postEvent('tab', `Opened ${name}`); + variables.stats.postEvent('tab', ${name}, 'opened'); } setCurrentTab(tab); setCurrentName(name); diff --git a/src/components/Elements/ResetModal/ResetModal.jsx b/src/components/Elements/ResetModal/ResetModal.jsx index 6beb55ba..3872ea41 100644 --- a/src/components/Elements/ResetModal/ResetModal.jsx +++ b/src/components/Elements/ResetModal/ResetModal.jsx @@ -6,7 +6,7 @@ import { Tooltip, Button } from 'components/Elements'; function ResetModal({ modalClose }) { const reset = () => { - variables.stats.postEvent('setting', 'Reset'); + variables.stats.postEvent('setting', 'reset'); setDefaultSettings('reset'); window.location.reload(); }; diff --git a/src/components/Form/Settings/Checkbox/Checkbox.jsx b/src/components/Form/Settings/Checkbox/Checkbox.jsx index 7a3375e4..3bdf11ba 100644 --- a/src/components/Form/Settings/Checkbox/Checkbox.jsx +++ b/src/components/Form/Settings/Checkbox/Checkbox.jsx @@ -21,7 +21,7 @@ const Checkbox = (props) => { props.onChange(value); } - variables.stats.postEvent('setting', `${props.name} ${value ? 'enabled' : 'disabled'}`); + variables.stats.postEvent('setting', props.name, value ? 'enabled' : 'disabled'); if (props.element) { if (!document.querySelector(props.element)) { diff --git a/src/components/Form/Settings/Radio/Radio.jsx b/src/components/Form/Settings/Radio/Radio.jsx index 85e12c18..a9e3af85 100644 --- a/src/components/Form/Settings/Radio/Radio.jsx +++ b/src/components/Form/Settings/Radio/Radio.jsx @@ -29,7 +29,11 @@ function Radio(props) { props.onChange(value); } - variables.stats.postEvent('setting', `${props.name} from ${value} to ${value}`); + if (props.name !== 'language') { + variables.stats.postEvent('setting', props.name, `${value}-${value}`); + } else { + variables.stats.postEvent('language', props.name, `${value}-${value}`); + } if (props.element) { if (!document.querySelector(props.element)) { diff --git a/src/components/Layout/Settings/Header/Header.jsx b/src/components/Layout/Settings/Header/Header.jsx index b6357449..83a1b4d6 100644 --- a/src/components/Layout/Settings/Header/Header.jsx +++ b/src/components/Layout/Settings/Header/Header.jsx @@ -22,7 +22,7 @@ function Header(props) { variables.stats.postEvent( 'setting', - `${props.name} ${setting === true ? 'enabled' : 'disabled'}`, + props.setting, setting === true ? 'enabled' : 'disabled', ); EventBus.emit('toggle', props.setting); diff --git a/src/components/Layout/Settings/Hero/Hero.jsx b/src/components/Layout/Settings/Hero/Hero.jsx index 590684b0..dfbf0b3f 100644 --- a/src/components/Layout/Settings/Hero/Hero.jsx +++ b/src/components/Layout/Settings/Hero/Hero.jsx @@ -31,7 +31,7 @@ const Controls = (props) => { variables.stats.postEvent( 'setting', - `${props.name} ${setting === true ? 'enabled' : 'disabled'}`, + props.name, setting === true ? 'enabled' : 'disabled', ); EventBus.emit('toggle', props.setting); diff --git a/src/features/background/components/Favourite.jsx b/src/features/background/components/Favourite.jsx index b40c0cf4..97e0631d 100644 --- a/src/features/background/components/Favourite.jsx +++ b/src/features/background/components/Favourite.jsx @@ -23,7 +23,7 @@ function Favourite({ credit, offline, pun, tooltipText }) { localStorage.removeItem('favourite'); setFavourited(buttons.unfavourited); tooltipText(variables.getMessage('widgets.quote.favourite')); - variables.stats.postEvent('feature', 'Background favourite'); + variables.stats.postEvent('feature', 'background', 'favourite'); } else { const type = localStorage.getItem('backgroundType') || defaults.backgroundType; @@ -87,7 +87,7 @@ function Favourite({ credit, offline, pun, tooltipText }) { tooltipText(variables.getMessage('widgets.quote.unfavourite')); - variables.stats.postEvent('feature', 'Background unfavourite'); + variables.stats.postEvent('feature', 'background', 'unfavourite'); } } diff --git a/src/features/background/components/PhotoInformation.jsx b/src/features/background/components/PhotoInformation.jsx index 5ae7e9a7..42a74433 100644 --- a/src/features/background/components/PhotoInformation.jsx +++ b/src/features/background/components/PhotoInformation.jsx @@ -50,7 +50,7 @@ const downloadImage = async (info) => { document.body.appendChild(link); link.click(); document.body.removeChild(link); - variables.stats.postEvent('feature', 'Background download'); + variables.stats.postEvent('feature', 'background', 'download'); }; function PhotoInformation({ info, url, api }) { diff --git a/src/features/marketplace/components/Elements/Lightbox/Lightbox.jsx b/src/features/marketplace/components/Elements/Lightbox/Lightbox.jsx index 294def64..4a54dc0c 100644 --- a/src/features/marketplace/components/Elements/Lightbox/Lightbox.jsx +++ b/src/features/marketplace/components/Elements/Lightbox/Lightbox.jsx @@ -2,7 +2,7 @@ import { memo } from 'react'; import variables from 'config/variables'; function Lightbox({ modalClose, img }) { - variables.stats.postEvent('modal', 'Opened lightbox'); + variables.stats.postEvent('modal', 'lightbox', 'opened'); return ( <> diff --git a/src/features/marketplace/views/Browse.jsx b/src/features/marketplace/views/Browse.jsx index 5c268d2e..2c493247 100644 --- a/src/features/marketplace/views/Browse.jsx +++ b/src/features/marketplace/views/Browse.jsx @@ -75,7 +75,7 @@ function Marketplace() { setType('item'); - variables.stats.postEvent('marketplace-item', `${item.display_name} viewed`); + variables.stats.postEvent('marketplace-item', item.display_name, 'viewed'); } else if (pageType === 'collection') { setDone(false); setItem({}); diff --git a/src/features/misc/modals/Modals.jsx b/src/features/misc/modals/Modals.jsx index f5b8330a..c1368908 100644 --- a/src/features/misc/modals/Modals.jsx +++ b/src/features/misc/modals/Modals.jsx @@ -17,7 +17,7 @@ function Modals() { window.location.search !== '?nointro=true' ) { setWelcomeVisible(true); - variables.stats.postEvent('modal', 'Opened welcome'); + variables.stats.postEvent('modal', 'welcome', 'opened'); } if (window.location.search === '?nointro=true') { @@ -45,7 +45,7 @@ function Modals() { } if (action !== false) { - variables.stats.postEvent('modal', `Opened ${type.replace('Modal', '')}`); + variables.stats.postEvent('modal', type.replace('Modal', ''), 'opened'); } }; diff --git a/src/features/misc/sections/Overview.jsx b/src/features/misc/sections/Overview.jsx index 5b1ad00c..570357f5 100644 --- a/src/features/misc/sections/Overview.jsx +++ b/src/features/misc/sections/Overview.jsx @@ -88,7 +88,7 @@ const Overview = () => { useEffect(() => { localStorage.setItem('order', JSON.stringify(items)); - variables.stats.postEvent('setting', 'Widget order'); + variables.stats.postEvent('setting', 'widget-order'); EventBus.emit('refresh', 'widgets'); }, [items]); diff --git a/src/features/navbar/components/Maximise.jsx b/src/features/navbar/components/Maximise.jsx index 87c101cc..44c715c1 100644 --- a/src/features/navbar/components/Maximise.jsx +++ b/src/features/navbar/components/Maximise.jsx @@ -49,14 +49,14 @@ function Maximise(props) { if (hidden === false) { setAttribute(0, 100); - variables.stats.postEvent('feature', 'Background maximise'); + variables.stats.postEvent('feature', 'background-maximise'); } else { setAttribute( localStorage.getItem('blur') || defaults.blur, localStorage.getItem('brightness') || defaults.brightness, true, ); - variables.stats.postEvent('feature', 'Background unmaximise'); + variables.stats.postEvent('feature', 'background-unmaximise'); } }; diff --git a/src/features/navbar/components/Notes.jsx b/src/features/navbar/components/Notes.jsx index 77066029..5ce11560 100644 --- a/src/features/navbar/components/Notes.jsx +++ b/src/features/navbar/components/Notes.jsx @@ -65,7 +65,7 @@ class Notes extends PureComponent { } pin() { - variables.stats.postEvent('feature', 'Notes pin'); + variables.stats.postEvent('feature', 'notes', 'pin'); const notesPinned = localStorage.getItem('notesPinned') === 'true'; localStorage.setItem('notesPinned', !notesPinned); this.setState({ @@ -74,7 +74,7 @@ class Notes extends PureComponent { } copy() { - variables.stats.postEvent('feature', 'Notes copied'); + variables.stats.postEvent('feature', 'notes', 'copied'); navigator.clipboard.writeText(this.state.notes); toast(variables.getMessage('toasts.notes')); } @@ -85,7 +85,7 @@ class Notes extends PureComponent { return; } - variables.stats.postEvent('feature', 'Notes download'); + variables.stats.postEvent('feature', 'notes', 'download'); saveFile(this.state.notes, 'mue-notes.txt', 'text/plain'); } diff --git a/src/features/navbar/components/Todo.jsx b/src/features/navbar/components/Todo.jsx index b9255f13..6051ba4c 100644 --- a/src/features/navbar/components/Todo.jsx +++ b/src/features/navbar/components/Todo.jsx @@ -129,7 +129,7 @@ class Todo extends PureComponent { } pin() { - variables.stats.postEvent('feature', 'Todo pin'); + variables.stats.postEvent('feature', 'todo', 'pin'); const todoPinned = localStorage.getItem('todoPinned') === 'true'; localStorage.setItem('todoPinned', !todoPinned); this.setState({ diff --git a/src/features/navbar/options/AppsOptions.jsx b/src/features/navbar/options/AppsOptions.jsx index f5b1352e..e50fe6e5 100644 --- a/src/features/navbar/options/AppsOptions.jsx +++ b/src/features/navbar/options/AppsOptions.jsx @@ -61,7 +61,7 @@ function AppsOptions({ appsEnabled }) { iconError: '', }); - variables.stats.postEvent('feature', 'App link add'); + variables.stats.postEvent('feature', 'app-link', 'add'); }; const startEditLink = (data) => { @@ -102,7 +102,7 @@ function AppsOptions({ appsEnabled }) { items: data, })); - variables.stats.postEvent('feature', 'App link delete'); + variables.stats.postEvent('feature', 'app-link', 'delete'); }; return ( diff --git a/src/features/navbar/options/NavbarOptions.jsx b/src/features/navbar/options/NavbarOptions.jsx index ff692f71..cb80a392 100644 --- a/src/features/navbar/options/NavbarOptions.jsx +++ b/src/features/navbar/options/NavbarOptions.jsx @@ -60,7 +60,7 @@ function NavbarOptions() { variables.stats.postEvent( 'setting', - `${settingName} ${!isDisabled === true ? 'enabled' : 'disabled'}`, + settingName, !isDisabled === true ? 'enabled' : 'disabled', ); EventBus.emit('refresh', 'navbar'); diff --git a/src/features/quicklinks/options/QuickLinksOptions.jsx b/src/features/quicklinks/options/QuickLinksOptions.jsx index 77df88be..78ec6361 100644 --- a/src/features/quicklinks/options/QuickLinksOptions.jsx +++ b/src/features/quicklinks/options/QuickLinksOptions.jsx @@ -38,7 +38,7 @@ class QuickLinksOptions extends PureComponent { items: data, }); - variables.stats.postEvent('feature', 'Quicklink delete'); + variables.stats.postEvent('feature', 'quicklink' ,'delete'); } async addLink(name, url, icon) { @@ -76,7 +76,7 @@ class QuickLinksOptions extends PureComponent { iconError: '', }); - variables.stats.postEvent('feature', 'Quicklink add'); + variables.stats.postEvent('feature', 'quicklink', 'add'); } startEditLink(data) { diff --git a/src/features/quote/Quote.jsx b/src/features/quote/Quote.jsx index f10c0248..90b8bca4 100644 --- a/src/features/quote/Quote.jsx +++ b/src/features/quote/Quote.jsx @@ -318,7 +318,7 @@ class Quote extends PureComponent { } copyQuote() { - variables.stats.postEvent('feature', 'Quote copied'); + variables.stats.postEvent('feature', 'quote', 'copied'); navigator.clipboard.writeText(`${this.state.quote} - ${this.state.author}`); toast(variables.getMessage('toasts.quote')); } @@ -336,7 +336,7 @@ class Quote extends PureComponent { }); } - variables.stats.postEvent('feature', 'Quote favourite'); + variables.stats.postEvent('feature', 'quote', 'favourite'); } init() { diff --git a/src/features/search/Search.jsx b/src/features/search/Search.jsx index a078dcff..2f919e88 100644 --- a/src/features/search/Search.jsx +++ b/src/features/search/Search.jsx @@ -107,7 +107,7 @@ function Search() { } setTimeout(() => { - variables.stats.postEvent('feature', 'Voice search'); + variables.stats.postEvent('feature', 'voice-search'); window.location.href = url + `?${query}=` + searchText.value; }, 1000); }; @@ -116,7 +116,7 @@ function Search() { function searchButton(e) { e.preventDefault(); const value = e.target.value || document.getElementById('searchtext').value || 'mue fast'; - variables.stats.postEvent('feature', 'Search'); + variables.stats.postEvent('feature', 'search'); window.location.href = url + `?${query}=` + value; } diff --git a/src/features/stats/api/stats.js b/src/features/stats/api/stats.js index 10e92833..830a4a64 100644 --- a/src/features/stats/api/stats.js +++ b/src/features/stats/api/stats.js @@ -20,39 +20,29 @@ export default class Stats { } /** - * It takes two arguments, a type and a name, and then it increments the value of the name in the type + * It takes three arguments, a type, a name, and an action, and then it increments the value of the name in the type * object in localStorage * @param type - The type of event you want to track. This can be anything you want, but I recommend * using something like "click" or "hover" * @param name - The name of the event. + * @param action - The action of the event. */ - static async postEvent(type, name) { - const value = name.toLowerCase().replaceAll(' ', '-'); - + static async postEvent(type, name, action) { const 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; - } + if (!name) { + data[type] = data[type] + 1 || 1; } else { - data[type][value] = data[type][value] + 1; - } - localStorage.setItem('statsData', JSON.stringify(data)); - this.achievementTrigger(data); - } + data[type] = data[type] || {}; + + if (action) { + data[type][name] = data[type][name] || {}; + data[type][name][action] = data[type][name][action] + 1 || 1; + } else { + data[type][name] = data[type][name] + 1 || 1; + } + } - /** - * It increments the value of the key 'tabs-opened' in the object stored in localStorage by 1. - */ - static async tabLoad() { - const data = JSON.parse(localStorage.getItem('statsData')) || {}; - data['tabs-opened'] = data['tabs-opened'] + 1 || 1; localStorage.setItem('statsData', JSON.stringify(data)); this.achievementTrigger(data); }