Skip to content
This repository has been archived by the owner on Nov 9, 2021. It is now read-only.

Commit

Permalink
Edit active timer time
Browse files Browse the repository at this point in the history
  • Loading branch information
alexcroox committed Feb 7, 2018
1 parent 01e5ea3 commit 8c4c8ef
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 6 deletions.
5 changes: 5 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
91 changes: 86 additions & 5 deletions src/containers/timer/timer-container.js
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand All @@ -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 () {
Expand All @@ -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)
Expand Down Expand Up @@ -134,7 +184,7 @@ class TimerContainer extends Component {
) : (
<Fragment>
{timer.paused ? (
<Control light onClick={() => this.props.pauseTimer(timer.id, false)}>
<Control light onClick={() => this.onPlay(timer.id)}>
<FontAwesomeIcon icon={faPlay} />
</Control>
) : (
Expand All @@ -145,7 +195,21 @@ class TimerContainer extends Component {
</Fragment>
)}

<Time>{timer.stopWatchDisplay}</Time>
<Time>
{this.state.editingTimer === timer.id ? (
<EditTime
autoFocus
value={this.state.editedTime}
onChange={this.onChange}
placeholder={secondsHuman(Math.round(timer.previouslyElapsed / 1000))}
onKeyUp={(e) => this.onKeyPress(e, timer.id)}
/>
) : (
<span onClick={() => this.onEditTime(timer.id)}>
{timer.stopWatchDisplay}
</span>
)}
</Time>
<TaskTitle>{timer.key} {timer.summary}</TaskTitle>
<OptionDots
onClick={() => this.onOpenOptions(timer)}
Expand All @@ -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;
Expand Down Expand Up @@ -186,7 +266,8 @@ const Time = styled.span`
const mapDispatchToProps = {
deleteTimer,
pauseTimer,
postTimer
postTimer,
updateTimer
}

const mapStateToProps = state => ({
Expand Down
23 changes: 22 additions & 1 deletion src/modules/timer.js
Original file line number Diff line number Diff line change
Expand Up @@ -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: []
Expand Down Expand Up @@ -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
}
}
Expand All @@ -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 = {
Expand Down Expand Up @@ -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)
Expand Down

0 comments on commit 8c4c8ef

Please sign in to comment.