workflow: added linter and linted src/ folder

This commit is contained in:
Roberto Tonino
2021-05-23 18:46:03 +02:00
parent 0f2a1103fd
commit 3a58636d36
61 changed files with 7343 additions and 2498 deletions

View File

@@ -1,9 +1,9 @@
<template>
<main
id="content"
@scroll="$route.name === 'Search' ? handleContentScroll($event) : null"
ref="content"
aria-label="main content"
@scroll="$route.name === 'Search' ? handleContentScroll($event) : null"
>
<div id="container">
<BackButton v-if="showBackButton" class="sticky -ml-20" style="top: 1rem" />
@@ -11,16 +11,16 @@
<keep-alive>
<router-view
v-if="!$route.meta.notKeepAlive"
:class="{ '-mt-16': showBackButton }"
:key="$route.fullPath"
:class="{ '-mt-16': showBackButton }"
:perform-scrolled-search="performScrolledSearch"
></router-view>
</keep-alive>
<router-view
v-if="$route.meta.notKeepAlive"
:class="{ '-mt-16': showBackButton }"
:key="$route.fullPath"
:class="{ '-mt-16': showBackButton }"
:perform-scrolled-search="performScrolledSearch"
></router-view>
</div>
@@ -83,7 +83,7 @@ export default {
}),
computed: {
showBackButton() {
return ['Tracklist', 'Artist', 'Album', 'Playlist', 'Spotify Playlist'].indexOf(this.$route.name) !== -1
return ['Tracklist', 'Artist', 'Album', 'Playlist', 'Spotify Playlist'].includes(this.$route.name)
}
},
mounted() {

View File

@@ -6,6 +6,7 @@
<input
id="searchbar"
ref="searchbar"
class="w-full"
autocomplete="off"
type="search"
@@ -13,7 +14,6 @@
value=""
:placeholder="$t('searchbar')"
autofocus
ref="searchbar"
@keyup="performSearch($event)"
/>
<!-- @keyup.enter.exact="onEnter"
@@ -134,20 +134,20 @@ export default defineComponent({
},
methods: {
async performSearch(keyEvent) {
let isEnterPressed = keyEvent.keyCode === 13
const isEnterPressed = keyEvent.keyCode === 13
if (!isEnterPressed) return
let term = this.$refs.searchbar.value
let isEmptySearch = term === ''
const term = this.$refs.searchbar.value
const isEmptySearch = term === ''
if (isEmptySearch) return
let isSearchingURL = isValidURL(term)
let isCtrlPressed = keyEvent.ctrlKey
let isShowingAnalyzer = this.$route.name === 'Link Analyzer'
let isShowingSearch = this.$route.name === 'Search'
let isSameAsLastSearch = term === this.lastTextSearch
const isSearchingURL = isValidURL(term)
const isCtrlPressed = keyEvent.ctrlKey
const isShowingAnalyzer = this.$route.name === 'Link Analyzer'
const isShowingSearch = this.$route.name === 'Search'
const isSameAsLastSearch = term === this.lastTextSearch
if (isSearchingURL) {
if (isCtrlPressed) {

View File

@@ -217,14 +217,14 @@
const possibleStates = ['converting', 'downloading', 'download finished', 'completed']
export default {
props: {
queueItem: Object
},
data() {
return {
isLoading: false
}
},
props: {
queueItem: Object
},
computed: {
hasFails() {
return this.queueItem.failed >= 1
@@ -242,7 +242,7 @@ export default {
return this.queueItem.status === 'download finished' && this.hasFails
},
isDeterminateStatus() {
return possibleStates.indexOf(this.queueItem.status) !== -1
return possibleStates.includes(this.queueItem.status)
},
barClass() {
return {
@@ -292,12 +292,10 @@ export default {
if (this.queueItem.status === 'download finished') {
if (!this.hasFails) {
text = 'done'
} else if (this.queueItem.failed >= this.queueItem.size) {
text = 'error'
} else {
if (this.queueItem.failed >= this.queueItem.size) {
text = 'error'
} else {
text = 'warning'
}
text = 'warning'
}
}

View File

@@ -1,29 +1,29 @@
<template>
<section
id="download_tab_container"
ref="container"
class="block h-screen bg-panels-bg text-foreground"
:class="{ 'tab-hidden': !isExpanded, 'w-8': !isExpanded }"
@transitionend="$refs.container.style.transition = ''"
ref="container"
:data-label="$t('downloads')"
aria-label="downloads"
@transitionend="$refs.container.style.transition = ''"
>
<!-- Drag handler -->
<div
v-show="isExpanded"
class="absolute w-4 h-full bg-grayscale-200"
@mousedown.prevent="startDrag"
style="cursor: ew-resize"
@mousedown.prevent="startDrag"
></div>
<!-- Bar toggler -->
<i
id="toggle_download_tab"
ref="toggler"
class="m-1 text-2xl cursor-pointer material-icons"
:class="{ 'ml-1': !isExpanded, 'ml-5': isExpanded }"
@click.prevent="toggleDownloadTab"
ref="toggler"
:title="$t('globals.toggle_download_tab_hint')"
@click.prevent="toggleDownloadTab"
></i>
<!-- Queue buttons -->
@@ -39,23 +39,23 @@
>
folder_open
</i>
<i class="m-1 text-2xl cursor-pointer material-icons" @click="cleanQueue" :title="$t('globals.clean_queue_hint')">
<i class="m-1 text-2xl cursor-pointer material-icons" :title="$t('globals.clean_queue_hint')" @click="cleanQueue">
clear_all
</i>
<i
class="m-1 text-2xl cursor-pointer material-icons"
@click="cancelQueue"
:title="$t('globals.cancel_queue_hint')"
@click="cancelQueue"
>
delete_sweep
</i>
</div>
<div v-show="isExpanded" id="download_list" class="w-full pr-2" :class="{ slim: isSlim }" ref="list">
<div v-show="isExpanded" id="download_list" ref="list" class="w-full pr-2" :class="{ slim: isSlim }">
<QueueItem
v-for="item in queueList"
:queue-item="item"
:key="item.uuid"
:queue-item="item"
@show-errors="showErrorsTab"
@remove-item="onRemoveItem"
/>
@@ -170,8 +170,8 @@ export default {
socket.on('removedFinishedDownloads', this.removedFinishedDownloads)
fetchData('getQueue')
// fetch('connect')
// .then(res => res.json())
// fetch('connect')
// .then(res => res.json())
.then(res => {
console.log(res)
this.initQueue(res)
@@ -179,7 +179,7 @@ export default {
.catch(console.error)
// Check if download tab has slim entries
if ('true' === localStorage.getItem('slimDownloads')) {
if (localStorage.getItem('slimDownloads') === 'true') {
this.$refs.list.classList.add('slim')
}
@@ -212,16 +212,18 @@ export default {
initQueue(data) {
const {
order: initQueue,
// queueComplete: initQueueComplete,
// queueComplete: initQueueComplete,
currentItem,
queue: initQueueList,
restored
} = data
console.log({ initQueueList })
const initQueueComplete = Object.values(initQueueList).filter(el => ['completed', 'withErrors', 'failed'].includes(el.status)).map(el => el.uuid)
const initQueueComplete = Object.values(initQueueList)
.filter(el => ['completed', 'withErrors', 'failed'].includes(el.status))
.map(el => el.uuid)
console.log({initQueueComplete})
console.log({ initQueueComplete })
if (initQueueComplete && initQueueComplete.length) {
initQueueComplete.forEach(item => {
@@ -274,7 +276,7 @@ export default {
const itemIsAlreadyDownloaded = queueItem.downloaded + queueItem.failed == queueItem.size
if (itemIsAlreadyDownloaded) {
const itemIsNotInCompletedQueue = this.queueComplete.indexOf(queueItem.uuid) == -1
const itemIsNotInCompletedQueue = !this.queueComplete.includes(queueItem.uuid)
this.$set(this.queueList[queueItem.uuid], 'status', 'download finished')
@@ -283,7 +285,7 @@ export default {
this.queueComplete.push(queueItem.uuid)
}
} else {
const itemIsNotInQueue = this.queue.indexOf(queueItem.uuid) == -1
const itemIsNotInQueue = !this.queue.includes(queueItem.uuid)
if (itemIsNotInQueue) {
this.queue.push(queueItem.uuid)
@@ -304,14 +306,14 @@ export default {
// downloaded and failed default to false?
const { uuid, downloaded, failed, progress, conversion, error, data, errid } = update
if (uuid && this.queue.indexOf(uuid) > -1) {
if (uuid && this.queue.includes(uuid)) {
if (downloaded) {
this.queueList[uuid].downloaded++
}
if (failed) {
this.queueList[uuid].failed++
this.queueList[uuid].errors.push({ message: error, data: data, errid: errid })
this.queueList[uuid].errors.push({ message: error, data, errid })
}
if (progress) {
@@ -324,7 +326,7 @@ export default {
}
},
removeFromQueue(uuid) {
let index = this.queue.indexOf(uuid)
const index = this.queue.indexOf(uuid)
if (index > -1) {
this.$delete(this.queue, index)
@@ -340,7 +342,7 @@ export default {
} else {
this.queue = [currentItem]
let tempQueueItem = this.queueList[currentItem]
const tempQueueItem = this.queueList[currentItem]
this.queueList = {}
this.queueList[currentItem] = tempQueueItem
@@ -397,14 +399,14 @@ export default {
this.$set(this.queueList[uuid], 'status', 'downloading')
},
finishDownload(uuid) {
let isInQueue = this.queue.indexOf(uuid) > -1
const isInQueue = this.queue.includes(uuid)
if (!isInQueue) return
this.$set(this.queueList[uuid], 'status', 'download finished')
toast(this.$t('toasts.finishDownload', { item: this.queueList[uuid].title }), 'done')
let index = this.queue.indexOf(uuid)
const index = this.queue.indexOf(uuid)
if (index > -1) {
this.queue.splice(index, 1)

View File

@@ -11,4 +11,4 @@
button {
transition: background 200ms ease-in-out;
}
</style>
</style>

View File

@@ -1,8 +1,8 @@
<template functional>
<div
v-show="!props.hidden"
class="flex justify-center items-center flex-col flex-1 h-full"
:class="props.additionalClasses"
v-show="!props.hidden"
>
<span class="mb-5">{{ props.text || 'Loading...' }}</span>
@@ -58,4 +58,3 @@
}
}
</style>

View File

@@ -1,6 +1,6 @@
<template>
<div class="wrapper" ref="wrapper">
<div class="body animate__animated animate__bounce" ref="body">
<div ref="wrapper" class="wrapper">
<div ref="body" class="body animate__animated animate__bounce">
<h1 style="flex: 1">{{ titleText }}</h1>
<div class="confirm-area">

View File

@@ -10,10 +10,10 @@
<button
role="button"
aria-label="download"
v-on="$listeners"
:data-link="link"
class="absolute p-0 text-center bg-black border-0 rounded-full opacity-0 download_overlay hover:bg-primary"
tabindex="0"
v-on="$listeners"
>
<i class="text-white cursor-pointer material-icons" :title="$t('globals.download_hint')">get_app</i>
</button>

View File

@@ -1,9 +1,9 @@
<template>
<i
@mouseenter="previewMouseEnter"
@mouseleave="previewMouseLeave"
class="absolute top-0 right-0 flex items-center justify-center w-full h-full text-center text-white transition-opacity duration-200 ease-in-out bg-black bg-opacity-50 rounded opacity-0 material-icons preview_controls"
:title="$t('globals.play_hint')"
@mouseenter="previewMouseEnter"
@mouseleave="previewMouseLeave"
>
play_arrow
</i>
@@ -18,4 +18,4 @@ export default {
previewMouseLeave
}
}
</script>
</script>

View File

@@ -1,10 +1,10 @@
<template>
<div class="context-menu" v-show="menuOpen" ref="contextMenu" :style="{ top: yPos, left: xPos }">
<div v-show="menuOpen" ref="contextMenu" class="context-menu" :style="{ top: yPos, left: xPos }">
<button
class="btn menu-option"
v-for="option of sortedOptions"
:key="option.label"
v-show="option.show"
:key="option.label"
class="btn menu-option"
@click.prevent="option.action"
>
<span class="menu-option__text">{{ option.label }}</span>
@@ -91,7 +91,7 @@ export default {
}
}
let nextValuePosition = Object.values(options).length + 1
const nextValuePosition = Object.values(options).length + 1
downloadQualities.forEach((quality, index) => {
options[quality.objName] = {
@@ -125,9 +125,9 @@ export default {
methods: {
showSearchbarMenu(url) {
console.log(url)
let searchbar = document.getElementById("searchbar")
const searchbar = document.getElementById('searchbar')
searchbar.dataset.cmLink = url
let contextMenuEvent = {
const contextMenuEvent = {
pageX: 115,
pageY: 57,
target: searchbar,

View File

@@ -1,5 +1,5 @@
<template>
<div id="modal_quality" class="smallmodal" v-show="open" @click="tryToDownloadTrack($event)" ref="modal">
<div v-show="open" id="modal_quality" ref="modal" class="smallmodal" @click="tryToDownloadTrack($event)">
<div class="smallmodal-content">
<button class="btn btn-primary quality-button" data-quality-value="9">
{{ $t('globals.download', { thing: 'FLAC' }) }}

View File

@@ -1,5 +1,5 @@
<template>
<audio id="preview-track" @canplay="onCanPlay" @timeupdate="onTimeUpdate" ref="preview">
<audio id="preview-track" ref="preview" @canplay="onCanPlay" @timeupdate="onTimeUpdate">
<source id="preview-track_source" src="" type="audio/mpeg" />
</audio>
</template>
@@ -86,7 +86,7 @@ export default {
const { currentTarget: obj } = e
var icon = obj.tagName == 'I' ? obj : obj.querySelector('i')
const icon = obj.tagName == 'I' ? obj : obj.querySelector('i')
if (obj.hasAttribute('playing')) {
if (this.$refs.preview.paused) {
@@ -133,7 +133,7 @@ export default {
}
},
async stopStackedTabsPreview() {
let controls = Array.prototype.slice.call(document.querySelectorAll('.preview_playlist_controls[playing]'))
const controls = Array.prototype.slice.call(document.querySelectorAll('.preview_playlist_controls[playing]'))
if (controls.length === 0) return
@@ -161,4 +161,3 @@ export default {
}
}
</script>

View File

@@ -5,10 +5,10 @@
<div
class="grid w-16 h-16 ml-auto rounded-full cursor-pointer bg-primary text-grayscale-870 place-items-center"
@click.stop="sendAddToQueue(downloadLink)"
aria-label="download"
role="button"
:data-cm-link="downloadLink"
@click.stop="sendAddToQueue(downloadLink)"
>
<i class="text-4xl material-icons" :title="$t('globals.download_hint')">get_app</i>
</div>
@@ -18,8 +18,8 @@
<BaseTab
v-for="(item, name) in artistReleases"
:key="name"
@click="currentTab = name"
:class="{ active: currentTab === name }"
@click="currentTab = name"
>
{{ $tc(`globals.listTabs.${name}`, 2) }}
</BaseTab>
@@ -31,7 +31,6 @@
<th
v-for="data in head"
:key="data.title"
@click="data.sortKey ? sortBy(data.sortKey) : null"
:style="{ width: data.width ? data.width : 'auto' }"
class="uppercase-first-letter"
:class="{
@@ -40,6 +39,7 @@
sortable: data.sortKey,
clickable: data.sortKey
}"
@click="data.sortKey ? sortBy(data.sortKey) : null"
>
<!-- Need to change this behaviour for translations -->
{{ data.title }}
@@ -74,9 +74,9 @@
<td class="w-32 text-center xl:w-40">{{ release.releaseDate }}</td>
<td class="w-20 text-center xl:w-32">{{ release.releaseTracksNumber }}</td>
<td
@click.stop="sendAddToQueue(release.releaseLink)"
:data-cm-link="release.releaseLink"
class="w-8 cursor-pointer"
@click.stop="sendAddToQueue(release.releaseLink)"
>
<i class="material-icons hover:text-primary" :title="$t('globals.download_hint')">file_download</i>
</td>

View File

@@ -1,6 +1,6 @@
<template>
<div>
<h1 class="mb-8 text-5xl">{{ $t('charts.title') }} {{ country ? (`- ${country}`) : '' }}</h1>
<h1 class="mb-8 text-5xl">{{ $t('charts.title') }} {{ country ? `- ${country}` : '' }}</h1>
<div v-if="country === ''">
<div class="release-grid">
@@ -14,7 +14,7 @@
role="button"
@click="getTrackList"
>
<img :src="release.picture_medium" class="w-full rounded coverart" :alt="release.title"/>
<img :src="release.picture_medium" class="w-full rounded coverart" :alt="release.title" />
</div>
</div>
</div>
@@ -26,9 +26,9 @@
</button>
<table class="table table--charts">
<tbody>
<tr v-for="track, pos in chart" class="track_row">
<tr v-for="(track, pos) in chart" class="track_row">
<td :class="{ first: pos === 0 }" class="p-3 text-center cursor-default">
{{ pos+1 }}
{{ pos + 1 }}
</td>
<td class="table__icon table__icon--big">
<span
@@ -107,13 +107,22 @@ export default {
},
computed: {
worldwideRelease() {
let worldwideRelease = this.countries.filter(country => {
const worldwideRelease = this.countries.filter(country => {
return country.title === 'Worldwide'
})
return worldwideRelease[0]
}
},
watch: {
id(newId) {
const isActualChart = newId !== 0
if (isActualChart) {
getChartTracks(newId).then(response => this.setTracklist(response.data))
}
}
},
async created() {
// socket.on('setChartTracks', this.setTracklist)
// this.$on('hook:destroyed', () => {
@@ -180,15 +189,6 @@ export default {
localStorage.setItem('chart', this.country)
}
}
},
watch: {
id(newId) {
const isActualChart = newId !== 0
if (isActualChart) {
getChartTracks(newId).then(response => this.setTracklist(response.data))
}
}
}
}
</script>

View File

@@ -35,5 +35,4 @@ export default {
}
</script>
<style>
</style>
<style></style>

View File

@@ -223,7 +223,7 @@ export default defineComponent({
},
computed: {
activeTabEmpty() {
let toCheck = this.getActiveRelease()
const toCheck = this.getActiveRelease()
return toCheck?.length === 0
}
@@ -233,10 +233,10 @@ export default defineComponent({
convertDuration,
downloadAllOfType() {
try {
let toDownload = this.getActiveRelease()
const toDownload = this.getActiveRelease()
if (this.activeTab === 'track') {
let lovedTracks = this.getLovedTracksPlaylist()
const lovedTracks = this.getLovedTracksPlaylist()
sendAddToQueue(lovedTracks.link)
} else {
@@ -274,13 +274,13 @@ export default defineComponent({
return toDownload
},
getTabLength(tab = this.activeTab) {
let total = this[`${tab}s`]?.length
const total = this[`${tab}s`]?.length
// TODO: Add Spotify playlists to downlaod queue as well
//if (tab === "playlist") total += this.spotifyPlaylists.length
// if (tab === "playlist") total += this.spotifyPlaylists.length
return total || 0
},
getLovedTracksPlaylist() {
let lovedTracks = this.playlists.filter(playlist => {
const lovedTracks = this.playlists.filter(playlist => {
return playlist.is_loved_track
})

View File

@@ -2,7 +2,7 @@
<div id="home_tab">
<h1 class="mb-8 text-5xl">{{ $t('globals.welcome') }}</h1>
<section class="py-6 border-0 border-t border-solid border-grayscale-500" ref="notLogged" v-if="!isLoggedIn">
<section v-if="!isLoggedIn" ref="notLogged" class="py-6 border-0 border-t border-solid border-grayscale-500">
<p id="home_not_logged_text" class="mb-4">{{ $t('home.needTologin') }}</p>
<router-link tag="button" class="btn btn-primary" name="button" :to="{ name: 'Settings' }">
{{ $t('home.openSettings') }}
@@ -13,13 +13,13 @@
<h2 class="mb-6 text-3xl">{{ $t('home.sections.popularPlaylists') }}</h2>
<div class="release-grid">
<router-link
tag="div"
v-for="release in playlists"
:key="release.id"
tag="div"
class="release clickable"
:to="{ name: 'Playlist', params: { id: release.id } }"
@keyup.enter.native="$router.push({ name: 'Playlist', params: { id: release.id } })"
tabindex="0"
@keyup.enter.native="$router.push({ name: 'Playlist', params: { id: release.id } })"
>
<CoverContainer is-rounded :cover="release.picture_medium" :link="release.link" @click.stop="addToQueue" />
<p class="primary-text">{{ release.title }}</p>
@@ -39,14 +39,14 @@
<h2 class="mb-6 text-3xl">{{ $t('home.sections.popularAlbums') }}</h2>
<div class="release-grid">
<router-link
tag="div"
v-for="release in albums"
:key="release.id"
tag="div"
class="release clickable"
:to="{ name: 'Album', params: { id: release.id } }"
@keyup.enter.native="$router.push({ name: 'Album', params: { id: release.id } })"
:data-id="release.id"
tabindex="0"
@keyup.enter.native="$router.push({ name: 'Album', params: { id: release.id } })"
>
<CoverContainer is-rounded :cover="release.cover_medium" :link="release.link" @click.stop="addToQueue" />
<p class="primary-text">{{ release.title }}</p>
@@ -100,5 +100,4 @@ export default {
}
</script>
<style>
</style>
<style></style>

View File

@@ -2,9 +2,9 @@
<div>
<h1 class="mb-8 text-5xl">{{ $t('settings.login.arl.question') }}</h1>
<p class="mb-2 text-base">
Deezer keeps track of login session by using a cookie called ARL.<br>
deemix uses that cookie to get the metadata that it needs to download the tracks from Deezer.<br>
ARLs last for 3 months, after that Deezer asks you to log in again. The same method is used in deemix<br>
Deezer keeps track of login session by using a cookie called ARL.<br />
deemix uses that cookie to get the metadata that it needs to download the tracks from Deezer.<br />
ARLs last for 3 months, after that Deezer asks you to log in again. The same method is used in deemix<br />
Following one of the guides below you can get your own account ARL.
</p>
@@ -26,7 +26,7 @@
<li>Go under the Application tab (if you don't see it click the double arrow)</li>
<li>Open the cookie dropdown</li>
<li>Select www.deezer.com</li>
<li>Find the `arl` cookie (It should be 192 chars long) </li>
<li>Find the `arl` cookie (It should be 192 chars long)</li>
<li>That's your ARL, now you can use it in the app</li>
</ul>

View File

@@ -2,30 +2,39 @@
<div>
<h1 class="mb-8 text-5xl">{{ $t('settings.spotify.question') }}</h1>
<p class="mb-2 text-base">
"Spotify Features" is a set of features that lets you convert Spotify tracks and albums links into Deezer ones.
If you provide a Spotify Playlist link the app will autmatically convert all the links of the tracks inside it into deezer tracks.
Enabling this set of features will let you see your public Spotify playlists in the favorites tab as well.
"Spotify Features" is a set of features that lets you convert Spotify tracks and albums links into Deezer ones. If
you provide a Spotify Playlist link the app will autmatically convert all the links of the tracks inside it into
deezer tracks. Enabling this set of features will let you see your public Spotify playlists in the favorites tab
as well.
</p>
<p class="mb-2 text-base">For security reasons you will need to provide your own Client ID and Secret</p>
<h2 class="mt-6 text-3xl">How do I get my Client ID and Secret?</h2>
<p class="mb-2 text-base">Connect to <a href="https://developer.spotify.com/dashboard" target="_blank">Spotify for Developers's Dashboard</a> and login with your Spotify account.</p>
<p class="mb-2 text-base">
Click on "Create an App".<br>
<img src="https://i.imgur.com/YFz7rHj.png" alt="Create an App button on Spotify for Developers's Dashboard">
Connect to
<a href="https://developer.spotify.com/dashboard" target="_blank">Spotify for Developers's Dashboard</a> and login
with your Spotify account.
</p>
<p class="mb-2 text-base">
Fill out the "App name" and "App description" fields and check both checkboxes. Then click on the "Create" button.<br>
<img src="https://i.imgur.com/A9cvDkK.png" alt="Create an app form">
Click on "Create an App".<br />
<img src="https://i.imgur.com/YFz7rHj.png" alt="Create an App button on Spotify for Developers's Dashboard" />
</p>
<p class="mb-2 text-base">
Now you can see the Client ID. If you click on "Show Client Secret" the client secret will be revealed.<br>
<img src="https://i.imgur.com/foEfIhO.png" alt="Screen of client ID and Secret">
Fill out the "App name" and "App description" fields and check both checkboxes. Then click on the "Create"
button.<br />
<img src="https://i.imgur.com/A9cvDkK.png" alt="Create an app form" />
</p>
<p class="mb-2 text-base">
Now you can see the Client ID. If you click on "Show Client Secret" the client secret will be revealed.<br />
<img src="https://i.imgur.com/foEfIhO.png" alt="Screen of client ID and Secret" />
</p>
<p class="mb-2 text-base">Now you can copy-paste those results in the appropriate fields in the settings.</p>
<h2 class="mt-6 text-3xl">How do I get my Spotify Username?</h2>
<p class="mb-2 text-base">You can get your Spotify Username from the <a href="https://www.spotify.com/it/account/overview/" target="_blank">Overview page on Spotify's Website</a>.</p>
<p class="mb-2 text-base">
You can get your Spotify Username from the
<a href="https://www.spotify.com/it/account/overview/" target="_blank">Overview page on Spotify's Website</a>.
</p>
</div>
</template>
@@ -33,5 +42,4 @@
export default {}
</script>
<style>
</style>
<style></style>

View File

@@ -65,10 +65,10 @@
<div
role="button"
aria-label="download"
@contextmenu.prevent="openQualityModal"
@click.stop="addToQueue"
:data-link="link"
class="grid w-16 h-16 ml-auto rounded-full cursor-pointer bg-primary text-grayscale-870 place-items-center"
@contextmenu.prevent="openQualityModal"
@click.stop="addToQueue"
>
<i class="text-4xl material-icons" :title="$t('globals.download_hint')">get_app</i>
</div>
@@ -152,6 +152,11 @@ export default {
countries: []
}
},
mounted() {
socket.on('analyze_track', this.showTrack)
socket.on('analyze_album', this.showAlbum)
socket.on('analyze_notSupported', this.notSupported)
},
methods: {
convertDuration,
reset() {
@@ -174,15 +179,15 @@ export default {
id
} = data
this.title = title + (title_version && title.indexOf(title_version) == -1 ? ' ' + title_version : '')
this.title = title + (title_version && !title.includes(title_version) ? ' ' + title_version : '')
this.image = cover_xl
this.type = 'track'
this.link = link
this.id = id
available_countries.forEach(cc => {
let temp = []
let chars = [...cc].map(c => c.charCodeAt() + 127397)
const temp = []
const chars = [...cc].map(c => c.charCodeAt() + 127397)
temp.push(String.fromCodePoint(...chars))
temp.push(COUNTRIES[cc])
this.countries.push(temp)
@@ -207,14 +212,8 @@ export default {
addToQueue(e) {
sendAddToQueue(e.currentTarget.dataset.link)
}
},
mounted() {
socket.on('analyze_track', this.showTrack)
socket.on('analyze_album', this.showAlbum)
socket.on('analyze_notSupported', this.notSupported)
}
}
</script>
<style>
</style>
<style></style>

View File

@@ -12,8 +12,8 @@
<BaseTab
v-for="tab in tabs"
:key="tab.name"
@click="changeSearchTab(tab.searchType)"
:class="{ active: currentTab.name === tab.name }"
@click="changeSearchTab(tab.searchType)"
>
{{ tab.name }}
</BaseTab>
@@ -22,7 +22,7 @@
<keep-alive>
<component
:is="currentTab.component"
:viewInfo="getViewInfo()"
:view-info="getViewInfo()"
want-headers
@add-to-queue="addToQueue"
@change-search-tab="changeSearchTab"
@@ -245,6 +245,22 @@ export default defineComponent({
return tabsLoaded
}
},
watch: {
performScrolledSearch(needToSearch) {
if (!needToSearch) return
this.scrolledSearch(needToSearch)
},
currentTab(newTab, old) {
if (this.isTabLoaded(newTab)) return
this.performSearch({
term: this.results.query,
type: newTab.searchType,
start: this.results[`${newTab.searchType}Tab`].next
})
}
},
methods: {
numberWithDots,
convertDuration,
@@ -289,29 +305,10 @@ export default defineComponent({
}
},
isTabLoaded(tab) {
return this.loadedTabs.indexOf(tab.searchType) !== -1 || tab.searchType === 'all'
}
},
watch: {
performScrolledSearch(needToSearch) {
if (!needToSearch) return
this.scrolledSearch(needToSearch)
},
currentTab(newTab, old) {
if (this.isTabLoaded(newTab)) return
this.performSearch({
term: this.results.query,
type: newTab.searchType,
start: this.results[`${newTab.searchType}Tab`].next
})
return this.loadedTabs.includes(tab.searchType) || tab.searchType === 'all'
}
}
})
</script>
<style>
</style>
<style></style>

View File

@@ -61,16 +61,18 @@
</div>
<div class="settings-group">
<h3 class="settings-group__header"><i class="material-icons">person</i>{{ $t('settings.loginWithCredentials.title') }}</h3>
<h3 class="settings-group__header">
<i class="material-icons">person</i>{{ $t('settings.loginWithCredentials.title') }}
</h3>
<form class="my-5 space-y-5" @submit.prevent="loginWithCredentials" ref="loginWithCredentialsForm">
<form ref="loginWithCredentialsForm" class="my-5 space-y-5" @submit.prevent="loginWithCredentials">
<label>
<span>Username</span>
<input type="text" name="username">
<input type="text" name="username" />
</label>
<label>
<span>Password</span>
<input type="password" name="password">
<input type="password" name="password" />
</label>
<button class="btn btn-primary" type="submit">{{ $t('settings.loginWithCredentials.login') }}</button>
@@ -876,14 +878,14 @@ export default {
this.initSettings(settingsData, spotifyCredentials)
// TODO Move in store
let storedAccountNum = localStorage.getItem('accountNum')
const storedAccountNum = localStorage.getItem('accountNum')
if (storedAccountNum) {
this.accountNum = storedAccountNum
}
// TODO Move in store
let spotifyUser = localStorage.getItem('spotifyUser')
const spotifyUser = localStorage.getItem('spotifyUser')
if (spotifyUser) {
this.lastUser = spotifyUser
@@ -924,7 +926,7 @@ export default {
this.spotifyUser = (' ' + this.lastUser).slice(1)
},
copyARLtoClipboard() {
let copyText = this.$refs.loginInput
const copyText = this.$refs.loginInput
copyText.setAttribute('type', 'text')
copyText.select()
@@ -978,7 +980,7 @@ export default {
// const res = await fetchData('login', { arl, force: true, child: this.accountNum })
},
async login() {
let newArl = this.$refs.loginInput.value.trim()
const newArl = this.$refs.loginInput.value.trim()
if (newArl && newArl !== this.arl) {
const res = await fetchData('login-arl', { arl: newArl, force: true, child: this.accountNum }, 'POST')
@@ -1020,7 +1022,7 @@ export default {
toast(this.$t('settings.toasts.init'), 'settings')
},
updateSettings(data) {
const {settings: newSettings, spotifySettings: newCredentials} = data
const { settings: newSettings, spotifySettings: newCredentials } = data
this.loadSettings(newSettings)
this.loadCredentials(newCredentials)

View File

@@ -41,7 +41,6 @@
<td class="table__cell--x-small table__cell--center">
<div class="table__cell-content table__cell-content--vertical-center">
<i
v-on="{ click: track.preview ? playPausePreview : false }"
:class="{
preview_playlist_controls: track.preview,
'cursor-pointer': track.preview,
@@ -50,6 +49,7 @@
:data-preview="track.preview"
:title="$t('globals.play_hint')"
class="material-icons"
v-on="{ click: track.preview ? playPausePreview : false }"
>
play_arrow
</i>

View File

@@ -7,8 +7,8 @@
<h1>{{ $t('search.noResultsAlbum') }}</h1>
</div>
<div class="release-grid" v-else>
<div class="w-40 release" v-for="release in viewInfo.data.slice(0, itemsToShow)" :key="release.albumID">
<div v-else class="release-grid">
<div v-for="release in viewInfo.data.slice(0, itemsToShow)" :key="release.albumID" class="w-40 release">
<router-link tag="div" class="cursor-pointer" :to="{ name: 'Album', params: { id: release.albumID } }">
<CoverContainer
is-rounded
@@ -53,9 +53,9 @@ export default {
},
props: {
viewInfo: {
validator: function (value) {
let isNull = Object.is(value, null)
let isObject = Object.prototype.toString.call(value) === '[object Object]'
validator(value) {
const isNull = Object.is(value, null)
const isObject = Object.prototype.toString.call(value) === '[object Object]'
return isNull || isObject
},

View File

@@ -12,13 +12,13 @@
>
<template v-if="checkSectionResults(section)">
<h2
@click="$emit('change-search-tab', section)"
class="mb-6 capitalize"
:class="{
'text-4xl text-center': section === 'TOP_RESULT',
'inline-block cursor-pointer text-3xl hover:text-primary transition-colors duration-200 ease-in-out':
section !== 'TOP_RESULT'
}"
@click="$emit('change-search-tab', section)"
>
{{ $tc(`globals.listTabs.${section.toLowerCase()}`, 2) }}
</h2>
@@ -31,29 +31,29 @@
<ResultsTracks
v-else-if="section === 'TRACK'"
:viewInfo="standardizeData(viewInfo.TRACK, formatSingleTrack)"
:itemsToShow="6"
:view-info="standardizeData(viewInfo.TRACK, formatSingleTrack)"
:items-to-show="6"
@add-to-queue="$emit('add-to-queue', $event)"
/>
<ResultsAlbums
v-else-if="section == 'ALBUM'"
:viewInfo="standardizeData(viewInfo.ALBUM, formatAlbums)"
:itemsToShow="6"
:view-info="standardizeData(viewInfo.ALBUM, formatAlbums)"
:items-to-show="6"
@add-to-queue="$emit('add-to-queue', $event)"
/>
<ResultsPlaylists
v-else-if="section == 'PLAYLIST'"
:viewInfo="standardizeData(viewInfo.PLAYLIST, formatPlaylist)"
:itemsToShow="6"
:view-info="standardizeData(viewInfo.PLAYLIST, formatPlaylist)"
:items-to-show="6"
@add-to-queue="$emit('add-to-queue', $event)"
/>
<ResultsArtists
v-else-if="section === 'ARTIST'"
:viewInfo="standardizeData(viewInfo.ARTIST, formatArtist)"
:itemsToShow="6"
:view-info="standardizeData(viewInfo.ARTIST, formatArtist)"
:items-to-show="6"
@add-to-queue="$emit('add-to-queue', $event)"
/>
</template>
@@ -90,13 +90,13 @@ export default {
},
computed: {
thereAreResults() {
let areInfosLoaded = !!this.viewInfo
const areInfosLoaded = !!this.viewInfo
if (!areInfosLoaded) {
return false
}
let noResultsPresent = this.viewInfo.ORDER.every(section =>
const noResultsPresent = this.viewInfo.ORDER.every(section =>
section === 'TOP_RESULT' ? this.viewInfo[section].length === 0 : this.viewInfo[section].data.length === 0
)

View File

@@ -8,7 +8,7 @@
</div>
<div v-else class="release-grid">
<div class="w-40 release" v-for="release in viewInfo.data.slice(0, itemsToShow)" :key="release.artistID">
<div v-for="release in viewInfo.data.slice(0, itemsToShow)" :key="release.artistID" class="w-40 release">
<router-link tag="div" class="cursor-pointer" :to="{ name: 'Artist', params: { id: release.artistID } }">
<CoverContainer
is-circle
@@ -41,9 +41,9 @@ export default {
},
props: {
viewInfo: {
validator: function (value) {
let isNull = Object.is(value, null)
let isObject = Object.prototype.toString.call(value) === '[object Object]'
validator(value) {
const isNull = Object.is(value, null)
const isObject = Object.prototype.toString.call(value) === '[object Object]'
return isNull || isObject
},

View File

@@ -6,8 +6,8 @@
<div v-if="viewInfo.data.length === 0">
<h1>{{ $t('search.noResultsPlaylist') }}</h1>
</div>
<div class="release-grid" v-else>
<div class="w-40 release" v-for="playlist in viewInfo.data.slice(0, itemsToShow)" :key="playlist.playlistID">
<div v-else class="release-grid">
<div v-for="playlist in viewInfo.data.slice(0, itemsToShow)" :key="playlist.playlistID" class="w-40 release">
<router-link tag="div" class="cursor-pointer" :to="{ name: 'Playlist', params: { id: playlist.playlistID } }">
<CoverContainer
is-rounded
@@ -46,9 +46,9 @@ export default {
},
props: {
viewInfo: {
validator: function (value) {
let isNull = Object.is(value, null)
let isObject = Object.prototype.toString.call(value) === '[object Object]'
validator(value) {
const isNull = Object.is(value, null)
const isObject = Object.prototype.toString.call(value) === '[object Object]'
return isNull || isObject
},

View File

@@ -24,9 +24,9 @@
<tr v-for="track in viewInfo.data.slice(0, itemsToShow)" :key="track.trackLink">
<td class="table__icon table__icon--big">
<span
@click="playPausePreview($event)"
class="relative inline-block rounded cursor-pointer"
:data-preview="track.trackPreview"
@click="playPausePreview($event)"
>
<PreviewControls v-if="track.trackPreview" />
@@ -67,9 +67,9 @@
<td
class="cursor-pointer table__cell--center group"
@click.stop="$emit('add-to-queue', $event)"
:data-link="track.trackLink"
aria-label="download"
@click.stop="$emit('add-to-queue', $event)"
>
<i
class="transition-colors duration-150 ease-in-out material-icons group-hover:text-primary"
@@ -101,9 +101,9 @@ export default {
},
props: {
viewInfo: {
validator: function (value) {
let isNull = Object.is(value, null)
let isObject = Object.prototype.toString.call(value) === '[object Object]'
validator(value) {
const isNull = Object.is(value, null)
const isObject = Object.prototype.toString.call(value) === '[object Object]'
return isNull || isObject
},
@@ -130,4 +130,4 @@ export default {
playPausePreview
}
}
</script>
</script>

View File

@@ -28,7 +28,6 @@
</div>
</template>
<script>
import { upperCaseFirstLowerCaseRest } from '@/utils/texts'
import CoverContainer from '@components/globals/CoverContainer.vue'
@@ -37,9 +36,6 @@ export default {
components: {
CoverContainer
},
methods: {
upperCaseFirstLowerCaseRest
},
computed: {
fansNumber() {
let number
@@ -56,6 +52,9 @@ export default {
' - ' +
this.$tc('globals.listTabs.trackN', this.$attrs.info.nb_song)
}
},
methods: {
upperCaseFirstLowerCaseRest
}
}
</script>

View File

@@ -1,5 +1,5 @@
<template>
<BaseAccordion style="--arrow-v-align: baseline; margin-bottom: 3rem;">
<BaseAccordion style="--arrow-v-align: baseline; margin-bottom: 3rem">
<template #title>
<slot name="title"></slot>
</template>