Commit b02c4e5a by zhanghaozhe

播放样式 选择视频

parent d0b782ad
...@@ -41,8 +41,6 @@ class App extends Component { ...@@ -41,8 +41,6 @@ class App extends Component {
//平台信息 //平台信息
cookie.set('plat', '5', {domain: '.julyedu.com'}) cookie.set('plat', '5', {domain: '.julyedu.com'})
console.log(this.props.location);
this.props.startFetchUser() this.props.startFetchUser()
http.get(`${API.home}/m/user_info`).then(res => { http.get(`${API.home}/m/user_info`).then(res => {
this.props.setCurrentUser(this.transformUser(res)) this.props.setCurrentUser(this.transformUser(res))
......
...@@ -283,7 +283,6 @@ class Detail extends Component { ...@@ -283,7 +283,6 @@ class Detail extends Component {
} }
// 点击子组件单集购买按钮 // 点击子组件单集购买按钮
toSingleset = (item) => { toSingleset = (item) => {
console.log(this.props);
const {user} = this.props const {user} = this.props
const uid = user && user.data && user.data.uid const uid = user && user.data && user.data.uid
if (!uid) { if (!uid) {
...@@ -415,7 +414,6 @@ class Detail extends Component { ...@@ -415,7 +414,6 @@ class Detail extends Component {
render() { render() {
const { course: { course_info={} }, barInfo, singleBox, singleType } = this.state; const { course: { course_info={} }, barInfo, singleBox, singleType } = this.state;
console.log(course_info);
let courseInfo = '', let courseInfo = '',
service = '', service = '',
number = 0, number = 0,
......
...@@ -104,6 +104,7 @@ class Single extends Component { ...@@ -104,6 +104,7 @@ class Single extends Component {
http.get(`${API['base-api']}/pay/wxpay/pub_charge/oid/${getParam('oid')}/code/${weixin_code}`).then((res) => { http.get(`${API['base-api']}/pay/wxpay/pub_charge/oid/${getParam('oid')}/code/${weixin_code}`).then((res) => {
if (res.data.errno === 0) { if (res.data.errno === 0) {
const data = res.data.data; const data = res.data.data;
function onBridgeReady() { function onBridgeReady() {
WeixinJSBridge.invoke( WeixinJSBridge.invoke(
'getBrandWCPayRequest', { 'getBrandWCPayRequest', {
...@@ -163,6 +164,7 @@ class Single extends Component { ...@@ -163,6 +164,7 @@ class Single extends Component {
} }
) )
} }
if (typeof WeixinJSBridge == "undefined") { if (typeof WeixinJSBridge == "undefined") {
if (document.addEventListener) { if (document.addEventListener) {
document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false) document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false)
...@@ -184,9 +186,9 @@ class Single extends Component { ...@@ -184,9 +186,9 @@ class Single extends Component {
// 支付完成之后获取状态 // 支付完成之后获取状态
payCallback = () => { payCallback = () => {
const _this = this; const _this = this;
if(!getParam('oid')) { if (!getParam('oid')) {
return; return;
}else{ } else {
_this.intervalPayStatus = setInterval(function () { _this.intervalPayStatus = setInterval(function () {
http.get(`${API['base-api']}/m/orderState/oid/${getParam('oid')}`).then(res => { http.get(`${API['base-api']}/m/orderState/oid/${getParam('oid')}`).then(res => {
if (res.data.errno === 401) { if (res.data.errno === 401) {
...@@ -301,7 +303,7 @@ class Single extends Component { ...@@ -301,7 +303,7 @@ class Single extends Component {
} }
render() { render() {
const { showSingleBox } = this.state; const {showSingleBox} = this.state;
if (this.state.endTime) { if (this.state.endTime) {
let date = this.state.endTime * 1000 let date = this.state.endTime * 1000
let now = Date.now() let now = Date.now()
...@@ -317,53 +319,46 @@ class Single extends Component { ...@@ -317,53 +319,46 @@ class Single extends Component {
}) })
}, 1000) }, 1000)
} }
const { singleType } = this.props; const {singleType} = this.props;
console.log(this.state.singleBox);
return ( return (
singleType === 1 &&
<div> <div>
<div className='popup-box'>
<div className='content singleset-payment'>
<div className='popup-box'> <div className='price-box'>
{ <span>实付款:</span>
singleType === 1 && <p>{this.props.data.class_price}</p>
<div className='content singleset-payment'> </div>
<div className='price-box'> <div className='course-info'>
<span>实付款:</span> <p className='text-overflow-1'><span>课程:</span>
<p>{this.props.data.class_price}</p> {this.props.title}
</div> </p>
<div className='course-info'> <p className='text-overflow-1'><span>课时:</span>
<p className='text-overflow-1'><span>课程:</span> {this.props.data.name}
{this.props.title} </p>
</p> </div>
<p className='text-overflow-1'><span>课时:</span> <div className='payment-type'>
{this.props.data.name} <label>支付方式:</label>
</p> {
</div> !browser.isWeixin &&
<div className='payment-type'> <p onClick={this.check.bind(this, '1')}>
<label>支付方式:</label> <i className='iconfont iconalipay'></i>
{ <span>支付宝</span>
!browser.isWeixin && <i className={`iconfont icondanseshixintubiao-5 redio ${this.state.payType === '1' ? 'redioed' : ''}`}></i>
<p onClick={this.check.bind(this, '1')}> </p>
<i className='iconfont iconalipay'></i> }
<span>支付宝</span>
<i className={`iconfont icondanseshixintubiao-5 redio ${this.state.payType === '1' ? 'redioed' : ''}`}></i>
</p>
}
<p onClick={this.check.bind(this, '0')}> <p onClick={this.check.bind(this, '0')}>
<i className='iconfont iconweixinzhifu buy'></i> <i className='iconfont iconweixinzhifu buy'></i>
<span>微信支付</span> <span>微信支付</span>
<i className={`iconfont icondanseshixintubiao-5 redio ${this.state.payType === '0' ? 'redioed' : ''}`}></i> <i className={`iconfont icondanseshixintubiao-5 redio ${this.state.payType === '0' ? 'redioed' : ''}`}></i>
</p> </p>
</div> </div>
<div className='btn btn-18B4ED' onClick={this.toBuy}>确认购买</div> <div className='btn btn-18B4ED' onClick={this.toBuy}>确认购买</div>
</div>
}
<i onClick={this.colse} className={'iconfont iconiconfront-2 close'}></i>
</div> </div>
<i onClick={this.colse} className={'iconfont iconiconfront-2 close'}></i>
</div>
</div> </div>
); );
......
import videojs from 'video.js'
const Component = videojs.getComponent('Component')
const Button = videojs.getComponent('Button')
class CustomPlayButtonCover extends Component {
createEl() {
return super.createEl('div', {
className: 'vjs-custom-play-button-cover'
})
}
dispose() {
this.el_ && (this.el_ = null)
}
}
class CustomPlayButton extends Button {
constructor(player, options) {
super(player, options)
this.on('tap', this.tap)
}
createEl() {
return super.createEl('button', {
className: 'vjs-custom-play-button'
}, {
type: 'button'
})
}
tap() {
this.player_.play()
}
dispose() {
if (this.el_) {
this.off('tap', this.tap)
this.el_ = null
}
}
}
Component.registerComponent('CustomPlayButton', CustomPlayButton)
CustomPlayButtonCover.prototype.options_ = {
children: [
'CustomPlayButton'
]
}
Component.registerComponent('CustomPlayButtonCover', CustomPlayButtonCover)
\ No newline at end of file
import React, {Component} from 'react' import React, { Component } from 'react'
import HeaderBar from '@/common/HeaderBar' import HeaderBar from '@/common/HeaderBar'
import './video.scss' import './video.scss'
import {NavLink, Route, Redirect, Switch, Link} from 'react-router-dom' import { NavLink, Route, Redirect, Switch, Link } from 'react-router-dom'
import {http, getParam} from '@/utils' import { http, getParam } from '@/utils'
import Recommendation from './recommendation' import Recommendation from './recommendation'
import VideoCatalog from './video-catalog' import VideoCatalog from './video-catalog'
import DatumCatalog from './datum-catalog' import DatumCatalog from './datum-catalog'
import {Toast} from 'antd-mobile' import { Toast } from 'antd-mobile'
import videojs from 'video.js' import videojs from 'video.js'
import 'video.js/dist/video-js.min.css' import 'video.js/dist/video-js.min.css'
import {Modal} from "antd-mobile" import { Modal } from "antd-mobile"
import {Loading} from '@/common' import { Loading } from '@/common'
import {connect} from "react-redux" import { connect } from "react-redux"
import jsCookie from 'js-cookie' import jsCookie from 'js-cookie'
import io from 'socket.io-client' import io from 'socket.io-client'
import Single from "@/components/detail/single"; import Single from "@/components/detail/single";
import './CustomPlayButton'
let alert = Modal.alert let alert = Modal.alert
...@@ -58,7 +59,6 @@ function ProgressShareModal(props) { ...@@ -58,7 +59,6 @@ function ProgressShareModal(props) {
) )
} }
class Video extends Component { class Video extends Component {
video //video element video //video element
...@@ -262,7 +262,7 @@ class Video extends Component { ...@@ -262,7 +262,7 @@ class Video extends Component {
this.player = videojs(this.video, { this.player = videojs(this.video, {
controls: true, controls: true,
preload: 'auto', preload: 'auto',
bigPlayButton: true, bigPlayButton: false,
textTrackDisplay: false, textTrackDisplay: false,
posterImage: false, posterImage: false,
errorDisplay: false, errorDisplay: false,
...@@ -271,6 +271,7 @@ class Video extends Component { ...@@ -271,6 +271,7 @@ class Video extends Component {
pictureInPictureToggle: false pictureInPictureToggle: false
} }
}) })
this.player.addChild('CustomPlayButtonCover')
this.player.on('ready', () => { this.player.on('ready', () => {
this.recordSocket.emit('load', this.recordUserInfo()) this.recordSocket.emit('load', this.recordUserInfo())
}) })
...@@ -310,7 +311,6 @@ class Video extends Component { ...@@ -310,7 +311,6 @@ class Video extends Component {
} }
selectVideo = index => { selectVideo = index => {
if (index === this.state.activeIndex) { if (index === this.state.activeIndex) {
return return
} }
...@@ -321,7 +321,7 @@ class Video extends Component { ...@@ -321,7 +321,7 @@ class Video extends Component {
activeIndex: index activeIndex: index
}, },
() => { () => {
if (this.hasAuth()) { if (this.hasAuth(this.state.activeIndex)) {
this.setPlayerSrc(this.state.videoList[index]['play_url']) this.setPlayerSrc(this.state.videoList[index]['play_url'])
this.sendLastRecord() this.sendLastRecord()
this.playVideo() this.playVideo()
...@@ -332,6 +332,9 @@ class Video extends Component { ...@@ -332,6 +332,9 @@ class Video extends Component {
) )
} }
getLastVideoIndex = lastIndex => {
return this.state.videoList.findIndex(item => item.id == lastIndex)
}
getVideoList = () => { getVideoList = () => {
let url = '' let url = ''
...@@ -356,29 +359,7 @@ class Video extends Component { ...@@ -356,29 +359,7 @@ class Video extends Component {
title: data.data.course['course_title'], title: data.data.course['course_title'],
isLoading: false isLoading: false
}), }),
() => { this.playSetup
if (this.state.course.is_aist) {
this.setupWS()
this.setupTimer()
}
if (this.lessonAvailable()) {
if (this.hasAuth()) {
Promise.resolve().then(() => {
this.initializePlayer()
this.playWithAuth()
})
} else {
this.getCoursePrice();
}
} else {
alert('暂无视频', '', [{
text: 'OK',
onPress: () => {
this.props.history.push('/')
}
}])
}
}
) )
} else { } else {
Toast.info(data.msg) Toast.info(data.msg)
...@@ -386,6 +367,37 @@ class Video extends Component { ...@@ -386,6 +367,37 @@ class Video extends Component {
}) })
} }
playSetup = () => {
if (this.state.course.is_aist) {
this.setupWS()
this.setupTimer()
}
let index = this.getLastVideoIndex(this.state.course.last_video_id)
index = index >= 0 ? index : 0
this.setState({
activeIndex: index
}, () => {
if (this.lessonAvailable(index)) {
if (this.hasAuth(index)) {
Promise.resolve().then(() => {
this.initializePlayer()
this.playWithAuth()
})
} else {
this.getCoursePrice();
}
} else {
alert('暂无视频', '', [{
text: 'OK',
onPress: () => {
this.props.history.push('/')
}
}])
}
})
}
setPlayerSrc = src => { setPlayerSrc = src => {
if (!this.player) { if (!this.player) {
this.initializePlayer() this.initializePlayer()
...@@ -417,13 +429,8 @@ class Video extends Component { ...@@ -417,13 +429,8 @@ class Video extends Component {
}) })
} }
lessonAvailable = () => { lessonAvailable = index => {
let {videoList, course} = this.state return this.state.videoList[index]['video_size'] !== 0
let videoIndex = videoList.findIndex(item => item.id == course.last_video_id)
this.setState({
activeIndex: videoIndex
})
return videoList[videoIndex]['video_size'] !== 0
} }
getCoursePrice = () => { getCoursePrice = () => {
...@@ -441,19 +448,15 @@ class Video extends Component { ...@@ -441,19 +448,15 @@ class Video extends Component {
playWithAuth = () => { playWithAuth = () => {
const {videoList, activeIndex} = this.state const {videoList, activeIndex} = this.state
if (this.hasAuth()) { if (this.hasAuth(activeIndex)) {
this.setPlayerSrc(videoList[activeIndex]['play_url']) this.setPlayerSrc(videoList[activeIndex]['play_url'])
} }
} }
hasAuth = () => { hasAuth = index => {
const {course, videoList} = this.state const {videoList} = this.state
let videoIndex = videoList.findIndex(item => item.id == course.last_video_id) let lesson = videoList[index]
this.setState({
activeIndex: videoIndex
})
let lesson = videoList[videoIndex]
if (lesson['video_auth']) { if (lesson['video_auth']) {
this.setState({ this.setState({
......
...@@ -9,12 +9,9 @@ ...@@ -9,12 +9,9 @@
&.active { &.active {
.title, .duration {
color: $active;
}
.video-title { .video-title {
background-color: #F5FBFF; background-color: #F5FBFF;
color: $active;
} }
.exercise{ .exercise{
border-top: 1px solid #E7EAF1; border-top: 1px solid #E7EAF1;
...@@ -73,4 +70,8 @@ ...@@ -73,4 +70,8 @@
float: right; float: right;
} }
.iconplay_hovericon{
color: $active;
}
} }
\ No newline at end of file
$tabHeight: 44px; $tabHeight: 44px;
.play { .play {
.video { .video {
width: 100%;
height: 215px;
background-color: $black;
position: relative;
.video-js {
width: 100%;
height: 100%;
.vjs-big-play-button {
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: #09f;
border: none;
}
}
.purchase-box {
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
background-color: rgba(0, 0, 0, 0.8);
display: flex;
flex-flow: column;
justify-content: center;
align-items: center;
.hint {
font-size: $font_14;
color: $white;
margin-bottom: 20px;
}
@mixin button {
display: block;
-webkit-appearance: none;
outline: none;
border: none;
background-color: transparent;
border-radius: 5px;
line-height: 30px;
font-size: 13px;
padding: 0 9px;
}
.btns {
width: 100%; width: 100%;
padding: 0 60px; height: 215px;
display: flex; background-color: $black;
justify-content: space-around; position: relative;
}
.purchase-class {
@include button;
background-color: $white;
color: $color_FF4000;
}
.purchase-episode {
@include button;
background-color: $bg_FF4000;
color: $white;
}
}
.is-aist-box { .video-js {
width: 100%; width: 100%;
height: 100%; height: 100%;
position: absolute;
left: 0; .vjs-custom-play-button-cover {
top: 0; position: absolute;
background-color: rgba(0, 0, 0, 0.8); top: 0;
display: flex; bottom: 0;
flex-flow: column; left: 0;
justify-content: center; right: 0;
align-items: center; background: rgba(0, 0, 0, 0.5);
color: #fff;
i {
font-size: 34px; .vjs-custom-play-button {
} position: absolute;
top: 50%;
.time { left: 50%;
font-size: 16px; transform: translate(-50%, -50%);
} width: 27px;
} height: 27px;
background: url("./images/play.png") no-repeat;
background-size: contain;
}
}
&.vjs-has-started{
.vjs-custom-play-button-cover{
bottom: 2.9em;
}
}
&.vjs-playing {
.vjs-custom-play-button-cover {
display: none;
}
}
}
video { .purchase-box {
width: 100%; width: 100%;
height: 100%; height: 100%;
} position: absolute;
} left: 0;
top: 0;
.tab { background-color: rgba(0, 0, 0, 0.8);
height: $tabHeight; display: flex;
max-height: $tabHeight; flex-flow: column;
line-height: $tabHeight; justify-content: center;
text-align: center; align-items: center;
background: #fff;
flex: 1 0 auto; .hint {
display: flex; font-size: $font_14;
justify-content: center; color: $white;
margin-bottom: 20px;
& > div { }
flex: 1 0 auto;
} @mixin button {
display: block;
-webkit-appearance: none;
outline: none;
border: none;
background-color: transparent;
border-radius: 5px;
line-height: 30px;
font-size: 13px;
padding: 0 9px;
}
.btns {
width: 100%;
padding: 0 60px;
display: flex;
justify-content: space-around;
}
.purchase-class {
@include button;
background-color: $white;
color: $color_FF4000;
}
.purchase-episode {
@include button;
background-color: $bg_FF4000;
color: $white;
}
}
a { .is-aist-box {
display: inline-block; width: 100%;
height: $tabHeight; height: 100%;
font-size: $font_16; position: absolute;
border-bottom: 1px solid transparent; left: 0;
top: 0;
background-color: rgba(0, 0, 0, 0.8);
display: flex;
flex-flow: column;
justify-content: center;
align-items: center;
color: #fff;
i {
font-size: 34px;
}
.time {
font-size: 16px;
}
}
&.active { video {
border-bottom: 1px solid $active; width: 100%;
} height: 100%;
}
} }
}
.active {
color: $active;
.iconiconfront-74 { .tab {
color: $color_555; height: $tabHeight;
} max-height: $tabHeight;
} line-height: $tabHeight;
text-align: center;
.progress-share-modal { background: #fff;
position: absolute; flex: 1 0 auto;
top: 50%; display: flex;
left: 50%; justify-content: center;
transform: translate(-50%, -50%);
width: 290px;
height: 332px;
padding: 18px 15px;
background: url("./images/progress-share-bg.png");
background-size: contain;
& > .title {
font-size: 21px;
color: #00656F;
line-height: 30px;
text-align: center;
margin-bottom: 20px;
}
.progress-container { & > div {
display: flex; flex: 1 0 auto;
justify-content: space-between;
margin-bottom: 20px;
li {
flex: 1;
.title {
font-size: 14px;
color: #00838F;
line-height: 20px;
text-align: center;
flex: 1;
margin-bottom: 10px;
} }
.number { a {
font-size: 15px; display: inline-block;
color: #00656F; height: $tabHeight;
text-align: center; font-size: $font_16;
border-bottom: 1px solid transparent;
.num { &.active {
font-size: 33px; border-bottom: 1px solid $active;
color: #00656F; }
}
} }
}
} }
.share-container { .active {
.title { color: $active;
position: relative;
text-align: center;
font-size: 14px;
color: #00838F;
margin-bottom: 25px;
&::before {
position: absolute;
top: 50%;
left: 30px;
transform: translateY(-50%);
content: '';
display: block;
width: 70px;
height: 1px;
background: #77c4bf;
}
&::after { .iconiconfront-74 {
position: absolute; color: $color_555;
top: 50%;
right: 30px;
transform: translateY(-50%);
content: '';
display: block;
width: 70px;
height: 1px;
background: #77c4bf;
} }
} }
ul { .progress-share-modal {
display: flex; position: absolute;
justify-content: space-around; top: 50%;
padding: 0 20px; left: 50%;
text-align: center; transform: translate(-50%, -50%);
width: 290px;
height: 332px;
padding: 18px 15px;
background: url("./images/progress-share-bg.png");
background-size: contain;
& > .title {
font-size: 21px;
color: #00656F;
line-height: 30px;
text-align: center;
margin-bottom: 20px;
}
li { .progress-container {
font-size: 12px; display: flex;
color: #00838F; justify-content: space-between;
margin-bottom: 20px;
li {
flex: 1;
.title {
font-size: 14px;
color: #00838F;
line-height: 20px;
text-align: center;
flex: 1;
margin-bottom: 10px;
}
.number {
font-size: 15px;
color: #00656F;
text-align: center;
.num {
font-size: 33px;
color: #00656F;
}
}
}
}
.iconfont { .share-container {
font-size: 40px; .title {
color: #00838f; position: relative;
} text-align: center;
font-size: 14px;
color: #00838F;
margin-bottom: 25px;
&::before {
position: absolute;
top: 50%;
left: 30px;
transform: translateY(-50%);
content: '';
display: block;
width: 70px;
height: 1px;
background: #77c4bf;
}
&::after {
position: absolute;
top: 50%;
right: 30px;
transform: translateY(-50%);
content: '';
display: block;
width: 70px;
height: 1px;
background: #77c4bf;
}
}
ul {
display: flex;
justify-content: space-around;
padding: 0 20px;
text-align: center;
li {
font-size: 12px;
color: #00838F;
.iconfont {
font-size: 40px;
color: #00838f;
}
}
}
} }
}
}
.close { .close {
position: absolute; position: absolute;
left: 50%; left: 50%;
transform: translateX(-50%); transform: translateX(-50%);
bottom: -63px; bottom: -63px;
color: #fff; color: #fff;
font-size: 30px; font-size: 30px;
} }
&-wrapper { &-wrapper {
position: fixed; position: fixed;
top: 0; top: 0;
left: 0; left: 0;
width: 100%; width: 100%;
height: 100%; height: 100%;
background: rgba(0, 0, 0, 0.5); background: rgba(0, 0, 0, 0.5);
touch-action: none; touch-action: none;
z-index: 100; z-index: 100;
}
} }
}
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment