Commit 80989c10 authored by Andreas Heimann's avatar Andreas Heimann

added playlists

parent 1f84e1dd
...@@ -262,7 +262,6 @@ main aside .search input { ...@@ -262,7 +262,6 @@ main aside .search input {
width: 100%; width: 100%;
font-family: 'Open Sans', sans-serif; font-family: 'Open Sans', sans-serif;
font-size: 14px; font-size: 14px;
background: transparent;
color: #fff; color: #fff;
border-radius: 4px; border-radius: 4px;
padding: 9px 20px; padding: 9px 20px;
...@@ -314,21 +313,6 @@ button.button-disabled, ...@@ -314,21 +313,6 @@ button.button-disabled,
opacity: 0.4; opacity: 0.4;
cursor: not-allowed; cursor: not-allowed;
} }
button.button-label,
.button.button-label {
background: transparent;
}
button.button-label:hover,
.button.button-label:hover {
background: rgba(255, 255, 255, 0.2);
color: #fff;
}
button.button-label:active,
.button.button-label:active {
background: #fff;
color: #222;
cursor: pointer;
}
input[type='range'] { input[type='range'] {
overflow: hidden; overflow: hidden;
width: 100%; width: 100%;
...@@ -361,6 +345,10 @@ input[type="range"]::-moz-range-track { ...@@ -361,6 +345,10 @@ input[type="range"]::-moz-range-track {
input[type="range"]::-ms-fill-lower { input[type="range"]::-ms-fill-lower {
background-color: #e22c78; background-color: #e22c78;
} }
.flex-break {
flex-basis: 100%;
height: 0;
}
.song-row { .song-row {
display: grid; display: grid;
grid-template-rows: auto 1fr; grid-template-rows: auto 1fr;
...@@ -378,7 +366,24 @@ input[type="range"]::-ms-fill-lower { ...@@ -378,7 +366,24 @@ input[type="range"]::-ms-fill-lower {
.song-row .pagination .button { .song-row .pagination .button {
margin-left: 10px; margin-left: 10px;
} }
.song-list-noresults { .playlist-row {
display: grid;
grid-template-rows: auto 1fr;
grid-gap: 5px;
}
.playlist-row .playlist-list {
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-gap: 15px;
}
.playlist-row .pagination {
text-align: right;
margin-top: 25px;
}
.playlist-row .pagination .button {
margin-left: 10px;
}
.list-noresults {
background: rgba(255, 255, 255, 0.1); background: rgba(255, 255, 255, 0.1);
border-radius: 6px; border-radius: 6px;
padding: 25px; padding: 25px;
...@@ -452,16 +457,6 @@ input[type="range"]::-ms-fill-lower { ...@@ -452,16 +457,6 @@ input[type="range"]::-ms-fill-lower {
margin-top: 10px; margin-top: 10px;
height: 20px; height: 20px;
display: flex; display: flex;
/*
& img {
height: 18px;
margin-right: 10px;
opacity: 0.3;
&.active {
opacity: 1;
}
} */
} }
.song-item .song-metadata .song-difficulties .difficulty { .song-item .song-metadata .song-difficulties .difficulty {
background: #fff; background: #fff;
...@@ -553,6 +548,58 @@ input[type="range"]::-ms-fill-lower { ...@@ -553,6 +548,58 @@ input[type="range"]::-ms-fill-lower {
.user-item.inactive { .user-item.inactive {
box-shadow: 0px 2px 10px 5px rgba(0, 0, 0, 0.2); box-shadow: 0px 2px 10px 5px rgba(0, 0, 0, 0.2);
} }
.playlist-item {
height: 200px;
background: rgba(255, 255, 255, 0.1);
background-size: cover;
background-position: left center;
border-radius: 6px;
color: #fff;
text-decoration: none;
transition: 0.2s ease all;
}
.playlist-item .shade {
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.4);
transition: 0.2s ease all;
display: flex;
justify-content: center;
align-items: center;
}
.playlist-item .shade .content {
text-align: center;
text-shadow: 0 4px 18px rgba(0, 0, 0, 0.6);
}
.playlist-item .shade .content .title {
font-size: 32px;
margin-bottom: 5px;
font-family: 'Oswald', sans-serif;
}
.playlist-item .shade .content .title .official-badge {
display: inline-block;
font-family: 'Open Sans', sans-serif;
font-weight: bold;
font-size: 10px;
padding: 2px 8px;
border-radius: 4px;
background: #fff;
color: #000;
text-shadow: 0px 0px 0px transparent;
margin-left: 10px;
transform: translateY(-8px);
}
.playlist-item .shade .content .quickinfo {
font-size: 18px;
opacity: 0.6;
}
.playlist-item:hover {
cursor: pointer;
box-shadow: 0px 4px 20px 5px rgba(0, 0, 0, 0.4);
}
.playlist-item:hover .shade {
opacity: 0;
}
@media screen and (max-width: 550px) { @media screen and (max-width: 550px) {
.song-row .song-list { .song-row .song-list {
grid-template-columns: repeat(1, 1fr); grid-template-columns: repeat(1, 1fr);
...@@ -578,3 +625,4 @@ input[type="range"]::-ms-fill-lower { ...@@ -578,3 +625,4 @@ input[type="range"]::-ms-fill-lower {
grid-template-columns: repeat(6, 1fr); grid-template-columns: repeat(6, 1fr);
} }
} }
/*# sourceMappingURL=main.css.map */
\ No newline at end of file
{"version":3,"sources":["main.less"],"names":[],"mappings":"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","file":"main.css"}
\ No newline at end of file
...@@ -277,7 +277,6 @@ main { ...@@ -277,7 +277,6 @@ main {
width: 100%; width: 100%;
font-family: 'Open Sans', sans-serif; font-family: 'Open Sans', sans-serif;
font-size: 14px; font-size: 14px;
background: transparent;
color: #fff; color: #fff;
border-radius: 4px; border-radius: 4px;
padding: 9px 20px; padding: 9px 20px;
...@@ -361,6 +360,10 @@ input[type="range"]::-moz-range-track { ...@@ -361,6 +360,10 @@ input[type="range"]::-moz-range-track {
input[type="range"]::-ms-fill-lower { input[type="range"]::-ms-fill-lower {
background-color: rgb(226, 44, 120); background-color: rgb(226, 44, 120);
} }
.flex-break {
flex-basis: 100%;
height: 0;
}
.song-row { .song-row {
display: grid; display: grid;
grid-template-rows: auto 1fr; grid-template-rows: auto 1fr;
...@@ -380,7 +383,26 @@ input[type="range"]::-ms-fill-lower { ...@@ -380,7 +383,26 @@ input[type="range"]::-ms-fill-lower {
} }
} }
} }
.song-list-noresults { .playlist-row {
display: grid;
grid-template-rows: auto 1fr;
grid-gap: 5px;
& .playlist-list {
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-gap: 15px;
}
& .pagination {
text-align: right;
margin-top: 25px;
& .button {
margin-left: 10px;
}
}
}
.list-noresults {
background: rgba(255,255,255,0.1); background: rgba(255,255,255,0.1);
border-radius: 6px; border-radius: 6px;
padding: 25px; padding: 25px;
...@@ -388,8 +410,7 @@ input[type="range"]::-ms-fill-lower { ...@@ -388,8 +410,7 @@ input[type="range"]::-ms-fill-lower {
text-align: center; text-align: center;
} }
.song-item {
& .song-item {
background: rgba(255,255,255,0.1); background: rgba(255,255,255,0.1);
transition: 0.2s ease-in-out transform, 0.2s ease-in-out box-shadow; transition: 0.2s ease-in-out transform, 0.2s ease-in-out box-shadow;
overflow: hidden; overflow: hidden;
...@@ -479,17 +500,6 @@ input[type="range"]::-ms-fill-lower { ...@@ -479,17 +500,6 @@ input[type="range"]::-ms-fill-lower {
opacity: 1; opacity: 1;
} }
} }
/*
& img {
height: 18px;
margin-right: 10px;
opacity: 0.3;
&.active {
opacity: 1;
}
} */
} }
} }
&:not(.inactive):hover { &:not(.inactive):hover {
...@@ -578,6 +588,64 @@ input[type="range"]::-ms-fill-lower { ...@@ -578,6 +588,64 @@ input[type="range"]::-ms-fill-lower {
box-shadow: 0px 2px 10px 5px rgba(0, 0, 0, 0.2); box-shadow: 0px 2px 10px 5px rgba(0, 0, 0, 0.2);
} }
} }
.playlist-item {
height: 200px;
background: rgba(255,255,255,0.1);
background-size: cover;
background-position: left center;
border-radius: 6px;
color: #fff;
text-decoration: none;
transition: 0.2s ease all;
& .shade {
width: 100%;
height: 100%;
background: rgba(0,0,0, 0.4);
transition: 0.2s ease all;
display: flex;
justify-content: center;
align-items: center;
& .content {
text-align: center;
text-shadow: 0 4px 18px rgba(0, 0, 0, 0.6);
& .title {
font-size: 32px;
margin-bottom: 5px;
font-family: 'Oswald', sans-serif;
& .official-badge {
display: inline-block;
font-family: 'Open Sans', sans-serif;
font-weight: bold;
font-size: 10px;
padding: 2px 8px;
border-radius: 4px;
background: #fff;
color: #000;
text-shadow: 0px 0px 0px transparent;
margin-left: 10px;
transform: translateY(-8px);
}
}
& .quickinfo {
font-size: 18px;
opacity: 0.6;
}
}
}
&:hover {
cursor: pointer;
box-shadow: 0px 4px 20px 5px rgba(0, 0, 0, 0.4);
& .shade {
opacity: 0;
}
}
}
@media screen and (max-width: 550px) { @media screen and (max-width: 550px) {
.song-row { .song-row {
& .song-list { & .song-list {
......
.section-playlist-detail .cover {
width: 100%;
height: 300px;
background: rgba(255, 255, 255, 0.1);
background-size: cover;
background-position: left center;
}
.section-playlist-detail .cover .shade {
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.4);
transition: 0.2s ease all;
display: flex;
justify-content: center;
align-items: center;
}
.section-playlist-detail .cover .shade .content {
text-align: center;
text-shadow: 0px 4px 18px rgba(0, 0, 0, 0.6);
}
.section-playlist-detail .cover .shade .content .title {
font-size: 48px;
margin-bottom: 5px;
font-family: 'Oswald', sans-serif;
}
.section-playlist-detail .cover .shade .content .title .official-badge {
display: inline-block;
font-family: 'Open Sans', sans-serif;
font-weight: bold;
font-size: 12px;
padding: 2px 10px;
border-radius: 4px;
background: #fff;
color: #000;
text-shadow: 0px 0px 0px transparent;
margin-left: 10px;
transform: translateY(-11px);
}
.section-playlist-detail .cover .shade .content .quickinfo {
font-size: 18px;
opacity: 0.6;
}
.section-playlist-detail .playlist-content {
padding: 50px;
display: grid;
grid-template-columns: 500px 1fr;
grid-gap: 25px;
}
.section-playlist-detail .playlist-content .playlist-detail .playlist-uploader {
display: grid;
grid-template-columns: auto 1fr;
grid-gap: 15px;
margin-top: 25px;
}
.section-playlist-detail .playlist-content .playlist-detail .playlist-uploader .label {
align-self: center;
opacity: 0.6;
}
.section-playlist-detail .playlist-content .playlist-detail .playlist-description {
background: #383C3F;
border-radius: 4px;
display: grid;
grid-gap: 20px;
padding: 20px;
}
.section-playlist-detail .playlist-content .playlist-detail .playlist-description .text {
line-height: 1.5em;
opacity: 0.7;
}
/*# sourceMappingURL=playlistdetail.css.map */
\ No newline at end of file
{"version":3,"sources":["playlistdetail.less"],"names":[],"mappings":"AACI,wBAAE;EACE,WAAA;EACA,aAAA;EACA,oCAAA;EACA,sBAAA;EACA,gCAAA;;AAEA,wBAPF,OAOI;EACE,WAAA;EACA,YAAA;EACA,8BAAA;EACA,yBAAA;EACA,aAAA;EACA,uBAAA;EACA,mBAAA;;AAEA,wBAhBN,OAOI,OASI;EACE,kBAAA;EACA,4CAAA;;AAEA,wBApBV,OAOI,OASI,SAII;EACE,eAAA;EACA,kBAAA;EACA,aAAa,oBAAb;;AAEA,wBAzBd,OAOI,OASI,SAII,OAKI;EACE,qBAAA;EACA,aAAa,uBAAb;EACA,iBAAA;EACA,eAAA;EACA,iBAAA;EACA,kBAAA;EACA,gBAAA;EACA,WAAA;EACA,oCAAA;EACA,iBAAA;EACA,WAAW,iBAAX;;AAIR,wBAxCV,OAOI,OASI,SAwBI;EACE,eAAA;EACA,YAAA;;AAKhB,wBAAE;EACE,aAAA;EACA,aAAA;EACA,gCAAA;EACA,cAAA;;AAGI,wBAPN,kBAMI,iBACI;EACE,aAAA;EACA,+BAAA;EACA,cAAA;EACA,gBAAA;;AAEA,wBAbV,kBAMI,iBACI,mBAMI;EACE,kBAAA;EACA,YAAA;;AAIR,wBAnBN,kBAMI,iBAaI;EACE,mBAAA;EACA,kBAAA;EACA,aAAA;EACA,cAAA;EACA,aAAA;;AAEA,wBA1BV,kBAMI,iBAaI,sBAOI;EACE,kBAAA;EACA,YAAA","file":"playlistdetail.css"}
\ No newline at end of file
.section-playlist-detail {
& .cover {
width: 100%;
height: 300px;
background: rgba(255,255,255,0.1);
background-size: cover;
background-position: left center;
& .shade {
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.4);
transition: 0.2s ease all;
display: flex;
justify-content: center;
align-items: center;
& .content {
text-align: center;
text-shadow: 0px 4px 18px rgba(0, 0, 0, 0.6);
& .title {
font-size: 48px;
margin-bottom: 5px;
font-family: 'Oswald', sans-serif;
& .official-badge {
display: inline-block;
font-family: 'Open Sans', sans-serif;
font-weight: bold;
font-size: 12px;
padding: 2px 10px;
border-radius: 4px;
background: #fff;
color: #000;
text-shadow: 0px 0px 0px transparent;
margin-left: 10px;
transform: translateY(-11px);
}
}
& .quickinfo {
font-size: 18px;
opacity: 0.6;
}
}
}
}
& .playlist-content {
padding: 50px;
display: grid;
grid-template-columns: 500px 1fr;
grid-gap: 25px;
& .playlist-detail {
& .playlist-uploader {
display: grid;
grid-template-columns: auto 1fr;
grid-gap: 15px;
margin-top: 25px;
& .label {
align-self: center;
opacity: 0.6;
}
}
& .playlist-description {
background: #383C3F;
border-radius: 4px;
display: grid;
grid-gap: 20px;
padding: 20px;
& .text {
line-height: 1.5em;
opacity: 0.7;
}
}
}
}
}
\ No newline at end of file
...@@ -56,16 +56,18 @@ ...@@ -56,16 +56,18 @@
.section-song-detail .song-detail .song-actions { .section-song-detail .song-detail .song-actions {
margin-top: 25px; margin-top: 25px;
width: 500px; width: 500px;
display: flex;
transition: all 0.2s ease-in-out; transition: all 0.2s ease-in-out;
border-radius: 4px; border-radius: 4px;
overflow: hidden; overflow: hidden;
background: #fff; background: #fff;
} }
.section-song-detail .song-detail .song-actions .action, .section-song-detail .song-detail .song-actions .action-row {
.section-song-detail .song-detail .song-actions .action-player { display: flex;
}
.section-song-detail .song-detail .song-actions .action-row .action,
.section-song-detail .song-detail .song-actions .action-row .action-player {
background: linear-gradient(135deg, rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.3)); background: linear-gradient(135deg, rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.3));
width: 25%; flex-grow: 1;
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
...@@ -74,8 +76,8 @@ ...@@ -74,8 +76,8 @@
transition: all 0.2s ease-in-out; transition: all 0.2s ease-in-out;
cursor: pointer; cursor: pointer;
} }
.section-song-detail .song-detail .song-actions .action .icon, .section-song-detail .song-detail .song-actions .action-row .action .icon,
.section-song-detail .song-detail .song-actions .action-player .icon { .section-song-detail .song-detail .song-actions .action-row .action-player .icon {
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
...@@ -83,24 +85,21 @@ ...@@ -83,24 +85,21 @@
width: 48px; width: 48px;
font-size: 24px; font-size: 24px;
} }
.section-song-detail .song-detail .song-actions .action .volume, .section-song-detail .song-detail .song-actions .action-row .action .volume,
.section-song-detail .song-detail .song-actions .action-player .volume { .section-song-detail .song-detail .song-actions .action-row .action-player .volume {
width: 0px; width: 0px;
overflow: hidden; overflow: hidden;
padding-right: 0px; padding-right: 0px;
transition: all 0.2s ease-in-out; transition: all 0.2s ease-in-out;
} }
.section-song-detail .song-detail .song-actions .action:hover, .section-song-detail .song-detail .song-actions .action-row .action:hover,
.section-song-detail .song-detail .song-actions .action-player:hover { .section-song-detail .song-detail .song-actions .action-row .action-player:hover {
opacity: 0.6; opacity: 0.6;
} }
.section-song-detail .song-detail .song-actions.player-active .action { .section-song-detail .song-detail .song-actions .action-row.player-active .action-player {
width: calc((100% - 250px) / 3);
}
.section-song-detail .song-detail .song-actions.player-active .action-player {
width: 250px; width: 250px;
} }
.section-song-detail .song-detail .song-actions.player-active .action-player .volume { .section-song-detail .song-detail .song-actions .action-row.player-active .action-player .volume {
width: 170px; width: 170px;
padding-right: 20px; padding-right: 20px;
} }
...@@ -589,6 +588,95 @@ ...@@ -589,6 +588,95 @@
.section-song-detail .song-social .tab .form-add .button:hover { .section-song-detail .song-social .tab .form-add .button:hover {
opacity: 0.6; opacity: 0.6;
} }
.playlist-overlay {
display: none;
position: fixed;
top: 0px;
left: 0px;
right: 0px;
bottom: 0px;
z-index: 1200;
background: rgba(0, 0, 0, 0.6);
justify-content: center;
align-items: center;
user-select: none;
}
.playlist-overlay.active {
display: flex;
}
.playlist-overlay .close {
font-size: 32px;
color: #fff;
position: absolute;
top: 40px;
right: 40px;
cursor: pointer;
transition: 0.2s ease-in-out opacity;
}
.playlist-overlay .close:hover {
opacity: 0.6;
}
.playlist-overlay .overlay-content {
width: 500px;
background: #383c3f;
border-radius: 6px;
}
.playlist-overlay .overlay-content .title {
padding: 25px;
letter-spacing: 0.25em;
font-size: 14px;
font-weight: bold;
text-transform: uppercase;
}
.playlist-overlay .overlay-content .playlist-empty {
background: rgba(255, 255, 255, 0.1);
border-radius: 4px;
padding: 30px 15px;
text-align: center;
}
.playlist-overlay .overlay-content .playlist-list {
padding: 0px 25px;
display: grid;
grid-gap: 15px;
}
.playlist-overlay .overlay-content .playlist-list .playlist-item {
display: grid;
grid-template-columns: 30px 1fr;
grid-gap: 15px;
height: 24px;
align-items: center;
}
.playlist-overlay .overlay-content .playlist-list .playlist-item input[type="checkbox"] {
appearance: none;
border: 0;
border-radius: 4px;
width: 18px;
height: 18px;
outline: none;
}
.playlist-overlay .overlay-content .playlist-list .playlist-item input[type="checkbox"]:after {
content: "";
display: inline-block;
width: 18px;
border: 2px solid rgba(255, 255, 255, 0.2);
border-radius: 4px;
height: 18px;
}
.playlist-overlay .overlay-content .playlist-list .playlist-item input[type="checkbox"]:checked:after {
content: "\F012C";
font-family: "Material Design Icons";
font-size: 14px;
background: #fff;
color: #000;
}
.playlist-overlay .overlay-content .actions {
padding: 25px;
display: flex;
justify-content: flex-end;
}
.playlist-overlay .overlay-content .actions .button {
margin-left: 10px;
}
@media screen and (min-width: 1700px) { @media screen and (min-width: 1700px) {
.section-song-detail .song-social .tab.tab-spinplays .spinplays { .section-song-detail .song-social .tab.tab-spinplays .spinplays {
grid-template-columns: 1fr 1fr 1fr; grid-template-columns: 1fr 1fr 1fr;
...@@ -599,3 +687,4 @@ ...@@ -599,3 +687,4 @@
grid-template-columns: 1fr; grid-template-columns: 1fr;
} }
} }
/*# sourceMappingURL=songdetail.css.map */
\ No newline at end of file
{"version":3,"sources":["songdetail.less"],"names":[],"mappings":"AAAA;EACI,aAAA;EACA,gCAAA;EACA,cAAA;EACA,aAAA;;AAEA,oBAAE;EACE,2BAAA;EACA,sBAAA;EACA,kBAAA;EACA,QAAA;EACA,SAAA;EACA,UAAA;EACA,aAAA;EACA,WAAA;;AAEA,oBAVF,wBAUI;EACE,kBAAA;EACA,QAAA;EACA,SAAA;EACA,WAAA;EACA,UAAA;EACA,YAAY,+DAAZ;;AAKJ,oBADF,aACI;EACE,aAAA;EACA,+BAAA;EACA,mBAAA;EACA,kBAAA;EACA,gBAAA;;AAEA,oBARN,aACI,WAOI;EACE,iBAAA;EACA,kBAAA;EACA,oBAAA;EACA,YAAA;EACA,WAAA;EACA,kBAAA;EACA,2BAAA;EACA,sBAAA;;AAGJ,oBAnBN,aACI,WAkBI;EACE,aAAA;;AAEA,oBAtBV,aACI,WAkBI,eAGI;EACE,iBAAA;EACA,eAAA;EACA,kBAAA;;AAGJ,oBA5BV,aACI,WAkBI,eASI;EACE,kBAAA;;AAGJ,oBAhCV,aACI,WAkBI,eAaI;EACE,YAAA;;AAIZ,oBArCF,aAqCI;EACE,gBAAA;EACA,YAAA;EACA,gCAAA;EACA,kBAAA;EACA,gBAAA;EACA,gBAAA;;AAEA,oBA7CN,aAqCI,cAQI;EACE,aAAA;;AAEA,oBAhDV,aAqCI,cAQI,YAGI;AAAS,oBAhDrB,aAqCI,cAQI,YAGe;EACT,YAAY,+DAAZ;EACA,YAAA;EACA,aAAA;EACA,uBAAA;EACA,mBAAA;EACA,WAAA;EACA,qBAAA;EACA,gCAAA;EACA,eAAA;;AAEA,oBA3Dd,aAqCI,cAQI,YAGI,QAWI;AAAF,oBA3Dd,aAqCI,cAQI,YAGe,eAWP;EACE,aAAA;EACA,uBAAA;EACA,mBAAA;EACA,YAAA;EACA,WAAA;EACA,eAAA;;AAGJ,oBApEd,aAqCI,cAQI,YAGI,QAoBI;AAAF,oBApEd,aAqCI,cAQI,YAGe,eAoBP;EACE,UAAA;EACA,gBAAA;EACA,kBAAA;EACA,gCAAA;;AAGJ,oBA3Ed,aAqCI,cAQI,YAGI,QA2BG;AAAD,oBA3Ed,aAqCI,cAQI,YAGe,eA2BR;EACG,YAAA;;AASJ,oBArFd,aAqCI,cAQI,YAmCG,cAKK;EACE,YAAA;;AAEA,oBAxFlB,aAqCI,cAQI,YAmCG,cAKK,eAGI;EACE,YAAA;EACA,mBAAA;;AAMpB,oBAhGF,aAgGI;EACE,aAAA;EACA,0BAAA;EACA,cAAA;EACA,mBAAA;EACA,aAAA;EACA,kBAAA;EACA,gBAAA;;AAEA,oBAzGN,aAgGI,iBASI;EACE,aAAA;EACA,+BAAA;EACA,cAAA;;AAEA,oBA9GV,aAgGI,iBASI,MAKI;EACE,aAAA;EACA,uBAAA;EACA,mBAAA;EACA,eAAA;;AAGJ,oBArHV,aAgGI,iBASI,MAYI;EACE,kBAAA;;AAEA,oBAxHd,aAgGI,iBASI,MAYI,cAGI;EACE,YAAA;EACA,iBAAA;EACA,YAAA;;AAEA,oBA7HlB,aAgGI,iBASI,MAYI,cAGI,IAKG;EACG,UAAA;;AAKZ,oBAnIV,aAgGI,iBASI,MA0BI;EACE,kBAAA;EACA,YAAA;;AAIZ,oBAzIF,aAyII;EACE,aAAA;EACA,+BAAA;EACA,cAAA;EACA,gBAAA;;AAEA,oBA/IN,aAyII,eAMI;EACE,kBAAA;EACA,YAAA;;AAGR,oBApJF,aAoJI;EACE,mBAAA;EACA,kBAAA;EACA,gBAAA;EACA,aAAA;EACA,cAAA;EACA,aAAA;;AAEA,oBA5JN,aAoJI,kBAQI;EACE,kBAAA;EACA,YAAA;;AAEJ,oBAhKN,aAoJI,kBAYI;EACE,aAAA;EACA,eAAA;;AAEA,oBApKV,aAoJI,kBAYI,MAII;EACE,cAAA;EACA,kBAAA;EACA,mBAAA;EACA,WAAA;EACA,oCAAA;EACA,gBAAA;EACA,kBAAA;EACA,eAAA;EACA,qBAAA;EACA,gCAAA;;AAEA,oBAhLd,aAoJI,kBAYI,MAII,KAYG;EACG,eAAA;EACA,WAAA;EACA,gBAAA;;AAOhB,oBADF,aACI;EACE,aAAA;;AAEA,oBAJN,aACI,YAGI;EACE,eAAA;EACA,iBAAA;EACA,yBAAA;EACA,sBAAA;EACA,kBAAA;EACA,2BAAA;EACA,4BAAA;EACA,mBAAA;EACA,+BAAA;EACA,gCAAA;EACA,qBAAA;;AAEA,oBAjBV,aACI,YAGI,iBAaG,IAAI,SAAS;EACV,eAAA;EACA,mBAAA;EACA,gCAAA;;AAEJ,oBAtBV,aACI,YAGI,iBAkBG;EACG,UAAA;EACA,cAAA;EACA,mBAAA;;AAIZ,oBA7BF,aA6BI;EACE,mBAAA;EACA,kBAAA;EACA,2BAAA;EACA,aAAA;EACA,aAAA;EACA,cAAA;;AAGI,oBAtCV,aA6BI,KAQG,YACK;EACE,oCAAA;EACA,kBAAA;EACA,kBAAA;EACA,aAAA;EACA,oCAAA;EACA,cAAA;EACA,mBAAA;;AAEA,oBA/Cd,aA6BI,KAQG,YACK,iBASI;EACE,WAAA;EACA,eAAA;;AAGA,oBApDlB,aA6BI,KAQG,YACK,iBAaI,MACI;EACE,eAAA;;AAEJ,oBAvDlB,aA6BI,KAQG,YACK,iBAaI,MAII;EACE,eAAA;EACA,iBAAA;EACA,yBAAA;EACA,sBAAA;EACA,kBAAA;;AAEJ,oBA9DlB,aA6BI,KAQG,YACK,iBAaI,MAWI;EACE,YAAA;;AAGR,oBAlEd,aA6BI,KAQG,YACK,iBA4BI;EACE,qBAAA;EACA,WAAA;EACA,eAAA;EACA,iBAAA;EACA,qBAAA;EACA,YAAY,2EAAZ;EACA,kBAAA;EACA,kBAAA;EACA,yBAAA;EACA,gCAAA;;AAEA,oBA9ElB,aA6BI,KAQG,YACK,iBA4BI,eAYG;EACG,YAAA;;AAIZ,oBAnFV,aA6BI,KAQG,YA8CK;EACE,aAAA;EACA,cAAA;;AAEA,oBAvFd,aA6BI,KAQG,YA8CK,SAII;EACE,oCAAA;EACA,kBAAA;EACA,aAAA;EACA,gBAAA;;AAEA,oBA7FlB,aA6BI,KAQG,YA8CK,SAII,QAMI;EACE,aAAA;EACA,oCAAA;EACA,cAAA;;AAEA,oBAlGtB,aA6BI,KAQG,YA8CK,SAII,QAMI,UAKI;EACE,WAAA;EACA,YAAA;EACA,mBAAA;EACA,2BAAA;EACA,sBAAA;EACA,cAAA;EACA,WAAA;EACA,qBAAA;EACA,oCAAA;;AAEA,oBA7G1B,aA6BI,KAQG,YA8CK,SAII,QAMI,UAKI,QAWG;EACG,YAAA;;AAIJ,oBAlH1B,aA6BI,KAQG,YA8CK,SAII,QAMI,UAoBI,MACI;EACE,eAAA;EACA,iBAAA;EACA,kBAAA;EACA,cAAA;EACA,WAAA;EACA,qBAAA;EACA,oCAAA;;AAEA,oBA3H9B,aA6BI,KAQG,YA8CK,SAII,QAMI,UAoBI,MACI,UASG;EACG,YAAA;;AAGR,oBA/H1B,aA6BI,KAQG,YA8CK,SAII,QAMI,UAoBI,MAcI;EACE,aAAA;EACA,aAAA;EACA,+BAAA;EACA,mBAAA;;AAEA,oBArI9B,aA6BI,KAQG,YA8CK,SAII,QAMI,UAoBI,MAcI,SAMI,EAAC;EAAY,cAAA;;AACf,oBAtI9B,aA6BI,KAQG,YA8CK,SAII,QAMI,UAoBI,MAcI,SAOI,EAAC;EAAY,cAAA;;AAEf,oBAxI9B,aA6BI,KAQG,YA8CK,SAII,QAMI,UAoBI,MAcI,SASI;EACE,YAAA;;AAIZ,oBA7ItB,aA6BI,KAQG,YA8CK,SAII,QAMI,UAgDI;EACE,kBAAA;;AADJ,oBA7ItB,aA6BI,KAQG,YA8CK,SAII,QAMI,UAgDI,SAGE;EACI,WAAA;EACA,qBAAA;EACA,eAAA;EACA,YAAY,2EAAZ;EACA,kBAAA;EACA,iBAAA;EACA,oCAAA;;AAEA,oBAzJ9B,aA6BI,KAQG,YA8CK,SAII,QAMI,UAgDI,SAGE,QASK;EACG,YAAA;;AAMhB,oBAhKlB,aA6BI,KAQG,YA8CK,SAII,QAyEI;EACE,gBAAA;EACA,kBAAA;EACA,kBAAA;EACA,gBAAA;EACA,8BAAA;;AAEA,oBAvKtB,aA6BI,KAQG,YA8CK,SAII,QAyEI,SAOG;EACG,eAAA;;AAGR,oBA3KlB,aA6BI,KAQG,YA8CK,SAII,QAoFI;EACE,gBAAA;EACA,yBAAA;EACA,iBAAA;EACA,cAAA;EACA,eAAA;EACA,6BAAA;;AAEA,oBAnLtB,aA6BI,KAQG,YA8CK,SAII,QAoFI,eAQG;EACG,YAAA;;AAKhB,oBAzLV,aA6BI,KAQG,YAoJK;EACE,oCAAA;EACA,kBAAA;EACA,kBAAA;EACA,aAAA;EACA,+BAAA;EACA,cAAA;EACA,mBAAA;;AAEA,oBAlMd,aA6BI,KAQG,YAoJK,YASI;EACE,WAAA;EACA,eAAA;;AAGA,oBAvMlB,aA6BI,KAQG,YAoJK,YAaI,MACI;EACE,eAAA;EACA,iBAAA;EACA,sBAAA;EACA,kBAAA;EACA,yBAAA;;AAEJ,oBA9MlB,aA6BI,KAQG,YAoJK,YAaI,MAQI;EACE,YAAA;;AAOZ,oBAtNV,aA6BI,KAwLG,cACK;EACE,oCAAA;EACA,kBAAA;EACA,kBAAA;EACA,aAAA;EACA,oCAAA;EACA,cAAA;EACA,mBAAA;;AAEA,oBA/Nd,aA6BI,KAwLG,cACK,mBASI;EACE,WAAA;EACA,eAAA;;AAGA,oBApOlB,aA6BI,KAwLG,cACK,mBAaI,MACI;EACE,eAAA;EACA,iBAAA;EACA,sBAAA;EACA,kBAAA;EACA,yBAAA;;AAEJ,oBA3OlB,aA6BI,KAwLG,cACK,mBAaI,MAQI;EACE,YAAA;;AAGR,oBA/Od,aA6BI,KAwLG,cACK,mBAyBI;EACE,qBAAA;EACA,WAAA;EACA,eAAA;EACA,iBAAA;EACA,qBAAA;EACA,YAAY,2EAAZ;EACA,kBAAA;EACA,kBAAA;EACA,yBAAA;EACA,gCAAA;;AAEA,oBA3PlB,aA6BI,KAwLG,cACK,mBAyBI,eAYG;EACG,YAAA;;AAIZ,oBAhQV,aA6BI,KAwLG,cA2CK;EACE,aAAA;EACA,8BAAA;EACA,cAAA;;AAEA,oBArQd,aA6BI,KAwLG,cA2CK,WAKI;EACE,oCAAA;EACA,kBAAA;EACA,gBAAA;EACA,WAAA;EACA,qBAAA;;AAEA,oBA5QlB,aA6BI,KAwLG,cA2CK,WAKI,UAOI;EACE,WAAA;EACA,cAAA;EACA,mBAAA;EACA,oCAAA;EACA,2BAAA;EACA,sBAAA;EACA,oCAAA;;AAEA,oBArRtB,aA6BI,KAwLG,cA2CK,WAKI,UAOI,WASG;EACG,YAAA;;AAGR,oBAzRlB,aA6BI,KAwLG,cA2CK,WAKI,UAoBI;EACE,aAAA;EACA,aAAA;EACA,cAAA;EACA,mBAAA;EACA,oCAAA;;AAEA,oBAhStB,aA6BI,KAwLG,cA2CK,WAKI,UAoBI,UAOI;EACE,WAAA;EACA,YAAA;EACA,oCAAA;EACA,2BAAA;EACA,sBAAA;EACA,mBAAA;;AAEJ,oBAxStB,aA6BI,KAwLG,cA2CK,WAKI,UAoBI,UAeI,SACE;EACI,WAAA;EACA,qBAAA;EACA,eAAA;EACA,YAAY,2EAAZ;EACA,kBAAA;EACA,iBAAA;EACA,oCAAA;;AAEA,oBAlT9B,aA6BI,KAwLG,cA2CK,WAKI,UAoBI,UAeI,SACE,QASK;EACG,YAAA;;AAOxB,oBA1TV,aA6BI,KAwLG,cAqGK;EACE,oCAAA;EACA,kBAAA;EACA,kBAAA;EACA,aAAA;EACA,+BAAA;EACA,cAAA;EACA,mBAAA;;AAEA,oBAnUd,aA6BI,KAwLG,cAqGK,cASI;EACE,WAAA;EACA,eAAA;;AAGA,oBAxUlB,aA6BI,KAwLG,cAqGK,cAaI,MACI;EACE,eAAA;EACA,iBAAA;EACA,sBAAA;EACA,kBAAA;EACA,yBAAA;;AAEJ,oBA/UlB,aA6BI,KAwLG,cAqGK,cAaI,MAQI;EACE,YAAA;;AAMhB,oBAtVN,aA6BI,KAyTI;EACE,kBAAA;EACA,aAAA;EACA,0BAAA;EACA,cAAA;;AAEA,oBA5VV,aA6BI,KAyTI,UAMI;EACE,aAAA;EACA,gCAAA;EACA,cAAA;;AAEA,oBAjWd,aA6BI,KAyTI,UAMI,WAKI;EACE,aAAA;;AAEA,oBApWlB,aA6BI,KAyTI,UAMI,WAKI,iBAGI;EACE,iBAAA;EACA,kBAAA;EACA,kBAAA;EACA,eAAA;;AAEA,oBA1WtB,aA6BI,KAyTI,UAMI,WAKI,iBAGI,iBAMI;EACE,kBAAA;EACA,eAAA;EACA,UAAA;EACA,WAAA;EACA,UAAA;;AAEA,oBAjX1B,aA6BI,KAyTI,UAMI,WAKI,iBAGI,iBAMI,MAOG,QAAS;EACN,mCAAA;EACA,qCAAA;EACA,cAAA;;AAEJ,oBAtX1B,aA6BI,KAyTI,UAMI,WAKI,iBAGI,iBAMI,MAYG,QAAS;EACN,kCAAA;EACA,oCAAA;EACA,cAAA;;AAGR,oBA5XtB,aA6BI,KAyTI,UAMI,WAKI,iBAGI,iBAwBI;EACE,qCAAA;EACA,WAAA;EACA,YAAA;EACA,kBAAA;EACA,aAAA;EACA,uBAAA;EACA,mBAAA;EACA,0CAAA;;AAKhB,oBAzYV,aA6BI,KAyTI,UAmDI;EACE,iBAAA;;AAGJ,oBA7YV,aA6BI,KAyTI,UAuDI,MAAK;AAvDX,oBAtVN,aA6BI,KAyTI,UAuDwB;EAClB,WAAA;EACA,aAAa,uBAAb;EACA,eAAA;EACA,WAAA;EACA,oCAAA;EACA,kBAAA;EACA,iBAAA;EACA,WAAA;EACA,+DAAA;;AAEA,oBAxZd,aA6BI,KAyTI,UAuDI,MAAK,aAWF,IAAI,WAAW;AAAhB,oBAxZd,aA6BI,KAyTI,UAuDwB,SAWjB,IAAI,WAAW;EACZ,oCAAA;EACA,WAAA;EACA,YAAA;;AAEJ,oBA7Zd,aA6BI,KAyTI,UAuDI,MAAK,aAgBF;AAAD,oBA7Zd,aA6BI,KAyTI,UAuDwB,SAgBjB;EACG,UAAA;;AAEJ,oBAhad,aA6BI,KAyTI,UAuDI,MAAK,aAmBF;AAAD,oBAhad,aA6BI,KAyTI,UAuDwB,SAmBjB;EACG,+BAAA;;AAEJ,oBAnad,aA6BI,KAyTI,UAuDI,MAAK,aAsBD;AAAF,oBAnad,aA6BI,KAyTI,UAuDwB,SAsBhB;EACE,gBAAA;EACA,uBAAA;;AAEJ,oBAvad,aA6BI,KAyTI,UAuDI,MAAK,aA0BF;AAAD,oBAvad,aA6BI,KAyTI,UAuDwB,SA0BjB;EACG,YAAA;;AAGR,oBA3aV,aA6BI,KAyTI,UAqFI,MAAK;AAAiB,oBA3alC,aA6BI,KAyTI,UAqF4B;EACtB,qBAAA;EACA,WAAA;EACA,WAAA;EACA,aAAa,uBAAb;EACA,eAAA;EACA,iBAAA;EACA,qBAAA;EACA,YAAY,2EAAZ;EACA,kBAAA;EACA,kBAAA;EACA,eAAA;EACA,yBAAA;EACA,gCAAA;;AAEA,oBA1bd,aA6BI,KAyTI,UAqFI,MAAK,eAeF;AAAD,oBA1bd,aA6BI,KAyTI,UAqF4B,QAerB;EACG,YAAA;;AAQxB;EACI,aAAA;EACA,eAAA;EACA,QAAA;EACA,SAAA;EACA,UAAA;EACA,WAAA;EACA,aAAA;EACA,8BAAA;EACA,uBAAA;EACA,mBAAA;EACA,iBAAA;;AAEA,iBAAC;EACG,aAAA;;AAGJ,iBAAE;EACE,eAAA;EACA,WAAA;EACA,kBAAA;EACA,SAAA;EACA,WAAA;EACA,eAAA;EACA,oCAAA;;AAEA,iBATF,OASG;EACG,YAAA;;AAIR,iBAAE;EACE,YAAA;EACA,mBAAA;EACA,kBAAA;;AAEA,iBALF,iBAKI;EACE,aAAA;EACA,sBAAA;EACA,eAAA;EACA,iBAAA;EACA,yBAAA;;AAGJ,iBAbF,iBAaI;EACE,oCAAA;EACA,kBAAA;EACA,kBAAA;EACA,kBAAA;;AAEJ,iBAnBF,iBAmBI;EACE,iBAAA;EACA,aAAA;EACA,cAAA;;AAEA,iBAxBN,iBAmBI,eAKI;EACE,aAAA;EACA,+BAAA;EACA,cAAA;EACA,YAAA;EACA,mBAAA;;AAEA,iBA/BV,iBAmBI,eAKI,eAOI,MAAK;EACH,gBAAA;EACA,SAAA;EACA,kBAAA;EACA,WAAA;EACA,YAAA;EACA,aAAA;;AAEA,iBAvCd,iBAmBI,eAKI,eAOI,MAAK,iBAQF;EACG,SAAS,EAAT;EACA,qBAAA;EACA,WAAA;EACA,0CAAA;EACA,kBAAA;EACA,YAAA;;AAEJ,iBA/Cd,iBAmBI,eAKI,eAOI,MAAK,iBAgBF,QAAQ;EACL,SAAS,QAAT;EACA,aAAa,uBAAb;EACA,eAAA;EACA,gBAAA;EACA,WAAA;;AAMhB,iBA1DF,iBA0DI;EACE,aAAA;EACA,aAAA;EACA,yBAAA;;AAEA,iBA/DN,iBA0DI,SAKI;EACE,iBAAA;;AAMhB,mBAAsC;EAItB,oBAFN,aACI,KAAI,cACA;IACE,kCAAA;;;AAOpB,mBAAsC;EAClC;IACI,0BAAA","file":"songdetail.css"}
\ No newline at end of file
...@@ -64,15 +64,17 @@ ...@@ -64,15 +64,17 @@
& .song-actions { & .song-actions {
margin-top: 25px; margin-top: 25px;
width: 500px; width: 500px;
display: flex;
transition: all 0.2s ease-in-out; transition: all 0.2s ease-in-out;
border-radius: 4px; border-radius: 4px;
overflow: hidden; overflow: hidden;
background: #fff; background: #fff;
& .action-row {
display: flex;
& .action, & .action-player { & .action, & .action-player {
background: linear-gradient(135deg, rgba(0,0,0,0.1), rgba(0,0,0,0.3)); background: linear-gradient(135deg, rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.3));
width: 25%; flex-grow: 1;
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
...@@ -89,6 +91,7 @@ ...@@ -89,6 +91,7 @@
width: 48px; width: 48px;
font-size: 24px; font-size: 24px;
} }
& .volume { & .volume {
width: 0px; width: 0px;
overflow: hidden; overflow: hidden;
...@@ -103,8 +106,9 @@ ...@@ -103,8 +106,9 @@
&.player-active { &.player-active {
& .action { & .action {
width: calc((100% - 250px) / 3); //width: calc((100% - 250px) / 3);
} }
& .action-player { & .action-player {
width: 250px; width: 250px;
...@@ -115,6 +119,7 @@ ...@@ -115,6 +119,7 @@
} }
} }
} }
}
& .song-statistics { & .song-statistics {
display: grid; display: grid;
grid-template-columns: 1fr; grid-template-columns: 1fr;
...@@ -655,6 +660,107 @@ ...@@ -655,6 +660,107 @@
} }
} }
.playlist-overlay {
display: none;
position: fixed;
top: 0px;
left: 0px;
right: 0px;
bottom: 0px;
z-index: 1200;
background: rgba(0,0,0,0.6);
justify-content: center;
align-items: center;
user-select: none;
&.active {
display: flex;
}
& .close {
font-size: 32px;
color: #fff;
position: absolute;
top: 40px;
right: 40px;
cursor: pointer;
transition: 0.2s ease-in-out opacity;
&:hover {
opacity: 0.6;
}
}
& .overlay-content {
width: 500px;
background: #383c3f;
border-radius: 6px;
& .title {
padding: 25px;
letter-spacing: 0.25em;
font-size: 14px;
font-weight: bold;
text-transform: uppercase;
}
& .playlist-empty {
background: rgba(255,255,255,0.1);
border-radius: 4px;
padding: 30px 15px;
text-align: center;
}
& .playlist-list {
padding: 0px 25px;
display: grid;
grid-gap: 15px;
& .playlist-item {
display: grid;
grid-template-columns: 30px 1fr;
grid-gap: 15px;
height: 24px;
align-items: center;
& input[type="checkbox"] {
appearance: none;
border: 0;
border-radius: 4px;
width: 18px;
height: 18px;
outline: none;
&:after {
content: "";
display: inline-block;
width: 18px;
border: 2px solid rgba(255,255,255,0.2);
border-radius: 4px;
height: 18px;
}
&:checked:after {
content: "\F012C";
font-family: "Material Design Icons";
font-size: 14px;
background: #fff;
color: #000;
}
}
}
}
& .actions {
padding: 25px;
display: flex;
justify-content: flex-end;
& .button {
margin-left: 10px;
}
}
}
}
@media screen and (min-width: 1700px) { @media screen and (min-width: 1700px) {
.section-song-detail { .section-song-detail {
& .song-social { & .song-social {
......
...@@ -105,6 +105,16 @@ ...@@ -105,6 +105,16 @@
padding: 50px; padding: 50px;
display: grid; display: grid;
} }
.section-user-detail .playlist-row-user {
padding: 50px;
display: grid;
}
.section-user-detail .playlist-action {
padding: 0px 50px 50px;
display: flex;
justify-content: center;
align-items: center;
}
.section-user-detail .reviews { .section-user-detail .reviews {
padding: 50px; padding: 50px;
} }
...@@ -254,3 +264,4 @@ ...@@ -254,3 +264,4 @@
.card-overlay .overlay-content .button { .card-overlay .overlay-content .button {
display: inline-block; display: inline-block;
} }
/*# sourceMappingURL=userdetail.css.map */
\ No newline at end of file
{"version":3,"sources":["userdetail.less"],"names":[],"mappings":"AACI,oBAAE;EACE,8BAAA;EACA,kBAAA;EACA,mBAAA;;AAEA,oBALF,OAKI;EACE,mBAAA;EACA,aAAA;EACA,+BAAA;EACA,cAAA;;AAEA,oBAXN,OAKI,QAMI;EACE,WAAA;EACA,YAAA;EACA,kBAAA;EACA,2BAAA;EACA,sBAAA;EACA,kBAAA;EACA,gBAAA;;AAEA,oBApBV,OAKI,QAMI,aASI;EACE,kBAAA;EACA,QAAA;EACA,SAAA;EACA,WAAA;EACA,UAAA;EACA,8BAAA;EACA,aAAA;EACA,uBAAA;EACA,mBAAA;EACA,UAAA;EACA,6BAAA;EACA,eAAA;;AAEA,oBAlCd,OAKI,QAMI,aASI,oBAcI;EACE,eAAA;;AAEJ,oBArCd,OAKI,QAMI,aASI,oBAiBI;EACE,kBAAA;EACA,QAAA;EACA,SAAA;EACA,WAAA;EACA,UAAA;EACA,eAAA;EACA,UAAA;;AAIJ,oBAhDd,OAKI,QAMI,aAoCG,MACK;EACE,UAAA;;AAKZ,oBAtDN,OAKI,QAiDI;EACE,aAAA;EACA,4BAAA;;AAEA,oBA1DV,OAKI,QAiDI,WAII;EACE,eAAA;EACA,mBAAA;;AAGA,oBA/Dd,OAKI,QAiDI,WAQI,cACI;EACE,iBAAA;;AAKhB,oBArEF,OAqEI;EACE,mBAAA;EACA,aAAA;;AAEA,oBAzEN,OAqEI,OAII;EACE,YAAA;EACA,aAAA;EACA,kBAAA;EACA,2BAAA;EACA,sBAAA;EACA,UAAA;EACA,oCAAA;;AAEA,oBAlFV,OAqEI,OAII,MASG;EACG,YAAA;EACA,eAAA;;AAIZ,oBAxFF,OAwFI;EACE,aAAA;;AAEA,oBA3FN,OAwFI,MAGI;EACE,eAAA;EACA,iBAAA;EACA,yBAAA;EACA,sBAAA;EACA,kBAAA;EACA,2BAAA;EACA,4BAAA;EACA,8BAAA;EACA,+BAAA;EACA,gCAAA;EACA,qBAAA;;AAEA,oBAxGV,OAwFI,MAGI,KAaG,IAAI,SAAS;EACV,eAAA;EACA,mBAAA;EACA,gCAAA;;AAEJ,oBA7GV,OAwFI,MAGI,KAkBG;EACG,UAAA;EACA,cAAA;EACA,mBAAA;;AAMhB,oBAAE;EACE,aAAA;EACA,aAAA;;AAGJ,oBAAE;EACE,aAAA;EACA,aAAA;;AAGJ,oBAAE;EACE,sBAAA;EACA,aAAA;EACA,uBAAA;EACA,mBAAA;;AAGJ,oBAAE;EACE,aAAA;;AAEA,oBAHF,SAGI;EACE,aAAA;EACA,8BAAA;EACA,cAAA;;AAEA,oBARN,SAGI,aAKI;EACE,oCAAA;EACA,kBAAA;EACA,aAAA;EACA,cAAA;EACA,oCAAA;;AAEA,oBAfV,SAGI,aAKI,QAOI;EACE,aAAA;EACA,oCAAA;EACA,cAAA;;AAEA,oBApBd,SAGI,aAKI,QAOI,UAKI;EACE,WAAA;EACA,YAAA;EACA,mBAAA;EACA,2BAAA;EACA,sBAAA;EACA,cAAA;EACA,WAAA;EACA,qBAAA;EACA,oCAAA;;AAEA,oBA/BlB,SAGI,aAKI,QAOI,UAKI,QAWG;EACG,YAAA;;AAIJ,oBApClB,SAGI,aAKI,QAOI,UAoBI,MACI;EACE,eAAA;EACA,iBAAA;EACA,kBAAA;EACA,cAAA;EACA,WAAA;EACA,qBAAA;;AAEJ,oBA5ClB,SAGI,aAKI,QAOI,UAoBI,MASI;EACE,aAAA;EACA,aAAA;EACA,+BAAA;EACA,mBAAA;EACA,WAAA;EACA,qBAAA;;AAEA,oBApDtB,SAGI,aAKI,QAOI,UAoBI,MASI,SAQI,EAAC;EAAY,cAAA;;AACf,oBArDtB,SAGI,aAKI,QAOI,UAoBI,MASI,SASI,EAAC;EAAY,cAAA;;AAEf,oBAvDtB,SAGI,aAKI,QAOI,UAoBI,MASI,SAWI;EACE,YAAA;;AAMhB,oBA9DV,SAGI,aAKI,QAsDI;EACE,gBAAA;EACA,kBAAA;EACA,kBAAA;EACA,WAAA;EACA,qBAAA;;AAGJ,oBAtEV,SAGI,aAKI,QA8DG;EACG,YAAA;;AAMhB,oBAAE;EACE,aAAA;;AAEA,oBAHF,WAGI;EACE,aAAA;EACA,sCAAA;EACA,cAAA;;AAEA,oBARN,WAGI,YAKI;EACE,oCAAA;EACA,kBAAA;EACA,gBAAA;EACA,WAAA;EACA,qBAAA;;AAEA,oBAfV,WAGI,YAKI,UAOI;EACE,WAAA;EACA,cAAA;EACA,mBAAA;EACA,oCAAA;EACA,2BAAA;EACA,sBAAA;EACA,oCAAA;;AAEA,oBAxBd,WAGI,YAKI,UAOI,WASG;EACG,YAAA;;AAQtB;EACE,aAAA;EACA,eAAA;EACA,QAAA;EACA,SAAA;EACA,UAAA;EACA,WAAA;EACA,aAAA;EACA,8BAAA;EACA,uBAAA;EACA,mBAAA;;AAEA,aAAC;EACG,aAAA;;AAGJ,aAAE;EACE,eAAA;EACA,WAAA;EACA,kBAAA;EACA,SAAA;EACA,WAAA;EACA,eAAA;EACA,oCAAA;;AAEA,aATF,OASG;EACG,YAAA;;AAIR,aAAE;EACE,gBAAA;EACA,kBAAA;;AAEA,aAJF,iBAII;EACE,YAAA;EACA,aAAA;EACA,mBAAA;;AAGJ,aAVF,iBAUI;EACE,eAAA;EACA,iBAAA;EACA,mBAAA;;AAGJ,aAhBF,iBAgBI;EACE,kBAAA;EACA,aAAA;EACA,mBAAA;;AAGJ,aAtBF,iBAsBI;EACE,mBAAA;EACA,iBAAA;;AAGJ,aA3BF,iBA2BI;EACE,qBAAA","file":"userdetail.css"}
\ No newline at end of file
...@@ -122,6 +122,18 @@ ...@@ -122,6 +122,18 @@
display: grid; display: grid;
} }
& .playlist-row-user {
padding: 50px;
display: grid;
}
& .playlist-action {
padding: 0px 50px 50px;
display: flex;
justify-content: center;
align-items: center;
}
& .reviews { & .reviews {
padding: 50px; padding: 50px;
......
<?php
namespace App\Controller;
use App\Entity\SongPlaylist;
use Exception;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\File\Exception\FileException;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\FileType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use App\Entity\Song;
use App\Entity\SongReview;
use App\Entity\SongSpinPlay;
use App\Utils\HelperFunctions;
use App\Entity\User;
use App\Entity\UserNotification;
class PlaylistController extends AbstractController
{
/**
* @Route("/playlist/create", name="playlist.create")
* @param Request $request
* @param int $playlistId
* @return RedirectResponse|Response
*/
public function playlistCreate(Request $request)
{
$user = $this->getUser();
$em = $this->getDoctrine()->getManager();
$data = [];
$data['formData'] = "";
$playlist = new SongPlaylist();
$form = $this->createFormBuilder()
->add('title', TextType::class, ['label' => 'Title', 'row_attr' => array('class' => 'tags-field'), 'required' => true])
->add('description', TextareaType::class, ['label' => 'Description', 'attr' => array('rows' => 5), 'row_attr' => array('class' => 'tags-field'), 'required' => false])
->add('coverPath', FileType::class, ['label' => 'Cover Image', 'row_attr' => array('class' => 'upload-field'), 'attr' => array('accept' => '.png, .jpg, .jpeg')])
->add('save', SubmitType::class, ['label' => 'Create'])
->getForm();
$form->handleRequest($request);
$data['form'] = $form->createView();
if($form->isSubmitted() && $form->isValid()) {
$formData = $form->getData();
$coverFile = $formData['coverPath'];
if($coverFile) {
try {
$playlist->setTitle($formData['title']);
$playlist->setDescription($formData['description']);
$playlist->setFileReference("playlist_" . uniqid());
$playlist->setUser($this->getUser());
$playlist->setIsOfficial(false);
rename($coverFile, $this->getParameter('cover_path') . DIRECTORY_SEPARATOR . $playlist->getFileReference() . ".png");
$em->persist($playlist);
$em->flush();
return $this->redirectToRoute('playlist.detail', ['playlistId' => $playlist->getId()]);
} catch(Exception $e) {
$this->addFlash('error', 'Creating failed. Please report back to our development team!');
var_dump($e);
return $this->render('playlist/create.html.twig', $data);
}
}
}
return $this->render('playlist/create.html.twig', $data);
}
/**
* @Route("/playlist/{playlistId}", name="playlist.detail")
* @param Request $request
* @param int $playlistId
* @return RedirectResponse|Response
*/
public function playlistDetail(Request $request, int $playlistId)
{
$em = $this->getDoctrine()->getManager();
$data = [];
$resultPlaylist = $em->getRepository(SongPlaylist::class)->findOneBy(array('id' => $playlistId));
if(!$resultPlaylist) throw new NotFoundHttpException();
$resultUser = $em->getRepository(User::class)->findOneBy(array('id' => $resultPlaylist->getUser()));
if(!$resultUser) throw new NotFoundHttpException();
$data['playlist'] = $resultPlaylist;
$data['playlistCount'] = count($resultPlaylist->getSongs());
$data['user'] = $resultUser;
return $this->render('playlist/detail.html.twig', $data);
}
/**
* @Route("/playlist/{playlistId}/delete", name="playlist.delete")
* @param Request $request
* @param int $playlistId
* @return RedirectResponse|Response
*/
public function playlistDelete(Request $request, int $playlistId)
{
$user = $this->getUser();
$em = $this->getDoctrine()->getManager();
$data = [];
$resultPlaylist = $em->getRepository(Song::class)->findOneBy(array('id' => $playlistId, 'user' => $user->getId()));
$data['playlist'] = $resultPlaylist;
if(!$resultPlaylist) {
throw new NotFoundHttpException();
} else {
if($request->query->get('isConfirmed')) {
// remove the entity
$em->remove($resultPlaylist);
$em->flush();
// Redirect
return $this->redirectToRoute('user.detail', ['userId' => $user->getId(), 'area' => 'playlists']);
} else {
return $this->render('playlist/delete.html.twig', $data);
}
}
}
/**
* @Route("/playlist/{playlistId}/song/{songId}/delete", name="playlist.song.delete")
* @param Request $request
* @param int $playlistId
* @param int $songId
* @return RedirectResponse
*/
public function playlistSongDelete(Request $request, int $playlistId, int $songId)
{
$user = $this->getUser();
$em = $this->getDoctrine()->getManager();
$data = [];
$resultPlaylist = $em->getRepository(SongPlaylist::class)->findOneBy(array('id' => $playlistId));
$resultSong = $em->getRepository(Song::class)->findOneBy(array('id' => $songId));
if(!$resultPlaylist || !$resultSong) {
return $this->redirectToRoute('playlist.detail', ['playlistId' => $playlistId]);
} else {
// TODO
$userRoles = $this->getUser()->getRoles();
$allowedRoles = ["ROLE_ADMIN", "ROLE_SUPERADMIN", "ROLE_MODERATOR"];
// Check if allowed to remove
if(count(array_intersect($allowedRoles, $userRoles)) > 0 || $resultPlaylist->getUser() == $this->getUser()) {
$resultPlaylist->removeSong($resultSong);
$em->persist($resultPlaylist);
$em->flush();
}
// Redirect
return $this->redirectToRoute('playlist.detail', ['playlistId' => $playlistId]);
}
}
}
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
namespace App\Controller; namespace App\Controller;
use App\Entity\SongPlaylist;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
...@@ -62,6 +63,31 @@ class SongController extends AbstractController ...@@ -62,6 +63,31 @@ class SongController extends AbstractController
$data['activeAction'] = $request->query->get('action'); $data['activeAction'] = $request->query->get('action');
if($this->getUser() != null) { if($this->getUser() != null) {
$resultUserPlaylists = $em->getRepository(SongPlaylist::class)->findBy(array('user' => $this->getUser()));
if($request->request->get('submitPlaylist')) {
$allValues = $request->request->all();
foreach($resultUserPlaylists as $playlist) {
$playlist->removeSong($resultSong);
$em->persist($playlist);
}
foreach($allValues as $key => $value) {
if(strpos($key, "playlist_") !== false) {
if($value == "on") {
$checkedPlaylist = $resultUserPlaylists[str_replace("playlist_", "", $key)];
$checkedPlaylist->addSong($resultSong);
$em->persist($checkedPlaylist);
}
}
}
$em->flush();
}
$data['userPlaylists'] = $resultUserPlaylists;
$resultUserReview = $em->getRepository(SongReview::class)->findBy(array('song' => $resultSong, 'user' => $this->getUser())); $resultUserReview = $em->getRepository(SongReview::class)->findBy(array('song' => $resultSong, 'user' => $this->getUser()));
$data['userReview'] = $resultUserReview; $data['userReview'] = $resultUserReview;
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
namespace App\Controller; namespace App\Controller;
use Exception;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\File\Exception\FileException; use Symfony\Component\HttpFoundation\File\Exception\FileException;
...@@ -15,6 +16,7 @@ use Symfony\Component\Form\Extension\Core\Type\SubmitType; ...@@ -15,6 +16,7 @@ use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use App\Entity\Song; use App\Entity\Song;
use App\Utils\HelperFunctions; use App\Utils\HelperFunctions;
use ZipArchive;
class UploadController extends AbstractController class UploadController extends AbstractController
{ {
...@@ -51,7 +53,7 @@ class UploadController extends AbstractController ...@@ -51,7 +53,7 @@ class UploadController extends AbstractController
$song->setUploadDate(new \DateTime('NOW')); $song->setUploadDate(new \DateTime('NOW'));
$song->setIsExplicit($data['isExplicit']); $song->setIsExplicit($data['isExplicit']);
$zip = new \ZipArchive; $zip = new ZipArchive;
if($zip->open($backupFile)) { if($zip->open($backupFile)) {
try { try {
// extract backup // extract backup
...@@ -124,8 +126,7 @@ class UploadController extends AbstractController ...@@ -124,8 +126,7 @@ class UploadController extends AbstractController
$hf = new HelperFunctions(); $hf = new HelperFunctions();
$hf->delTree($extractionPath); $hf->delTree($extractionPath);
var_dump($e); return $this->render('upload/index.html.twig', $tempVars);
exit;
} }
try { try {
...@@ -150,8 +151,7 @@ class UploadController extends AbstractController ...@@ -150,8 +151,7 @@ class UploadController extends AbstractController
$hf = new HelperFunctions(); $hf = new HelperFunctions();
$hf->delTree($extractionPath); $hf->delTree($extractionPath);
var_dump($e); return $this->render('upload/index.html.twig', $tempVars);
exit;
} }
try { try {
...@@ -172,8 +172,7 @@ class UploadController extends AbstractController ...@@ -172,8 +172,7 @@ class UploadController extends AbstractController
$hf = new HelperFunctions(); $hf = new HelperFunctions();
$hf->delTree($extractionPath); $hf->delTree($extractionPath);
var_dump($e); return $this->render('upload/index.html.twig', $tempVars);
exit;
} }
// write new track/clip info // write new track/clip info
...@@ -207,14 +206,12 @@ class UploadController extends AbstractController ...@@ -207,14 +206,12 @@ class UploadController extends AbstractController
} catch(\Exception $e) { } catch(\Exception $e) {
$this->addFlash('error', 'Uploading failed. Please report back to our development team!'); $this->addFlash('error', 'Uploading failed. Please report back to our development team!');
var_dump($e); return $this->render('upload/index.html.twig', $tempVars);
exit;
} }
} catch(\Exception $e) { } catch(\Exception $e) {
$this->addFlash('error', 'Uploading failed. Please report back to our development team!'); $this->addFlash('error', 'Uploading failed. Please report back to our development team!');
var_dump($e); return $this->render('upload/index.html.twig', $tempVars);
exit;
} }
} else { } else {
$this->addFlash('error', 'Uploading failed. Please report back to our development team!'); $this->addFlash('error', 'Uploading failed. Please report back to our development team!');
......
...@@ -2,7 +2,10 @@ ...@@ -2,7 +2,10 @@
namespace App\Controller; namespace App\Controller;
use App\Entity\SongPlaylist;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
...@@ -15,17 +18,12 @@ use App\Entity\SongSpinPlay; ...@@ -15,17 +18,12 @@ use App\Entity\SongSpinPlay;
class UserController extends AbstractController class UserController extends AbstractController
{ {
/** /**
* @Route("/user/{userId}", name="user.detail") * @Route("/user/{userId}/{area}", defaults={"area"="charts"}, name="user.detail")
* @param Request $request
* @param int $userId
* @return Response
*/ */
public function userDetail(Request $request, int $userId) public function userDetailCharts(Request $request, int $userId, string $area)
{
return $this->redirectToRoute('user.detail.charts', array('userId' => $userId));
}
/**
* @Route("/user/{userId}/charts", name="user.detail.charts")
*/
public function userDetailCharts(Request $request, int $userId)
{ {
$user = $this->getUser(); $user = $this->getUser();
$em = $this->getDoctrine()->getManager(); $em = $this->getDoctrine()->getManager();
...@@ -55,102 +53,28 @@ class UserController extends AbstractController ...@@ -55,102 +53,28 @@ class UserController extends AbstractController
if(!$resultUser) throw new NotFoundHttpException(); if(!$resultUser) throw new NotFoundHttpException();
$resultCharts = $em->getRepository(Song::class)->findBy(array('uploader' => $resultUser->getId()), array('uploadDate' => 'DESC')); $resultCharts = $em->getRepository(Song::class)->findBy(array('uploader' => $resultUser->getId()), array('uploadDate' => 'DESC'));
$resultPlaylists = $em->getRepository(SongPlaylist::class)->findBy(array('user' => $resultUser->getId()), array('id' => 'DESC'));
$resultReviews = $em->getRepository(SongReview::class)->findBy(array('user' => $resultUser->getId()), array('reviewDate' => 'DESC')); $resultReviews = $em->getRepository(SongReview::class)->findBy(array('user' => $resultUser->getId()), array('reviewDate' => 'DESC'));
$resultSpinPlays = $em->getRepository(SongSpinPlay::class)->findBy(array('isActive' => true, 'user' => $resultUser->getId()), array('submitDate' => 'DESC')); $resultSpinPlays = $em->getRepository(SongSpinPlay::class)->findBy(array('isActive' => true, 'user' => $resultUser->getId()), array('submitDate' => 'DESC'));
$data['user'] = $resultUser; $data['user'] = $resultUser;
$data['area'] = $area;
$data['charts'] = $resultCharts; $data['charts'] = $resultCharts;
$data['playlists'] = $resultPlaylists;
$data['reviews'] = $resultReviews; $data['reviews'] = $resultReviews;
$data['spinPlays'] = $resultSpinPlays; $data['spinPlays'] = $resultSpinPlays;
switch($area) {
case "charts":
return $this->render('user/detail-charts.html.twig', $data); return $this->render('user/detail-charts.html.twig', $data);
} case "playlists":
return $this->render('user/detail-playlists.html.twig', $data);
/** case "reviews":
* @Route("/user/{userId}/reviews", name="user.detail.reviews")
*/
public function userDetailReviews(Request $request, int $userId)
{
$user = $this->getUser();
$em = $this->getDoctrine()->getManager();
$data = [];
if($user) {
if($user->getId() == $userId) {
if($request->request->get('save') == "changeAvatar") {
if($request->files->get('newAvatar')) {
$allowedMimeTypes = array("image/jpeg", "image/png");
if(in_array($request->files->get('newAvatar')->getMimeType(), $allowedMimeTypes)) {
@unlink($this->getParameter('avatar_path').DIRECTORY_SEPARATOR.$user->getCoverReference());
$user->setCoverReference(uniqid().".png");
rename($request->files->get('newAvatar'), $this->getParameter('avatar_path').DIRECTORY_SEPARATOR.$user->getCoverReference());
$em->persist($user);
$em->flush();
}
}
}
}
}
$resultUser = $em->getRepository(User::class)->findOneBy(array('id' => $userId));
if(!$resultUser) throw new NotFoundHttpException();
$resultCharts = $em->getRepository(Song::class)->findBy(array('uploader' => $resultUser->getId()), array('uploadDate' => 'DESC'));
$resultReviews = $em->getRepository(SongReview::class)->findBy(array('user' => $resultUser->getId()), array('reviewDate' => 'DESC'));
$resultSpinPlays = $em->getRepository(SongSpinPlay::class)->findBy(array('isActive' => true, 'user' => $resultUser->getId()), array('submitDate' => 'DESC'));
$data['user'] = $resultUser;
$data['charts'] = $resultCharts;
$data['reviews'] = $resultReviews;
$data['spinPlays'] = $resultSpinPlays;
return $this->render('user/detail-reviews.html.twig', $data); return $this->render('user/detail-reviews.html.twig', $data);
case "spinplays":
return $this->render('user/detail-spinplays.html.twig', $data);
} }
/** return null;
* @Route("/user/{userId}/spinplays", name="user.detail.spinplays")
*/
public function userDetailSpinPlays(Request $request, int $userId)
{
$user = $this->getUser();
$em = $this->getDoctrine()->getManager();
$data = [];
if($user) {
if($user->getId() == $userId) {
if($request->request->get('save') == "changeAvatar") {
if($request->files->get('newAvatar')) {
$allowedMimeTypes = array("image/jpeg", "image/png");
if(in_array($request->files->get('newAvatar')->getMimeType(), $allowedMimeTypes)) {
@unlink($this->getParameter('avatar_path').DIRECTORY_SEPARATOR.$user->getCoverReference());
$user->setCoverReference(uniqid().".png");
rename($request->files->get('newAvatar'), $this->getParameter('avatar_path').DIRECTORY_SEPARATOR.$user->getCoverReference());
$em->persist($user);
$em->flush();
}
}
}
}
}
$resultUser = $em->getRepository(User::class)->findOneBy(array('id' => $userId));
if(!$resultUser) throw new NotFoundHttpException();
$resultCharts = $em->getRepository(Song::class)->findBy(array('uploader' => $resultUser->getId()), array('uploadDate' => 'DESC'));
$resultReviews = $em->getRepository(SongReview::class)->findBy(array('user' => $resultUser->getId()), array('reviewDate' => 'DESC'));
$resultSpinPlays = $em->getRepository(SongSpinPlay::class)->findBy(array('isActive' => true, 'user' => $resultUser->getId()), array('submitDate' => 'DESC'));
$data['user'] = $resultUser;
$data['charts'] = $resultCharts;
$data['reviews'] = $resultReviews;
$data['spinPlays'] = $resultSpinPlays;
return $this->render('user/detail-spinplays.html.twig', $data);
} }
} }
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
namespace App\Entity; namespace App\Entity;
use DateTimeInterface;
use Doctrine\ORM\Mapping as ORM; use Doctrine\ORM\Mapping as ORM;
/** /**
...@@ -51,12 +52,12 @@ class ClientRelease ...@@ -51,12 +52,12 @@ class ClientRelease
return $this->id; return $this->id;
} }
public function getUploadDate(): ?\DateTimeInterface public function getUploadDate(): ?DateTimeInterface
{ {
return $this->uploadDate; return $this->uploadDate;
} }
public function setUploadDate(\DateTimeInterface $uploadDate): self public function setUploadDate(DateTimeInterface $uploadDate): self
{ {
$this->uploadDate = $uploadDate; $this->uploadDate = $uploadDate;
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
namespace App\Entity; namespace App\Entity;
use DateTimeInterface;
use Doctrine\ORM\Mapping as ORM; use Doctrine\ORM\Mapping as ORM;
/** /**
...@@ -54,12 +55,12 @@ class Connection ...@@ -54,12 +55,12 @@ class Connection
return $this; return $this;
} }
public function getConnectDate(): ?\DateTimeInterface public function getConnectDate(): ?DateTimeInterface
{ {
return $this->connectDate; return $this->connectDate;
} }
public function setConnectDate(\DateTimeInterface $connectDate): self public function setConnectDate(DateTimeInterface $connectDate): self
{ {
$this->connectDate = $connectDate; $this->connectDate = $connectDate;
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
namespace App\Entity; namespace App\Entity;
use DateTimeInterface;
use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection; use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM; use Doctrine\ORM\Mapping as ORM;
...@@ -68,11 +69,6 @@ class Song ...@@ -68,11 +69,6 @@ class Song
*/ */
private $isExplicit; private $isExplicit;
/**
* @ORM\Column(type="boolean", nullable=true, options={"default": false})
*/
private $isTournament;
/** /**
* @ORM\Column(type="boolean") * @ORM\Column(type="boolean")
*/ */
...@@ -260,18 +256,6 @@ class Song ...@@ -260,18 +256,6 @@ class Song
return $this; return $this;
} }
public function getIsTournament(): ?bool
{
return $this->isTournament;
}
public function setIsTournament(bool $isTournament): self
{
$this->isTournament = $isTournament;
return $this;
}
public function getHasEasyDifficulty(): ?bool public function getHasEasyDifficulty(): ?bool
{ {
return $this->hasEasyDifficulty; return $this->hasEasyDifficulty;
...@@ -332,12 +316,12 @@ class Song ...@@ -332,12 +316,12 @@ class Song
return $this; return $this;
} }
public function getUploadDate(): ?\DateTimeInterface public function getUploadDate(): ?DateTimeInterface
{ {
return $this->uploadDate; return $this->uploadDate;
} }
public function setUploadDate(\DateTimeInterface $uploadDate): self public function setUploadDate(DateTimeInterface $uploadDate): self
{ {
$this->uploadDate = $uploadDate; $this->uploadDate = $uploadDate;
...@@ -419,7 +403,7 @@ class Song ...@@ -419,7 +403,7 @@ class Song
} }
public function getJSON() { public function getJSON() {
$response = array( return array(
'id' => $this->id, 'id' => $this->id,
'title' => $this->title, 'title' => $this->title,
'subtitle' => $this->subtitle, 'subtitle' => $this->subtitle,
...@@ -431,7 +415,6 @@ class Song ...@@ -431,7 +415,6 @@ class Song
'views' => $this->views, 'views' => $this->views,
'downloads' => $this->downloads, 'downloads' => $this->downloads,
'isExplicit' => $this->isExplicit, 'isExplicit' => $this->isExplicit,
'isTournament' => $this->isTournament,
'hasEasyDifficulty' => $this->hasEasyDifficulty, 'hasEasyDifficulty' => $this->hasEasyDifficulty,
'hasNormalDifficulty' => $this->hasNormalDifficulty, 'hasNormalDifficulty' => $this->hasNormalDifficulty,
'hasHardDifficulty' => $this->hasHardDifficulty, 'hasHardDifficulty' => $this->hasHardDifficulty,
...@@ -440,8 +423,6 @@ class Song ...@@ -440,8 +423,6 @@ class Song
'uploadDate' => $this->uploadDate, 'uploadDate' => $this->uploadDate,
'description' => $this->description 'description' => $this->description
); );
return $response;
} }
/** /**
......
...@@ -43,6 +43,12 @@ class SongPlaylist ...@@ -43,6 +43,12 @@ class SongPlaylist
*/ */
private $songs; private $songs;
/**
* @ORM\ManyToOne(targetEntity="App\Entity\User", inversedBy="songPlaylists")
* @ORM\JoinColumn(nullable=false)
*/
private $user;
public function __construct() public function __construct()
{ {
$this->songs = new ArrayCollection(); $this->songs = new ArrayCollection();
...@@ -126,4 +132,34 @@ class SongPlaylist ...@@ -126,4 +132,34 @@ class SongPlaylist
return $this; return $this;
} }
public function getJSON() {
$songs = array();
foreach($this->songs as $song) {
$songs[] = $song->getJSON();
}
return array(
'id' => $this->id,
'title' => $this->title,
'description' => $this->description,
'fileReference' => $this->fileReference,
'user' => $this->user->getJSON(),
'songs' => $songs,
'isOfficial' => $this->isOfficial
);
}
public function getUser(): ?User
{
return $this->user;
}
public function setUser(?User $user): self
{
$this->user = $user;
return $this;
}
} }
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
namespace App\Entity; namespace App\Entity;
use DateTimeInterface;
use Doctrine\ORM\Mapping as ORM; use Doctrine\ORM\Mapping as ORM;
/** /**
...@@ -133,12 +134,12 @@ class SongReport ...@@ -133,12 +134,12 @@ class SongReport
return $this; return $this;
} }
public function getReportDate(): ?\DateTimeInterface public function getReportDate(): ?DateTimeInterface
{ {
return $this->reportDate; return $this->reportDate;
} }
public function setReportDate(\DateTimeInterface $reportDate): self public function setReportDate(DateTimeInterface $reportDate): self
{ {
$this->reportDate = $reportDate; $this->reportDate = $reportDate;
......
...@@ -47,7 +47,6 @@ class SongReview ...@@ -47,7 +47,6 @@ class SongReview
public function __construct() public function __construct()
{ {
$this->user = new ArrayCollection();
} }
public function getId(): ?int public function getId(): ?int
...@@ -116,7 +115,7 @@ class SongReview ...@@ -116,7 +115,7 @@ class SongReview
} }
public function getJSON() { public function getJSON() {
$response = array( return array(
'id' => $this->id, 'id' => $this->id,
'song' => $this->song->getJSON(), 'song' => $this->song->getJSON(),
'user' => $this->user->getJSON(), 'user' => $this->user->getJSON(),
...@@ -124,7 +123,5 @@ class SongReview ...@@ -124,7 +123,5 @@ class SongReview
'comment' => $this->comment, 'comment' => $this->comment,
'reviewDate' => $this->reviewDate 'reviewDate' => $this->reviewDate
); );
return $response;
} }
} }
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
namespace App\Entity; namespace App\Entity;
use DateTimeInterface;
use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection; use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM; use Doctrine\ORM\Mapping as ORM;
...@@ -47,7 +48,6 @@ class SongSpinPlay ...@@ -47,7 +48,6 @@ class SongSpinPlay
public function __construct() public function __construct()
{ {
$this->user = new ArrayCollection();
} }
public function getId(): ?int public function getId(): ?int
...@@ -93,18 +93,18 @@ class SongSpinPlay ...@@ -93,18 +93,18 @@ class SongSpinPlay
public function getVideoThumbnail(): ?string public function getVideoThumbnail(): ?string
{ {
$videoUrlSplitted = explode('/' , $this->videoUrl); $videoUrlSplit = explode('/' , $this->videoUrl);
$splittedCount = count($videoUrlSplitted); $splitCount = count($videoUrlSplit);
return $this->fetch_highest_res(str_replace("watch?v=", "", $videoUrlSplitted[$splittedCount - 1])); return $this->fetch_highest_res(str_replace("watch?v=", "", $videoUrlSplit[$splitCount - 1]));
} }
public function getSubmitDate(): ?\DateTimeInterface public function getSubmitDate(): ?DateTimeInterface
{ {
return $this->submitDate; return $this->submitDate;
} }
public function setSubmitDate(\DateTimeInterface $submitDate): self public function setSubmitDate(DateTimeInterface $submitDate): self
{ {
$this->submitDate = $submitDate; $this->submitDate = $submitDate;
...@@ -134,7 +134,7 @@ class SongSpinPlay ...@@ -134,7 +134,7 @@ class SongSpinPlay
} }
public function getJSON() { public function getJSON() {
$response = array( return array(
'id' => $this->id, 'id' => $this->id,
'user' => $this->user->getJSON(), 'user' => $this->user->getJSON(),
'videoUrl' => $this->videoUrl, 'videoUrl' => $this->videoUrl,
...@@ -142,7 +142,5 @@ class SongSpinPlay ...@@ -142,7 +142,5 @@ class SongSpinPlay
'submitDate' => $this->submitDate, 'submitDate' => $this->submitDate,
'isActive' => $this->isActive 'isActive' => $this->isActive
); );
return $response;
} }
} }
...@@ -71,6 +71,11 @@ ...@@ -71,6 +71,11 @@
*/ */
private $userCards; private $userCards;
/**
* @ORM\OneToMany(targetEntity="App\Entity\SongPlaylist", mappedBy="user")
*/
private $songPlaylists;
public function __construct() public function __construct()
{ {
parent::__construct(); parent::__construct();
...@@ -81,6 +86,7 @@ ...@@ -81,6 +86,7 @@
$this->connections = new ArrayCollection(); $this->connections = new ArrayCollection();
$this->userNotifications = new ArrayCollection(); $this->userNotifications = new ArrayCollection();
$this->userCards = new ArrayCollection(); $this->userCards = new ArrayCollection();
$this->songPlaylists = new ArrayCollection();
} }
public function getCoverReference(): ?string public function getCoverReference(): ?string
...@@ -179,15 +185,13 @@ ...@@ -179,15 +185,13 @@
} }
public function getJSON() { public function getJSON() {
$response = array( return array(
'id' => $this->id, 'id' => $this->id,
'username' => $this->username, 'username' => $this->username,
'coverReference' => $this->coverReference, 'coverReference' => $this->coverReference,
'isVerified' => $this->isVerified, 'isVerified' => $this->isVerified,
'isPatreon' => $this->isPatreon 'isPatreon' => $this->isPatreon
); );
return $response;
} }
public function getConnectCode(): ?string public function getConnectCode(): ?string
...@@ -306,4 +310,35 @@ ...@@ -306,4 +310,35 @@
return $this; return $this;
} }
/**
* @return Collection|SongPlaylist[]
*/
public function getSongPlaylists(): Collection
{
return $this->songPlaylists;
}
public function addSongPlaylist(SongPlaylist $songPlaylist): self
{
if (!$this->songPlaylists->contains($songPlaylist)) {
$this->songPlaylists[] = $songPlaylist;
$songPlaylist->setUser($this);
}
return $this;
}
public function removeSongPlaylist(SongPlaylist $songPlaylist): self
{
if ($this->songPlaylists->contains($songPlaylist)) {
$this->songPlaylists->removeElement($songPlaylist);
// set the owning side to null (unless already changed)
if ($songPlaylist->getUser() === $this) {
$songPlaylist->setUser(null);
}
}
return $this;
}
} }
\ No newline at end of file
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
namespace App\Entity; namespace App\Entity;
use DateTimeInterface;
use Doctrine\ORM\Mapping as ORM; use Doctrine\ORM\Mapping as ORM;
/** /**
...@@ -60,12 +61,12 @@ class UserCard ...@@ -60,12 +61,12 @@ class UserCard
return $this; return $this;
} }
public function getGivenDate(): ?\DateTimeInterface public function getGivenDate(): ?DateTimeInterface
{ {
return $this->givenDate; return $this->givenDate;
} }
public function setGivenDate(\DateTimeInterface $givenDate): self public function setGivenDate(DateTimeInterface $givenDate): self
{ {
$this->givenDate = $givenDate; $this->givenDate = $givenDate;
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
namespace App\Entity; namespace App\Entity;
use DateTimeInterface;
use Doctrine\ORM\Mapping as ORM; use Doctrine\ORM\Mapping as ORM;
/** /**
...@@ -133,12 +134,12 @@ class UserReport ...@@ -133,12 +134,12 @@ class UserReport
return $this; return $this;
} }
public function getReportDate(): ?\DateTimeInterface public function getReportDate(): ?DateTimeInterface
{ {
return $this->reportDate; return $this->reportDate;
} }
public function setReportDate(\DateTimeInterface $reportDate): self public function setReportDate(DateTimeInterface $reportDate): self
{ {
$this->reportDate = $reportDate; $this->reportDate = $reportDate;
......
...@@ -25,9 +25,7 @@ class SongRepository extends ServiceEntityRepository ...@@ -25,9 +25,7 @@ class SongRepository extends ServiceEntityRepository
->orderBy('e.uploadDate', 'DESC') ->orderBy('e.uploadDate', 'DESC')
->setFirstResult(12 * $page) ->setFirstResult(12 * $page)
->setMaxResults(12); ->setMaxResults(12);
$result = $qb->getQuery()->getResult(); return $qb->getQuery()->getResult();
return $result;
} }
public function getHot(int $page) { public function getHot(int $page) {
...@@ -41,9 +39,7 @@ class SongRepository extends ServiceEntityRepository ...@@ -41,9 +39,7 @@ class SongRepository extends ServiceEntityRepository
->setMaxResults(12) ->setMaxResults(12)
->setParameter('begin', new \DateTime('NOW')) ->setParameter('begin', new \DateTime('NOW'))
->setParameter('end', new \DateTime('-7 days')); ->setParameter('end', new \DateTime('-7 days'));
$result = $qb->getQuery()->getResult(); return $qb->getQuery()->getResult();
return $result;
} }
public function getPopular(int $page) { public function getPopular(int $page) {
...@@ -53,8 +49,6 @@ class SongRepository extends ServiceEntityRepository ...@@ -53,8 +49,6 @@ class SongRepository extends ServiceEntityRepository
->orderBy('e.views', 'DESC') ->orderBy('e.views', 'DESC')
->setFirstResult(12 * $page) ->setFirstResult(12 * $page)
->setMaxResults(12); ->setMaxResults(12);
$result = $qb->getQuery()->getResult(); return $qb->getQuery()->getResult();
return $result;
} }
} }
...@@ -144,6 +144,18 @@ ...@@ -144,6 +144,18 @@
"swiftmailer/swiftmailer": { "swiftmailer/swiftmailer": {
"version": "v6.2.3" "version": "v6.2.3"
}, },
"symfony/apache-pack": {
"version": "1.0",
"recipe": {
"repo": "github.com/symfony/recipes-contrib",
"branch": "master",
"version": "1.0",
"ref": "71599f5b0fdeeeec0fb90e9b17c85e6f5e1350c1"
},
"files": [
"./public/.htaccess"
]
},
"symfony/asset": { "symfony/asset": {
"version": "v4.4.6" "version": "v4.4.6"
}, },
......
...@@ -98,9 +98,21 @@ ...@@ -98,9 +98,21 @@
<div class="item item-user" tabindex="0"> <div class="item item-user" tabindex="0">
<div class="user-avatar" style="background-image: url({{ asset('uploads/avatar/' ~ app.user.coverReference ~ '?t=' ~ date().timestamp) }}), url({{ asset("assets/img/defaultAvatar.jpg") }});"></div> <div class="user-avatar" style="background-image: url({{ asset('uploads/avatar/' ~ app.user.coverReference ~ '?t=' ~ date().timestamp) }}), url({{ asset("assets/img/defaultAvatar.jpg") }});"></div>
<div class="user-actions"> <div class="user-actions">
<a href="{{ path('user.detail', {userId: app.user.id}) }}" class="user-action-item"> <a href="{{ path('user.detail', {userId: app.user.id, area: "charts"}) }}" class="user-action-item">
<i class="mdi mdi-account"></i> <i class="mdi mdi-music"></i>
<span>My Profile</span> <span>My Charts</span>
</a>
<a href="{{ path('user.detail', {userId: app.user.id, area: "playlists"}) }}" class="user-action-item">
<i class="mdi mdi-playlist-music"></i>
<span>My Playlists</span>
</a>
<a href="{{ path('user.detail', {userId: app.user.id, area: "reviews"}) }}" class="user-action-item">
<i class="mdi mdi-thumbs-up-down"></i>
<span>My Reviews</span>
</a>
<a href="{{ path('user.detail', {userId: app.user.id, area: "spinplays"}) }}" class="user-action-item">
<i class="mdi mdi-youtube"></i>
<span>My SpinPlays</span>
</a> </a>
<a href="{{ path('user.settings') }}" class="user-action-item"> <a href="{{ path('user.settings') }}" class="user-action-item">
<i class="mdi mdi-cog"></i> <i class="mdi mdi-cog"></i>
......
{% extends 'base.html.twig' %}
{% block title %}Create Playlist{% endblock %}
{% block content %}
<section class="section-upload">
{{ form_start(form) }}
{% for label, messages in app.flashes %}
{% for message in messages %}
<div class="flashbang flashbang-{{ label }}">
{{ message }}
</div>
{% endfor %}
{% endfor %}
<div class="box">
<div class="title">Create Playlist</div>
<div class="tags-input">
{{ form_row(form.title) }}
</div>
<div class="tags-input">
{{ form_row(form.description) }}
</div>
<div class="upload-input">
{{ form_row(form.coverPath) }}
<div class="upload-input-select active">
<i class="mdi mdi-folder-upload"></i>
<div>SELECT A COVER<br />FOR YOUR PLAYLIST</div>
</div>
<div class="upload-input-selected">
<i class="mdi mdi-folder-image"></i>
<div></div>
</div>
</div>
<div class="actions">
{{ form_row(form.save) }}
</div>
</div>
{{ form_end(form) }}
</section>
{% endblock %}
{% block scripts %}
<script src="{{ asset('assets/js/upload.js') }}"></script>
{% endblock %}
{% block styles %}
<link rel="stylesheet" href="{{ asset('assets/css/upload.css?v=' ~ date().timestamp) }}" />
{% endblock %}
{% extends 'base.html.twig' %}
{% block title %}{{ playlist.title }} on SpinShare{% endblock %}
{% block meta %}
<meta property="og:title" content="{{ playlist.title }} on SpinShare"/>
<meta property="og:description" content="Created by {{ user.username }} &dash; {{ playlistCount }} Charts"/>
<meta property="og:type" content="music.playlist"/>
<meta property="og:url" content="{{ path('playlist.detail', {playlistId: playlist.id}) }}"/>
<meta property="og:image" content="{{ asset("uploads/cover/" ~ playlist.fileReference ~ ".png?v=" ~ date().timestamp) }}"/>
{% endblock %}
{% block content %}
<section class="section-playlist-detail">
<div class="cover" style="background-image: url({{ asset('uploads/cover/' ~ playlist.fileReference ~ '.png?t=' ~ date().timestamp) }});">
<div class="shade">
<div class="content">
<div class="title">{{ playlist.title }}{% if playlist.isOfficial %}<span class="official-badge">OFFICIAL</span>{% endif %}</div>
<div class="quickinfo">{{ playlistCount }} Charts</div>
</div>
</div>
</div>
<div class="playlist-content">
<div class="playlist-detail">
<div class="playlist-description">
{{ playlist.description }}
</div>
{% if not playlist.isOfficial %}
<div class="playlist-uploader">
<div class="label">Created by</div>
<a href="{{ path('user.detail', {userId: user.id}) }}" class="user-item">
<div class="user-avatar" style="background-image: url({{ asset('uploads/avatar/' ~ user.coverReference ~ '?t=' ~ date().timestamp) }}), url({{ asset("assets/img/defaultAvatar.jpg") }});"></div>
<div class="user-metadata">
<div class="user-username">{{ user.username }}</div>
{% if user.isVerified %}
<div class="user-badge"><i class="mdi mdi-check-decagram"></i></div>
{% endif %}
{% if user.isPatreon %}
<div class="user-badge"><i class="mdi mdi-patreon"></i></div>
{% endif %}
</div>
</a>
</div>
{% endif %}
</div>
<div class="song-row song-row-playlist">
{% if playlist.songs|length > 0 %}
<div class="song-list">
{% for song in playlist.songs %}
{{ include('components/song-item.html.twig', {song: song}) }}
{% endfor %}
</div>
{% else %}
<div class="list-noresults">
<div class="noresults-text">This playlist is empty.</div>
</div>
{% endif %}
</div>
</div>
</section>
{% endblock %}
{% block styles %}
<link rel="stylesheet" href="{{ asset('assets/css/playlistdetail.css?v=' ~ date().timestamp) }}" />
{% endblock %}
\ No newline at end of file
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
</div> </div>
</div> </div>
<div class="song-actions"> <div class="song-actions">
<div class="action-row">
<a href="{{ path('song.download', {songId: song.id}) }}" class="action"> <a href="{{ path('song.download', {songId: song.id}) }}" class="action">
<div class="icon"> <div class="icon">
<i class="mdi mdi-download"></i> <i class="mdi mdi-download"></i>
...@@ -49,6 +50,8 @@ ...@@ -49,6 +50,8 @@
</div> </div>
</a> </a>
{% if is_granted('ROLE_USER') %} {% if is_granted('ROLE_USER') %}
</div>
<div class="action-row">
{% if uploader.id == app.user.id %} {% if uploader.id == app.user.id %}
<a href="{{ path('song.update', {songId: song.id}) }}" class="action"> <a href="{{ path('song.update', {songId: song.id}) }}" class="action">
<div class="icon"> <div class="icon">
...@@ -67,17 +70,12 @@ ...@@ -67,17 +70,12 @@
</div> </div>
</a> </a>
{% endif %} {% endif %}
{% endif %} <div class="action" onclick="openPlaylistOverlay()">
{% if is_granted('ROLE_MODERATOR') %}
<a href="{{ path('moderation.song.toggleTournament', {songId: song.id}) }}" class="action">
<div class="icon"> <div class="icon">
{% if song.isTournament %} <i class="mdi mdi-playlist-plus"></i>
<i class="mdi mdi-heart-remove"></i> </div>
{% else %} </div>
<i class="mdi mdi-heart-plus"></i>
{% endif %}
</div> </div>
</a>
{% endif %} {% endif %}
</div> </div>
<div class="song-statistics"> <div class="song-statistics">
...@@ -309,6 +307,42 @@ ...@@ -309,6 +307,42 @@
{% endif %} {% endif %}
</div> </div>
</section> </section>
{% if is_granted('ROLE_USER') %}
<div class="playlist-overlay">
<div class="close" onclick="closePlaylistOverlay()"><i class="mdi mdi-close"></i></div>
<form action="" method="POST" class="overlay-content">
<div class="title">ADD TO PLAYLIST</div>
<div class="playlist-list">
{% if is_granted('ROLE_MODERATOR') %}
{% for key,playlist in userPlaylists %}
{% set isInPlaylist = false %}
{% for playlistSong in playlist.songs %}
{% if playlistSong.id == song.id %}
{% set isInPlaylist = true %}
{% endif %}
{% endfor %}
<label class="playlist-item">
<input type="checkbox" name="playlist_{{ key }}" {{ isInPlaylist ? 'checked' : '' }} />
<span>{{ playlist.title }}</span>
</label>
{% endfor %}
{% if userPlaylists|length == 0 %}
<div class="playlist-empty">You don't have any playlists yet.</div>
{% endif %}
{% else %}
<div class="playlist-empty">Coming Soon</div>
{% endif %}
</div>
<div class="actions">
<div class="button" onclick="closePlaylistOverlay()">Close</div>
{% if is_granted('ROLE_MODERATOR') %}<input type="submit" value="Save" name="submitPlaylist" class="button" />{% endif %}
</div>
</form>
</div>
{% endif %}
{% endblock %} {% endblock %}
{% block styles %} {% block styles %}
...@@ -318,7 +352,7 @@ ...@@ -318,7 +352,7 @@
{% block scripts %} {% block scripts %}
<script> <script>
// Song Preview // Song Preview
let songActions = document.querySelector(".song-actions"); let songActionsRow = document.querySelector(".action-row");
let playerToggle = document.querySelector(".song-actions .action-player .icon"); let playerToggle = document.querySelector(".song-actions .action-player .icon");
let playerVolume = document.querySelector(".song-actions .playerVolume"); let playerVolume = document.querySelector(".song-actions .playerVolume");
...@@ -345,7 +379,7 @@ ...@@ -345,7 +379,7 @@
} }
isPlaying = true; isPlaying = true;
songActions.classList.add("player-active"); songActionsRow.classList.add("player-active");
playerToggle.innerHTML = '<i class="mdi mdi-stop"></i>'; playerToggle.innerHTML = '<i class="mdi mdi-stop"></i>';
} }
...@@ -357,14 +391,16 @@ ...@@ -357,14 +391,16 @@
currentPreviewAudio = null; currentPreviewAudio = null;
isPlaying = false; isPlaying = false;
songActions.classList.remove("player-active"); songActionsRow.classList.remove("player-active");
playerToggle.innerHTML = '<i class="mdi mdi-play"></i>'; playerToggle.innerHTML = '<i class="mdi mdi-play"></i>';
} }
function UpdateVolume() { function UpdateVolume() {
currentPreviewAudio.volume = playerVolume.value / 100; currentPreviewAudio.volume = playerVolume.value / 100;
} }
</script>
<script>
// Comments
function ToggleComment(commentID) { function ToggleComment(commentID) {
let DOMtoggleComment = document.querySelector("#toggleComment-" + commentID); let DOMtoggleComment = document.querySelector("#toggleComment-" + commentID);
let DOMcomment = document.querySelector("#comment-" + commentID); let DOMcomment = document.querySelector("#comment-" + commentID);
...@@ -393,4 +429,15 @@ ...@@ -393,4 +429,15 @@
} }
}); });
</script> </script>
<script>
let UIPlaylistOverlay = document.querySelector(".playlist-overlay");
function openPlaylistOverlay() {
UIPlaylistOverlay.classList.add("active");
}
function closePlaylistOverlay() {
UIPlaylistOverlay.classList.remove("active");
}
</script>
{% endblock %} {% endblock %}
\ No newline at end of file
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
{% endfor %} {% endfor %}
</div> </div>
{% else %} {% else %}
<div class="song-list-noresults"> <div class="list-noresults">
<div class="noresults-text">This user did not upload any charts yet.</div> <div class="noresults-text">This user did not upload any charts yet.</div>
</div> </div>
{% endif %} {% endif %}
......
{% extends 'user/detail.html.twig' %}
{% block userDetailContent %}
<div class="playlist-row playlist-row-user">
{% if playlists|length > 0 %}
<div class="playlist-list">
{% for playlist in playlists %}
<a href="{{ path('playlist.detail', {playlistId: playlist.id}) }}" class="playlist-item" style="background-image: url({{ asset('uploads/cover/' ~ playlist.fileReference ~ '.png?t=' ~ date().timestamp) }});">
<div class="shade">
<div class="content">
<div class="title">{{ playlist.title }}{% if playlist.isOfficial %}<span class="official-badge">OFFICIAL</span>{% endif %}</div>
<div class="quickinfo">{{ playlist.songs|length }} Charts</div>
</div>
</div>
</a>
{% endfor %}
</div>
{% else %}
<div class="list-noresults">
<!-- <div class="noresults-text">This user did not create any playlists yet.</div> -->
<div class="noresults-text">Coming Soon!</div>
</div>
{% endif %}
</div>
{% if(is_granted('ROLE_MODERATOR') and user.id == app.user.id) %}
<div class="playlist-action">
<a href="{{ path('playlist.create') }}" class="button">Add New</a>
</div>
{% endif %}
{% endblock %}
\ No newline at end of file
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
{% endfor %} {% endfor %}
</div> </div>
{% else %} {% else %}
<div class="song-list-noresults"> <div class="list-noresults">
<div class="noresults-text">This user has no reviews yet.</div> <div class="noresults-text">This user has no reviews yet.</div>
</div> </div>
{% endif %} {% endif %}
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
{% endfor %} {% endfor %}
</div> </div>
{% else %} {% else %}
<div class="song-list-noresults"> <div class="list-noresults">
<div class="noresults-text">This user did not release any SpinPlays yet.</div> <div class="noresults-text">This user did not release any SpinPlays yet.</div>
</div> </div>
{% endif %} {% endif %}
......
...@@ -49,9 +49,10 @@ ...@@ -49,9 +49,10 @@
{% endif %} {% endif %}
<div class="tabs"> <div class="tabs">
<a class="tab {% if app.request.attributes.get('_route') == 'user.detail.charts' %}active{% endif %}" href="{{ path('user.detail.charts', {userId: user.id}) }}">Charts ({{ charts|length|default("0") }})</a> <a class="tab {% if area == 'charts' %}active{% endif %}" href="{{ path('user.detail', {userId: user.id, area: "charts"}) }}">Charts ({{ charts|length|default("0") }})</a>
<a class="tab {% if app.request.attributes.get('_route') == 'user.detail.reviews' %}active{% endif %}" href="{{ path('user.detail.reviews', {userId: user.id}) }}">Reviews ({{ reviews|length|default("0")}})</a> <a class="tab {% if area == 'playlists' %}active{% endif %}" href="{{ path('user.detail', {userId: user.id, area: "playlists"}) }}">Playlists ({{ playlists|length|default("0")}})</a>
<a class="tab {% if app.request.attributes.get('_route') == 'user.detail.spinplays' %}active{% endif %}" href="{{ path('user.detail.spinplays', {userId: user.id}) }}">SpinPlays ({{ spinPlays|length|default("0")}})</a> <a class="tab {% if area == 'reviews' %}active{% endif %}" href="{{ path('user.detail', {userId: user.id, area: "reviews"}) }}">Reviews ({{ reviews|length|default("0")}})</a>
<a class="tab {% if area == 'spinplays' %}active{% endif %}" href="{{ path('user.detail', {userId: user.id, area: "spinplays"}) }}">SpinPlays ({{ spinPlays|length|default("0")}})</a>
</div> </div>
</header> </header>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment