Browse Source

完成我的音乐页面

pull/19/head
zyronon 4 years ago
parent
commit
c2d105a0f2
  1. 4
      README.md
  2. 27
      src/App.vue
  3. BIN
      src/assets/img/icon/me/float-play.png
  4. 1
      src/components/Comment.vue
  5. 6
      src/components/Mask.vue
  6. 45
      src/components/Share.vue
  7. 53
      src/components/dialog/FromBottomDialog.vue
  8. 31
      src/components/slide/SlideColumnList.vue
  9. 3
      src/pages/home/Music.vue
  10. 1
      src/pages/home/components/FollowSetting.vue
  11. 1
      src/pages/home/components/FollowSetting2.vue
  12. 9
      src/pages/home/components/ShareToFriend.vue
  13. 3
      src/pages/login/OtherLogin.vue
  14. 256
      src/pages/me/MyMusic.vue
  15. 3
      src/pages/me/RequestUpdate.vue
  16. 269
      src/pages/me/components/CollectMusic.vue
  17. 251
      src/pages/me/components/GuessMusic.vue
  18. 70
      src/pages/me/components/SlideItemMusic.vue
  19. 2
      src/pages/message/Message.vue
  20. 1
      src/pages/message/components/BlockDialog.vue
  21. 3
      src/pages/people/FindAcquaintance.vue
  22. 21
      src/utils/dom.js

4
README.md

@ -24,9 +24,9 @@
-- 粉丝|0 -- 粉丝|0
-- 编辑资料|☑ -- 编辑资料|☑
-- 添加朋友|☑ -- 添加朋友|☑
-- 我的音乐|50% -- 我的音乐|☑
-- 收藏视频\音乐|50%
-- 抖音商城|0 -- 抖音商城|0
-- 收藏视频\音乐|50%
-- 右侧菜单子页面|10% -- 右侧菜单子页面|10%
-- 设置|☑ -- 设置|☑
-- -- 子页面|☑ -- -- 子页面|☑

27
src/App.vue

