diff --git a/package-lock.json b/package-lock.json
index 5eb13ed..6c329a6 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -8220,6 +8220,11 @@
}
}
},
+ "parse-duration": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/parse-duration/-/parse-duration-0.1.1.tgz",
+ "integrity": "sha1-ExFN3JiRwezSgANiRFVN5DZHoiY="
+ },
"parse-entities": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-1.1.1.tgz",
diff --git a/package.json b/package.json
index 275c887..b18e2ba 100644
--- a/package.json
+++ b/package.json
@@ -99,6 +99,7 @@
"node-loader": "^0.6.0",
"object-get": "^2.1.0",
"opn": "^5.2.0",
+ "parse-duration": "^0.1.1",
"performance-now": "^2.1.0",
"pretty-ms": "^3.1.0",
"prop-types": "^15.6.0",
diff --git a/src/containers/timer/timer-container.js b/src/containers/timer/timer-container.js
index d4c0d44..aa6a64a 100644
--- a/src/containers/timer/timer-container.js
+++ b/src/containers/timer/timer-container.js
@@ -3,9 +3,10 @@ import React, { Component, Fragment } from 'react'
import { connect } from 'react-redux'
import styled from 'styled-components'
import find from 'lodash.find'
+import parseDuration from 'parse-duration'
import { formatSecondsToStopWatch, roundToNearestMinutes, secondsHuman } from '../../lib/time'
import { openInJira } from '../../lib/jira'
-import { deleteTimer, pauseTimer, postTimer } from '../../modules/timer'
+import { deleteTimer, pauseTimer, postTimer, updateTimer } from '../../modules/timer'
import FontAwesomeIcon from '@fortawesome/react-fontawesome'
import faPlay from '@fortawesome/fontawesome-free-solid/faPlay'
import faPause from '@fortawesome/fontawesome-free-solid/faPause'
@@ -23,11 +24,19 @@ class TimerContainer extends Component {
this.renderTime = true
this.lastTitleUpdate = null
this.state = {
- timers: []
+ timers: [],
+ editingTimer: null,
+ editedTime: ''
}
this.onOpenOptions = this.onOpenOptions.bind(this)
this.displayTimers = this.displayTimers.bind(this)
+ this.onEditTime = this.onEditTime.bind(this)
+ this.onSaveEditedTime = this.onSaveEditedTime.bind(this)
+ this.onChange = this.onChange.bind(this)
+ this.onPlay = this.onPlay.bind(this)
+ this.onResetEditTime = this.onResetEditTime.bind(this)
+ this.onKeyPress = this.onKeyPress.bind(this)
}
componentDidMount () {
@@ -40,6 +49,47 @@ class TimerContainer extends Component {
this.renderTime = false
}
+ onKeyPress (e, timerId) {
+ if (e.key === 'Enter')
+ this.onSaveEditedTime(timerId)
+
+ if (e.key === 'Escape')
+ this.onResetEditTime()
+ }
+
+ onEditTime (timerId) {
+ this.props.pauseTimer(timerId, true)
+
+ this.setState({ editingTimer: timerId })
+ }
+
+ onChange (event) {
+ this.setState({ editedTime: event.target.value })
+ }
+
+ onSaveEditedTime (timerId) {
+
+ let editedTime = this.state.editedTime
+ if (editedTime != '') {
+ let ms = parseDuration(editedTime)
+
+ // Is the timer entered valid?
+ if (ms > 0)
+ this.props.updateTimer(timerId, ms)
+ }
+
+ this.onResetEditTime()
+ }
+
+ onResetEditTime () {
+ this.setState({ editingTimer: null, editedTime: '' })
+ }
+
+ onPlay (timerId) {
+ this.onResetEditTime()
+ this.props.pauseTimer(timerId, false)
+ }
+
displayTimers () {
if (!this.renderTime)
@@ -134,7 +184,7 @@ class TimerContainer extends Component {
) : (
{timer.paused ? (
- this.props.pauseTimer(timer.id, false)}>
+ this.onPlay(timer.id)}>
) : (
@@ -145,7 +195,21 @@ class TimerContainer extends Component {
)}
-
+
{timer.key} {timer.summary}
this.onOpenOptions(timer)}
@@ -159,6 +223,22 @@ class TimerContainer extends Component {
}
}
+const EditTime = styled.input`
+ background: none;
+ border: none;
+ color: #FFF;
+ outline: none;
+ width: 50px;
+ font-weight: 500;
+ letter-spacing: 0.04em;
+ font-size: 13px;
+
+ &::placeholder {
+ color: #FFF;
+ font-style: italic;
+ }
+`
+
const TimerWrapper = styled.div`
padding: 0 15px 0 4px;
background: #2381FA;
@@ -186,7 +266,8 @@ const Time = styled.span`
const mapDispatchToProps = {
deleteTimer,
pauseTimer,
- postTimer
+ postTimer,
+ updateTimer
}
const mapStateToProps = state => ({
diff --git a/src/modules/timer.js b/src/modules/timer.js
index d68ab19..abcb373 100644
--- a/src/modules/timer.js
+++ b/src/modules/timer.js
@@ -12,6 +12,7 @@ const ADD_TIMER = 'jt/timer/ADD_TIMER'
const DELETE_TIMER = 'jt/timer/DELETE_TIMER'
const PAUSE_TIMER = 'jt/timer/PAUSE_TIMER'
const POST_TIMER = 'jt/timer/POST_TIMER'
+const UPDATE_TIMER = 'jt/timer/UPDATE_TIMER'
const initialState = Immutable({
list: []
@@ -79,6 +80,20 @@ export default function reducer (state = initialState, action = {}) {
}
}
+ case UPDATE_TIMER: {
+ let list = Immutable.asMutable(state.list, {deep: true})
+ let timerIndex = findIndex(list, ['id', action.timerId])
+
+ if (timerIndex > -1) {
+ let timer = list[timerIndex]
+ timer.previouslyElapsed = action.ms
+
+ return state.set('list', Immutable(list))
+ } else {
+ return state
+ }
+ }
+
default: return state
}
}
@@ -101,6 +116,12 @@ export const postingTimer = (timerId, posting) => ({
posting
})
+export const updateTimer = (timerId, ms) => ({
+ type: UPDATE_TIMER,
+ timerId,
+ ms
+})
+
// Side effects
export const addTimer = (id, key, summary) => dispatch => {
let timer = {
@@ -154,7 +175,7 @@ export const postTimer = stateTimer => async (dispatch, getState) => {
// Save to recents
dispatch(addRecentTask(timer))
- dispatch(fetchWorklogs())
+ dispatch(fetchWorklogs(false))
})
.catch(error => {
console.log('Error posting timer', error)