Browse Source

feat: 添加视频播放结束事件,优化轮播图组件的自动播放逻辑

EvilDragon 3 months ago
parent
commit
933138696d

+ 22 - 10
packages/app/src/pages/home/components/home-banner.vue

@@ -10,7 +10,7 @@ const props = withDefaults(
   }>(),
   {},
 )
-const emits = defineEmits<{ play: [id: string | number] }>()
+const emits = defineEmits<{ play: [id: string | number]; ended: [id: string | number] }>()
 const instance = getCurrentInstance()
 const playing = ref(false)
 const duration = ref(0)
@@ -24,22 +24,34 @@ const handlePlay = async () => {
 const handleLoadedMetaData = ({ detail }) => {
   duration.value = detail.duration
 }
+const handleEnded = () => {
+  playing.value = false
+  videoContext.value?.pause()
+  emits('ended', props.id)
+}
 onMounted(async () => {
   videoContext.value = uni.createVideoContext(`video-${props.id}`, instance)
 })
+defineExpose({
+  videoContext,
+})
 </script>
 <template>
   <div class="w-full h-full relative">
-    <video
-      class="w-full h-full"
-      :id="`video-${id}`"
-      :src="url"
-      :controls="'contimg'"
-      :show-center-play-btn="false"
-      @loadedmetadata="handleLoadedMetaData"
-    ></video>
+    <div class="w-full h-full box-border pb-4">
+      <video
+        class="w-full h-full"
+        :id="`video-${id}`"
+        :src="url"
+        :controls="'contimg'"
+        :show-center-play-btn="false"
+        :enable-progress-gesture="false"
+        :loop="false"
+        @ended="handleEnded"
+        @loadedmetadata="handleLoadedMetaData"
+      ></video>
+    </div>
     <div v-if="!playing" class="absolute left-0 top-0 w-full h-full bg-black">
-      <!-- <wd-img width="100%" height="100%" :src="cover" /> -->
       <ImageEvo :src="cover"></ImageEvo>
     </div>
     <div

+ 15 - 7
packages/app/src/pages/home/index.vue

@@ -26,7 +26,6 @@ import {
   updateSetIndexConfig,
 } from '../../core/libs/requests'
 import { logo } from '../../core/libs/svgs'
-import PageHelper from '@/components/page-helper.vue'
 import { ComponentExposed } from 'vue-component-type-helpers'
 import { usePermissions } from '../../composables/permissions'
 import { storeToRefs } from 'pinia'
@@ -34,10 +33,6 @@ import { messages } from '../../core/libs/messages'
 import { handleUpvoteClick, handleShareClick } from '../../core/libs/actions'
 import { useUserStore } from '../../store'
 import ScheduleCard from './components/schedule-card.vue'
-import TiltedButton from '@/components/tilted-button.vue'
-import ButtonEvo from '@/components/button-evo.vue'
-import ImgBtnEvo from '@/components/img-btn-evo.vue'
-import SectionHeading from '@/components/section-heading.vue'
 import dayjs from 'dayjs'
 import { pick, sort } from 'radash'
 import { Activity, StudyTour } from '../../core/libs/models'
@@ -63,6 +58,8 @@ const { data: studyTours, run: setStudyTours } = useRequest(() => getMyStudyTour
 })
 const swiperData = ref<{ data: any }[]>()
 const swiperCurrent = ref(0)
+const autoplay = ref(true)
+const homeBannerRef = ref<ComponentExposed<typeof HomeBanner>[]>()
 const hotActivities =
   ref<{ type: 'studyTour' | 'activity'; data: StudyTour & Activity; startAt: string | number }[]>()
 const currentStudyTour = computed(() =>
@@ -74,7 +71,11 @@ const currentStudyTour = computed(() =>
 const toAbout = () => {
   uni.navigateTo({ url: '/pages/home/about/index' })
 }
-const handleSwiperChange = ({ detail: { current } }) => {
+const handleSwiperChange = ({ detail: { current, source } }) => {
+  // console.log('current', current)
+
+  console.log(current, source, swiperCurrent.value)
+  homeBannerRef.value?.[swiperCurrent.value]?.videoContext.pause()
   swiperCurrent.value = current
 }
 const handleLike = async (options) => {
@@ -99,6 +100,7 @@ const setHotActivities = async () => {
 }
 const handlePlay = async (id) => {
   const body = pick(swiperData.value?.find((it) => it.data.id === id).data, ['id', 'status'])
+  autoplay.value = false
   await updateSetIndexConfig(body)
 }
 onShow(async () => {
@@ -112,6 +114,10 @@ onLoad(async () => {
   }))
   show.value({ title: '看不见', content: '看不见', path: '', image: '' })
 })
+onHide(() => {
+  // autoplay.value = true
+  homeBannerRef.value?.[swiperCurrent.value]?.videoContext.pause()
+})
 onShareAppMessage(async ({ from, target }) => {
   console.log('from', from)
   console.log('target', target)
@@ -132,17 +138,19 @@ onShareAppMessage(async ({ from, target }) => {
 <template>
   <view class="">
     <view class="bg-black w-full relative aspect-[1.26/1]">
-      <swiper autoplay @change="handleSwiperChange">
+      <swiper :autoplay="autoplay" @change="handleSwiperChange">
         <template
           v-for="{ data: { id, coverVideoImage, indexPromotionalVideoImage } } of swiperData"
           :key="id"
         >
           <swiper-item>
             <HomeBanner
+              ref="homeBannerRef"
               :id="id"
               :url="indexPromotionalVideoImage"
               :cover="coverVideoImage"
               @play="handlePlay"
+              @ended="autoplay = true"
             />
           </swiper-item>
         </template>