369 lines
10 KiB
JavaScript
369 lines
10 KiB
JavaScript
/**
|
|
* 播放器详情页
|
|
* 大封面、进度条、倍速切换、播放控制
|
|
* 从 globalData.activeContent 获取当前节目
|
|
*/
|
|
const app = getApp()
|
|
const api = require('../../utils/api')
|
|
const util = require('../../utils/util')
|
|
|
|
Page({
|
|
data: {
|
|
domain: {},
|
|
activeContent: null,
|
|
isPlaying: false,
|
|
isVip: false,
|
|
isLiked: false,
|
|
currentTime: 0,
|
|
duration: 0,
|
|
currentTimeText: '00:00',
|
|
durationText: '00:00',
|
|
displayDate: '',
|
|
playbackRate: 1.0,
|
|
statusBarHeight: 0,
|
|
showTranscript: false,
|
|
// 评论弹层
|
|
showComments: false,
|
|
commentList: [],
|
|
commentText: '',
|
|
commentLoading: false,
|
|
submitting: false
|
|
},
|
|
|
|
_isSeeking: false,
|
|
|
|
|
|
onLoad() {
|
|
},
|
|
|
|
onShow() {
|
|
this._syncState()
|
|
|
|
// 监听播放状态
|
|
this._onPlayerChange = (state) => {
|
|
if (this._isSeeking) return
|
|
this.setData({
|
|
activeContent: state.activeContent,
|
|
isPlaying: state.isPlaying,
|
|
playbackRate: state.playbackRate
|
|
})
|
|
this._updateDomain()
|
|
}
|
|
|
|
// 监听时间更新
|
|
this._onTimeUpdate = (data) => {
|
|
if (this._isSeeking) return
|
|
this.setData({
|
|
currentTime: data.currentTime,
|
|
duration: data.duration || this.data.duration,
|
|
currentTimeText: util.formatTime(data.currentTime),
|
|
durationText: util.formatTime(data.duration || this.data.duration)
|
|
})
|
|
}
|
|
|
|
app.on('playerStateChange', this._onPlayerChange)
|
|
app.on('timeUpdate', this._onTimeUpdate)
|
|
|
|
// 查询当前节目点赞状态
|
|
this._loadLikeStatus()
|
|
},
|
|
|
|
onHide() {
|
|
if (this._onPlayerChange) app.off('playerStateChange', this._onPlayerChange)
|
|
if (this._onTimeUpdate) app.off('timeUpdate', this._onTimeUpdate)
|
|
},
|
|
|
|
/**
|
|
* 同步当前状态
|
|
*/
|
|
_syncState() {
|
|
const gd = app.globalData
|
|
const content = gd.activeContent
|
|
|
|
if (!content) {
|
|
wx.navigateBack()
|
|
return
|
|
}
|
|
|
|
var dateStr = ''
|
|
if (content.createdAt) {
|
|
dateStr = content.createdAt.substring(0, 10).replace(/-/g, '.')
|
|
} else if (content.date) {
|
|
dateStr = util.dateToDot(content.date)
|
|
}
|
|
|
|
this.setData({
|
|
activeContent: content,
|
|
isPlaying: gd.isPlaying,
|
|
isVip: gd.isVip,
|
|
currentTime: gd.currentTime,
|
|
duration: gd.duration || content.duration,
|
|
currentTimeText: util.formatTime(gd.currentTime),
|
|
durationText: util.formatTime(gd.duration || content.duration),
|
|
displayDate: dateStr,
|
|
playbackRate: gd.playbackRate,
|
|
statusBarHeight: gd.statusBarHeight || 0
|
|
})
|
|
|
|
this._updateDomain()
|
|
},
|
|
|
|
/**
|
|
* 获取频道信息
|
|
*/
|
|
_updateDomain() {
|
|
const content = this.data.activeContent
|
|
if (!content) return
|
|
|
|
var channelId = content.channelId || (content.channel && content.channel.id)
|
|
if (!channelId) {
|
|
if (content.channel) {
|
|
this.setData({ domain: content.channel })
|
|
}
|
|
return
|
|
}
|
|
|
|
if (this.data.domain && this.data.domain.id === channelId) return
|
|
|
|
var self = this
|
|
api.getChannelDetail(channelId).then(function (res) {
|
|
if (res.code === 200 && res.data) {
|
|
self.setData({ domain: res.data })
|
|
}
|
|
}).catch(function (err) {
|
|
console.error('[Player] 获取频道信息失败:', err)
|
|
})
|
|
},
|
|
|
|
/**
|
|
* 查询当前节目点赞状态
|
|
*/
|
|
_loadLikeStatus() {
|
|
const content = this.data.activeContent
|
|
if (!content) return
|
|
var self = this
|
|
api.getProgramDetail(content.id).then(function (res) {
|
|
if (res.code === 200 && res.data) {
|
|
self.setData({ isLiked: !!res.data.isLiked })
|
|
}
|
|
}).catch(function () { })
|
|
},
|
|
|
|
/**
|
|
* 播放/暂停
|
|
*/
|
|
onTogglePlay() {
|
|
app.togglePlay()
|
|
},
|
|
|
|
/**
|
|
* 进度条拖动中
|
|
*/
|
|
onSliderChanging(e) {
|
|
this._isSeeking = true
|
|
this.setData({
|
|
currentTime: e.detail.value,
|
|
currentTimeText: util.formatTime(e.detail.value)
|
|
})
|
|
},
|
|
|
|
/**
|
|
* 进度条拖动完成 → 跳转播放
|
|
*/
|
|
onSliderChange(e) {
|
|
this._isSeeking = false
|
|
app.seekTo(e.detail.value)
|
|
},
|
|
|
|
/**
|
|
* 快退 15 秒
|
|
*/
|
|
onBackward() {
|
|
const newTime = Math.max(0, this.data.currentTime - 15)
|
|
app.seekTo(newTime)
|
|
},
|
|
|
|
/**
|
|
* 快进 15 秒
|
|
*/
|
|
onForward() {
|
|
const newTime = Math.min(this.data.duration, this.data.currentTime + 15)
|
|
app.seekTo(newTime)
|
|
},
|
|
|
|
/**
|
|
* 倍速设置(VIP 功能)
|
|
*/
|
|
onSpeed() {
|
|
if (!this.data.isVip) {
|
|
wx.showModal({
|
|
title: '会员提示',
|
|
content: '倍速播放是会员专属功能,是否前往开通?',
|
|
success: (res) => {
|
|
if (res.confirm) {
|
|
wx.navigateTo({ url: '/pages/vip/index' })
|
|
}
|
|
}
|
|
})
|
|
} else {
|
|
this.setData({ showSpeedSheet: true })
|
|
}
|
|
},
|
|
|
|
onSpeedSelect(e) {
|
|
const label = this.data.speedItems[e.detail.index].label
|
|
const rate = parseFloat(label)
|
|
app.setPlaybackRate(rate)
|
|
this.setData({ showSpeedSheet: false, playbackRate: rate })
|
|
},
|
|
|
|
onSpeedCancel() {
|
|
this.setData({ showSpeedSheet: false })
|
|
},
|
|
|
|
/**
|
|
* 下载(VIP 功能)
|
|
*/
|
|
onDownload() {
|
|
if (!this.data.isVip) {
|
|
wx.showModal({
|
|
title: '会员提示',
|
|
content: '音频下载是会员专属功能,是否前往开通?',
|
|
success: (res) => {
|
|
if (res.confirm) {
|
|
wx.navigateTo({ url: '/pages/vip/index' })
|
|
}
|
|
}
|
|
})
|
|
} else {
|
|
wx.showToast({ title: '下载功能开发中', icon: 'none' })
|
|
}
|
|
},
|
|
|
|
/**
|
|
* 查看文案
|
|
*/
|
|
onTranscript() {
|
|
const content = this.data.activeContent
|
|
if (content && content.content) {
|
|
wx.showModal({
|
|
title: '完整文案',
|
|
content: content.content,
|
|
showCancel: false
|
|
})
|
|
}
|
|
},
|
|
|
|
/**
|
|
* 点击中央 Banner:封面 ⇔ 文案切换
|
|
*/
|
|
onBannerTap() {
|
|
this.setData({ showTranscript: !this.data.showTranscript })
|
|
},
|
|
|
|
onLike() {
|
|
const content = this.data.activeContent
|
|
if (!content) return
|
|
const self = this
|
|
const wasLiked = this.data.isLiked
|
|
// 乐观更新
|
|
this.setData({ isLiked: !wasLiked })
|
|
api.toggleLike(content.id).then(function (res) {
|
|
if (res.code !== 200) {
|
|
// 回滚
|
|
self.setData({ isLiked: wasLiked })
|
|
wx.showToast({ title: res.msg || '操作失败', icon: 'none' })
|
|
} else {
|
|
wx.showToast({ title: wasLiked ? '已取消喜欢' : '已喜欢 ♥', icon: 'none' })
|
|
}
|
|
}).catch(function () {
|
|
self.setData({ isLiked: wasLiked })
|
|
wx.showToast({ title: '网络异常', icon: 'none' })
|
|
})
|
|
},
|
|
|
|
// ===== 评论弹层 =====
|
|
|
|
onOpenComments() {
|
|
this.setData({ showComments: true })
|
|
this._loadComments()
|
|
},
|
|
|
|
onCloseComments() {
|
|
this.setData({ showComments: false, commentText: '' })
|
|
},
|
|
|
|
_loadComments() {
|
|
const content = this.data.activeContent
|
|
if (!content) return
|
|
const self = this
|
|
this.setData({ commentLoading: true })
|
|
api.getCommentList(content.id, { current: 1, pageSize: 30 }).then(function (res) {
|
|
if (res.code === 200 && res.data) {
|
|
var list = (res.data.list || res.data || []).map(function (c) {
|
|
return Object.assign({}, c, {
|
|
_isOwn: c.userId === (getApp().globalData.userInfo && getApp().globalData.userInfo.id)
|
|
})
|
|
})
|
|
self.setData({ commentList: list, commentLoading: false })
|
|
} else {
|
|
self.setData({ commentLoading: false })
|
|
}
|
|
}).catch(function () {
|
|
self.setData({ commentLoading: false })
|
|
})
|
|
},
|
|
|
|
onCommentInput(e) {
|
|
this.setData({ commentText: e.detail.value })
|
|
},
|
|
|
|
onSubmitComment() {
|
|
const text = (this.data.commentText || '').trim()
|
|
if (!text) return
|
|
const content = this.data.activeContent
|
|
if (!content) return
|
|
const self = this
|
|
this.setData({ submitting: true })
|
|
api.addComment(content.id, text).then(function (res) {
|
|
self.setData({ submitting: false, commentText: '' })
|
|
if (res.code === 200) {
|
|
wx.showToast({ title: '发布成功', icon: 'none' })
|
|
self._loadComments()
|
|
} else {
|
|
wx.showToast({ title: res.msg || '发布失败', icon: 'none' })
|
|
}
|
|
}).catch(function () {
|
|
self.setData({ submitting: false })
|
|
wx.showToast({ title: '网络异常', icon: 'none' })
|
|
})
|
|
},
|
|
|
|
onDeleteComment(e) {
|
|
const id = e.currentTarget.dataset.id
|
|
const self = this
|
|
wx.showModal({
|
|
title: '提示',
|
|
content: '确认删除该评论吗?',
|
|
success(res) {
|
|
if (!res.confirm) return
|
|
api.deleteComment(id).then(function (r) {
|
|
if (r.code === 200) {
|
|
self._loadComments()
|
|
} else {
|
|
wx.showToast({ title: '删除失败', icon: 'none' })
|
|
}
|
|
})
|
|
}
|
|
})
|
|
},
|
|
|
|
onShare() {
|
|
wx.showToast({ title: '分享功能开发中', icon: 'none' })
|
|
},
|
|
|
|
goBack() {
|
|
wx.navigateBack()
|
|
}
|
|
})
|