tabbar页面增加分享,自定义ui视频组件封装

v2
一杯沧海 1 year ago
parent 9178e7ba47
commit 1df2db15b0
  1. 4
      src/components/videoPro/index.module.scss
  2. 200
      src/components/videoPro/index.tsx
  3. 4
      src/pages/home/home.config.ts
  4. 15
      src/pages/home/home.tsx
  5. 2
      src/pages/index/index.config.ts
  6. 17
      src/pages/index/index.tsx
  7. 4
      src/pages/my/my.config.ts
  8. 7
      src/pages/my/my.tsx
  9. 4
      src/pages/preview/brand/info/info.config.ts
  10. 2
      src/pages/preview/brand/info/info.module.scss
  11. 44
      src/pages/preview/brand/info/info.tsx
  12. 4
      src/pages/search/index.config.ts
  13. 16
      src/pages/search/index.tsx

@ -0,0 +1,4 @@
.container{
width:750rpx;
height:600rpx;
}

@ -0,0 +1,200 @@
import React, {FC, useEffect, useRef, useState, useImperativeHandle} from "react";
import {Image, Text, Video, View} from "@tarojs/components";
import "./index.module.scss"
import Icon from "@/components/icon";
import {AtSlider} from "taro-ui";
import Taro from "@tarojs/taro";
import full from "@/static/img/fullscreen.png"
import unfull from "@/static/img/exitFullscreen.png"
type Props = {
src: string
onRef: any
}
const VideoPro:FC<Props> = ({src,onRef}) => {
const globalData = Taro.getApp().globalData
//用useImperativeHandle暴露一些外部ref能访问的属性
useImperativeHandle(onRef, () => {
return {
func: pause,
}
})
// 视频ui控制需要的响应式数据
const videoContext = useRef<any>()
const [isPlay, setIsPlay] = useState(false)
const [duration,setDuration] = useState(0) // 视频长度 单位秒
const updateState = useRef(false)
const [sliderValue,setSlidervalue] = useState(0)
const [process_duration, set_process_duration] = useState('00:00')
const [total_duration, set_total_duration] = useState('00:00')
const [showMenu,setShowMenu] = useState(true)
const [isFull,setIsFull] = useState(false)
const time = useRef<any>()
useEffect(() => {
console.log('组件加载')
videoContext.current = Taro.createVideoContext('video')
updateState.current = true
}, []);
function onTouchStart(){
if(!showMenu) {
setShowMenu(true)
}
}
function onTouchEnd(){
if(time.current) {
clearTimeout(time.current)
time.current = null
}
time.current = setTimeout(() => {
setShowMenu(false)
},5000)
}
function bindTimeupdateFun(e) {
if (updateState.current) {
let sliderValue = e.detail.currentTime / e.detail.duration * 100;
setSlidervalue(sliderValue)
setDuration(e.detail.duration)
set_total_duration(formatSeconds(e.detail.duration))
set_process_duration(formatSeconds(e.detail.currentTime))
}
}
function addZero(i){
i = typeof i === 'string' ? Number(i) : i;
return i < 10 ? "0" + i : "" + i;
}
function formatSeconds(value){
if (value == undefined) {
value = 0;
}
let second = parseInt(value);
let min = 0;
let secondStr = ''
let minStr = ''
let result = ''
if (second > 60) {
min = parseInt(String(second / 60));
second = parseInt(String(second % 60));
if (min > 60) {
// hour = parseInt(String(min / 60));
min = parseInt(String(min % 60));
}
}
if (min > 0) {
minStr = addZero(parseInt(String(min)));
result = minStr + ":";
}else{
result = "00:";
}
if(second > 0){
secondStr = addZero(parseInt(String(second)));
result = result + secondStr;
}else{
result = result + '00';
}
return result;
}
function bindEnded(){
setIsPlay(false)
if(!showMenu){
setShowMenu(true)
}
}
function onFullScreenChange(e){
console.log(e.detail.fullScreen)
if(e.detail.fullScreen){
setIsFull(true)
}else{
setIsFull(false)
}
}
function play(e){
e.stopPropagation();
videoContext.current.play()
setIsPlay(true)
}
function pause(){
setIsPlay(false)
videoContext.current.pause()
}
function sliderOnChange(e){
if (duration) {
// 视频跳转到指定位置
videoContext.current.seek(e / 100 * duration);
updateState.current = true
setSlidervalue(e)
}
}
function sliderOnChanging(){
updateState.current = false
}
return (
<View className="container">
<Video
style={{width: '750rpx', height: '600rpx'}}
id='video'
// src={brandInfo?.introductory_video_resource?.url}
src={src}
controls={false}
showPlayBtn={false}
showCenterPlayBtn={false}
showProgress={false}
showFullscreenBtn={false}
enableProgressGesture={false}
onTimeUpdate={bindTimeupdateFun}
onEnded={bindEnded}
onFullScreenChange={onFullScreenChange}
>
<View onTouchStart={onTouchStart} onTouchEnd={onTouchEnd} style={{width:isFull?`${globalData.screenHeight}px`:'750rpx',height:isFull?'750rpx':'600rpx',display:'flex',flexDirection:'column',boxSizing:'border-box',paddingLeft:isFull?`${globalData.statusBarHeight}px`:'0',paddingRight:isFull?`${globalData.statusBarHeight}px`:'0'}}>
<View onClick={pause} className="justify-center align-center flex pt-5" style={{flex:'1',boxSizing:'border-box'}}>
{ !isPlay && showMenu &&
<View className="flex justify-center align-center rounded-50 pl-1" style={{width:'50px',height:'50px',backgroundColor:'rgba(0,0,0,0.5)',boxSizing:'border-box'}}>
<Icon onClick={play} name="play" color="#fff" size="35px"></Icon>
</View>
}
</View>
<View className="flex align-center px-3" style={{height:'40px',boxSizing:'border-box'}}>
{ duration && showMenu &&
<>
{
isPlay ?
<Icon name="pause" color="#fff" size="23px" onClick={() => {videoContext.current.pause();setIsPlay(false)}} /> :
<Icon name="play" color="#fff" size="23px" onClick={() => {videoContext.current.play();setIsPlay(true)}} />
}
<Text className="text-white pl-1 font-26">{process_duration}</Text>
<View style={{flex:'1'}}>
<AtSlider onChange={sliderOnChange} onChanging={sliderOnChanging} step={1} value={sliderValue} activeColor='#fff' backgroundColor='#BDBDBD' blockColor='#fff' blockSize={10}></AtSlider>
</View>
<Text onClick={() => {
isFull?videoContext.current.exitFullScreen():videoContext.current.requestFullScreen({direction:90})
}} className="text-white font-26 pr-1">{total_duration}</Text>
{
isFull? <Image style={{width:'25px',height:'25px'}} onClick={() => {videoContext.current.exitFullScreen()}} src={unfull} />
: <Image style={{width:'23px',height:'23px'}} src={full} onClick={() => {videoContext.current.requestFullScreen({direction:90})}} />
}
</>
}
</View>
</View>
</Video>
</View>
)
}
export default VideoPro

