git.fiddlerwoaroof.com
Raw Blame History
<template>
    <div id="app">
	<header>
	    <h1>
		Timer
	    </h1>
	    <div>
		<button @click="mark">Go</button>
		<button @click="reset">Reset</button>
	    </div>
	</header>
	<ol>
	    <li class=header>
		<div>Time</div><div>Lap Time</div><div>Cumulative</div>
	    </li>

	    <li v-for="[time,diff,cum,new_annotation] in times">
		<div class="time">{{formatTime(time.time)}}</div>
		<div class="diff"><div class="time">{{formatDiff(diff)[0]}}</div><div class="mills">.{{formatDiff(diff)[1]}}</div></div>
		<div class="cum"><div class="time">{{formatDiff(cum)[0]}}</div><div class="mills">.{{formatDiff(cum)[1]}}</div></div>
		<div class="actions">
		    <form @submit.prevent="annotate(time.id, new_annotation)">
		    <input type=text v-model="new_annotation">
		    <button type="submit">+</button>
		    </form>
		</div>
		<ul v-show="time.annotations.length > 0">
		    <li class="annotation" v-for="annotation in time.annotations">
			<div>
			    {{annotation.text}}
			</div>
			<time datetime="annotation.time">{{formatTime(annotation.time)}}</time>
		    </li>
		</ul>
		
	    </li>
	</ol>
    </div>
  </template>

<script>

import {mapGetters} from 'vuex';

export default {
    name: 'app',
    data () {
	return {
	    msg: 'Welcome to Your Vue.js App',
	    curTime: Date.now(),
	}
    },

    beforeMount() {
	// this.$data.curTime = new Date();
	// console.log('foo');
	// window.setInterval( () => {
	//     console.log(this.$data);
	//     this.$data.curTime = new Date();
	// }, 100);
    },

    computed: {
	times() {
	    let result = [];
	    for (let cur of this.$store.state.times) {
		if ((typeof cur.time) === "string") {
		    cur = Object.assign(
			Object.create(cur),
			{time: new Date(cur.time)}
		    );
		}
		
		let diff = 0, cum = 0;
		if (cur.id > 0) {
		    cum = cur.time - result[cur.id-1][0].time;
		    diff = cur.time-result[0][0].time
		}

		result.unshift([cur, diff, cum, '']);
	    }
	    return result;
	},
    },

    methods: {
	reset() {
	    this.$store.commit('reset');
	},
	
	annotate(idx, annotation) {
	    this.$store.commit('annotate', {idx, annotation});
	},
	mark() {
	    this.$store.commit('add');
	},

	formatTime: function (time) {
	    return (new Intl.DateTimeFormat('en-US', {
		year:'numeric', month:'numeric', day:'numeric', hour:'2-digit', minute: '2-digit', second:'2-digit'
	    })).format(time.time);
	},

	formatDiff(diff) {
	    let secs = Math.floor(diff/1000),
		mills = diff % 1000,
		mins = Math.floor(secs/60);
	    secs = secs % 60;
	    mins = `${mins}`;
	    if (mills.length < 3) {
		let pad = '0'*(3-mills.length);
		mills = pad + mills;
	    }
	    let result = `${secs}`
	    if (mins > 0) {
		result = `${mins}:${result.padStart(2,'0')}`;
	    }
	    return [result,mills];
	}
    },
}
    </script>

<style lang="scss">
  * { box-sizing: border-box; }
    #app {
	font-family: 'Lato', Helvetica, Arial, sans-serif;
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
	text-align: right;
	color: #2c3e50;
    }

    header {
	display: grid;
	grid-template-columns: 75fr 25fr;
	height: 3em;
	line-height: 3em;
	padding: 0;
    }
    
    h1, h2 {
	text-align: center;
	font-size: 1.25em;
	padding: 0;
	margin: 0;
    }

    ul {
	list-style-type: none;
	padding: 0;
    }

    a {
	color: #42b983;
    }

    ol {
	position: absolute;
	width: 100%;
	top: 4em;
	bottom: 0;
	left: 0;
	margin: 0;
	padding: 0 1em;
	padding-top: 3.25em;
	overflow-y: scroll;
	overflow-x: auto;
    }

    ol > li {
	display: grid;
	grid-template-columns: 25fr 12.5fr 12.5fr 25fr 25fr;
	padding: 0.5em;
	margin-bottom: 0.25em;
    }

    li.header {
	position: fixed;
	top: 4em;
	left: 1em;
	right: 1em;
	background: #eee;
    }

    ul {
	/* grid-column-start: 2; */
	/* grid-column-end: span 2; */
	padding: 0.25em;
	margin: 0.25em;
	padding-right: 0;
	margin-right: 0;
    }
    ul > li {
	padding: 0.2em 1em;
	background: #ffb;
	font-style: italic;
    }
    ul > li+li {
	border-top: 0.25em double #eee;
    }

    .diff, .cum {
	text-align: right;
    }
    
    .diff div, .cum div {
	display: inline-block;
    }

    .diff .time, .cum .time {
	max-width: 80%;
	text-align: right;
    }

    .diff .mills, .cum .mills {
	width: 20%;
	text-align: left;
    }

    button {
	height: 100%;
    }

    .annotation {
	color: #888;
	}
    .annotation time::before {
	content: "— "
    }
    .annotation time {
	font-size: 60%;

    }
</style>