diff options
| author | syuilo <Syuilotan@yahoo.co.jp> | 2023-01-10 06:08:40 +0900 |
|---|---|---|
| committer | syuilo <Syuilotan@yahoo.co.jp> | 2023-01-10 06:08:40 +0900 |
| commit | 618405c4d39753c1a9135fd0759aff2ecb3a94b3 (patch) | |
| tree | b0551494d3ffd37ee3e7f7ad75bc81f54d3fb249 /packages/frontend/src/widgets/WidgetCalendar.vue | |
| parent | refactor(client): use css modules (diff) | |
| download | misskey-618405c4d39753c1a9135fd0759aff2ecb3a94b3.tar.gz misskey-618405c4d39753c1a9135fd0759aff2ecb3a94b3.tar.bz2 misskey-618405c4d39753c1a9135fd0759aff2ecb3a94b3.zip | |
refactor(client): rename widget filename
Diffstat (limited to 'packages/frontend/src/widgets/WidgetCalendar.vue')
| -rw-r--r-- | packages/frontend/src/widgets/WidgetCalendar.vue | 214 |
1 files changed, 214 insertions, 0 deletions
diff --git a/packages/frontend/src/widgets/WidgetCalendar.vue b/packages/frontend/src/widgets/WidgetCalendar.vue new file mode 100644 index 0000000000..1bd431259a --- /dev/null +++ b/packages/frontend/src/widgets/WidgetCalendar.vue @@ -0,0 +1,214 @@ +<template> +<div class="mkw-calendar" :class="{ _panel: !widgetProps.transparent }"> + <div class="calendar" :class="{ isHoliday }"> + <p class="month-and-year"> + <span class="year">{{ $t('yearX', { year }) }}</span> + <span class="month">{{ $t('monthX', { month }) }}</span> + </p> + <p v-if="month === 1 && day === 1" class="day">🎉{{ $t('dayX', { day }) }}<span style="display: inline-block; transform: scaleX(-1);">🎉</span></p> + <p v-else class="day">{{ $t('dayX', { day }) }}</p> + <p class="week-day">{{ weekDay }}</p> + </div> + <div class="info"> + <div> + <p>{{ i18n.ts.today }}<b>{{ dayP.toFixed(1) }}%</b></p> + <div class="meter"> + <div class="val" :style="{ width: `${dayP}%` }"></div> + </div> + </div> + <div> + <p>{{ i18n.ts.thisMonth }}<b>{{ monthP.toFixed(1) }}%</b></p> + <div class="meter"> + <div class="val" :style="{ width: `${monthP}%` }"></div> + </div> + </div> + <div> + <p>{{ i18n.ts.thisYear }}<b>{{ yearP.toFixed(1) }}%</b></p> + <div class="meter"> + <div class="val" :style="{ width: `${yearP}%` }"></div> + </div> + </div> + </div> +</div> +</template> + +<script lang="ts" setup> +import { onUnmounted, ref } from 'vue'; +import { useWidgetPropsManager, Widget, WidgetComponentEmits, WidgetComponentExpose, WidgetComponentProps } from './widget'; +import { GetFormResultType } from '@/scripts/form'; +import { i18n } from '@/i18n'; +import { useInterval } from '@/scripts/use-interval'; + +const name = 'calendar'; + +const widgetPropsDef = { + transparent: { + type: 'boolean' as const, + default: false, + }, +}; + +type WidgetProps = GetFormResultType<typeof widgetPropsDef>; + +// 現時点ではvueの制限によりimportしたtypeをジェネリックに渡せない +//const props = defineProps<WidgetComponentProps<WidgetProps>>(); +//const emit = defineEmits<WidgetComponentEmits<WidgetProps>>(); +const props = defineProps<{ widget?: Widget<WidgetProps>; }>(); +const emit = defineEmits<{ (ev: 'updateProps', props: WidgetProps); }>(); + +const { widgetProps, configure } = useWidgetPropsManager(name, + widgetPropsDef, + props, + emit, +); + +const year = ref(0); +const month = ref(0); +const day = ref(0); +const weekDay = ref(''); +const yearP = ref(0); +const monthP = ref(0); +const dayP = ref(0); +const isHoliday = ref(false); +const tick = () => { + const now = new Date(); + const nd = now.getDate(); + const nm = now.getMonth(); + const ny = now.getFullYear(); + + year.value = ny; + month.value = nm + 1; + day.value = nd; + weekDay.value = [ + i18n.ts._weekday.sunday, + i18n.ts._weekday.monday, + i18n.ts._weekday.tuesday, + i18n.ts._weekday.wednesday, + i18n.ts._weekday.thursday, + i18n.ts._weekday.friday, + i18n.ts._weekday.saturday, + ][now.getDay()]; + + const dayNumer = now.getTime() - new Date(ny, nm, nd).getTime(); + const dayDenom = 1000/*ms*/ * 60/*s*/ * 60/*m*/ * 24/*h*/; + const monthNumer = now.getTime() - new Date(ny, nm, 1).getTime(); + const monthDenom = new Date(ny, nm + 1, 1).getTime() - new Date(ny, nm, 1).getTime(); + const yearNumer = now.getTime() - new Date(ny, 0, 1).getTime(); + const yearDenom = new Date(ny + 1, 0, 1).getTime() - new Date(ny, 0, 1).getTime(); + + dayP.value = dayNumer / dayDenom * 100; + monthP.value = monthNumer / monthDenom * 100; + yearP.value = yearNumer / yearDenom * 100; + + isHoliday.value = now.getDay() === 0 || now.getDay() === 6; +}; + +useInterval(tick, 1000, { + immediate: true, + afterMounted: false, +}); + +defineExpose<WidgetComponentExpose>({ + name, + configure, + id: props.widget ? props.widget.id : null, +}); +</script> + +<style lang="scss" scoped> +.mkw-calendar { + padding: 16px 0; + + &:after { + content: ""; + display: block; + clear: both; + } + + > .calendar { + float: left; + width: 60%; + text-align: center; + + &.isHoliday { + > .day { + color: #ef95a0; + } + } + + > .month-and-year, > .week-day { + margin: 0; + line-height: 18px; + font-size: 0.9em; + + > .year, > .month { + margin: 0 4px; + } + } + + > .day { + margin: 10px 0; + line-height: 32px; + font-size: 1.75em; + } + } + + > .info { + display: block; + float: left; + width: 40%; + padding: 0 16px 0 0; + box-sizing: border-box; + + > div { + margin-bottom: 8px; + + &:last-child { + margin-bottom: 4px; + } + + > p { + display: flex; + margin: 0 0 2px 0; + font-size: 0.75em; + line-height: 18px; + opacity: 0.8; + + > b { + margin-left: auto; + } + } + + > .meter { + width: 100%; + overflow: hidden; + background: var(--X11); + border-radius: 8px; + + > .val { + height: 4px; + transition: width .3s cubic-bezier(0.23, 1, 0.32, 1); + } + } + + &:nth-child(1) { + > .meter > .val { + background: #f7796c; + } + } + + &:nth-child(2) { + > .meter > .val { + background: #a1de41; + } + } + + &:nth-child(3) { + > .meter > .val { + background: #41ddde; + } + } + } + } +} +</style> |