@ -3,5 +3,7 @@ export default definePageConfig({
navigationStyle: 'custom', navigationStyle: 'custom',
navigationBarBackgroundColor: '#92ecc5', navigationBarBackgroundColor: '#92ecc5',
// navigationBarTextStyle: 'white', // navigationBarTextStyle: 'white',
onReachBottomDistance: 50 onReachBottomDistance: 50,
enableShareTimeline: true,
enableShareAppMessage: true
}) })

@ -42,6 +42,21 @@ const Home: FC = () => {
setNavbarOpacity(v) setNavbarOpacity(v)
} }
}) })
Taro.useShareAppMessage((res) => {
if(res.from === 'button'){
}
return {
title:'信桂',
path: '/pages/home/home'
}
})
Taro.useShareTimeline(() => {
return {
title: '信桂'
}
})
return ( return (
<> <>

@ -1,3 +1,5 @@
export default definePageConfig({ export default definePageConfig({
navigationStyle: 'custom', navigationStyle: 'custom',
enableShareTimeline: true,
enableShareAppMessage: true
}) })

@ -9,6 +9,7 @@ import Spin from "@/components/spinner";
import {isBoolean} from "@tarojs/shared"; import {isBoolean} from "@tarojs/shared";
import ArticlesBox from "@/components/articlesBox/articlesBox"; import ArticlesBox from "@/components/articlesBox/articlesBox";
import PageScript from "@/components/pageScript/pageScript"; import PageScript from "@/components/pageScript/pageScript";
import Taro from "@tarojs/taro";
const category: TabList[] = [ const category: TabList[] = [
{title: "企选课程", value: 'is_required'}, {title: "企选课程", value: 'is_required'},
@ -22,6 +23,22 @@ const Index: FC = () => {
setCategoryKey(data.tab?.value as CoursesKey) setCategoryKey(data.tab?.value as CoursesKey)
} }
Taro.useShareAppMessage((res) => {
if(res.from === 'button'){
}
return {
title:'信桂',
path: '/pages/index/index'
}
})
Taro.useShareTimeline(() => {
return {
title: '信桂'
}
})
return ( return (
<View className={styles.content}> <View className={styles.content}>
<NavigationBar <NavigationBar

@ -1,3 +1,5 @@
export default definePageConfig({ export default definePageConfig({
navigationStyle: 'custom' navigationStyle: 'custom',
enableShareTimeline: true,
enableShareAppMessage: true,
}) })

@ -60,6 +60,13 @@ const My: FC = () => {
{title: '未完成', time: '0', src: incomplete, type: 4}, {title: '未完成', time: '0', src: incomplete, type: 4},
]) ])
Taro.useShareAppMessage(() => {
return {
title:'信桂',
path: '/pages/my/my'
}
})
Taro.useDidShow(async () => { Taro.useDidShow(async () => {
try { try {
const res = await curriculum.course() const res = await curriculum.course()

@ -1,4 +1,6 @@
export default definePageConfig({ export default definePageConfig({
navigationBarTitleText: '', navigationBarTitleText: '',
onReachBottomDistance: 30 onReachBottomDistance: 30,
enableShareTimeline: true,
enableShareAppMessage: true
}) })

@ -9,7 +9,7 @@ page {
.curIndexBox { .curIndexBox {
position: absolute; position: absolute;
top: 530rpx; top: 480rpx;
right: 30rpx; right: 30rpx;
background-color: rgba(0, 0, 0, 0.5); background-color: rgba(0, 0, 0, 0.5);
border-radius: 30rpx; border-radius: 30rpx;

@ -1,5 +1,5 @@
import {FC, useCallback, useEffect, useState} from "react"; import React, {FC, useCallback, useEffect, useState} from "react";
import {Swiper, SwiperItem, Text, Video, View} from "@tarojs/components"; import {Swiper, SwiperItem, Text, View} from "@tarojs/components";
import {brandApi, BrandRecord} from "@/api"; import {brandApi, BrandRecord} from "@/api";
import styles from './info.module.scss' import styles from './info.module.scss'
import Taro, {useReachBottom, useRouter} from "@tarojs/taro"; import Taro, {useReachBottom, useRouter} from "@tarojs/taro";
@ -9,6 +9,7 @@ import Spin from "@/components/spinner";
import Collect from "@/components/collect/collect"; import Collect from "@/components/collect/collect";
import ArticlesBox from "@/components/articlesBox/articlesBox"; import ArticlesBox from "@/components/articlesBox/articlesBox";
import PageScript from "@/components/pageScript/pageScript"; import PageScript from "@/components/pageScript/pageScript";
import VideoPro from "@/components/videoPro"
type Params = { type Params = {
id: number id: number
@ -22,6 +23,14 @@ const BrandInfo: FC = () => {
const [total, setTotal] = useState(0) const [total, setTotal] = useState(0)
const [enable, setEnable] = useState(true) const [enable, setEnable] = useState(true)
let VideoRef = React.createRef<any>()
Taro.useDidHide(() => {
console.log("页面隐藏",VideoRef.current.func)
// 视频被隐藏后自动暂停播放了,再打开自动继续播放了
// VideoRef.current.func()
})
useEffect(() => { useEffect(() => {
getData() getData()
}, [id]) }, [id])
@ -43,6 +52,22 @@ const BrandInfo: FC = () => {
setEnable(false) setEnable(false)
} }
Taro.useShareAppMessage((res) => {
if(res.from === 'button'){
}
return {
title:brandInfo?.name ?? '信桂',
path: `/pages/preview/brand/info/info?id=${id}`
}
})
Taro.useShareTimeline(() => {
return {
title: '信桂'
}
})
useReachBottom(useCallback(() => { useReachBottom(useCallback(() => {
if (articleList?.length < total) { if (articleList?.length < total) {
setPage(page + 1) setPage(page + 1)
@ -64,7 +89,6 @@ const BrandInfo: FC = () => {
setCurIndex(+e.detail.current + 1) setCurIndex(+e.detail.current + 1)
} }
return ( return (
<View className='flex flex-column' style={{display: 'flex'}}> <View className='flex flex-column' style={{display: 'flex'}}>
<Spin enable={enable} overlay/> <Spin enable={enable} overlay/>
@ -79,19 +103,7 @@ const BrandInfo: FC = () => {
onChange={onChange} onChange={onChange}
> >
{brandInfo?.introductory_video_resource?.url && <SwiperItem> {brandInfo?.introductory_video_resource?.url && <SwiperItem>
<Video <VideoPro onRef={VideoRef} src={"http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"}></VideoPro>
style={{width: '750rpx', height: '600rpx'}}
playBtnPosition={"center"}
id='video'
src={brandInfo?.introductory_video_resource?.url}
initialTime={0}
controls={true}
enableProgressGesture={false}
showFullscreenBtn={false}
autoplay={false}
loop={false}
muted={false}
/>
</SwiperItem>} </SwiperItem>}
{ {
(brandInfo?.brand_album?.length || 0) > 0 (brandInfo?.brand_album?.length || 0) > 0

@ -1,3 +1,5 @@
export default definePageConfig({ export default definePageConfig({
navigationStyle: 'custom' navigationStyle: 'custom',
enableShareTimeline: true,
enableShareAppMessage: true
}) })

@ -19,6 +19,22 @@ const Search: FC = () => {
useDidShow(getRecentSearch) useDidShow(getRecentSearch)
Taro.useShareAppMessage((res) => {
if(res.from === 'button'){
}
return {
title:'信桂',
path: '/pages/search/index'
}
})
Taro.useShareTimeline(() => {
return {
title: '信桂',
}
})
useEffect(() => { useEffect(() => {
!show && getRecentSearch() !show && getRecentSearch()
}, [show]) }, [show])

Loading…
Cancel
Save