started re-organization of settings tab

This commit is contained in:
Roberto Tonino 2020-04-29 21:46:10 +02:00
parent f5455ab580
commit 97986372fe
9 changed files with 237 additions and 157 deletions

View File

@ -1,7 +1,7 @@
/* Normalizing */
* { * {
/* Normalizing */ margin: 0;
/* margin: 0; */ padding: 0;
/* padding: 0; */
box-sizing: border-box; box-sizing: border-box;
} }

View File

@ -20,12 +20,12 @@ img.circle {
display: block; display: block;
width: 100%; width: 100%;
height: auto; height: auto;
transition: .5s ease; transition: 0.5s ease;
backface-visibility: hidden; backface-visibility: hidden;
} }
.cover_container .download_overlay { .cover_container .download_overlay {
transition: .5s ease; transition: 0.5s ease;
opacity: 0; opacity: 0;
position: absolute; position: absolute;
top: 50%; top: 50%;
@ -44,7 +44,7 @@ img.circle {
} }
.cover_container:hover .coverart { .cover_container:hover .coverart {
opacity: 0.75 opacity: 0.75;
} }
.cover_container:hover .download_overlay { .cover_container:hover .download_overlay {
@ -66,7 +66,8 @@ table {
-webkit-border-vertical-spacing: 0px; -webkit-border-vertical-spacing: 0px;
} }
table td, table th { table td,
table th {
padding: 4px 12px 4px 5px; padding: 4px 12px 4px 5px;
vertical-align: middle; vertical-align: middle;
border: 0px black solid; border: 0px black solid;
@ -80,7 +81,7 @@ table tr:nth-child(even) {
background-color: var(--secondary-background); background-color: var(--secondary-background);
border: 0px black solid; border: 0px black solid;
} }
th{ th {
text-align: left; text-align: left;
} }
@ -105,7 +106,7 @@ p,
display: flex; display: flex;
align-items: center; align-items: center;
} }
.inline-flex .right{ .inline-flex .right {
margin-left: auto; margin-left: auto;
} }
@ -155,9 +156,9 @@ button.with_icon i {
margin-left: 8px; margin-left: 8px;
} }
input[type="text"], input[type='text'],
input[type="password"], input[type='password'],
input[type="number"] { input[type='number'] {
width: calc(100% - 16px); width: calc(100% - 16px);
border: 0px solid black; border: 0px solid black;
line-height: 36px; line-height: 36px;
@ -168,7 +169,7 @@ input[type="number"] {
margin-bottom: 8px; margin-bottom: 8px;
} }
select{ select {
-webkit-appearance: none; -webkit-appearance: none;
appearance: none; appearance: none;
width: 100%; width: 100%;
@ -191,7 +192,7 @@ input[type='checkbox'] {
appearance: none; appearance: none;
background-color: none; background-color: none;
border: 2px solid black; border: 2px solid black;
opacity: .50; opacity: 0.5;
border-radius: 2px; border-radius: 2px;
padding: 7px; padding: 7px;
margin: 3px; margin: 3px;
@ -230,13 +231,23 @@ input[type='checkbox']:checked {
.tab { .tab {
margin: 16px 0px; margin: 16px 0px;
} }
th.sortable{ th.sortable {
-webkit-user-select: none; -webkit-user-select: none;
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-asc:after {
th.sort-desc:after {content: "\25bc";font-size: 0.7em;padding-left: 3px;line-height: 0.7em;} content: '\25b2';
.fab{ 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; width: 56px;
height: 56px; height: 56px;
border-radius: 28px; border-radius: 28px;
@ -245,7 +256,7 @@ th.sort-desc:after {content: "\25bc";font-size: 0.7em;padding-left: 3px;line-hei
color: var(--accent-text); color: var(--accent-text);
cursor: pointer; cursor: pointer;
} }
.fab i{ .fab i {
font-size: 24px; font-size: 24px;
padding: 16px; padding: 16px;
} }

View File

@ -0,0 +1,5 @@
.top-tracks-position {
padding: 12px;
text-align: center;
cursor: default;
}

View File

@ -1,4 +1,31 @@
/* Settings */ #settings_heading {
font-size: 2.5rem;
margin-bottom: 35px;
}
#settings_picture {
width: 125px;
height: 125px;
}
#logged_in_info {
height: 250px;
display: flex;
flex-direction: column;
justify-content: space-evenly;
align-items: center;
}
#logged_in_info.hide {
display: none;
}
#log_info {
display: flex;
flex-direction: column;
align-items: center;
}
#open_login_prompt { #open_login_prompt {
margin: 8px 0px; margin: 8px 0px;
} }
@ -18,7 +45,15 @@
padding: 6px 0px; padding: 6px 0px;
} }
#logged_in_info { .settings_group {
display: none; display: flex;
margin-bottom: 12px; flex-direction: column;
} justify-content: center;
border-top: 1px solid #8f8f8f; /* Need less opacity */
padding-top: 20px;
padding-bottom: 20px;
}
.settings_group > * {
margin-bottom: 15px;
}

