diff --git a/website/src/bootstrapping/matomo.ts b/website/src/bootstrapping/matomo.ts index 83859b3aed..0b56c3153d 100644 --- a/website/src/bootstrapping/matomo.ts +++ b/website/src/bootstrapping/matomo.ts @@ -1,6 +1,7 @@ // eslint-disable-next-line import/no-extraneous-dependencies import { History } from 'history'; import { each } from 'lodash'; +import { useState, useEffect } from 'react'; import { Tracker } from 'types/vendor/piwik'; import insertScript from 'utils/insertScript'; @@ -36,7 +37,7 @@ function trackInitialPageView() { } // Code mostly adopted from https://github.com/AmazingDreams/vue-matomo -export function initializeMamoto() { +export function initializeMatomo() { const siteId = '1'; const host = 'https://analytics.nusmods.com'; const scriptSrc = `${host}/piwik.js`; @@ -77,3 +78,13 @@ export function trackPageView(history: History) { } }); } + +export function useMatomo() { + // need to use useState here or the matomo returned will always be undefined + const [matomoCopy, setMatomoCopy] = useState(undefined); + useEffect(() => { + setMatomoCopy(matomo); + }, [matomo]); + + return matomoCopy; +} diff --git a/website/src/entry/main.tsx b/website/src/entry/main.tsx index 19d4e03251..440d4ff649 100644 --- a/website/src/entry/main.tsx +++ b/website/src/entry/main.tsx @@ -11,7 +11,7 @@ import ReactModal from 'react-modal'; import configureStore from 'bootstrapping/configure-store'; import subscribeOnlineEvents from 'bootstrapping/subscribeOnlineEvents'; -import { initializeMamoto } from 'bootstrapping/matomo'; +import { initializeMatomo } from 'bootstrapping/matomo'; import registerServiceWorker from 'bootstrapping/service-worker-manager'; import 'styles/main.scss'; @@ -38,5 +38,5 @@ if ( } if (NUSMODS_ENV === 'production') { - initializeMamoto(); + initializeMatomo(); } diff --git a/website/src/types/views.ts b/website/src/types/views.ts index 06673679e8..9e08b8d256 100644 --- a/website/src/types/views.ts +++ b/website/src/types/views.ts @@ -45,7 +45,7 @@ export type ExamClashes = { [key: string]: Module[] }; export type OnModifyCell = (lesson: ModifiableLesson, position: ClientRect) => void; export type OnHoverCell = (hoverLesson: HoverLesson | null) => void; -// Incomplete typing of Mamoto's API. If you need something not here, feel free +// Incomplete typing of Matomo's API. If you need something not here, feel free // to declare the typing here. export type TimeSegment = 'Morning' | 'Afternoon' | 'Evening'; diff --git a/website/src/views/settings/SettingsContainer.tsx b/website/src/views/settings/SettingsContainer.tsx index adb3be4d22..477926343a 100644 --- a/website/src/views/settings/SettingsContainer.tsx +++ b/website/src/views/settings/SettingsContainer.tsx @@ -4,7 +4,6 @@ import classnames from 'classnames'; import { isEqual } from 'lodash'; import { ColorSchemePreference, ThemeId } from 'types/settings'; -import { Tracker } from 'types/vendor/piwik'; import { ModRegNotificationSettings } from 'types/reducers'; import { State as StoreState } from 'types/state'; import { RegPeriod, SCHEDULE_TYPES, ScheduleType } from 'config'; @@ -26,7 +25,7 @@ import Title from 'views/components/Title'; import deferComponentRender from 'views/hocs/deferComponentRender'; import Online from 'views/components/Online'; import { supportsCSSVariables } from 'utils/css'; -import { withTracker } from 'bootstrapping/matomo'; +import { useMatomo } from 'bootstrapping/matomo'; import ExternalLink from 'views/components/ExternalLink'; import Toggle from 'views/components/Toggle'; import ModRegNotification from 'views/components/notfications/ModRegNotification'; @@ -68,22 +67,26 @@ const SettingsContainer: React.FC = ({ ...props }) => { const [allowTracking, setAllowTracking] = useState(true); - - const onToggleTracking = useCallback((isTrackingAllowed: boolean) => { - withTracker((tracker: Tracker) => { - if (isTrackingAllowed) { - tracker.forgetUserOptOut(); - } else { - tracker.optUserOut(); + const matomo = useMatomo(); + + const onToggleTracking = useCallback( + (isTrackingAllowed: boolean) => { + if (matomo !== undefined) { + if (isTrackingAllowed) { + matomo.forgetUserOptOut(); + } else { + matomo.optUserOut(); + } + setAllowTracking(!matomo.isUserOptedOut()); } - - setAllowTracking(!tracker.isUserOptedOut()); - }); - }, []); + }, + [matomo]); useEffect(() => { - withTracker((tracker: Tracker) => setAllowTracking(!tracker.isUserOptedOut())); - }, [onToggleTracking]); + if (matomo !== undefined) { + setAllowTracking(!matomo.isUserOptedOut()); + } + }, [onToggleTracking, matomo]); const rounds = getRounds(modRegNotification); @@ -263,8 +266,9 @@ const SettingsContainer: React.FC = ({
)}