feat: add duration in the timeline

This commit is contained in:
Adrien Marquès 2022-10-12 19:00:34 +02:00
parent 0098c0708f
commit 043a36d15f
Signed by: xdrm-brackets
GPG Key ID: D75243CA236D825E
3 changed files with 53 additions and 8 deletions

View File

@ -61,10 +61,10 @@
</div> </div>
<div :key="'end-'+proj.name" class='end'> <div :key="'end-'+proj.name" class='end'>
<template v-if='proj.stopped_at != null'> <template v-if='proj.stopped_at != null'>
{{ $t('project.end') }} {{ proj.stopped_at | short_date }} <span>{{ elapsed(proj.stopped_at) }}</span> {{ $t('project.end') }} {{ proj.stopped_at | short_date }} <span>{{ duration(proj.started_at, proj.stopped_at, true) }}</span>
</template> </template>
<template v-else> <template v-else>
{{ $t('project.still') }} {{ $t('project.still') }} <span>{{ duration(proj.started_at, new Date(), false) }}</span>
</template> </template>
</div> </div>
@ -90,17 +90,16 @@ interface TimeDiff {
plural: string; // plural translation label plural: string; // plural translation label
} }
// returns a TimeDiff from a date. Holds the time elapsed until now in the most // returns a TimeDiff from a date. Holds the time elapsed until @stop in the most
// broad unit that is greater than 0. // broad unit that is greater than 0.
function getTimeDiff(date: Date): TimeDiff { function getTimeDiff(start: Date, stop: Date): TimeDiff {
const minute = 60 * 1000; const minute = 60 * 1000;
const hour = 60 * minute; const hour = 60 * minute;
const day = 24 * hour; const day = 24 * hour;
const month = 30 * day; const month = 30 * day;
const year = 365 * day; const year = 365 * day;
const now = new Date(); const diff = stop.getTime() - start.getTime();
const diff = now.getTime() - date.getTime();
if ( diff < 0 ) { if ( diff < 0 ) {
return {diff: 0, one: 'time.some', plural: 'time.some'}; return {diff: 0, one: 'time.some', plural: 'time.some'};
@ -153,7 +152,7 @@ export default class Timeline extends Vue {
protected elapsed(date: Date): string { protected elapsed(date: Date): string {
const fmt = 'time.diff-format'; const fmt = 'time.diff-format';
const td = getTimeDiff(date); const td = getTimeDiff(date, new Date());
const diff = Math.floor(td.diff); const diff = Math.floor(td.diff);
@ -168,6 +167,22 @@ export default class Timeline extends Vue {
return this.$t(fmt, { elapsed: this.$t(td.one, { n: diff }) }).toString(); return this.$t(fmt, { elapsed: this.$t(td.one, { n: diff }) }).toString();
} }
protected duration(start: Date, stop: Date, ended: boolean): string {
const fmt = ended ? 'time.dur-format' : 'time.cur-format';
const td = getTimeDiff(start, stop);
const diff = Math.floor(td.diff);
if( diff == 0 ){
return this.$t(fmt, { duration: this.$t(td.one) }).toString();
}
if( diff > 1 ){ // plural
return this.$t(fmt, { duration: this.$t(td.plural, { n: diff }) }).toString();
}
// singular
return this.$t(fmt, { duration: this.$t(td.one, { n: diff }) }).toString();
}
private onScroll(e: Event) { private onScroll(e: Event) {
const target = e.target as HTMLElement; const target = e.target as HTMLElement;
const header = this.$refs.header as HTMLElement; const header = this.$refs.header as HTMLElement;
@ -214,6 +229,7 @@ export default class Timeline extends Vue {
width: 100%; width: 100%;
height: $header-height; height: $header-height;
font-size: 1em;
background: #202228; background: #202228;
box-shadow: 0 0 1em transparent; box-shadow: 0 0 1em transparent;
@ -229,6 +245,8 @@ export default class Timeline extends Vue {
border-radius .2s ease-in-out, border-radius .2s ease-in-out,
box-shadow .1s ease-in-out; box-shadow .1s ease-in-out;
overflow: hidden;
img { img {
width: $logo-size; width: $logo-size;
height: $logo-size; height: $logo-size;
@ -245,6 +263,8 @@ export default class Timeline extends Vue {
margin: auto; margin: auto;
flex-flow: row nowrap; flex-flow: row nowrap;
justify-content: space-around;
align-items: center;
h3 { h3 {
color: #fff; color: #fff;
@ -473,6 +493,7 @@ export default class Timeline extends Vue {
padding-bottom: 2em; padding-bottom: 2em;
margin-bottom: 1.5em; margin-bottom: 1.5em;
color: #c1c1c1;
background: #323841; background: #323841;
border: .1rem solid #45454b; border: .1rem solid #45454b;
@ -540,4 +561,25 @@ export default class Timeline extends Vue {
} }
</style>
<style lang="scss">
// for translated styles
.desc {
b {
color: #fff;
}
i {
color: #d5d5d5;
}
li {
list-style-type: none;
list-style-image: url('../assets/timeline/list-icon.svg');
margin-left: 1.5em;
}
}
</style> </style>

View File

@ -76,6 +76,8 @@
"skill.rnd": "R&D", "skill.rnd": "R&D",
"skill.teamlead": "Team Lead", "skill.teamlead": "Team Lead",
"time.dur-format": "took {duration}",
"time.cur-format": "since {duration}",
"time.diff-format": "{elapsed} ago", "time.diff-format": "{elapsed} ago",
"time.some": "sometime", "time.some": "sometime",

View File

@ -38,7 +38,8 @@
"skill.concurrency": "Programmation Concurrente", "skill.concurrency": "Programmation Concurrente",
"skill.teamlead": "Chef d'équipe", "skill.teamlead": "Chef d'équipe",
"time.dur-format": "a duré {duration}",
"time.cur-format": "depuis {duration}",
"time.diff-format": "il y a {elapsed}", "time.diff-format": "il y a {elapsed}",
"time.some": "un moment", "time.some": "un moment",