66 lines
1.7 KiB
Vue
66 lines
1.7 KiB
Vue
<script setup lang="ts">
|
|
import { nextTick, ref } from "vue";
|
|
import { back, slideRight, useOrigin } from "@native-vue-router/core-v2";
|
|
import InstanceCard from "../components/InstanceCard.vue";
|
|
import { useDemoInstance } from "../lab-state";
|
|
|
|
const origin = useOrigin();
|
|
const identity = useDemoInstance("Chat");
|
|
const draft = ref("");
|
|
const messages = ref([
|
|
"This page deliberately owns no edge recognizer.",
|
|
"Try swiping right. Nothing should happen.",
|
|
]);
|
|
|
|
function goBack() {
|
|
if (origin.context.value.canGoBack) void origin.perform(back(slideRight));
|
|
}
|
|
|
|
async function send() {
|
|
const message = draft.value.trim();
|
|
if (!message) return;
|
|
messages.value.push(message);
|
|
draft.value = "";
|
|
await nextTick();
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<!--
|
|
No gesture binding is used here. Gesture absence is the policy, rather
|
|
than a global back gesture followed by an exception.
|
|
-->
|
|
<div class="chat-view">
|
|
<header class="chat-header">
|
|
<button type="button" @click="goBack">←</button>
|
|
<div class="chat-avatar">M</div>
|
|
<div>
|
|
<strong>Maya</strong>
|
|
<span>online</span>
|
|
</div>
|
|
<span class="chat-lock">edge locked</span>
|
|
</header>
|
|
|
|
<main class="messages">
|
|
<div
|
|
v-for="(message, index) in messages"
|
|
:key="`${index}-${message}`"
|
|
class="message"
|
|
:class="{ 'message--mine': index > 1 }"
|
|
>
|
|
{{ message }}
|
|
</div>
|
|
<InstanceCard
|
|
label="Chat instance"
|
|
:instance="identity.instance"
|
|
:status="identity.status.value"
|
|
/>
|
|
</main>
|
|
|
|
<form class="composer" @submit.prevent="send">
|
|
<input v-model="draft" placeholder="Write something…" />
|
|
<button type="submit">Send</button>
|
|
</form>
|
|
</div>
|
|
</template>
|