This commit is contained in:
Stepan Fedyanin 2024-06-21 18:09:59 +05:00
parent 08e9541177
commit 36aa2bd206
13 changed files with 246 additions and 41 deletions

View File

@ -7,7 +7,7 @@ ROBOTS_USER_AGENT=*
ROBOTS_ALLOW=
ROBOTS_DISALLOW=["/"]
SERVICE_SELF_URL=//it-radio.flexidev.ru
SERVICE_URL=//82.97.242.49
SERVICE_URL=//it-radio.flexidev.ru
SERVICE_URL_AUDIO=//82.97.242.49:10084
SERVICE_PROTOCOL=http
SERVICE_PORT=8000

View File

@ -6,11 +6,12 @@ CACHE_STORAGE=tempStorage
ROBOTS_USER_AGENT=*
ROBOTS_ALLOW=
ROBOTS_DISALLOW=["/"]
SERVICE_SELF_URL=//tender.alidi.ru
SERVICE_URL=//backend.tender.alidi.ru
SERVICE_SELF_URL=//itradio.team
SERVICE_URL=//itradio.team
SERVICE_URL_AUDIO=//82.97.242.49:10084
SERVICE_PROTOCOL=https
SERVICE_PORT=8000
SERVICE_API=
SERVICE_API=/api
SERVICE_ON_LOCAL=false
SENTRY_DSN=https://e6dd82de128240cd8858fc6d47a0fff9@glitchtip.flexidev.ru/6
METRIKA_ID=

View File

@ -11,6 +11,7 @@
"serve": "npx cross-env NODE_ENV=development quasar dev",
"serve:ssr": "quasar dev -m ssr",
"build": "npx cross-env NODE_ENV=development quasar build",
"build:prod": "npx cross-env NODE_ENV=production quasar build",
"build:ssr": "quasar build -m ssr",
"build:dev": "quasar build",
"build:ssr:dev": "npx cross-env NODE_ENV=development quasar build -m ssr"

View File

