|
| 1 | +<script setup lang="ts"> |
| 2 | +import { computed } from 'vue' |
| 3 | +
|
| 4 | +const props = withDefaults( |
| 5 | + defineProps<{ |
| 6 | + ms?: number |
| 7 | + colorize?: boolean |
| 8 | + mode?: 'day' | 'hour' |
| 9 | + }>(), |
| 10 | + { |
| 11 | + colorize: true, |
| 12 | + mode: 'hour', |
| 13 | + }, |
| 14 | +) |
| 15 | +
|
| 16 | +const colorScale = [ |
| 17 | + [180, 'color-scale-neutral'], |
| 18 | + [365, 'color-scale-low'], |
| 19 | + [365 * 3, 'color-scale-medium'], |
| 20 | + [365 * 5, 'color-scale-high'], |
| 21 | + [730 * 5, 'color-scale-critical'], |
| 22 | +] as const |
| 23 | +
|
| 24 | +const MS_PER_DAY = 24 * 60 * 60 * 1000 |
| 25 | +
|
| 26 | +const daysAgo = computed(() => { |
| 27 | + if (props.ms == null) |
| 28 | + return 0 |
| 29 | + return Math.floor(props.ms / MS_PER_DAY) |
| 30 | +}) |
| 31 | +
|
| 32 | +const timeAgo = computed(() => { |
| 33 | + if (!props.ms) |
| 34 | + return ['', ''] |
| 35 | + if (daysAgo.value < 1) { |
| 36 | + if (props.mode === 'day') { |
| 37 | + return ['today', ''] |
| 38 | + } |
| 39 | + else { |
| 40 | + const hoursAgo = Math.floor(props.ms / (1000 * 60 * 60)) |
| 41 | + return [hoursAgo, 'hr'] |
| 42 | + } |
| 43 | + } |
| 44 | + if (daysAgo.value > 365) |
| 45 | + return [+(daysAgo.value / 365).toFixed(1), 'yr'] |
| 46 | + if (daysAgo.value > 30) |
| 47 | + return [Math.round(daysAgo.value / 30), 'mo'] |
| 48 | + return [daysAgo.value, 'd'] |
| 49 | +}) |
| 50 | +
|
| 51 | +const color = computed(() => { |
| 52 | + if (!props.colorize) |
| 53 | + return colorScale[0][1] |
| 54 | +
|
| 55 | + for (const [limit, color] of colorScale) { |
| 56 | + if (daysAgo.value < limit) |
| 57 | + return color |
| 58 | + } |
| 59 | +
|
| 60 | + return colorScale[colorScale.length - 1][1] |
| 61 | +}) |
| 62 | +</script> |
| 63 | + |
| 64 | +<template> |
| 65 | + <div |
| 66 | + v-if="ms" |
| 67 | + :class="color" |
| 68 | + class="px-0.4em py-0.2em line-height-none bg-gray:5 text-sm" |
| 69 | + > |
| 70 | + <span font-mono>{{ timeAgo[0] }}</span> |
| 71 | + <span op-fade text-xs ml0.5>{{ timeAgo[1] }}</span> |
| 72 | + </div> |
| 73 | +</template> |
0 commit comments