fix player

This commit is contained in:
Stepan Fedyanin 2024-06-18 17:56:09 +05:00
parent 4e3ceb30ce
commit 935a1cd020
20 changed files with 339 additions and 163 deletions

19
.idea/php.xml Normal file
View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="MessDetectorOptionsConfiguration">
<option name="transferred" value="true" />
</component>
<component name="PHPCSFixerOptionsConfiguration">
<option name="transferred" value="true" />
</component>
<component name="PHPCodeSnifferOptionsConfiguration">
<option name="highlightLevel" value="WARNING" />
<option name="transferred" value="true" />
</component>
<component name="PhpStanOptionsConfiguration">
<option name="transferred" value="true" />
</component>
<component name="PsalmOptionsConfiguration">
<option name="transferred" value="true" />
</component>
</project>

View File

@ -29,7 +29,6 @@
"scrolltrigger": "^1.0.1",
"swiper": "^11.1.3",
"vue": "^3.3.13",
"vue-content-loader": "^2.0.1",
"vue-final-modal": "^4.5.4",
"vue-router": "^4.0.0",
"vuex": "^4.0.1",

View File

@ -7,6 +7,7 @@
@mixin responsive-l {
top: 0;
}
&__wrapper {
padding: 40px 20px 10px;
width: 100%;
@ -39,7 +40,6 @@
&__menu {
display: flex;
align-items: center;
gap: 50px;
transition: transform .3s ease;
@mixin responsive-xl {
gap: 20px;
@ -64,6 +64,21 @@
&-item {
margin: 0 25px;
&.m--tools {
margin: 0 10px 0 25px;
}
@mixin responsive-xl {
margin: 0 10px;
&.m--tools {
margin: 0 5px 0 10px;
}
}
@mixin responsive-l {
}
}
&-link {
@ -75,6 +90,31 @@
background-image: var(--linear-gradient);
}
}
&-icon {
background: none;
border: none;
width: 24px;
height: 24px;
cursor: url("./assets/img/icon/cursor.svg"), auto;
transition: all .3s ease;
&.m--profile {
background: svg-load('./assets/img/icon/user-icon.svg', stroke=$color-primary) no-repeat 100%;
&:hover {
background: svg-load('./assets/img/icon/user-icon.svg', stroke=$color-white) no-repeat 100%;
}
}
&.m--exit {
background: svg-load('./assets/img/icon/exit-icon.svg', fill=$color-primary) no-repeat 100%;
&:hover {
background: svg-load('./assets/img/icon/exit-icon.svg', fill=$color-white) no-repeat 100%;
}
}
}
}
&__btn {
@ -89,14 +129,17 @@
height: 24px;
position: relative;
display: none;
&:hover {
cursor: url("./assets/img/icon/cursor.svg"), auto;
}
&.m--menu{
&.m--menu {
position: absolute;
right: 15px;
top: 15px;
}
&.m--active {
span {
display: none;

View File

@ -30,7 +30,8 @@
display: flex;
flex-direction: column;
margin-left: 20px;
min-width: 135px;
gap: 0.25rem;
span {
color: var(--color-white-opacity);
}
@ -41,6 +42,9 @@
height: 27px;
background: svg-load('./assets/img/icon/favorites.svg', fill=#404145FF) no-repeat 100%;
margin-left: var(--space-between-block);
&.m--skeleton{
background: none;
}
&:hover {
cursor: url("./assets/img/icon/cursor.svg"), auto;
}
@ -60,7 +64,7 @@
color: var(--color-white-opacity);
font-weight: 500;
position: relative;
min-width: 105px;
&.m--ether {
padding-right: 10px;
@ -68,7 +72,7 @@
content: '';
position: absolute;
border-radius: 50%;
right: 0;
left: 40px;
top: 0;
width: 5px;
height: 5px;
@ -81,6 +85,9 @@
gap: var(--space-between-block);
align-items: center;
margin-left: auto;
&.m--skeleton{
min-width: 200px;
}
}
&__volume{
display: flex;
@ -192,5 +199,9 @@
background-size: contain;
}
}
&.m--skeleton{
background: none;
}
}
}

View File

@ -67,6 +67,7 @@
margin: auto;
background: svg-load('./assets/img/icon/favorites.svg', fill=$color-primary) no-repeat 100%;
background-size: contain;
transition: all .3s ease;
}
&:hover:after {
@ -83,6 +84,7 @@
margin: auto;
background: svg-load('./assets/img/icon/add-icon.svg', fill=$color-primary) no-repeat 100%;
background-size: contain;
transition: all .3s ease;
}
&:hover:after {
@ -99,6 +101,7 @@
margin: auto;
background: svg-load('./assets/img/icon/play.svg', fill=#FFFF) no-repeat 100%;
background-size: contain;
transition: all .3s ease;
}
&:hover:after {
@ -116,6 +119,7 @@
margin: auto;
background: svg-load('./assets/img/icon/pause.svg', fill=#FFFF) no-repeat 100%;
background-size: contain;
transition: all .3s ease;
}
&:hover:after {

View File

@ -5,9 +5,10 @@ $document-width-s: 730px;
$document-width-xs: 640px;
$document-width-xxs: 480px;
$color-primary: #5E5BFC;
$color-white: #FFFFFF;
:root {
--color-black: #232323;
--color-white: #FFFFFF;
--color-white: $color-white;
--color-white-darker: #E7E7E7;
--color-white-opacity: #BBB9CA;
--bg-wrapper-modal: #000000E5;

View File

@ -0,0 +1,10 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="current" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_47_1475)">
<path d="M12 3C12.2549 3.00028 12.5 3.09788 12.6854 3.27285C12.8707 3.44782 12.9822 3.68695 12.9972 3.94139C13.0121 4.19584 12.9293 4.44638 12.7657 4.64183C12.6021 4.83729 12.3701 4.9629 12.117 4.993L12 5H7C6.75507 5.00003 6.51866 5.08996 6.33563 5.25272C6.15259 5.41547 6.03566 5.63975 6.007 5.883L6 6V18C6.00003 18.2449 6.08996 18.4813 6.25272 18.6644C6.41547 18.8474 6.63975 18.9643 6.883 18.993L7 19H11.5C11.7549 19.0003 12 19.0979 12.1854 19.2728C12.3707 19.4478 12.4822 19.687 12.4972 19.9414C12.5121 20.1958 12.4293 20.4464 12.2657 20.6418C12.1021 20.8373 11.8701 20.9629 11.617 20.993L11.5 21H7C6.23479 21 5.49849 20.7077 4.94174 20.1827C4.38499 19.6578 4.04989 18.9399 4.005 18.176L4 18V6C3.99996 5.23479 4.29233 4.49849 4.81728 3.94174C5.34224 3.38499 6.06011 3.04989 6.824 3.005L7 3H12ZM17.707 8.464L20.535 11.293C20.7225 11.4805 20.8278 11.7348 20.8278 12C20.8278 12.2652 20.7225 12.5195 20.535 12.707L17.707 15.536C17.5194 15.7235 17.2649 15.8288 16.9996 15.8287C16.7344 15.8286 16.48 15.7231 16.2925 15.5355C16.105 15.3479 15.9997 15.0934 15.9998 14.8281C15.9999 14.5629 16.1054 14.3085 16.293 14.121L17.414 13H12C11.7348 13 11.4804 12.8946 11.2929 12.7071C11.1054 12.5196 11 12.2652 11 12C11 11.7348 11.1054 11.4804 11.2929 11.2929C11.4804 11.1054 11.7348 11 12 11H17.414L16.293 9.879C16.1054 9.69149 15.9999 9.43712 15.9998 9.17185C15.9997 8.90658 16.105 8.65214 16.2925 8.4645C16.48 8.27686 16.7344 8.17139 16.9996 8.1713C17.2649 8.1712 17.5194 8.27649 17.707 8.464Z" fill="current"/>
</g>
<defs>
<clipPath id="clip0_47_1475">
<rect width="24" height="24" fill="current"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -0,0 +1,4 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M19.7269 20.447C19.2719 19.171 18.267 18.044 16.87 17.24C15.473 16.436 13.7609 16 11.9999 16C10.2389 16 8.52695 16.436 7.12995 17.24C5.73295 18.044 4.72795 19.171 4.27295 20.447" stroke="current" stroke-width="2" stroke-linecap="round"/>
<path d="M12 12C14.2091 12 16 10.2091 16 8C16 5.79086 14.2091 4 12 4C9.79086 4 8 5.79086 8 8C8 10.2091 9.79086 12 12 12Z" stroke="current" stroke-width="2" stroke-linecap="round"/>
</svg>

After

Width:  |  Height:  |  Size: 531 B

View File

@ -24,7 +24,7 @@
{{ item.title }}
</router-link>
<button v-else-if="item.title" class="button" :class="[item.icon, showAuthentication&&'m--active']" @click="handlerClick(item.action)">{{ item.title }}</button>
<button v-else class="button button-violet" @click="handlerClick(item.action)">{{ user.first_name || user.email }}</button>
<button v-else class="header__menu-icon" :class="[item.icon]" @click="handlerClick(item.action)"></button>
</li>
</ul>
<div class="header__burger" @click="handlerShowMenu">
@ -81,10 +81,18 @@ export default {
class: 'header__btn'
},
{
name: 'home',
name: 'profile',
role: 'auth',
icon: 'm--profile',
action: 'profile',
class: 'header__btn'
class:'m--tools'
},
{
name: 'exit',
role: 'auth',
icon: 'm--exit',
action: 'exit',
class:'m--tools'
},
],
showMenu: true,
@ -123,6 +131,10 @@ export default {
if (methods==='profile'){
this.next('profile')
}
if(methods==='exit'){
this.$store.dispatch('deathUser');
this.next('home')
}
},
next(name){
this.$router.push({name})

View File

@ -89,14 +89,6 @@ export default {
formLogin: {},
formRegistration: {},
registerForm: [
{
$formkit: 'text',
name: 'first_name',
label: 'ваше имя',
placeholder: 'Ваше Имя',
validation: 'required',
outerClass: 'field--required'
},
{
$formkit: 'text',
name: 'email',
@ -112,6 +104,14 @@ export default {
placeholder: 'Придумайте пароль',
validation: 'required',
outerClass: 'field--required'
},
{
$formkit: 'password',
name: 'repeatPassword',
label: 'Повторите пароль',
placeholder: 'Повторите пароль',
validation: 'required',
outerClass: 'field--required'
}
],
loginForm: [
@ -144,7 +144,7 @@ export default {
changeTab(tab) {
this.currentTabsItem = tab;
},
submitHandler() {
submitHandler(data, node) {
if (this.currentTabsItem === 'login') {
app.loginUser(this.formLogin).then(res=>{
this.$store.dispatch('setToken', res);
@ -156,21 +156,38 @@ export default {
console.log(err)
})
}).catch(err=>{
console.log(err)
node.setErrors(
[err.detail],
err.error
)
})
} else {
app.createUser(this.formRegistration).then(res=>{
this.$store.dispatch('setToken', res);
app.user().then(user=>{
this.$store.dispatch('setUser', user);
this.close();
this.next('profile');
if (this.formRegistration.password === this.formRegistration.repeatPassword){
app.createUser(this.formRegistration).then(res=>{
this.$store.dispatch('setToken', res);
app.user().then(user=>{
this.$store.dispatch('setUser', user);
this.close();
this.next('profile');
}).catch(err=>{
console.log(err)
})
}).catch(err=>{
node.setErrors(
[err.detail],
err.error
)
console.log(err)
})
}).catch(err=>{
console.log(err)
})
}else {
node.setErrors(
['Пароли не совпадают'],
{
password: '',
repeatPassword: '',
}
)
}
}
},

View File

@ -1,26 +0,0 @@
<template>
<ContentLoader
viewBox="0 0 1920 40"
:speed="2"
primaryColor="#bbb9ca"
secondaryColor="#ecebeb"
>
<rect x="68" y="18" rx="2" ry="2" width="25" height="5" />
<rect x="444" y="11" rx="2" ry="2" width="75" height="10" />
<rect x="68" y="11" rx="2" ry="2" width="25" height="5" />
<rect x="45" y="29" rx="2" ry="2" width="538" height="6" />
<rect x="9" y="10" rx="2" ry="2" width="25" height="25" />
<rect x="22" y="21" rx="0" ry="0" width="6" height="2" />
<circle cx="54" cy="17" r="8" />
<rect x="523" y="11" rx="2" ry="2" width="58" height="10" />
<rect x="101" y="11" rx="2" ry="2" width="13" height="13" />
</ContentLoader>
</template>
<script>
import { ContentLoader } from "vue-content-loader"
export default {
name: 'playLoader',
components: [ContentLoader]
}
</script>

View File

@ -1,72 +1,87 @@
<template>
<div class="player">
<playLoader v-if="false"/>
<template v-else>
<div class="player__cover">
<img :src="currentPlay.art" alt="player"/>
</div>
<div class="player__content">
<div class="player__top">
<div class="player__cover">
<q-skeleton v-if="loaderPlay" height="100%"/>
<img v-else :src="currentPlay.art" alt="player"/>
</div>
<div class="player__content">
<div class="player__top">
<q-skeleton v-if="loaderPlay" type="circle" class="player__btn m--skeleton"/>
<template v-else>
<button v-if="currentPlay.isPlay" @click="handlerPause" class="button player__btn m--pause">
</button>
<button v-else @click="handlerPlay" class="button player__btn m--play">
</button>
<div class="player__executor">
</template>
<div class="player__executor">
<q-skeleton v-if="loaderPlay"/>
<template v-else>
{{ currentPlay.title || '—' }}
<span>{{ currentPlay.artist || '—' }}</span>
</div>
<div class="player__favorites" :class="[isFavorites&&'m--active']" @click="handlerFavorites">
</div>
<div class="player__tools">
<FormKit
v-model="isUserMusic"
type="toggle"
label="Включить мою музыку"
:disabled="!user"
/>
<div class="player__volume">
<span @click="setVolume"/>
<input type="range" v-model="player.volume" @change="changeVolume">
</div>
</div>
</template>
<span>
<q-skeleton v-if="loaderPlay"/>
<template v-else>
{{ currentPlay.artist || '—' }}
</template>
</span>
</div>
<div class="player__bottom">
<div class="player__time" :class="!isUserMusic&&'m--ether'">
<template v-if="isUserMusic">
{{ getTime(playerInfo.currentTime) }}/{{ getTime(playerInfo.duration) }}
</template>
<template v-else>
Эфир
</template>
</div>
<div class="player__progress">
<input :disabled="!isUserMusic" type="range" v-model="playerInfo.progress">
<q-skeleton v-if="loaderPlay" class="player__favorites m--skeleton"/>
<div v-else class="player__favorites" :class="[isFavorites&&'m--active']" @click="handlerFavorites">
</div>
<div class="player__tools">
<q-skeleton v-if="loaderPlay" class="player__tools m--skeleton"/>
<FormKit
v-else
v-model="isUserMusic"
type="toggle"
label="Включить мою музыку"
:disabled="!user?.id"
/>
<q-skeleton v-if="loaderPlay" class="player__tools m--skeleton"/>
<div v-else class="player__volume">
<span @click="changeVolume('set')"/>
<input type="range" v-model="songVolume" @change="changeVolume">
</div>
</div>
</div>
</template>
<div class="player__bottom">
<div class="player__time" :class="!loaderPlay&&!isUserMusic&&'m--ether'">
<q-skeleton v-if="loaderPlay"/>
<template v-else-if="isUserMusic">
{{ getTime(playerInfo.currentTime) }} / {{ getTime(playerInfo.duration) }}
</template>
<template v-else>
Эфир
</template>
</div>
<div class="player__progress">
<q-skeleton v-if="loaderPlay" height="5px"/>
<input v-else :disabled="!isUserMusic" type="range" v-model="playerInfo.progress">
</div>
</div>
</div>
</div>
</template>
<script>
import {audio as Player, app} from "@/services";
import PlayLoader from "components/player-loader.vue";
import {app, audio as Player} from "@/services";
export default {
name: 'player',
components: {PlayLoader},
components: {},
data() {
return {
audioUrl: 'http://82.97.242.49:18000/radio.mp3',
isFavorites: false,
isPlayRadio: true,
isPlayRadio: false,
connection: null,
isUserMusic: !this.$store.state.currentPlay.live,
songVolume: this.$store.state.currentPlay.volume,
playerInfo: {
progress: 0,
currentTime: 0,
duration: 0
}
},
}
},
computed: {
@ -81,20 +96,23 @@ export default {
},
userSongList() {
return this.$store.state.userFavorite?.songs || []
},
loaderPlay() {
return this.$store.state.currentPlay.isLoader
}
},
watch: {
'currentPlay': {
immediate: false,
handler(to, from) {
if (this.isUserMusic !== !this.currentPlay.live) {
if (this.isUserMusic === this.currentPlay.live) {
this.isUserMusic = !this.currentPlay.live;
}
if (to.id !== from.id && this.user.id) {
if (to.id !== from.id && this.user?.id) {
this.checkSongIsFavorite();
}
if (!this.currentPlay.live && to.id !== from.id) {
this.getAudio(this.userSongList[0].azura_id);
this.getAudio(this.currentPlay.azura_id);
}
},
},
@ -109,20 +127,20 @@ export default {
},
created() {
this.connectionPlayer();
if (this.user.id) {
this.checkSongIsFavorite();
}
},
mounted() {
console.log(this.currentPlay)
this.$store.dispatch('initPlayer');
if (this.user?.id) {
this.checkSongIsFavorite();
}
this.playerInfo.progress = this.currentPlay.live ? 100 : 0;
if (!this.currentPlay.live) {
console.log(this.currentPlay)
if (!this.currentPlay.live && this.userSongList?.length > 0) {
this.$store.dispatch('setCurrentPlay', {...this.userSongList[0], live: false});
this.getAudio(this.userSongList[0].azura_id);
if (this.player.target){
this.player.target.addEventListener('timeupdate',this.updateProgress)
this.getAudio(this.userSongList[0]?.azura_id);
if (this.player.target) {
this.player.target.addEventListener('timeupdate', this.updateProgress)
}
}
},
@ -136,10 +154,18 @@ export default {
this.connection.onHandler(this.getPlaying);
},
checkSongIsFavorite() {
console.debug(this.currentPlay.azura_id || this.currentPlay.id, this.currentPlay.title)
app.getCheckFavoriteSong(this.currentPlay.azura_id || this.currentPlay.id).then(res => {
this.isFavorites = true;
this.isFavorites = res.is_favorite;
}).catch(err => {
this.isFavorites = false;
console.error(err)
})
},
removeFavorites(song) {
app.removeFavorites(song).then(() => {
this.getSongList();
}).catch(err => {
this.showLoader = false;
console.error(err)
})
},
@ -152,23 +178,29 @@ export default {
console.log('data.np.station.listen_url', data.np.station.listen_url)
this.$store.dispatch('changePlayer', data.np.station.listen_url);
}
this.$store.dispatch('setCurrentPlay', {
const params = {
...this.currentPlay,
...data.np.now_playing.song,
live: true
});
azura_id: data.np.now_playing.song.id,
isLoader: false,
live: true,
}
delete params.unique_id;
this.$store.dispatch('setCurrentPlay', params);
}
}
},
updateProgress(e) {
this.playerInfo = {
...this.playerInfo,
progress: this.player.target.currentTime / this.player.target.duration * 100,
currentTime: this.player.target.currentTime,
duration: this.player.target.duration
currentTime: this.player.target.currentTime
}
if (this.player.target.currentTime === this.player.target.duration){
this.getAudio(this.userSongList[1]?.azura_id);
}
},
handlerPlay() {
console.log(this.player.target.src)
this.$store.dispatch('handlerPlayer', {play: true});
},
handlerPause() {
@ -185,6 +217,7 @@ export default {
if (this.user?.id) {
const params = {...this.currentPlay, azura_id: this.currentPlay.id};
if (!this.isFavorites) {
delete params.id;
app.createFavoriteForUser(params).then(() => {
this.isFavorites = !this.isFavorites;
this.getSongList();
@ -193,30 +226,45 @@ export default {
})
} else {
console.log(params)
// app.removeFavoriteForUser(params).then(()=>{
// this.isFavorites = !this.isFavorites;
// this.getSongList();
// }).catch(err=>{
// console.error(err)
// })
app.removeFavorites(params).then(()=>{
this.getSongList();
}).catch(err=>{
console.error(err)
})
}
} else {
this.$emit('shopAuthentication', true)
}
},
setVolume() {
this.$store.dispatch('handlerPlayer', {volume: 100});
},
changeVolume() {
this.$store.dispatch('handlerPlayer', {volume: 100});
changeVolume(type) {
let volume = this.songVolume;
if (type === 'set') {
volume = this.songVolume === 0 ? 0.9 : 0.01;
this.songVolume = this.songVolume === 0 ? 100 : 0;
} else {
volume = this.songVolume / 100;
}
if (volume === 0) volume = 0.01
this.$store.dispatch('handlerPlayer', {volume});
},
getAudio(id) {
app.getAudio(id).then(res => {
const blob = new Blob([res], {type: 'application/audio'});
const audioUrl = URL.createObjectURL(blob);
this.$store.dispatch('setCurrentPlay', {...this.currentPlay, isLoader: false})
this.$store.dispatch('changePlayer', audioUrl);
this.player.target.addEventListener('timeupdate', this.updateProgress);
blob.arrayBuffer().then(buffer => {
var audioContext = new (window.AudioContext || window.webkitAudioContext)();
audioContext.decodeAudioData(buffer, (decodedData) => {
this.playerInfo.duration = decodedData.duration;
});
});
}).catch(err => {
this.$store.dispatch('setCurrentPlay', {...this.currentPlay, isLoader: false})
console.debug(err)
})
},
@ -225,11 +273,10 @@ export default {
console.log('избранное')
this.getAudio(this.userSongList[0].azura_id);
this.playerInfo.progress = 0;
this.player.target.addEventListener('timeupdate', this.updateProgress)
this.$store.dispatch('setCurrentPlay', {...this.userSongList[0], live: false});
this.$store.dispatch('setCurrentPlay', {...this.userSongList[0], live: false, isLoader: true});
} else {
this.playerInfo.progress = 100;
this.$store.dispatch('setCurrentPlay', {...this.currentPlay, live: true});
this.$store.dispatch('setCurrentPlay', {...this.currentPlay, live: true, isLoader: true});
console.log('поток')
}
},
@ -239,9 +286,10 @@ export default {
let paddedMinutes = minutes < 10 ? "0" + minutes : minutes;
let paddedSeconds = seconds < 10 ? "0" + seconds : seconds;
if (!paddedMinutes) paddedMinutes = '00';
if (!paddedSeconds) paddedSeconds = '00';
return `${paddedMinutes}:${paddedSeconds}`;
}
},
}
}
</script>

View File

@ -31,7 +31,7 @@
<div class="rubric-modal__description">
{{rubrik.description}}
</div>
<button class="button m--fit-content m--white m--arrow" v-if="user.id">Написать</button>
<button class="button m--fit-content m--white m--arrow" v-if="user?.id">Написать</button>
</template>
</vue-final-modal>

View File

@ -20,7 +20,7 @@
{{song.artist}}
</div>
<div class="song-item__tools">
<button class="button song-item__btn m--small m--favorites"></button>
<button class="button song-item__btn m--small m--favorites" @click.stop="removeSong"></button>
<button class="button song-item__btn m--small m--add"></button>
</div>
</div>
@ -71,6 +71,9 @@ export default {
},
handlerSelectSong(){
this.$emit('selectSong', {...this.song, live: false})
},
removeSong(){
this.$emit('removeSong', this.song);
}
}
}

View File

@ -4,11 +4,12 @@
v-for="song in songList"
:key="song"
:song="song"
:playSong="!currentPlay.live && song.id === currentPlay.id? currentPlay.isPlay: false"
:selectSong="!currentPlay.live && song.id === currentPlay.id"
:playSong="song.azura_id === currentPlay.azura_id? currentPlay.isPlay: false"
:selectSong="song.azura_id === currentPlay.azura_id"
@selectSong="handlerSelectSong"
@playSong="handlerPlaySong"
@pauseSong="handlerPauseSong"
@removeSong="removeSong"
/>
</div>
</template>
@ -35,15 +36,22 @@ export default {
},
methods: {
handlerSelectSong(params) {
this.$store.dispatch('setCurrentPlay', {...this.currentPlay, ...params});
this.$store.dispatch('setCurrentPlay', {...this.currentPlay, ...params, isLoader: true});
console.log('handlerSelectSong')
},
handlerPlaySong(params) {
this.$store.dispatch('setCurrentPlay', params);
console.log('handlerPlaySong')
// this.$store.dispatch('handlerPlayer', {pause: true});
},
handlerPauseSong(params) {
this.$store.dispatch('setCurrentPlay', params);
console.log('handlerPauseSong')
// this.$store.dispatch('handlerPlayer', {play: true});
},
removeSong(song){
this.$emit('removeSong', song)
}
}
}
</script>

View File

@ -1,20 +1,20 @@
<!DOCTYPE html>
<html lang="ru">
<head>
<head>
<meta charset="utf-8">
<meta name="format-detection" content="telephone=no">
<meta name="msapplication-tap-highlight" content="no">
<meta name="viewport" content="user-scalable=yes, initial-scale=1, maximum-scale=5, minimum-scale=1, width=device-width<% if (ctx.mode.cordova || ctx.mode.capacitor) { %>, viewport-fit=cover<% } %>">
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
<link rel="manifest" href="/site.webmanifest">
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5">
<meta name="msapplication-TileColor" content="#00a300">
<meta name="theme-color" content="#119b58">
</head>
<body>
<!-- DO NOT touch the following DIV -->
<div id="q-app"></div>
</body>
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
<link rel="manifest" href="/site.webmanifest">
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5">
<meta name="msapplication-TileColor" content="#00a300">
<meta name="theme-color" content="#119b58">
</head>
<body>
<!-- DO NOT touch the following DIV -->
<div id="q-app"></div>
</body>
</html>

View File

@ -41,7 +41,7 @@ export default route(function (/* { store, ssrContext } */) {
Router.beforeEach((to, from, next) => {
if (to.matched.some(record => record.meta.requiresAuth) && !process.env.SERVER) {
if (store.state.user && store.state.user.id) {
if (store.state.user && store.state.user?.id) {
next();
} else {
next({ name: 'home' });

View File

@ -88,6 +88,14 @@ export default class extends REST {
});
}
static removeFavorites(params) {
return this._post(`radio/song/delete_song`, {}, params).then((data) => {
return data;
}).catch((error) => {
throw new RESTError(error, 'Ошибка при получении рубрик');
});
}

View File

@ -19,12 +19,13 @@ export default createStore({
id: 1
},
currentPlay: {
isPlay: false
isPlay: false,
isLoader: false,
live: true,
volume: 50,
},
player: {
target: null,
volume: 50,
live: true,
},
userFavorite: {
podcast: [],
@ -60,12 +61,16 @@ export default createStore({
state.player.target.src = '';
state.player.target.preload = 'auto';
state.player.target.controls = true;
state.player.target.volume = 0.5;
console.log('initPlayer', state.player.target)
},
changePlayer(state, params) {
const awaitPlay = () => {
if (state.player.target.readyState >= 4) {
state.player.target.play();
if (state.currentPlay.isPlay){
state.player.target.play();
}
state.currentPlay.isLoader = false;
state.player.target.removeEventListener('canplaythrough', awaitPlay);
} else {
awaitPlay();
@ -74,9 +79,10 @@ export default createStore({
state.player.target.src = params;
state.player.src = params;
if (state.currentPlay.isPlay){
state.player.target.addEventListener('canplaythrough', awaitPlay)
}
console.log(state.player.target.src)
// state.currentPlay.isLoader = true;
state.player.target.addEventListener('canplaythrough', awaitPlay)
},
handlerPlayer(state, params) {
if (params.pause) {
@ -84,9 +90,10 @@ export default createStore({
state.player.target.pause();
}
if (params.play) {
state.currentPlay.isPlay = true;
console.log(state.player.target.readyState)
state.player.target.play();
if (state.player.target.readyState >= 3){
state.currentPlay.isPlay = true;
state.player.target.play();
}
}
if (params.volume) {
state.player.target.volume = params.volume;

View File

@ -26,7 +26,7 @@
Загрузка данных
</div>
</template>
<SongList v-else :songList="userFavorite.songs"/>
<SongList v-else :songList="userFavorite.songs" @removeSong="removeFavorites"/>
</template>
</div>
</template>
@ -97,6 +97,14 @@ export default {
changeTab(tab) {
this.currentTabsItem = tab;
this.$router.push({name: this.$route.name, hash: `#${tab}`});
},
removeFavorites(song){
app.removeFavorites(song).then(() => {
this.getSongList();
}).catch(err => {
this.showLoader = false;
console.error(err)
})
}
}
}