Ver código fonte

fix(app): 优化首页视频播放逻辑

EvilDragon 5 meses atrás
pai
commit
d1ecaa5881

+ 17 - 0
.vscode/extensions.json

@@ -0,0 +1,17 @@
+{
+  "recommendations": [
+    "vue.volar",
+    "stylelint.vscode-stylelint",
+    "esbenp.prettier-vscode",
+    "dbaeumer.vscode-eslint",
+    "antfu.unocss",
+    "antfu.iconify",
+    "evils.uniapp-vscode",
+    "uni-helper.uni-helper-vscode",
+    "uni-helper.uni-app-schemas-vscode",
+    "uni-helper.uni-highlight-vscode",
+    "uni-helper.uni-ui-snippets-vscode",
+    "uni-helper.uni-app-snippets-vscode",
+    "mrmlnc.vscode-json5"
+  ]
+}

+ 63 - 0
.vscode/settings.json

@@ -0,0 +1,63 @@
+{
+  // 默认格式化工具选择prettier
+  "editor.defaultFormatter": "esbenp.prettier-vscode",
+  // 保存的时候自动格式化
+  "editor.formatOnSave": true,
+  //开启自动修复
+  "editor.codeActionsOnSave": {
+    "source.fixAll": "explicit",
+    "source.fixAll.eslint": "explicit",
+    "source.fixAll.stylelint": "explicit"
+  },
+  // 配置stylelint检查的文件类型范围
+  "stylelint.validate": ["css", "scss", "vue", "html"], // 与package.json的scripts对应
+  "stylelint.enable": true,
+  "css.validate": false,
+  "less.validate": false,
+  "scss.validate": false,
+  "[shellscript]": {
+    "editor.defaultFormatter": "foxundermoon.shell-format"
+  },
+  "[dotenv]": {
+    "editor.defaultFormatter": "foxundermoon.shell-format"
+  },
+  "[vue]": {
+    "editor.defaultFormatter": "esbenp.prettier-vscode"
+  },
+  "[typescript]": {
+    "editor.defaultFormatter": "esbenp.prettier-vscode"
+  },
+  "[jsonc]": {
+    "editor.defaultFormatter": "esbenp.prettier-vscode"
+  },
+  // 配置语言的文件关联
+  "files.associations": {
+    "pages.json": "jsonc", // pages.json 可以写注释
+    "manifest.json": "jsonc" // manifest.json 可以写注释
+  },
+  "cSpell.words": [
+    "climblee",
+    "commitlint",
+    "dcloudio",
+    "iconfont",
+    "qrcode",
+    "refresherrefresh",
+    "scrolltolower",
+    "tabbar",
+    "unibest",
+    "uvui",
+    "WechatMiniprogram"
+  ],
+  "typescript.tsdk": "node_modules\\typescript\\lib",
+  // 控制相关文件嵌套展示
+  "explorer.fileNesting.enabled": true,
+  "explorer.fileNesting.expand": false,
+  "explorer.fileNesting.patterns": {
+    "*.ts": "$(capture).test.ts, $(capture).test.tsx",
+    "*.tsx": "$(capture).test.ts, $(capture).test.tsx",
+    // "*.env": "$(capture).env.*",
+    "CHANGELOG.md": "CHANGELOG*",
+    "package.json": "pnpm-lock.yaml,pnpm-workspace.yaml,LICENSE,.gitattributes,.gitignore,.gitpod.yml,CNAME,.npmrc,.browserslistrc",
+    ".eslintrc.cjs": ".eslintignore,.prettierignore,.stylelintignore,.commitlintrc.*,.prettierrc.*,.stylelintrc.*,.eslintrc-auto-import.json,.editorconfig,.commitlint.cjs"
+  }
+}

+ 56 - 0
.vscode/vue3.code-snippets