View File

@ -16,3 +16,4 @@
@import './modules/download-tab.css'; @import './modules/download-tab.css';
@import './modules/track-preview.css'; @import './modules/track-preview.css';
@import './modules/tracklist-tab.css'; @import './modules/tracklist-tab.css';
@import './modules/home-tab.css';

View File

@ -249,76 +249,74 @@ <h1>No Playlists found</h1>
<div id="home_tab" class="main_tabcontent"> <div id="home_tab" class="main_tabcontent">
<h1>Home</h1> <h1>Home</h1>
<div v-if="tracks.length"> <div v-if="tracks.length">
<h2>Top Tracks</h2> <h2>Top Tracks</h2>
<table> <table>
<tr v-for="track in tracks" class="track_row"> <tr v-for="track in tracks" class="track_row">
<td style="width: 48px; text-align: center;"> <td class="top-tracks-position" :class="{ first: track.position === 1 }">{{ track.position }}</td>
<a href="#" @click="playPausePreview" :class="'rounded' + (track.preview ? ' single-cover' : '')" <td style="width: 48px; text-align: center;">
:data-preview="track.preview"><i @mouseenter="previewMouseEnter" @mouseleave="previewMouseLeave" <a href="#" @click="playPausePreview" :class="'rounded' + (track.preview ? ' single-cover' : '')"
v-if="track.preview" class="material-icons preview_controls">play_arrow</i><img :data-preview="track.preview"><i @mouseenter="previewMouseEnter" @mouseleave="previewMouseLeave"
class="rounded coverart" :src="track.album.cover_small"> v-if="track.preview" class="material-icons preview_controls">play_arrow</i><img
</td> class="rounded coverart" :src="track.album.cover_small">
<td class="breakline">{{track.title + (track.title_version ? ' '+track.title_version : '')}}</td> </td>
<td class="breakline clickable" @click="artistView" :data-id="track.artist.id"> <td class="breakline">{{track.title + (track.title_version ? ' '+track.title_version : '')}}</td>
{{track.artist.name}}</td> <td class="breakline clickable" @click="artistView" :data-id="track.artist.id">
<td class="breakline clickable" @click="albumView" :data-id="track.album.id"> {{track.artist.name}}</td>
{{track.album.title}}</td> <td class="breakline clickable" @click="albumView" :data-id="track.album.id">
<td>{{convertDuration(track.duration)}}</td> {{track.album.title}}</td>
<td role="button" aria-label="download" @contextmenu.prevent="openQualityModal" <td>{{convertDuration(track.duration)}}</td>
@click.stop="addToQueue" :data-link="track.link" style="width: 56px; text-align: center;" <td role="button" aria-label="download" @contextmenu.prevent="openQualityModal"
class="clickable"><i class="material-icons">get_app</i> @click.stop="addToQueue" :data-link="track.link" style="width: 56px; text-align: center;"
</td> class="clickable"><i class="material-icons">get_app</i>
</tr> </td>
</table> </tr>
</div> </table>
<div v-if="albums.length"> </div>
<h2>Top Albums</h2> <div v-if="albums.length">
<div class="release_grid"> <h2>Top Albums</h2>
<div v-for="release in albums" class="release clickable" @click="albumView" <div class="release_grid">
:data-id="release.id"> <div v-for="release in albums" class="release clickable" @click="albumView" :data-id="release.id">
<div class="cover_container"> <div class="cover_container">
<img class="rounded coverart" :src="release.cover_medium"> <img class="rounded coverart" :src="release.cover_medium">
<div role="button" aria-label="download" @contextmenu.prevent="openQualityModal" <div role="button" aria-label="download" @contextmenu.prevent="openQualityModal"
@click.stop="addToQueue" :data-link="release.link" class="download_overlay"><i @click.stop="addToQueue" :data-link="release.link" class="download_overlay"><i
class="material-icons">get_app</i></div> class="material-icons">get_app</i></div>
</div> </div>
<p class="primary-text">{{ release.title }}</p> <p class="primary-text">{{ release.title }}</p>
<p class="secondary-text">{{ 'by '+release.artist.name }}</p> <p class="secondary-text">{{ 'by '+release.artist.name }}</p>
</div> </div>
</div> </div>
</div> </div>
<div v-if="artists.length"> <div v-if="artists.length">
<h2>Top Artists</h2> <h2>Top Artists</h2>
<div class="release_grid"> <div class="release_grid">
<div v-for="release in artists" class="release clickable" @click="artistView" <div v-for="release in artists" class="release clickable" @click="artistView" :data-id="release.id">
:data-id="release.id"> <div class="cover_container">
<div class="cover_container"> <img class="circle coverart" :src="release.picture_medium">
<img class="circle coverart" :src="release.picture_medium"> <div role="button" aria-label="download" @contextmenu.prevent="openQualityModal"
<div role="button" aria-label="download" @contextmenu.prevent="openQualityModal" @click.stop="addToQueue" :data-link="release.link" class="download_overlay"><i
@click.stop="addToQueue" :data-link="release.link" class="download_overlay"><i class="material-icons">get_app</i></div>
class="material-icons">get_app</i></div> </div>
</div> <p class="primary-text">{{ release.name }}</p>
<p class="primary-text">{{ release.name }}</p> </div>
</div> </div>
</div> </div>
</div> <div v-if="playlists.length">
<div v-if="playlists.length"> <h2>Top Playlists</h2>
<h2>Top Playlists</h2> <div class="release_grid">
<div class="release_grid"> <div v-for="release in playlists" class="release clickable" @click="playlistView" :data-id="release.id">
<div v-for="release in playlists" class="release clickable" @click="playlistView" <div class="cover_container">
:data-id="release.id"> <img class="rounded coverart" :src="release.picture_medium">
<div class="cover_container"> <div role="button" aria-label="download" @contextmenu.prevent="openQualityModal"
<img class="rounded coverart" :src="release.picture_medium"> @click.stop="addToQueue" :data-link="release.link" class="download_overlay"><i
<div role="button" aria-label="download" @contextmenu.prevent="openQualityModal" class="material-icons">get_app</i></div>
@click.stop="addToQueue" :data-link="release.link" class="download_overlay"><i </div>
class="material-icons">get_app</i></div> <p class="primary-text">{{ release.title }}</p>
</div> <p class="secondary-text">{{ 'by '+release.user.name+' - '+release.nb_tracks+' tracks' }}</p>
<p class="primary-text">{{ release.title }}</p> </div>
<p class="secondary-text">{{ 'by '+release.user.name+' - '+release.nb_tracks+' tracks' }}</p> </div>
</div> </div>
</div>
</div>
</div> </div>
<div id="charts_tab" class="main_tabcontent"> <div id="charts_tab" class="main_tabcontent">
@ -381,76 +379,96 @@ <h2>{{ subtitle }}</h2>
</div> </div>
<div id="settings_tab" class="main_tabcontent fixed_footer"> <div id="settings_tab" class="main_tabcontent fixed_footer">
<h1>Settings</h1> <h2 id="settings_heading">Settings</h2>
<div id="logged_in_info" class="inline-flex">
<img id="settings_picture" src="" alt="Profile Picture" class="circle" <div id="logged_in_info">
style="width: 125px;height:125px; margin-right: 12px;" /> <img id="settings_picture" src="" alt="Profile Picture" class="circle" />
<div> <p>You are logged in as <strong id="settings_username"></strong></p>
<p>You are logged in as <b id="settings_username"></b></p> <button id="settings_btn_logout" @click="logout">Logout</button>
<button id="settings_btn_logout" @click="logout">Logout</button>
</div>
</div> </div>
<div class="inline-flex">
<input autocomplete="off" type="password" id="login_input_arl" ref="loginInput" placeholder="ARL" /> <div class="settings_group">
<button id="settings_btn_copyArl" @click="copyARLtoClipboard"><i <h3>ARL</h3>
class="material-icons">assignment</i></button> <div class="inline-flex">
<input autocomplete="off" type="password" id="login_input_arl" ref="loginInput" placeholder="ARL" />
<button id="settings_btn_copyArl" @click="copyARLtoClipboard">
<i class="material-icons">assignment</i>
</button>
</div>
<a href="https://notabug.org/RemixDevs/DeezloaderRemix/wiki/Login+via+userToken" target="_blank">
How do I get my own ARL?
</a>
<button id="settings_btn_updateArl" @click="login" style="width:100%;">Update ARL</button>
</div> </div>
<p><a href="https://notabug.org/RemixDevs/DeezloaderRemix/wiki/Login+via+userToken" target="_blank">How do I
get my own ARL?</a></p> <div class="settings_group">
<p><button id="settings_btn_updateArl" @click="login" style="width:100%;">Update ARL</button></p> <h3>Download Path</h3>
<div id="settings_generic_tab"> <input type="text" v-model="settings.downloadLocation">
<div class="input_group"> </div>
<p>Download Path</p>
<input type="text" v-model="settings.downloadLocation"> <div class="settings_group">
</div> <h3>Templates</h3>
<div class="input_group">
<p>Trackname template</p> <p>Trackname template</p>
<input type="text" v-model="settings.tracknameTemplate"> <input type="text" v-model="settings.tracknameTemplate">
</div>
<div class="input_group"> <p>Album track template</p>
<p>Album track template</p> <input type="text" v-model="settings.albumTracknameTemplate">
<input type="text" v-model="settings.albumTracknameTemplate">
</div> <p>Playlist track template</p>
<div class="input_group"> <input type="text" v-model="settings.playlistTracknameTemplate">
<p>Playlist track template</p> </div>
<input type="text" v-model="settings.playlistTracknameTemplate">
</div> <div class="settings_group">
<div class="input_group"> <h3>Folders</h3>
<p>Create folder for playlist</p>
<input type="checkbox" v-model="settings.createPlaylistFolder">
</div> <label><input type="checkbox" v-model="settings.createPlaylistFolder">Create folder for playlist</label>
<div class="input_group" v-if="settings.createPlaylistFolder">
<div v-if="settings.createPlaylistFolder">
<p>Playlist folder template</p> <p>Playlist folder template</p>
<input type="text" v-model="settings.playlistNameTemplate"> <input type="text" v-model="settings.playlistNameTemplate">
</div> </div>
<div class="input_group">
<div>
<p>Create folder for artist</p> <p>Create folder for artist</p>
<input type="checkbox" v-model="settings.createArtistFolder"> <input type="checkbox" v-model="settings.createArtistFolder">
</div> </div>
<div class="input_group" v-if="settings.createArtistFolder">
<div v-if="settings.createArtistFolder">
<p>Artist folder template</p> <p>Artist folder template</p>
<input type="text" v-model="settings.artistNameTemplate"> <input type="text" v-model="settings.artistNameTemplate">
</div> </div>
<div class="input_group">
<div>
<p>Create folder for album</p> <p>Create folder for album</p>
<input type="checkbox" v-model="settings.createAlbumFolder"> <input type="checkbox" v-model="settings.createAlbumFolder">
</div> </div>
<div class="input_group" v-if="settings.createAlbumFolder">
<div v-if="settings.createAlbumFolder">
<p>Album folder template</p> <p>Album folder template</p>
<input type="text" v-model="settings.albumNameTemplate"> <input type="text" v-model="settings.albumNameTemplate">
</div> </div>
<div class="input_group">
<div>
<p>Create folder for CDs</p> <p>Create folder for CDs</p>
<input type="checkbox" v-model="settings.createCDFolder"> <input type="checkbox" v-model="settings.createCDFolder">
</div> </div>
<div class="input_group">
<div>
<p>Create folder structure for playlists</p> <p>Create folder structure for playlists</p>
<input type="checkbox" v-model="settings.createStructurePlaylist"> <input type="checkbox" v-model="settings.createStructurePlaylist">
</div> </div>
<div class="input_group">
<div>
<p>Create folder structure for singles</p> <p>Create folder structure for singles</p>
<input type="checkbox" v-model="settings.createSingleFolder"> <input type="checkbox" v-model="settings.createSingleFolder">
</div> </div>
</div>
<div id="settings_generic_tab">
<div class="input_group"> <div class="input_group">
<p>Pad tracks</p> <p>Pad tracks</p>
<input type="checkbox" v-model="settings.padTracks"> <input type="checkbox" v-model="settings.padTracks">
@ -725,4 +743,4 @@ <h2 class="inline-flex"><span v-if="metadata">{{ metadata }}</span><span class="
<script type="module" src="/public/js/app.js"></script> <script type="module" src="/public/js/app.js"></script>
</html> </html>

