Merge branch 'main' into router-implementation
This commit is contained in:
@@ -7,6 +7,8 @@
|
||||
|
||||
<TheTrackPreview />
|
||||
<TheQualityModal />
|
||||
|
||||
<TheContextMenu />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -16,6 +18,7 @@ import TheMainContent from '@components/TheMainContent.vue'
|
||||
import TheTrackPreview from '@components/TheTrackPreview.vue'
|
||||
import TheQualityModal from '@components/TheQualityModal.vue'
|
||||
import BaseLoadingPlaceholder from '@components/BaseLoadingPlaceholder.vue'
|
||||
import TheContextMenu from '@components/TheContextMenu.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
@@ -23,10 +26,8 @@ export default {
|
||||
TheMainContent,
|
||||
TheTrackPreview,
|
||||
TheQualityModal,
|
||||
BaseLoadingPlaceholder
|
||||
BaseLoadingPlaceholder,
|
||||
TheContextMenu
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
@@ -8,14 +8,7 @@
|
||||
}"
|
||||
>
|
||||
<h1>{{ title }}</h1>
|
||||
<div
|
||||
role="button"
|
||||
aria-label="download"
|
||||
@contextmenu.prevent="openQualityModal"
|
||||
@click.stop="addToQueue"
|
||||
:data-link="link"
|
||||
class="fab right"
|
||||
>
|
||||
<div role="button" aria-label="download" @click.stop="addToQueue" :data-link="link" class="fab right">
|
||||
<i class="material-icons" :title="$t('globals.download_hint')">get_app</i>
|
||||
</div>
|
||||
</header>
|
||||
@@ -69,12 +62,8 @@
|
||||
</i>
|
||||
</td>
|
||||
<td>{{ release.release_date }}</td>
|
||||
<td
|
||||
@click.stop="addToQueue"
|
||||
@contextmenu.prevent="openQualityModal"
|
||||
:data-link="release.link"
|
||||
class="clickable"
|
||||
>
|
||||
<td>{{ release.nb_song }}</td>
|
||||
<td @click.stop="addToQueue" :data-link="release.link" class="clickable">
|
||||
<i class="material-icons" :title="$t('globals.download_hint')">
|
||||
file_download
|
||||
</i>
|
||||
@@ -129,9 +118,6 @@ export default {
|
||||
e.stopPropagation()
|
||||
Downloads.sendAddToQueue(e.currentTarget.dataset.link)
|
||||
},
|
||||
openQualityModal(e) {
|
||||
this.$root.$emit('QualityModal:open', e.currentTarget.dataset.link)
|
||||
},
|
||||
sortBy(key) {
|
||||
if (key == this.sortKey) {
|
||||
this.sortOrder = this.sortOrder == 'asc' ? 'desc' : 'asc'
|
||||
@@ -172,6 +158,7 @@ export default {
|
||||
this.head = [
|
||||
{ title: this.$tc('globals.listTabs.title', 1), sortKey: 'title' },
|
||||
{ title: this.$t('globals.listTabs.releaseDate'), sortKey: 'release_date' },
|
||||
{ title: this.$tc('globals.listTabs.track', 2), sortKey: 'nb_song' },
|
||||
{ title: '', width: '32px' }
|
||||
]
|
||||
if (isEmpty(releases)) {
|
||||
@@ -183,8 +170,17 @@ export default {
|
||||
},
|
||||
computed: {
|
||||
showTable() {
|
||||
if (this.body) return orderBy(this.body[this.currentTab], this.sortKey, this.sortOrder)
|
||||
else return []
|
||||
if (this.body) {
|
||||
if (this.sortKey == 'nb_song')
|
||||
return orderBy(
|
||||
this.body[this.currentTab],
|
||||
function (o) {
|
||||
return new Number(o.nb_song)
|
||||
},
|
||||
this.sortOrder
|
||||
)
|
||||
else return orderBy(this.body[this.currentTab], this.sortKey, this.sortOrder)
|
||||
} else return []
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
|
||||
@@ -82,10 +82,6 @@
|
||||
<strong>PayPal:</strong>
|
||||
<a href="https://paypal.me/RemixDev" target="_blank">PayPal.me/RemixDev</a>
|
||||
</li>
|
||||
<li>
|
||||
<i class="bitcoin" v-html="bitcoin" />
|
||||
<strong>Bitcoin:</strong> 1sdNymSJrMBWyHM4u2m9uco5nv6uV4Qs1
|
||||
</li>
|
||||
<li>
|
||||
<i class="ethereum" v-html="ethereum" />
|
||||
<strong>Ethereum:</strong> 0x1d2aa67e671485CD4062289772B662e0A6Ff976c
|
||||
@@ -123,10 +119,6 @@ i /deep/ svg {
|
||||
width: 20px;
|
||||
}
|
||||
|
||||
.bitcoin /deep/ svg {
|
||||
fill: #ff9900;
|
||||
}
|
||||
|
||||
.ethereum /deep/ svg {
|
||||
fill: var(--foreground);
|
||||
}
|
||||
@@ -200,14 +192,12 @@ ul {
|
||||
</style>
|
||||
<script>
|
||||
import paypal from '@/assets/paypal.svg'
|
||||
import bitcoin from '@/assets/bitcoin.svg'
|
||||
import ethereum from '@/assets/ethereum.svg'
|
||||
|
||||
export default {
|
||||
data: () => ({
|
||||
paypal,
|
||||
ethereum,
|
||||
bitcoin
|
||||
ethereum
|
||||
}),
|
||||
mounted() {
|
||||
console.log('about mounted')
|
||||
|
||||
@@ -36,11 +36,7 @@
|
||||
</div>
|
||||
<div v-else id="charts_table">
|
||||
<button @click="changeCountry">{{ $t('charts.changeCountry') }}</button>
|
||||
<button
|
||||
@contextmenu.prevent="openQualityModal"
|
||||
@click.stop="addToQueue"
|
||||
:data-link="'https://www.deezer.com/playlist/' + id"
|
||||
>
|
||||
<button @click.stop="addToQueue" :data-link="'https://www.deezer.com/playlist/' + id">
|
||||
{{ $t('charts.download') }}
|
||||
</button>
|
||||
<table class="table table--charts">
|
||||
@@ -94,7 +90,6 @@
|
||||
</td>
|
||||
<td
|
||||
class="table__cell--download"
|
||||
@contextmenu.prevent="openQualityModal"
|
||||
@click.stop="addToQueue"
|
||||
:data-link="track.link"
|
||||
role="button"
|
||||
@@ -144,9 +139,6 @@ export default {
|
||||
e.stopPropagation()
|
||||
Downloads.sendAddToQueue(e.currentTarget.dataset.link)
|
||||
},
|
||||
openQualityModal(e) {
|
||||
this.$root.$emit('QualityModal:open', e.currentTarget.dataset.link)
|
||||
},
|
||||
getTrackList(event) {
|
||||
document.getElementById('content').scrollTo(0, 0)
|
||||
|
||||
|
||||
316
src/components/TheContextMenu.vue
Normal file
316
src/components/TheContextMenu.vue
Normal file
@@ -0,0 +1,316 @@
|
||||
<template>
|
||||
<div class="context-menu" v-show="menuOpen" ref="contextMenu" :style="{ top: yPos, left: xPos }">
|
||||
<button
|
||||
class="menu-option"
|
||||
v-for="option of sortedOptions"
|
||||
:key="option.label"
|
||||
v-show="option.show"
|
||||
@click.prevent="option.action"
|
||||
>
|
||||
<span class="menu-option__text">{{ option.label }}</span>
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Downloads from '@/utils/downloads'
|
||||
import downloadQualities from '@js/qualities'
|
||||
import { generatePath, copyToClipboard } from '@/utils/utils'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
menuOpen: false,
|
||||
xPos: 0,
|
||||
yPos: 0,
|
||||
deezerHref: '',
|
||||
generalHref: '',
|
||||
imgSrc: ''
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
options() {
|
||||
// In the action property:
|
||||
// Use arrow functions to keep the Vue instance in 'this'
|
||||
// Use normal functions to keep the object instance in 'this'
|
||||
const options = {
|
||||
cut: {
|
||||
label: this.$t('globals.cut'),
|
||||
show: false,
|
||||
position: 1,
|
||||
action: () => {
|
||||
document.execCommand('Cut')
|
||||
}
|
||||
},
|
||||
copy: {
|
||||
label: this.$t('globals.copy'),
|
||||
show: false,
|
||||
position: 2,
|
||||
action: () => {
|
||||
document.execCommand('Copy')
|
||||
}
|
||||
},
|
||||
copyLink: {
|
||||
label: this.$t('globals.copyLink'),
|
||||
show: false,
|
||||
position: 3,
|
||||
action: () => {
|
||||
copyToClipboard(this.generalHref)
|
||||
}
|
||||
},
|
||||
copyImageLink: {
|
||||
label: this.$t('globals.copyImageLink'),
|
||||
show: false,
|
||||
position: 4,
|
||||
action: () => {
|
||||
copyToClipboard(this.imgSrc)
|
||||
}
|
||||
},
|
||||
copyDeezerLink: {
|
||||
label: this.$t('globals.copyDeezerLink'),
|
||||
show: false,
|
||||
position: 5,
|
||||
action: () => {
|
||||
copyToClipboard(this.deezerHref)
|
||||
}
|
||||
},
|
||||
paste: {
|
||||
label: this.$t('globals.paste'),
|
||||
show: false,
|
||||
position: 6,
|
||||
action: () => {
|
||||
// Paste does not always work
|
||||
if (clipboard in navigator) {
|
||||
navigator.clipboard.readText().then(text => {
|
||||
document.execCommand('insertText', undefined, text)
|
||||
})
|
||||
} else {
|
||||
document.execCommand('paste')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let nextValuePosition = Object.values(options).length + 1
|
||||
|
||||
downloadQualities.forEach((quality, index) => {
|
||||
options[quality.objName] = {
|
||||
label: `${this.$t('globals.download', [quality.label])}`,
|
||||
show: false,
|
||||
position: nextValuePosition + index,
|
||||
action: this.tryToDownloadTrack.bind(null, quality.value)
|
||||
}
|
||||
})
|
||||
|
||||
return options
|
||||
},
|
||||
/**
|
||||
* This computed property is used for rendering the options in the wanted order
|
||||
* while keeping the options computed property an Object to make the properties
|
||||
* accessible via property name (es this.options.copyLink)
|
||||
*
|
||||
* @return {object[]} Options in order according to position property
|
||||
*/
|
||||
sortedOptions() {
|
||||
return Object.values(this.options).sort((first, second) => {
|
||||
return first.position < second.position ? -1 : 1
|
||||
})
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
document.body.addEventListener('contextmenu', this.showMenu)
|
||||
document.body.addEventListener('click', this.hideMenu)
|
||||
},
|
||||
methods: {
|
||||
showMenu(contextMenuEvent) {
|
||||
// contextMenuEvent.preventDefault()
|
||||
const { pageX, pageY, target: elementClicked } = contextMenuEvent
|
||||
const path = generatePath(elementClicked)
|
||||
let deezerLink = null
|
||||
|
||||
// Searching for the first element with a data-link attribute
|
||||
// let deezerLink = this.searchForDataLink(...)
|
||||
for (let i = 0; i < path.length; i++) {
|
||||
if (path[i] == document) break
|
||||
|
||||
if (path[i].matches('[data-link]')) {
|
||||
deezerLink = path[i].dataset.link
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
const isLink = elementClicked.matches('a')
|
||||
const isImage = elementClicked.matches('img')
|
||||
const hasDeezerLink = !!deezerLink
|
||||
|
||||
if (!isLink && !isImage && !hasDeezerLink) return
|
||||
|
||||
contextMenuEvent.preventDefault()
|
||||
this.menuOpen = true
|
||||
this.positionMenu(pageX, pageY)
|
||||
|
||||
if (isLink) {
|
||||
// Show 'Copy Link' option
|
||||
this.generalHref = elementClicked.href
|
||||
this.options.copyLink.show = true
|
||||
}
|
||||
|
||||
if (isImage) {
|
||||
// Show 'Copy Image Link' option
|
||||
this.imgSrc = elementClicked.src
|
||||
this.options.copyImageLink.show = true
|
||||
}
|
||||
|
||||
if (deezerLink) {
|
||||
// Show 'Copy Deezer Link' option
|
||||
this.deezerHref = deezerLink
|
||||
this.showDeezerOptions()
|
||||
}
|
||||
},
|
||||
hideMenu() {
|
||||
if (!this.menuOpen) return
|
||||
|
||||
// Finish all operations before closing (may be not necessary)
|
||||
this.$nextTick()
|
||||
.then(() => {
|
||||
this.menuOpen = false
|
||||
|
||||
this.options.copyLink.show = false
|
||||
this.options.copyDeezerLink.show = false
|
||||
this.options.copyImageLink.show = false
|
||||
|
||||
downloadQualities.forEach(quality => {
|
||||
this.options[quality.objName].show = false
|
||||
})
|
||||
})
|
||||
.catch(err => {
|
||||
console.error(err)
|
||||
})
|
||||
},
|
||||
positionMenu(newX, newY) {
|
||||
this.xPos = `${newX}px`
|
||||
this.yPos = `${newY}px`
|
||||
|
||||
this.$nextTick().then(() => {
|
||||
const { innerHeight, innerWidth } = window
|
||||
const menuXOffest = newX + this.$refs.contextMenu.getBoundingClientRect().width
|
||||
const menuYOffest = newY + this.$refs.contextMenu.getBoundingClientRect().height
|
||||
|
||||
if (menuXOffest > innerWidth) {
|
||||
const difference = menuXOffest - innerWidth + 15
|
||||
this.xPos = `${newX - difference}px`
|
||||
}
|
||||
|
||||
if (menuYOffest > innerHeight) {
|
||||
const difference = menuYOffest - innerHeight + 15
|
||||
this.yPos = `${newY - difference}px`
|
||||
}
|
||||
})
|
||||
},
|
||||
showDeezerOptions() {
|
||||
this.options.copyDeezerLink.show = true
|
||||
|
||||
downloadQualities.forEach(quality => {
|
||||
this.options[quality.objName].show = true
|
||||
})
|
||||
},
|
||||
tryToDownloadTrack(qualityValue) {
|
||||
Downloads.sendAddToQueue(this.deezerHref, qualityValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.context-menu {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
min-width: 100px;
|
||||
border-radius: 7px;
|
||||
background: var(--foreground-inverted);
|
||||
box-shadow: 4px 10px 18px 0px hsla(0, 0%, 0%, 0.15);
|
||||
overflow: hidden;
|
||||
z-index: 10000;
|
||||
}
|
||||
|
||||
.menu-option {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
color: var(--foreground);
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
background: var(--table-highlight);
|
||||
filter: brightness(150%);
|
||||
}
|
||||
|
||||
&__text {
|
||||
text-transform: capitalize;
|
||||
}
|
||||
}
|
||||
|
||||
// Resetting buttons only for this component (because the style is scoped)
|
||||
button {
|
||||
color: var(--accent-text);
|
||||
color: unset;
|
||||
background-color: var(--accent-color);
|
||||
background-color: unset;
|
||||
min-width: unset;
|
||||
position: unset;
|
||||
border: unset;
|
||||
border-radius: unset;
|
||||
font-family: unset;
|
||||
font-weight: unset;
|
||||
font-size: unset;
|
||||
padding: unset;
|
||||
margin-right: unset;
|
||||
height: unset;
|
||||
text-transform: unset;
|
||||
cursor: unset;
|
||||
transition: unset;
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
&[disabled] {
|
||||
background-color: unset;
|
||||
color: unset;
|
||||
opacity: unset;
|
||||
}
|
||||
|
||||
&.selective {
|
||||
background-color: unset;
|
||||
color: unset;
|
||||
|
||||
&.active {
|
||||
background-color: unset;
|
||||
color: unset;
|
||||
}
|
||||
}
|
||||
|
||||
&.with_icon {
|
||||
display: unset;
|
||||
align-items: unset;
|
||||
|
||||
i {
|
||||
margin-left: unset;
|
||||
}
|
||||
}
|
||||
|
||||
&:active {
|
||||
background-color: unset;
|
||||
transform: unset;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: unset;
|
||||
border: unset;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -15,9 +15,7 @@
|
||||
:title="$t('globals.toggle_download_tab_hint')"
|
||||
></i>
|
||||
<div id="queue_buttons">
|
||||
<i id="open_downloads_folder" class="material-icons download_bar_icon hide" @click="openDownloadsFolder">
|
||||
folder_open
|
||||
</i>
|
||||
<i id="open_downloads_folder" class="material-icons download_bar_icon hide" :title="$t('globals.open_downloads_folder')" @click="openDownloadsFolder">folder_open</i>
|
||||
<i id="clean_queue" class="material-icons download_bar_icon" @click="cleanQueue" :title="$t('globals.clean_queue_hint')">clear_all</i>
|
||||
<i id="cancel_queue" class="material-icons download_bar_icon" @click="cancelQueue" :title="$t('globals.cancel_queue_hint')">delete_sweep</i>
|
||||
</div>
|
||||
@@ -42,6 +40,7 @@ export default {
|
||||
}),
|
||||
mounted() {
|
||||
socket.on('startDownload', this.startDownload)
|
||||
socket.on('startConversion', this.startConversion)
|
||||
socket.on('init_downloadQueue', this.initQueue)
|
||||
socket.on('addedToQueue', this.addToQueue)
|
||||
socket.on('updateQueue', this.updateQueue)
|
||||
@@ -97,26 +96,43 @@ export default {
|
||||
}
|
||||
},
|
||||
initQueue(data) {
|
||||
const { queue: initQueue, queueComplete: initQueueComplete, currentItem, queueList: initQueueList } = data
|
||||
const { queue: initQueue, queueComplete: initQueueComplete, currentItem, queueList: initQueueList, restored } = data
|
||||
|
||||
if (initQueueComplete.length) {
|
||||
initQueueComplete.forEach(item => {
|
||||
initQueueList[item].init = true
|
||||
initQueueList[item].silent = true
|
||||
this.addToQueue(initQueueList[item])
|
||||
})
|
||||
}
|
||||
|
||||
if (currentItem) {
|
||||
initQueueList[currentItem].init = true
|
||||
initQueueList[currentItem].silent = true
|
||||
this.addToQueue(initQueueList[currentItem], true)
|
||||
}
|
||||
|
||||
initQueue.forEach(item => {
|
||||
initQueueList[item].init = true
|
||||
initQueueList[item].silent = true
|
||||
this.addToQueue(initQueueList[item])
|
||||
})
|
||||
|
||||
if (restored){
|
||||
toast(this.$t('toasts.queueRestored'), 'done', true, 'restoring_queue')
|
||||
socket.emit('queueRestored')
|
||||
}
|
||||
},
|
||||
addToQueue(queueItem, current = false) {
|
||||
if (Array.isArray(queueItem)){
|
||||
if (queueItem.length > 1){
|
||||
queueItem.forEach((item, i) => {
|
||||
item.silent = true
|
||||
this.addToQueue(item)
|
||||
});
|
||||
toast(this.$t('toasts.addedMoreToQueue', [queueItem.length]), 'playlist_add_check')
|
||||
return
|
||||
}else{
|
||||
queueItem = queueItem[0]
|
||||
}
|
||||
}
|
||||
this.queueList[queueItem.uuid] = queueItem
|
||||
|
||||
if (queueItem.downloaded + queueItem.failed == queueItem.size) {
|
||||
@@ -188,13 +204,13 @@ export default {
|
||||
}
|
||||
}
|
||||
|
||||
if (!queueItem.init) {
|
||||
if (!queueItem.silent) {
|
||||
toast(this.$t('toasts.addedToQueue', [queueItem.title]), 'playlist_add_check')
|
||||
}
|
||||
},
|
||||
updateQueue(update) {
|
||||
// downloaded and failed default to false?
|
||||
const { uuid, downloaded, failed, progress, error, data, errid } = update
|
||||
const { uuid, downloaded, failed, progress, conversion, error, data, errid } = update
|
||||
|
||||
if (uuid && this.queue.indexOf(uuid) > -1) {
|
||||
if (downloaded) {
|
||||
@@ -224,6 +240,10 @@ export default {
|
||||
this.queueList[uuid].progress = progress
|
||||
$('#bar_' + uuid).css('width', progress + '%')
|
||||
}
|
||||
|
||||
if (conversion) {
|
||||
$('#bar_' + uuid).css('width', (100-conversion) + '%')
|
||||
}
|
||||
}
|
||||
},
|
||||
removeFromQueue(uuid) {
|
||||
@@ -339,9 +359,17 @@ export default {
|
||||
},
|
||||
startDownload(uuid) {
|
||||
$('#bar_' + uuid)
|
||||
.removeClass('converting')
|
||||
.removeClass('indeterminate')
|
||||
.addClass('determinate')
|
||||
},
|
||||
startConversion(uuid) {
|
||||
$('#bar_' + uuid)
|
||||
.addClass('converting')
|
||||
.removeClass('indeterminate')
|
||||
.addClass('determinate')
|
||||
.css('width', '100%')
|
||||
},
|
||||
showErrorsTab(clickEvent) {
|
||||
this.$root.$emit('showTabErrors', clickEvent.data.item, clickEvent.target)
|
||||
}
|
||||
|
||||
@@ -38,7 +38,6 @@
|
||||
<div
|
||||
role="button"
|
||||
aria-label="download"
|
||||
@contextmenu.prevent="openQualityModal"
|
||||
@click.stop="addToQueue"
|
||||
:data-link="release.link"
|
||||
class="download_overlay"
|
||||
@@ -62,7 +61,6 @@
|
||||
<div
|
||||
role="button"
|
||||
aria-label="download"
|
||||
@contextmenu.prevent="openQualityModal"
|
||||
@click.stop="addToQueue"
|
||||
:data-link="release.link"
|
||||
class="download_overlay"
|
||||
@@ -88,7 +86,6 @@
|
||||
<div
|
||||
role="button"
|
||||
aria-label="download"
|
||||
@contextmenu.prevent="openQualityModal"
|
||||
@click.stop="addToQueue"
|
||||
:data-link="release.link"
|
||||
class="download_overlay"
|
||||
@@ -112,7 +109,6 @@
|
||||
<div
|
||||
role="button"
|
||||
aria-label="download"
|
||||
@contextmenu.prevent="openQualityModal"
|
||||
@click.stop="addToQueue"
|
||||
:data-link="release.link"
|
||||
class="download_overlay"
|
||||
@@ -178,7 +174,6 @@
|
||||
</td>
|
||||
<td
|
||||
class="table__cell--download clickable"
|
||||
@contextmenu.prevent="openQualityModal"
|
||||
@click.stop="addToQueue"
|
||||
:data-link="track.link"
|
||||
role="button"
|
||||
@@ -260,9 +255,6 @@ export default {
|
||||
e.stopPropagation()
|
||||
Downloads.sendAddToQueue(e.currentTarget.dataset.link)
|
||||
},
|
||||
openQualityModal(e) {
|
||||
this.$root.$emit('QualityModal:open', e.currentTarget.dataset.link)
|
||||
},
|
||||
updated_userSpotifyPlaylists(data) {
|
||||
this.spotifyPlaylists = data
|
||||
},
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
<div
|
||||
role="button"
|
||||
aria-label="download"
|
||||
@contextmenu.prevent="openQualityModal"
|
||||
@click.stop="addToQueue"
|
||||
:data-link="release.link"
|
||||
class="download_overlay"
|
||||
@@ -50,7 +49,6 @@
|
||||
<div
|
||||
role="button"
|
||||
aria-label="download"
|
||||
@contextmenu.prevent="openQualityModal"
|
||||
@click.stop="addToQueue"
|
||||
:data-link="release.link"
|
||||
class="download_overlay"
|
||||
@@ -89,9 +87,6 @@ export default {
|
||||
addToQueue(e) {
|
||||
Downloads.sendAddToQueue(e.currentTarget.dataset.link)
|
||||
},
|
||||
openQualityModal(e) {
|
||||
this.$root.$emit('QualityModal:open', e.currentTarget.dataset.link)
|
||||
},
|
||||
initHome(data) {
|
||||
const {
|
||||
playlists: { data: playlistData },
|
||||
|
||||
@@ -118,6 +118,7 @@ import { socket } from '@/utils/socket'
|
||||
import { showView } from '@js/tabs.js'
|
||||
import Utils from '@/utils/utils'
|
||||
import EventBus from '@/utils/EventBus'
|
||||
import Downloads from '@/utils/downloads'
|
||||
|
||||
export default {
|
||||
name: 'the-link-analyzer-tab',
|
||||
@@ -184,6 +185,9 @@ export default {
|
||||
},
|
||||
notSupported() {
|
||||
this.link = 'error'
|
||||
},
|
||||
addToQueue(e) {
|
||||
Downloads.sendAddToQueue(e.currentTarget.dataset.link)
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
|
||||
@@ -50,7 +50,6 @@
|
||||
<div
|
||||
role="button"
|
||||
aria-label="download"
|
||||
@contextmenu.prevent="openQualityModal"
|
||||
@click.stop="addToQueue"
|
||||
:data-link="results.allTab.TOP_RESULT[0].link"
|
||||
class="download_overlay"
|
||||
@@ -115,7 +114,6 @@
|
||||
</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"
|
||||
@@ -149,7 +147,6 @@
|
||||
<div
|
||||
role="button"
|
||||
aria-label="download"
|
||||
@contextmenu.prevent="openQualityModal"
|
||||
@click.stop="addToQueue"
|
||||
:data-link="'https://deezer.com/artist/' + release.ART_ID"
|
||||
class="download_overlay"
|
||||
@@ -181,7 +178,6 @@
|
||||
<div
|
||||
role="button"
|
||||
aria-label="download"
|
||||
@contextmenu.prevent="openQualityModal"
|
||||
@click.stop="addToQueue"
|
||||
:data-link="'https://deezer.com/album/' + release.ALB_ID"
|
||||
class="download_overlay"
|
||||
@@ -224,7 +220,6 @@
|
||||
<div
|
||||
role="button"
|
||||
aria-label="download"
|
||||
@contextmenu.prevent="openQualityModal"
|
||||
@click.stop="addToQueue"
|
||||
:data-link="'https://deezer.com/playlist/' + release.PLAYLIST_ID"
|
||||
class="download_overlay"
|
||||
@@ -321,7 +316,6 @@
|
||||
</td>
|
||||
<td
|
||||
class="table__cell--download table__cell--center clickable"
|
||||
@contextmenu.prevent="openQualityModal"
|
||||
@click.stop="addToQueue"
|
||||
:data-link="track.link"
|
||||
role="button"
|
||||
@@ -353,7 +347,6 @@
|
||||
<div
|
||||
role="button"
|
||||
aria-label="download"
|
||||
@contextmenu.prevent="openQualityModal"
|
||||
@click.stop="addToQueue"
|
||||
:data-link="release.link"
|
||||
class="download_overlay"
|
||||
@@ -391,7 +384,6 @@
|
||||
<div
|
||||
role="button"
|
||||
aria-label="download"
|
||||
@contextmenu.prevent="openQualityModal"
|
||||
@click.stop="addToQueue"
|
||||
:data-link="release.link"
|
||||
class="download_overlay"
|
||||
@@ -422,7 +414,6 @@
|
||||
<div
|
||||
role="button"
|
||||
aria-label="download"
|
||||
@contextmenu.prevent="openQualityModal"
|
||||
@click.stop="addToQueue"
|
||||
:data-link="release.link"
|
||||
class="download_overlay"
|
||||
@@ -625,9 +616,6 @@ export default {
|
||||
addToQueue(e) {
|
||||
Downloads.sendAddToQueue(e.currentTarget.dataset.link)
|
||||
},
|
||||
openQualityModal(e) {
|
||||
this.$root.$emit('QualityModal:open', e.currentTarget.dataset.link)
|
||||
},
|
||||
numberWithDots: Utils.numberWithDots,
|
||||
convertDuration: Utils.convertDuration,
|
||||
search(type) {
|
||||
|
||||
@@ -53,7 +53,6 @@ export default {
|
||||
}),
|
||||
mounted() {
|
||||
this.$root.$on('QualityModal:open', this.openModal)
|
||||
|
||||
this.$refs.modal.addEventListener('webkitAnimationEnd', this.handleAnimationEnd)
|
||||
},
|
||||
methods: {
|
||||
|
||||
@@ -19,13 +19,16 @@
|
||||
</h3>
|
||||
<div class="inline-flex">
|
||||
<input autocomplete="off" type="password" id="login_input_arl" ref="loginInput" placeholder="ARL" />
|
||||
<button id="settings_btn_copyArl" @click="copyARLtoClipboard">
|
||||
<button id="settings_btn_copyArl" class="only_icon" @click="copyARLtoClipboard">
|
||||
<i class="material-icons">assignment</i>
|
||||
</button>
|
||||
</div>
|
||||
<a href="https://codeberg.org/RemixDev/deemix/wiki/Getting-your-own-ARL" target="_blank">
|
||||
{{ $t('settings.login.arl.question') }}
|
||||
</a>
|
||||
<a id="settings_btn_applogin" class="hide" href="#" @click="applogin">
|
||||
Automated login
|
||||
</a>
|
||||
<button id="settings_btn_updateArl" @click="login" style="width: 100%;">
|
||||
{{ $t('settings.login.arl.update') }}
|
||||
</button>
|
||||
@@ -62,7 +65,12 @@
|
||||
<h3 class="settings-group__header settings-group__header--with-icon">
|
||||
<i class="material-icons">folder</i>{{ $t('settings.downloadPath.title') }}
|
||||
</h3>
|
||||
<input type="text" v-model="settings.downloadLocation" />
|
||||
<div class="inline-flex">
|
||||
<input autocomplete="off" type="text" v-model="settings.downloadLocation" />
|
||||
<button id="select_downloads_folder" class="only_icon hide" @click="selectDownloadFolder">
|
||||
<i class="material-icons">folder</i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="settings-group">
|
||||
@@ -186,6 +194,8 @@
|
||||
<select v-model="settings.overwriteFile">
|
||||
<option value="y">{{ $t('settings.downloads.overwriteFile.y') }}</option>
|
||||
<option value="n">{{ $t('settings.downloads.overwriteFile.n') }}</option>
|
||||
<option value="e">{{ $t('settings.downloads.overwriteFile.e') }}</option>
|
||||
<option value="b">{{ $t('settings.downloads.overwriteFile.b') }}</option>
|
||||
<option value="t">{{ $t('settings.downloads.overwriteFile.t') }}</option>
|
||||
</select>
|
||||
</div>
|
||||
@@ -264,12 +274,14 @@
|
||||
|
||||
<div class="input_group">
|
||||
<p class="input_group_text">{{ $t('settings.covers.localArtworkSize') }}</p>
|
||||
<input type="number" min="100" max="1800" step="100" v-model.number="settings.localArtworkSize" />
|
||||
<input type="number" min="100" max="10000" step="100" v-model.number="settings.localArtworkSize" />
|
||||
<p v-if="settings.localArtworkSize > 1200" class="input_group_text" style="opacity: 0.75; color: #ffcc22;">⚠️ {{ $t('settings.covers.imageSizeWarning') }}</p>
|
||||
</div>
|
||||
|
||||
<div class="input_group">
|
||||
<p class="input_group_text">{{ $t('settings.covers.embeddedArtworkSize') }}</p>
|
||||
<input type="number" min="100" max="1800" step="100" v-model.number="settings.embeddedArtworkSize" />
|
||||
<input type="number" min="100" max="10000" step="100" v-model.number="settings.embeddedArtworkSize" />
|
||||
<p v-if="settings.embeddedArtworkSize > 1200" class="input_group_text" style="opacity: 0.75; color: #ffcc22;">⚠️ {{ $t('settings.covers.imageSizeWarning') }}</p>
|
||||
</div>
|
||||
|
||||
<div class="input_group">
|
||||
@@ -281,6 +293,12 @@
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<label class="with_checkbox">
|
||||
<input type="checkbox" v-model="settings.embeddedArtworkPNG" />
|
||||
<span class="checkbox_text">{{ $t('settings.covers.embeddedArtworkPNG') }}</span>
|
||||
</label>
|
||||
<p v-if="settings.embeddedArtworkPNG" style="opacity: 0.75; color: #ffcc22;">⚠️ {{ $t('settings.covers.embeddedPNGWarning') }}</p>
|
||||
|
||||
<div class="input_group">
|
||||
<p class="input_group_text">{{ $t('settings.covers.jpegImageQuality') }}</p>
|
||||
<input type="number" min="1" max="100" v-model.number="settings.jpegImageQuality" />
|
||||
@@ -727,6 +745,8 @@ export default {
|
||||
socket.on('updateSettings', this.updateSettings)
|
||||
socket.on('accountChanged', this.accountChanged)
|
||||
socket.on('familyAccounts', this.initAccounts)
|
||||
socket.on('downloadFolderSelected', this.downloadFolderSelected)
|
||||
socket.on('applogin_arl', this.setArl)
|
||||
},
|
||||
methods: {
|
||||
revertSettings() {
|
||||
@@ -768,6 +788,13 @@ export default {
|
||||
|
||||
socket.emit('saveSettings', this.lastSettings, this.lastCredentials, changed ? this.lastUser : false)
|
||||
},
|
||||
selectDownloadFolder() {
|
||||
if (window.clientMode) socket.emit('selectDownloadFolder')
|
||||
},
|
||||
downloadFolderSelected(folder){
|
||||
console.log(folder)
|
||||
this.settings.downloadLocation = folder
|
||||
},
|
||||
loadSettings(settings, spotifyCredentials, defaults = null) {
|
||||
if (defaults) {
|
||||
this.defaultSettings = { ...defaults }
|
||||
@@ -784,6 +811,14 @@ export default {
|
||||
socket.emit('login', arl, true, this.accountNum)
|
||||
}
|
||||
},
|
||||
applogin(e) {
|
||||
e.preventDefault()
|
||||
if (window.clientMode) socket.emit('applogin')
|
||||
},
|
||||
setArl(arl) {
|
||||
this.$refs.loginInput.value = arl
|
||||
this.login()
|
||||
},
|
||||
changeAccount() {
|
||||
socket.emit('changeAccount', this.accountNum)
|
||||
},
|
||||
|
||||
@@ -9,11 +9,11 @@
|
||||
<span class="main_tablinks_text">{{ $t('sidebar.search') }}</span>
|
||||
</span>
|
||||
<span id="main_charts_tablink" class="main_tablinks" role="link" aria-label="charts">
|
||||
<i class="material-icons side_icon">bubble_chart</i>
|
||||
<i class="material-icons side_icon">show_chart</i>
|
||||
<span class="main_tablinks_text">{{ $t('sidebar.charts') }}</span>
|
||||
</span>
|
||||
<span id="main_favorites_tablink" class="main_tablinks" role="link" aria-label="favorites">
|
||||
<i class="material-icons side_icon">album</i>
|
||||
<i class="material-icons side_icon">star</i>
|
||||
<span class="main_tablinks_text">{{ $t('sidebar.favorites') }}</span>
|
||||
</span>
|
||||
<span id="main_analyzer_tablink" class="main_tablinks" role="link" aria-label="link analyzer">
|
||||
@@ -194,4 +194,3 @@ export default {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
@@ -30,7 +30,10 @@ export default {
|
||||
onTimeUpdate() {
|
||||
// Prevents first time entering in this function
|
||||
if (isNaN(this.$refs.preview.duration)) return
|
||||
if (this.$refs.preview.currentTime <= this.$refs.preview.duration - 1) return
|
||||
let duration = this.$refs.preview.duration
|
||||
if (!isFinite(duration)) duration = 30
|
||||
if (duration - this.$refs.preview.currentTime >= 1) return
|
||||
if (this.previewStopped) return
|
||||
|
||||
$(this.$refs.preview).animate({ volume: 0 }, 800)
|
||||
|
||||
|
||||
@@ -133,15 +133,10 @@
|
||||
</table>
|
||||
<span v-if="label" style="opacity: 0.4; margin-top: 8px; display: inline-block; font-size: 13px;">{{ label }}</span>
|
||||
<footer>
|
||||
<button @contextmenu.prevent="openQualityModal" @click.stop="addToQueue" :data-link="link">
|
||||
<button @click.stop="addToQueue" :data-link="link">
|
||||
{{ `${$t('globals.download', [$tc(`globals.listTabs.${type}`, 1)])}` }}
|
||||
</button>
|
||||
<button
|
||||
class="with_icon"
|
||||
@contextmenu.prevent="openQualityModal"
|
||||
@click.stop="addToQueue"
|
||||
:data-link="selectedLinks()"
|
||||
>
|
||||
<button class="with_icon" @click.stop="addToQueue" :data-link="selectedLinks()">
|
||||
{{ $t('tracklist.downloadSelection') }}<i class="material-icons">file_download</i>
|
||||
</button>
|
||||
<button class="back-button" @click="backTab">{{ $t('globals.back') }}</button>
|
||||
@@ -191,9 +186,6 @@ export default {
|
||||
addToQueue(e) {
|
||||
Downloads.sendAddToQueue(e.currentTarget.dataset.link)
|
||||
},
|
||||
openQualityModal(e) {
|
||||
this.$root.$emit('QualityModal:open', e.currentTarget.dataset.link)
|
||||
},
|
||||
toggleAll(e) {
|
||||
this.body.forEach(item => {
|
||||
if (item.type == 'track') {
|
||||
|
||||
Reference in New Issue
Block a user