fix(stage-web): mobile screensafe area & style issues
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
<meta charset="UTF-8" />
|
||||
<title>AIRI</title>
|
||||
<meta name="description" content="Open source attempt to create cyber companion">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover" />
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg" sizes="any" />
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
|
||||
<meta name="theme-color" content="rgb(18,18,18)" id="themeColor" />
|
||||
|
||||
@@ -4,7 +4,7 @@ import type { ChatProvider } from '@xsai-ext/shared-providers'
|
||||
import { useMicVAD } from '@proj-airi/stage-ui/composables'
|
||||
import { useChatStore, useConsciousnessStore, useProvidersStore, useSettings } from '@proj-airi/stage-ui/stores'
|
||||
import { BasicTextarea } from '@proj-airi/ui'
|
||||
import { useDark } from '@vueuse/core'
|
||||
import { useDark, useResizeObserver, useScreenSafeArea } from '@vueuse/core'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { onMounted, ref, useTemplateRef, watch } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
@@ -23,9 +23,12 @@ const messageInput = ref('')
|
||||
const listening = ref(false)
|
||||
const isComposing = ref(false)
|
||||
|
||||
const screenSafeArea = useScreenSafeArea()
|
||||
const providersStore = useProvidersStore()
|
||||
const { activeProvider, activeModel } = storeToRefs(useConsciousnessStore())
|
||||
|
||||
useResizeObserver(document.documentElement, () => screenSafeArea.update())
|
||||
|
||||
// const { audioInputs } = useDevicesList({ constraints: { audio: true }, requestPermissions: true })
|
||||
// const { selectedAudioDevice, isAudioInputOn, selectedAudioDeviceId } = storeToRefs(useSettings())
|
||||
const { isAudioInputOn, selectedAudioDeviceId, themeColorsHueDynamic, stageView, stageViewControlsEnabled } = storeToRefs(useSettings())
|
||||
@@ -105,6 +108,7 @@ watch([activeProvider, activeModel], async () => {
|
||||
|
||||
onMounted(() => {
|
||||
start()
|
||||
screenSafeArea.update()
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -112,14 +116,14 @@ onMounted(() => {
|
||||
<div fixed bottom-0 w-full flex flex-col>
|
||||
<KeepAlive>
|
||||
<Transition name="fade">
|
||||
<MobileChatHistory v-if="!stageViewControlsEnabled" max-w="[calc(100%-3.5rem)]" w-full self-start pl-2 />
|
||||
<MobileChatHistory v-if="!stageViewControlsEnabled" max-w="[calc(100%-3.5rem)]" w-full self-start pl-3 />
|
||||
</Transition>
|
||||
</KeepAlive>
|
||||
<div relative w-full self-end>
|
||||
<div top="50%" translate-y="[-50%]" fixed z-15 px-2>
|
||||
<div top="50%" translate-y="[-50%]" fixed z-15 px-3>
|
||||
<ViewControlInputs ref="viewControlsInputs" :mode="viewControlsActiveMode" />
|
||||
</div>
|
||||
<div translate-y="[-100%]" absolute right-0 w-full px-2 pb-2 font-sans>
|
||||
<div translate-y="[-100%]" absolute right-0 w-full px-3 pb-3 font-sans>
|
||||
<div flex="~ col" w-full gap-1>
|
||||
<button border="2 solid neutral-100/60 dark:neutral-800/30" bg="neutral-50/70 dark:neutral-800/70" w-fit flex items-center self-end justify-center rounded-xl p-2 backdrop-blur-md title="About">
|
||||
<div i-solar:info-circle-outline size-5 text="neutral-500 dark:neutral-400" />
|
||||
@@ -150,11 +154,11 @@ onMounted(() => {
|
||||
<ActionViewControls v-model="viewControlsActiveMode" @reset="() => viewControlsInputsRef?.resetOnMode()" />
|
||||
</div>
|
||||
</div>
|
||||
<div bg="white dark:neutral-800" w-full flex gap-1 px-2 py-2>
|
||||
<div bg="white dark:neutral-800" max-h-100dvh max-w-100dvw w-full flex gap-1 overflow-auto px-3 pt-2 :style="{ paddingBottom: `${Math.max(Number.parseFloat(screenSafeArea.bottom.value.replace('px', '')), 12)}px` }">
|
||||
<BasicTextarea
|
||||
v-model="messageInput"
|
||||
:placeholder="t('stage.message')"
|
||||
border="solid 2 primary-50 dark:primary-950/10"
|
||||
border="solid 2 neutral-200/60 dark:neutral-700/60"
|
||||
text="neutral-500 hover:neutral-600 dark:neutral-100 dark:hover:neutral-200 placeholder:neutral-400 placeholder:hover:neutral-500 placeholder:dark:neutral-300 placeholder:dark:hover:neutral-400"
|
||||
bg="neutral-100/80 dark:neutral-950/80"
|
||||
max-h="[10lh]" min-h="[calc(1lh+4px+4px)]"
|
||||
|
||||
@@ -1,19 +1,9 @@
|
||||
<script setup lang="ts">
|
||||
import { useScreenSafeArea } from '@vueuse/core'
|
||||
|
||||
const { top, right, bottom, left } = useScreenSafeArea()
|
||||
import { RouterView } from 'vue-router'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<main
|
||||
text="gray-700 dark:gray-200" h-full font-cuteen
|
||||
:style="{
|
||||
paddingTop: `${top}px`,
|
||||
paddingRight: `${right}px`,
|
||||
paddingBottom: `${bottom}px`,
|
||||
paddingLeft: `${left}px`,
|
||||
}"
|
||||
>
|
||||
<main text="gray-700 dark:gray-200" font-cuteen h-full>
|
||||
<RouterView />
|
||||
</main>
|
||||
</template>
|
||||
|
||||
@@ -297,7 +297,7 @@ onMounted(() => {
|
||||
<!-- Provider Selection -->
|
||||
<template v-else-if="step === 2">
|
||||
<div h-full flex flex-col gap-4>
|
||||
<div bg="white dark:#181818" sticky top-0 z-100 flex flex-shrink-0 items-center gap-2>
|
||||
<div sticky top-0 z-100 flex flex-shrink-0 items-center gap-2>
|
||||
<button outline-none @click="handlePreviousStep">
|
||||
<div class="i-solar:alt-arrow-left-line-duotone h-5 w-5" />
|
||||
</button>
|
||||
@@ -332,7 +332,7 @@ onMounted(() => {
|
||||
<!-- Configuration Form -->
|
||||
<template v-else-if="step === 3 && selectedProvider">
|
||||
<div h-full flex flex-col gap-4>
|
||||
<div bg="white dark:#181818" sticky top-0 z-100 flex flex-shrink-0 items-center gap-2>
|
||||
<div sticky top-0 z-100 flex flex-shrink-0 items-center gap-2>
|
||||
<button outline-none @click="handlePreviousStep">
|
||||
<div i-solar:alt-arrow-left-line-duotone h-5 w-5 />
|
||||
</button>
|
||||
@@ -422,7 +422,7 @@ onMounted(() => {
|
||||
<!-- Models Configuration Form -->
|
||||
<template v-else-if="step === 4 && selectedProvider">
|
||||
<div h-full flex flex-col gap-4>
|
||||
<div bg="white dark:#181818" sticky top-0 z-100 flex flex-shrink-0 items-center gap-2>
|
||||
<div sticky top-0 z-100 flex flex-shrink-0 items-center gap-2>
|
||||
<button outline-none @click="handlePreviousStep">
|
||||
<div i-solar:alt-arrow-left-line-duotone h-5 w-5 />
|
||||
</button>
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
<script setup lang="ts">
|
||||
import { useMediaQuery } from '@vueuse/core'
|
||||
import { useMediaQuery, useResizeObserver, useScreenSafeArea } from '@vueuse/core'
|
||||
import { DialogContent, DialogOverlay, DialogPortal, DialogRoot } from 'reka-ui'
|
||||
import { DrawerContent, DrawerHandle, DrawerOverlay, DrawerPortal, DrawerRoot } from 'vaul-vue'
|
||||
import { onMounted } from 'vue'
|
||||
|
||||
import Onboarding from './Onboarding.vue'
|
||||
|
||||
@@ -13,6 +14,10 @@ const emit = defineEmits<{
|
||||
const showDialog = defineModel({ type: Boolean, default: false, required: false })
|
||||
|
||||
const isDesktop = useMediaQuery('(min-width: 768px)')
|
||||
const screenSafeArea = useScreenSafeArea()
|
||||
|
||||
useResizeObserver(document.documentElement, () => screenSafeArea.update())
|
||||
onMounted(() => screenSafeArea.update())
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -27,7 +32,7 @@ const isDesktop = useMediaQuery('(min-width: 768px)')
|
||||
<DrawerRoot v-else :open="showDialog" should-scale-background @update:open="value => showDialog = value">
|
||||
<DrawerPortal>
|
||||
<DrawerOverlay class="fixed inset-0" />
|
||||
<DrawerContent class="fixed bottom-0 left-0 right-0 z-1000 mt-20 h-full max-h-[96%] flex flex-col rounded-t-2xl bg-neutral-50 p-4 outline-none backdrop-blur-md dark:bg-neutral-900/95">
|
||||
<DrawerContent class="fixed bottom-0 left-0 right-0 z-1000 mt-20 h-full max-h-[96%] flex flex-col rounded-t-2xl bg-neutral-50 px-4 pt-4 outline-none backdrop-blur-md dark:bg-neutral-900/95" :style="{ paddingBottom: `${Math.max(Number.parseFloat(screenSafeArea.bottom.value.replace('px', '')), 12)}px` }">
|
||||
<DrawerHandle />
|
||||
<Onboarding @configured="emit('configured')" @skipped="emit('skipped')" />
|
||||
</DrawerContent>
|
||||
|
||||
Reference in New Issue
Block a user