-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathItemSingle.vue
166 lines (142 loc) · 3.59 KB
/
ItemSingle.vue
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
<template lang="pug">
.screen
header.bar
.bar-block
router-link.bar-button._start(
:to="{ name: 'List' }"
) ← Back
router-link.bar-button._end(
:to="{ name: 'Edit' }"
) Edit
.bar-block
h1 {{ item.label }}
main
template(v-if="item")
.list-item.date-item
.list-item-inner
time(:datetime="item.datetime") {{ dateString }}
.list-item.sentence-item
.list-item-inner
p(v-html="sentence")
counter(
type="seconds"
:milliseconds="milliseconds"
)
counter(
type="minutes"
:milliseconds="milliseconds"
)
counter(
type="hours"
:milliseconds="milliseconds"
)
counter(
type="days"
:milliseconds="milliseconds"
)
counter(
type="weeks"
:milliseconds="milliseconds"
)
counter(
type="months"
:milliseconds="milliseconds"
)
counter(
type="years"
:milliseconds="milliseconds"
)
template(v-else)
.layout
p That doesn’t exist
p
router-link(:to="{ name: 'List' }") Go to the list
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator'
import { formatDistanceStrict } from 'date-fns'
import Counter from '@/components/Counter.vue'
@Component({
components: {
Counter,
},
filters: {
thousands: (n: number) => {
return n.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,')
},
fromNow: (date: string) => {
return formatDistanceStrict(new Date(date), new Date(), {
addSuffix: true,
})
},
},
})
export default class ItemSingle extends Vue {
tick: number = 0
tickInterval: any = null
get itemId() {
return this.$route.params.id
}
get item() {
return this.$store.getters.getItemById(this.itemId)
}
mounted() {
this.tickInterval = setInterval(() => {
this.tick++
}, 1000)
}
beforeDestroy() {
clearInterval(this.tickInterval)
}
get dateString() {
const options = {
timeZone: this.item.timezone,
dateStyle: 'full',
timeStyle: 'full',
}
const date = new Date(this.item.datetime).toLocaleString(
navigator.language,
options
)
return date.replace(':00 ', ' ')
}
get now() {
const t = this.tick // force update
return new Date().getTime()
}
get then() {
return new Date(this.item.datetime).getTime()
}
get milliseconds() {
const d = this.then - this.now
return d
}
get sentence() {
let seconds = Math.abs(this.milliseconds) / 1000
const strings: string[] = []
const units = [
{ label: 'years', divisor: 31557600 },
{ label: 'months', divisor: 2629800 },
{ label: 'days', divisor: 86400 },
{ label: 'hours', divisor: 3600 },
{ label: 'minutes', divisor: 60 },
{ label: 'seconds', divisor: 0 },
]
units.forEach(unit => {
const total = Math.floor(seconds / (unit.divisor || 1))
seconds -= total * unit.divisor
if (total) {
const unitLabel =
total === 1 ? unit.label.substr(0, unit.label.length - 1) : unit.label
strings.push(`<span class="tabular">${total}</span> ${unitLabel}`)
}
})
if (this.milliseconds < 0) {
const lastIndex = strings.length - 1
const suffixString = `${strings[lastIndex]} ago`
strings.splice(lastIndex, 1, suffixString)
}
return strings.join(', ')
}
}
</script>