home-banner.vue 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. <script setup lang="ts">
  2. import ImageEvo from '@/components/image-evo.vue'
  3. import { unix } from 'dayjs'
  4. import { useRouter } from '../../../core/utils/router'
  5. const router = useRouter()
  6. const props = withDefaults(
  7. defineProps<{
  8. id: string | number
  9. url: string
  10. cover: string
  11. detailsType: number | string | null | undefined
  12. item: object | any
  13. }>(),
  14. {},
  15. )
  16. const emits = defineEmits<{ play: [id: string | number]; ended: [id: string | number] }>()
  17. const instance = getCurrentInstance()
  18. const playing = ref(false)
  19. const duration = ref(0)
  20. const durationText = computed(() => unix(duration.value).format('mm:ss'))
  21. const videoContext = ref<UniNamespace.VideoContext>()
  22. const handleClick = async () => {
  23. if (props?.item?.url && props.item?.url?.startsWith('http')) {
  24. router.push(`/pages-sub/common/webview/index?url=${props.item.url}`)
  25. }
  26. if (props.detailsType === '1' && !props?.item?.url) {
  27. // router.push(
  28. // `/pages-sub/home/content/index?type=home-banner&id=${props.id}&data=${encodeURIComponent(JSON.stringify(props.item))}`,
  29. // )
  30. router.push(
  31. `/pages-sub/home/content/index?type=home-banner&id=${props.id}`,
  32. )
  33. }
  34. if (props.detailsType === '2' && props?.item?.url) {
  35. router.push(props?.item?.url)
  36. }
  37. }
  38. const handlePlay = async () => {
  39. videoContext.value?.play()
  40. playing.value = true
  41. emits('play', props.id)
  42. }
  43. const handleLoadedMetaData = ({ detail }) => {
  44. duration.value = detail.duration
  45. }
  46. const handleEnded = () => {
  47. playing.value = false
  48. videoContext.value?.pause()
  49. emits('ended', props.id)
  50. }
  51. const handlePause = () => {
  52. playing.value = false
  53. }
  54. onMounted(async () => {
  55. videoContext.value = uni.createVideoContext(`video-${props.id}`, instance)
  56. })
  57. defineExpose({
  58. videoContext,
  59. })
  60. </script>
  61. <template>
  62. <div class="w-full h-full relative" v-if="!detailsType && item.indexPromotionalVideoImage">
  63. <div v-show="!playing" class="absolute left-0 top-0 w-full h-full bg-black">
  64. <ImageEvo :src="cover"></ImageEvo>
  65. </div>
  66. <div class="w-full h-full box-border pb-6" v-show="playing">
  67. <video
  68. class="w-full h-full"
  69. :id="`video-${id}`"
  70. :src="url"
  71. :controls="'contimg'"
  72. :show-center-play-btn="false"
  73. :enable-progress-gesture="false"
  74. :loop="false"
  75. @pause="handlePause"
  76. @ended="handleEnded"
  77. @loadedmetadata="handleLoadedMetaData"
  78. ></video>
  79. </div>
  80. <div
  81. v-if="!playing"
  82. class="w-[375px] h-[90px] bg-gradient-to-t from-black to-black/0 absolute left-0 bottom-0 w-full flex items-center"
  83. >
  84. <view class="mx-7">
  85. <wd-button
  86. plain
  87. custom-class="bg-transparent! text-white! w-20.5! min-w-20! h-8.25! border! border-solid! border-white!"
  88. @click="handlePlay()"
  89. >
  90. <div class="flex items-center">
  91. <wd-icon name="play" size="22px"></wd-icon>
  92. <div class="text-white text-[13px] font-['Gotham'] leading-[10.18px]">
  93. {{ durationText }}
  94. </div>
  95. </div>
  96. </wd-button>
  97. </view>
  98. </div>
  99. </div>
  100. <div class="w-full h-full relative" v-else @click="handleClick">
  101. <ImageEvo :src="cover"></ImageEvo>
  102. </div>
  103. </template>