Browse Source

长视频

pull/40/head
zyronon 1 year ago
parent
commit
43507e9138
  1. 13318
      src/assets/data/resource.js
  2. 1824
      src/assets/data/user.json
  3. 4
      src/components/Posters.vue
  4. 71
      src/components/UserPanel.vue
  5. 23
      src/components/slide/BVideo.vue
  6. 6
      src/pages/home/components/FollowSetting.vue
  7. 15
      src/pages/home/components/FollowSetting2.vue
  8. 2
      src/pages/home/components/IndicatorHome.vue
  9. 28
      src/pages/home/index.vue
  10. 86
      src/pages/home/slide/LongVideo.vue
  11. 24
      src/pages/home/slide/SlideList.vue
  12. 13
      src/utils/index.jsx

13318
src/assets/data/resource.js

File diff suppressed because it is too large Load Diff

1824
src/assets/data/user.json

File diff suppressed because it is too large Load Diff

4
src/components/Posters.vue

@ -21,7 +21,7 @@ @@ -21,7 +21,7 @@
</template>
<script>
import {$checkImgUrl, $no} from "@/utils";
import {_checkImgUrl, $no} from "@/utils";
export default {
/*@click="$nav('/video-detail')"*/
@ -40,7 +40,7 @@ export default { @@ -40,7 +40,7 @@ export default {
},
methods: {
$no,
$checkImgUrl,
$checkImgUrl: _checkImgUrl,
getDay(time) {
let date = new Date(time * 1000)
return date.getDate()

71
src/components/UserPanel.vue

@ -3,8 +3,8 @@ @@ -3,8 +3,8 @@
@scroll="scroll"
ref="page">
<div ref="float" class="float" :class="state.floatFixed?'fixed':''">
<div class="left" @click="$emit('back')">
<Icon class="icon" icon="eva:arrow-ios-back-fill"/>
<div class="left">
<Icon @click="$emit('back')" class="icon" icon="eva:arrow-ios-back-fill"/>
<transition name="fade">
<div class="float-user" v-if="state.floatFixed">
<img v-lazy="Utils.$imgPreview(props.currentItem.author.avatar_168x168.url_list[0])" class="avatar"/>
@ -21,7 +21,7 @@ @@ -21,7 +21,7 @@
<span>求更新</span>
</div>
</transition>
<Icon class="icon" icon="ion:search"/>
<Icon class="icon" icon="ion:search" @click.stop="$no()"/>
<Icon class="icon" icon="ri:more-line" @click.stop="$emit('showFollowSetting')"/>
</div>
</div>
@ -35,21 +35,21 @@ @@ -35,21 +35,21 @@
<img
:style="{opacity:props.currentItem.author.cover_url[0].url_list.length?1:0}"
ref="cover"
:src="$checkImgUrl(props.currentItem.author.cover_url[0].url_list[0])"
@click="state.previewImg = $checkImgUrl(props.currentItem.author.cover_url[0].url_list[0])"
:src="_checkImgUrl(props.currentItem.author.cover_url[0].url_list[0])"
@click="state.previewImg = _checkImgUrl(props.currentItem.author.cover_url[0].url_list[0])"
alt=""
class="cover">
<div class="avatar-wrapper">
<img v-lazy="$checkImgUrl(props.currentItem.author.avatar_168x168.url_list[0])" class="avatar"
@click="state.previewImg = $checkImgUrl(props.currentItem.author.avatar_300x300.url_list[0])">
<img v-lazy="_checkImgUrl(props.currentItem.author.avatar_168x168.url_list[0])" class="avatar"
@click="state.previewImg = _checkImgUrl(props.currentItem.author.avatar_300x300.url_list[0])">
<div class="description">
<div class="name f22 mb1r">{{ props.currentItem.author.nickname }}</div>
<div class="name f22">{{ props.currentItem.author.nickname }}</div>
<div class="certification" v-if="props.currentItem.author.certification ">
<img src="@/assets/img/icon/me/certification.webp">
{{ props.currentItem.author.certification }}
</div>
<div class="number" v-else>
<span>抖音号{{ props.currentItem.author.unique_id || props.currentItem.author.short_id }}</span>
<span>抖音号{{ _getUserDouyinId(props.currentItem) }}</span>
<img src="@/assets/img/icon/me/copy.png" alt=""
@click.stop="Utils.copy(props.currentItem.author.unique_id || props.currentItem.author.short_id)">
</div>
@ -120,7 +120,7 @@ @@ -120,7 +120,7 @@
<div class="followed">
<div class="l-button" @click="$emit('showFollowSetting2')">
<span>已关注</span>
<img src="@/assets/img/icon/arrow-up-white.png" alt="">
<Icon icon="bxs:down-arrow" class="arrow"/>
</div>
<div class="l-button" @click="$nav('/message/chat')">
<span>私信</span>
@ -133,7 +133,7 @@ @@ -133,7 +133,7 @@
@click="state.isShowRecommend = !state.isShowRecommend">
<img v-if="state.loadings.showRecommend" class="loading" src="@/assets/img/icon/loading-gray.png"
alt="">
<img v-else class="arrow" src="@/assets/img/icon/arrow-up-white.png" alt="">
<Icon icon="bxs:down-arrow" v-else class="arrow"/>
</div>
</div>
@ -145,7 +145,7 @@ @@ -145,7 +145,7 @@
<div class="friends"
@touchmove="stop">
<div class="friend" v-for="item in friends.all">
<img :style="item.select?'opacity: .5;':''" class="avatar" :src="$checkImgUrl(item.avatar)" alt="">
<img :style="item.select?'opacity: .5;':''" class="avatar" :src="_checkImgUrl(item.avatar)" alt="">
<span class="name">{{ item.name }}</span>
<span class="tips">可能感兴趣的人</span>
<dy-button type="primary">关注</dy-button>
@ -176,7 +176,7 @@ @@ -176,7 +176,7 @@
<script setup>
import {computed, onMounted, reactive, ref, watch} from "vue";
import Utils, {$checkImgUrl} from "@/utils";
import Utils, {_checkImgUrl, $no, _getUserDouyinId} from "@/utils";
import {useNav} from "@/utils/hooks/useNav";
import {useStore} from "vuex";
import resource from "@/assets/data/resource";
@ -232,7 +232,7 @@ const state = reactive({ @@ -232,7 +232,7 @@ const state = reactive({
lastMoveYDistance: 0,
canTransformY: 0,
startTime: 0,
floatHeight: 46,
floatHeight: 52,
videos: {
my: {
list: [],
@ -274,7 +274,7 @@ const state = reactive({ @@ -274,7 +274,7 @@ const state = reactive({
start: {x: 0, y: 0, time: 0},
move: {x: 0, y: 0},
isTop: false,
coverHeight: 240,
coverHeight: 220,
//
canMoveMaxHeight: document.body.clientHeight / 4,
//Cover
@ -320,7 +320,7 @@ function scroll(e) { @@ -320,7 +320,7 @@ function scroll(e) {
// console.log('scroll', page.value.scrollTop)
let scrollTop = page.value.scrollTop
let totalY = total.value.getBoundingClientRect().y
state.floatFixed = totalY <= 46
state.floatFixed = totalY <= state.floatHeight
let isTop = scrollTop === 0
if (isTop && state.isAutoScaleCover) {
cover.value.style.transition = 'all .1s'
@ -576,7 +576,7 @@ function touchEnd(e) { @@ -576,7 +576,7 @@ function touchEnd(e) {
color: white;
.cover {
height: 240rem;
height: 220rem;
object-fit: cover;
width: 100vw;
//transition: height .3s;
@ -594,10 +594,11 @@ function touchEnd(e) { @@ -594,10 +594,11 @@ function touchEnd(e) {
.avatar {
background: white;
padding: 2px;
padding: 2.5px;
border-radius: 50%;
width: 80rem;
height: 80rem;
@w: 100rem;
width: @w;
height: @w;
}
.description {
@ -750,6 +751,8 @@ function touchEnd(e) { @@ -750,6 +751,8 @@ function touchEnd(e) {
justify-content: flex-end;
align-items: center;
@width: 36rem;
@gap: 6rem;
gap: @gap;
.follow-display {
flex: 1;
@ -774,7 +777,6 @@ function touchEnd(e) { @@ -774,7 +777,6 @@ function touchEnd(e) {
display: flex;
align-items: center;
justify-content: center;
margin-right: 5rem;
box-sizing: border-box;
span {
@ -787,26 +789,19 @@ function touchEnd(e) { @@ -787,26 +789,19 @@ function touchEnd(e) {
display: flex;
justify-content: space-around;
align-items: center;
gap: @gap;
.l-button {
color: white;
border-radius: 4rem;
border-radius: 5rem;
background: @second-btn-color;
height: @width;
width: 50%;
margin-right: 5rem;
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: center;
span {
margin-left: 2rem;
}
img {
transform: rotate(180deg);
}
gap: @gap;
}
}
}
@ -832,7 +827,7 @@ function touchEnd(e) { @@ -832,7 +827,7 @@ function touchEnd(e) {
&.option-recommend {
.arrow {
transform: rotate(0deg);
transform: rotate(180deg);
}
}
}
@ -855,10 +850,7 @@ function touchEnd(e) { @@ -855,10 +850,7 @@ function touchEnd(e) {
.arrow {
transition: transform .3s ease;
transform: rotate(180deg);
@width: 16rem;
width: @width;
height: @width;
font-size: 13rem;
}
}
@ -900,6 +892,7 @@ function touchEnd(e) { @@ -900,6 +892,7 @@ function touchEnd(e) {
display: flex;
flex-direction: column;
align-items: center;
border-radius: 10rem;
.avatar {
@width: 100rem;
@ -956,7 +949,7 @@ function touchEnd(e) { @@ -956,7 +949,7 @@ function touchEnd(e) {
padding: 15rem 20rem;
padding-top: 0rem;
position: sticky;
top: 46rem;
top: 52rem;
z-index: 2;
img {
@ -980,7 +973,7 @@ function touchEnd(e) { @@ -980,7 +973,7 @@ function touchEnd(e) {
display: flex;
justify-content: space-between;
align-items: center;
height: 46rem;
height: 52rem;
padding: 0 15rem;
background: transparent;
transition: all .2s;
@ -999,7 +992,7 @@ function touchEnd(e) { @@ -999,7 +992,7 @@ function touchEnd(e) {
border-radius: 50%;
background: rgba(82, 80, 80, 0.5);
padding: 6rem;
font-size: 16rem;
font-size: 18rem;
}
.left {

23
src/components/slide/BVideo.vue

@ -4,7 +4,7 @@ @@ -4,7 +4,7 @@
<!-- <video :src="item.video + '?v=123'"-->
<video
:src="item.video.play_addr.url_list[0]"
:poster="$checkImgUrl(item.video.cover.url_list[0])"
:poster="_checkImgUrl(item.video.cover.url_list[0])"
ref="video"
muted
preload
@ -58,16 +58,18 @@ @@ -58,16 +58,18 @@
<span class="currentTime">{{ LUtils.$duration(currentTime) }}</span>
<span class="duration"> / {{ LUtils.$duration(duration) }}</span>
</div>
<div class="bg"></div>
<div class="progress-line" :style="durationStyle"></div>
<div class="point" v-if="duration > 15 || isMove"></div>
<template v-if="duration > 15 || isMove">
<div class="bg"></div>
<div class="progress-line" :style="durationStyle"></div>
<div class="point"></div>
</template>
</div>
</div>
</div>
</template>
<script>
import Utils, {$checkImgUrl} from '../../utils'
import Utils, {_checkImgUrl} from '../../utils'
import Loading from "../Loading";
import ItemToolbar from "./ItemToolbar";
import ItemDesc from "./ItemDesc";
@ -241,7 +243,7 @@ export default { @@ -241,7 +243,7 @@ export default {
bus.off(EVENT_KEY.CLOSE_SUB_TYPE, this.onCloseSubType)
},
methods: {
$checkImgUrl,
_checkImgUrl,
onOpenSubType() {
this.commentVisible = true
},
@ -629,7 +631,7 @@ export default { @@ -629,7 +631,7 @@ export default {
@radius: 10rem;
@h: 1rem;
@h: 2rem;
@tr: height .3s;;
.bg {
@ -637,7 +639,7 @@ export default { @@ -637,7 +639,7 @@ export default {
position: absolute;
width: 100%;
height: @h;
background: rgba(#000, .3);
background: #4f4f4f;
border-radius: @radius;
}
@ -645,10 +647,10 @@ export default { @@ -645,10 +647,10 @@ export default {
.progress-line {
transition: @tr;
height: @h;
height: calc(@h + 0.5rem);
width: @p;
border-radius: @radius 0 0 @radius;
background: rgba(#000, .8);
background: #777777;
z-index: 1;
}
@ -688,7 +690,6 @@ export default { @@ -688,7 +690,6 @@ export default {
.bg {
height: @h;
background: rgba(#000, .8);
}
.progress-line {

6
src/pages/home/components/FollowSetting.vue

@ -11,8 +11,8 @@ @@ -11,8 +11,8 @@
<div class="follow-setting-dialog">
<div class="dialog-header">
<div class="title-wrapper">
<span class="title">{{ currentItem.user.nickname }}</span>
<span class="subtitle">抖音号{{ currentItem.user.short_id }}</span>
<span class="title">{{ currentItem.author.nickname }}</span>
<span class="subtitle">抖音号{{ _getUserDouyinId(currentItem) }}</span>
</div>
<dy-back mode="dark" img="close" direction="right" @click="cancel()"></dy-back>
</div>
@ -79,6 +79,7 @@ @@ -79,6 +79,7 @@
import FromBottomDialog from "../../../components/dialog/FromBottomDialog";
import Switches from "../../message/components/swtich/switches";
import {DefaultUser} from "@/utils/const_var";
import {_getUserDouyinId} from "@/utils";
export default {
name: "FollowSetting",
@ -107,6 +108,7 @@ export default { @@ -107,6 +108,7 @@ export default {
created() {
},
methods: {
_getUserDouyinId,
cancel(cb) {
this.$emit('update:modelValue', false)
cb && cb()

15
src/pages/home/components/FollowSetting2.vue

@ -11,8 +11,8 @@ @@ -11,8 +11,8 @@
<div class="follow-setting-dialog">
<div class="dialog-header">
<div class="title-wrapper">
<span class="title">成都验证码</span>
<span class="subtitle">私信给朋友</span>
<span class="title">{{ currentItem.author.nickname }}</span>
<span class="subtitle">抖音号{{ _getUserDouyinId(currentItem) }}</span>
</div>
<dy-back mode="dark" img="close" direction="right" @click="cancel()"></dy-back>
</div>
@ -44,6 +44,8 @@ @@ -44,6 +44,8 @@
import FromBottomDialog from "../../../components/dialog/FromBottomDialog";
import Switches from "../../message/components/swtich/switches";
import {DefaultUser} from "@/utils/const_var";
import {_getUserDouyinId} from "@/utils";
export default {
name: "FollowSetting",
@ -52,6 +54,14 @@ export default { @@ -52,6 +54,14 @@ export default {
Switches
},
props: {
currentItem: {
type: Object,
default: {
user: DefaultUser,
isRequest: false,
post: [],
}
},
modelValue: false
},
data() {
@ -64,6 +74,7 @@ export default { @@ -64,6 +74,7 @@ export default {
created() {
},
methods: {
_getUserDouyinId,
cancel(cb) {
this.$emit('update:modelValue', false)
cb && cb()

2
src/pages/home/components/IndicatorHome.vue

@ -23,7 +23,7 @@ @@ -23,7 +23,7 @@
<span>关注</span>
<img src="../../../assets/img/icon/live.webp" class="tab2-img">
</div>
<div class="tab" :class="{active:index === 3}" @click.stop="change(3)"><span>商城</span>
<div class="tab" :class="{active:index === 3}" @click.stop="change(3)"><span>长视频</span>
</div>
<div class="tab" :class="{active:index === 4}" @click.stop="change(4)"><span>推荐</span>
</div>

28
src/pages/home/index.vue

@ -174,6 +174,7 @@ @@ -174,6 +174,7 @@
v-model="state.showFollowSetting"/>
<FollowSetting2
v-model:currentItem="state.currentItem"
@cancelFollow="$refs.uploader.cancelFollow()"
v-model="state.showFollowSetting2"/>
@ -212,12 +213,11 @@ import FollowSetting2 from "@/pages/home/components/FollowSetting2.vue"; @@ -212,12 +213,11 @@ import FollowSetting2 from "@/pages/home/components/FollowSetting2.vue";
import ShareToFriend from "@/pages/home/components/ShareToFriend.vue";
import UserPanel from "@/components/UserPanel.vue";
import Community from "@/pages/home/slide/Community.vue";
import Shop from "@/pages/shop/Shop.vue";
import Slide0 from "@/pages/home/slide/Slide0.vue";
import Slide2 from "@/pages/home/slide/Slide2.vue";
import Slide4 from "@/pages/home/slide/Slide4.vue";
import {DefaultUser} from "@/utils/const_var";
import {$no} from "@/utils";
import {$no, _getUserDouyinId} from "@/utils";
import LongVideo from "@/pages/home/slide/LongVideo.vue";
const nav = useNav()
@ -231,20 +231,7 @@ const state = reactive({ @@ -231,20 +231,7 @@ const state = reactive({
baseIndex: 1,
navIndex: 4,
test: '',
recommendList: [
// {
// type: 'img',
// src: `http://douyin.ttentau.top/0.mp4?vframe/jpg/offset/0/w/${document.body.clientWidth}`
// },
// {
// type: 'user-imgs',
// src: `http://douyin.ttentau.top/0.mp4?vframe/jpg/offset/0/w/${document.body.clientWidth}`
// },
// {
// type: 'user',
// src: `http://douyin.ttentau.top/0.mp4?vframe/jpg/offset/0/w/${document.body.clientWidth}`
// },
],
recommendList: [],
isSharing: false,
canMove: true,
shareType: -1,
@ -269,14 +256,12 @@ const state = reactive({ @@ -269,14 +256,12 @@ const state = reactive({
})
function delayShowDialog(cb) {
setTimeout(() => {
cb()
}, 400)
setTimeout(cb, 400)
}
function setCurrentItem(item) {
if (state.currentItem.author.uid !== item.author.uid) {
let id = item.author.unique_id || item.author.short_id
let id = _getUserDouyinId(item)
console.log('item', id)
state.currentItem = {
...item,
@ -312,8 +297,9 @@ onMounted(() => { @@ -312,8 +297,9 @@ onMounted(() => {
bus.on(EVENT_KEY.GO_USERINFO, () => {
state.baseIndex = 2
})
bus.once(EVENT_KEY.CURRENT_ITEM, setCurrentItem)
bus.on(EVENT_KEY.CURRENT_ITEM, setCurrentItem)
})
onUnmounted(() => {
bus.offAll()
})

86
src/pages/home/slide/LongVideo.vue

@ -1,7 +1,62 @@ @@ -1,7 +1,62 @@
<script setup>
import {computed, onMounted, onUnmounted, reactive, ref} from "vue";
import {uniqueId} from "lodash";
import api from "@/api";
import {useStore} from "vuex";
import {_checkImgUrl, _duration, _formatNumber} from "@/utils";
const store = useStore()
const loading = computed(() => store.state.loading)
const p = {
onShowComments() {
console.log('onShowComments')
}
}
const listRef = ref(null)
const state = reactive({
index: 0,
list: [],
uniqueId: uniqueId('uniqueId_'),
totalSize: 0,
pageSize: 10,
pageNo: 0,
})
function loadMore() {
if (!loading.value) {
state.pageNo++
getData()
}
}
async function getData(refresh = false) {
if (loading.value) return
store.commit('setLoading', true)
let res = await api.videos.recommended({pageNo: refresh ? 0 : state.pageNo, pageSize: state.pageSize})
// console.log('getSlide4Data-', 'refresh', refresh, res)
store.commit('setLoading', false)
if (res.code === 200) {
state.totalSize = res.data.total
if (refresh) {
state.list = []
}
state.list = state.list.concat(res.data.list)
} else {
state.pageNo--
}
}
onMounted(() => {
getData()
})
onUnmounted(() => {
})
</script>
<template>
<div class="page">
<div class="item"
@ -10,22 +65,25 @@ @@ -10,22 +65,25 @@
i % 5 === 0 ? '' : (i % 2 === 1 && 'l'),
i % 5 === 0 ? '' : (i % 2 === 0 && 'r'),
]"
v-for="(item,i) in 100">
v-for="(item,i) in state.list">
<video
controls
src="@/assets/video/0.mp4"></video>
<img v-lazy="`https://cdn.seovx.com/ha/?mom=302&d=${i}`" alt="" class="poster">
:poster="_checkImgUrl(item.video.cover.url_list[0])"
:src="item.video.play_addr.url_list[0]"
></video>
<img v-lazy="_checkImgUrl(item.video.cover.url_list[0])" alt="" class="poster">
<div class="duration">{{ _duration(item.duration / 1000) }}</div>
<div class="title">
哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈
{{ item.desc }}
</div>
<div class="bottom">
<div class="l">
<img v-lazy="`https://cdn.seovx.com/ha/?mom=302&d=${i}`" alt="" class="avatar">
<div class="name">哈哈哈哈</div>
<img v-lazy="item.author.avatar_168x168.url_list[0]" alt="" class="avatar">
<div class="name">{{ item.author.nickname }}</div>
</div>
<div class="r">
<Icon icon="icon-park-outline:like"/>
<div class="num">9.2</div>
<div class="num">{{ _formatNumber(item.statistics.digg_count) }}</div>
</div>
</div>
</div>
@ -49,6 +107,7 @@ @@ -49,6 +107,7 @@
display: flex;
flex-direction: column;
gap: 8rem;
position: relative;
.poster {
border-radius: 12rem;
@ -81,12 +140,21 @@ @@ -81,12 +140,21 @@
gap: 5rem;
}
.duration {
color: white;
position: absolute;
bottom: 80rem;
right: 10rem;
font-size: 13rem;
}
.bottom {
color: gray;
.f;
font-size: 13rem;
.l {
.f;
.avatar {
@ -113,6 +181,10 @@ @@ -113,6 +181,10 @@
grid-column-end: 3;
margin: 0;
.duration {
display: none;
}
.poster {
display: none;
}

24
src/pages/home/slide/SlideList.vue

@ -54,29 +54,7 @@ const render = useSlideListItemRender({...props.cbs, ...p}) @@ -54,29 +54,7 @@ const render = useSlideListItemRender({...props.cbs, ...p})
const listRef = ref(null)
const state = reactive({
index: 0,
list: [
// {
// type: 'img',
// src: `http://douyin.ttentau.top/0.mp4?vframe/jpg/offset/0/w/${document.body.clientWidth}`,
// author: {
// unique_id: uniqueId('list_')
// }
// },
// {
// type: 'user-imgs',
// src: `http://douyin.ttentau.top/0.mp4?vframe/jpg/offset/0/w/${document.body.clientWidth}`,
// author: {
// unique_id: uniqueId('list_')
// }
// },
// {
// type: 'user',
// src: `http://douyin.ttentau.top/0.mp4?vframe/jpg/offset/0/w/${document.body.clientWidth}`,
// author: {
// unique_id: uniqueId('list_')
// }
// },
],
list: [],
uniqueId: uniqueId('uniqueId_'),
totalSize: 0,
pageSize: 10,

13
src/utils/index.jsx

@ -435,7 +435,7 @@ export function $notice(val) { @@ -435,7 +435,7 @@ export function $notice(val) {
Utils.$notice(val)
}
export function $checkImgUrl(url) {
export function _checkImgUrl(url) {
// console.log(url)
if (!url) return
//
@ -448,4 +448,15 @@ export function $checkImgUrl(url) { @@ -448,4 +448,15 @@ export function $checkImgUrl(url) {
} else {
return '/imgs/' + url
}
}
export function _duration(num){
return Utils.$duration(num)
}
export function _formatNumber(num) {
return Utils.formatNumber(num)
}
export function _getUserDouyinId(item) {
return item.author.unique_id || item.author.short_id
}
Loading…
Cancel
Save