View File

@ -33,7 +33,8 @@ socket.on('logged_in', function (data) {
'src', 'src',
`https://e-cdns-images.dzcdn.net/images/user/${data.user.picture}/125x125-000000-80-0-0.jpg` `https://e-cdns-images.dzcdn.net/images/user/${data.user.picture}/125x125-000000-80-0-0.jpg`
) )
$('#logged_in_info').show() // $('#logged_in_info').show()
document.getElementById('logged_in_info').classList.remove('hide')
} }
break break
case 2: case 2:
@ -44,7 +45,8 @@ socket.on('logged_in', function (data) {
'src', 'src',
`https://e-cdns-images.dzcdn.net/images/user/${data.user.picture}/125x125-000000-80-0-0.jpg` `https://e-cdns-images.dzcdn.net/images/user/${data.user.picture}/125x125-000000-80-0-0.jpg`
) )
$('#logged_in_info').show() // $('#logged_in_info').show()
document.getElementById('logged_in_info').classList.remove('hide')
} }
break break
case 0: case 0:
@ -52,7 +54,8 @@ socket.on('logged_in', function (data) {
localStorage.removeItem('arl') localStorage.removeItem('arl')
$('#login_input_arl').val('') $('#login_input_arl').val('')
$('#open_login_prompt').show() $('#open_login_prompt').show()
$('#logged_in_info').hide() document.getElementById('logged_in_info').classList.add('hide')
// $('#logged_in_info').hide()
$('#settings_username').text('Not Logged') $('#settings_username').text('Not Logged')
$('#settings_picture').attr('src', `https://e-cdns-images.dzcdn.net/images/user/125x125-000000-80-0-0.jpg`) $('#settings_picture').attr('src', `https://e-cdns-images.dzcdn.net/images/user/125x125-000000-80-0-0.jpg`)
break break
@ -64,7 +67,8 @@ socket.on('logged_out', function () {
localStorage.removeItem('arl') localStorage.removeItem('arl')
$('#login_input_arl').val('') $('#login_input_arl').val('')
$('#open_login_prompt').show() $('#open_login_prompt').show()
$('#logged_in_info').hide() document.getElementById('logged_in_info').classList.add('hide')
// $('#logged_in_info').hide()
$('#settings_username').text('Not Logged') $('#settings_username').text('Not Logged')
$('#settings_picture').attr('src', `https://e-cdns-images.dzcdn.net/images/user/125x125-000000-80-0-0.jpg`) $('#settings_picture').attr('src', `https://e-cdns-images.dzcdn.net/images/user/125x125-000000-80-0-0.jpg`)
}) })

View File

@ -8,33 +8,32 @@ import Utils from '../utils.js'
const HomeTab = new Vue({ const HomeTab = new Vue({
data() { data() {
return { return {
tracks: [], tracks: [],
albums: [], albums: [],
artists: [], artists: [],
playlists: [] playlists: []
} }
}, },
methods: { methods: {
artistView, artistView,
albumView, albumView,
playlistView, playlistView,
playPausePreview: TrackPreview.playPausePreview, playPausePreview: TrackPreview.playPausePreview,
previewMouseEnter: TrackPreview.previewMouseEnter, previewMouseEnter: TrackPreview.previewMouseEnter,
previewMouseLeave: TrackPreview.previewMouseLeave, previewMouseLeave: TrackPreview.previewMouseLeave,
numberWithDots: Utils.numberWithDots, numberWithDots: Utils.numberWithDots,
convertDuration: Utils.convertDuration, convertDuration: Utils.convertDuration,
addToQueue: function (e) { addToQueue(e) {
e.stopPropagation() e.stopPropagation()
Downloads.sendAddToQueue(e.currentTarget.dataset.link) Downloads.sendAddToQueue(e.currentTarget.dataset.link)
}, },
openQualityModal: function (e) { openQualityModal(e) {
e.preventDefault()
QualityModal.open(e.currentTarget.dataset.link) QualityModal.open(e.currentTarget.dataset.link)
}, },
initHome(data) { initHome(data) {
this.tracks = data.tracks.data this.tracks = data.tracks.data
this.albums = data.albums.data this.albums = data.albums.data
this.artists = data.artists.data this.artists = data.artists.data
this.playlists = data.playlists.data this.playlists = data.playlists.data
} }
}, },

View File

@ -15,6 +15,9 @@ window.windows_stack = []
/* ===== Locals ===== */ /* ===== Locals ===== */
let currentStack = {} let currentStack = {}
// Exporting this function out of the default export
// because it's used in components that are needed
// in this file too
export function artistView(ev) { export function artistView(ev) {
let id = ev.currentTarget.dataset.id let id = ev.currentTarget.dataset.id
ArtistTab.reset() ArtistTab.reset()
@ -22,6 +25,9 @@ export function artistView(ev) {
showTab('artist', id) showTab('artist', id)
} }
// Exporting this function out of the default export
// because it's used in components that are needed
// in this file too
export function albumView(ev) { export function albumView(ev) {
let id = ev.currentTarget.dataset.id let id = ev.currentTarget.dataset.id
TracklistTab.reset() TracklistTab.reset()
@ -29,6 +35,9 @@ export function albumView(ev) {
showTab('album', id) showTab('album', id)
} }
// Exporting this function out of the default export
// because it's used in components that are needed
// in this file too
export function playlistView(ev) { export function playlistView(ev) {
let id = ev.currentTarget.dataset.id let id = ev.currentTarget.dataset.id
TracklistTab.reset() TracklistTab.reset()
@ -145,8 +154,6 @@ function changeTab(sidebarEl, section, tabName) {
search_selected = tabName search_selected = tabName
} }
// window[section + '_selected'] = tabName
// Not choosing .currentTarget beacuse the event // Not choosing .currentTarget beacuse the event
// is delegated // is delegated
sidebarEl.classList.add('active') sidebarEl.classList.add('active')