Files
Native-Router-Vue/apps/origins-demo/src/views/PlayerView.vue

106 lines
2.8 KiB
Vue

<script setup lang="ts">
import { computed, onBeforeUnmount, ref } from "vue";
import {
OriginGesture,
back,
gesture,
useOrigin,
type OriginContext,
} from "@native-vue-router/core-v2";
import InstanceCard from "../components/InstanceCard.vue";
import { useDemoInstance } from "../lab-state";
import { coverDown } from "../motions";
const origin = useOrigin();
const identity = useDemoInstance("Player");
const playing = ref(false);
const position = ref(38);
const elapsed = computed(() => `1:${String(position.value).padStart(2, "0")}`);
const timer = window.setInterval(() => {
if (playing.value) position.value = (position.value + 1) % 60;
}, 1000);
onBeforeUnmount(() => window.clearInterval(timer));
const dismiss = (context: OriginContext) =>
context.canGoBack ? back(coverDown) : null;
const dismissGesture = gesture.to
.down()
.navigate((context) => (context.canGoBack ? back() : null))
.animate(coverDown);
function close() {
const action = dismiss(origin.context.value);
if (action) void origin.perform(action);
}
</script>
<template>
<OriginGesture class="player-view" :gesture="dismissGesture">
<header class="player-header">
<button type="button" data-origin-gesture="ignore" @click="close">
</button>
<span>Now playing</span>
<button type="button" data-origin-gesture="ignore"></button>
</header>
<div class="album-art">
<span class="album-ring album-ring--one" />
<span class="album-ring album-ring--two" />
<span class="album-center">O</span>
</div>
<section class="track-copy">
<div>
<h1>Independent Frames</h1>
<p>The Scene Graph</p>
</div>
<button
type="button"
data-origin-gesture="ignore"
:aria-pressed="playing"
@click="playing = !playing"
>
{{ playing ? "♥" : "♡" }}
</button>
</section>
<label class="timeline">
<input
v-model="position"
data-origin-gesture="ignore"
type="range"
min="0"
max="59"
/>
<span>{{ elapsed }}</span>
<span>3:42</span>
</label>
<div class="player-controls">
<button type="button" data-origin-gesture="ignore"></button>
<button
class="play-button"
type="button"
data-origin-gesture="ignore"
@click="playing = !playing"
>
{{ playing ? "Ⅱ" : "▶" }}
</button>
<button type="button" data-origin-gesture="ignore"></button>
</div>
<InstanceCard
label="Player instance"
:instance="identity.instance"
:status="identity.status.value"
/>
<p class="policy-note">
Swipe down anywhere to dismiss. Horizontal back is intentionally absent,
like a native full-screen player.
</p>
<div class="drag-handle" />
</OriginGesture>
</template>