@ -1,8 +1,5 @@
<template> <template>
<router-view v-slot="{ Component }"> <router-view v-slot="{ Component }">
<transition name="fade">
<Mask v-if="maskDialog" @click="hideMaskDialog" :mode="maskDialogMode"></Mask>
</transition>
<transition :name="transitionName"> <transition :name="transitionName">
<!-- <keep-alive>--> <!-- <keep-alive>-->
<!-- </keep-alive>--> <!-- </keep-alive>-->
@ -19,26 +16,22 @@
* try {navigator.control.gesture(false);} catch (e) {} //UC * try {navigator.control.gesture(false);} catch (e) {} //UC
try {navigator.control.longpressMenu(false);} catch (e) {} // try {navigator.control.longpressMenu(false);} catch (e) {} //
* */ * */
import * as Vue from "vue";
import Loading from "./components/Loading";
import Mask from "./components/Mask";
export default { export default {
name: 'App', name: 'App',
components: {
Mask
},
data() { data() {
return { return {
transitionName: 'go', transitionName: 'go',
} }
}, },
computed: { computed: {},
maskDialog() { methods: {},
return this.$store.state.maskDialog
},
maskDialogMode() {
return this.$store.state.maskDialogMode
},
},
methods: {
hideMaskDialog() {
this.$store.commit('setMaskDialog', {state: false, mode: this.maskDialogMode})
}
},
// watch $route 使 // watch $route 使
watch: { watch: {
'$route'(to, from) { '$route'(to, from) {
@ -107,7 +100,7 @@ export default {
const toDepth = routeDeep.indexOf(to.path) const toDepth = routeDeep.indexOf(to.path)
const fromDepth = routeDeep.indexOf(from.path) const fromDepth = routeDeep.indexOf(from.path)
this.transitionName = toDepth > fromDepth ? 'go' : 'back' this.transitionName = toDepth > fromDepth ? 'go' : 'back'
} },
}, },
mounted() { mounted() {
// this.$store.dispatch('getFriends') // this.$store.dispatch('getFriends')

BIN
src/assets/img/icon/me/float-play.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

1
src/components/Comment.vue

@ -1,5 +1,6 @@
<template> <template>
<from-bottom-dialog <from-bottom-dialog
page-id="home-index"
v-model="modelValue" v-model="modelValue"
@cancel="cancel" @cancel="cancel"
:show-heng-gang="false" :show-heng-gang="false"

6
src/components/Mask.vue

@ -4,6 +4,8 @@
></div> ></div>
</template> </template>
<script> <script>
//使FromBottomDialog.vuejs appenddom
//使app
export default { export default {
name: "Mask", name: "Mask",
props: { props: {
@ -15,7 +17,7 @@ export default {
} }
</script> </script>
<style scoped lang="less"> <style lang="less">
.Mask { .Mask {
z-index: 3; z-index: 3;
@ -35,7 +37,7 @@ export default {
} }
&.lightgray { &.lightgray {
background: rgba(0, 0, 0, 0.15); background: rgba(0, 0, 0, 0.25);
} }
&.white { &.white {

45
src/components/Share.vue

@ -1,5 +1,6 @@
<template> <template>
<from-bottom-dialog <from-bottom-dialog
:page-id="pageId"
v-model="modelValue" v-model="modelValue"
@cancel="closeShare" @cancel="closeShare"
:show-heng-gang="false" :show-heng-gang="false"
@ -24,13 +25,12 @@
</div> </div>
</div> </div>
<div class="line"></div> <div class="line"></div>
<div class="shares "> <div class="shares">
<template v-if="mode === 'video'"> <template v-if="mode === 'video'">
<div class="share-to" @click="$no"> <div class="share-to" @click="$no">
<img src="../assets/img/icon/components/video/torichang.png" alt=""> <img src="../assets/img/icon/components/video/torichang.png" alt="">
<span>分享日常</span> <span>分享日常</span>
</div> </div>
</template>
<div class="share-to" @click="closeShare($emit('ShareToFriend'))"> <div class="share-to" @click="closeShare($emit('ShareToFriend'))">
<img src="../assets/img/icon/components/video/tofriend.webp" alt=""> <img src="../assets/img/icon/components/video/tofriend.webp" alt="">
<span>私信朋友</span> <span>私信朋友</span>
@ -51,7 +51,6 @@
<img src="../assets/img/icon/components/video/toqq.webp" alt=""> <img src="../assets/img/icon/components/video/toqq.webp" alt="">
<span>QQ好友</span> <span>QQ好友</span>
</div> </div>
<template v-if="mode === 'video'">
<div class="share-to" @click="closeShare($emit('showShareDuoshan'))"> <div class="share-to" @click="closeShare($emit('showShareDuoshan'))">
<img src="../assets/img/icon/components/video/duoshan.png" alt=""> <img src="../assets/img/icon/components/video/duoshan.png" alt="">
<span>多闪</span> <span>多闪</span>
@ -60,11 +59,47 @@
<img src="../assets/img/icon/components/video/totoutiao.webp" alt=""> <img src="../assets/img/icon/components/video/totoutiao.webp" alt="">
<span>今日头条</span> <span>今日头条</span>
</div> </div>
<div class="share-to" @click="closeShare($emit('share2Webo'))">
<img src="../assets/img/icon/components/video/toweibo.webp" alt="">
<span>微博</span>
</div>
</template> </template>
<template v-if="mode === 'music'">
<div class="share-to" @click="closeShare($emit('ShareToFriend'))">
<img src="../assets/img/icon/components/video/tofriend.webp" alt="">
<span>私信朋友</span>
</div>
<div class="share-to" @click="closeShare($emit('showShare2WeChatZone'))">
<img src="../assets/img/icon/components/video/towechat.webp" alt="">
<span>朋友圈</span>
</div>
<div class="share-to" @click="closeShare($emit('share2WeChat'))">
<img src="../assets/img/icon/components/video/towechatchat.webp" alt="">
<span>微信好友</span>
</div>
<div class="share-to" @click="closeShare($emit('share2QQZone'))">
<img src="../assets/img/icon/components/video/tozone.webp" alt="">
<span>QQ空间</span>
</div>
<div class="share-to" @click="closeShare($emit('share2QQ'))">
<img src="../assets/img/icon/components/video/toqq.webp" alt="">
<span>QQ好友</span>
</div>
<div class="share-to" @click="closeShare($emit('share2Webo'))"> <div class="share-to" @click="closeShare($emit('share2Webo'))">
<img src="../assets/img/icon/components/video/toweibo.webp" alt=""> <img src="../assets/img/icon/components/video/toweibo.webp" alt="">
<span>微博</span> <span>微博</span>
</div> </div>
</template>
<template v-if="mode === 'my-music'">
<div class="share-to" @click="$no">
<img src="../assets/img/icon/components/video/torichang.png" alt="">
<span>转发到日常</span>
</div>
<div class="share-to" @click="closeShare($emit('ShareToFriend'))">
<img src="../assets/img/icon/components/video/tofriend.webp" alt="">
<span>私信朋友</span>
</div>
</template>
</div> </div>
<div class="toolbar "> <div class="toolbar ">
<template v-if="mode === 'qrcode'"> <template v-if="mode === 'qrcode'">
@ -174,6 +209,10 @@ export default {
type: String, type: String,
default: null default: null
}, },
pageId: {
type: String,
default: 'home-index'
},
canDownload: { canDownload: {
type: Boolean, type: Boolean,
default: true default: true

53
src/components/dialog/FromBottomDialog.vue

@ -42,11 +42,6 @@ export default {
// default: 'light' // default: 'light'
// default: 'white' // default: 'white'
}, },
//
touchMoved: {
type: Boolean,
default: true
},
maskMode: { maskMode: {
type: String, type: String,
default: 'dark' default: 'dark'
@ -61,41 +56,40 @@ export default {
}, },
pageId: { pageId: {
type: String, type: String,
default: null default: null,
} required: true
},
borderRadius: {
type: String,
default: '.5rem .5rem 0 0'
},
}, },
watch: { watch: {
modelValue(newVal) { modelValue(newVal) {
let app = document.getElementById('app')
if (newVal) {
if (this.pageId) {
let page = document.getElementById(this.pageId) let page = document.getElementById(this.pageId)
if (newVal) {
this.pagePosition = this.$getCss2(page, 'position') this.pagePosition = this.$getCss2(page, 'position')
page.style.position = 'absolute' page.style.position = 'absolute'
} else {
this.pagePosition = this.$getCss2(app.children[0], 'position')
app.children[0].style.position = 'absolute'
}
this.scroll = document.documentElement.scrollTop this.scroll = document.documentElement.scrollTop
document.body.style.position = 'fixed' document.body.style.position = 'fixed'
document.body.style.top = -this.scroll + 'px' document.body.style.top = -this.scroll + 'px'
let maskTemplate = `<div class="Mask fade-in ${this.maskMode}"></div>`
let mask = new Dom().create(maskTemplate)
mask.on('click', () => this.hide(false))
page.appendChild(mask.els[0])
} else { } else {
if (this.pageId) {
let page = document.getElementById(this.pageId) let page = document.getElementById(this.pageId)
page.style.position = this.pagePosition || 'fixed' page.style.position = this.pagePosition || 'fixed'
} else {
app.children[1].style.position = this.pagePosition || 'fixed'
}
document.body.style.position = 'static' document.body.style.position = 'static'
document.documentElement.scrollTop = this.scroll document.documentElement.scrollTop = this.scroll
let mask = new Dom('.Mask').replaceClass('fade-in', 'fade-out')
setTimeout(() => {
mask.remove()
}, 300)
} }
this.$store.commit('setMaskDialog', {state: newVal, mode: this.maskMode})
}, },
maskDialog(newVal) {
if (!newVal) {
this.hide(newVal)
}
}
}, },
data() { data() {
return { return {
@ -106,11 +100,7 @@ export default {
pagePosition: null pagePosition: null
} }
}, },
computed: { computed: {},
maskDialog() {
return this.$store.state.maskDialog
},
},
created() { created() {
}, },
methods: { methods: {
@ -149,13 +139,11 @@ export default {
this.$emit('cancel') this.$emit('cancel')
}, },
start(e) { start(e) {
if (!this.touchMoved) return;
if (this.$refs.dialog.scrollTop !== 0) return if (this.$refs.dialog.scrollTop !== 0) return
this.startLocationY = e.touches[0].pageY this.startLocationY = e.touches[0].pageY
this.startTime = Date.now() this.startTime = Date.now()
}, },
move(e) { move(e) {
if (!this.touchMoved) return;
if (this.$refs.dialog.scrollTop !== 0) return if (this.$refs.dialog.scrollTop !== 0) return
this.moveYDistance = e.touches[0].pageY - this.startLocationY this.moveYDistance = e.touches[0].pageY - this.startLocationY
if (this.moveYDistance > 0) { if (this.moveYDistance > 0) {
@ -164,7 +152,6 @@ export default {
} }
}, },
end(e) { end(e) {
if (!this.touchMoved) return;
// //
if (Date.now() - this.startTime < 150 && Math.abs(this.moveYDistance) < 30) { if (Date.now() - this.startTime < 150 && Math.abs(this.moveYDistance) < 30) {
@ -203,7 +190,7 @@ export default {
bottom: 0; bottom: 0;
left: 0; left: 0;
box-sizing: border-box; box-sizing: border-box;
border-radius: .5rem .5rem 0 0; border-radius: v-bind(borderRadius);
transition: all .3s; transition: all .3s;
&.dark { &.dark {

31
src/components/slide/SlideColumnList.vue

@ -10,6 +10,8 @@
</div> </div>
</template> </template>
<script> <script>
import {nextTick} from "vue";
export default { export default {
name: "BaseSlideList", name: "BaseSlideList",
props: { props: {
@ -17,6 +19,15 @@ export default {
type: Number, type: Number,
default: () => 0 default: () => 0
}, },
//index使
changeActiveIndexUseAnim: {
type: Boolean,
default: true
},
canMove: {
type: Boolean,
default: true
},
}, },
data() { data() {
return { return {
@ -42,8 +53,7 @@ export default {
} }
}, },
watch: { watch: {
activeIndex() { activeIndex(newVal) {
// console.log('activeIndex')
this.changeIndex() this.changeIndex()
}, },
}, },
@ -52,14 +62,29 @@ export default {
await this.checkChildren() await this.checkChildren()
}, },
methods: { methods: {
async changeIndex() {
await this.checkChildren()
this.currentSlideItemIndex = this.activeIndex
if (this.changeActiveIndexUseAnim) {
this.$setCss(this.slideList, 'transition-duration', `300ms`)
}
this.$setCss(this.slideList, 'transform', `translate3d(0px, ${-this.getHeight(this.currentSlideItemIndex) + this.moveYDistance}px, 0px)`)
this.$attrs['onUpdate:active-index'] && this.$emit('update:active-index', this.currentSlideItemIndex)
},
checkChildren() { checkChildren() {
return new Promise(resolve => {
nextTick(() => {
this.slideList = this.$refs.slideList this.slideList = this.$refs.slideList
this.slideItems = this.slideList.children this.slideItems = this.slideList.children
this.wrapperHeight = this.$getCss(this.slideList, 'height') this.wrapperHeight = this.$getCss(this.slideList, 'height')
this.slideItemsHeights = []
for (let i = 0; i < this.slideItems.length; i++) { for (let i = 0; i < this.slideItems.length; i++) {
let el = this.slideItems[i] let el = this.slideItems[i]
this.slideItemsHeights.push(this.$getCss(el, 'height')) this.slideItemsHeights.push(this.$getCss(el, 'height'))
} }
resolve()
})
})
}, },
touchStart(e) { touchStart(e) {
this.checkChildren() this.checkChildren()
@ -70,6 +95,7 @@ export default {
this.startTime = Date.now() this.startTime = Date.now()
}, },
touchMove(e) { touchMove(e) {
if (!this.canMove) return;
this.moveXDistance = e.touches[0].pageX - this.startLocationX this.moveXDistance = e.touches[0].pageX - this.startLocationX
this.moveYDistance = e.touches[0].pageY - this.startLocationY this.moveYDistance = e.touches[0].pageY - this.startLocationY
@ -90,6 +116,7 @@ export default {
} }
}, },
touchEnd(e) { touchEnd(e) {
if (!this.canMove) return;
if (this.isCanDownWiping) { if (this.isCanDownWiping) {
if (this.currentSlideItemIndex === 0 && !this.isDrawDown) return if (this.currentSlideItemIndex === 0 && !this.isDrawDown) return
if (this.currentSlideItemIndex === this.slideItems.length - 1 && this.isDrawDown) return this.$attrs['onEnd'] && this.$emit('end') if (this.currentSlideItemIndex === this.slideItems.length - 1 && this.isDrawDown) return this.$attrs['onEnd'] && this.$emit('end')

3
src/pages/home/Music.vue

@ -60,6 +60,7 @@
<Share v-model="isSharing" <Share v-model="isSharing"
mode="music" mode="music"
ref="share" ref="share"
pageId="Music"
@showDouyinCode="showDouyinCode = true" @showDouyinCode="showDouyinCode = true"
@showShare2WeChatZone="shareType = 2" @showShare2WeChatZone="shareType = 2"
@share2WeChat="shareType = 3" @share2WeChat="shareType = 3"
@ -85,7 +86,7 @@
</template> </template>
</ConfirmDialog> </ConfirmDialog>
<ShareToFriend v-model="shareToFriend"/> <ShareToFriend pageId="Music" v-model="shareToFriend"/>
</div> </div>
</template> </template>

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

@ -1,5 +1,6 @@
<template> <template>
<from-bottom-dialog <from-bottom-dialog
page-id="home-index"
v-model="modelValue" v-model="modelValue"
:show-heng-gang="false" :show-heng-gang="false"
maskMode="dark" maskMode="dark"

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

@ -1,5 +1,6 @@
<template> <template>
<from-bottom-dialog <from-bottom-dialog
page-id="home-index"
v-model="modelValue" v-model="modelValue"
:show-heng-gang="false" :show-heng-gang="false"
maskMode="dark" maskMode="dark"

9
src/pages/home/components/ShareToFriend.vue

@ -1,5 +1,6 @@
<template> <template>
<from-bottom-dialog <from-bottom-dialog
:page-id="pageId"
v-model="modelValue" v-model="modelValue"
@cancel="cancel" @cancel="cancel"
maskMode="light" maskMode="light"
@ -108,7 +109,11 @@ export default {
Check Check
}, },
props: { props: {
modelValue: false modelValue: false,
pageId: {
type: String,
default: 'home-index'
},
}, },
data() { data() {
return { return {
@ -167,7 +172,7 @@ export default {
.button { .button {
width: 6.4rem; width: 6.4rem;
height: 2.6rem!important; height: 2.6rem !important;
} }
@avatar-width: 3.8rem; @avatar-width: 3.8rem;

3
src/pages/login/OtherLogin.vue

@ -1,5 +1,5 @@
<template> <template>
<div class="other-login"> <div class="other-login" id="other-login">
<BaseHeader mode="light" backMode="dark" backImg="back"> <BaseHeader mode="light" backMode="dark" backImg="back">
<template v-slot:right> <template v-slot:right>
<span class="f16">帮助</span> <span class="f16">帮助</span>
@ -41,6 +41,7 @@
</div> </div>
<from-bottom-dialog <from-bottom-dialog
page-id="other-login"
v-model="isOtherLogin" v-model="isOtherLogin"
:show-heng-gang="false" :show-heng-gang="false"
height="27rem" height="27rem"

256
src/pages/me/MyMusic.vue

@ -9,13 +9,9 @@
</IndicatorLight> </IndicatorLight>
<back style="opacity: 0;" mode="light" img="back"/> <back style="opacity: 0;" mode="light" img="back"/>
</div> </div>
<SlideRowList <SlideRowList name="myMusicList" v-model:active-index="slideIndex">
name="myMusicList"
v-model:active-index="slideIndex">
<SlideItem> <SlideItem>
<SlideColumnList> <GuessMusic :list="guessMusic"/>
<SlideItemMusic v-model="guessMusic[index]" v-for="(item,index) in guessMusic "/>
</SlideColumnList>
</SlideItem> </SlideItem>
<SlideItem style="overflow: auto;"> <SlideItem style="overflow: auto;">
<div class="my-collect"> <div class="my-collect">
@ -29,7 +25,7 @@
<img class="menu" src="../../assets/img/icon/menu-white.png" alt=""> <img class="menu" src="../../assets/img/icon/menu-white.png" alt="">
</div> </div>
<div class="collect-list"> <div class="collect-list">
<div class="item" v-for="item in collectMusic" @click="playMusic(item)"> <div class="item" v-for="(item,index) in collectMusic" @click="page2PlayMusic(item)">
<div class="left"> <div class="left">
<div class="cover-wrapper"> <div class="cover-wrapper">
<img v-lazy="$imgPreview(item.cover)" alt="" class="cover"> <img v-lazy="$imgPreview(item.cover)" alt="" class="cover">
@ -44,7 +40,8 @@
</div> </div>
</div> </div>
<div class="right"> <div class="right">
<img v-if="item.is_play" class="playing-icon" src="../../assets/img/icon/me/pinlv.gif"> <img v-if="page2SlideIndex === index" class="playing-icon"
src="../../assets/img/icon/me/pinlv.gif">
</div> </div>
</div> </div>
</div> </div>
@ -56,7 +53,7 @@
</div> </div>
</div> </div>
<div class="recommend-list"> <div class="recommend-list">
<div class="item" v-for="item in recommendMusic" @click="playMusic(item)"> <div class="item" v-for="(item,index) in recommendMusic" @click="page2PlayMusic(item)">
<div class="left"> <div class="left">
<div class="cover-wrapper"> <div class="cover-wrapper">
<img v-lazy="$imgPreview(item.cover)" alt="" class="cover"> <img v-lazy="$imgPreview(item.cover)" alt="" class="cover">
@ -71,39 +68,46 @@
</div> </div>
</div> </div>
<div class="right"> <div class="right">
<img v-if="item.is_play" class="playing-icon" src="../../assets/img/icon/me/pinlv.gif"> <img v-if="page2SlideIndex - collectMusic.length === index" class="playing-icon"
src="../../assets/img/icon/me/pinlv.gif">
<div class="collect-icon"> <div class="collect-icon">
<img src="../../assets/img/icon/star-white.png" v-show="!isCollect" @click="isCollect = !isCollect"> <img src="../../assets/img/icon/star-white.png" v-show="!item.isCollect"
<img src="../../assets/img/icon/star-yellow.png" v-show="isCollect" @click="isCollect = !isCollect"> @click.stop="item.isCollect = !item.isCollect">
<img src="../../assets/img/icon/star-yellow.png" v-show="item.isCollect"
@click.stop="item.isCollect = !item.isCollect">
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div class="playing" @click="isShowCollectDialog = true"> <transition name="float-play">
<div v-if="isShowFloatPlay" class="playing" @click="isShowCollectDialog = true">
<div class="playing-wrapper"> <div class="playing-wrapper">
<div class="cover-wrapper"> <div class="cover-wrapper">
<img v-lazy="$imgPreview(currentMusic.cover)" alt="" class="cover"> <img v-lazy="$imgPreview(currentMusic.cover)" alt="" class="cover">
</div> </div>
<div class="name">{{ currentMusic.name }}</div> <div class="name">{{ currentMusic.name }}</div>
<img class="option" src="../../assets/img/icon/me/float-pause-one.png" alt=""> <img v-show="page2IsPlay" @click.stop="togglePage2Play" class="option"
<img class="menu-list" src="../../assets/img/icon/me/music-list.png" alt=""> src="../../assets/img/icon/me/float-pause-one.png" alt="">
<img v-show="!page2IsPlay" @click.stop="togglePage2Play" class="option"
src="../../assets/img/icon/me/float-play.png" alt="">
<img @click.stop="$no" class="menu-list" src="../../assets/img/icon/me/music-list.png" alt="">
</div> </div>
</div> </div>
</transition>
</div> </div>
</SlideItem> </SlideItem>
</SlideRowList> </SlideRowList>
<transition name="my-collect-dialog"> <transition name="my-collect-dialog">
<div class="my-collect-dialog" v-if="isShowCollectDialog"> <div class="my-collect-dialog" v-show="isShowCollectDialog">
<div class="dialog-header"> <div class="dialog-header">
<back class="close" mode="light" img="back" @click="isShowCollectDialog = false"/> <back class="close" mode="light" img="back" @click="isShowCollectDialog = false"/>
<span>我的收藏</span> <span>我的收藏</span>
<back style="opacity: 0;" mode="light" img="back"/> <back style="opacity: 0;" mode="light" img="back"/>
</div> </div>
<SlideColumnList> <CollectMusic ref="CollectMusic" :list="page2Music" v-model:page2SlideIndex="page2SlideIndex"/>
<SlideItemMusic v-model="guessMusic[index]" v-for="(item,index) in guessMusic "/>
</SlideColumnList>
</div> </div>
</transition> </transition>
</div> </div>
@ -116,17 +120,24 @@ import gaobaiqiqiu from '../../assets/data/lyrics/gaobaiqiqiu.lrc'
import Switches from "../message/components/swtich/switches"; import Switches from "../message/components/swtich/switches";
import SlideItemMusic from "./components/SlideItemMusic"; import SlideItemMusic from "./components/SlideItemMusic";
import IndicatorLight from "../../components/slide/IndicatorLight"; import IndicatorLight from "../../components/slide/IndicatorLight";
import FromBottomDialog from "../../components/dialog/FromBottomDialog";
import GuessMusic from "./components/GuessMusic";
import CollectMusic from "./components/CollectMusic";
//TODO page
export default { export default {
name: "MyMusic", name: "MyMusic",
components: { components: {
FromBottomDialog,
Switches, Switches,
SlideItemMusic, SlideItemMusic,
IndicatorLight IndicatorLight,
GuessMusic,
CollectMusic
}, },
data() { data() {
return { return {
slideIndex: 0, slideIndex: 1,
currentMusic: { currentMusic: {
name: '告白气球', name: '告白气球',
mp3: 'https://mp32.9ku.com/upload/128/2017/02/05/858423.mp3', mp3: 'https://mp32.9ku.com/upload/128/2017/02/05/858423.mp3',
@ -140,98 +151,42 @@ export default {
collectMusic: [], collectMusic: [],
recommendMusic: [], recommendMusic: [],
guessMusic: [], guessMusic: [],
lyricsTexts: [],
lyricsFullTexts: [],
isShowCollectDialog: false, isShowCollectDialog: false,
isPlay: false, isShowFloatPlay: false,
isAutoPlay: true, isAutoPlay: true,
isLoop: false,
isMove: false,
isCollect: false, isCollect: false,
isFullLyrics: false,
lastPageX: 0, page2SlideIndex: -1,
pageX: 0, page2IsPlay: false
audio: new Audio(),
duration: 0,
currentTime: 0,
step: 0,
startX: 0,
slideBarWidth: 0
} }
}, },
computed: { computed: {
...mapState(['bodyWidth']) ...mapState(['bodyWidth']),
page2Music() {
return this.collectMusic.concat(this.recommendMusic)
}
}, },
created() { created() {
this.getCollectMusic() this.getCollectMusic()
}, },
mounted() { methods: {
if (process.env.NODE_ENV === 'development') { togglePage2Play() {
this.audio.volume = .2 this.page2IsPlay = !this.page2IsPlay
} if (this.page2IsPlay) {
this.audio.addEventListener('loadedmetadata', e => { this.$refs.CollectMusic.play(this.page2SlideIndex)
this.duration = this.audio.duration
this.slideBarWidth = this.$refs.slideBar.clientWidth
this.step = this.slideBarWidth / Math.floor(this.duration)
})
let lrcObj = this.createLrcObj(gaobaiqiqiu);
this.lyricsTexts.push(lrcObj.ms[0])
this.lyricsTexts.push(lrcObj.ms[1])
lrcObj.ms.map(v => {
if (v.c) this.lyricsFullTexts.push(v)
})
console.log(lrcObj.ms)
this.audio.addEventListener('timeupdate', e => {
let currentTime = Math.ceil(e.target.currentTime)
// let lastLyricsText = this.lyricsTexts[this.lyricsTexts.length - 1]
// if (Number(lastLyricsText.t) < currentTime) {
// for (let i = 0; i < lrcObj.ms.length; i++) {
// let item = lrcObj.ms[i]
// if (Number(item.t) > currentTime) {
// if (item.c) {
// console.log(item)
// this.t(item)
// break
// }
// }
// }
// }
if (!this.isMove) {
this.currentTime = currentTime
if (Math.ceil(e.target.currentTime) * this.step > this.slideBarWidth - 5) {
this.pageX = this.slideBarWidth - 5
} else {
this.pageX = Math.ceil(e.target.currentTime) * this.step
}
}
})
this.audio.addEventListener('play', e => this.isPlay = true)
this.audio.addEventListener('ended', e => {
if (this.isLoop) {
this.lastPageX = 0
this.audio.currentTime = 0
this.audio.play()
} else { } else {
this.isPlay = false this.$refs.CollectMusic.pause()
} }
})
}, },
methods: { page2PlayMusic(item) {
playMusic(item) {
this.collectMusic.map(v => v.is_play = false)
this.recommendMusic.map(v => v.is_play = false)
item.is_play = true
this.currentMusic = item this.currentMusic = item
this.audio.src = this.currentMusic.mp3 this.isShowFloatPlay = true
this.togglePlay(true) this.page2IsPlay = true
}, this.page2SlideIndex = this.page2Music.findIndex(v => v.name === item.name)
togglePlay(state) { this.isShowCollectDialog = true
this.currentMusic.is_play = state || !this.currentMusic.is_play this.$refs.CollectMusic.play(this.page2SlideIndex)
if (this.currentMusic.is_play) {
this.audio.play()
} else {
this.audio.pause()
}
}, },
async getCollectMusic() { async getCollectMusic() {
this.loading = true this.loading = true
@ -242,93 +197,6 @@ export default {
this.guessMusic = this.recommendMusic = res.data.music.list.slice(2, -1) this.guessMusic = this.recommendMusic = res.data.music.list.slice(2, -1)
} }
}, },
createLrcObj(lrc) {
let oLRC = {
ti: "", //
ar: "", //
al: "", //
by: "", //
offset: 0, //
ms: [] //{t:,c:}
};
if (lrc.length === 0) return;
let lrcs = lrc.split('\n');//
for (let i in lrcs) {//
lrcs[i] = lrcs[i].replace(/(^\s*)|(\s*$)/g, ""); //
let t = lrcs[i].substring(lrcs[i].indexOf("[") + 1, lrcs[i].indexOf("]"));//[]
let s = t.split(":");//:
if (isNaN(parseInt(s[0]))) { //
for (let i in oLRC) {
if (i != "ms" && i == s[0].toLowerCase()) {
oLRC[i] = s[1];
}
}
} else { //
let arr = lrcs[i].match(/\[(\d+:.+?)\]/g);//
let start = 0;
for (let k in arr) {
start += arr[k].length; //
}
let content = lrcs[i].substring(start);//
for (let k in arr) {
let t = arr[k].substring(1, arr[k].length - 1);//[]
let s = t.split(":");//:
oLRC.ms.push({//{t:,c:}ms
t: (parseFloat(s[0]) * 60 + parseFloat(s[1])).toFixed(3),
c: content
});
}
}
}
oLRC.ms.sort(function (a, b) {//
return a.t - b.t;
});
return oLRC
/*
for(let i in oLRC){ //
console.log(i,":",oLRC[i]);
}*/
},
t(txt) {
// if (this.test.length === 2) return
this.lyricsTexts.push(txt)
nextTick(() => {
let comments = this.$refs['lyrics-wrapper']
comments.scrollTo({top: comments.scrollHeight - comments.clientHeight, behavior: 'smooth'})
})
},
start(e) {
this.startX = e.touches[0].pageX
},
move(e) {
this.isMove = true
this.pageX = this.lastPageX + (e.touches[0].pageX - this.startX)
if (this.pageX < 0) this.pageX = 0
if (this.pageX > this.slideBarWidth) this.pageX = this.slideBarWidth - 5
this.currentTime = Math.ceil(this.pageX / this.step)
globalMethods.$stopPropagation(e)
},
end(e) {
this.lastPageX = this.pageX
this.currentTime = Math.ceil(this.pageX / this.step)
this.audio.currentTime = this.currentTime
this.audio.play()
this.isMove = false
globalMethods.$stopPropagation(e)
},
$durationTime(time) {
if (time === 0) return '00:00'
else {
return this.$duration(time)
}
},
durationStyle(type) {
// return {}
if (type === 1) {
return {width: this.pageX + 'px'}
}
return {left: this.pageX + 'px'}
},
} }
} }
</script> </script>
@ -383,6 +251,7 @@ export default {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
color: white;
.left { .left {
display: flex; display: flex;
@ -394,6 +263,7 @@ export default {
} }
.num { .num {
font-size: 1.3rem;
color: gray; color: gray;
margin-left: .5rem; margin-left: .5rem;
} }
@ -406,6 +276,7 @@ export default {
.collect-list, .recommend-list { .collect-list, .recommend-list {
.item { .item {
color: white;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
margin-bottom: 1.5rem; margin-bottom: 1.5rem;
@ -584,7 +455,6 @@ export default {
} }
} }
.my-collect-dialog-enter-active, .my-collect-dialog-enter-active,
.my-collect-dialog-leave-active { .my-collect-dialog-leave-active {
transition-duration: 300ms; transition-duration: 300ms;
@ -596,5 +466,17 @@ export default {
transition-duration: 300ms; transition-duration: 300ms;
transform: translateY(100vh); transform: translateY(100vh);
} }
.float-play-enter-active,
.float-play-leave-active {
transition-duration: 200ms;
transform: translateY(0);
}
.float-play-enter-from,
.float-play-leave-to {
transition-duration: 200ms;
transform: translateY(100%);
}
} }
</style> </style>

3
src/pages/me/RequestUpdate.vue

@ -1,5 +1,5 @@
<template> <template>
<div class="RequestUpdate"> <div class="RequestUpdate" id="RequestUpdate">
<BaseHeader> <BaseHeader>
<template v-slot:center> <template v-slot:center>
<span class="f16">求更新</span> <span class="f16">求更新</span>
@ -37,6 +37,7 @@
</div> </div>
<from-bottom-dialog <from-bottom-dialog
page-id="RequestUpdate"
height="16rem" height="16rem"
:show-heng-gang="false" :show-heng-gang="false"
mode="white" mode="white"

269
src/pages/me/components/CollectMusic.vue

@ -0,0 +1,269 @@
<template>
<div id="CollectMusic">
<SlideColumnList
:changeActiveIndexUseAnim="false"
v-model:active-index="activeIndex"
:canMove="slideCanMove">
<SlideItemMusic
:ref="setItemRef"
@showList="isShowList = true"
@showShare="isSharing = true"
@previous="previous"
@next="next"
@slideCanMove="e => this.slideCanMove = e"
v-model="list[index]"
v-model:isLoop="isLoop"
v-for="(item,index) in list "/>
</SlideColumnList>
<from-bottom-dialog
mask-mode="lightgray"
page-id="CollectMusic"
border-radius="1.5rem 1.5rem 0 0"
:show-heng-gang="false"
height="70vh"
v-model="isShowList">
<div class="music-list-dialog">
<div class="music-list-header">
<div class="left">待播清单</div>
<div class="right" @click="isLoop = !isLoop">
<img v-show="isLoop" src="@/assets/img/icon/me/loop.png" alt="">
<img v-show="!isLoop" src="@/assets/img/icon/me/play-normal.png" alt="">
<span>{{ isLoop ? '单曲循环' : '顺序播放' }}</span>
</div>
</div>
<div class="wrapper">
<div class="l-row"
@click="play(index)"
:class="{active:activeIndex === index}"
v-for="(item,index) in list">
<div class="left">
<img v-if="activeIndex === index" src="@/assets/img/icon/me/pinlv.gif" alt="" class="play-icon">
<div class="name">{{ item.name }}</div>
<div class="author">{{ item.author }}</div>
</div>
<back class="right" mode="gray" img="close"/>
</div>
</div>
<div class="footer" @click="isShowList = false">取消</div>
</div>
</from-bottom-dialog>
<Share v-model="isSharing"
mode="my-music"
ref="share"
pageId="GuessMusic"
@ShareToFriend="delayShowDialog( e => this.isShowShareToFriend = true)"
/>
<ShareToFriend pageId="GuessMusic" v-model="isShowShareToFriend"/>
</div>
</template>
<script>
import FromBottomDialog from "../../../components/dialog/FromBottomDialog";
import Switches from "../../message/components/swtich/switches";
import SlideItemMusic from "./SlideItemMusic";
import IndicatorLight from "../../../components/slide/IndicatorLight";
import SlideColumnList from "../../../components/slide/SlideColumnList";
import Share from "../../../components/Share";
import ShareToFriend from "../../home/components/ShareToFriend";
export default {
name: "GuessMusic",
components: {
FromBottomDialog,
Switches,
SlideItemMusic,
IndicatorLight,
SlideColumnList,
Share,
ShareToFriend
},
props: {
list: {
type: Array,
default: []
},
page2SlideIndex: {
type: Number,
default: 0
},
},
data() {
return {
slideCanMove: true,
isShowShareToFriend: false,
isShowList: false,
isSharing: false,
isLoop: false,
collectSlideIndex: 0,
isShowCollectDialog: false,
itemRefs: []
}
},
computed: {
activeIndex: {
get() {
return this.page2SlideIndex
},
set(val) {
this.$emit('update:page2SlideIndex', val)
}
}
},
created() {
},
watch: {
activeIndex(newVal, oldVal) {
this.itemRefs.map(ref => {
ref.togglePlay(false)
})
this.itemRefs[newVal].togglePlay(true, true)
}
},
methods: {
previous() {
if (this.activeIndex > 0) {
this.play(this.activeIndex - 1)
}
},
next() {
if (this.activeIndex < this.list.length - 1) {
this.play(this.activeIndex + 1)
}
},
delayShowDialog(cb) {
setTimeout(() => {
cb()
}, 100)
},
setItemRef(el) {
if (el) {
this.itemRefs.push(el)
}
},
play(index) {
this.activeIndex = index
this.itemRefs.map(ref => {
ref.togglePlay(false)
})
this.itemRefs[index].togglePlay(true, true)
},
pause() {
this.itemRefs.map(ref => {
ref.togglePlay(false)
})
}
}
}
</script>
<style scoped lang="less">
@import "@/assets/less/index";
#CollectMusic {
//width: 100vw;
//height: 100vh;
position: fixed;
left: 0;
right: 0;
bottom: 0;
top: 0;
overflow: auto;
color: white;
font-size: 1.4rem;
}
.music-list-dialog {
height: 70vh;
@bg-color: #1e1d1d;
background: @bg-color;
.music-list-header {
position: fixed;
width: 100vw;
background: @bg-color;
box-sizing: border-box;
border-bottom: 1px solid #2a2828;
display: flex;
justify-content: space-between;
align-items: center;
height: 5rem;
padding: 0 @padding-page;
border-radius: 1.5rem 1.5rem 0 0;
z-index: 9;
.left {
font-size: 1.6rem;
}
.right {
display: flex;
align-items: center;
font-size: 1.2rem;
img {
width: 2rem;
margin-right: .5rem;
}
}
}
.wrapper {
padding-top: 5rem;
}
.l-row {
background: @bg-color;
height: 5rem;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 @padding-page;
&.active {
color: @primary-btn-color;
}
.left {
display: flex;
align-items: center;
.author {
font-size: 1.2rem;
color: @second-text-color;
margin-left: 2rem;
position: relative;
display: flex;
align-items: center;
&:after {
content: '';
width: .6rem;
height: .5px;
background: @second-text-color;
position: absolute;
left: -1.2rem;
}
}
.play-icon {
width: 1.5rem;
margin-right: 1rem;
}
}
.right {
width: 1.5rem;
}
}
.footer {
background: @bg-color;
border-top: 1px solid #2a2828;
height: 6rem;
display: flex;
align-items: center;
justify-content: center;
}
}
</style>

251
src/pages/me/components/GuessMusic.vue

@ -0,0 +1,251 @@
<template>
<div id="GuessMusic">
<SlideColumnList
:changeActiveIndexUseAnim="false"
v-model:active-index="guessSlideIndex"
:canMove="slideCanMove">
<SlideItemMusic
:ref="setItemRef"
@showList="isShowList = true"
@showShare="isSharing = true"
@previous="previous"
@next="next"
@slideCanMove="e => this.slideCanMove = e"
v-model="list[index]"
v-model:isLoop="isLoop"
v-for="(item,index) in list "/>
</SlideColumnList>
<from-bottom-dialog
mask-mode="lightgray"
page-id="GuessMusic"
border-radius="1.5rem 1.5rem 0 0"
:show-heng-gang="false"
height="70vh"
v-model="isShowList">
<div class="music-list-dialog">
<div class="music-list-header">
<div class="left">待播清单</div>
<div class="right" @click="isLoop = !isLoop">
<img v-show="isLoop" src="@/assets/img/icon/me/loop.png" alt="">
<img v-show="!isLoop" src="@/assets/img/icon/me/play-normal.png" alt="">
<span>{{ isLoop ? '单曲循环' : '顺序播放' }}</span>
</div>
</div>
<div class="wrapper">
<div class="l-row"
@click="play(index)"
:class="{active:guessSlideIndex === index}"
v-for="(item,index) in list">
<div class="left">
<img v-if="guessSlideIndex === index" src="@/assets/img/icon/me/pinlv.gif" alt="" class="play-icon">
<div class="name">{{ item.name }}</div>
<div class="author">{{ item.author }}</div>
</div>
<back class="right" mode="gray" img="close"/>
</div>
</div>
<div class="footer" @click="isShowList = false">取消</div>
</div>
</from-bottom-dialog>
<Share v-model="isSharing"
mode="my-music"
ref="share"
pageId="GuessMusic"
@ShareToFriend="delayShowDialog( e => this.isShowShareToFriend = true)"
/>
<ShareToFriend pageId="GuessMusic" v-model="isShowShareToFriend"/>
</div>
</template>
<script>
import FromBottomDialog from "../../../components/dialog/FromBottomDialog";
import Switches from "../../message/components/swtich/switches";
import SlideItemMusic from "./SlideItemMusic";
import IndicatorLight from "../../../components/slide/IndicatorLight";
import SlideColumnList from "../../../components/slide/SlideColumnList";
import Share from "../../../components/Share";
import ShareToFriend from "../../home/components/ShareToFriend";
export default {
name: "GuessMusic",
components: {
FromBottomDialog,
Switches,
SlideItemMusic,
IndicatorLight,
SlideColumnList,
Share,
ShareToFriend
},
props: {
list: {
type: Array,
default: []
}
},
data() {
return {
slideCanMove: true,
isShowShareToFriend: false,
isShowList: false,
isSharing: false,
isLoop: false,
guessSlideIndex: 0,
isShowCollectDialog: false,
itemRefs: []
}
},
watch: {
guessSlideIndex(newVal, oldVal) {
this.itemRefs.map(ref => {
ref.togglePlay(false)
})
this.itemRefs[newVal].togglePlay(true, true)
}
},
computed: {},
created() {
},
methods: {
previous() {
if (this.guessSlideIndex > 0) {
this.play(this.guessSlideIndex - 1)
}
},
next() {
if (this.guessSlideIndex < this.list.length - 1) {
this.play(this.guessSlideIndex + 1)
}
},
delayShowDialog(cb) {
setTimeout(() => {
cb()
}, 100)
},
setItemRef(el) {
if (el) {
this.itemRefs.push(el)
}
},
play(index) {
this.guessSlideIndex = index
this.itemRefs.map(ref => {
ref.togglePlay(false)
})
this.itemRefs[index].togglePlay(true, true)
}
}
}
</script>
<style scoped lang="less">
@import "@/assets/less/index";
#GuessMusic {
//width: 100vw;
//height: 100vh;
position: fixed;
left: 0;
right: 0;
bottom: 0;
top: 0;
overflow: auto;
color: white;
font-size: 1.4rem;
}
.music-list-dialog {
height: 70vh;
@bg-color: #1e1d1d;
background: @bg-color;
.music-list-header {
position: fixed;
width: 100vw;
background: @bg-color;
box-sizing: border-box;
border-bottom: 1px solid #2a2828;
display: flex;
justify-content: space-between;
align-items: center;
height: 5rem;
padding: 0 @padding-page;
border-radius: 1.5rem 1.5rem 0 0;
z-index: 9;
.left {
font-size: 1.6rem;
}
.right {
display: flex;
align-items: center;
font-size: 1.2rem;
img {
width: 2rem;
margin-right: .5rem;
}
}
}
.wrapper {
padding-top: 5rem;
}
.l-row {
background: @bg-color;
height: 5rem;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 @padding-page;
&.active {
color: @primary-btn-color;
}
.left {
display: flex;
align-items: center;
.author {
font-size: 1.2rem;
color: @second-text-color;
margin-left: 2rem;
position: relative;
display: flex;
align-items: center;
&:after {
content: '';
width: .6rem;
height: .5px;
background: @second-text-color;
position: absolute;
left: -1.2rem;
}
}
.play-icon {
width: 1.5rem;
margin-right: 1rem;
}
}
.right {
width: 1.5rem;
}
}
.footer {
background: @bg-color;
border-top: 1px solid #2a2828;
height: 6rem;
display: flex;
align-items: center;
justify-content: center;
}
}
</style>

70
src/pages/me/components/SlideItemMusic.vue

@ -12,7 +12,10 @@
<!-- <div class="lyrics-mask" @click="isFullLyrics = true"></div>--> <!-- <div class="lyrics-mask" @click="isFullLyrics = true"></div>-->
</div> </div>
<div class="lyrics-full" v-show="isFullLyrics" @click="isFullLyrics = false"> <div class="lyrics-full" v-show="isFullLyrics" @click="isFullLyrics = false">
<div class="list" style="overflow:auto;"> <div class="list" style="overflow:auto;"
@touchmove="$emit('slideCanMove', false)"
@touchend="$emit('slideCanMove', true)"
>
<div class="item" v-for="item in lyricsFullTexts">{{ item.c }}</div> <div class="item" v-for="item in lyricsFullTexts">{{ item.c }}</div>
</div> </div>
</div> </div>
@ -28,7 +31,7 @@
<img src="@/assets/img/icon/star-yellow.png" v-show="isCollect" @click="isCollect = !isCollect"> <img src="@/assets/img/icon/star-yellow.png" v-show="isCollect" @click="isCollect = !isCollect">
<span>收藏</span> <span>收藏</span>
</div> </div>
<div class="btn"> <div class="btn" @click="$emit('showShare')">
<img src="@/assets/img/icon/share-white-full.png" alt=""> <img src="@/assets/img/icon/share-white-full.png" alt="">
<span>分享</span> <span>分享</span>
</div> </div>
@ -48,17 +51,17 @@
<div class="end">{{ $durationTime(duration) }}</div> <div class="end">{{ $durationTime(duration) }}</div>
</div> </div>
<div class="options"> <div class="options">
<img v-show="isLoop" src="@/assets/img/icon/me/loop.png" @click="isLoop = !isLoop"> <img v-show="isLoop" src="@/assets/img/icon/me/loop.png" @click="$emit('update:isLoop',false)">
<img v-show="!isLoop" src="@/assets/img/icon/me/play-normal.png" @click="isLoop = !isLoop"> <img v-show="!isLoop" src="@/assets/img/icon/me/play-normal.png" @click="$emit('update:isLoop',true)">
<div class="center"> <div class="center">
<img src="@/assets/img/icon/me/previous.png" @click="t"> <img src="@/assets/img/icon/me/previous.png" @click="slide('previous')">
<img v-show="modelValue.is_play" class="control" src="@/assets/img/icon/me/pause.png" <img v-show="isPlay" class="control" src="@/assets/img/icon/me/pause.png"
@click="togglePlay()"> @click="togglePlay()">
<img v-show="!modelValue.is_play" class="control" src="@/assets/img/icon/me/play.png" <img v-show="!isPlay" class="control" src="@/assets/img/icon/me/play.png"
@click="togglePlay()"> @click="togglePlay()">
<img src="@/assets/img/icon/me/next.png"> <img src="@/assets/img/icon/me/next.png" @click="slide('next')">
</div> </div>
<img src="@/assets/img/icon/me/music-list.png"> <img src="@/assets/img/icon/me/music-list.png" @click="$emit('showList')">
</div> </div>
</div> </div>
</div> </div>
@ -77,30 +80,19 @@ export default {
default: function () { default: function () {
return {} return {}
} }
} },
isLoop: {
type: Boolean,
default: false
},
}, },
data() { data() {
return { return {
slideIndex: 1, slideIndex: 1,
currentMusic: {
name: '告白气球',
mp3: 'https://mp32.9ku.com/upload/128/2017/02/05/858423.mp3',
cover: require('../../../assets/img/music-cover/7.png'),
author: '周杰伦',
duration: 60,
use_count: 37441000,
is_collect: false,
is_play: false,
},
collectMusic: [],
recommendMusic: [],
guessMusic: [],
lyricsTexts: [], lyricsTexts: [],
lyricsFullTexts: [], lyricsFullTexts: [],
isShowCollectDialog: false,
isPlay: false, isPlay: false,
isAutoPlay: true, isAutoPlay: true,
isLoop: false,
isMove: false, isMove: false,
isCollect: false, isCollect: false,
isFullLyrics: false, isFullLyrics: false,
@ -127,12 +119,14 @@ export default {
this.slideBarWidth = this.$refs.slideBar.clientWidth this.slideBarWidth = this.$refs.slideBar.clientWidth
this.step = this.slideBarWidth / Math.floor(this.duration) this.step = this.slideBarWidth / Math.floor(this.duration)
}) })
let lrcObj = this.createLrcObj(gaobaiqiqiu); let lrcObj = this.createLrcObj(gaobaiqiqiu);
this.lyricsTexts.push(lrcObj.ms[0]) this.lyricsTexts.push(lrcObj.ms[0])
this.lyricsTexts.push(lrcObj.ms[1]) this.lyricsTexts.push(lrcObj.ms[1])
lrcObj.ms.map(v => { lrcObj.ms.map(v => {
if (v.c) this.lyricsFullTexts.push(v) if (v.c) this.lyricsFullTexts.push(v)
}) })
// console.log(lrcObj.ms) // console.log(lrcObj.ms)
this.audio.addEventListener('timeupdate', e => { this.audio.addEventListener('timeupdate', e => {
let currentTime = Math.ceil(e.target.currentTime) let currentTime = Math.ceil(e.target.currentTime)
@ -170,10 +164,19 @@ export default {
}) })
}, },
methods: { methods: {
togglePlay(state) { slide(state) {
this.modelValue.is_play = state || !this.modelValue.is_play this.togglePlay(false)
if (this.modelValue.is_play) { this.$emit(state)
this.audio.play() },
//TODO DOMException: The play() request was interrupted by a call to pause()
//TODO page2
async togglePlay(state, reStart = false) {
this.isPlay = state !== undefined ? state : !this.isPlay
if (reStart) {
this.audio.currentTime = 0
}
if (this.isPlay) {
await this.audio.play()
} else { } else {
this.audio.pause() this.audio.pause()
} }
@ -303,6 +306,7 @@ export default {
object-fit: cover; object-fit: cover;
width: 100%; width: 100%;
height: 100%; height: 100%;
box-shadow: 0 0 1.5rem .5rem #514f4f;
} }
} }
@ -412,11 +416,11 @@ export default {
height: 2rem; height: 2rem;
width: 100%; width: 100%;
top: -1rem; top: -1rem;
z-index: 11; z-index: 9;
} }
&:before { &:before {
z-index: 9; z-index: 8;
content: ' '; content: ' ';
height: 1.5px; height: 1.5px;
width: 100%; width: 100%;
@ -426,7 +430,7 @@ export default {
} }
.bar-line { .bar-line {
z-index: 10; z-index: 9;
content: ''; content: '';
position: absolute; position: absolute;
top: 0; top: 0;
@ -436,7 +440,7 @@ export default {
} }
.bar-point { .bar-point {
z-index: 10; z-index: 9;
position: absolute; position: absolute;
left: 50vw; left: 50vw;
top: -3px; top: -3px;

2
src/pages/message/Message.vue

@ -57,7 +57,7 @@
</div> </div>
<Footer v-bind:init-tab="4"/> <Footer v-bind:init-tab="4"/>
<from-bottom-dialog v-model="createChatDialog"> <from-bottom-dialog page-id="Message" v-model="createChatDialog">
<div class="create-chat-wrapper" v-show="!showJoinedChat"> <div class="create-chat-wrapper" v-show="!showJoinedChat">
<Search :isShowText="isShowText" <Search :isShowText="isShowText"
@click="isShowText = true" @click="isShowText = true"

1
src/pages/message/components/BlockDialog.vue

@ -1,5 +1,6 @@
<template> <template>
<from-bottom-dialog <from-bottom-dialog
page-id="home-index"
v-model="modelValue" v-model="modelValue"
:show-heng-gang="false" :show-heng-gang="false"
height="20rem" height="20rem"

3
src/pages/people/FindAcquaintance.vue

@ -1,5 +1,5 @@
<template> <template>
<div class="FindAcquaintance"> <div class="FindAcquaintance" id="FindAcquaintance">
<div class="header"> <div class="header">
<back mode="light" @click="back"></back> <back mode="light" @click="back"></back>
<Indicator <Indicator
@ -80,6 +80,7 @@
</transition> </transition>
<from-bottom-dialog <from-bottom-dialog
page-id="FindAcquaintance"
v-model="moreOptionDialog" v-model="moreOptionDialog"
:show-heng-gang="false" :show-heng-gang="false"
height="21rem" height="21rem"

21
src/utils/dom.js

@ -16,6 +16,27 @@ export default class Dom {
return this return this
} }
addClass(class1) {
if (typeof class1 === 'string') {
this.els.forEach(el => {
el.classList.add(class1)
})
} else {
this.els.forEach(el => {
el.classList.add(...class1)
})
}
return this
}
replaceClass(class1, class2) {
this.els.forEach(el => {
el.classList.replace(class1, class2)
})
return this
}
find(tag) { find(tag) {
let els = [] let els = []
if (this.els.length) { if (this.els.length) {

Loading…
Cancel
Save