调整导览讲解为底部主导航
This commit is contained in:
@@ -1,6 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="audio-player-host">
|
<view class="audio-player-host">
|
||||||
<view class="audio-player" v-if="visible && currentAudio">
|
<view
|
||||||
|
class="audio-player"
|
||||||
|
:class="{ 'avoid-bottom-nav': avoidBottomNav }"
|
||||||
|
v-if="visible && currentAudio"
|
||||||
|
>
|
||||||
<!-- 迷你播放器 (底部固定) -->
|
<!-- 迷你播放器 (底部固定) -->
|
||||||
<view class="mini-player" @tap="handleExpand">
|
<view class="mini-player" @tap="handleExpand">
|
||||||
<!-- 封面图 -->
|
<!-- 封面图 -->
|
||||||
@@ -65,6 +69,7 @@ const props = defineProps<{
|
|||||||
visible?: boolean
|
visible?: boolean
|
||||||
audio?: AudioItem | null
|
audio?: AudioItem | null
|
||||||
autoPlay?: boolean
|
autoPlay?: boolean
|
||||||
|
avoidBottomNav?: boolean
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
@@ -517,6 +522,11 @@ defineExpose({
|
|||||||
padding-bottom: env(safe-area-inset-bottom);
|
padding-bottom: env(safe-area-inset-bottom);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.audio-player.avoid-bottom-nav {
|
||||||
|
bottom: calc(82px + env(safe-area-inset-bottom));
|
||||||
|
padding-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
@media (min-width: 768px) {
|
@media (min-width: 768px) {
|
||||||
.audio-player {
|
.audio-player {
|
||||||
left: 50%;
|
left: 50%;
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ const handleBack = () => {
|
|||||||
|
|
||||||
.explain-scroll {
|
.explain-scroll {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
padding: 76px 20px calc(28px + env(safe-area-inset-bottom));
|
padding: 76px 20px calc(112px + env(safe-area-inset-bottom));
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -526,7 +526,7 @@ const handleBrowseAll = () => {
|
|||||||
|
|
||||||
.explain-scroll {
|
.explain-scroll {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
padding: 0 16px calc(28px + env(safe-area-inset-bottom));
|
padding: 0 16px calc(110px + env(safe-area-inset-bottom));
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -897,7 +897,7 @@ const handleBrowseAll = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.card-list {
|
.card-list {
|
||||||
padding-bottom: calc(28px + env(safe-area-inset-bottom));
|
padding-bottom: calc(110px + env(safe-area-inset-bottom));
|
||||||
}
|
}
|
||||||
|
|
||||||
.list-more {
|
.list-more {
|
||||||
|
|||||||
173
src/components/navigation/GuideBottomNav.vue
Normal file
173
src/components/navigation/GuideBottomNav.vue
Normal file
@@ -0,0 +1,173 @@
|
|||||||
|
<template>
|
||||||
|
<view class="guide-bottom-nav">
|
||||||
|
<view class="guide-bottom-nav-inner">
|
||||||
|
<view
|
||||||
|
v-for="tab in GUIDE_TOP_TABS"
|
||||||
|
:key="tab.id"
|
||||||
|
class="guide-bottom-tab"
|
||||||
|
:class="[`tab-${tab.id}`, { active: activeTab === tab.id }]"
|
||||||
|
@tap="handleTabTap(tab.id)"
|
||||||
|
>
|
||||||
|
<view class="guide-bottom-icon" aria-hidden="true">
|
||||||
|
<template v-if="tab.id === 'guide'">
|
||||||
|
<view class="guide-icon-pin"></view>
|
||||||
|
<view class="guide-icon-path"></view>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<view class="explain-icon-wave top"></view>
|
||||||
|
<view class="explain-icon-wave middle"></view>
|
||||||
|
<view class="explain-icon-wave bottom"></view>
|
||||||
|
</template>
|
||||||
|
</view>
|
||||||
|
<text class="guide-bottom-label">{{ tab.label }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import {
|
||||||
|
GUIDE_TOP_TABS,
|
||||||
|
type GuideTopTab
|
||||||
|
} from '@/utils/guideTopTabs'
|
||||||
|
|
||||||
|
withDefaults(defineProps<{
|
||||||
|
activeTab?: GuideTopTab
|
||||||
|
}>(), {
|
||||||
|
activeTab: 'guide'
|
||||||
|
})
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
tabChange: [tab: GuideTopTab]
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const handleTabTap = (tab: GuideTopTab) => {
|
||||||
|
emit('tabChange', tab)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.guide-bottom-nav {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
padding: 8px 14px calc(8px + env(safe-area-inset-bottom));
|
||||||
|
box-sizing: border-box;
|
||||||
|
background: rgba(255, 255, 255, 0.96);
|
||||||
|
border-top: 1px solid #e6e8df;
|
||||||
|
box-shadow: 0 -10px 24px rgba(36, 49, 42, 0.1);
|
||||||
|
z-index: 2200;
|
||||||
|
transform: translateZ(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.guide-bottom-nav-inner {
|
||||||
|
height: 56px;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||||
|
gap: 10px;
|
||||||
|
padding: 4px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
background: #f4f5ef;
|
||||||
|
border: 1px solid #dfe2d9;
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.guide-bottom-tab {
|
||||||
|
min-width: 0;
|
||||||
|
height: 46px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 8px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border-radius: 6px;
|
||||||
|
color: #515151;
|
||||||
|
transition: background-color 0.18s ease, color 0.18s ease, transform 0.18s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.guide-bottom-tab.active {
|
||||||
|
background: #000000;
|
||||||
|
color: var(--museum-accent);
|
||||||
|
box-shadow: 0 6px 14px rgba(0, 0, 0, 0.14);
|
||||||
|
}
|
||||||
|
|
||||||
|
.guide-bottom-tab:active {
|
||||||
|
transform: translateY(1px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.guide-bottom-icon {
|
||||||
|
position: relative;
|
||||||
|
width: 22px;
|
||||||
|
height: 22px;
|
||||||
|
flex: 0 0 22px;
|
||||||
|
color: currentColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
.guide-icon-pin {
|
||||||
|
position: absolute;
|
||||||
|
left: 4px;
|
||||||
|
top: 1px;
|
||||||
|
width: 12px;
|
||||||
|
height: 15px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border: 2px solid currentColor;
|
||||||
|
border-radius: 8px 8px 8px 0;
|
||||||
|
transform: rotate(-45deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.guide-icon-pin::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
left: 3px;
|
||||||
|
top: 3px;
|
||||||
|
width: 3px;
|
||||||
|
height: 3px;
|
||||||
|
background: currentColor;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.guide-icon-path {
|
||||||
|
position: absolute;
|
||||||
|
left: 1px;
|
||||||
|
right: 1px;
|
||||||
|
bottom: 2px;
|
||||||
|
height: 6px;
|
||||||
|
border-bottom: 2px solid currentColor;
|
||||||
|
border-left: 2px solid currentColor;
|
||||||
|
border-radius: 0 0 0 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.explain-icon-wave {
|
||||||
|
position: absolute;
|
||||||
|
left: 2px;
|
||||||
|
right: 2px;
|
||||||
|
height: 4px;
|
||||||
|
border: 2px solid currentColor;
|
||||||
|
border-left: 0;
|
||||||
|
border-right: 0;
|
||||||
|
border-bottom: 0;
|
||||||
|
border-radius: 999px 999px 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.explain-icon-wave.top {
|
||||||
|
top: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.explain-icon-wave.middle {
|
||||||
|
top: 9px;
|
||||||
|
left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.explain-icon-wave.bottom {
|
||||||
|
top: 15px;
|
||||||
|
right: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.guide-bottom-label {
|
||||||
|
font-size: 15px;
|
||||||
|
line-height: 20px;
|
||||||
|
font-weight: 700;
|
||||||
|
color: currentColor;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -18,6 +18,7 @@
|
|||||||
:target-focus-distance-factor="targetFocusDistanceFactor"
|
:target-focus-distance-factor="targetFocusDistanceFactor"
|
||||||
:route-preview="routePreview"
|
:route-preview="routePreview"
|
||||||
:show-route="showRoute"
|
:show-route="showRoute"
|
||||||
|
:disable-auto-exit="disableAutoExit"
|
||||||
:auto-switch-threshold-low="autoSwitchThresholdLow"
|
:auto-switch-threshold-low="autoSwitchThresholdLow"
|
||||||
:auto-switch-threshold-high="autoSwitchThresholdHigh"
|
:auto-switch-threshold-high="autoSwitchThresholdHigh"
|
||||||
@floor-change="handleThreeFloorChange"
|
@floor-change="handleThreeFloorChange"
|
||||||
@@ -29,7 +30,7 @@
|
|||||||
<!-- #endif -->
|
<!-- #endif -->
|
||||||
<!-- #ifndef H5 -->
|
<!-- #ifndef H5 -->
|
||||||
<view class="indoor-platform-fallback">
|
<view class="indoor-platform-fallback">
|
||||||
<text class="indoor-platform-title">室内三维导览</text>
|
<text class="indoor-platform-title">馆内三维导览</text>
|
||||||
<text class="indoor-platform-desc">当前端暂不支持 WebGL 三维展示,请在 H5 端查看。</text>
|
<text class="indoor-platform-desc">当前端暂不支持 WebGL 三维展示,请在 H5 端查看。</text>
|
||||||
</view>
|
</view>
|
||||||
<!-- #endif -->
|
<!-- #endif -->
|
||||||
@@ -81,14 +82,14 @@
|
|||||||
:class="{ active: activeMode === '2d' }"
|
:class="{ active: activeMode === '2d' }"
|
||||||
@tap="handleModeChange('2d')"
|
@tap="handleModeChange('2d')"
|
||||||
>
|
>
|
||||||
<text class="mode-label">室外2D</text>
|
<text class="mode-label">馆外2D</text>
|
||||||
</view>
|
</view>
|
||||||
<view
|
<view
|
||||||
class="mode-option"
|
class="mode-option"
|
||||||
:class="{ active: activeMode === '3d' }"
|
:class="{ active: activeMode === '3d' }"
|
||||||
@tap="handleModeChange('3d')"
|
@tap="handleModeChange('3d')"
|
||||||
>
|
>
|
||||||
<text class="mode-label">室内3D</text>
|
<text class="mode-label">馆内3D</text>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
@@ -98,14 +99,14 @@
|
|||||||
:class="{ active: activeMode === '2d' }"
|
:class="{ active: activeMode === '2d' }"
|
||||||
@tap="handleModeChange('2d')"
|
@tap="handleModeChange('2d')"
|
||||||
>
|
>
|
||||||
<text class="mode-label">室外2D</text>
|
<text class="mode-label">馆外2D</text>
|
||||||
</view>
|
</view>
|
||||||
<view
|
<view
|
||||||
class="mode-option"
|
class="mode-option"
|
||||||
:class="{ active: activeMode === '3d' }"
|
:class="{ active: activeMode === '3d' }"
|
||||||
@tap="handleModeChange('3d')"
|
@tap="handleModeChange('3d')"
|
||||||
>
|
>
|
||||||
<text class="mode-label">室内3D</text>
|
<text class="mode-label">馆内3D</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="mode-status-chip" :class="`tone-${modeStatusTone}`">
|
<view class="mode-status-chip" :class="`tone-${modeStatusTone}`">
|
||||||
@@ -316,6 +317,7 @@ const props = withDefaults(defineProps<{
|
|||||||
targetFocusDistanceFactor?: number
|
targetFocusDistanceFactor?: number
|
||||||
routePreview?: GuideRouteResult | null
|
routePreview?: GuideRouteResult | null
|
||||||
showRoute?: boolean
|
showRoute?: boolean
|
||||||
|
disableAutoExit?: boolean
|
||||||
autoSwitchThresholdLow?: number
|
autoSwitchThresholdLow?: number
|
||||||
autoSwitchThresholdHigh?: number
|
autoSwitchThresholdHigh?: number
|
||||||
outdoorNavPolylines?: OutdoorNavPolyline[]
|
outdoorNavPolylines?: OutdoorNavPolyline[]
|
||||||
@@ -363,6 +365,7 @@ const props = withDefaults(defineProps<{
|
|||||||
targetFocusDistanceFactor: 0.22,
|
targetFocusDistanceFactor: 0.22,
|
||||||
routePreview: null,
|
routePreview: null,
|
||||||
showRoute: false,
|
showRoute: false,
|
||||||
|
disableAutoExit: false,
|
||||||
autoSwitchThresholdLow: 1.0,
|
autoSwitchThresholdLow: 1.0,
|
||||||
autoSwitchThresholdHigh: 1.3,
|
autoSwitchThresholdHigh: 1.3,
|
||||||
outdoorNavPolylines: () => [] as OutdoorNavPolyline[]
|
outdoorNavPolylines: () => [] as OutdoorNavPolyline[]
|
||||||
@@ -590,8 +593,7 @@ defineExpose({
|
|||||||
position: relative;
|
position: relative;
|
||||||
z-index: 0;
|
z-index: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100vh;
|
height: 100%;
|
||||||
height: 100dvh;
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
background: #ffffff;
|
background: #ffffff;
|
||||||
color: #000000;
|
color: #000000;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<view
|
<view
|
||||||
class="guide-page-frame"
|
class="guide-page-frame"
|
||||||
:class="[`variant-${variant}`, { 'no-top-tabs': !showTopTabs }]"
|
:class="[`variant-${variant}`, { 'no-top-tabs': !showTopTabs, 'has-bottom-nav': showBottomNav }]"
|
||||||
>
|
>
|
||||||
<GuideTopTabs
|
<GuideTopTabs
|
||||||
v-if="showTopTabs"
|
v-if="showTopTabs"
|
||||||
@@ -32,10 +32,16 @@
|
|||||||
<view class="guide-page-frame-body">
|
<view class="guide-page-frame-body">
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</view>
|
</view>
|
||||||
|
<GuideBottomNav
|
||||||
|
v-if="showBottomNav"
|
||||||
|
:active-tab="activeTab"
|
||||||
|
@tab-change="handleTabChange"
|
||||||
|
/>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import GuideBottomNav from '@/components/navigation/GuideBottomNav.vue'
|
||||||
import GuideTopTabs from '@/components/navigation/GuideTopTabs.vue'
|
import GuideTopTabs from '@/components/navigation/GuideTopTabs.vue'
|
||||||
import type { GuideTopTab } from '@/utils/guideTopTabs'
|
import type { GuideTopTab } from '@/utils/guideTopTabs'
|
||||||
|
|
||||||
@@ -45,6 +51,7 @@ withDefaults(defineProps<{
|
|||||||
topTabsVariant?: 'underline' | 'segmented'
|
topTabsVariant?: 'underline' | 'segmented'
|
||||||
topTabsTop?: string
|
topTabsTop?: string
|
||||||
showTopTabs?: boolean
|
showTopTabs?: boolean
|
||||||
|
showBottomNav?: boolean
|
||||||
showBack?: boolean
|
showBack?: boolean
|
||||||
showCancel?: boolean
|
showCancel?: boolean
|
||||||
backLabel?: string
|
backLabel?: string
|
||||||
@@ -55,6 +62,7 @@ withDefaults(defineProps<{
|
|||||||
topTabsVariant: 'underline',
|
topTabsVariant: 'underline',
|
||||||
topTabsTop: '0',
|
topTabsTop: '0',
|
||||||
showTopTabs: true,
|
showTopTabs: true,
|
||||||
|
showBottomNav: false,
|
||||||
showBack: false,
|
showBack: false,
|
||||||
showCancel: false,
|
showCancel: false,
|
||||||
backLabel: '返回',
|
backLabel: '返回',
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
<view v-if="isCollapsed" class="panel-collapsed" @tap="expandPanel">
|
<view v-if="isCollapsed" class="panel-collapsed" @tap="expandPanel">
|
||||||
<view class="panel-collapsed-copy">
|
<view class="panel-collapsed-copy">
|
||||||
<text class="panel-title">室外导览</text>
|
<text class="panel-title">馆外导览</text>
|
||||||
<text class="panel-summary">{{ collapsedSummary }}</text>
|
<text class="panel-summary">{{ collapsedSummary }}</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="panel-expand">
|
<view class="panel-expand">
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
<template v-else>
|
<template v-else>
|
||||||
<view class="panel-header">
|
<view class="panel-header">
|
||||||
<view class="panel-title-group">
|
<view class="panel-title-group">
|
||||||
<text class="panel-title">室外导览</text>
|
<text class="panel-title">馆外导览</text>
|
||||||
<text v-if="routeSummary" class="panel-summary">{{ routeSummary }}</text>
|
<text v-if="routeSummary" class="panel-summary">{{ routeSummary }}</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="panel-actions">
|
<view class="panel-actions">
|
||||||
@@ -244,7 +244,7 @@ const collapsedSummary = computed(() => {
|
|||||||
if (effectiveStartMode.value === 'gps') {
|
if (effectiveStartMode.value === 'gps') {
|
||||||
return '使用 GPS 定位'
|
return '使用 GPS 定位'
|
||||||
}
|
}
|
||||||
return '室外导览到馆'
|
return '馆外导览到馆'
|
||||||
})
|
})
|
||||||
|
|
||||||
const formatStartPointName = () => {
|
const formatStartPointName = () => {
|
||||||
@@ -411,7 +411,7 @@ const handlePanelMouseEnd = (event: MouseEvent) => {
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
left: 15px;
|
left: 15px;
|
||||||
right: 15px;
|
right: 15px;
|
||||||
bottom: calc(env(safe-area-inset-bottom) + 24px);
|
bottom: calc(env(safe-area-inset-bottom) + 106px);
|
||||||
padding: 12px 15px 15px;
|
padding: 12px 15px 15px;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
<view v-if="isCollapsed" class="panel-collapsed" @tap="expandPanel">
|
<view v-if="isCollapsed" class="panel-collapsed" @tap="expandPanel">
|
||||||
<view class="panel-collapsed-copy">
|
<view class="panel-collapsed-copy">
|
||||||
<text class="panel-title">室内导览</text>
|
<text class="panel-title">馆内导览</text>
|
||||||
<text class="panel-summary">{{ collapsedSummary }}</text>
|
<text class="panel-summary">{{ collapsedSummary }}</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="panel-expand">
|
<view class="panel-expand">
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
<template v-else>
|
<template v-else>
|
||||||
<view class="panel-header">
|
<view class="panel-header">
|
||||||
<view class="panel-title-group">
|
<view class="panel-title-group">
|
||||||
<text class="panel-title">室内导览</text>
|
<text class="panel-title">馆内导览</text>
|
||||||
<text v-if="summary" class="panel-summary">{{ summary }}</text>
|
<text v-if="summary" class="panel-summary">{{ summary }}</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="panel-actions">
|
<view class="panel-actions">
|
||||||
@@ -201,10 +201,10 @@ const primaryActionText = computed(() => (
|
|||||||
: (props.routeReady ? '查看路线' : '查看位置关系')
|
: (props.routeReady ? '查看路线' : '查看位置关系')
|
||||||
))
|
))
|
||||||
|
|
||||||
const routeOptionsTitle = computed(() => '室内导览')
|
const routeOptionsTitle = computed(() => '馆内导览')
|
||||||
|
|
||||||
const loadingText = computed(() => (
|
const loadingText = computed(() => (
|
||||||
props.routeReady ? '正在规划室内导览路线' : '正在生成室内位置关系'
|
props.routeReady ? '正在规划馆内导览路线' : '正在生成馆内位置关系'
|
||||||
))
|
))
|
||||||
|
|
||||||
const collapsedSummary = computed(() => {
|
const collapsedSummary = computed(() => {
|
||||||
@@ -403,7 +403,7 @@ const handlePrimaryAction = () => {
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
left: 12px;
|
left: 12px;
|
||||||
right: 12px;
|
right: 12px;
|
||||||
bottom: calc(env(safe-area-inset-bottom) + 30px);
|
bottom: calc(env(safe-area-inset-bottom) + 112px);
|
||||||
padding: 10px 14px 14px;
|
padding: 10px 14px 14px;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
<GuidePageFrame
|
<GuidePageFrame
|
||||||
active-tab="explain"
|
active-tab="explain"
|
||||||
variant="static"
|
variant="static"
|
||||||
|
:show-top-tabs="false"
|
||||||
|
show-bottom-nav
|
||||||
show-back
|
show-back
|
||||||
back-label="讲解首页"
|
back-label="讲解首页"
|
||||||
@tab-change="handleTopTabChange"
|
@tab-change="handleTopTabChange"
|
||||||
@@ -27,6 +29,7 @@
|
|||||||
:visible="showAudioPlayer"
|
:visible="showAudioPlayer"
|
||||||
:audio="currentAudio"
|
:audio="currentAudio"
|
||||||
:auto-play="true"
|
:auto-play="true"
|
||||||
|
avoid-bottom-nav
|
||||||
@update:visible="handleAudioVisibleChange"
|
@update:visible="handleAudioVisibleChange"
|
||||||
@play="handleAudioPlay"
|
@play="handleAudioPlay"
|
||||||
@pause="handleAudioPause"
|
@pause="handleAudioPause"
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
<GuidePageFrame
|
<GuidePageFrame
|
||||||
active-tab="guide"
|
active-tab="guide"
|
||||||
variant="overlay"
|
variant="overlay"
|
||||||
|
:show-top-tabs="false"
|
||||||
|
show-bottom-nav
|
||||||
show-back
|
show-back
|
||||||
:show-cancel="isStartPanelOpen"
|
:show-cancel="isStartPanelOpen"
|
||||||
@tab-change="handleTopTabChange"
|
@tab-change="handleTopTabChange"
|
||||||
@@ -283,7 +285,7 @@ const handleStartNavigation = () => {
|
|||||||
const handleModeChange = (mode: '2d' | '3d') => {
|
const handleModeChange = (mode: '2d' | '3d') => {
|
||||||
activeMode.value = mode
|
activeMode.value = mode
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
title: mode === '2d' ? '已切换室外入口参考' : '已切换室内三维位置',
|
title: mode === '2d' ? '已切换馆外入口参考' : '已切换馆内三维位置',
|
||||||
icon: 'none'
|
icon: 'none'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -335,7 +337,7 @@ const handlePageBack = () => {
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
bottom: calc(env(safe-area-inset-bottom) + 34px);
|
bottom: calc(env(safe-area-inset-bottom) + 116px);
|
||||||
height: 252px;
|
height: 252px;
|
||||||
padding: 22px 20px 20px;
|
padding: 22px 20px 20px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
@@ -478,7 +480,7 @@ const handlePageBack = () => {
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
bottom: calc(env(safe-area-inset-bottom) + 34px);
|
bottom: calc(env(safe-area-inset-bottom) + 116px);
|
||||||
height: 276px;
|
height: 276px;
|
||||||
padding: 22px 20px 16px;
|
padding: 22px 20px 16px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
|||||||
@@ -2,9 +2,8 @@
|
|||||||
<GuidePageFrame
|
<GuidePageFrame
|
||||||
:active-tab="currentTab"
|
:active-tab="currentTab"
|
||||||
variant="overlay"
|
variant="overlay"
|
||||||
:top-tabs-variant="currentTab === 'guide' ? 'segmented' : 'underline'"
|
:show-top-tabs="false"
|
||||||
:top-tabs-top="currentTab === 'guide' ? '80px' : '0'"
|
show-bottom-nav
|
||||||
:show-top-tabs="currentTab === 'guide'"
|
|
||||||
@tab-change="handleTabChange"
|
@tab-change="handleTabChange"
|
||||||
>
|
>
|
||||||
<GuideMapShell
|
<GuideMapShell
|
||||||
@@ -38,11 +37,12 @@
|
|||||||
:show-floor="is3DMode"
|
:show-floor="is3DMode"
|
||||||
:tools="indoorCameraTools"
|
:tools="indoorCameraTools"
|
||||||
tools-top=""
|
tools-top=""
|
||||||
tools-bottom="54px"
|
tools-bottom="138px"
|
||||||
show-zoom-controls
|
show-zoom-controls
|
||||||
zoom-controls-top="calc(100vh - 284px)"
|
zoom-controls-top="calc(100vh - 284px)"
|
||||||
:route-preview="activeRoutePreview"
|
:route-preview="activeRoutePreview"
|
||||||
:show-route="Boolean(activeRoutePreview)"
|
:show-route="Boolean(activeRoutePreview)"
|
||||||
|
:disable-auto-exit="disableIndoorAutoExit"
|
||||||
:auto-switch-threshold-low="0.58"
|
:auto-switch-threshold-low="0.58"
|
||||||
:auto-switch-threshold-high="1.18"
|
:auto-switch-threshold-high="1.18"
|
||||||
:outdoor-nav-polylines="outdoorNavPolylines"
|
:outdoor-nav-polylines="outdoorNavPolylines"
|
||||||
@@ -171,14 +171,14 @@
|
|||||||
<view v-if="guideOutdoorState === 'entrance' && !is3DMode" class="entrance-bottom-card">
|
<view v-if="guideOutdoorState === 'entrance' && !is3DMode" class="entrance-bottom-card">
|
||||||
<text class="entrance-card-title">主入口</text>
|
<text class="entrance-card-title">主入口</text>
|
||||||
<text class="entrance-card-desc">
|
<text class="entrance-card-desc">
|
||||||
可参考主入口位置,也可手动进入室内3D并选择楼层/区域。
|
可参考主入口位置,也可手动进入馆内3D并选择楼层/区域。
|
||||||
</text>
|
</text>
|
||||||
<view class="entrance-actions">
|
<view class="entrance-actions">
|
||||||
<view class="entrance-btn secondary" @tap="handleSwitchEntrance">
|
<view class="entrance-btn secondary" @tap="handleSwitchEntrance">
|
||||||
<text class="entrance-btn-text">切换入口</text>
|
<text class="entrance-btn-text">切换入口</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="entrance-btn primary" @tap="handleEnter3DMode">
|
<view class="entrance-btn primary" @tap="handleEnter3DMode">
|
||||||
<text class="entrance-btn-text">进入室内3D</text>
|
<text class="entrance-btn-text">进入馆内3D</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -320,7 +320,7 @@ const guideMapShellRef = ref<{
|
|||||||
clearRoute?: () => void
|
clearRoute?: () => void
|
||||||
} | null>(null)
|
} | null>(null)
|
||||||
|
|
||||||
// 室外导航相关状态
|
// 馆外导航相关状态
|
||||||
const showOutdoorNavPanel = ref(false)
|
const showOutdoorNavPanel = ref(false)
|
||||||
const outdoorNavLoading = ref(false)
|
const outdoorNavLoading = ref(false)
|
||||||
const outdoorNavError = ref('')
|
const outdoorNavError = ref('')
|
||||||
@@ -373,6 +373,13 @@ const routePlanSummary = computed(() => {
|
|||||||
|
|
||||||
const routePanelError = computed(() => routePlanError.value)
|
const routePanelError = computed(() => routePlanError.value)
|
||||||
|
|
||||||
|
const disableIndoorAutoExit = computed(() => (
|
||||||
|
Boolean(selectedGuidePoi.value)
|
||||||
|
|| Boolean(activeRoutePreview.value)
|
||||||
|
|| showRoutePlanner.value
|
||||||
|
|| isSimulatingRoute.value
|
||||||
|
))
|
||||||
|
|
||||||
const showGuideQuickActions = computed(() => (
|
const showGuideQuickActions = computed(() => (
|
||||||
currentTab.value === 'guide'
|
currentTab.value === 'guide'
|
||||||
&& !showRoutePlanner.value
|
&& !showRoutePlanner.value
|
||||||
@@ -398,12 +405,12 @@ const selectedGuidePoiSubtitle = computed(() => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
const routeSimulationStepText = computed(() => {
|
const routeSimulationStepText = computed(() => {
|
||||||
if (!activeRoutePreview.value) return routeReady.value ? '室内导览 · 查看路线' : '室内导览 · 查看位置'
|
if (!activeRoutePreview.value) return routeReady.value ? '馆内导览 · 查看路线' : '馆内导览 · 查看位置'
|
||||||
const hasConnector = activeRoutePreview.value.connectorPoints.length > 0
|
const hasConnector = activeRoutePreview.value.connectorPoints.length > 0
|
||||||
if (routeReady.value) {
|
if (routeReady.value) {
|
||||||
return hasConnector ? '室内导览 · 跨楼层路线' : '室内导览 · 同层路线'
|
return hasConnector ? '馆内导览 · 跨楼层路线' : '馆内导览 · 同层路线'
|
||||||
}
|
}
|
||||||
return hasConnector ? '室内导览 · 跨楼层位置关系' : '室内导览 · 同层位置关系'
|
return hasConnector ? '馆内导览 · 跨楼层位置关系' : '馆内导览 · 同层位置关系'
|
||||||
})
|
})
|
||||||
|
|
||||||
const explainHallItems = ref<ExplainHallSelectItem[]>([])
|
const explainHallItems = ref<ExplainHallSelectItem[]>([])
|
||||||
@@ -868,7 +875,7 @@ const handleRouteView = async ({ startPoint, endPoint }: { startPoint: RoutePoin
|
|||||||
|
|
||||||
if (!result.route) {
|
if (!result.route) {
|
||||||
activeRoutePreview.value = null
|
activeRoutePreview.value = null
|
||||||
routePlanError.value = result.error || '室内导览位置关系生成失败'
|
routePlanError.value = result.error || '馆内导览位置关系生成失败'
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -876,9 +883,9 @@ const handleRouteView = async ({ startPoint, endPoint }: { startPoint: RoutePoin
|
|||||||
focusRouteFloor(result.route)
|
focusRouteFloor(result.route)
|
||||||
showRoutePlanner.value = true
|
showRoutePlanner.value = true
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('室内导览位置关系生成失败:', error)
|
console.error('馆内导览位置关系生成失败:', error)
|
||||||
activeRoutePreview.value = null
|
activeRoutePreview.value = null
|
||||||
routePlanError.value = error instanceof Error ? error.message : '室内导览位置关系生成失败'
|
routePlanError.value = error instanceof Error ? error.message : '馆内导览位置关系生成失败'
|
||||||
} finally {
|
} finally {
|
||||||
routePlanning.value = false
|
routePlanning.value = false
|
||||||
}
|
}
|
||||||
@@ -892,9 +899,9 @@ const handleRouteSimulate = () => {
|
|||||||
isSimulatingRoute.value = true
|
isSimulatingRoute.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
// 进入 3D 室内模式
|
// 进入 3D 馆内模式
|
||||||
const handleEnter3DMode = () => {
|
const handleEnter3DMode = () => {
|
||||||
console.log('进入 3D 室内模式')
|
console.log('进入 3D 馆内模式')
|
||||||
indoorView.value = 'overview'
|
indoorView.value = 'overview'
|
||||||
is3DMode.value = true
|
is3DMode.value = true
|
||||||
guideOutdoorState.value = 'home'
|
guideOutdoorState.value = 'home'
|
||||||
@@ -927,15 +934,15 @@ const handleModeChange = (mode: '2d' | '3d') => {
|
|||||||
const guideStatusLabel = computed(() => {
|
const guideStatusLabel = computed(() => {
|
||||||
if (is3DMode.value) {
|
if (is3DMode.value) {
|
||||||
if (indoorView.value === 'overview') return '建筑外观'
|
if (indoorView.value === 'overview') return '建筑外观'
|
||||||
if (indoorView.value === 'multi') return '室内多层'
|
if (indoorView.value === 'multi') return '馆内多层'
|
||||||
return '室内单层'
|
return '馆内单层'
|
||||||
}
|
}
|
||||||
|
|
||||||
if (guideOutdoorState.value === 'entrance') {
|
if (guideOutdoorState.value === 'entrance') {
|
||||||
return '推荐入口'
|
return '推荐入口'
|
||||||
}
|
}
|
||||||
|
|
||||||
return '室外参考'
|
return '馆外参考'
|
||||||
})
|
})
|
||||||
|
|
||||||
const handleSwitchEntrance = () => {
|
const handleSwitchEntrance = () => {
|
||||||
@@ -946,13 +953,13 @@ const handleMoreRouteGuide = () => {
|
|||||||
openRoutePlanner()
|
openRoutePlanner()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 室外导航处理函数
|
// 馆外导航处理函数
|
||||||
const openOutdoorNavPanel = () => {
|
const openOutdoorNavPanel = () => {
|
||||||
showOutdoorNavPanel.value = true
|
showOutdoorNavPanel.value = true
|
||||||
showRoutePlanner.value = false
|
showRoutePlanner.value = false
|
||||||
selectedGuidePoi.value = null
|
selectedGuidePoi.value = null
|
||||||
isPoiCardCollapsed.value = false
|
isPoiCardCollapsed.value = false
|
||||||
// 切换到室外 2D 地图
|
// 切换到馆外 2D 地图
|
||||||
is3DMode.value = false
|
is3DMode.value = false
|
||||||
clearOutdoorNavState()
|
clearOutdoorNavState()
|
||||||
}
|
}
|
||||||
@@ -1163,7 +1170,7 @@ const handleExplainBack = () => {
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
left: 12px;
|
left: 12px;
|
||||||
right: 12px;
|
right: 12px;
|
||||||
bottom: calc(env(safe-area-inset-bottom) + 30px);
|
bottom: calc(env(safe-area-inset-bottom) + 112px);
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
background: rgba(255, 255, 255, 0.96);
|
background: rgba(255, 255, 255, 0.96);
|
||||||
border: 1px solid #e5e6de;
|
border: 1px solid #e5e6de;
|
||||||
@@ -1325,7 +1332,7 @@ const handleExplainBack = () => {
|
|||||||
.guide-quick-actions {
|
.guide-quick-actions {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 18px;
|
right: 18px;
|
||||||
bottom: calc(env(safe-area-inset-bottom) + 54px);
|
bottom: calc(env(safe-area-inset-bottom) + 136px);
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: stretch;
|
align-items: stretch;
|
||||||
@@ -1454,7 +1461,7 @@ const handleExplainBack = () => {
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
left: 12px;
|
left: 12px;
|
||||||
right: 12px;
|
right: 12px;
|
||||||
bottom: calc(env(safe-area-inset-bottom) + 30px);
|
bottom: calc(env(safe-area-inset-bottom) + 112px);
|
||||||
min-height: 54px;
|
min-height: 54px;
|
||||||
padding: 10px 10px 10px 14px;
|
padding: 10px 10px 10px 14px;
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -1556,7 +1563,7 @@ const handleExplainBack = () => {
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
left: 12px;
|
left: 12px;
|
||||||
right: 12px;
|
right: 12px;
|
||||||
bottom: calc(env(safe-area-inset-bottom) + 134px);
|
bottom: calc(env(safe-area-inset-bottom) + 216px);
|
||||||
height: 84px;
|
height: 84px;
|
||||||
padding: 16px 10px 8px;
|
padding: 16px 10px 8px;
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -1694,7 +1701,7 @@ const handleExplainBack = () => {
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
left: 12px;
|
left: 12px;
|
||||||
right: 12px;
|
right: 12px;
|
||||||
bottom: calc(env(safe-area-inset-bottom) + 134px);
|
bottom: calc(env(safe-area-inset-bottom) + 216px);
|
||||||
z-index: 1003;
|
z-index: 1003;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1702,7 +1709,7 @@ const handleExplainBack = () => {
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
left: 12px;
|
left: 12px;
|
||||||
right: 12px;
|
right: 12px;
|
||||||
bottom: calc(env(safe-area-inset-bottom) + 30px);
|
bottom: calc(env(safe-area-inset-bottom) + 112px);
|
||||||
height: 94px;
|
height: 94px;
|
||||||
padding: 16px 16px 10px;
|
padding: 16px 16px 10px;
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -1758,7 +1765,7 @@ const handleExplainBack = () => {
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
left: 12px;
|
left: 12px;
|
||||||
right: 12px;
|
right: 12px;
|
||||||
bottom: calc(env(safe-area-inset-bottom) + 34px);
|
bottom: calc(env(safe-area-inset-bottom) + 116px);
|
||||||
height: 158px;
|
height: 158px;
|
||||||
padding: 18px 16px 14px;
|
padding: 18px 16px 14px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
<GuidePageFrame
|
<GuidePageFrame
|
||||||
active-tab="guide"
|
active-tab="guide"
|
||||||
variant="overlay"
|
variant="overlay"
|
||||||
|
:show-top-tabs="false"
|
||||||
|
show-bottom-nav
|
||||||
show-back
|
show-back
|
||||||
:show-cancel="isManualLocationPanelOpen"
|
:show-cancel="isManualLocationPanelOpen"
|
||||||
@tab-change="handleTopTabChange"
|
@tab-change="handleTopTabChange"
|
||||||
@@ -97,16 +99,16 @@
|
|||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view v-else-if="routeViewState === 'outdoor-preview'" class="outdoor-preview-card">
|
<view v-else-if="routeViewState === 'outdoor-preview'" class="outdoor-preview-card">
|
||||||
<text class="outdoor-preview-title">室外地图预览:{{ route.target }}</text>
|
<text class="outdoor-preview-title">馆外地图预览:{{ route.target }}</text>
|
||||||
<text class="outdoor-preview-desc">
|
<text class="outdoor-preview-desc">
|
||||||
室外地图仅作入口参考;馆内当前支持三维位置预览。
|
馆外地图仅作入口参考;馆内当前支持三维位置预览。
|
||||||
</text>
|
</text>
|
||||||
<view class="outdoor-preview-actions">
|
<view class="outdoor-preview-actions">
|
||||||
<view class="outdoor-preview-btn secondary" @tap="handleReturnToPreview">
|
<view class="outdoor-preview-btn secondary" @tap="handleReturnToPreview">
|
||||||
<text class="outdoor-preview-btn-text">返回预览</text>
|
<text class="outdoor-preview-btn-text">返回预览</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="outdoor-preview-btn primary" @tap="handleReturnToPreview">
|
<view class="outdoor-preview-btn primary" @tap="handleReturnToPreview">
|
||||||
<text class="outdoor-preview-btn-text">返回室内3D</text>
|
<text class="outdoor-preview-btn-text">返回馆内3D</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -283,7 +285,7 @@ const shellConfig = computed(() => {
|
|||||||
|
|
||||||
if (routeViewState.value === 'outdoor-preview') {
|
if (routeViewState.value === 'outdoor-preview') {
|
||||||
return {
|
return {
|
||||||
searchText: `室外地图参考:${route.value.target}`,
|
searchText: `馆外地图参考:${route.value.target}`,
|
||||||
searchTop: '60px',
|
searchTop: '60px',
|
||||||
activeMode: '2d' as GuideMode,
|
activeMode: '2d' as GuideMode,
|
||||||
activeFloor: activeFloor.value,
|
activeFloor: activeFloor.value,
|
||||||
@@ -295,14 +297,14 @@ const shellConfig = computed(() => {
|
|||||||
showModeRow: false,
|
showModeRow: false,
|
||||||
modeTop: '104px',
|
modeTop: '104px',
|
||||||
modeLayout: 'status' as const,
|
modeLayout: 'status' as const,
|
||||||
modeStatus: '室外参考',
|
modeStatus: '馆外参考',
|
||||||
mapType: 'outdoor' as const,
|
mapType: 'outdoor' as const,
|
||||||
outdoorVariant: 'entrance' as const
|
outdoorVariant: 'entrance' as const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
searchText: routeReady.value ? `室内导览:${route.value.target}` : `位置预览:${route.value.target}`,
|
searchText: routeReady.value ? `馆内导览:${route.value.target}` : `位置预览:${route.value.target}`,
|
||||||
searchTop: '60px',
|
searchTop: '60px',
|
||||||
activeMode: '3d' as GuideMode,
|
activeMode: '3d' as GuideMode,
|
||||||
activeFloor: activeFloor.value,
|
activeFloor: activeFloor.value,
|
||||||
@@ -321,7 +323,7 @@ const shellConfig = computed(() => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
const indoorGuideTitle = computed(() => (
|
const indoorGuideTitle = computed(() => (
|
||||||
routeReady.value ? `室内导览:${route.value.target}` : `位置预览:${route.value.target}`
|
routeReady.value ? `馆内导览:${route.value.target}` : `位置预览:${route.value.target}`
|
||||||
))
|
))
|
||||||
|
|
||||||
const indoorGuideDesc = computed(() => {
|
const indoorGuideDesc = computed(() => {
|
||||||
@@ -643,7 +645,7 @@ const handleStartIndoorGuide = async () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
if (!result.route) {
|
if (!result.route) {
|
||||||
routePlanError.value = result.error || '室内导览路线规划失败'
|
routePlanError.value = result.error || '馆内导览路线规划失败'
|
||||||
activeRoutePreview.value = null
|
activeRoutePreview.value = null
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -651,7 +653,7 @@ const handleStartIndoorGuide = async () => {
|
|||||||
activeRoutePreview.value = result.route
|
activeRoutePreview.value = result.route
|
||||||
activeFloor.value = result.route.start.floorLabel
|
activeFloor.value = result.route.start.floorLabel
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
routePlanError.value = error instanceof Error ? error.message : '室内导览路线规划失败'
|
routePlanError.value = error instanceof Error ? error.message : '馆内导览路线规划失败'
|
||||||
activeRoutePreview.value = null
|
activeRoutePreview.value = null
|
||||||
} finally {
|
} finally {
|
||||||
routePlanning.value = false
|
routePlanning.value = false
|
||||||
@@ -719,7 +721,7 @@ const handlePageBack = () => {
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
left: 16px;
|
left: 16px;
|
||||||
right: 16px;
|
right: 16px;
|
||||||
bottom: calc(env(safe-area-inset-bottom) + 34px);
|
bottom: calc(env(safe-area-inset-bottom) + 116px);
|
||||||
min-height: 170px;
|
min-height: 170px;
|
||||||
padding: 22px 20px 20px;
|
padding: 22px 20px 20px;
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -736,7 +738,7 @@ const handlePageBack = () => {
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
left: 16px;
|
left: 16px;
|
||||||
right: 16px;
|
right: 16px;
|
||||||
bottom: calc(env(safe-area-inset-bottom) + 34px);
|
bottom: calc(env(safe-area-inset-bottom) + 116px);
|
||||||
min-height: 156px;
|
min-height: 156px;
|
||||||
padding: 18px 18px 16px;
|
padding: 18px 18px 16px;
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -958,7 +960,7 @@ const handlePageBack = () => {
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
bottom: calc(env(safe-area-inset-bottom) + 34px);
|
bottom: calc(env(safe-area-inset-bottom) + 116px);
|
||||||
height: 196px;
|
height: 196px;
|
||||||
padding: 21px 20px 14px;
|
padding: 21px 20px 14px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
@@ -1098,7 +1100,7 @@ const handlePageBack = () => {
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
left: 12px;
|
left: 12px;
|
||||||
right: 12px;
|
right: 12px;
|
||||||
bottom: calc(env(safe-area-inset-bottom) + 34px);
|
bottom: calc(env(safe-area-inset-bottom) + 116px);
|
||||||
height: 158px;
|
height: 158px;
|
||||||
padding: 18px 16px 14px;
|
padding: 18px 16px 14px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
|||||||
Reference in New Issue
Block a user