app/components/vlog/videoDetail.nvue

694 lines
18 KiB
Plaintext
Raw Normal View History

2025-03-14 16:27:50 +08:00
<template>
<view style="flex: 1">
<list
:pagingEnabled="true"
:show-scrollbar="false"
@scroll="listScroll"
@scrollend="scroll"
:scrollable="true">
<cell
:recycle="false"
v-for="(item, index) in playerList"
:key="index"
:data-index="index"
:style="{ height: screenHeight + 'px' }">
<video
ref="videoDetail"
id="videoDetail"
:object-fit="item.width >= item.height ? 'contain' : 'fill'"
:src="item.url"
:controls="false"
:enable-progress-gesture="false"
v-if="playerCur === index"
loop
autoplay
show-loading="true"
style="width: 750rpx"
:style="{ height: screenHeight + 'px' }"
@click="playOrPause"
@play="onplay"
@error="onerror"
@timeupdate="timeupdate"></video>
<image
:lazy-load="true"
:fade-show="false"
v-if="!item.play"
:src="item.cover"
:mode="item.width >= item.height ? 'aspectFit' : 'scaleToFill'"
style="width: 750rpx; filter: blur(10px)"
:style="{ height: screenHeight + 'px' }"></image>
<view class="publish-info-box">
<view class="">
<text class="publish-info-vloger-name">@{{ item.vlogerName }}</text>
<text class="publish-info-content">{{ item.content }}</text>
<view class="publish-info-music-box">
<image
src="/static/images/icon-fire.png"
class="icon-fire"></image>
<text class="muisc-words">{{ item.vlogerName }}的原声创作</text>
</view>
</view>
<view class="" style="flex-direction: row">
<image src="/static/images/cd-play-4.gif"
style="width: 150rpx;height: 150rpx;opacity: 0.8;"></image>
<image
v-if="!isIOS"
src="/static/images/icon-cd.png"
class="play-cd"
style="width: 120rpx; height: 120rpx"></image>
<image
v-if="isIOS"
:src="
'https://imooc-news.oss-cn-shanghai.aliyuncs.com/image/cd-play-4.gif?time=' +
times
"
class="play-cd"></image>
</view>
</view>
<!-- 视频展示右侧的操作按钮, 头像 - 点赞 - 评论 - 转发 -->
<view class="operation-box">
<view class="operation-face-box">
<image
:src="item.vlogerFace"
class="user-face"
@click="goUserInfoSeeSee(item.vlogerId)"></image>
</view>
<image
v-if="!item.doIFollowVloger && userId != item.vlogerId"
src="/static/images/icon-follow.png"
@click="followMe(item.vlogerId)"
class="follow-me"></image>
<view class="like-box">
<image
v-if="!item.doILikeThisVlog"
src="/static/images/icon-unlike.png"
@click="likeOrDislikeVlog(1)"
class="icon"></image>
<image
v-if="item.doILikeThisVlog"
src="/static/images/icon-like.png"
@click="likeOrDislikeVlog(0)"
class="icon"></image>
<text class="some-counts">{{ item.likeCounts }}</text>
</view>
<view class="comment-and-share-box">
<image
src="/static/images/icon-comments.png"
@click="commentToggle"
class="icon"></image>
<text class="some-counts">{{ thisVlogTotalComentCounts }}</text>
</view>
<view class="comment-and-share-box">
<image
src="/static/images/icon-share.png"
@click="shareToggle"
class="icon"></image>
<text class="some-counts">分享</text>
</view>
</view>
</cell>
</list>
<!-- </uni-list> -->
<view v-if="thisVlog != null && thisVlog != {}">
<uni-popup ref="comment" type="comment">
<uni-popup-comments
:thisVlogerId="thisVlogerId"
:thisVlogId="thisVlogId"></uni-popup-comments>
</uni-popup>
<uni-popup ref="share" background-color="#fff" type="share">
<uni-popup-share
:thisVlogerId="thisVlogerId"
:thisVlogId="thisVlogId"
:vlogUrl="thisVlog.url"
:isPrivate="thisVlog.isPrivate"></uni-popup-share>
</uni-popup>
</view>
</view>
</template>
<script>
let app = getApp();
export default {
props: {
screenHeight: {
default: 0,
},
src: {
default: false,
},
playStatus: {
default: false,
},
vlogId: {
default: false,
},
},
data() {
return {
thisVlog: {}, // 当前的短视频对象
thisVlogId: "", // 当前的短视频主键id
thisVlogerId: "", // 当前的短视频博主的主键id
userId: "",
playerCur: 0,
page: 0,
totalPage: 0,
// videoList:[
// {
// width:750,//视频宽
// height:300,//视频高
// play:true, // 是否自动播放
// cover:'/static/video/c1.jpg', //首帧图
// url:'/static/video/v1.mp4', // 视频地址
// vlogerName:'我是vlogerName', // 博主名称
// vlogerFace: '/static/face/face-cat.png', // 博主头像
// content:'我是content', //视频内容
// vlogerId:123,//博主id
// doIFollowVloger:false, //是否关注博主
// doILikeThisVlog:false, //是否喜欢视频
// }
// ],
playerList: this.videoList,
thisVlogTotalComentCounts: 0,
videoContext: {},
currentIndex: 0,
contentOffsetY: 0,
times: new Date().getTime(),
objectFit: "fill",
isIOS: uni.getSystemInfoSync().platform == "ios",
};
},
created() {
if (!this.isIOS) {
this.objectFit = "cover";
}
let myUserInfo = getApp().getUserInfoSession();
if (!app.isStrEmpty(myUserInfo)) {
this.userId = myUserInfo.id;
}
// 查询首页短视频列表
this.displayVideoPaging(this.page + 1, true);
let videoContext = uni.createVideoContext("videoDetail");
this.videoContext = videoContext;
},
watch: {
refreshList(value) {
let me = this;
let newList = value;
if (newList != null && newList != undefined && newList.length > 0) {
me.playerList = newList;
}
// 重置
this.playerCur = 0;
this.currentIndex = 0;
this.contentOffsetY = 0;
},
playStatus: function (val) {
let me = this;
if (!val) {
me.videoContext.pause();
} else {
me.videoContext.play();
}
},
},
methods: {
// 喜欢, 点赞的list重新设置
reLikePlayList(vlogId) {
let me = this;
let playerList = me.playerList;
for (let i = 0; i < playerList.length; i++) {
let vlog = playerList[i];
if (vlog.vlogId == vlogId) {
vlog.doILikeThisVlog = true;
playerList.splice(i, 1, vlog);
}
}
me.playerList = playerList;
},
reDislikePlayList(vlogId) {
let me = this;
let playerList = me.playerList;
for (let i = 0; i < playerList.length; i++) {
let vlog = playerList[i];
if (vlog.vlogId == vlogId) {
vlog.doILikeThisVlog = false;
playerList.splice(i, 1, vlog);
}
}
me.playerList = playerList;
},
reChangeVlogLikedCountsInPlayList(vlogId, counts) {
let me = this;
let playerList = me.playerList;
for (let i = 0; i < playerList.length; i++) {
let vlog = playerList[i];
if (vlog.vlogId == vlogId) {
vlog.likeCounts = counts;
playerList.splice(i, 1, vlog);
}
}
me.playerList = playerList;
},
refreshVlogCounts() {
// 查询当前点赞数, 重新赋值给当前视频
let me = this;
let serverUrl = app.globalData.serverUrl;
let currentIndex = me.playerCur;
let vlog = me.playerList[currentIndex];
uni.request({
method: "POST",
url: serverUrl + "/vlog/totalLikedCounts?vlogId=" + vlog.vlogId,
success(result) {
if (result.data.status == 2095) {
let counts = result.data.data;
me.reChangeVlogLikedCountsInPlayList(vlog.vlogId, counts);
} else {
uni.showToast({
title: result.data.msg,
duration: 3000,
icon: "none",
});
}
},
});
},
likeOrDislikeVlog(isLike) {
let me = this;
if (isLike == 1) {
// 点赞视频
let myUserInfo = getApp().getUserInfoSession();
if (app.isStrEmpty(myUserInfo)) {
2025-03-15 10:09:26 +08:00
2025-03-14 16:27:50 +08:00
uni.navigateTo({
2025-03-15 10:09:26 +08:00
url: "/pages/passport/login",
2025-03-14 16:27:50 +08:00
animationType: "slide-in-bottom",
2025-03-15 10:09:26 +08:00
2025-03-14 16:27:50 +08:00
});
return;
}
let userId = myUserInfo.id;
let serverUrl = app.globalData.serverUrl;
let currentIndex = me.playerCur;
let vlog = me.playerList[currentIndex];
uni.request({
method: "POST",
header: {
headerUserId: userId,
headerUserToken: app.getUserSessionToken(),
},
url:
serverUrl +
"/vlog/like?userId=" +
userId +
"&vlogerId=" +
vlog.vlogerId +
"&vlogId=" +
vlog.vlogId,
success(result) {
if (result.data.status == 2093) {
me.reLikePlayList(vlog.vlogId);
me.refreshVlogCounts();
} else {
uni.showToast({
title: result.data.msg,
icon: "none",
duration: 3000,
});
}
},
});
} else if (isLike == 0) {
let myUserInfo = getApp().getUserInfoSession();
if (app.isStrEmpty(myUserInfo)) {
2025-03-15 10:09:26 +08:00
2025-03-14 16:27:50 +08:00
uni.navigateTo({
2025-03-15 10:09:26 +08:00
url: "/pages/passport/login",
2025-03-14 16:27:50 +08:00
animationType: "slide-in-bottom",
2025-03-15 10:09:26 +08:00
2025-03-14 16:27:50 +08:00
});
return;
}
let userId = myUserInfo.id;
let serverUrl = app.globalData.serverUrl;
let currentIndex = me.playerCur;
let vlog = me.playerList[currentIndex];
uni.request({
method: "POST",
header: {
headerUserId: userId,
headerUserToken: app.getUserSessionToken(),
},
url:
serverUrl +
"/vlog/unlike?userId=" +
userId +
"&vlogerId=" +
vlog.vlogerId +
"&vlogId=" +
vlog.vlogId,
success(result) {
if (result.data.status == 2094) {
me.reDislikePlayList(vlog.vlogId);
me.refreshVlogCounts();
} else {
uni.showToast({
title: result.data.msg,
icon: "none",
duration: 3000,
});
}
},
});
}
},
// 关注后的list重新设置
reFollowPlayList(vlogerId) {
let me = this;
let playerList = me.playerList;
for (let i = 0; i < playerList.length; i++) {
let vlog = playerList[i];
if (vlog.vlogerId == vlogerId) {
vlog.doIFollowVloger = true;
playerList.splice(i, 1, vlog);
}
}
me.playerList = playerList;
},
// 取关后的list重新设置
reCancelPlayList(vlogerId) {
let me = this;
let playerList = me.playerList;
for (let i = 0; i < playerList.length; i++) {
let vlog = playerList[i];
if (vlog.vlogerId == vlogerId) {
vlog.doIFollowVloger = false;
playerList.splice(i, 1, vlog);
}
}
me.playerList = playerList;
},
// 关注博主
followMe(vlogerId) {
let me = this;
let myUserInfo = getApp().getUserInfoSession();
if (app.isStrEmpty(myUserInfo)) {
uni.navigateTo({
2025-03-15 10:09:26 +08:00
url: "/pages/passport/login",
animationType: "slide-in-bottom"
2025-03-14 16:27:50 +08:00
});
return;
}
let userId = myUserInfo.id;
let serverUrl = app.globalData.serverUrl;
uni.request({
method: "POST",
header: {
headerUserId: userId,
headerUserToken: app.getUserSessionToken(),
},
url:
serverUrl + "/fans/follow?myId=" + userId + "&vlogerId=" + vlogerId,
success(result) {
if (result.data.status == 208) {
me.reFollowPlayList(vlogerId);
} else {
uni.showToast({
title: result.data.msg,
icon: "none",
duration: 3000,
});
}
},
});
},
goUserInfoSeeSee(userId) {
// 是否是当前登录的用户
let myUserId = "";
if (!app.isStrEmpty(app.getUserInfoSession())) {
myUserId = app.getUserInfoSession().id;
}
if (myUserId == userId) {
uni.switchTab({
url: "/pages/me/me",
});
} else {
uni.navigateTo({
url: "/pages/me/vlogerInfo?userPageId=" + userId,
});
}
},
downloadVlog() {
var me = this;
var serverUrl = app.globalData.serverUrl;
var currentIndex = me.playerCur;
var vlog = me.playerList[currentIndex];
var pendingLength = vlog.url;
},
onplay: function (e) {
if (uni.getSystemInfoSync().platform == "ios") {
this.doplay(0.1);
}
},
timeupdate: function (e) {
if (e.detail.currentTime > 0.2) {
this.doplay(e.detail.currentTime);
}
},
playOrPause() {
let me = this;
let playStatus = this.playStatus;
if (!playStatus) {
me.videoContext.pause();
} else {
me.videoContext.play();
}
this.playStatus = !playStatus;
},
displayVideoPaging(page, needClearList) {
let me = this;
let vlogId = me.vlogId;
let myUserInfo = getApp().getUserInfoSession();
let userId = "";
if (!app.isStrEmpty(myUserInfo)) {
userId = myUserInfo.id;
}
let serverUrl = app.globalData.serverUrl;
uni.request({
method: "GET",
url: serverUrl + "/vlog/detail?userId=" + userId + "&vlogId=" + vlogId,
success(result) {
if (result.data.status == 207) {
let vlog = result.data.data;
let playerList = [];
playerList.push(vlog);
me.playerList = playerList;
me.freshCommentCounts();
me.setThisVlogInfo();
} else {
uni.showToast({
title: result.data.msg,
icon: "none",
duration: 3000,
});
}
},
});
},
doplay: function (time) {
if (time > 0) {
this.playerList[this.playerCur].play = true;
}
},
onchange: function (index) {
if (index != this.playerCur) {
this.playerList[this.playerCur].play = false;
this.playerCur = index;
}
this.setThisVlogInfo();
},
// 设置当前vlog的信息
setThisVlogInfo() {
let me = this;
let serverUrl = app.globalData.serverUrl;
if (
me.playerList != null &&
me.playerList != undefined &&
me.playerList.length > 0
) {
let currentIndex = me.playerCur;
let vlog = me.playerList[currentIndex];
this.thisVlog = vlog;
this.thisVlogId = vlog.vlogId;
this.thisVlogerId = vlog.vlogerId;
}
},
freshCommentCounts() {
var me = this;
var userId = getApp().getUserInfoSession().id;
var serverUrl = app.globalData.serverUrl;
if (
me.playerList == null ||
me.playerList == undefined ||
me.playerList.length == 0
) {
return;
}
var currentIndex = me.playerCur;
var vlog = me.playerList[currentIndex];
var vlogId = vlog.vlogId;
var serverUrl = app.globalData.serverUrl;
uni.request({
method: "GET",
url: serverUrl + "/comment/counts?vlogId=" + vlogId,
success(result) {
if (result.data.status == 200) {
me.thisVlogTotalComentCounts = result.data.data;
} else {
me.thisVlogTotalComentCounts = 0;
}
},
});
},
commentToggle() {
this.$refs.comment.open();
uni.hideTabBar({
animation: true,
});
},
shareToggle() {
this.$refs.share.open();
uni.hideTabBar({
animation: true,
});
},
},
};
</script>
<style lang="scss">
.icon {
width: 80rpx;
height: 80rpx;
opacity: 0.9;
}
.user-face {
width: 100rpx;
height: 100rpx;
border-radius: 100rpx;
}
.play-cd {
width: 150rpx;
height: 150rpx;
opacity: 0.8;
}
.refresh-info-txt {
color: #f1f1f1;
text-align: center;
font-size: 12px;
}
.publish-info-box {
position: absolute;
bottom: 200rpx;
left: 0;
right: 0;
padding-left: 20rpx;
padding-right: 20rpx;
flex-direction: row;
justify-content: space-between;
align-items: center;
}
.publish-info-vloger-name {
color: #ffffff;
font-size: 40rpx;
font-weight: 600;
padding: 10rpx;
}
.publish-info-music-box {
flex-direction: row;
align-items: center;
}
.publish-info-content {
color: #ffffff;
font-size: 28rpx;
font-weight: 400;
padding: 10rpx;
lines: 5;
width: 520rpx;
text-overflow: ellipsis;
}
.icon-fire {
width: 36rpx;
height: 36rpx;
}
.muisc-words {
color: #ffffff;
font-size: 28rpx;
padding: 10rpx;
width: 400rpx;
}
.some-counts {
font-size: 24rpx;
font-weight: 500;
text-align: center;
color: #ffffff;
margin-top: 2rpx;
}
.operation-box {
position: absolute;
top: 0;
bottom: 0;
right: 0;
align-items: center;
justify-content: center;
padding-right: 20rpx;
}
.operation-face-box {
border-radius: 100rpx;
border-color: #ffffff;
border-width: 3rpx;
}
.follow-me {
width: 40rpx;
height: 40rpx;
border-radius: 10px;
position: relative;
top: -20rpx;
}
.like-box {
flex-direction: column;
align-items: center;
margin-top: 30rpx;
}
.comment-and-share-box {
flex-direction: column;
align-items: center;
margin-top: 45rpx;
}
</style>