ahbeng/NUSMods

View on GitHub
website/src/reducers/theme.ts

Summary

Maintainability
A
1 hr
Test Coverage
import { HORIZONTAL, ThemeState, VERTICAL } from 'types/reducers';
import { Theme } from 'types/settings';
import { Actions } from 'types/actions';

import { SET_EXPORTED_DATA } from 'actions/constants';
import {
  CYCLE_THEME,
  SELECT_THEME,
  TOGGLE_TIMETABLE_ORIENTATION,
  TOGGLE_TITLE_DISPLAY,
} from 'actions/theme';
import themes from 'data/themes.json';
import { DIMENSIONS, withTracker } from 'bootstrapping/matomo';

export const defaultThemeState: ThemeState = {
  // Available themes are defined in `themes.scss`
  id: 'eighties',
  timetableOrientation: HORIZONTAL,
  showTitle: false,
};
export const themeIds = themes.map((obj: Theme) => obj.id);

function theme(state: ThemeState = defaultThemeState, action: Actions): ThemeState {
  function setTheme(newTheme: string): ThemeState {
    // Update theme analytics info
    withTracker((tracker) => tracker.setCustomDimension(DIMENSIONS.theme, newTheme));

    return {
      ...state,
      id: newTheme,
    };
  }

  switch (action.type) {
    case SELECT_THEME:
      return setTheme(action.payload);

    case CYCLE_THEME: {
      const newThemeIndex =
        (themeIds.indexOf(state.id) + themeIds.length + action.payload) % themeIds.length;

      return setTheme(themeIds[newThemeIndex]);
    }
    case TOGGLE_TIMETABLE_ORIENTATION:
      return {
        ...state,
        timetableOrientation: state.timetableOrientation === VERTICAL ? HORIZONTAL : VERTICAL,
      };

    case SET_EXPORTED_DATA:
      return action.payload.theme;

    case TOGGLE_TITLE_DISPLAY:
      return {
        ...state,
        showTitle: !state.showTitle,
      };
    default:
      return state;
  }
}

export default theme;