<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue';
import { OIcon, ODialog } from '@opensig/opendesign';
import FloatingButtonHome from '@/components/feedback/FloatingButtonHome.vue';
import FeedbackSlider from '@/components/feedback/FeedbackSlider.vue';
import IconTop from '~icons/app/icon-top.svg';
import IconSmile from '~icons/app/icon-smile.svg';
import IconClose from '~icons/app/icon-close.svg';
import { scrollToTop } from '@/shared/utils'
import { useScreen } from '@/components/hooks/useScreen';
import { useI18n } from 'vue-i18n';
const { gtPhone, isPhone } = useScreen();
const { t } = useI18n();
const showBackTop = ref(false);
const oscrollerDom = ref();
const listenScroll = () => {
if (oscrollerDom.value.scrollTop > document.body.clientHeight) {
showBackTop.value = true;
} else {
showBackTop.value = false;
}
};
onMounted(() => {
oscrollerDom.value = document.querySelector('#app > .o-scroller > .o-scroller-container');
oscrollerDom.value?.addEventListener('scroll', listenScroll);
});
onUnmounted(() => {
oscrollerDom.value?.removeEventListener('scroll', listenScroll);
});
const isShow = ref(false);
const dialogVisible = ref(false);
const isShowFeedbackMb = ref(false);
const toggleDialogVisible = () => {
dialogVisible.value = true;
};
const closeFeedbackMb = () => {
isShowFeedbackMb.value = false;
};
const change = (visible: boolean) => {
if (!visible) {
dialogVisible.value = false;
}
};
onMounted(() => {
isShowFeedbackMb.value = true;
});
</script>
<template>
<div v-if="gtPhone" class="feedback-home">
<div class="feedback-wrap">
<FloatingButtonHome />
<div v-if="showBackTop" class="nav-box2" @click="scrollToTop(0)">
<OIcon class="icon-top"><IconTop /> </OIcon>
</div>
</div>
</div>
<div v-if="isPhone && isShowFeedbackMb" class="feedback-mb">
<div class="feedback-mb-head">
<div class="head-title" @click="toggleDialogVisible">
<OIcon class="icon-box"><component :is="IconSmile"></component> </OIcon>
<p>
{{ t('feedback.title1') }}<span class="title-name">{{ t('feedback.title2') }}</span
>{{ t('feedback.title3') }}
</p>
</div>
<OIcon class="icon-box icon-close" @click="closeFeedbackMb"><component :is="IconClose"></component> </OIcon>
</div>
<ODialog
main-class="feedback-dialog"
:visible="dialogVisible"
:phone-half-full="true"
:style="{ '--dlg-head-padding': '16px 24px 0', '--dlg-body-padding': '24px 24px 16px', '--dlg-padding-body-top': '12px', '--dlg-radius': '4px 4px 0 0' }"
:scroller="false"
@change="change"
>
<FeedbackSlider :show="isShow" @close="change" />
</ODialog>
</div>
</template>
<style lang="scss" scoped>
.feedback-home {
position: fixed;
bottom: 200px;
right: 64px;
z-index: 10;
height: 164px;
@include respond-to('<=laptop') {
right: 24px;
}
}
.feedback-wrap {
display: flex;
flex-direction: column;
position: relative;
}
.feedback-mb {
position: sticky;
bottom: 16px;
z-index: 11;
width: 100%;
padding: 0 24px;
}
.feedback-mb-head {
height: 40px;
padding: 8px;
background: linear-gradient(90deg, var(--o-color-border2) 0%, var(--o-color-border2) 100%);
border-radius: var(--o-radius-xs);
display: flex;
align-items: center;
justify-content: center;
position: relative;
.o-icon {
font-size: 16px;
}
.icon-close {
position: absolute;
right: 12px;
top: 50%;
cursor: pointer;
transform: translateY(-50%);
transition: all 0.25s cubic-bezier(0, 0, 0, 1);
@include hover {
transform: translateY(-50%) rotate(180deg);
color: var(--o-color-brand1);
}
}
.head-title {
display: flex;
align-items: center;
white-space: nowrap;
@include text1;
.title-name {
font-weight: 500;
}
.o-icon {
margin-right: 8px;
color: var(--o-color-brand1);
}
}
}
</style>
<style lang="scss">
.feedback-dialog {
background: #fff;
.o-button {
border: none
}
}
</style>