Merge branch 'table-refactor'
This commit is contained in:
commit
791e218154
@ -9,7 +9,7 @@
|
||||
"scripts": {
|
||||
"build:js": "rollup -c",
|
||||
"watch:js": "rollup -c -w",
|
||||
"serve": "python server.py",
|
||||
"serve": "python ../server.py",
|
||||
"dev": "npm-run-all --parallel watch:js serve",
|
||||
"build": "npm-run-all build:js"
|
||||
},
|
||||
|
@ -29,6 +29,10 @@ html[data-theme='light'] {
|
||||
--panels-background: #222324;
|
||||
--panels-text: #ffffff;
|
||||
--accent-text: #ffffff;
|
||||
|
||||
--table-bg: #ffffff;
|
||||
--table-zebra: #c9c9c9;
|
||||
--table-highlight: #8f8f8f;
|
||||
}
|
||||
|
||||
html[data-theme='dark'] {
|
||||
@ -39,6 +43,10 @@ html[data-theme='dark'] {
|
||||
--panels-background: #1a1a1a;
|
||||
--panels-text: #ffffff;
|
||||
--accent-text: #dfdfdf;
|
||||
|
||||
--table-bg: #141414;
|
||||
--table-zebra: #242424;
|
||||
--table-highlight: #343434;
|
||||
}
|
||||
|
||||
html[data-theme='purple'] {
|
||||
@ -50,6 +58,10 @@ html[data-theme='purple'] {
|
||||
--panels-background: #100727;
|
||||
--panels-text: #ffffff;
|
||||
--accent-text: #dfdfdf;
|
||||
|
||||
--table-bg: #0c041b;
|
||||
--table-zebra: #130a29;
|
||||
--table-highlight: #321874;
|
||||
}
|
||||
|
||||
body {
|
||||
|
23
public/css/modules/base/normalize.css
vendored
23
public/css/modules/base/normalize.css
vendored
@ -4,6 +4,27 @@
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
:root {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
table,
|
||||
caption,
|
||||
tbody,
|
||||
tfoot,
|
||||
thead,
|
||||
tr,
|
||||
th,
|
||||
td {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
font-size: 100%;
|
||||
font: inherit;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
}
|
||||
|
@ -81,10 +81,11 @@ img.circle {
|
||||
|
||||
i.disabled {
|
||||
opacity: 0.5;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
i.explicit_icon {
|
||||
color: #FF3B30;
|
||||
color: #ff3b30;
|
||||
margin-right: var(--explicit-separator);
|
||||
}
|
||||
|
||||
@ -97,33 +98,7 @@ span.tag {
|
||||
padding: 3px 6px;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
-webkit-border-horizontal-spacing: 0px;
|
||||
-webkit-border-vertical-spacing: 0px;
|
||||
}
|
||||
|
||||
table td,
|
||||
table th {
|
||||
padding: 4px 12px 4px 5px;
|
||||
vertical-align: middle;
|
||||
border: 0px black solid;
|
||||
}
|
||||
|
||||
td img {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
table tr:nth-child(even) {
|
||||
background-color: var(--secondary-background);
|
||||
border: 0px black solid;
|
||||
}
|
||||
th {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
p,
|
||||
.tracks_table td.breakline {
|
||||
p {
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
@ -147,6 +122,7 @@ a:visited {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.inline-flex .right {
|
||||
margin-left: auto;
|
||||
}
|
||||
@ -264,25 +240,30 @@ input[type='checkbox']:checked {
|
||||
width: 100%;
|
||||
margin-top: 24px;
|
||||
}
|
||||
|
||||
.tab {
|
||||
margin: 16px 0px;
|
||||
}
|
||||
|
||||
th.sortable {
|
||||
-webkit-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
th.sort-asc:after {
|
||||
content: '\25b2';
|
||||
font-size: 0.7em;
|
||||
padding-left: 3px;
|
||||
line-height: 0.7em;
|
||||
}
|
||||
|
||||
th.sort-desc:after {
|
||||
content: '\25bc';
|
||||
font-size: 0.7em;
|
||||
padding-left: 3px;
|
||||
line-height: 0.7em;
|
||||
}
|
||||
|
||||
.fab {
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
@ -292,6 +273,7 @@ th.sort-desc:after {
|
||||
color: var(--accent-text);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.fab i {
|
||||
font-size: 24px;
|
||||
padding: 16px;
|
200
public/css/modules/globals/tables.css
Normal file
200
public/css/modules/globals/tables.css
Normal file
@ -0,0 +1,200 @@
|
||||
.table {
|
||||
width: 100%;
|
||||
-webkit-border-horizontal-spacing: 0px;
|
||||
-webkit-border-vertical-spacing: 0px;
|
||||
|
||||
--vertical-separator: 7px;
|
||||
}
|
||||
|
||||
.table tr {
|
||||
background: var(--table-bg);
|
||||
transition: background-color 175ms ease-in-out;
|
||||
}
|
||||
|
||||
.table tr:nth-child(even) {
|
||||
background: var(--table-zebra);
|
||||
transition: background-color 175ms ease-in-out;
|
||||
}
|
||||
|
||||
.table tr:not(:last-child) {
|
||||
border-bottom: 1px solid var(--table-highlight);
|
||||
}
|
||||
|
||||
.table tbody tr:not(.table__row-no-highlight):hover {
|
||||
background: var(--table-highlight);
|
||||
}
|
||||
|
||||
.table td,
|
||||
.table th {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.table td {
|
||||
padding: var(--vertical-separator) 10px;
|
||||
}
|
||||
|
||||
.table td:first-child {
|
||||
padding: var(--vertical-separator) 10px var(--vertical-separator) 20px;
|
||||
}
|
||||
|
||||
.table td:last-child {
|
||||
padding: var(--vertical-separator) 20px var(--vertical-separator) 10px;
|
||||
}
|
||||
|
||||
.table td img {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.table .table__icon {
|
||||
box-sizing: content-box;
|
||||
width: 32px;
|
||||
}
|
||||
|
||||
.table__icon.table__icon--big {
|
||||
width: 48px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* .table .table__cell {} */
|
||||
|
||||
.table__cell--x-small {
|
||||
width: 0.32%;
|
||||
}
|
||||
|
||||
.table__cell--small {
|
||||
width: 3.2%;
|
||||
}
|
||||
|
||||
.table__cell--medium {
|
||||
width: 28.7%;
|
||||
}
|
||||
|
||||
.table__cell--large {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.table__cell--left {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.table__cell--center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.table__cell--right {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
/* .table__cell-content {} */
|
||||
|
||||
.table__cell-content.table__cell-content--vertical-center {
|
||||
/* Wrap cell content in this to center vertically cells
|
||||
with material icons or both material icons and text */
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.table__cell--download {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.table__cell--download i.material-icons {
|
||||
transition: color 175ms ease-in-out;
|
||||
}
|
||||
|
||||
.table__cell--download:hover i.material-icons {
|
||||
color: var(--table-bg);
|
||||
}
|
||||
|
||||
.track_row > td > img {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
.track_row > td > a > img {
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
}
|
||||
|
||||
.top-tracks-position {
|
||||
padding: 12px;
|
||||
text-align: center;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
/* === Tracks Table === */
|
||||
.table--tracks {
|
||||
border-collapse: collapse;
|
||||
|
||||
--radius: 3px;
|
||||
}
|
||||
|
||||
.table--tracks thead {
|
||||
border-bottom: 2px solid var(--table-highlight);
|
||||
}
|
||||
|
||||
.table--tracks th {
|
||||
padding-bottom: 10px;
|
||||
height: 45px;
|
||||
}
|
||||
|
||||
.table--tracks td {
|
||||
height: 35px;
|
||||
}
|
||||
|
||||
.table--tracks td.breakline {
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.table--tracks tr:first-child td:first-child {
|
||||
border-top-left-radius: var(--radius);
|
||||
}
|
||||
|
||||
.table--tracks tr:first-child td:last-child {
|
||||
border-top-right-radius: var(--radius);
|
||||
}
|
||||
|
||||
.table--tracks tr:last-child td:first-child {
|
||||
border-bottom-left-radius: var(--radius);
|
||||
}
|
||||
|
||||
.table--tracks tr:last-child td:last-child {
|
||||
border-bottom-right-radius: var(--radius);
|
||||
}
|
||||
|
||||
/* === Tracklist Table === */
|
||||
|
||||
/* .table--tracklist {} */
|
||||
|
||||
.table--tracklist thead {
|
||||
border-bottom: 2px solid var(--table-highlight);
|
||||
}
|
||||
|
||||
.table--tracklist th {
|
||||
height: 45px;
|
||||
padding: var(--vertical-separator) 10px;
|
||||
}
|
||||
|
||||
.table--tracklist th:first-child {
|
||||
padding: var(--vertical-separator) 10px var(--vertical-separator) 20px;
|
||||
}
|
||||
|
||||
.table--tracklist th:last-child {
|
||||
padding: var(--vertical-separator) 20px var(--vertical-separator) 10px;
|
||||
}
|
||||
|
||||
.table--tracklist td {
|
||||
height: 35px;
|
||||
}
|
||||
|
||||
.explicit_tracklist {
|
||||
margin-left: var(--explicit-separator);
|
||||
}
|
||||
|
||||
/* === Charts Table === */
|
||||
|
||||
/* .table--charts {} */
|
||||
|
||||
.table--charts td {
|
||||
height: 35px;
|
||||
}
|
@ -2,12 +2,6 @@
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.top-tracks-position {
|
||||
padding: 12px;
|
||||
text-align: center;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.home_section {
|
||||
border-top: 1px solid var(--separator);
|
||||
padding-top: 25px;
|
||||
|
@ -1,6 +1,5 @@
|
||||
#main_search .search_section {
|
||||
float: none;
|
||||
cursor: pointer;
|
||||
padding-top: 20px;
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
@ -11,6 +10,7 @@
|
||||
|
||||
.search_header {
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
font-size: 1.75rem;
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
@ -104,13 +104,3 @@
|
||||
grid-row-gap: 0px;
|
||||
overflow-y: hidden;
|
||||
}
|
||||
|
||||
.track_row > td > img {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
.track_row > td > a > img {
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
}
|
||||
|
@ -1,23 +1 @@
|
||||
.tracklist_table td {
|
||||
height: 50px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.tracklist_table .explicit_icon {
|
||||
vertical-align: middle;
|
||||
margin-right: var(--explicit-separator);
|
||||
}
|
||||
|
||||
.tracklist_table .track_position_head,
|
||||
.tracklist_table .track_position {
|
||||
width: 10px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.explicit_tracklist {
|
||||
margin-left: var(--explicit-separator);
|
||||
}
|
||||
|
||||
.track_checkbox {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
.preview_controls {
|
||||
opacity: 0;
|
||||
display: block;
|
||||
background: rgba(0, 0, 0, .5);
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
text-align: center;
|
||||
@ -11,8 +11,9 @@
|
||||
top: 0;
|
||||
right: 0;
|
||||
}
|
||||
.preview_playlist_controls{
|
||||
cursor:pointer;
|
||||
|
||||
.preview_playlist_controls {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
a.single-cover {
|
||||
|
@ -4,7 +4,8 @@
|
||||
@import './vendor/toastify.css';
|
||||
|
||||
@import './modules/base/base.css';
|
||||
@import './modules/globals.css';
|
||||
@import './modules/globals/globals.css';
|
||||
@import './modules/globals/tables.css';
|
||||
@import './modules/animations.css';
|
||||
@import './modules/progressbar.css';
|
||||
|
||||
|
@ -68,8 +68,8 @@
|
||||
<main id="main_content">
|
||||
<div id="middle_section">
|
||||
<header id="search">
|
||||
<input id="searchbar" autocomplete="off" type="text" name="searchbar" value="" placeholder="Search or paste a link..."
|
||||
autofocus>
|
||||
<input id="searchbar" autocomplete="off" type="text" name="searchbar" value=""
|
||||
placeholder="Search or paste a link..." autofocus>
|
||||
</header>
|
||||
<section id="content">
|
||||
<div id="container">
|
||||
@ -122,26 +122,41 @@ <h2>Start searching!</h2>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else-if="section == 'TRACK'">
|
||||
<table class="tracks_table">
|
||||
<tr v-for="track in results.allTab.TRACK.data.slice(0, 6)" class="track_row">
|
||||
<td aria-hidden="true" style="width: 48px; text-align: center;"><img class="rounded coverart"
|
||||
:src="'https://e-cdns-images.dzcdn.net/images/cover/'+track.ALB_PICTURE+'/32x32-000000-80-0-0.jpg'">
|
||||
</td>
|
||||
<td class="breakline inline-flex">
|
||||
<i v-if="track.EXPLICIT_LYRICS == 1" class="material-icons explicit_icon">explicit</i>
|
||||
{{track.SNG_TITLE + (track.VERSION ? ' '+track.VERSION : '')}}
|
||||
</td>
|
||||
<td class="breakline"><span class="clickable" @click="artistView" :data-id="artist.ART_ID"
|
||||
v-for="artist in track.ARTISTS">{{artist.ART_NAME}} </span>
|
||||
</td>
|
||||
<td class="breakline clickable" @click="albumView" :data-id="track.ALB_ID">
|
||||
{{track.ALB_TITLE}}</td>
|
||||
<td>{{convertDuration(track.DURATION)}}</td>
|
||||
<td role="button" aria-label="download" @contextmenu.prevent="openQualityModal"
|
||||
@click.stop="addToQueue" :data-link="'https://www.deezer.com/track/'+track.SNG_ID"
|
||||
style="width: 56px; text-align: center;" class="clickable"><i
|
||||
class="material-icons">get_app</i></td>
|
||||
</tr>
|
||||
<table class="table table--tracks">
|
||||
<tbody>
|
||||
<tr v-for="track in results.allTab.TRACK.data.slice(0, 6)">
|
||||
<td class="table__icon" aria-hidden="true">
|
||||
<img class="rounded coverart"
|
||||
:src="'https://e-cdns-images.dzcdn.net/images/cover/'+track.ALB_PICTURE+'/32x32-000000-80-0-0.jpg'">
|
||||
</td>
|
||||
<td class="table__cell table__cell--large breakline">
|
||||
<i v-if="track.EXPLICIT_LYRICS == 1" class="material-icons explicit_icon">
|
||||
explicit
|
||||
</i>
|
||||
{{ track.SNG_TITLE + (track.VERSION ? ' ' + track.VERSION : '') }}
|
||||
</td>
|
||||
<td class="table__cell table__cell--medium table__cell--center breakline">
|
||||
<span class="clickable" @click="artistView" :data-id="artist.ART_ID"
|
||||
v-for="artist in track.ARTISTS">{{artist.ART_NAME}}
|
||||
</span>
|
||||
</td>
|
||||
<td class="table__cell--medium table__cell--center breakline clickable"
|
||||
@click="albumView" :data-id="track.ALB_ID">
|
||||
{{track.ALB_TITLE}}
|
||||
</td>
|
||||
<td class="table__cell table__cell--center">
|
||||
{{convertDuration(track.DURATION)}}
|
||||
</td>
|
||||
<td class="table__cell--download table__cell--center clickable"
|
||||
@contextmenu.prevent="openQualityModal" @click.stop="addToQueue"
|
||||
:data-link="'https://www.deezer.com/track/'+track.SNG_ID" role="button"
|
||||
aria-label="download">
|
||||
<i class="material-icons">
|
||||
get_app
|
||||
</i>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div v-else-if="section == 'ARTIST'" class="release_grid firstrow_only">
|
||||
@ -154,7 +169,7 @@ <h2>Start searching!</h2>
|
||||
@click.stop="addToQueue" :data-link="'https://deezer.com/artist/'+release.ART_ID"
|
||||
class="download_overlay"><i class="material-icons">get_app</i></div>
|
||||
</div>
|
||||
<p class="primary-text">{{release.ART_NAME}}</p>
|
||||
<p class="primary-text">{{ release.ART_NAME }}</p>
|
||||
<p class="secondary-text">{{numberWithDots(release.NB_FAN) + ' fans'}}</p>
|
||||
</div>
|
||||
</div>
|
||||
@ -205,37 +220,58 @@ <h1>Loading</h1>
|
||||
<div v-else-if="results.trackTab.data.length == 0">
|
||||
<h1>No Tracks found</h1>
|
||||
</div>
|
||||
<table class="tracks_table" v-if="results.trackTab.data.length > 0">
|
||||
<tr>
|
||||
<th style="width: 48px;"></th>
|
||||
<th>Title</th>
|
||||
<th>Artists</th>
|
||||
<th>Album</th>
|
||||
<th><i class="material-icons">timer</i></th>
|
||||
<th style="width: 56px;"></th>
|
||||
</tr>
|
||||
<tr v-for="track in results.trackTab.data" class="track_row">
|
||||
<td style="width: 48px; text-align: center;">
|
||||
<a href="#" @click="playPausePreview"
|
||||
:class="'rounded' + (track.preview ? ' single-cover' : '')" :data-preview="track.preview"><i
|
||||
@mouseenter="previewMouseEnter" @mouseleave="previewMouseLeave" v-if="track.preview"
|
||||
class="material-icons preview_controls">play_arrow</i><img class="rounded coverart"
|
||||
:src="track.album.cover_small">
|
||||
</td>
|
||||
<td class="breakline inline-flex">
|
||||
<i v-if="track.explicit_lyrics" class="material-icons explicit_icon">explicit</i>
|
||||
{{ track.title + (track.title_version && track.title.indexOf(track.title_version) == -1 ? ' '+ track.title_version : '') }}
|
||||
</td>
|
||||
<td class="breakline clickable" @click="artistView" :data-id="track.artist.id">
|
||||
{{track.artist.name}}</td>
|
||||
<td class="breakline clickable" @click="albumView" :data-id="track.album.id">
|
||||
{{track.album.title}}</td>
|
||||
<td>{{convertDuration(track.duration)}}</td>
|
||||
<td role="button" aria-label="download" @contextmenu.prevent="openQualityModal"
|
||||
@click.stop="addToQueue" :data-link="track.link" style="width: 56px; text-align: center;"
|
||||
class="clickable"><i class="material-icons">get_app</i>
|
||||
</td>
|
||||
</tr>
|
||||
<table class="table table--tracks" v-if="results.trackTab.data.length > 0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="2">Title</th>
|
||||
<th>Artists</th>
|
||||
<th>Album</th>
|
||||
<th>
|
||||
<i class="material-icons">
|
||||
timer
|
||||
</i>
|
||||
</th>
|
||||
<th style="width: 56px;"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="track in results.trackTab.data">
|
||||
<td class="table__icon table__icon--big">
|
||||
<a href="#" @click="playPausePreview"
|
||||
:class="'rounded' + (track.preview ? ' single-cover' : '')" :data-preview="track.preview">
|
||||
<i @mouseenter="previewMouseEnter" @mouseleave="previewMouseLeave" v-if="track.preview"
|
||||
class="material-icons preview_controls">
|
||||
play_arrow
|
||||
</i>
|
||||
<img class="rounded coverart" :src="track.album.cover_small">
|
||||
</a>
|
||||
</td>
|
||||
<td class="table__cell table__cell--large breakline">
|
||||
<i v-if="track.explicit_lyrics" class="material-icons explicit_icon">
|
||||
explicit
|
||||
</i>
|
||||
{{ track.title + (track.title_version && track.title.indexOf(track.title_version) == -1 ? ' '+ track.title_version : '') }}
|
||||
</td>
|
||||
<td class="table__cell table__cell--medium table__cell--center breakline clickable"
|
||||
@click="artistView" :data-id="track.artist.id">
|
||||
{{track.artist.name}}
|
||||
</td>
|
||||
<td class="table__cell table__cell--medium table__cell--center breakline clickable"
|
||||
@click="albumView" :data-id="track.album.id">
|
||||
{{track.album.title}}
|
||||
</td>
|
||||
<td class="table__cell table__cell--small table__cell--center">
|
||||
{{convertDuration(track.duration)}}
|
||||
</td>
|
||||
<td class="table__cell--download table__cell--center clickable"
|
||||
@contextmenu.prevent="openQualityModal" @click.stop="addToQueue" :data-link="track.link"
|
||||
role="button" aria-label="download">
|
||||
<i class="material-icons">
|
||||
get_app
|
||||
</i>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<!-- ### Album Search Tab ### -->
|
||||
@ -378,28 +414,42 @@ <h2 class="page_heading">Charts</h2>
|
||||
<button @click="changeCountry">Change Country</button>
|
||||
<button @contextmenu.prevent="openQualityModal" @click.stop="addToQueue"
|
||||
:data-link="'https://www.deezer.com/playlist/'+id">Download Chart</button>
|
||||
<table>
|
||||
<tr v-for="track in chart" class="track_row">
|
||||
<td class="top-tracks-position" :class="{ first: track.position === 1 }">{{ track.position }}</td>
|
||||
<td style="width: 48px; text-align: center;">
|
||||
<a href="#" @click="playPausePreview" :class="'rounded' + (track.preview ? ' single-cover' : '')"
|
||||
:data-preview="track.preview"><i @mouseenter="previewMouseEnter" @mouseleave="previewMouseLeave"
|
||||
v-if="track.preview" class="material-icons preview_controls">play_arrow</i><img
|
||||
class="rounded coverart" :src="track.album.cover_small">
|
||||
</td>
|
||||
<td class="breakline">
|
||||
{{ track.title + (track.title_version && track.title.indexOf(track.title_version) == -1 ? ' '+ track.title_version : '') }}
|
||||
</td>
|
||||
<td class="breakline clickable" @click="artistView" :data-id="track.artist.id">
|
||||
{{track.artist.name}}</td>
|
||||
<td class="breakline clickable" @click="albumView" :data-id="track.album.id">
|
||||
{{track.album.title}}</td>
|
||||
<td>{{convertDuration(track.duration)}}</td>
|
||||
<td role="button" aria-label="download" @contextmenu.prevent="openQualityModal"
|
||||
@click.stop="addToQueue" :data-link="track.link" style="width: 56px; text-align: center;"
|
||||
class="clickable"><i class="material-icons">get_app</i>
|
||||
</td>
|
||||
</tr>
|
||||
<table class="table table--charts">
|
||||
<tbody>
|
||||
<tr v-for="track in chart" class="track_row">
|
||||
<td class="top-tracks-position" :class="{ first: track.position === 1 }">
|
||||
{{ track.position }}
|
||||
</td>
|
||||
<td class="table__icon table__icon--big">
|
||||
<a href="#" @click="playPausePreview" class="rounded"
|
||||
:class="{ 'single-cover' : track.preview }" :data-preview="track.preview">
|
||||
<i @mouseenter="previewMouseEnter" @mouseleave="previewMouseLeave" v-if="track.preview"
|
||||
class="material-icons preview_controls">
|
||||
play_arrow
|
||||
</i>
|
||||
<img class="rounded coverart" :src="track.album.cover_small">
|
||||
</a>
|
||||
</td>
|
||||
<td class="table__cell--large breakline">
|
||||
{{ track.title + (track.title_version && track.title.indexOf(track.title_version) == -1 ? ' '+ track.title_version : '') }}
|
||||
</td>
|
||||
<td class="table__cell--medium table__cell--center breakline clickable" @click="artistView"
|
||||
:data-id="track.artist.id">
|
||||
{{track.artist.name}}
|
||||
</td>
|
||||
<td class="table__cell--medium table__cell--center breakline clickable" @click="albumView"
|
||||
:data-id="track.album.id">
|
||||
{{track.album.title}}
|
||||
</td>
|
||||
<td class="table__cell--small table__cell--center">
|
||||
{{convertDuration(track.duration)}}
|
||||
</td>
|
||||
<td class="table__cell--download" @contextmenu.prevent="openQualityModal" @click.stop="addToQueue"
|
||||
:data-link="track.link" role="button" aria-label="download">
|
||||
<i class="material-icons">get_app</i>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
@ -478,26 +528,40 @@ <h1>No Favorite Artist found</h1>
|
||||
<div v-if="tracks.length == 0">
|
||||
<h1>No Favorite Tracks found</h1>
|
||||
</div>
|
||||
<table v-if="tracks.length > 0">
|
||||
<table v-if="tracks.length > 0" class="table">
|
||||
<tr v-for="track in tracks" class="track_row">
|
||||
<td class="top-tracks-position" :class="{ first: track.position === 1 }">{{ track.position }}</td>
|
||||
<td style="width: 48px; text-align: center;">
|
||||
<a href="#" @click="playPausePreview" :class="'rounded' + (track.preview ? ' single-cover' : '')"
|
||||
:data-preview="track.preview"><i @mouseenter="previewMouseEnter" @mouseleave="previewMouseLeave"
|
||||
v-if="track.preview" class="material-icons preview_controls">play_arrow</i><img
|
||||
class="rounded coverart" :src="track.album.cover_small">
|
||||
<td class="top-tracks-position" :class="{ first: track.position === 1 }">
|
||||
{{ track.position }}
|
||||
</td>
|
||||
<td class="breakline">
|
||||
<td>
|
||||
<a href="#" class="rounded" :class="{ 'single-cover' : !!track.preview }"
|
||||
@click="playPausePreview" :data-preview="track.preview">
|
||||
<i @mouseenter="previewMouseEnter" @mouseleave="previewMouseLeave" v-if="track.preview"
|
||||
class="material-icons preview_controls">
|
||||
play_arrow
|
||||
</i>
|
||||
<img class="rounded coverart" :src="track.album.cover_small">
|
||||
</a>
|
||||
</td>
|
||||
<td class="table__cell--large breakline">
|
||||
{{ track.title + (track.title_version && track.title.indexOf(track.title_version) == -1 ? ' '+ track.title_version : '') }}
|
||||
</td>
|
||||
<td class="breakline clickable" @click="artistView" :data-id="track.artist.id">
|
||||
{{track.artist.name}}</td>
|
||||
<td class="breakline clickable" @click="albumView" :data-id="track.album.id">
|
||||
{{track.album.title}}</td>
|
||||
<td>{{convertDuration(track.duration)}}</td>
|
||||
<td role="button" aria-label="download" @contextmenu.prevent="openQualityModal"
|
||||
@click.stop="addToQueue" :data-link="track.link" style="width: 56px; text-align: center;"
|
||||
class="clickable"><i class="material-icons">get_app</i>
|
||||
<td class="table__cell--medium table__cell--center breakline clickable" @click="artistView"
|
||||
:data-id="track.artist.id">
|
||||
{{track.artist.name}}
|
||||
</td>
|
||||
<td class="table__cell--medium table__cell--center breakline clickable" @click="albumView"
|
||||
:data-id="track.album.id">
|
||||
{{track.album.title}}
|
||||
</td>
|
||||
<td class="table__cell--small">
|
||||
{{convertDuration(track.duration)}}
|
||||
</td>
|
||||
<td class="table__cell--download clickable" @contextmenu.prevent="openQualityModal"
|
||||
@click.stop="addToQueue" :data-link="track.link" role="button" aria-label="download">
|
||||
<div class="table__cell-content table__cell-content--vertical-center">
|
||||
<i class="material-icons">get_app</i>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@ -526,7 +590,7 @@ <h2 v-else-if="type == 'album'">by <span class="clickable" @click="artistView"
|
||||
@click.stop="addToQueue" :data-link="link" class="fab right"><i class="material-icons">get_app</i>
|
||||
</div>
|
||||
</header>
|
||||
<table>
|
||||
<table class="table">
|
||||
<tr v-if="data.isrc">
|
||||
<td>ISRC</td>
|
||||
<td>{{ data.isrc }}</td>
|
||||
@ -1021,7 +1085,8 @@ <h3 class="settings-group__header settings-group__header--with-icon">
|
||||
|
||||
<div class="input_group">
|
||||
<p class="input_group_text">Preview Volume</p>
|
||||
<input type="range" @change="updateMaxVolume" min="0" max="100" step="1" class="slider" v-model.number="previewVolume.preview_max_volume">
|
||||
<input type="range" @change="updateMaxVolume" min="0" max="100" step="1" class="slider"
|
||||
v-model.number="previewVolume.preview_max_volume">
|
||||
<span>{{previewVolume.preview_max_volume}}%</span>
|
||||
</div>
|
||||
|
||||
@ -1067,17 +1132,22 @@ <h3 class="settings-group__header settings-group__header--with-icon">
|
||||
<div id="about_tab" class="main_tabcontent">
|
||||
<h1>About</h1>
|
||||
<p>
|
||||
This app uses the <a href="https://deemix.app" target="_blank">deemix</a> library, you can use this library to make your own UI for deemix.</br>
|
||||
Here's the <a href="https://notabug.org/RemixDev/deemix" target="_blank">official repo</a> for the library.<br/>
|
||||
<br/>
|
||||
Stay up to date with the updates by following the <a href="https://t.me/RemixDevNews" target="_blank">news channel</a> on Telegram.<br/>
|
||||
This app uses the <a href="https://deemix.app" target="_blank">deemix</a> library, you can use this
|
||||
library to make your own UI for deemix.</br>
|
||||
Here's the <a href="https://notabug.org/RemixDev/deemix" target="_blank">official repo</a> for the
|
||||
library.<br />
|
||||
<br />
|
||||
Stay up to date with the updates by following the <a href="https://t.me/RemixDevNews"
|
||||
target="_blank">news channel</a> on Telegram.<br />
|
||||
</p>
|
||||
<br/>
|
||||
<br />
|
||||
<p>
|
||||
<a rel="license" href="https://www.gnu.org/licenses/gpl-3.0.en.html" target="_blank">
|
||||
<img alt="GNU General Public License" style="border-width:0" src="https://www.gnu.org/graphics/gplv3-127x51.png"/>
|
||||
</a><br/>
|
||||
This work is licensed under a <a rel="license" href="https://www.gnu.org/licenses/gpl-3.0.en.html" target="_blank">GNU General Public License 3.0</a>.
|
||||
<img alt="GNU General Public License" style="border-width:0"
|
||||
src="https://www.gnu.org/graphics/gplv3-127x51.png" />
|
||||
</a><br />
|
||||
This work is licensed under a <a rel="license" href="https://www.gnu.org/licenses/gpl-3.0.en.html"
|
||||
target="_blank">GNU General Public License 3.0</a>.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@ -1097,7 +1167,7 @@ <h1>{{ title }}</h1>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<table>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th v-for="data in head" @click="data.sortKey ? sortBy(data.sortKey) : null"
|
||||
@ -1112,14 +1182,21 @@ <h1>{{ title }}</h1>
|
||||
<td class="inline-flex clickable" @click="albumView" :data-id="release.id">
|
||||
<img class="rounded coverart" :src="release.cover_small"
|
||||
style="margin-right: 16px; width: 56px; height: 56px;" />
|
||||
<i v-if="release.explicit_lyrics" class="material-icons explicit_icon">explicit</i>
|
||||
<i v-if="release.explicit_lyrics" class="material-icons explicit_icon">
|
||||
explicit
|
||||
</i>
|
||||
{{release.title}}
|
||||
<i v-if="checkNewRelease(release.release_date)" class="material-icons"
|
||||
style="color:#FF7300;">fiber_new</i>
|
||||
<i v-if="checkNewRelease(release.release_date)" class="material-icons" style="color:#FF7300;">
|
||||
fiber_new
|
||||
</i>
|
||||
</td>
|
||||
<td>{{release.release_date}}</td>
|
||||
<td @click.stop="addToQueue" @contextmenu.prevent="openQualityModal" :data-link="release.link"
|
||||
class="clickable"><i class="material-icons">file_download</i></td>
|
||||
class="clickable">
|
||||
<i class="material-icons">
|
||||
file_download
|
||||
</i>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@ -1138,48 +1215,82 @@ <h2 class="inline-flex"><span v-if="metadata">{{ metadata }}</span><span class="
|
||||
v-if="release_date">{{ release_date }}</span></h2>
|
||||
</header>
|
||||
|
||||
<table class="tracklist_table">
|
||||
<table class="table table--tracklist">
|
||||
<thead>
|
||||
<tr>
|
||||
<th v-for="data in head" v-html="data.title"
|
||||
:class="{ track_position_head: data.title.trim() === '#' }"
|
||||
:style="{ 'width': data.width ? data.width : 'auto'}">
|
||||
<th>
|
||||
<i class="material-icons">music_note</i>
|
||||
</th>
|
||||
<th>#</th>
|
||||
<th>Song</th>
|
||||
<th>Artist</th>
|
||||
<th v-if="type == 'Playlist'">Album</th>
|
||||
<th>
|
||||
<i class="material-icons">timer</i>
|
||||
</th>
|
||||
<th class="table__icon table__cell--center clickable">
|
||||
<input @click="toggleAll" class="selectAll" type="checkbox">
|
||||
</th>
|
||||
<th style="width: 32px"><input @click="toggleAll" class="selectAll" type="checkbox"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<template v-if="type!='Spotify Playlist'">
|
||||
<template v-if="type !== 'Spotify Playlist'">
|
||||
<template v-for="track in body">
|
||||
<tr v-if="track.type == 'track'">
|
||||
<td>
|
||||
<i v-if="track.preview" @click=playPausePreview
|
||||
:class="'material-icons' + (track.preview ? ' preview_playlist_controls' : '')"
|
||||
:data-preview="track.preview">play_arrow</i>
|
||||
<i v-else class="material-icons disabled">play_arrow</i>
|
||||
<td class="table__cell--x-small table__cell--center">
|
||||
<div class="table__cell-content table__cell-content--vertical-center">
|
||||
<i class="material-icons"
|
||||
:class="{ 'preview_playlist_controls' : track.preview, disabled: !track.preview }"
|
||||
v-on="{ click: track.preview ? playPausePreview : null }" :data-preview="track.preview">
|
||||
play_arrow
|
||||
</i>
|
||||
</div>
|
||||
</td>
|
||||
<td class="track_position">{{ track.track_position }}</td>
|
||||
<td class="inline-flex">
|
||||
<i v-if="track.explicit_lyrics" class="material-icons explicit_icon">explicit</i>
|
||||
{{ track.title + (track.title_version && track.title.indexOf(track.title_version) == -1 ? ' '+ track.title_version : '') }}
|
||||
<td class="table__cell--small table__cell--center track_position">
|
||||
{{ type === 'Album' ? track.track_position : (body.indexOf(track) + 1) }}
|
||||
</td>
|
||||
<td class="table__cell--large table__cell--with-icon">
|
||||
<div class="table__cell-content table__cell-content--vertical-center">
|
||||
<i v-if="track.explicit_lyrics" class="material-icons explicit_icon">
|
||||
explicit
|
||||
</i>
|
||||
{{ track.title + (track.title_version && track.title.indexOf(track.title_version) == -1 ? ' '+ track.title_version : '') }}
|
||||
</div>
|
||||
</td>
|
||||
<td class="table__cell--medium table__cell--center clickable" @click="artistView"
|
||||
:data-id="track.artist.id">
|
||||
{{ track.artist.name }}
|
||||
</td>
|
||||
<td v-if="type == 'Playlist'" class="table__cell--medium table__cell--center clickable"
|
||||
@click="albumView" :data-id="track.album.id">
|
||||
{{ track.album.title }}
|
||||
</td>
|
||||
<td class="table__cell--center"
|
||||
:class="{ 'table__cell--small' : type === 'Album', 'table__cell--x-small' : type === 'Playlist' }">
|
||||
{{ convertDuration(track.duration) }}
|
||||
</td>
|
||||
<td class="table__icon table__cell--center">
|
||||
<input class="clickable" type="checkbox" v-model="track.selected">
|
||||
</td>
|
||||
<td class="clickable" @click="artistView" :data-id="track.artist.id">
|
||||
{{ track.artist.name }}</td>
|
||||
<td class="clickable" v-if="type == 'Playlist'" @click="albumView" :data-id="track.album.id">
|
||||
{{ track.album.title }}</td>
|
||||
<td>{{ convertDuration(track.duration) }}</td>
|
||||
<td><input class="track_checkbox" type="checkbox" v-model="track.selected"></td>
|
||||
</tr>
|
||||
<tr v-else-if="track.type == 'disc_separator'">
|
||||
<td colspan="6" style="opacity: 0.54;"><i class="material-icons">album</i>{{ track.number }}
|
||||
<tr v-else-if="track.type == 'disc_separator'" class="table__row-no-highlight"
|
||||
style="opacity: 0.54;">
|
||||
<td>
|
||||
<div class="table__cell-content table__cell-content--vertical-center" style="opacity: 0.54;">
|
||||
<i class="material-icons">album</i>
|
||||
</div>
|
||||
</td>
|
||||
<td class="table__cell--center">
|
||||
{{ track.number }}
|
||||
</td>
|
||||
<td colspan="4"></td>
|
||||
</tr>
|
||||
</template>
|
||||
</template>
|
||||
<template v-else>
|
||||
<tr v-for="(track, i) in body">
|
||||
<td>
|
||||
<i v-if="track.preview_url" @click=playPausePreview
|
||||
<i v-if="track.preview_url" @click="playPausePreview"
|
||||
:class="'material-icons' + (track.preview_url ? ' preview_playlist_controls' : '')"
|
||||
:data-preview="track.preview_url">play_arrow</i>
|
||||
<i v-else class="material-icons disabled">play_arrow</i>
|
||||
@ -1192,7 +1303,7 @@ <h2 class="inline-flex"><span v-if="metadata">{{ metadata }}</span><span class="
|
||||
<td>{{ track.artists[0].name }}</td>
|
||||
<td>{{ track.album.name }}</td>
|
||||
<td>{{ convertDuration(Math.floor(track.duration_ms/1000)) }}</td>
|
||||
<td><input class="track_checkbox" type="checkbox" v-model="track.selected"></td>
|
||||
<td><input class="clickable" type="checkbox" v-model="track.selected"></td>
|
||||
</tr>
|
||||
</template>
|
||||
</tbody>
|
||||
@ -1244,4 +1355,4 @@ <h2 class="inline-flex"><span v-if="metadata">{{ metadata }}</span><span class="
|
||||
|
||||
<script src="/public/js/bundle.js"></script>
|
||||
|
||||
</html>
|
||||
</html>
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -85,9 +85,8 @@ const TracklistTab = new Vue({
|
||||
{ title: 'Artist' },
|
||||
{ title: '<i class="material-icons">timer</i>', width: '40px' }
|
||||
]
|
||||
if (_.isEmpty(data.tracks)) {
|
||||
console.log('show e lodash ok')
|
||||
|
||||
if (_.isEmpty(data.tracks)) {
|
||||
this.body = null
|
||||
} else {
|
||||
this.body = data.tracks
|
||||
@ -108,6 +107,7 @@ const TracklistTab = new Vue({
|
||||
{ title: 'Album' },
|
||||
{ title: '<i class="material-icons">timer</i>', width: '40px' }
|
||||
]
|
||||
|
||||
if (_.isEmpty(data.tracks)) {
|
||||
this.body = null
|
||||
} else {
|
||||
|
@ -18,7 +18,7 @@ function init() {
|
||||
preview_track.addEventListener('canplay', function () {
|
||||
preview_track.play()
|
||||
preview_stopped = false
|
||||
$(preview_track).animate({ volume: vol.preview_max_volume/100 }, 500)
|
||||
$(preview_track).animate({ volume: vol.preview_max_volume / 100 }, 500)
|
||||
})
|
||||
|
||||
// auto fadeout when at the end of the song
|
||||
@ -67,16 +67,17 @@ function playPausePreview(e) {
|
||||
|
||||
const { currentTarget: obj } = event
|
||||
|
||||
var icon = obj.tagName == 'I' ? $(obj) : $(obj).children('i')
|
||||
var $icon = obj.tagName == 'I' ? $(obj) : $(obj).children('i')
|
||||
|
||||
if ($(obj).attr('playing')) {
|
||||
if (preview_track.paused) {
|
||||
preview_track.play()
|
||||
preview_stopped = false
|
||||
icon.text('pause')
|
||||
$(preview_track).animate({ volume: vol.preview_max_volume/100 }, 500)
|
||||
$icon.text('pause')
|
||||
$(preview_track).animate({ volume: vol.preview_max_volume / 100 }, 500)
|
||||
} else {
|
||||
preview_stopped = true
|
||||
icon.text('play_arrow')
|
||||
$icon.text('play_arrow')
|
||||
$(preview_track).animate({ volume: 0 }, 250, 'swing', () => {
|
||||
preview_track.pause()
|
||||
})
|
||||
@ -87,8 +88,8 @@ function playPausePreview(e) {
|
||||
$('.preview_controls').text('play_arrow')
|
||||
$('.preview_playlist_controls').text('play_arrow')
|
||||
$('.preview_controls').css({ opacity: 0 })
|
||||
icon.text('pause')
|
||||
icon.css({ opacity: 1 })
|
||||
$icon.text('pause')
|
||||
$icon.css({ opacity: 1 })
|
||||
preview_stopped = false
|
||||
$(preview_track).animate({ volume: 0 }, 250, 'swing', () => {
|
||||
preview_track.pause()
|
||||
|
Loading…
Reference in New Issue
Block a user