54 lines
1.9 KiB
Vue
54 lines
1.9 KiB
Vue
<script setup lang="ts">
|
|
import { ref } from 'vue'
|
|
import { useNativeViewActiveEffect } from '@native-vue-router/core'
|
|
import AppAvatar from '../components/AppAvatar.vue'
|
|
import AppHeader from '../components/AppHeader.vue'
|
|
import { useDemoStore } from '../data'
|
|
|
|
const store = useDemoStore()
|
|
const mountId = crypto.randomUUID()
|
|
const mountedAt = Date.now()
|
|
const mountedSeconds = ref(0)
|
|
const activeTicks = ref(0)
|
|
|
|
useNativeViewActiveEffect(() => {
|
|
const update = () => {
|
|
mountedSeconds.value = Math.floor((Date.now() - mountedAt) / 1_000)
|
|
activeTicks.value += 1
|
|
}
|
|
update()
|
|
const timer = window.setInterval(update, 200)
|
|
return () => window.clearInterval(timer)
|
|
})
|
|
const gradients = [
|
|
'linear-gradient(155deg, #f4a261, #d64e7d 48%, #5427a8)',
|
|
'linear-gradient(155deg, #44c6e9, #4378db 48%, #1b245d)',
|
|
'linear-gradient(155deg, #68d391, #2a9d8f 48%, #173e48)',
|
|
'linear-gradient(155deg, #b794f4, #805ad5 48%, #322659)',
|
|
]
|
|
</script>
|
|
|
|
<template>
|
|
<main
|
|
class="screen screen--tabs"
|
|
data-testid="stories-view"
|
|
:data-mount-id="mountId"
|
|
:data-mounted-seconds="mountedSeconds"
|
|
:data-active-ticks="activeTicks"
|
|
>
|
|
<AppHeader title="Stories" subtitle="Moments from your circle" large />
|
|
<section class="story-grid">
|
|
<article v-for="(person, index) in store.people.value.slice(0, 4)" :key="person.id" class="story-card" :style="{ background: gradients[index] }">
|
|
<div class="story-card__glow" />
|
|
<AppAvatar :person="person" size="sm" />
|
|
<div>
|
|
<strong>{{ person.name }}</strong>
|
|
<p>{{ index % 2 ? '2 hours ago' : 'Just now' }}</p>
|
|
</div>
|
|
<span class="story-card__mark">{{ ['✦', '◌', '△', '◇'][index] }}</span>
|
|
</article>
|
|
</section>
|
|
<p class="gesture-tip">Mounted {{ mountedSeconds }}s · active work {{ activeTicks }} ticks. The tick loop pauses while this sibling is cached.</p>
|
|
</main>
|
|
</template>
|