@ -43,6 +43,9 @@
border: 1px solid var(--color-primary);
}
}
&.m--hidden{
display: none;
}
}
&__checkbox {
&-label{

View File

@ -1,6 +1,40 @@
.playlist {
position: relative;
z-index: 2;
&__header{
display: flex;
align-items: center;
gap: calc(var(--space-between-block) / 2);
margin-bottom: var(--space-between-block);
}
&__title{
font-size: 32px;
margin: 0;
padding: 0;
&.m--margin{
margin-bottom: 1rem;
}
}
&__back{
width: 30px;
height: 30px;
background: svg-load('./assets/img/icon/arrow-right.svg', stroke=$color-white) no-repeat 100%;
cursor: url("./assets/img/icon/cursor.svg"), auto;
transition: all .3s ease;
&:hover{
background: svg-load('./assets/img/icon/arrow-right.svg', stroke=$color-primary) no-repeat 100%;
}
}
&__edit{
width: 30px;
height: 30px;
background: svg-load('./assets/img/icon/ellipsis.svg', fill=$color-white) no-repeat 100%;
cursor: url("./assets/img/icon/cursor.svg"), auto;
transition: all .3s ease;
&:hover{
background: svg-load('./assets/img/icon/ellipsis.svg', fill=$color-primary) no-repeat 100%;
}
}
&-roster {
display: flex;
flex-wrap: wrap;
@ -31,6 +65,27 @@
background-image: var(--linear-gradient);
margin-bottom: 1rem;
}
&__upload{
cursor: url("./assets/img/icon/cursor.svg"), auto;
border: none;
padding: 0;
background-clip: text;
color: transparent;
background-image: var(--linear-gradient-highlight);
margin: 0 0 var(--space-between-block);
transition: all .3s ease;
display: flex;
gap: 10px;
&:before{
content: '';
width: 20px;
height: 20px;
background: svg-load('./assets/img/icon/paper-clip.svg', fill=$color-primary) no-repeat 100%;
}
&:hover{
color: var(--color-white);
}
}
}
&-item {

View File

@ -25,9 +25,11 @@
</template>
</span>
</div>
<q-skeleton v-if="loaderPlay" class="player__favorites m--skeleton"/>
<div v-else class="player__favorites" :class="[isFavorites&&'m--active']" @click="handlerFavorites">
</div>
<template v-if="user?.id">
<q-skeleton v-if="loaderPlay" class="player__favorites m--skeleton"/>
<div v-else class="player__favorites" :class="[isFavorites&&'m--active']" @click="handlerFavorites">
</div>
</template>
<div class="player__tools">
<q-skeleton v-if="loaderPlay" class="player__tools m--skeleton"/>
<FormKit

View File

@ -1,7 +1,8 @@
<template>
<div class="playlist-item" @click="selectPlaylist">
<div class="playlist-item__cover"></div>
<div>{{playlist.title}}</div>
<div>{{playlist.name}}</div>
<div @click="editPlaylist">...</div>
</div>
</template>
@ -15,6 +16,9 @@ export default {
}
},
methods:{
editPlaylist(){
this.$emit('editPlaylist', this.playlist)
},
selectPlaylist(){
this.$emit('selectPlaylist', this.playlist)
}

View File

@ -5,6 +5,7 @@
:key="`playlist_${item.id}`"
:playlist="item"
@selectPlaylist="selectPlaylist"
@editPlaylist="editPlaylist"
/>
<div class="playlist-item m--create" @click="createPlaylist">
<div class="playlist-item__cover"></div>
@ -31,6 +32,9 @@ export default {
},
selectPlaylist(params) {
this.$router.push({name: 'playlist', params: {id: params.id}})
},
editPlaylist(params) {
this.$router.push({name: 'playlist-edit', params: {id: params.id}})
}
}
}

View File

@ -21,7 +21,7 @@
</div>
<div class="song-item__tools">
<button class="button song-item__btn m--small m--favorites" @click.stop="removeSong"></button>
<button class="button song-item__btn m--small m--add" :class="songAlreadyAddPlaylist&&'m--already'" @click.stop="songAlreadyAddPlaylist?removeToPlaylist:addPlaylist"></button>
<button class="button song-item__btn m--small m--add" :class="songAlreadyAddPlaylist&&'m--already'" @click.stop="songAlreadyAddPlaylist?removeToPlaylist():addPlaylist()"></button>
</div>
</div>
</template>

View File

@ -132,6 +132,21 @@ export default class extends REST {
throw new RESTError(error, 'Ошибка при получении плейлистов');
});
}
static removeSongToPlaylist(params) {
return this._post(`radio/playlists/delete_song_with_playlist`, {}, params).then((data) => {
return data;
}).catch((error) => {
throw new RESTError(error, 'Ошибка при удаления треков из плейлиста');
});
}
static updatePlaylist(params) {
return this._post(`radio/playlists/update_playlist`, {}, params).then((data) => {
return data;
}).catch((error) => {
throw new RESTError(error, 'Ошибка при удаления треков из плейлиста');
});
}
static createPlaylists() {
return this._post(`radio/playlists/create_playlist`, {}, {}).then((data) => {
return data;

View File

@ -8,7 +8,18 @@
{ name: 'Добавление плейлиста', route: { name: 'playlist-create' } }:
{ name: 'Редактирование плейлиста', route: { name: 'playlist-edit' } },
]"/>
<h1 class="h2">{{ $route.name==='playlist-create'?'Новый плейлист':playlist.name }}</h1>
<h1 class="h2 playlist__title m--margin">{{ $route.name === 'playlist-create' ? 'Новый плейлист' : playlist.name }}</h1>
<button class="playlist-edit__upload" @click="handlerUploadCover">Добавить обложку</button>
<div class="field__input m--hidden">
<input
id="cover"
ref="coverInput"
accept=".jpg,.png,.svg"
class="input"
type="file"
name="logo"
>
</div>
<FormKit
v-model="playlist.name"
type="text"
@ -25,7 +36,12 @@
Загрузка данных
</div>
</template>
<SongList v-else-if="songs.length>0" :songList="songs" class="m--column" @addPlaylist="addPlaylist"/>
<SongList
v-else-if="songsFiltered.length>0"
:songList="songsFiltered"
class="m--column"
@addPlaylist="addPlaylist"
/>
<div v-else>Каталог музыки пуст!</div>
</div>
<div class="playlist-edit__item">
@ -36,7 +52,13 @@
Загрузка данных
</div>
</template>
<SongList v-else-if="playlist.song?.length>0" :songList="playlist.song" class="m--column" :songAlreadyAdd="true" @removePlaylist="removePlaylist"/>
<SongList
v-else-if="playlist.song?.length>0"
:songList="playlist.song"
class="m--column"
:songAlreadyAdd="true"
@removePlaylist="removePlaylist"
/>
<div v-else>Добавьте музыку в плейлист!</div>
</div>
</div>
@ -64,44 +86,93 @@ export default {
this.getAllSong();
this.getPlaylist();
},
methods:{
getPlaylist(){
computed: {
songsFiltered() {
return this.songs.filter(song => {
const alreadyAdd = this.playlist.song.find(item => item.azura_id === song.azura_id)
return !alreadyAdd
})
}
},
methods: {
getPlaylist() {
this.showLoaderPlaylist = true;
app.getPlaylist(this.$route.params.id).then(res=>{
app.getPlaylist(this.$route.params.id).then(res => {
this.showLoaderPlaylist = false;
this.playlist = res;
}).catch(err=>{
}).catch(err => {
this.showLoaderPlaylist = false;
console.error(err)
})
},
getAllSong(){
getAllSong() {
this.showLoaderSongs = true;
app.getAllSong().then(res=>{
app.getAllSong().then(res => {
this.showLoaderSongs = false;
this.songs = res;
}).catch(err=>{
}).catch(err => {
this.showLoaderSongs = false;
console.error(err)
})
},
addPlaylist(song){
addPlaylist(song) {
console.log(song)
const params = {
playlist_id: this.$route.params.id,
...song
}
this.showLoaderSongs = true;
this.showLoaderPlaylist = true;
app.addSongToPlaylist(params).then(() => {
this.showLoaderPlaylist = false;
this.showLoaderSongs = false;
this.getPlaylist();
}).catch(err => {
this.showLoaderPlaylist = false;
this.showLoaderSongs = false;
console.error(err)
})
},
removePlaylist(song) {
const params = {
playlist_id: this.$route.params.id,
azura_id: song.azura_id
}
this.showLoaderSongs = true;
this.showLoaderPlaylist = true;
app.addSongToPlaylist(params).then(()=>{
app.removeSongToPlaylist(params).then(() => {
this.showLoaderPlaylist = false;
this.showLoaderSongs = false;
this.getPlaylist();
}).catch(err=>{
}).catch(err => {
this.showLoaderPlaylist = false;
this.showLoaderSongs = false;
console.error(err)
})
},
removePlaylist(){
handlerUploadCover(){
let logoInput = this.$refs.coverInput;
let click = new MouseEvent('click');
logoInput.onchange = this.uploadCover;
logoInput.dispatchEvent(click);
},
uploadCover(event){
let file = event.target.files ? event.target.files[0] : null
if (file) {
const data = new FormData();
data.append('playlist_art', file);
data.append('playlist_id', this.$route.params.id);
app.updatePlaylist(data).then((res) => {
this.showLoaderPlaylist = false;
this.showLoaderSongs = false;
this.playlist = res;
}).catch(err => {
this.showLoaderPlaylist = false;
this.showLoaderSongs = false;
console.error(err)
})
}
}
}
}

View File

@ -1,11 +1,55 @@
<template>
<div class="playlist">
<template v-if="showLoaderPlaylist">
<div class="loader">
<div class="spinner"/>
Загрузка данных
</div>
</template>
<template v-else>
<div class="playlist__header">
<div class="playlist__back" @click="handlerBack"></div>
<div class="h2 playlist__title">{{ playlist.name }}</div>
<div class="playlist__edit" @click="next({name: 'playlist-edit', params:{id:this.playlist.id}})"></div>
</div>
<SongList :songList="playlist.song" :songAlreadyAdd="true"/>
</template>
</div>
</template>
<script>
import {app} from "@/services";
import SongList from "@/components/song-list.vue";
export default {
name: 'playlist'
name: 'playlist',
components: {SongList},
data() {
return {
showLoaderPlaylist: false,
playlist: {}
}
},
created() {
this.getPlaylist();
},
methods: {
getPlaylist() {
this.showLoaderPlaylist = true;
app.getPlaylist(this.$route.params.id).then(res => {
this.showLoaderPlaylist = false;
this.playlist = res;
}).catch(err => {
this.showLoaderPlaylist = false;
console.error(err)
})
},
handlerBack() {
this.$router.go(-1);
},
next(params) {
this.$router.push(params);
}
}
}
</script>

View File

@ -1,6 +1,6 @@
<template>
<div class="app__content profile">
<template v-if="$route.name !== 'playlist-edit'">
<template v-if="$route.name !== 'playlist-edit' && $route.name !== 'playlist-create'">
<AppBreadcrumbs
:breadcrumbs="[
{ name: 'Главная', route: { name: 'home' } },
@ -89,21 +89,26 @@ export default {
}
},
watch: {
'$route.hash': {
'$route': {
immediate: true,
handler(to) {
if (to) {
this.currentTabsItem = to?.replace('#', '') || 'music';
} else {
this.currentTabsItem = 'music';
handler(to, from) {
if (!from && to?.hash && to?.name==='"profile"'){
console.log('1')
this.currentTabsItem = to?.hash.replace('#', '') || 'music';
}
},
},
'$route.name': {
immediate: false,
handler(to) {
if (to === 'playlist') {
this.currentTabsItem = 'playlists'
if (to?.hash !== from?.hash && to?.name === from?.name || !from?.name && !from?.hash){
console.log('2')
if (to.hash) {
this.currentTabsItem = to?.hash.replace('#', '') || 'music';
} else {
this.currentTabsItem = 'music';
}
}
else {
console.log('3')
if (to?.name === 'playlist') {
this.currentTabsItem = 'playlists'
}
}
},
},
@ -156,7 +161,7 @@ export default {
},
createPlayList() {
app.createPlaylists().then(res=>{
this.$router.push({name: 'playlist-edit'});
this.$router.push({name: 'playlist-create', params: {id: res.id}});
}).catch(err=>{
console.error(err)
})