heartwood every commit a ring

Swap hotkeys to global hotkeys, adjusting prettier problems

7a3a83c1 by Isaac Bythewood · 5 years ago

modified components/HotKeysMapping.js
@@ -1,25 +1,18 @@import React, { useContext } from "react";import ReactDOM from "react-dom";import { useRouter } from "next/router";import { HotKeys, configure } from "react-hotkeys";import { GlobalHotKeys, configure } from "react-hotkeys";import PropTypes from "prop-types";import { Context } from "../components/context";configure({  ignoreTags: [],  //logLevel: "debug",  /* below is workaround for bug in react-hotkeys   "[BUG] typing a space in <input /> will disable all hotkeys in that <input /> #237"   causing hotkeys to after pressing a whitespace character (space, enter,..)   in one of the per default ignored elements (input, textarea...),   this whitespace character is included in the combination for all further hotkeys.*/  ignoreEventsCondition: keyEvent => {  ignoreEventsCondition: (keyEvent) => {    if (keyEvent.key === "Enter" || keyEvent.key === " ") {      return true;    }    return false;  }  },});const keyMap = {
@@ -32,34 +25,28 @@ const keyMap = {  LOG_NEXT: "ArrowDown",  LOG_PREVIOUS: "ArrowUp",  LOG_EDIT: "alt+e",  LOG_DELETE_SINGLE: "alt+d"  LOG_DELETE_SINGLE: "alt+d",};const HotKeysMapping = props => {const HotKeysMapping = (props) => {  const { state, dispatch } = useContext(Context);  const router = useRouter();  const autofocus = el => {    const found = ReactDOM.findDOMNode(el);    if (found && !state.edit) {      found.focus();    }  };  const handlers = {    RESET: event => dispatch({ type: "NEW_TIMER" }),    ADD_LOG: event => {    RESET: () => dispatch({ type: "NEW_TIMER" }),    ADD_LOG: (event) => {      event.preventDefault();      dispatch({ type: "ADD_LOG", note: state.note });    },    TIMER_PAGE: event => {    TIMER_PAGE: (event) => {      event.preventDefault();      router.push("/");    },    LOG_PAGE: event => router.push("/log"),    ABOUT_PAGE: event => router.push("/about"),    CLEAR_LOG: event => dispatch({ type: "CLEAR_LOG" }),    LOG_NEXT: event => {    LOG_PAGE: () => router.push("/log"),    ABOUT_PAGE: () => router.push("/about"),    CLEAR_LOG: () => dispatch({ type: "CLEAR_LOG" }),    LOG_NEXT: (event) => {      event.preventDefault();      if (        window.location.href.substr(window.location.href.length - 3) == "log"
@@ -68,7 +55,7 @@ const HotKeysMapping = props => {        dispatch({ type: "NEXT_LOG_ITEM" });      }    },    LOG_PREVIOUS: event => {    LOG_PREVIOUS: (event) => {      event.preventDefault();      if (
@@ -78,32 +65,32 @@ const HotKeysMapping = props => {        dispatch({ type: "PREVIOUS_LOG_ITEM" });      }    },    LOG_EDIT: event => {    LOG_EDIT: (event) => {      event.preventDefault();      if (!state.logSelectedEntry) return;      if (window.location.href.substr(window.location.href.length - 3) == "log")        dispatch({ type: "TOGGLE_EDITION", edit: true });    },    LOG_DELETE_SINGLE: event => {    LOG_DELETE_SINGLE: (event) => {      event.preventDefault();      if (!state.logSelectedEntry) return;      if (window.location.href.substr(window.location.href.length - 3) == "log")        dispatch({ type: "REMOVE_LOG" });    }    },  };  return (    <HotKeys keyMap={keyMap} handlers={handlers} ref={autofocus}>    <GlobalHotKeys keyMap={keyMap} handlers={handlers}>      {props.children}    </HotKeys>    </GlobalHotKeys>  );};HotKeysMapping.propTypes = {  children: PropTypes.oneOfType([    PropTypes.element,    PropTypes.arrayOf(PropTypes.element)  ])    PropTypes.arrayOf(PropTypes.element),  ]),};export default HotKeysMapping;
modified components/context.js
@@ -13,7 +13,7 @@ const initialState = {  timer: new Date(),  log: [],  logSelectedEntry: "",  edit: false  edit: false,};const Context = createContext();
@@ -31,21 +31,21 @@ const reducer = (state, action) => {    case "SET_LANGUAGE":      newState = {        ...state,        language: action.language        language: action.language,      };      localForage.setItem("context", newState);      return newState;    case "NEW_TIMER":      newState = {        ...state,        timer: new Date()        timer: new Date(),      };      localForage.setItem("context", newState);      return newState;    case "NOTE_UPDATED":      newState = {        ...state,        note: action.note        note: action.note,      };      localForage.setItem("context", newState);      return newState;
@@ -61,14 +61,14 @@ const reducer = (state, action) => {            note: state.note,            tags: state.note              .split(" ")              .filter(word => word.startsWith("#"))              .map(word => {              .filter((word) => word.startsWith("#"))              .map((word) => {                return word.toLowerCase();              })              }),          },          ...state.log          ...state.log,        ],        note: ""        note: "",      };      localForage.setItem("context", newState);      toast.success(strings.addedEntry);
@@ -77,10 +77,10 @@ const reducer = (state, action) => {      newState = {        ...state,        log: [          ...state.log.map(entry => {          ...state.log.map((entry) => {            return entry.id == action.entry.id ? action.entry : entry;          })        ]          }),        ],      };      localForage.setItem("context", newState);      return newState;
@@ -88,17 +88,17 @@ const reducer = (state, action) => {      if (action.id !== undefined)        newState = {          ...state,          log: [...state.log.filter(entry => entry.id !== action.id)],          log: [...state.log.filter((entry) => entry.id !== action.id)],          logSelectedEntry:            state.logSelectedEntry == action.id ? "" : state.logSelectedEntry            state.logSelectedEntry == action.id ? "" : state.logSelectedEntry,        };      else {        newState = {          ...state,          log: [            ...state.log.filter(entry => entry.id !== state.logSelectedEntry)            ...state.log.filter((entry) => entry.id !== state.logSelectedEntry),          ],          logSelectedEntry: ""          logSelectedEntry: "",        };      }      localForage.setItem("context", newState);
@@ -109,7 +109,7 @@ const reducer = (state, action) => {        ...state,        log: [],        logSelectedEntry: "",        edit: false        edit: false,      };      localForage.setItem("context", newState);      toast.error(strings.resetLog);
@@ -117,7 +117,7 @@ const reducer = (state, action) => {    case "CLEAR_TAG":      newState = {        ...state,        log: [...state.log.filter(entry => !entry.tags.includes(action.tag))]        log: [...state.log.filter((entry) => !entry.tags.includes(action.tag))],      };      localForage.setItem("context", newState);      toast.error(strings.deletedEntry);
@@ -128,7 +128,7 @@ const reducer = (state, action) => {        newState = { ...state, logSelectedEntry: state.log[0].id };      } else {        const index = state.log.findIndex(          el => el.id == state.logSelectedEntry          (el) => el.id == state.logSelectedEntry        );        if (index + 1 < state.log.length)          newState = { ...state, logSelectedEntry: state.log[index + 1].id };
@@ -142,7 +142,7 @@ const reducer = (state, action) => {        newState = { ...state, logSelectedEntry: state.log[0].id };      } else {        const index = state.log.findIndex(          el => el.id == state.logSelectedEntry          (el) => el.id == state.logSelectedEntry        );        if (index - 1 >= 0) {          newState = { ...state, logSelectedEntry: state.log[index - 1].id };
@@ -171,7 +171,7 @@ const ContextProvider = ({ children }) => {  useEffect(() => {    localForage      .getItem("context")      .then(value => {      .then((value) => {        if (value !== null)          dispatch({ type: "LOCALDATA_READY", localdata: value });      })
@@ -185,8 +185,8 @@ const ContextProvider = ({ children }) => {ContextProvider.propTypes = {  children: PropTypes.oneOfType([    PropTypes.element,    PropTypes.arrayOf(PropTypes.element)  ])    PropTypes.arrayOf(PropTypes.element),  ]),};const ContextConsumer = Context.Consumer;
modified components/entry.js
@@ -1,5 +1,5 @@import React, { useContext, useRef, useEffect } from "react";import styled, { ThemeContext } from "styled-components";import styled from "styled-components";import useForm from "react-hook-form";import PropTypes from "prop-types";
@@ -9,10 +9,9 @@ import { Context } from "../components/context";const Entry = ({ entry, removeEntry, isSelected }) => {  const { state, dispatch } = useContext(Context);  const { register, handleSubmit } = useForm();  const themeContext = useContext(ThemeContext);  const focusedEntry = useRef(null);  const onSubmit = data => {  const onSubmit = (data) => {    dispatch({      type: "EDIT_LOG",      entry: {
@@ -20,11 +19,11 @@ const Entry = ({ entry, removeEntry, isSelected }) => {        note: data.note,        tags: data.note          .split(" ")          .filter(word => word.startsWith("#"))          .map(word => {          .filter((word) => word.startsWith("#"))          .map((word) => {            return word.toLowerCase();          })      }          }),      },    });    dispatch({ type: "TOGGLE_EDITION", edit: false, submited: true });  };
@@ -53,8 +52,8 @@ const Entry = ({ entry, removeEntry, isSelected }) => {              name="note"              ref={register}              autoFocus              value={state.log.find(x => x.id == entry.id).note || ""}              onChange={e =>              value={state.log.find((x) => x.id == entry.id).note || ""}              onChange={(e) =>                dispatch({                  type: "EDIT_LOG",                  entry: {
@@ -62,11 +61,11 @@ const Entry = ({ entry, removeEntry, isSelected }) => {                    note: e.target.value,                    tags: e.target.value                      .split(" ")                      .filter(word => word.startsWith("#"))                      .map(word => {                      .filter((word) => word.startsWith("#"))                      .map((word) => {                        return word.toLowerCase();                      })                  }                      }),                  },                })              }            />
@@ -90,7 +89,7 @@ const Entry = ({ entry, removeEntry, isSelected }) => {            {entry.tags.length > 0 && (              <small>                {entry.tags                  .map(tag => {                  .map((tag) => {                    return tag;                  })                  .join(", ")}
@@ -121,7 +120,7 @@ const Entry = ({ entry, removeEntry, isSelected }) => {Entry.propTypes = {  entry: PropTypes.object,  removeEntry: PropTypes.func  removeEntry: PropTypes.func,};export default Entry;
@@ -133,7 +132,7 @@ const EntryContainer = styled.div`  display: grid;  grid-template-columns: 150px 1fr 50px 50px;  align-items: center;  border-bottom: 1px solid ${props => props.theme.colors.four};  border-bottom: 1px solid ${(props) => props.theme.colors.four};  transition-duration: 250ms;  transition-property: transform;
@@ -168,7 +167,7 @@ const EntryContainer = styled.div`    transform: translateX(100px);  }  @media (${props => props.theme.breakpoint}) {  @media (${(props) => props.theme.breakpoint}) {    grid-template-columns: 1fr 1fr;    grid-template-rows: auto auto auto;    text-align: center;
@@ -184,7 +183,7 @@ const EntryNoteInput = styled.input`  padding: 12px 0;  font-size: 1em;  width: 100%;  border-bottom: 2px solid ${props => props.theme.colors.three};  border-bottom: 2px solid ${(props) => props.theme.colors.three};`;const EntryTime = styled.div`
@@ -192,7 +191,7 @@ const EntryTime = styled.div`  font-size: 1.3em;  padding: 15px;  height: 100%;  background-color: ${props => props.theme.colors.four};  background-color: ${(props) => props.theme.colors.four};  color: white;  text-align: center;  display: flex;
@@ -201,7 +200,7 @@ const EntryTime = styled.div`  box-sizing: border-box;  flex-direction: column;  @media (${props => props.theme.breakpoint}) {  @media (${(props) => props.theme.breakpoint}) {    grid-column: 1 / span 2;  }
@@ -225,7 +224,7 @@ const EntryNote = styled.div`    margin-top: 5px;  }  @media (${props => props.theme.breakpoint}) {  @media (${(props) => props.theme.breakpoint}) {    grid-column: 1 / span 2;  }`;
@@ -236,12 +235,12 @@ const EntryEdit = styled.button`  color: white;  cursor: pointer;  border: 0;  background: ${props => props.theme.colors.four};  background: ${(props) => props.theme.colors.four};  margin: 0;  padding: 15px;  height: 100%;  @media (${props => props.theme.breakpoint}) {  @media (${(props) => props.theme.breakpoint}) {    padding: 5px;  }`;
@@ -252,12 +251,12 @@ const EntrySubmit = styled.button`  color: white;  cursor: pointer;  border: 0;  background: ${props => props.theme.colors.four};  background: ${(props) => props.theme.colors.four};  margin: 0;  padding: 15px;  height: 100%;  @media (${props => props.theme.breakpoint}) {  @media (${(props) => props.theme.breakpoint}) {    padding: 5px;  }`;
@@ -268,12 +267,12 @@ const EntryRemove = styled.button`  color: white;  cursor: pointer;  border: 0;  background: ${props => props.theme.colors.five};  background: ${(props) => props.theme.colors.five};  margin: 0;  padding: 15px;  height: 100%;  @media (${props => props.theme.breakpoint}) {  @media (${(props) => props.theme.breakpoint}) {    padding: 5px;  }`;
modified components/l10n.js
@@ -11,7 +11,7 @@ const L10n = () => {  // TODO: This should probably not be buttons and be a select box of some kind...  return (    <Select      onChange={evt => {      onChange={(evt) => {        dispatch({ type: "SET_LANGUAGE", language: evt.target.value });      }}      value={state.language}
@@ -24,7 +24,7 @@ const L10n = () => {};L10n.propTypes = {  setLanguage: PropTypes.func  setLanguage: PropTypes.func,};export default L10n;
@@ -34,12 +34,12 @@ const Select = styled.select`  bottom: 5px;  right: 5px;  z-index: 2;  background-color: ${props => props.theme.colors.four};  background-color: ${(props) => props.theme.colors.four};  color: white;  padding: 5px;  border: none;  @media (${props => props.theme.breakpoint}) {  @media (${(props) => props.theme.breakpoint}) {    top: 5px;    right: 5px;    text-align: center;
modified components/page.js
@@ -3,7 +3,7 @@ import Head from "next/head";import PropTypes from "prop-types";import styled from "styled-components";const Page = props => {const Page = (props) => {  const baseTitle = "Timelite";  return (
@@ -22,15 +22,15 @@ Page.propTypes = {  title: PropTypes.string,  children: PropTypes.oneOfType([    PropTypes.element,    PropTypes.arrayOf(PropTypes.element)  ])    PropTypes.arrayOf(PropTypes.element),  ]),};export default Page;const Content = styled.div`  margin-left: 250px;  @media (${props => props.theme.breakpoint}) {  @media (${(props) => props.theme.breakpoint}) {    margin-left: 0;  }`;
modified components/sidebar.js
@@ -35,7 +35,7 @@ const Sidebar = ({ router }) => {Sidebar.propTypes = {  router: PropTypes.object,  language: PropTypes.string  language: PropTypes.string,};export default withRouter(Sidebar);
@@ -51,7 +51,7 @@ const Side = styled.div`  justify-content: space-between;  flex-direction: column;  @media (${props => props.theme.breakpoint}) {  @media (${(props) => props.theme.breakpoint}) {    width: 100%;    height: 60px;    bottom: 0;
@@ -63,7 +63,7 @@ const Side = styled.div``;const Title = styled.div`  color: ${props => props.theme.colors.one};  color: ${(props) => props.theme.colors.one};  text-transform: uppercase;  font-size: 2em;  font-weight: 900;
@@ -71,7 +71,7 @@ const Title = styled.div`  padding: 15px;  white-space: nowrap;  @media (${props => props.theme.breakpoint}) {  @media (${(props) => props.theme.breakpoint}) {    padding: 4px 10px;    font-size: 1.4em;  }
@@ -82,7 +82,7 @@ const Pages = styled.div`  flex-direction: column;  padding: 15px;  @media (${props => props.theme.breakpoint}) {  @media (${(props) => props.theme.breakpoint}) {    flex-direction: row;    padding: 5px;  }
@@ -96,7 +96,7 @@ const Page = styled.a`  transition: color 300ms, font-size 300ms;  font-size: 2em;  font-weight: 100;  ${props =>  ${(props) =>    props.active ? "color: rgba(0, 0, 0, 1);" : "color: rgba(0, 0, 0, 0.5);"}  &:hover {
@@ -104,7 +104,7 @@ const Page = styled.a`    font-size: 3em;  }  @media (${props => props.theme.breakpoint}) {  @media (${(props) => props.theme.breakpoint}) {    font-size: 1.4em;    margin-bottom: 0;    margin-right: 15px;
@@ -121,10 +121,10 @@ const About = styled.a`  display: block;  text-decoration: none;  font-family: monospace;  background: ${props => props.theme.colors.two};  background: ${(props) => props.theme.colors.two};  color: white;  @media (${props => props.theme.breakpoint}) {  @media (${(props) => props.theme.breakpoint}) {    padding: 0 15px;    display: flex;    justify-content: center;
modified l10n/about.js
@@ -18,14 +18,14 @@ const strings = new LocalizedStrings({    keyPreviousLogEntry: "Move to previous log entry",    keyEditEntry: "Edit log entry",    keyDeleteSingleEntry: "Delete single log entry",    keyClearLog: "Clear all log entries"    keyClearLog: "Clear all log entries",  },  // None of this is accurate past this line, someone please help me translate...  jp: {    title: "タイムライト?",    quote:      "なぜ午前5時ですか。常に行っていることを追跡するために使用できる簡単なものはありますか?",    name: "アイザックバイザウッド"    name: "アイザックバイザウッド",  },  pl: {    title: "Timelite?",
@@ -44,8 +44,8 @@ const strings = new LocalizedStrings({    keyPreviousLogEntry: "Przejdź do poprzedniego wpisu",    keyEditEntry: "Edytuj wpis dziennika",    keyDeleteSingleEntry: "Skasuj pojedynczy wpis dziennika",    keyClearLog: "Wyczyść wszystkie wpisy dziennika"  }    keyClearLog: "Wyczyść wszystkie wpisy dziennika",  },});export default strings;
modified l10n/context.js
@@ -6,7 +6,7 @@ const strings = new LocalizedStrings({    addedEntry: "You've added an entry.",    editedEntry: "You've edited an entry.",    deletedEntry: "You've deleted an entry.",    resetLog: "You've reset your log."    resetLog: "You've reset your log.",  },  // None of this is accurate past this line, someone please help me translate...  jp: {
@@ -14,14 +14,14 @@ const strings = new LocalizedStrings({    addedEntry: "エントリを追加しました。",    editedEntry: "エントリを編集しました。",    deletedEntry: "エントリを削除しました。",    resetLog: "ログをリセットしました。"    resetLog: "ログをリセットしました。",  },  pl: {    loaded: "Wczytano stan z lokalnego zapisu.",    addedEntry: "Dodałeś wpis.",    editedEntry: "Zmieniłeś wpis.",    deletedEntry: "Skasowałeś wpis.",    resetLog: "Wyczyściłeś dziennik."    resetLog: "Wyczyściłeś dziennik.",  },});
modified l10n/log.js
@@ -9,7 +9,7 @@ const strings = new LocalizedStrings({    tags: "Tags",    show: "Show All",    clear: "Clear",    export: "Export"    export: "Export",  },  // None of this is accurate past this line, someone please help me translate...  jp: {
@@ -20,7 +20,7 @@ const strings = new LocalizedStrings({    tags: "タグ",    show: "すべて",    clear: "すべてクリア",    export: "書き出す"    export: "書き出す",  },  pl: {    total: "Razem",
@@ -30,7 +30,7 @@ const strings = new LocalizedStrings({    tags: "Tagi",    show: "Pokaż wszystko",    clear: "Wyczyść",    export: "Wyeksportuj"    export: "Wyeksportuj",  },});
modified l10n/sidebar.js
@@ -5,20 +5,20 @@ const strings = new LocalizedStrings({    name: "Timelite",    timer: "Timer",    log: "Log",    about: "About"    about: "About",  },  // None of this is accurate past this line, someone please help me translate...  jp: {    name: "タイムライト",    timer: "タイマー",    log: "ログ",    about: "約"    about: "約",  },  pl: {    name: "Timelite",    timer: "Zegar",    log: "Dziennik",    about: "O Timelite"    about: "O Timelite",  },});
modified l10n/timer.js
@@ -4,18 +4,18 @@ const strings = new LocalizedStrings({  en: {    note: "Add a note with a #tag",    reset: "Reset",    add: "Add"    add: "Add",  },  // None of this is accurate past this line, someone please help me translate...  jp: {    note: "#tagでメモを追加",    reset: "リセット",    add: "追加する"    add: "追加する",  },  pl: {    note: "Dodaj wpis z #tagiem",    reset: "Zeruj",    add: "Dodaj"    add: "Dodaj",  },});
modified pages/_app.js
@@ -55,7 +55,7 @@ const GlobalStyle = createGlobalStyle`      -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial,      sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";    color: white;    background-color: ${props => props.theme.colors.one};    background-color: ${(props) => props.theme.colors.one};    min-height: 100vh;    width: 100%;    padding: 0;
modified pages/_document.js
@@ -10,7 +10,8 @@ class MyDocument extends Document {    try {      ctx.renderPage = () =>        originalRenderPage({          enhanceApp: App => props => sheet.collectStyles(<App {...props} />)          enhanceApp: (App) => (props) =>            sheet.collectStyles(<App {...props} />),        });      const initialProps = await Document.getInitialProps(ctx);
@@ -21,7 +22,7 @@ class MyDocument extends Document {            {initialProps.styles}            {sheet.getStyleElement()}          </>        )        ),      };    } finally {      sheet.seal();
modified pages/about.js
@@ -151,7 +151,7 @@ const Heading = styled.h1`  animation-duration: 1000ms;  animation-timing-function: ease-out;  @media (${props => props.theme.breakpoint}) {  @media (${(props) => props.theme.breakpoint}) {    font-size: 3em;  }`;
@@ -178,7 +178,7 @@ const Blockquote = styled.blockquote`    line-height: 0.5em;  }  @media (${props => props.theme.breakpoint}) {  @media (${(props) => props.theme.breakpoint}) {    font-size: 1.2em;  }`;
@@ -206,7 +206,7 @@ const Creator = styled.a`    right: 0;    bottom: -10px;    height: 2px;    background: ${props => props.theme.colors.three};    background: ${(props) => props.theme.colors.three};    transform-origin: left;    animation: ${ScaleLeft} 300ms normal forwards;    pointer-events: none;
@@ -219,7 +219,7 @@ const Creator = styled.a`    right: 0;    bottom: -10px;    height: 2px;    background: ${props => props.theme.colors.three};    background: ${(props) => props.theme.colors.three};    opacity: 0.2;    pointer-events: none;  }
@@ -230,7 +230,7 @@ const Creator = styled.a`    }  }  @media (${props => props.theme.breakpoint}) {  @media (${(props) => props.theme.breakpoint}) {    font-size: 1.2em;  }`;
@@ -239,7 +239,7 @@ const DescriptionContainer = styled.div`  display: flex;  margin-top: 2em;  @media (${props => props.theme.breakpoint}) {  @media (${(props) => props.theme.breakpoint}) {    display: none;  }`;
@@ -282,7 +282,7 @@ const KeysDescription = styled.div`    font-size: 1.1em;  }  @media (${props => props.theme.breakpoint}) {  @media (${(props) => props.theme.breakpoint}) {    font-size: 1.2em;  }`;
modified pages/index.js
@@ -38,17 +38,17 @@ const Background = styled.div`  bottom: 0;  left: 0;  background-image: linear-gradient(      ${props => props.theme.colors.one},      ${(props) => props.theme.colors.one},      transparent    ),    linear-gradient(      to top left,      ${props => props.theme.colors.four},      ${(props) => props.theme.colors.four},      transparent    ),    linear-gradient(      to top right,      ${props => props.theme.colors.five},      ${(props) => props.theme.colors.five},      transparent    );  background-blend-mode: screen;
modified pages/log.js
@@ -15,9 +15,9 @@ const Log = () => {  strings.setLanguage(state.language);  const getTags = entries => {  const getTags = (entries) => {    let tags = [];    entries.map(entry => tags.push(...entry.tags));    entries.map((entry) => tags.push(...entry.tags));    return [...new Set(tags)];  };
@@ -26,7 +26,7 @@ const Log = () => {      case "SHOW_ALL":        return entries;      case "SHOW_TAG":        return entries.filter(entry => entry.tags.includes(filter.tag));        return entries.filter((entry) => entry.tags.includes(filter.tag));      default:        return entries;    }
@@ -44,7 +44,7 @@ const Log = () => {    }, 0);  };  const removeEntry = id => {  const removeEntry = (id) => {    if (getVisibleEntries(state.log, filter).length === 1) {      setFilter({ type: "SHOW_ALL" });    }
@@ -83,7 +83,7 @@ const Log = () => {            <TopBar>              <Filters>                <span>{strings.tags}</span>                {getTags(state.log).map(tag => {                {getTags(state.log).map((tag) => {                  return (                    <FilterButton                      key={tag}
@@ -154,7 +154,7 @@ const Grid = styled.div`  width: 100%;  min-height: 100vh;  @media (${props => props.theme.breakpoint}) {  @media (${(props) => props.theme.breakpoint}) {    grid-template-columns: 1fr;    grid-auto-rows: min-content;  }
@@ -171,9 +171,9 @@ const Details = styled.div`  padding: 15px;  box-sizing: border-box;  background-color: #e2e2e2;  color: ${props => props.theme.colors.one};  color: ${(props) => props.theme.colors.one};  @media (${props => props.theme.breakpoint}) {  @media (${(props) => props.theme.breakpoint}) {    position: relative;    grid-column: 1;    height: auto;
@@ -196,7 +196,7 @@ const Main = styled.main`    flex-direction: column;  }  @media (${props => props.theme.breakpoint}) {  @media (${(props) => props.theme.breakpoint}) {    grid-column: 1;    padding-top: 0;    min-height: auto;
@@ -213,7 +213,7 @@ const TopBar = styled.div`  justify-content: space-between;  margin-bottom: 40px;  @media (${props => props.theme.breakpoint}) {  @media (${(props) => props.theme.breakpoint}) {    flex-direction: column;  }`;
@@ -228,8 +228,8 @@ const Filters = styled.div``;const FilterButton = styled.button`  background: ${props => props.theme.colors.three};  border-bottom: 1px solid ${props => props.theme.colors.four};  background: ${(props) => props.theme.colors.three};  border-bottom: 1px solid ${(props) => props.theme.colors.four};  padding: 6px 9px;  color: white;  border: none;
@@ -241,8 +241,8 @@ const FilterButton = styled.button`const Reset = styled.button`  font-size: 1.1em;  border: 0;  background-color: ${props => props.theme.colors.five};  border-bottom: 1px solid ${props => props.theme.colors.four};  background-color: ${(props) => props.theme.colors.five};  border-bottom: 1px solid ${(props) => props.theme.colors.four};  padding: 10px 25px;  letter-spacing: 1px;  text-transform: uppercase;
@@ -250,7 +250,7 @@ const Reset = styled.button`  font-weight: bolder;  cursor: pointer;  @media (${props => props.theme.breakpoint}) {  @media (${(props) => props.theme.breakpoint}) {    font-size: 0.8em;    padding: 8px 15px;    margin-top: 15px;
@@ -263,11 +263,11 @@ const CSVButton = styled(CSVLink)`  display: block;  text-decoration: none;  font-family: monospace;  background: ${props => props.theme.colors.one};  background: ${(props) => props.theme.colors.one};  color: white;  margin: 5px;  @media (${props => props.theme.breakpoint}) {  @media (${(props) => props.theme.breakpoint}) {    padding: 10px 0;  }`;
@@ -285,10 +285,10 @@ const Nothing = styled.div`    left: 0;    bottom: -15px;    height: 3px;    background-color: ${props => props.theme.colors.three};    background-color: ${(props) => props.theme.colors.three};  }  @media (${props => props.theme.breakpoint}) {  @media (${(props) => props.theme.breakpoint}) {    font-size: 1.4em;  }`;
modified utils/time.js
@@ -1,17 +1,17 @@const timeDiff = time => {const timeDiff = (time) => {  const timeNow = new Date();  return timeNow - time;};const timeString = timeDiff => {const timeString = (timeDiff) => {  // timeDiff should be milliseconds  const timerTotal = [    (timeDiff / 1000 / 60 / 60) % 60, // Hours    (timeDiff / 1000 / 60) % 60, // Minutes    (timeDiff / 1000) % 60 // Seconds    (timeDiff / 1000) % 60, // Seconds  ];  return timerTotal    .map(timer => {    .map((timer) => {      let stringTime = Math.floor(timer).toString();      if (stringTime.length < 2) stringTime = `0${stringTime}`;      return stringTime;