Browse Source

沉浸式播放器 播放功能

harry 1 year ago
parent
commit
9732b01cb5

+ 1 - 1
config/prod.ts

@@ -24,7 +24,7 @@ export default {
     //     .plugin('prerender')
     //     .use(new Prerender({
     //       staticDir,
-    //       routes: [ '/pages/index/index' ],
+    //       routes: [ '/pages/category/index' ],
     //       postProcess: (context) => ({ ...context, outputPath: path.join(staticDir, 'index.html') })
     //     }))
     // }

+ 35 - 28
src/app.config.ts

@@ -1,31 +1,38 @@
 export default defineAppConfig({
-  pages: [
-    'pages/index/index',
-    'pages/user-videos/user-videos',
-    'pages/home/home'
-  ],
-  window: {
-    backgroundTextStyle: 'light',
-    navigationBarBackgroundColor: '#fff',
-    navigationBarTitleText: 'WeChat',
-    navigationBarTextStyle: 'black'
-  },
-  "subpackages": [],
+    pages: [
+        'pages/category/index',
+        'pages/share/share',
+        'pages/home/home'
+    ],
+    window: {
+        backgroundTextStyle: 'light',
+        navigationBarBackgroundColor: '#fff',
+        navigationBarTitleText: 'WeChat',
+        navigationBarTextStyle: 'black'
+    },
+    "subpackages": [
+        {
+            "root": "subPackages/safe",
+            "pages": [
+                "complaining/index"
+            ]
+        }
+    ],
 
-  tabBar: {
-    custom: true,
-    color: '#ffffff',
-    selectedColor: '#DC143C',
-    backgroundColor: '#000000',
-    list: [
-      {
-        pagePath: 'pages/index/index',
-        text: '首页'
-      },
-      {
-        pagePath: 'pages/home/home',
-        text: '我的'
-      }
-    ]
-  }
+    tabBar: {
+        custom: true,
+        color: '#ffffff',
+        selectedColor: '#DC143C',
+        backgroundColor: '#000000',
+        list: [
+            {
+                pagePath: 'pages/category/index',
+                text: '首页'
+            },
+            {
+                pagePath: 'pages/home/home',
+                text: '我的'
+            }
+        ]
+    }
 })

+ 73 - 26
src/app.ts

@@ -3,8 +3,13 @@ import Taro, { useDidHide, useDidShow, useLaunch } from '@tarojs/taro'
 import { globalApp } from '@/class/GlobalContext'
 import {
     isEasyMode, createSessionId, formatQuery, formatDate
-  } from '@/utils'
+} from '@/utils'
 import useHotLaunch from '@/hooks/useHotLaunch'
+import http from '@/http/index'
+import {
+    getWxUserInfoByCode, getAbtestConfig, getPositionInfo,
+    generateMidv2, getUserFrontConfig
+} from '@/http/api'
 
 import './app.less'
 
@@ -12,20 +17,21 @@ function App({ children }: PropsWithChildren<any>) {
 
     useLaunch(async (launch) => {
         globalApp()
+        console.log('hhz - launch option:', launch)
 
-        // // create session id
-        // updateSession()
+        // create session id
+        updateSession()
 
         // system info
         updateSystem()
 
-        // updateGlobal(launch)
+        updateGlobal(launch)
 
         // // network change
         // listeningConnectStatus()
 
-        // // userinfo
-        // await updateUserInfo()
+        // userinfo
+        await updateUserInfo()
 
         // mid
         // const mid = await requestMid()
@@ -36,17 +42,6 @@ function App({ children }: PropsWithChildren<any>) {
         // getAccountInfoInApp()
     })
 
-    // useHotLaunch((options) => {
-    //     Taro.$global.set('subSessionid', createSessionId())
-
-    //     const launchOption = Taro.$global.get('launchOption')
-    //     Taro.$global.set('launchOption', {
-    //         ...launchOption,
-    //         hotScene: options.scene
-    //     })
-
-    //     reportShareVideo()
-    // })
 
     useDidShow((options) => {
         // updateAbGroup()
@@ -60,30 +55,82 @@ function App({ children }: PropsWithChildren<any>) {
         Taro.$abGroupInstance
             .cleanLoop()
             .cleanStack()
+
+    
+        const id = createSessionId()
+        Taro.$global.set('subSessionId', id)
     })
+
     useHotLaunch((options) => {
         Taro.$global.set('subSessionid', createSessionId())
-    
+
         const launchOption = Taro.$global.get('launchOption')
         Taro.$global.set('launchOption', {
-          ...launchOption,
-          hotScene: options.scene
+            ...launchOption,
+            hotScene: options.scene
         })
-    
+
         // reportShareVideo()
-      })
+    })
     // children 是将要会渲染的页面
     return children
 }
 
+function updateGlobal(launch) {
+    Taro.$global.set('launchOption', {
+        ...launch,
+        hotScene: launch.scene
+    })
+
+    // 三十天有无回流
+    Taro.$global.set('isReturningUser', !!Taro.getStorageSync('$RETURNING'))
+
+    // 上报
+    // fetchPositionInfo()
+}
+
 // system
 function updateSystem() {
     const systemInfo = Taro.getSystemInfoSync()
-  
+
     Taro.$global.set('systemInfo', {
-      ...systemInfo,
-      easyMode: isEasyMode(systemInfo) && 2 || 1// 关怀模式
-    }) 
+        ...systemInfo,
+        easyMode: isEasyMode(systemInfo) && 2 || 1// 关怀模式
+    })
+}
+// userinfo
+async function updateUserInfo() {
+    const userInfo = Taro.getStorageSync('$USER_INFO')
+
+    if (userInfo) {
+        Taro.$global.set('userInfo', userInfo)
+        return Promise.resolve(userInfo)
+    }
+
+    return Taro.loginSync()
+        .then((res: Taro.login.SuccessCallbackResult) => {
+            const { code } = res
+            return http.post(getWxUserInfoByCode, { code })
+        }).then((res: RequestType) => {
+            const { code, data } = res
+
+            if (code !== 0)
+                return
+
+            Taro.$global.set('userInfo', data)
+            Taro.setStorageSync('$USER_INFO', data)
+
+            return data
+        }).catch((err) => {
+            console.log(err)
+        })
 }
+// session
+function updateSession() {
+    const id = createSessionId()
+    Taro.$global.set('sessionId', id)
+    Taro.$global.set('subSessionId', id)
+}
+
 
 export default App

+ 328 - 200
src/components/VideoSwiper/index.less

