mirror of
https://github.com/generativefm/generative.fm.git
synced 2026-01-10 07:07:59 -05:00
Add feature analytics
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import React, { useState, useMemo } from 'react';
|
||||
import React, { useState, useMemo, useCallback } from 'react';
|
||||
import propTypes from 'prop-types';
|
||||
import TextButton from '@components/shared/text-button';
|
||||
import './timer-config.scss';
|
||||
@@ -15,6 +15,10 @@ const StartTimerContent = ({ lastDurationsMS, startTimer }) => {
|
||||
startTimer(durationMS);
|
||||
};
|
||||
|
||||
const handleDurationInputChange = useCallback(event => {
|
||||
setCustomDuration(event.target.value);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<ul className="timer-box__durations">
|
||||
@@ -34,7 +38,7 @@ const StartTimerContent = ({ lastDurationsMS, startTimer }) => {
|
||||
size={3}
|
||||
className="timer-box__input"
|
||||
value={customDuration}
|
||||
onChange={event => setCustomDuration(event.target.value)}
|
||||
onChange={handleDurationInputChange}
|
||||
title="Timer duration in minutes"
|
||||
/>
|
||||
minutes
|
||||
@@ -64,6 +68,9 @@ const ADD_MS = [1 * 60 * 1000, 3 * 60 * 1000, 5 * 60 * 1000];
|
||||
const InProgressContent = ({ remainingMS, updateTimer, cancelTimer }) => {
|
||||
const remainingMinutes = Math.round(remainingMS / 60 / 1000);
|
||||
const remainingSeconds = Math.round(remainingMS / 1000);
|
||||
|
||||
const handleCancelClick = useCallback(() => cancelTimer(), [cancelTimer]);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<span className="timer-box__time">
|
||||
@@ -77,7 +84,7 @@ const InProgressContent = ({ remainingMS, updateTimer, cancelTimer }) => {
|
||||
<button
|
||||
type="button"
|
||||
className="timer-box__durations__item__btn"
|
||||
onClick={() => updateTimer(addMS)}
|
||||
onClick={() => updateTimer(addMS, true)}
|
||||
title={`Add ${addMS / 60000} minutes to timer`}
|
||||
>{`+ ${addMS / 60 / 1000} minutes`}</button>
|
||||
</li>
|
||||
@@ -85,7 +92,7 @@ const InProgressContent = ({ remainingMS, updateTimer, cancelTimer }) => {
|
||||
</ul>
|
||||
<TextButton
|
||||
className="timer-box__btn"
|
||||
onClick={() => cancelTimer()}
|
||||
onClick={handleCancelClick}
|
||||
title="Cancel timer and resume endless playback"
|
||||
>
|
||||
Cancel Timer
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
import UPDATE_TIMER from '../types/update-timer.type';
|
||||
|
||||
const updateTimer = deltaMS => ({ type: UPDATE_TIMER, payload: deltaMS });
|
||||
const updateTimer = (deltaMS, isUserUpdate = false) => ({
|
||||
type: UPDATE_TIMER,
|
||||
payload: deltaMS,
|
||||
meta: { isUserUpdate },
|
||||
});
|
||||
|
||||
export default updateTimer;
|
||||
|
||||
50
src/store/reducers/analytics.reducer.js
Normal file
50
src/store/reducers/analytics.reducer.js
Normal file
@@ -0,0 +1,50 @@
|
||||
import START_TIMER from '../actions/types/start-timer.type';
|
||||
import NEXT from '../actions/types/next.type';
|
||||
import PREVIOUS from '../actions/types/previous.type';
|
||||
import UPDATE_TIMER from '../actions/types/update-timer.type';
|
||||
import CANCEL_TIMER from '../actions/types/cancel-timer.type';
|
||||
|
||||
const updateCount = (state, propName) =>
|
||||
Object.assign({}, state, {
|
||||
[propName]: (state[propName] || 0) + 1,
|
||||
});
|
||||
|
||||
const analyticsReducer = (state = {}, action) => {
|
||||
switch (action.type) {
|
||||
case START_TIMER: {
|
||||
const { payload: durationMs } = action;
|
||||
const newState = updateCount(state, 'timerStartCount');
|
||||
newState.timerDurationCounts = updateCount(
|
||||
newState.timerDurationCounts || {},
|
||||
durationMs
|
||||
);
|
||||
return newState;
|
||||
}
|
||||
case UPDATE_TIMER: {
|
||||
const { payload: deltaMs, meta } = action;
|
||||
if (!meta || !meta.isUserUpdate) {
|
||||
return state;
|
||||
}
|
||||
const newState = updateCount(state, 'timerUpdateCount');
|
||||
newState.timerDeltaCounts = updateCount(
|
||||
newState.timerDeltaCounts || {},
|
||||
deltaMs
|
||||
);
|
||||
return newState;
|
||||
}
|
||||
case CANCEL_TIMER: {
|
||||
return updateCount(state, 'timerCancelCount');
|
||||
}
|
||||
case NEXT: {
|
||||
return updateCount(state, 'nextCount');
|
||||
}
|
||||
case PREVIOUS: {
|
||||
return updateCount(state, 'previousCount');
|
||||
}
|
||||
default: {
|
||||
return state;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export default analyticsReducer;
|
||||
@@ -22,6 +22,7 @@ import visiblePieceIdsReducer from './visible-piece-ids.reducer';
|
||||
import isInstallable from './is-installable.reducer';
|
||||
import globalPlayTime from './global-play-time.reducer';
|
||||
import favoriteCount from './favorite-count.reducer';
|
||||
import analytics from './analytics.reducer';
|
||||
|
||||
const combinedReducer = combineReducers({
|
||||
isMuted,
|
||||
@@ -46,6 +47,7 @@ const combinedReducer = combineReducers({
|
||||
isInstallable,
|
||||
globalPlayTime,
|
||||
favoriteCount,
|
||||
analytics,
|
||||
});
|
||||
|
||||
const rootReducer = (state = {}, action) => {
|
||||
|
||||
Reference in New Issue
Block a user