@@ -0,0 +1,56 @@
+{
+  // Place your unibest 工作区 snippets here. Each snippet is defined under a snippet name and has a scope, prefix, body and
+  // description. Add comma separated ids of the languages where the snippet is applicable in the scope field. If scope
+  // is left empty or omitted, the snippet gets applied to all languages. The prefix is what is
+  // used to trigger the snippet and the body will be expanded and inserted. Possible variables are:
+  // $1, $2 for tab stops, $0 for the final cursor position, and ${1:label}, ${2:another} for placeholders.
+  // Placeholders with the same ids are connected.
+  // Example:
+  // "Print to console": {
+  // 	"scope": "javascript,typescript",
+  // 	"prefix": "log",
+  // 	"body": [
+  // 		"console.log('$1');",
+  // 		"$2"
+  // 	],
+  // 	"description": "Log output to console"
+  // }
+  "Print unibest Vue3 SFC": {
+    "scope": "vue",
+    "prefix": "v3",
+    "body": [
+      "<route lang=\"json5\" type=\"page\">",
+      "{",
+      "  layout: 'default',",
+      "  style: {",
+      "    navigationBarTitleText: '$1',",
+      "  },",
+      "}",
+      "</route>\n",
+      "<template>",
+      "  <view class=\"\">$2</view>",
+      "</template>\n",
+      "<script lang=\"ts\" setup>",
+      "//$3",
+      "</script>\n",
+      "<style lang=\"scss\" scoped>",
+      "//$4",
+      "</style>\n",
+    ],
+  },
+  "Print unibest style": {
+    "scope": "vue",
+    "prefix": "st",
+    "body": ["<style lang=\"scss\" scoped>", "//", "</style>\n"],
+  },
+  "Print unibest script": {
+    "scope": "vue",
+    "prefix": "sc",
+    "body": ["<script lang=\"ts\" setup>", "//$3", "</script>\n"],
+  },
+  "Print unibest template": {
+    "scope": "vue",
+    "prefix": "te",
+    "body": ["<template>", "  <view class=\"\">$1</view>", "</template>\n"],
+  },
+}

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

@@ -28,32 +28,42 @@ const { data: indexConfigsData, run: setIndexConfigsData } = useRequest(
   () => getSetIndexConfigs(),
   { initialData: { list: [] } },
 )
-const indexVideoContexts = ref([])
+const swiperData = ref<{ data: any; videoContext: UniNamespace.VideoContext; playing: boolean }[]>()
+const swiperCurrent = ref(0)
 
 onShow(async () => {
   await run()
-  console.log(circlesData.value)
 })
 onLoad(async () => {
   await setIndexConfigsData()
-  console.log(indexConfigsData.value)
-  indexVideoContexts.value = indexConfigsData.value.list.map((it) =>
-    uni.createVideoContext(`video-${it.id}`, instance),
-  )
-  console.log(indexVideoContexts.value)
+  swiperData.value = indexConfigsData.value.list.map((it) => ({
+    data: it,
+    videoContext: uni.createVideoContext(`video-${it.id}`, instance),
+    playing: false,
+  }))
 })
 const toAbout = () => {
   uni.navigateTo({ url: '/pages/home/about/index' })
 }
+const handleSwiperChange = ({ detail: { current } }) => {
+  swiperCurrent.value = current
+}
+const handlePlay = () => {
+  swiperData.value[swiperCurrent.value].videoContext.play()
+  swiperData.value[swiperCurrent.value].playing = true
+}
 onShareAppMessage(() => ({}))
 </script>
 
 <template>
   <view class="">
     <view class="bg-black w-full relative aspect-[1.26/1]">
-      <swiper>
+      <swiper @change="handleSwiperChange">
         <template
-          v-for="{ id, coverVideoImage, indexPromotionalVideoImage } of indexConfigsData.list"
+          v-for="{
+            data: { id, coverVideoImage, indexPromotionalVideoImage },
+            playing,
+          } of swiperData"
           :key="id"
         >
           <swiper-item>
@@ -63,10 +73,11 @@ onShareAppMessage(() => ({}))
                 :id="`video-${id}`"
                 :src="indexPromotionalVideoImage"
               ></video>
-              <div class="absolute left-0 top-0 w-full h-full bg-black">
+              <div v-if="!playing" class="absolute left-0 top-0 w-full h-full bg-black">
                 <wd-img width="100%" height="100%" :src="coverVideoImage" />
               </div>
               <div
+                v-if="!playing"
                 class="w-[375px] h-[90px] bg-gradient-to-t from-black to-black/0 absolute left-0 bottom-0 w-full flex items-center"
               >
                 <view class="mx-7">
@@ -74,6 +85,7 @@ onShareAppMessage(() => ({}))
                     plain
                     custom-class="bg-transparent! border-white! text-white!"
                     icon="play"
+                    @click="handlePlay"
                   >
                     02:30
                   </wd-button>