@@ -1,225 +1,353 @@
 .video-swiper {
-  width: 100%;
-  height: 100%;
-  background-color: #000;
-
-  .video-swiper-item {
-    display: flex;
-    flex-direction: column;
-    position: relative;
-    box-sizing: border-box;
-
-    .custom-video {
-      width: 100%;
-      height: calc(100% - 100px);
-      position: relative;
-
-      .video {
-        width: 100%;
-        height: 100%
-      }
-
-      .video-play-end-cover {
-        position: absolute;
-        top: 0;
-        bottom: 0;
-        left: 0;
-        right: 0;
-        background: rgba(0, 0, 0, .95);
-        z-index: 1;
+    width: 100%;
+    height: 100%;
+    background-color: #000;
+
+    .video-swiper-item {
         display: flex;
         flex-direction: column;
-        align-items: center;
-        justify-content: center;
-
-        .container {
-          width: 100%;
-          display: flex;
-          justify-content: space-around;
-          color: #fff;
-          margin-top: 150px;
-          margin-bottom: 300px;
-
-          .item {
-            display: flex;
-            flex-direction: column;
-            font-size: 30px;
-            align-items: center;
-            margin: 0;
-            padding: 0;
-            background: transparent;
+        position: relative;
+        box-sizing: border-box;
+
+        .custom-video {
+            width: 100%;
+            height: 100%;
+            position: relative;
+
+            .video {
+                width: 100%;
+                height: calc(100% - 6px);
+            }
+
+            .progress-bg {
+                position: absolute;
+                bottom: 0;
+                width: 100%;
+                height: 40px;
+
+                .progress-container {
+                    position: absolute;
+                    bottom: 0;
+                    width: 100%;
+                    height: 6px;
+                    border-radius: 3px;
+                    background-color: #0f0f0f;
+    
+                    .progress{
+                        height: inherit;
+                        border-radius: 4px 0 0 4px;
+                        background-color: #4c4c4c;
+                    }
+                }
+            }
+
+            .progress-indicator{
+                position: absolute;
+                bottom: 20px;
+                left: 0;
+                width: 100%;
+                height: 100px;
+                display: flex;
+                flex-direction: column;
+                justify-content: space-between;
+                align-items: center;
+
+                .showInfo {
+                    display: flex;
+                    flex-direction: row;
+                    height: 60px;
+                    width: 400px;
+                    align-items: center;
+                    justify-content: center;
+                    font-size: 36px;
+                    font-weight: 500;
+                    .showInfo-a {
+                        height: 60px;
+                        color: #fff;
+                        margin-right: 20px;
+                    }
+                    .showInfo-m{
+                        height: 24px;
+                        width: 2px;
+                        background-color: #999;
+                    }
+                    .showInfo-b {
+                        height: 60px;
+                        color: #999;
+                        margin-left: 20px;
+                    }
+                }
+                .indicator-bg {
+                    display: flex;
+                    flex-direction: row;
+                    width: 90%;
+                    height: 20px;
+                    background-color: #979797;
+                    align-items: center;
+                    border-radius: 10px;
+
+                    .indcator-active{
+                        height: 20px;
+                        background-color: #d5d5d5;
+                        border-radius: 10px 0 0 10px;
+                    }
+                    .indicator-dot {
+                        background-color: white;
+                        height: 32px;
+                        width: 12px;
+                        border-radius: 6px;
+                    }
+                }
+            }
+
+            .video-play-end-cover {
+                position: absolute;
+                top: 0;
+                bottom: 0;
+                left: 0;
+                right: 0;
+                background: rgba(0, 0, 0, .5);
+                z-index: 1;
+                display: flex;
+                flex-direction: column;
+                align-items: center;
+                justify-content: center;
+
+                .container {
+                    width: 100%;
+                    display: flex;
+                    justify-content: space-around;
+                    color: #fff;
+                    margin-top: 150px;
+                    margin-bottom: 300px;
+
+                    .item {
+                        display: flex;
+                        flex-direction: column;
+                        font-size: 30px;
+                        align-items: center;
+                        margin: 0;
+                        padding: 0;
+                        background: transparent;
+                        color: #fff;
+
+                        Image {
+                            width: 120px;
+                            height: 120px;
+                            margin-bottom: 20px;
+                        }
+                    }
+                }
+
+                .more-video {
+                    position: relative;
+                    width: 100%;
+                    color: #fff;
+                    font-size: 26px;
+                    display: flex;
+                    align-items: center;
+                    flex-direction: column;
+
+                    Image {
+                        position: absolute;
+                        bottom: 0;
+                        width: 108px;
+                        height: 106px;
+                        animation: turn 1.5s infinite;
+                    }
+                }
+            }
+
+        }
+
+        .video-introduce {
+            box-sizing: border-box;
+            width: calc(100% - 120px);
+            position: absolute;
+            left: 0;
+            bottom: 40px;
             color: #fff;
+            font-size: 32px;
+            padding: 0 20px;
+            text-shadow: #000 1px 0 6px;
+            background: linear-gradient(to bottom, rgba(0, 0, 0, 0), 10%, rgba(0, 0, 0, .1), rgba(0, 0, 0, 0));
+
+            .video-user-info {
+                display: flex;
+                align-items: center;
+                font-size: 36px;
+
+                .avatar {
+                    width: 50px;
+                    height: 50px;
+                    border-radius: 50%;
+                    margin-right: 15px;
+                }
+            }
+
+            .video-title {
+                margin: 20px 0;
+            }
+
+            .redShareBtn{
+                width: 90%;
+                height: 80px;
+                background-color: #EE2C4F;
+                border-radius: 8px;
 
-            Image {
-              width: 120px;
-              height: 120px;
-              margin-bottom: 20px;
+                text-align: center;
+                font-size: 38px;
+                line-height: 80px;
+                color: #fff;
+                text-shadow: none;
             }
-          }
         }
 
-        .more-video {
-          position: relative;
-          width: 100%;
-          color: #fff;
-          font-size: 26px;
-          display: flex;
-          align-items: center;
-          flex-direction: column;
 
-          Image {
+        .video-bar {
+            display: flex;
+            flex-direction: column;
+            align-items: center;
+            box-sizing: border-box;
+            width: 90px;
+            height: 100%;
+            padding: 10px 0px;
+            margin-right: 20px;
+            justify-content: flex-end;
             position: absolute;
-            bottom: 0;
-            width: 108px;
-            height: 106px;
-            animation: turn 1.5s infinite;
-          }
-        }
-      }
-    }
+            right: 0;
+            bottom: 10px;
 
-    .video-bar {
-      display: flex;
-      align-items: center;
-      box-sizing: border-box;
-      width: 100%;
-      height: 100px;
-      padding: 0 40px;
-      justify-content: space-between;
-
-      .operation {
-        height: 60px;
-        display: flex;
-        margin-right: 40px;
-        position: relative;
-        align-items: center;
+            .friend {
+                display: flex;
+                flex-direction: column;
+                align-items: center;
+                height: 190px;
+                width: 70px;
+                color: #fff;
+                font-size: 24px;
+                padding-bottom: 16px;
+                border-radius: 40px;
+                background-color: #04740399;
 
-        .bot {
-          width: 2px;
-          height: 2px;
-          border: 2px solid #fff;
-          border-radius: 50%;
-        }
+                image {
+                    width: 70px;
+                    height: 70px;
+                    margin-bottom: 10px;
+                }
+                .text {
+                    width: 30px;
+                    font-size: 30px;
+                    line-height: 44px;
+                }
 
-        .margin10 {
-          margin: 0 10px;
-        }
+            }
 
-        .tips {
-          position: absolute;
-          width: 100px;
-          height: 40px;
-          border-radius: 4px;
-          background: #fff;
-          font-size: 22px;
-          display: flex;
-          justify-content: center;
-          align-items: center;
-          padding: 4px 10px;
-          color: #6a6969;
-          top: -40px;
-          z-index: 1;
-
-          image {
-            width: 40px;
-            height: 40px;
-            margin-right: 8px;
-          }
-        }
+            .pyq {
+                display: flex;
+                flex-direction: column;
+                align-items: center;
+                background-color: transparent;
+                width: 70px;
+                height: 110px;
+                margin-top: 40px;
+                font-size: 26px;
+                image {
+                    width: 70px;
+                    height: 70px;
+                    margin-bottom: 10px;
+                }
+                .text {
+                    color: white;
+                    width: 90px;
+                    font-size: 22px;
+                    line-height: 30px;
+                }
+            }
 
-        .tips::after {
-          position: absolute;
-          content: ' ';
-          bottom: -10px;
-          left: 4px;
-          width: 0;
-          height: 0;
-          border-top: 16px solid #fff;
-          border-left: 16px solid transparent;
-          border-right: 16px solid transparent;
-        }
-      }
+            .more {
+                height: 60px;
+                display: flex;
+                position: relative;
+                align-items: center;
+                margin-top: 40px;
 
-      .right {
-        display: flex;
-        align-items: center;
-
-        .like {
-          display: flex;
-          align-items: center;
-          height: 100px;
-          color: #fff;
-          font-size: 24px;
-  
-          .like-icon {
-            width: 60px;
-            height: 60px;
-          }
-        }
+                .bot {
+                    width: 4px;
+                    height: 4px;
+                    background-color: #999;
+                    border: 2px solid #999;
+                    border-radius: 50%;
+                }
 
-        .share-btn-f {
-          margin-left: 20px;
-          height: 60px;
-          background: #55c57c;
-          display: flex;
-          align-items: center;
-          color: #fff;
-          font-size: 28px;
-
-          .wechat-icon {
-            margin-right: 10px;
-            width: 40px;
-            height: 40px;
-            background: transparent url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFAAAABGCAMAAABsQOMZAAAAflBMVEUAAAD////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////vroaSAAAAKXRSTlMA9wjz1ykDEMQx5IHeXG7ovVQao2jtzqmdkXoVi0g9tU1CIMmvlmI4dBMRDGIAAALGSURBVFjDtddnc6MwEAbglRCYYtPdwL2///8P3lzgBoWiQnLPp8zGZrza1SLRqPy1P4vEYc7yfi4+b04/scieAt+xNHJpptvewSg/88heUDBMCitum+wWauJKNq4htIqaTPEDTCSBabp3mHGOZIL7MMVeJs9LYWFFOt4ZNhztOh5gZ7nQ9AuTP1y+Lzs0JmNndcJC3mFfuyED1DFlqWO5hLcmVozE5H20UVU4QUdQY6WJIaOhsc/51LhoYhA0yYfE4U0wUsQa7uSeY5Admqno6GL4qDKWPWvyLqE+ltKE/XCQMmhjLBScxqWwE+5WJ1e1U5awkMZtLeqc04Q1TLFtQMRPUSoSBsBZ+sUqpwEGQzuXeHl2elHx7I8ex3DprlRH49mk1xlr+Fjw/XQumxN17jAQ01tAgR26Gu2gV3oRg9rGpVYJrY/3gJbzL20XOpG3tXrTCKj5XgEj6/aJFZSYG8FQ0uzInKkTdlmXVZR9BCRstypTqfcH82Zoyf0up1v/jHHsfb9p8dxRdWAp/d2v4pb+4t0GamdarCjdQkox6G/WeDABM91MfAToXJp3hvRuGPTJo4nkISa85AU+97si/CrrVa5SO3qDqWV015AUOfGKoXMPyMsSSEpqHNlEE/ZbjfW7uRcoqHVyRpsmg6HhGSVYjv07hqVEfanwI1hiJBkOAfGzB96HA8Q65ZA6OQbYak5RBrNb6gTrB+6GhxL/xE/xtq15lMBO2T/XbY7U8Gr3fTy6e9i5fT/XiYx6AljxqbPF8uXRgMDMSxYXMacRL1gQnvRArj2D62VkwGUw9SAjlfEuqcnMzu6SqucVdld9PZPDzTIgC17FdB1dk51AQOXpkS1+cDDtRDMsqgRTDjQLfz36P5O1JaG5vHd03oTs67p3f65cHifSbXe+RXc149UaQEW/aBE52NCvqvcsp9+Vu/Sf/AGRfvtxDfRcnAAAAABJRU5ErkJggg==) no-repeat no-repeat center/contain;
-          }
-        }
-      }
+                .margin10 {
+                    margin: 0 10px;
+                }
 
-    }
+                .tips {
+                    position: absolute;
+                    width: 100px;
+                    height: 40px;
+                    border-radius: 4px;
+                    background: #fff;
+                    font-size: 22px;
+                    display: flex;
+                    justify-content: center;
+                    align-items: center;
+                    padding: 4px 10px;
+                    color: #6a6969;
+                    right: 60px;
+                    z-index: 1;
 
-    .video-introduce {
-      box-sizing: border-box;
-      width: 100%;
-      position: absolute;
-      left: 0;
-      bottom: 180px;
-      color: #fff;
-      font-size: 30px;
-      padding: 0 20px;
-      text-shadow: #000 1px 0 6px;
-      background: linear-gradient(to bottom, rgba(0, 0, 0, 0), 10%, rgba(0, 0, 0, .1), rgba(0, 0, 0, 0));
-
-      .video-user-info {
-        display: flex;
-        align-items: center;
+                    image {
+                        width: 40px;
+                        height: 40px;
+                        margin-right: 8px;
+                    }
+                }
 
-        .avatar {
-          width: 50px;
-          height: 50px;
-          border-radius: 50%;
-          margin-right: 15px;
-        }
-      }
+                .tips::after {
+                    position: absolute;
+                    content: ' ';
+                    right: -26px;
+                    width: 0;
+                    height: 0;
+                    border: 10px solid transparent;
+                    border-left: 26px solid #fff;
+                }
+            }
 
-      .video-title {
-        margin: 10px 0;
-      }
+            .share-btn-f {
+                margin-left: 20px;
+                height: 60px;
+                background: #55c57c;
+                display: flex;
+                align-items: center;
+                color: #fff;
+                font-size: 28px;
+
+                .wechat-icon {
+                    margin-right: 10px;
+                    width: 40px;
+                    height: 40px;
+                    background: transparent url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFAAAABGCAMAAABsQOMZAAAAflBMVEUAAAD////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////vroaSAAAAKXRSTlMA9wjz1ykDEMQx5IHeXG7ovVQao2jtzqmdkXoVi0g9tU1CIMmvlmI4dBMRDGIAAALGSURBVFjDtddnc6MwEAbglRCYYtPdwL2///8P3lzgBoWiQnLPp8zGZrza1SLRqPy1P4vEYc7yfi4+b04/scieAt+xNHJpptvewSg/88heUDBMCitum+wWauJKNq4htIqaTPEDTCSBabp3mHGOZIL7MMVeJs9LYWFFOt4ZNhztOh5gZ7nQ9AuTP1y+Lzs0JmNndcJC3mFfuyED1DFlqWO5hLcmVozE5H20UVU4QUdQY6WJIaOhsc/51LhoYhA0yYfE4U0wUsQa7uSeY5Admqno6GL4qDKWPWvyLqE+ltKE/XCQMmhjLBScxqWwE+5WJ1e1U5awkMZtLeqc04Q1TLFtQMRPUSoSBsBZ+sUqpwEGQzuXeHl2elHx7I8ex3DprlRH49mk1xlr+Fjw/XQumxN17jAQ01tAgR26Gu2gV3oRg9rGpVYJrY/3gJbzL20XOpG3tXrTCKj5XgEj6/aJFZSYG8FQ0uzInKkTdlmXVZR9BCRstypTqfcH82Zoyf0up1v/jHHsfb9p8dxRdWAp/d2v4pb+4t0GamdarCjdQkox6G/WeDABM91MfAToXJp3hvRuGPTJo4nkISa85AU+97si/CrrVa5SO3qDqWV015AUOfGKoXMPyMsSSEpqHNlEE/ZbjfW7uRcoqHVyRpsmg6HhGSVYjv07hqVEfanwI1hiJBkOAfGzB96HA8Q65ZA6OQbYak5RBrNb6gTrB+6GhxL/xE/xtq15lMBO2T/XbY7U8Gr3fTy6e9i5fT/XiYx6AljxqbPF8uXRgMDMSxYXMacRL1gQnvRArj2D62VkwGUw9SAjlfEuqcnMzu6SqucVdld9PZPDzTIgC17FdB1dk51AQOXpkS1+cDDtRDMsqgRTDjQLfz36P5O1JaG5vHd03oTs67p3f65cHifSbXe+RXc149UaQEW/aBE52NCvqvcsp9+Vu/Sf/AGRfvtxDfRcnAAAAABJRU5ErkJggg==) no-repeat no-repeat center/contain;
+                }
+            }
+        }
 
-      .video-play-count {
-        font-size: 28px;
-      }
     }
 
-    @keyframes turn { 
-      0% {             
-          transform: translate(0px, -150px);            
-       }            
-       50% {                
-          transform: translate(0px, -50px);            
-       }            
-       100% {                
-          transform: translate(0px, -150px);
-       }
+    @keyframes turn {
+        0% {
+            transform: translate(0px, -150px);
+        }
+
+        50% {
+            transform: translate(0px, -50px);
+        }
+
+        100% {
+            transform: translate(0px, -150px);
+        }
     }
-  }
-}
+}

+ 544 - 329
src/components/VideoSwiper/index.tsx

@@ -1,376 +1,591 @@
-import { useEffect, useState, useCallback } from 'react'
-import Taro, { useReady } from '@tarojs/taro'
+import { useEffect, useState, useImperativeHandle, memo, forwardRef } from 'react'
+import Taro, { useLoad, useReady } from '@tarojs/taro'
 import {
-  Swiper, SwiperItem, Video,
-  View,  Image, Button
+    Swiper, SwiperItem, Video,
+    View, Image, Button, Progress
 } from '@tarojs/components'
-import { DETAIL_PAGESOURCE, CATEGORY_PAGESOURCE, LIKE_ICON, DEFAULT_ICON, VIEW_AUTO_TYPE } from '@/const'
-import { favoriteUrl, unfavoriteUrl } from '@/http/api'
+import { DETAIL_PAGESOURCE, CATEGORY_PAGESOURCE, VIEW_AUTO_TYPE } from '@/const'
+// import { favoriteUrl, unfavoriteUrl } from '@/http/api'
 import Route from '@/class/Route'
 import { videoViewReport, videoPlayReport, videoActionReport } from '@/logger'
-import { once } from '@/utils'
+import { once, formatSecondsAsTime } from '@/utils'
 import './index.less'
+import { PlayState } from '@/constants/commentTypes'
 
 
 let activeIndex = 0
-let favoritePending = false
+let lastSwiperItemIndex = 0     // 上个 item 索引
+let currentListIndex = 0 // 大视频列表的索引
+let isUp = false
+
 const videoViewedMap = new Map()
 
-export default function VideoSwiper({ list, onFinish, circular, onFavorited }) {
-  const [currentIndex, setCurrentIndex] = useState(0)
-
-  useReady(() => {
-    activeIndex = 0
-    videoViewedMap.clear()
-  })
-
-  function onSwiperChange(res) {
-    const { detail } = res || {}
-    const { current } = detail || {}
-    activeIndex = current
-  }
-
-  function onAnimationFinish() {
-    onFinish(activeIndex)
-    setCurrentIndex(activeIndex)
-  }
-
-  return (
-    <Swiper
-      className='video-swiper'
-      vertical
-      circular={circular}
-      current={currentIndex}
-      onChange={onSwiperChange}
-      onAnimationFinish={onAnimationFinish}
-    >
-      {list.map((video, index) => {
-        return (
-          <SwiperItem className='video-swiper-item' key={video.id}>
-            <CustomVideo video={video} current={currentIndex} index={index}/>
-            <VideoIntroduce detail={video} />
-            <VideoBar video={video} onFavorited={onFavorited}/>
-          </SwiperItem>
-        )
-      })}
-    </Swiper>
-  )
+export default function VideoSwiper({ list, onFinish, needResumePlay }) {
+    const [currentIndex, setCurrentIndex] = useState(0)
+    const [circular, setCircular] = useState(false)
+    const [showRedShareBtn, setShowRedShareBtn] = useState(false)
+    const [seekProgress, setSeekProgress] = useState(false)
+    const [needPlayerResume, setNeedPlayerResume] = useState(false)
+
+
+    const [videoList, setVideoList] = useState<VideoInfo[]>(list.slice(0, 3))
+    useReady(() => {
+        activeIndex = 0
+        videoViewedMap.clear()
+    })
+
+    useLoad(() => {
+
+    })
+
+    /**
+     * @description: 进度回调。秒单位
+     * @param {*} e
+     * @return {*}
+     */
+    function didTimeUpdate(e) {
+        // console.log(e)
+        let { currentTime = 0, duration = 1000000 } = e
+        if (!showRedShareBtn && currentTime / duration >= 0.1) {
+            setShowRedShareBtn(true)
+        }
+    }
+    function onProgressMove(e) {
+        setSeekProgress(e || false)
+    }
+
+    function onSwiperChange(res) {
+        const { detail } = res || {}
+        const { current } = detail || {}
+        isUp = (lastSwiperItemIndex + 1) % 3 == current
+        lastSwiperItemIndex = current
+
+        if (isUp) {
+            currentListIndex += 1
+        } else {
+            currentListIndex -= 1
+            if (currentListIndex < 0) {
+                currentListIndex += 3
+            }
+        }
+        console.log('hhz- currentListIndex:', currentListIndex)
+
+    }
+
+    function onAnimationFinish(e) {
+        const { detail } = e || {}
+        const { current } = detail || {}
+
+        if (activeIndex == current) {
+            if (currentListIndex == 0) {
+                onFinish(-99)
+            }
+            return
+        }
+        activeIndex = current
+
+        if (isUp) {
+            if (!circular && currentListIndex > 0) {
+                setCircular(true)
+            }
+        } else {
+            if (circular && currentListIndex < 2) {
+                setCircular(false)
+            }
+        }
+
+        let changed = false
+        let nextSwiperItemIndex = (current + 1) % 3
+        if (currentListIndex < list.length - 1) {
+            let nextVideo = list[currentListIndex + 1]
+            let replaceVideo = videoList[nextSwiperItemIndex]
+            if (nextVideo && nextVideo.id != replaceVideo.id) {
+                videoList[nextSwiperItemIndex] = nextVideo
+                changed = true
+            }
+        }
+        let preSwiperItemIndex = (current - 1 + 3) % 3
+        if (currentListIndex > 0) {
+            let nextVideo = list[currentListIndex - 1]
+            let replaceVideo = videoList[preSwiperItemIndex]
+            if (nextVideo && nextVideo.id != replaceVideo.id) {
+                videoList[preSwiperItemIndex] = nextVideo
+                changed = true
+            }
+        }
+        changed && setVideoList(videoList)
+        onFinish(currentListIndex)
+        setCurrentIndex(activeIndex)
+    }
+
+    function replayCurrentVideo() {
+        setNeedPlayerResume(true)
+        setTimeout(() => {
+            setNeedPlayerResume(false)
+        }, 1000);
+
+    }
+
+    useEffect(() => {
+        if (list.length > 0 && videoList.length == 0) {
+            setVideoList(list.slice(0, 3))
+        }
+    }, [list])
+    useEffect(() => {
+        if (needResumePlay) {
+            replayCurrentVideo()
+        }
+    }, [needResumePlay])
+
+    return (
+        <Swiper
+            className='video-swiper'
+            vertical
+            circular={circular}
+            current={currentIndex}
+            onChange={onSwiperChange}
+            onAnimationFinish={onAnimationFinish}
+        >
+            {videoList.map((video, index) => {
+                return (
+                    <SwiperItem className='video-swiper-item' key={video.id}>
+                        <CustomVideo
+                            video={video}
+                            current={currentIndex}
+                            index={index}
+                            needResumePlay={needPlayerResume}
+                            onTimeUpdate={didTimeUpdate}
+                            onProgressMove={onProgressMove} />
+                        {!seekProgress && <VideoIntroduce detail={video} showRedShareBtn={showRedShareBtn} />}
+                        {!seekProgress && <VideoBar video={video} />}
+                    </SwiperItem>
+                )
+            })}
+        </Swiper>
+    )
 }
 
-function CustomVideo({ video, current, index }) {
-  const [showEndCover, setShowEndCover] = useState(false)
-  let videoContext = Taro.createVideoContext(`${video.id}`)
-  const logReportVideoPlaySuccessOnce = once(logReportVideoPlaySuccess)
-  const logReportVideoRealPlayOnce = once(logReportVideoRealPlay)
-  const logReportVideoPlayEndOnce = once(logReportVideoPlayEnd)
-  
-  useEffect(() => {
-    logReportVideoView(video, current, index)
-
-    if (current === index) {
-      videoContext.play()
-
-      logReportVideoPlay(video)
-    } else {
-      videoContext.pause()
+function CustomVideo({ video, current, index, onTimeUpdate, onProgressMove, needResumePlay }) {
+    const [showEndCover, setShowEndCover] = useState(false)
+    const [durPersec, setDurPersec] = useState(1)
+    const [showProgressIndicator, setShowProgressIndicator] = useState(false)
+    const [playerState, setPlayerState] = useState(0)
+    const [isPlaying, setIsPlaying] = useState(false)
+    const [seekTime, setSeekTime] = useState(0)
+    const [videoDuraing, setVideoDuraing] = useState(0)
+    const [playTimeWhenMove, setPlayTimeWhenMove] = useState(0)
+    const [currentPlayTime, setCurrentPlayTime] = useState(0)
+    const [startMoveX, setStartMoveX] = useState(0)
+
+    let videoContext = Taro.createVideoContext(`${video.id}`)
+    const logReportVideoPlaySuccessOnce = once(logReportVideoPlaySuccess)
+    const logReportVideoRealPlayOnce = once(logReportVideoRealPlay)
+    const logReportVideoPlayEndOnce = once(logReportVideoPlayEnd)
+
+    useEffect(() => {
+        logReportVideoView(video, current, index)
+
+        if (current === index) {
+            playerPlay()
+
+            logReportVideoPlay(video)
+        } else {
+            playerPause()
+        }
+    }, [current, video])
+
+    useEffect(() => {
+        setShowEndCover(false)
+    }, [current])
+    useEffect(() => {
+        if (needResumePlay && current == index){
+            playerPlay()
+        }
+    }, [current, needResumePlay])
+
+    function playerPlay() {
+        videoContext.play()
+        setPlayerState(PlayState.playing)
+
+        setIsPlaying(true)
     }
-  }, [current, video])
 
-  useEffect(() => {
-    setShowEndCover(false)
-  }, [current])
+    function playerPause() {
+        videoContext.pause()
+        setPlayerState(PlayState.pause)
+        setIsPlaying(false)
+    }
 
-  function onTimeUpdate(evt) {
-    if (current !== index)
-      return
-    
-    const { detail } = evt || {}
-    const { currentTime, duration } = detail || {}
-
-    logReportVideoPlaySuccessOnce(video)
-
-    if (currentTime / duration >= 0.3 || currentTime >= 20)
-      logReportVideoRealPlayOnce(video)
-  }
-
-  function onEnded() {
-    logReportVideoPlayEndOnce(video)
-    current === index && setShowEndCover(true)
-  }
-
-  function onRePlay() {
-    setShowEndCover(false)
-    videoContext.seek(0)
-    videoContext.play()
-
-    logReportVideoPlay(video)
-  }
-
-  return (
-    <View className='custom-video'>
-      <Video
-        className='video'
-        id={`${video.id}`}
-        src={video.videoPath || ''}
-        controls
-        autoplay={false}
-        showCenterPlayBtn={false}
-        poster={video.videoCoverSnapshotPath}
-        onTimeUpdate={onTimeUpdate}
-        onEnded={onEnded}
-      />
-
-      {showEndCover && <VideoPlayEndCover onRePlay={onRePlay} />}
-    </View>
-  )
+    function didLoadedMeta(e) {
+        let { duration = 0 } = e.detail || {}
+        setVideoDuraing(duration)
+    }
+
+    function onSeekCom(e) {
+        console.log(e)
+    }
+
+    function didTimeUpdate(evt) {
+        if (current !== index)
+            return
+
+        const { detail } = evt || {}
+        const { currentTime, duration } = detail || {}
+        setCurrentPlayTime(currentTime)
+
+        onTimeUpdate(detail)
+        setDurPersec(currentTime / duration)
+
+        logReportVideoPlaySuccessOnce(video)
+        if (durPersec >= 0.3 || currentTime >= 20)
+            logReportVideoRealPlayOnce(video)
+    }
+
+    function didPaused() {
+        console.log('didPaused', index)
+    }
+    function onEnded() {
+        setPlayerState(PlayState.stoped)
+        current === index && setShowEndCover(true)
+        logReportVideoPlayEndOnce(video)
+        setIsPlaying(false)
+
+        // 自动重播
+        videoContext.seek(0)
+        playerPlay()
+    }
+
+    function onTapVideo() {
+        if (playerState != PlayState.playing) {
+            playerPlay()
+        } else if (playerState == PlayState.playing) {
+            playerPause()
+        }
+    }
+
+    function onRePlay() {
+        setShowEndCover(false)
+        videoContext.seek(0)
+        playerPlay()
+        logReportVideoPlay(video)
+    }
+
+    function onTouchStart(e) {
+        console.log('hhz- start ', e)
+        let { clientX = 0 } = (e.changedTouches || [])[0]
+        setStartMoveX(clientX)
+        onProgressMove(true)
+        setShowProgressIndicator(true)
+        setPlayTimeWhenMove(currentPlayTime)
+    }
+
+    function onTouchMove(e) {
+        let { clientX = 0 } = (e.changedTouches || [])[0]
+        let rate = coculationRate(clientX - startMoveX)
+
+        changeIndicator(rate)
+        // 移动中
+        //计算 seek 进度,并设置播放器 seek。 等比设置:拖动屏幕宽距离,偏移 50% 进度
+
+
+
+    }
+
+    function onTouchEnd(e) {
+        let { clientX = 0 } = (e.changedTouches || [])[0]
+
+        onProgressMove(false)
+        setShowProgressIndicator(false)
+
+        let rate = coculationRate(clientX - startMoveX)
+        let t = Math.min(Math.max(0, playTimeWhenMove + videoDuraing * rate), videoDuraing)
+        videoContext.seek(t)
+
+    }
+
+    function changeIndicator(rate) {
+        let t = Math.min(Math.max(0, playTimeWhenMove + videoDuraing * rate), videoDuraing)
+        setSeekTime(t)
+    }
+
+    function coculationRate(distance) {
+        const systemInfo = Taro.$global.get('systemInfo')
+        let { width = 375 } = systemInfo.safeArea
+
+        // 移动中
+        //计算 seek 进度,并设置播放器 seek。 等比设置:拖动屏幕宽距离,偏移 50% 进度
+        let rate = distance / width * 0.5
+        return rate
+    }
+
+    return (
+        <View className='custom-video'>
+            <Video
+                className='video'
+                id={`${video.id}`}
+                src={video.videoPath || ''}
+                controls={false}
+                autoplay={false}
+                showCenterPlayBtn={false}
+                showBottomProgress={true}
+                poster={video.videoCoverSnapshotPath}
+                onTimeUpdate={didTimeUpdate}
+                onEnded={onEnded}
+                onPause={didPaused}
+                onLoadedMetaData={didLoadedMeta}
+                onSeekComplete={onSeekCom}
+                onTap={onTapVideo}
+            />
+            <View className='progress-bg'
+                onTouchStart={onTouchStart}
+                onTouchMove={onTouchMove}
+                onTouchEnd={onTouchEnd}
+            >
+                <View className='progress-container'>
+                    <View className='progress' style={{ width: `${durPersec * 100}%;` }}>
+
+                    </View>
+                </View>
+
+            </View>
+            {showProgressIndicator && <View className='progress-indicator'>
+                <View className='showInfo'>
+                    <View className='showInfo-a'>{formatSecondsAsTime(seekTime)}</View>
+                    <View className='showInfo-m'></View>
+                    <View className='showInfo-b'>{formatSecondsAsTime(videoDuraing)}</View>
+                </View>
+                <View className='indicator-bg'>
+                    <View className='indcator-active' style={{ width: `${seekTime / videoDuraing * 100}%;` }}></View>
+                    <View className='indicator-dot'>
+
+                    </View>
+                </View>
+            </View>}
+            {showEndCover && <VideoPlayEndCover onRePlay={onRePlay} />}
+        </View>
+    )
 }
 
-function VideoIntroduce({detail}) {
-  return (
-    <View className='video-introduce'>
-      <View className='video-user-info'>
-        <Image className='avatar' src={detail.avatarUrl} />
-        {detail.nickName}
-      </View>
-      <View className='video-title'>
-        {detail.title}
-      </View>
-      <View className='video-play-count'>
-        播放{detail.playCount}次
-      </View>
-    </View>
-  )
+function VideoIntroduce({ detail, showRedShareBtn }) {
+    return (
+        <View className='video-introduce'>
+            <View className='video-user-info'>
+                <Image className='avatar' src={detail.user.avatarUrl} />
+                {detail.user.nickName}
+            </View>
+            <View className='video-title'>
+                {detail.title}
+            </View>
+            {showRedShareBtn && <Button className='redShareBtn' openType='share' data-button-type={2}>分享给群友</Button>}
+        </View>
+    )
 }
 
-function VideoBar({ video, onFavorited }) {
-  const [likeIcon, setLikeIcon] = useState(video.favorited ? LIKE_ICON : DEFAULT_ICON)
-  const [showTips, setShowTips] = useState(false)
+function VideoBar({ video }) {
+    const [showTips, setShowTips] = useState(false)
 
-  useEffect(() => {
-    setLikeIcon(video.favorited ? LIKE_ICON : DEFAULT_ICON)
-  }, [video.favorited])
+    function clickOperationBar(e) {
+        e.stopPropagation()
+        setShowTips(!showTips)
+    }
 
-  function clickLikeIcon(favorite) {
-    if (favoritePending)
-      return
+    function shareToPyq() {
+        /// TODO: 
+        console.log('share to pyq')
+    }
 
-    favoritePending = true
+    function shareToFriend() {
+        /// TODO: 
+        console.log('share to friend')
+    }
 
-    const url = favorite ? favoriteUrl : unfavoriteUrl
-    onFavorited(video.id, favorite)
-    
-    Taro.$http.post(url, {
-      videoId: video.id
-    }).then((res: RequestType) => {
-      const { code } = res
+    /**
+     * @description: 举报按钮
+     * @return {*}
+     */
+    function clickTips() {
+        const route = new Route()
+        route.push({
+            url: '/subPackages/safe/complaining/index',
+            query: {
+                videoId: video.id
+            }
+        })
+    }
 
-      favoritePending = false
+    function clickVideoBar(e) {
+        e.stopPropagation()
+        setShowTips(false)
+    }
 
-      if (code !== 0) {
-        onFavorited(video.id, !favorite)
-        Taro.showToast({
-          title: '收藏失败',
-          icon: 'error'
-        })
-        return
-      }
-    }).catch(() => {
-      favoritePending = false
-      onFavorited(video.id, !favorite)
-      Taro.showToast({
-        title: '收藏失败',
-        icon: 'error'
-      })
-    })
-  }
-
-  function clickOperationBar(e) {
-    e.stopPropagation()
-    setShowTips(!showTips)
-  }
-
-  function clickTips() {
-    const route = new Route()
-    route.push({
-      url: '/pages/complaining/index',
-      query: {
-        videoId: video.id
-      }
-    })
-  }
-
-  function clickVideoBar(e) {
-    e.stopPropagation()
-    setShowTips(false)
-  }
-
-  return (
-    <View className='video-bar' onClick={clickVideoBar}>
-      <View className='operation' onClick={clickOperationBar}>
-        <View className='bot'></View>
-        <View className='bot margin10'></View>
-        <View className='bot'></View>
-        {showTips && <View className='tips' onClick={clickTips}>
-          <Image src='http://weapppiccdn.yishihui.com/wxicon/common/icon_jubao.png' />
-          举报
-        </View>}
-      </View>
-      <View className='right'>
-        <View className='like'>
-          <Image className='like-icon' src={likeIcon} onClick={() => clickLikeIcon(!video.favorited)}/>
+    return (
+        <View className='video-bar' onClick={clickVideoBar}>
+            <Button className='friend' onClick={shareToFriend} openType='share' data-button-type={6}>
+                <Image src="http://weapppiccdn.yishihui.com/wxicon/common/icon_point_share_wechat.png" />
+                <View className='text'>分享</View>
+            </Button>
+            <Button className='pyq' onClick={shareToPyq} openType='contact'>
+                <Image src="http://weapppiccdn.yishihui.com/wxicon/common/icon_point_share_pyq.png" />
+                <View className='text'>朋友圈</View>
+
+            </Button>
+
+            <View className='more' onClick={clickOperationBar}>
+                <View className='bot'></View>
+                <View className='bot margin10'></View>
+                <View className='bot'></View>
+                {showTips && <View className='tips' onClick={clickTips}>
+                    <Image src='http://weapppiccdn.yishihui.com/wxicon/common/icon_jubao.png' />
+                    投诉
+                </View>}
+            </View>
         </View>
-        <Button className='share-btn-f' openType='share' data-button-type={6}>
-          <View className='wechat-icon' />
-          发给好友
-        </Button>
-      </View>
-    </View>
-  )
+    )
 }
 
 function VideoPlayEndCover({ onRePlay }) {
-  return (
-    <View className='video-play-end-cover'>
-      <View className='container'>
-        <View className='item left'>
-          <Image src='http://weapppiccdn.yishihui.com/wxicon/common/icon_replay_01.png' onClick={onRePlay} />
-          重播
+    return (
+        <View className='video-play-end-cover'>
+            <View className='container'>
+                <View className='item left'>
+                    <Image src='http://weapppiccdn.yishihui.com/wxicon/common/icon_replay_01.png' onClick={onRePlay} />
+                    重播
+                </View>
+                <Button className='item right' openType='share' data-button-type={10}>
+                    <Image src='http://weapppiccdn.yishihui.com/wxicon/common/icon_share_wechat_01.png' />
+                    发给好友
+                </Button>
+            </View>
+            <View className='more-video'>
+                <Image src='http://weapppiccdn.yishihui.com/wxicon/common/icon_slide_tips.png' />
+                上滑看更多精彩视频
+            </View>
         </View>
-        <Button className='item right' openType='share' data-button-type={10}>
-          <Image src='http://weapppiccdn.yishihui.com/wxicon/common/icon_share_wechat_01.png' />
-          发给好友
-        </Button>
-      </View>
-      <View className='more-video'>
-        <Image src='http://weapppiccdn.yishihui.com/wxicon/common/icon_slide_tips.png' />
-        上滑看更多精彩视频
-      </View>
-    </View>
-  )
+    )
 }
 
 // 视频曝光
 function logReportVideoView(video, current, index) {
-  if (videoViewedMap.has(video.id))
-    return
-
-  if (current !== index)
-    return
-
-  if (video.type === 'temp')
-    return
-
-  videoViewReport({
-    actionPosition: index,
-    autoType: VIEW_AUTO_TYPE.clickView,
-    extParams: JSON.stringify({
-      recomTraceId: video.recomTraceId,
-    }),
-    viewId: video.viewId,
-    flowPool: video.flowPool || '',
-    measureId: video.measure,
-    measureType: video.measureType,
-    pageSource: DETAIL_PAGESOURCE,
-    recommendLogVO: video.recommendLogVO || '',
-    recommendSource: video.recommendSource,
-    rootPageSource: '', // TODO: 分享之后加上
-    rootPageTimestamp: '', // TODO: 分享之后加上
-    shareDepth: '', // TODO: 分享之后加上
-    videoIds: [video.id]
-  }).then(() => videoViewedMap.set(video.id, video.id))
+    if (videoViewedMap.has(video.id))
+        return
+
+    if (current !== index)
+        return
+
+    if (video.type === 'temp')
+        return
+
+    videoViewReport({
+        actionPosition: index,
+        autoType: VIEW_AUTO_TYPE.clickView,
+        extParams: JSON.stringify({
+            recomTraceId: video.recomTraceId,
+        }),
+        viewId: video.viewId,
+        flowPool: video.flowPool || '',
+        measureId: video.measure,
+        measureType: video.measureType,
+        pageSource: DETAIL_PAGESOURCE,
+        recommendLogVO: video.recommendLogVO || '',
+        recommendSource: video.recommendSource,
+        rootPageSource: '', // TODO: 分享之后加上
+        rootPageTimestamp: '', // TODO: 分享之后加上
+        shareDepth: '', // TODO: 分享之后加上
+        videoIds: [video.id]
+    }).then(() => videoViewedMap.set(video.id, video.id))
 }
 // 视频播放
 function logReportVideoPlay(video) {
-  if (video.type === 'temp')
-    return
-
-  videoPlayReport({
-    videoId: video.id,
-    pageSource: DETAIL_PAGESOURCE,
-    rootPageSource: CATEGORY_PAGESOURCE,
-    shareDepth: '', // TODO: 分享之后
-    rootPageTimestamp: '', // TODO: 分享之后
-    rootMid: '', // TODO: 分享之后
-    recommendSource: video.recommendSource || 0,
-    autoType: VIEW_AUTO_TYPE.clickView,
-    playId: video.playId,
-    viewId: video.viewId,
-    measureType: video.measureType || 0,
-    measureId: video.measure,
-    flowPool: video.flowPool || '',
-    recommendId: video.recommendId || '',
-    recommendLogVO: video.recommendLogVO || ''
-  })
+    if (video.type === 'temp')
+        return
+
+    videoPlayReport({
+        videoId: video.id,
+        pageSource: DETAIL_PAGESOURCE,
+        rootPageSource: CATEGORY_PAGESOURCE,
+        shareDepth: '', // TODO: 分享之后
+        rootPageTimestamp: '', // TODO: 分享之后
+        rootMid: '', // TODO: 分享之后
+        recommendSource: video.recommendSource || 0,
+        autoType: VIEW_AUTO_TYPE.clickView,
+        playId: video.playId,
+        viewId: video.viewId,
+        measureType: video.measureType || 0,
+        measureId: video.measure,
+        flowPool: video.flowPool || '',
+        recommendId: video.recommendId || '',
+        recommendLogVO: video.recommendLogVO || ''
+    })
 }
 // 播放成功
 function logReportVideoPlaySuccess(video) {
-  if (video.type === 'temp')
-    return
-
-  videoActionReport({
-    businessType: 'videoPlaySuccess',
-    videoId: video.id,
-    pageSource: DETAIL_PAGESOURCE,
-    rootPageSource: CATEGORY_PAGESOURCE,
-    shareDepth: '', // TODO: 分享之后
-    rootPageTimestamp: '', // TODO: 分享之后
-    rootMid: '', // TODO: 分享之后
-    recommendSource: video.recommendSource || 0,
-    autoType: VIEW_AUTO_TYPE.clickView,
-    playId: video.playId,
-    viewId: video.viewId,
-    measureType: video.measureType || 0,
-    measureId: video.measure,
-    flowPool: video.flowPool || '',
-    recommendId: video.recommendId || '',
-    recommendLogVO: video.recommendLogVO || ''
-  })
+    if (video.type === 'temp')
+        return
+
+    videoActionReport({
+        businessType: 'videoPlaySuccess',
+        videoId: video.id,
+        pageSource: DETAIL_PAGESOURCE,
+        rootPageSource: CATEGORY_PAGESOURCE,
+        shareDepth: '', // TODO: 分享之后
+        rootPageTimestamp: '', // TODO: 分享之后
+        rootMid: '', // TODO: 分享之后
+        recommendSource: video.recommendSource || 0,
+        autoType: VIEW_AUTO_TYPE.clickView,
+        playId: video.playId,
+        viewId: video.viewId,
+        measureType: video.measureType || 0,
+        measureId: video.measure,
+        flowPool: video.flowPool || '',
+        recommendId: video.recommendId || '',
+        recommendLogVO: video.recommendLogVO || ''
+    })
 }
 // 真实播放
 function logReportVideoRealPlay(video) {
-  if (video.type === 'temp')
-    return
-
-  videoActionReport({
-    businessType: 'videoRealPlay',
-    videoId: video.id,
-    pageSource: DETAIL_PAGESOURCE,
-    rootPageSource: CATEGORY_PAGESOURCE,
-    shareDepth: '', // TODO: 分享之后
-    rootPageTimestamp: '', // TODO: 分享之后
-    rootMid: '', // TODO: 分享之后
-    recommendSource: video.recommendSource || 0,
-    autoType: VIEW_AUTO_TYPE.clickView,
-    playId: video.playId,
-    viewId: video.viewId,
-    measureType: video.measureType || 0,
-    measureId: video.measure,
-    flowPool: video.flowPool || '',
-    recommendId: video.recommendId || '',
-    recommendLogVO: video.recommendLogVO || ''
-  })
+    if (video.type === 'temp')
+        return
+
+    videoActionReport({
+        businessType: 'videoRealPlay',
+        videoId: video.id,
+        pageSource: DETAIL_PAGESOURCE,
+        rootPageSource: CATEGORY_PAGESOURCE,
+        shareDepth: '', // TODO: 分享之后
+        rootPageTimestamp: '', // TODO: 分享之后
+        rootMid: '', // TODO: 分享之后
+        recommendSource: video.recommendSource || 0,
+        autoType: VIEW_AUTO_TYPE.clickView,
+        playId: video.playId,
+        viewId: video.viewId,
+        measureType: video.measureType || 0,
+        measureId: video.measure,
+        flowPool: video.flowPool || '',
+        recommendId: video.recommendId || '',
+        recommendLogVO: video.recommendLogVO || ''
+    })
 }
 // 播放结束
 function logReportVideoPlayEnd(video) {
-  if (video.type === 'temp')
-    return
-
-  videoActionReport({
-    businessType: 'videoPlayEnd',
-    videoId: video.id,
-    pageSource: DETAIL_PAGESOURCE,
-    rootPageSource: CATEGORY_PAGESOURCE,
-    shareDepth: '', // TODO: 分享之后
-    rootPageTimestamp: '', // TODO: 分享之后
-    rootMid: '', // TODO: 分享之后
-    recommendSource: video.recommendSource || 0,
-    autoType: VIEW_AUTO_TYPE.clickView,
-    playId: video.playId,
-    viewId: video.viewId,
-    measureType: video.measureType || 0,
-    measureId: video.measure,
-    flowPool: video.flowPool || '',
-    recommendId: video.recommendId || '',
-    recommendLogVO: video.recommendLogVO || ''
-  })
+    if (video.type === 'temp')
+        return
+
+    videoActionReport({
+        businessType: 'videoPlayEnd',
+        videoId: video.id,
+        pageSource: DETAIL_PAGESOURCE,
+        rootPageSource: CATEGORY_PAGESOURCE,
+        shareDepth: '', // TODO: 分享之后
+        rootPageTimestamp: '', // TODO: 分享之后
+        rootMid: '', // TODO: 分享之后
+        recommendSource: video.recommendSource || 0,
+        autoType: VIEW_AUTO_TYPE.clickView,
+        playId: video.playId,
+        viewId: video.viewId,
+        measureType: video.measureType || 0,
+        measureId: video.measure,
+        flowPool: video.flowPool || '',
+        recommendId: video.recommendId || '',
+        recommendLogVO: video.recommendLogVO || ''
+    })
 }

+ 313 - 0
src/components/VideoSwiper/index.wxss

@@ -0,0 +1,313 @@
+.video-swiper {
+  width: 100%;
+  height: 100%;
+  background-color: #000;
+}
+.video-swiper .video-swiper-item {
+  display: flex;
+  flex-direction: column;
+  position: relative;
+  box-sizing: border-box;
+}
+.video-swiper .video-swiper-item .custom-video {
+  width: 100%;
+  height: 100%;
+  position: relative;
+}
+.video-swiper .video-swiper-item .custom-video .video {
+  width: 100%;
+  height: calc(100% - 6px);
+}
+.video-swiper .video-swiper-item .custom-video .progress-bg {
+  position: absolute;
+  bottom: 0;
+  width: 100%;
+  height: 40px;
+}
+.video-swiper .video-swiper-item .custom-video .progress-bg .progress-container {
+  position: absolute;
+  bottom: 0;
+  width: 100%;
+  height: 6px;
+  border-radius: 3px;
+  background-color: #0f0f0f;
+}
+.video-swiper .video-swiper-item .custom-video .progress-bg .progress-container .progress {
+  height: inherit;
+  border-radius: 4px 0 0 4px;
+  background-color: #4c4c4c;
+}
+.video-swiper .video-swiper-item .custom-video .progress-indicator {
+  position: absolute;
+  bottom: 20px;
+  left: 0;
+  width: 100%;
+  height: 100px;
+  display: flex;
+  flex-direction: column;
+  justify-content: space-between;
+  align-items: center;
+}
+.video-swiper .video-swiper-item .custom-video .progress-indicator .showInfo {
+  display: flex;
+  flex-direction: row;
+  height: 60px;
+  width: 400px;
+  align-items: center;
+  justify-content: center;
+  font-size: 36px;
+  font-weight: 500;
+}
+.video-swiper .video-swiper-item .custom-video .progress-indicator .showInfo .showInfo-a {
+  height: 60px;
+  color: #fff;
+  margin-right: 20px;
+}
+.video-swiper .video-swiper-item .custom-video .progress-indicator .showInfo .showInfo-m {
+  height: 24px;
+  width: 2px;
+  background-color: #999;
+}
+.video-swiper .video-swiper-item .custom-video .progress-indicator .showInfo .showInfo-b {
+  height: 60px;
+  color: #999;
+  margin-left: 20px;
+}
+.video-swiper .video-swiper-item .custom-video .progress-indicator .indicator-bg {
+  display: flex;
+  flex-direction: row;
+  width: 90%;
+  height: 20px;
+  background-color: #979797;
+  align-items: center;
+  border-radius: 10px;
+}
+.video-swiper .video-swiper-item .custom-video .progress-indicator .indicator-bg .indcator-active {
+  height: 20px;
+  background-color: #d5d5d5;
+  border-radius: 10px 0 0 10px;
+}
+.video-swiper .video-swiper-item .custom-video .progress-indicator .indicator-bg .indicator-dot {
+  background-color: white;
+  height: 32px;
+  width: 12px;
+  border-radius: 6px;
+}
+.video-swiper .video-swiper-item .custom-video .video-play-end-cover {
+  position: absolute;
+  top: 0;
+  bottom: 0;
+  left: 0;
+  right: 0;
+  background: rgba(0, 0, 0, 0.5);
+  z-index: 1;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+}
+.video-swiper .video-swiper-item .custom-video .video-play-end-cover .container {
+  width: 100%;
+  display: flex;
+  justify-content: space-around;
+  color: #fff;
+  margin-top: 150px;
+  margin-bottom: 300px;
+}
+.video-swiper .video-swiper-item .custom-video .video-play-end-cover .container .item {
+  display: flex;
+  flex-direction: column;
+  font-size: 30px;
+  align-items: center;
+  margin: 0;
+  padding: 0;
+  background: transparent;
+  color: #fff;
+}
+.video-swiper .video-swiper-item .custom-video .video-play-end-cover .container .item Image {
+  width: 120px;
+  height: 120px;
+  margin-bottom: 20px;
+}
+.video-swiper .video-swiper-item .custom-video .video-play-end-cover .more-video {
+  position: relative;
+  width: 100%;
+  color: #fff;
+  font-size: 26px;
+  display: flex;
+  align-items: center;
+  flex-direction: column;
+}
+.video-swiper .video-swiper-item .custom-video .video-play-end-cover .more-video Image {
+  position: absolute;
+  bottom: 0;
+  width: 108px;
+  height: 106px;
+  animation: turn 1.5s infinite;
+}
+.video-swiper .video-swiper-item .video-introduce {
+  box-sizing: border-box;
+  width: calc(100% - 120px);
+  position: absolute;
+  left: 0;
+  bottom: 40px;
+  color: #fff;
+  font-size: 32px;
+  padding: 0 20px;
+  text-shadow: #000 1px 0 6px;
+  background: linear-gradient(to bottom, rgba(0, 0, 0, 0), 10%, rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0));
+}
+.video-swiper .video-swiper-item .video-introduce .video-user-info {
+  display: flex;
+  align-items: center;
+  font-size: 36px;
+}
+.video-swiper .video-swiper-item .video-introduce .video-user-info .avatar {
+  width: 50px;
+  height: 50px;
+  border-radius: 50%;
+  margin-right: 15px;
+}
+.video-swiper .video-swiper-item .video-introduce .video-title {
+  margin: 20px 0;
+}
+.video-swiper .video-swiper-item .video-introduce .redShareBtn {
+  width: 90%;
+  height: 80px;
+  background-color: #EE2C4F;
+  border-radius: 8px;
+  text-align: center;
+  font-size: 38px;
+  line-height: 80px;
+  color: #fff;
+  text-shadow: none;
+}
+.video-swiper .video-swiper-item .video-bar {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  box-sizing: border-box;
+  width: 90px;
+  height: 100%;
+  padding: 10px 0px;
+  margin-right: 20px;
+  justify-content: flex-end;
+  position: absolute;
+  right: 0;
+  bottom: 10px;
+}
+.video-swiper .video-swiper-item .video-bar .friend {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  height: 190px;
+  width: 70px;
+  color: #fff;
+  font-size: 24px;
+  padding-bottom: 16px;
+  border-radius: 40px;
+  background-color: #04740399;
+}
+.video-swiper .video-swiper-item .video-bar .friend image {
+  width: 70px;
+  height: 70px;
+  margin-bottom: 10px;
+}
+.video-swiper .video-swiper-item .video-bar .friend .text {
+  width: 30px;
+  font-size: 30px;
+  line-height: 44px;
+}
+.video-swiper .video-swiper-item .video-bar .pyq {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  background-color: transparent;
+  width: 70px;
+  height: 110px;
+  margin-top: 40px;
+  font-size: 26px;
+}
+.video-swiper .video-swiper-item .video-bar .pyq image {
+  width: 70px;
+  height: 70px;
+  margin-bottom: 10px;
+}
+.video-swiper .video-swiper-item .video-bar .pyq .text {
+  color: white;
+  width: 90px;
+  font-size: 22px;
+  line-height: 30px;
+}
+.video-swiper .video-swiper-item .video-bar .more {
+  height: 60px;
+  display: flex;
+  position: relative;
+  align-items: center;
+  margin-top: 40px;
+}
+.video-swiper .video-swiper-item .video-bar .more .bot {
+  width: 4px;
+  height: 4px;
+  background-color: #999;
+  border: 2px solid #999;
+  border-radius: 50%;
+}
+.video-swiper .video-swiper-item .video-bar .more .margin10 {
+  margin: 0 10px;
+}
+.video-swiper .video-swiper-item .video-bar .more .tips {
+  position: absolute;
+  width: 100px;
+  height: 40px;
+  border-radius: 4px;
+  background: #fff;
+  font-size: 22px;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  padding: 4px 10px;
+  color: #6a6969;
+  right: 60px;
+  z-index: 1;
+}
+.video-swiper .video-swiper-item .video-bar .more .tips image {
+  width: 40px;
+  height: 40px;
+  margin-right: 8px;
+}
+.video-swiper .video-swiper-item .video-bar .more .tips::after {
+  position: absolute;
+  content: ' ';
+  right: -26px;
+  width: 0;
+  height: 0;
+  border: 10px solid transparent;
+  border-left: 26px solid #fff;
+}
+.video-swiper .video-swiper-item .video-bar .share-btn-f {
+  margin-left: 20px;
+  height: 60px;
+  background: #55c57c;
+  display: flex;
+  align-items: center;
+  color: #fff;
+  font-size: 28px;
+}
+.video-swiper .video-swiper-item .video-bar .share-btn-f .wechat-icon {
+  margin-right: 10px;
+  width: 40px;
+  height: 40px;
+  background: transparent url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFAAAABGCAMAAABsQOMZAAAAflBMVEUAAAD////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////vroaSAAAAKXRSTlMA9wjz1ykDEMQx5IHeXG7ovVQao2jtzqmdkXoVi0g9tU1CIMmvlmI4dBMRDGIAAALGSURBVFjDtddnc6MwEAbglRCYYtPdwL2///8P3lzgBoWiQnLPp8zGZrza1SLRqPy1P4vEYc7yfi4+b04/scieAt+xNHJpptvewSg/88heUDBMCitum+wWauJKNq4htIqaTPEDTCSBabp3mHGOZIL7MMVeJs9LYWFFOt4ZNhztOh5gZ7nQ9AuTP1y+Lzs0JmNndcJC3mFfuyED1DFlqWO5hLcmVozE5H20UVU4QUdQY6WJIaOhsc/51LhoYhA0yYfE4U0wUsQa7uSeY5Admqno6GL4qDKWPWvyLqE+ltKE/XCQMmhjLBScxqWwE+5WJ1e1U5awkMZtLeqc04Q1TLFtQMRPUSoSBsBZ+sUqpwEGQzuXeHl2elHx7I8ex3DprlRH49mk1xlr+Fjw/XQumxN17jAQ01tAgR26Gu2gV3oRg9rGpVYJrY/3gJbzL20XOpG3tXrTCKj5XgEj6/aJFZSYG8FQ0uzInKkTdlmXVZR9BCRstypTqfcH82Zoyf0up1v/jHHsfb9p8dxRdWAp/d2v4pb+4t0GamdarCjdQkox6G/WeDABM91MfAToXJp3hvRuGPTJo4nkISa85AU+97si/CrrVa5SO3qDqWV015AUOfGKoXMPyMsSSEpqHNlEE/ZbjfW7uRcoqHVyRpsmg6HhGSVYjv07hqVEfanwI1hiJBkOAfGzB96HA8Q65ZA6OQbYak5RBrNb6gTrB+6GhxL/xE/xtq15lMBO2T/XbY7U8Gr3fTy6e9i5fT/XiYx6AljxqbPF8uXRgMDMSxYXMacRL1gQnvRArj2D62VkwGUw9SAjlfEuqcnMzu6SqucVdld9PZPDzTIgC17FdB1dk51AQOXpkS1+cDDtRDMsqgRTDjQLfz36P5O1JaG5vHd03oTs67p3f65cHifSbXe+RXc149UaQEW/aBE52NCvqvcsp9+Vu/Sf/AGRfvtxDfRcnAAAAABJRU5ErkJggg==) no-repeat no-repeat center / contain;
+}
+@keyframes turn {
+  0% {
+    transform: translate(0px, -150px);
+  }
+  50% {
+    transform: translate(0px, -50px);
+  }
+  100% {
+    transform: translate(0px, -150px);
+  }
+}

+ 8 - 0
src/const/Enum.ts

@@ -0,0 +1,8 @@
+export const VIDEO_FRONTEND_PRE_VIEW = 'videoPreViewFrontEnd'
+
+export const VIEW_AUTO_TYPE = {
+  topVideoView: 0,
+  userScrollView: 1,
+  autoNextScrollView: 2, //自动播放下一个
+  clickView: 3
+}

+ 22 - 0
src/const/index.ts

@@ -0,0 +1,22 @@
+export * from './Enum'
+
+export const CATEGORY_ID = 55
+
+export const CATEGORY_PAGESOURCE = 'immerse-pages/category'
+
+export const DETAIL_PAGESOURCE = 'immerse-pages/user-videos-detail'
+export const DETAIL_RECOMMEND = 'immerse-pages/detail-recommend'
+
+export const USER_SHARE_PAGESOURCE = 'immerse-pages/user-videos-share'
+export const RECOMMEND_PAGESOURCE = 'immerse-pages/user-videos-share-recommend-detail'
+
+
+export const DEFAULT_ICON = 'http://weapppiccdn.yishihui.com/wxicon/common/icon_share_collect_x.png'
+
+export const LIKE_ICON = 'http://weapppiccdn.yishihui.com/wxicon/common/icon_share_collect_s.png'
+
+export const USER_SENCE = {
+  share: '0',
+  category: '1',
+  home: '2'
+}

+ 4 - 3
src/constants/commentTypes.ts

@@ -1,7 +1,8 @@
 export const PlayState = {
-    playing: 0,
-    pause: 1,
-    stoped: 2 
+    prepared: 1,
+    playing: 2,
+    pause: 3,
+    stoped: 4, 
 }
 
 export type VideoInfo = {

+ 1 - 1
src/custom-tab-bar/index.tsx

@@ -13,7 +13,7 @@ export default class Index extends Component {
     fontSize: 22,
     list: [
       {
-        pagePath: '/pages/index/index',
+        pagePath: '/pages/category/index',
         text: '首页'
       },
       {

+ 249 - 0
src/logger/const.ts

@@ -0,0 +1,249 @@
+export const eventId = {
+  /**
+   * eventId 由6位构成,由前端开发自定义
+   * 前3为为小分类标记,例如页面、组件等标识
+   * 100-299 视频相关
+   * 300-399 小程序页面
+   * 400-799 预留字段
+   * 800-899 H5相关、pc站相关
+   * 900-999 图片加工相关
+   * 后三位为事件标记
+   *
+   * e.g.900001进入图片加工main页
+   */
+
+  //900+ 图片加工相关字段
+
+  //901是首页进行的操作
+  clickMakeAlbum: '901001', //点击首页做影集
+  //902是制作页进行的操作
+  enterMakePageFromShare1: '902001', //进入制作页(做影集)
+  enterMakePageFromShare6: '902002', //进入制作页(做同款)
+  makePageDrawingCompleteFromShare1: '902003', //制作页渲染完成(做影集)
+  makePageDrawingCompleteFromShare6: '902004', //制作页渲染完成(做同款)
+  clickSaveFromShare1: '902005', //制作页点击保存(做影集)
+  clickSaveFromShare6: '902006', //制作页点击保存(做同款)
+  clickShareFromShare1: '902007', //制作页点击分享(做影集)
+  clickShareFromShare6: '902008', //制作页点击分享(做同款)
+  //903是完成页
+  enterCompletePageFromShare1: '903001', //进入完成页(做影集)
+  enterCompletePageFromShare6: '903002', //进入完成页(做同款)
+  //904是编辑页(影集编辑进入)
+  //905是分享进入页
+  clickMakeSame: '905001', //点击做同款
+
+  //950+ debug日志
+  requestFailDebug: '950001',
+  requestErrorDebug: '950002',
+  debugUserVideoFolder: '951001',
+  debugShortVideoShare: '952001',
+
+  /**
+   * 片尾测试 106
+   */
+  tailVideoPlayed: '106001', //带片尾的视频播放
+  tailVideoPlayedTail: '106002', //带片尾的视频播放了片尾
+  videoSharedWithTail: '106003', //片尾测试的视频,分享的时候视频是带片尾的
+  videoSharedWithoutTail: '106004', //片尾测试的视频,分享的时候视频是没有带片尾的
+  VideoEditMusicOperation: '100001',
+  withoutTailVideoPlayed: '106005', //没有带片尾的视频播放
+  videoPlayEndWithoutTail: '106006', //没有带片尾的视频播放完成
+  videoPlayEndWithTail: '106007', //带片尾的视频播放完成
+  tailVideoSharedPre: '106008', //带片尾视频片尾前被分享
+  tailVideoSharedLast: '106009', //看了片尾并分享
+  tailVideoSharedEnd: '106010', //带片尾视频播完片尾后被分享
+
+  /**
+   * 视频封面加载 - 107
+   */
+  videoCoverLoad: '107001', //封面加载完成
+  videoCoverLoadError: '107002', //封面加载失败
+
+  /**
+   * 播放时长 - 108
+   */
+  videoPlayDuration: '108001', //视频暂停,停止播放的时长上报
+
+  /**
+   * 用户活跃 - 109
+   */
+  userActiveAction: '109001', //用户活跃日志
+
+  /**
+   * 首页跳转 - 110
+   */
+  categoryPrepare2Route: '110001', //首页启动准备跳转
+  videoShareRouteSuccess: '110002', //首页跳转分享页成功
+  otherShareRouteSuccess: '110003', //首页跳转其他分享页成功
+  videoShareRouteFail: '110004', //首页跳转分享页失败
+  otherShareRouteFail: '110005', //首页跳转其他分享页失败
+  videoShareLaunchFromRouter: '110006', //分享页启动从首页跳转
+  videoShareLaunchFromApp: '110007', //分享页启动从直接启动页面
+  videoShareOpenByDirect: '110008', //直接打开视频分享页
+  videoShareOpenByRoute: '110009', //首页跳转打开视频分享页
+  /**
+   * 关注 - 301
+   */
+  hasFollowVideo: 301001, //有关注视频
+  withoutFollowVideo: 301002, //无关注视频
+  followPageComAttached: 301003, //关注页启动
+
+  /**
+   * feed流页面
+   */
+  inVideoTab: 302001, // 视频tab
+  inCommentTab: 302002, // 评论tab
+  inShareSummaryTab: 302003, // 分享空间tab
+
+  /**
+   * 滑动引导
+   */
+  haveShowScrollGuide: 110100, //显示了滑动引导
+  withoutScrollGuide: 110101, //没显示滑动引导
+  haveShowOldScrollGuide: 110102, //显示了老的滑动引导
+  /**
+   * 活动事件
+   */
+  enterNativeActivity: 120001, //进入活动页面
+
+  /**
+   * 广告
+   */
+  adLoad: 130001, // 广告组加载成功
+  adError: 130002, // 广告组件加载失败
+  adClose: 130003, // 广告组件关闭
+  adPlay: 130004, // 广告组件播放
+  adView: '130009', // 广告组件曝光
+  adAttached: '130010', // 广告组件加入页面
+
+  interstitialAdLoadSuccess: '130005', //插屏广告加载成功
+  interstitialAdLoadError: '130006', //插屏广告加载失败
+  interstitialAdShowSuccess: '130007', //插屏广告显示成功
+  interstitialAdShowError: '130008', //插屏广告显示失败
+  interstitialAdCreate: '130011', // 创建插屏广告
+
+  test1: '1301200',
+  test2: '1300013',
+  test3: '1300014',
+
+  //平台广告
+  pfAdStartValidate: '140001', //开始校验广告
+  pfAdValidateSuccess: '140002', //校验成功上报
+  pfAdValidateFail: '140003', //校验失败上报
+
+  //站外消息
+  offSiteNews: '160000',
+  //消息H5漏斗事件
+  msgH5: '150000',
+  //上传Banner点击
+  clickPostBanner: 170001,
+  //首页模块上报
+  homeBanner: 180001,
+  homeIcon: 180002,
+  //内存告警
+  memoryWarning: 190000,
+
+  // 点击app下载分享卡片
+  appDownloadCardClick: 230000,
+
+  downloadModalShow: 240000, //下载弹窗显示
+  downloadModalClick: 240001, //点击下载弹窗下载按钮
+
+  hoverDownloadBtn: 240002, //悬浮下载app按钮
+  shareWindow: 240003, //悬浮下载app按钮
+
+  buttonClick: 300000, //按钮点击相关上报
+  buttonView: 300001, //按钮曝光
+  buttonSlide: 300011, // 广告滑动事件
+  
+  windowView: 300002, //弹窗曝光
+  pageView: 300003, //页面曝光
+  pageBack: 300004, //复制成功
+  windowClose: 300005, //弹窗曝光
+  sharePopupAVlogCode: 330001,
+  sharePopupBVlogCode: 330002,
+  downAppGuideShow: 330011,
+  downAppGuideClick: 330012,
+  playActivityWindowShow: 330021,
+  playActivityWindowClick: 330022,
+
+  showGuideClipToolsPanel: 400000,
+
+  downAppGuideBtn: 400011,
+  downVideoFlow: 500001,
+  // 分享页页面
+  sharePageEventReport: '220221',
+  // 详情页页面
+  detailPageEventReport: '22022220',
+  // 详情页接口成功
+  detailRequestSuccessEventReport: '22022221',
+  // 详情页接口失败
+  detailRequestErrorEventReport: '22022222',
+
+  videoStepTime: 520000,
+  videoClickEvent: 299001,
+
+  // 请求超时
+  adPreLimt: 510400,
+  // 获取设备信息
+  sysInfoSuc: 510410,
+  sysInfoErr: 510411,
+  sysInfoExp: 510412,
+  sysInfoSucAsyn: 510413,
+
+  // 性能数据上报
+  appLaunch: 510420,
+  router: 510421,
+  scriptInject: 510422,
+  firstRender: 510423,
+
+
+  // home页跳转来源
+  homeFrom: 510432,
+  // 复制广告口令
+  copy_ad_success: 510440,
+  copy_ad_fail: 510441,
+  copy_ad_event: 510442,
+  clipboard_ad_success: 510443,
+
+  /*
+      小程序关闭爬虫用户入口 520开头
+  */
+  categoryClick: 520010, // 首页点击用户头像或昵称
+  followClick: 520021, // 关注页-已关注
+  unFollowClick: 520022, // 关注页-未关注
+  vHeadClick: 520031, // 视频列表页-头部
+  vContentClick: 520032, // 视频列表页-相关推荐
+  vCommentlistClick: 520033, // 视频列表页-评论列表
+  vCommentDHeadClick: 520034, // 视频列表页-评论详情-个人
+  vCommentDOthersClick: 520035, // 视频列表页-评论详情-其他回复
+  apperciateClick: 520036, // 赞赏页面
+  vDetailClick: 520040, // 沉浸式播放页
+
+  miniappToWechatDialog: 510433,
+  autoPlayVideoEventId: 510434,
+
+
+  selfAd_backBtn_Click: 510450,
+  selfAd_playBtn_Click: 510451,
+
+  errorScript: 540001,
+  errorReject: 540002,
+  errorPageNotFound: 540003,
+
+}
+
+export const logType = {
+  abTest: 10, //abtestinfo-log
+  funnel: 20, //operation-log
+  independent: 30, //simpleevent-log
+  debug: 40, //frontend-log
+  playAction: 50, //playaction-log
+  useractiveLog: 60, //useractive-log
+  productionLog: 110, //video-production-log
+  adActionLog: 120, //ad-action-log
+  adActionNewLog: 170, //ad-new-action-log
+  apiMonitorLog: 180, //api-monitor : we-data
+  performanceMonitorLog: 190, //performance-log : we-data
+  errorLog: 27, //error-log
+}

+ 41 - 0
src/logger/index.ts

@@ -0,0 +1,41 @@
+import {
+  videoActionPreReportUrl, videoViewUrl, playedUrl,
+  videoActionReportUrl, shareReportUrl, weixinFriendUrl,
+  shareClickUrl
+} from '@/http/api'
+import http from '@/http/index'
+
+// category 卡片 preview 上报
+export function videoActionPreReport(params) {
+  return http.post(videoActionPreReportUrl, params)
+}
+
+// 视频曝光上报
+export function videoViewReport(params) {
+  return http.post(videoViewUrl, params)
+}
+
+// 视频曝光播放
+export function videoPlayReport(params) {
+  return http.post(playedUrl, params)
+}
+
+// 播放上报
+export function videoActionReport(params) {
+  return http.post(videoActionReportUrl, params)
+}
+
+// 分享 report 
+export function shareReport(params) {
+  return http.post(shareReportUrl, params)
+}
+
+// 分享 friend
+export function weixinFriend(params) {
+  return http.post(weixinFriendUrl, params)
+}
+
+// 回流 click
+export function shareClickReport(params) {
+  return http.post(shareClickUrl, params)
+}

+ 60 - 0
src/logger/userActivieLog.ts

@@ -0,0 +1,60 @@
+import Taro from '@tarojs/taro'
+import { uploadLogFromFrontendUrl } from '@/http/api'
+import { wrapData, createBaseInfoToFetchData } from '@/http/index'
+import { logType } from './const'
+
+const { useractiveLog } = logType
+
+// user action log
+export function userActivie (eventId, eventData = {}, extParams = {}) {
+  if (!eventId)
+    return
+
+  paramsPretreatmentAndRequest(useractiveLog, eventId, eventData, extParams)
+}
+
+function paramsPretreatmentAndRequest(logType, eventId, eventData, extParams) {
+  const { pageSource = '' } = eventData
+
+  const res: any = wrapData({
+    logType,
+    eventId,
+    eventData: JSON.stringify(eventData),
+    pageSource,
+    extParams: JSON.stringify(wrapObject(extParams))
+  })
+
+  uploadLogFromFrontend(res)
+}
+
+function uploadLogFromFrontend(params) {
+  const data = createBaseInfoToFetchData(params)
+  request(uploadLogFromFrontendUrl, data, {
+    headers: {
+      'content-type': 'application/json',
+    },
+    method: 'POST'
+  })
+}
+
+function request(url, data, config) {
+  Taro.request({
+    url,
+    data,
+    ...config
+  })
+}
+
+function wrapObject(extParams) {
+  if (typeDecide(extParams, 'Object')) {
+      return extParams
+  }
+  return { defaultExt: extParams }
+}
+
+/**
+* 检测对象类型
+*/
+function typeDecide(o, type) {
+  return Object.prototype.toString.call(o) === `[object ${type}]`
+}

+ 0 - 0
src/pages/index/index.config.ts → src/pages/category/index.config.ts


+ 8 - 0
src/pages/category/index.less

@@ -0,0 +1,8 @@
+.category-page {
+    background-color: black;
+    width: 100%;
+    height: calc(100% - 110px);
+    position: absolute;
+    top: 0;
+
+}

+ 164 - 0
src/pages/category/index.tsx

@@ -0,0 +1,164 @@
+import Taro, { useLoad, useDidShow, useReady, useDidHide, usePullDownRefresh, useShareAppMessage, useRouter } from '@tarojs/taro'
+import { useMemo, useRef, useState } from 'react'
+import type CustomTabBar from '@/custom-tab-bar'
+import { View } from '@tarojs/components'
+import { VideoInfo } from '@/constants/commentTypes'
+import { videoListV2 } from '@/http/api'
+import VideoSwiper from '@/components/VideoSwiper'
+import { sharePageAppMessage, returnedCrowdClickReport } from '@/shareHelper'
+import Route from '@/class/Route'
+
+// import { getTopSafeHeight, throttle, formatSecondsAsTime, getPreIds } from '@/utils'
+
+// import Route from '@/class/Route'
+import './index.less'
+
+let pageNo = 1
+let pending = false
+let start = -1
+let end = 1
+let activeIndex = 0
+
+export default function Index() {
+    const page = useMemo(() => Taro.getCurrentInstance().page, []);
+    const router = useRouter()
+    const { params } = router || {}
+
+    const [videoList, setVideoList] = useState<VideoInfo[]>([])
+    const [refresherTriggered, setRefresherTriggered] = useState(false)
+    const [needResumePlay, setNeedResumePlay] = useState(false)
+    const [ toSharePage, setToSharePage] = useState(false)
+
+    useLoad(() => {
+        const { redirect } = params
+        let dur = 0
+        if (redirect) {
+            const route = new Route()
+            route.push(decodeURIComponent(redirect))
+            dur = 1000
+            setToSharePage(true)
+        }
+        setTimeout(() => {
+            fecthVideoListV2()
+        }, dur);
+    })
+
+    useDidShow(() => {
+        const tabbar = Taro.getTabBar<CustomTabBar>(page)
+        tabbar?.setSelected(0)
+
+        if (videoList.length > 0 && toSharePage) {
+            setToSharePage(false)
+            setNeedResumePlay(!needResumePlay)
+        }
+    })
+
+    useReady(() => {
+    })
+
+    useDidHide(() => {
+
+    })
+
+    usePullDownRefresh(() => {
+        console.log('usePullDownRefresh')
+    })
+
+    useShareAppMessage((shareRes) => {
+        return sharePageAppMessage({
+          video: videoList[activeIndex],
+          activeIndex,
+          router,
+          shareRes
+        })
+    })
+
+    // const fecthVideoList = throttle(fecthVideoListV2)
+    function fecthVideoListV2(cleanOldCardList = false) {
+        if (cleanOldCardList)
+            pageNo = 1
+
+        Taro.$http.post(videoListV2, {
+            categoryId: 55,
+            pageNo,
+            pageSize: 6,
+            pageSource: 'pages/category'
+        }).then((res: RequestType) => {
+            const { code, data } = res
+            if (code != 0)
+                return
+
+            let oldCardList = videoList
+
+            if (cleanOldCardList) {
+                oldCardList = []
+                setRefresherTriggered(false)
+            }
+
+            pageNo++
+
+            setVideoList([
+                ...oldCardList,
+                ...filterCardProps(data)
+            ])
+
+        }).catch(() => {
+            pending = false
+        })
+    }
+
+    function pause() {
+        console.log('hhz-')
+    }
+
+    // 视频卡片需要参数过滤重组一次,并不需要把所有的数据都传进去
+    function filterCardProps(list) {
+        return list.map((item: RoughCardType) => {
+            const {
+                title, coverImg, user, id, videoPath,
+                recomTraceId, flowPool, shareTitle = ''
+            } = item || {}
+            const { coverImgPath = '' } = coverImg || {}
+            const { avatarUrl = '', nickName = '', uid = 0 } = user || {}
+
+            return {
+                id,
+                title,
+                coverImgPath,
+                shareTitle,
+                videoPath,
+                recomTraceId,
+                flowPool,
+                user: {
+                    uid,
+                    avatarUrl,
+                    nickName,
+                }
+            }
+        })
+    }
+
+    function onAnimationFinish(current) {
+        if (current == -99){
+            fecthVideoListV2(true)
+
+            return
+        }
+        activeIndex = current
+        if (current >= videoList.length - 4) {
+            fecthVideoListV2()
+        }
+    }
+
+
+    return (
+        <View className='category-page'>
+            <VideoSwiper
+                list={videoList}
+                needResumePlay={needResumePlay}
+                onFinish={onAnimationFinish}
+            />
+
+        </View>
+    )
+}

+ 7 - 0
src/pages/category/index.wxss

@@ -0,0 +1,7 @@
+.category-page {
+  background-color: black;
+  width: 100%;
+  height: calc(100% - 110px);
+  position: absolute;
+  top: 0;
+}

+ 0 - 20
src/pages/index/index.less

@@ -1,20 +0,0 @@
-.container {
-    background-color: black;
-    width: 100%;
-    height: calc(100% - 110px);
-    position: absolute;
-    top: 0;
-
-    .video_list {
-        display: flex;
-        overflow: scroll;
-        width: 100%;
-        height: 100%;
-
-        .videoplayer {
-            width: 100%;
-            height: calc(100% - 40px);
-            margin-top: 40px;
-        }
-    }
-}

+ 0 - 178
src/pages/index/index.tsx

@@ -1,178 +0,0 @@
-import Taro, { useLoad, useDidShow, useReady, useDidHide, usePullDownRefresh, useShareAppMessage, useRouter } from '@tarojs/taro'
-import { useMemo, useState } from 'react'
-import type CustomTabBar from '@/custom-tab-bar'
-import { View, Swiper, SwiperItem, Video } from '@tarojs/components'
-import { VideoInfo } from '@/constants/commentTypes'
-import { videoListV2 } from '@/http/api'
-// import { getTopSafeHeight, throttle, formatSecondsAsTime, getPreIds } from '@/utils'
-
-// import Route from '@/class/Route'
-import './index.less'
-
-let pageNo = 1
-let pending = false
-
-export default function Index() {
-    const page = useMemo(() => Taro.getCurrentInstance().page, []);
-    const router = useRouter()
-    const { params } = router || {}
-
-
-    let state = {
-        currentIdx: 0,
-        currentSwiperIdex: 0,
-    }
-    const [videoList, setVideoList] = useState<VideoInfo[]>([])
-    const [refresherTriggered, setRefresherTriggered] = useState(false)
-
-    useLoad(() => {
-        const { redirect } = params
-        if (redirect) {
-            // const route = new Route()
-            // route.push(decodeURIComponent(redirect))
-        }
-        fecthVideoListV2()
-    })
-
-    useDidShow(() => {
-        const tabbar = Taro.getTabBar<CustomTabBar>(page)
-        tabbar?.setSelected(0)
-
-    })
-
-    useReady(() => {
-        setVideoList([
-            {
-                id: 8987051,
-                videoPath: 'http://rescdn.yishihui.com/longvideo/multitranscode/video/vpc/20210821/1244745QN8L8QWQjlbUmyQ5yI20210822131000216222495-3HD.mp4',
-                title: '标题 1',
-                shareTitle: '标题 1',
-                coverImgPath: 'http://rescdn.yishihui.com/longvideo/snapshot/vpc/20210821/1244745QN8L8QWQjlbUmyQ5yI_0?x-oss-process=image/resize,m_fill,w_600,h_480,limit_0/format,jpg/watermark,image_eXNoL3BpYy93YXRlcm1hcmtlci9iZ195eS5wbmc_eC1vc3MtcHJvY2Vzcz1pbWFnZS9yZXNpemUsaF80OS9yZXNpemUsbV9maWxsLHdfMTg1LGhfNDksbGltaXRfMA==,g_nw,x_408,y_414/watermark,type_d3F5LW1pY3JvaGVp,size_31,text_NS405LiH5Lq655yL6L-H,color_FFFFFF,t_100,g_nw,x_420,y_423/watermark,image_eXNoL3BpYy93YXRlcm1hcmtlci9pY29uX3BsYXlfd2hpdGUucG5nP3gtb3NzLXByb2Nlc3M9aW1hZ2UvcmVzaXplLHdfMTQ0,g_center',
-                recomTraceId: '',
-                flowPool: '',
-                user: {
-                    uid: 6282380,
-                    nickName: 'dax15818675906',
-                    avatarUrl: 'http://rescdn.yishihui.com/longvideo/pic/vpc/20201219/1244745CJ2mPPZ3eXhsjjjf8t?x-oss-process=image/rotate,0/resize,m_fill,w_100,h_100,limit_0/format,jpg'
-                }
-
-            },
-            {
-                id: 9105322,
-                videoPath: 'http://visionularcdn.yishihui.com/output/longvideo/multitranscode/video/vpc/20211112/12188054KWIADXkh5GTl8w2ijD20211114191000658534245-1LD.mp4',
-                title: '生存法则',
-                shareTitle: '生存法则',
-                coverImgPath: 'http://rescdn.yishihui.com/longvideo/pic/62e7c34380754aeab87fc1386fb879d61631682451076?x-oss-process=image/resize,m_fill,w_600,h_480,limit_0/format,jpg/watermark,image_eXNoL3BpYy93YXRlcm1hcmtlci9iZ195eS5wbmc_eC1vc3MtcHJvY2Vzcz1pbWFnZS9yZXNpemUsaF80OS9yZXNpemUsbV9maWxsLHdfMTg1LGhfNDksbGltaXRfMA==,g_nw,x_408,y_414/watermark,type_d3F5LW1pY3JvaGVp,size_31,text_NS4y5LiH5Lq655yL6L-H,color_FFFFFF,t_100,g_nw,x_420,y_423/watermark,image_eXNoL3BpYy93YXRlcm1hcmtlci9pY29uX3BsYXlfd2hpdGUucG5nP3gtb3NzLXByb2Nlc3M9aW1hZ2UvcmVzaXplLHdfMTQ0,g_center',
-                recomTraceId: '',
-                flowPool: '',
-                user: {
-                    uid: 6282380,
-                    nickName: '寰娱圈子',
-                    avatarUrl: 'http://rescdn.yishihui.com/longvideo/pic/vpc/20210401/151084326SAWDfr35MbV13Yqjf?x-oss-process=image/quality,q_10'
-                }
-
-            }
-        ])
-    })
-
-    useDidHide(() => {
-
-    })
-
-    usePullDownRefresh(() => {
-
-    })
-
-    useShareAppMessage(() => {
-        return {
-            title: '好友分享给你一个视频,点击查看~',
-        }
-    })
-
-    // const fecthVideoList = throttle(fecthVideoListV2)
-    function fecthVideoListV2(cleanOldCardList = false) {
-        Taro.$http.post(videoListV2, {
-            categoryId: 55,
-            pageNo,
-            pageSize: 6,
-            pageSource: 'pages/category'
-        }).then((res: RequestType) => {
-            const { code, data } = res
-            if (code != 0)
-                return
-
-            let oldCardList = videoList
-
-            if (cleanOldCardList) {
-                oldCardList = []
-                setRefresherTriggered(false)
-            }
-
-            pageNo++
-
-            setVideoList([
-                ...oldCardList,
-                ...filterCardProps(data)
-            ])
-
-        }).catch(() => {
-            pending = false
-        })
-    }
-
-    function pause() {
-        console.log('hhz-')
-    }
-
-    // 视频卡片需要参数过滤重组一次,并不需要把所有的数据都传进去
-    function filterCardProps(list) {
-        return list.map((item: RoughCardType) => {
-            const {
-                title, coverImg, user, id, videoPath,
-                recomTraceId, flowPool, shareTitle = ''
-            } = item || {}
-            const { coverImgPath = '' } = coverImg || {}
-            const { avatarUrl = '', nickName = '', uid = 0 } = user || {}
-
-            return {
-                id,
-                title,
-                coverImgPath,
-                shareTitle,
-                videoPath,
-                recomTraceId,
-                flowPool,
-                user:{
-                    uid,
-                    avatarUrl,
-                    nickName,
-                }
-            }
-        })
-    }
-
-    return (
-        <View className='container'>
-            <Swiper
-                className="video_list"
-                duration={300}
-                circular
-                vertical
-            >
-                {videoList.map(item => (
-                    <SwiperItem key={item.id} className="banner_list__item">
-                        <Video className='videoplayer'
-                            src={item.videoPath}
-                            loop
-                            controls={false}
-                            enableProgressGesture={false}
-                            onTap={pause}
-                        >
-
-                        </Video>
-                    </SwiperItem>
-                ))}
-            </Swiper>
-        </View>
-    )
-}

+ 0 - 18
src/pages/index/index.wxss

@@ -1,18 +0,0 @@
-.container {
-  background-color: black;
-  width: 100%;
-  height: calc(100% - 110px);
-  position: absolute;
-  top: 0;
-}
-.container .video_list {
-  display: flex;
-  overflow: scroll;
-  width: 100%;
-  height: 100%;
-}
-.container .video_list .videoplayer {
-  width: 100%;
-  height: calc(100% - 40px);
-  margin-top: 40px;
-}

+ 5 - 0
src/pages/share/share.config.ts

@@ -0,0 +1,5 @@
+export default definePageConfig({
+  navigationBarTitleText: '分享页',
+  navigationStyle: 'custom',
+  usingComponents: {},
+})

+ 20 - 0
src/pages/share/share.less

@@ -0,0 +1,20 @@
+.share-page {
+    background-color: black;
+    width: 100%;
+    height: 100%;
+    position: absolute;
+    top: 0;
+
+    .backBtn {
+        position: absolute;
+        top: 40px;
+        left: 40px;
+        width: 80px;
+        height: 80px;
+
+        image {
+            width: 100%;
+            height: 100%;
+        }
+    }
+}

+ 156 - 0
src/pages/share/share.tsx

@@ -0,0 +1,156 @@
+import { useState } from 'react'
+import Taro, { useLoad, useDidShow, useReady, useDidHide, usePullDownRefresh, useShareAppMessage, useRouter } from '@tarojs/taro'
+import { View, Text, Image } from '@tarojs/components'
+import { VideoInfo } from '@/constants/commentTypes'
+import VideoSwiper from "@/components/VideoSwiper";
+import { videoDetail, recommendSharePageList } from '@/http/api'
+import { guid } from '@/utils/index'
+import { USER_SHARE_PAGESOURCE, RECOMMEND_PAGESOURCE } from '@/const/index'
+import './share.less'
+
+
+export default function Share() {
+
+    const router = useRouter()
+    const { params } = router || {}
+
+    const [videoList, setVideoList] = useState<any>([{
+        id: +params.id!,
+        title: decodeURIComponent(params.title || ''),
+        videoCoverSnapshotPath: decodeURIComponent(params.videoCoverSnapshotPath || ''),
+        videoPath: decodeURIComponent(params.videoPath || ''),
+        avatarUrl: decodeURIComponent(params.avatarUrl || ''),
+        nickName: params.nickName || '',
+        playCount: +params.playCount! || 0,
+        shareImgPath: decodeURIComponent(params.shareImgPath || ''),
+        favorited: params.favorited === 'true',
+        type: 'temp',
+        pageSource: USER_SHARE_PAGESOURCE
+    }])
+
+    useLoad(() => {
+        console.log('Page loaded.')
+
+        getVideoDetail()
+        getRecommendList()
+
+    })
+
+    useReady(() => {
+
+    })
+
+    useDidShow(() => {
+
+    })
+
+    useDidHide(() => {
+
+    })
+
+    useShareAppMessage((shareRes) => {
+
+        return {}
+    })
+
+    function getVideoDetail() {
+        let { id } = params
+
+        Taro.$http.post(videoDetail, {
+            videoId: id,
+            pageSource: 'lite-pages/user-videos-detail',
+            rootPageSource: 'lite-pages/category',
+        }).then((res: RequestType) => {
+            const { code, data } = res
+            if (code !== 0)
+                return
+
+            if (!data.videoPath || !data.id) {
+                Taro.showToast({
+                    title: '视频地址为空~!',
+                    icon: 'error'
+                })
+
+                return
+            }
+
+            let video = formatVideoDetail(data)
+            video.pageSource = USER_SHARE_PAGESOURCE
+            setVideoList([video])
+
+        })
+    }
+
+    function getRecommendList() {
+        let { id } = params
+
+        Taro.$http.post(recommendSharePageList, {
+            currentVideoId: id
+        }, { timeout: 5000 })
+            .then(res => {
+                const { code, data } = res
+                if (code != 0) {
+                    return
+                }
+                let oldCardList = videoList
+
+                const recomList = data.map(item => {
+                    let video = formatVideoDetail(item)
+                    video.pageSource = RECOMMEND_PAGESOURCE
+
+                    return video
+                })
+
+                setVideoList({
+                    ...oldCardList,
+                    ...recomList
+                })
+            })
+
+    }
+
+    function onAnimationFinished(){
+
+    }
+    function backBtnAction(){
+        Taro.navigateBack()
+    }
+
+    return (
+        <View className='share-page'>
+            <View className='backBtn' onClick={backBtnAction}>
+                <Image src='https://weapppiccdn.yishihui.com/wxicon/common/ad_cover_back.png'/>
+            </View>
+            {/* <VideoSwiper list={videoList} onFinish={onAnimationFinished}/> */}
+            <Text>Hello world!</Text>
+        </View>
+    )
+}
+
+// 尽量不在组件间传输大量不用的数据
+function formatVideoDetail(detail) {
+    const {
+        videoPath, id, videoCoverSnapshotPath,
+        title, user, playCount, shareImgPath,
+        favorited, recomTraceId, flowPool,
+        measure, measureType, recommendLogVO,
+        recommendSource, uid, shareImgId,
+        titleId, isRecommendShare, transcodeStatus,
+        shareLinkType, rotate, sharePageType, pageSource = ''
+    } = detail
+    const { avatarUrl, nickName } = user
+
+    return {
+        videoPath, id, videoCoverSnapshotPath,
+        title, avatarUrl, nickName, playCount,
+        shareImgPath, favorited, recomTraceId,
+        flowPool, measure, measureType,
+        recommendLogVO, recommendSource,
+        playId: `${guid()}-${id}`,
+        viewId: `view-${new Date().getTime()}-${guid()}`,
+        uid, shareImgId, titleId, isRecommendShare,
+        transcodeStatus, shareLinkType, rotate,
+        sharePageType,
+        pageSource
+    }
+}

+ 18 - 0
src/pages/share/share.wxss

@@ -0,0 +1,18 @@
+.share-page {
+  background-color: black;
+  width: 100%;
+  height: 100%;
+  position: absolute;
+  top: 0;
+}
+.share-page .backBtn {
+  position: absolute;
+  top: 40px;
+  left: 40px;
+  width: 80px;
+  height: 80px;
+}
+.share-page .backBtn image {
+  width: 100%;
+  height: 100%;
+}

+ 0 - 3
src/pages/user-videos/user-videos.config.ts

@@ -1,3 +0,0 @@
-export default definePageConfig({
-  navigationBarTitleText: '分享页'
-})

+ 0 - 0
src/pages/user-videos/user-videos.less


+ 0 - 16
src/pages/user-videos/user-videos.tsx

@@ -1,16 +0,0 @@
-import { View, Text } from '@tarojs/components'
-import { useLoad } from '@tarojs/taro'
-import './user-videos.less'
-
-export default function Index() {
-
-  useLoad(() => {
-    console.log('Page loaded.')
-  })
-
-  return (
-    <View className='index'>
-      <Text>Hello world!</Text>
-    </View>
-  )
-}

+ 8 - 6
src/shareHelper/index.ts

@@ -37,7 +37,8 @@ export function sharePageAppMessage({ video, activeIndex, router, shareRes }) {
 
 export function shareVideoToWechat(params) {
   const { video } = params
-  const shareId = Taro.$global.get('mid') + '-' + S4() + new Date().getTime()
+  const mid = Taro.$global.get('mid')
+  const shareId = mid + '-' + S4() + new Date().getTime()
 
   // TODO: 处理 pagesource
   let pageSource = video.head ? USER_SHARE_PAGESOURCE : RECOMMEND_PAGESOURCE
@@ -49,8 +50,8 @@ export function shareVideoToWechat(params) {
 
   const query = {
       userSence: USER_SENCE.share,
-      mid: Taro.$global.get('mid'),
-      rootMid: params.rootMid || Taro.$global.get('mid'),
+      mid: mid,
+      rootMid: params.rootMid || mid,
       shareId,
       pageSource,
       rootPageSource: params.rootPageSource || pageSource,
@@ -91,7 +92,7 @@ export function shareVideoToWechat(params) {
       ...videoPlayParams(video)
   }
 
-  const detailPath = `${params.path}?${stringify(query)}`
+  const detailPath = `/pages/share/share?${stringify(query)}`
 
   shareReport(query)
   weixinFriend(query)
@@ -106,9 +107,10 @@ export function shareVideoToWechat(params) {
 function videoPlayParams(video) {
   const {
     id, title, shareImgPath,
-    videoCoverSnapshotPath, videoPath, avatarUrl,
-    playCount, nickName, favorited
+    videoCoverSnapshotPath, videoPath,
+    playCount, favorited, user
   } = video
+  let {nickName, avatarUrl} = user
 
   return {
     title: encodeURIComponent(title || ''),

+ 7 - 0
src/subPackages/safe/complaining/index.config.ts

@@ -0,0 +1,7 @@
+export default definePageConfig({
+  renderer: 'webview',
+  navigationStyle: 'default',
+  navigationBarBackgroundColor: '#fff',
+  navigationBarTextStyle: 'black',
+  navigationBarTitleText: '投诉'
+})

+ 54 - 0
src/subPackages/safe/complaining/index.less

@@ -0,0 +1,54 @@
+.complaining-page {
+  .complaining-comment {
+    text-align: center;
+    padding: 20px 0;
+    font-size: 24px;
+    color: #999;
+  }
+
+  .reason {
+    box-sizing: border-box;
+    width: 100%;
+    height: 80px;
+    display: flex;
+    align-items: center;
+    padding: 0 40px;
+    font-size: 28px;
+    color: #333;
+    border-bottom: 2px solid #f7f7f7; 
+  }
+
+  .other-reason {
+    width: 100%;
+    margin-top: 20px;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    font-size: 24px;
+    flex-direction: column;
+
+    textarea {
+      border: 1px solid #f2f2f2;
+      padding: 10px;
+      background: #f9f9f9;
+      height: 100px;
+    }
+
+    .placeholder-class {
+      font-size: 24px;
+      color: #999;
+    }
+
+    .submit {
+      width: 200px;
+      height: 60px;
+      text-align: 60px;
+      font-size: 26px;
+      background: #55c57c;
+      color: #fff;
+      border: 0;
+      margin-top: 20px;
+    }
+  }
+}
+

+ 108 - 0
src/subPackages/safe/complaining/index.tsx

@@ -0,0 +1,108 @@
+import { useState } from 'react'
+import Taro, { useLoad, useRouter } from '@tarojs/taro'
+import { View, Textarea, Button } from "@tarojs/components"
+import { reasonList, videoReport } from '@/http/api/index'
+import './index.less'
+
+function Complaining() {
+  let reason = ''
+  const { params } = useRouter()
+  const { videoId } = params
+  const [list, setList] = useState([])
+  const [showOtherReason, setShowOtherReason] = useState(false)
+  useLoad(() => {
+    fetchList()
+  })
+
+  function fetchList() {
+    Taro.$http.post(reasonList).then((res: RequestType) => {
+      const { code, data } = res
+      if (code !== 0)
+        return
+
+      const reasons = data.reduce((calc, cur) => {
+        return calc.concat(cur.reasons)
+      }, [])
+
+      setList(reasons)
+    })
+  }
+
+  function onClick(item, index) {
+    if (list.length - 1 === index) {
+      setShowOtherReason(true)
+      return
+    }
+
+    showOtherReason && setShowOtherReason(false)
+
+    reason = item
+
+    onSubmit()
+  }
+
+  function textInput(res) {
+    const { detail } = res
+
+    reason = detail?.value
+  }
+
+  function onSubmit() {
+    if (!reason) {
+      Taro.showToast({
+        title: '请填写举报理由',
+        icon: 'none'
+      })
+      return
+    }
+
+    Taro.$http.post(videoReport, { videoId }).then((res: RequestType) => {
+      const { code, msg } = res
+
+      if (code !== 0) {
+        Taro.showToast({
+          title: msg,
+          icon: 'none'
+        })
+        return
+      }
+
+      Taro.showToast({
+        title: '举报成功',
+        icon: 'none'
+      })
+
+      setTimeout(() => {
+        Taro.navigateBack()
+      }, 500)
+    })
+  }
+
+  return (
+    <View className='complaining-page'>
+    <View className='complaining-comment'>
+      此投诉为本小程序自有投诉渠道,非微信官方投诉渠道
+    </View>
+
+      {
+        list.map((item, index) => {
+          return (
+            <View className='reason' onClick={() => onClick(item, index)}>
+              {item}
+            </View>
+          )
+        })
+      }
+
+      {
+        showOtherReason && <View className='other-reason'>
+          <Textarea autoFocus placeholderClass='placeholder-class' placeholder='填写举报理由' onInput={textInput}/>
+
+          <Button className='submit' onClick={onSubmit}>提交</Button>
+        </View>
+      }
+    </View>
+  )
+}
+
+export default Complaining