moved track preview logic to Vue

This commit is contained in:
Roberto Tonino 2020-07-16 22:49:08 +02:00
parent 07df1f2847
commit 1a300a6b1b
10 changed files with 136 additions and 145 deletions

View file

@ -5,8 +5,8 @@ This is just the WebUI for deemix, it should be used with deemix-pyweb or someth
## What's left to do? ## What's left to do?
- Use Vue as much as possible - Use Vue as much as possible
- First step: Single File Components - First step: rewrite the app in Single File Components way ✅
- Completely remove jQuery dependency - Second step: Remove jQuery
- Make the UI look coherent - Make the UI look coherent
- Style buttons - Style buttons
- Style text inputs - Style text inputs

File diff suppressed because one or more lines are too long

View file

@ -6,7 +6,6 @@ window.vol = {
} }
import App from '@/js/App.vue' import App from '@/js/App.vue'
import TrackPreview from '@/js/track-preview.js'
import $ from 'jquery' import $ from 'jquery'
import { socket } from '@/js/socket.js' import { socket } from '@/js/socket.js'
@ -17,9 +16,7 @@ import { init as initTabs } from '@/js/tabs.js'
function startApp() { function startApp() {
mountApp() mountApp()
initTabs() initTabs()
TrackPreview.init()
} }
function mountApp() { function mountApp() {

View file

@ -115,7 +115,6 @@
import { socket } from '@/js/socket.js' import { socket } from '@/js/socket.js'
import { showView } from '@/js/tabs.js' import { showView } from '@/js/tabs.js'
import Downloads from '@/js/downloads.js' import Downloads from '@/js/downloads.js'
import TrackPreview from '@/js/track-preview.js'
import Utils from '@/js/utils.js' import Utils from '@/js/utils.js'
export default { export default {
@ -131,9 +130,15 @@ export default {
methods: { methods: {
artistView: showView.bind(null, 'artist'), artistView: showView.bind(null, 'artist'),
albumView: showView.bind(null, 'album'), albumView: showView.bind(null, 'album'),
playPausePreview: TrackPreview.playPausePreview, playPausePreview(e) {
previewMouseEnter: TrackPreview.previewMouseEnter, EventBus.$emit('trackPreview:playPausePreview', e)
previewMouseLeave: TrackPreview.previewMouseLeave, },
previewMouseEnter(e) {
EventBus.$emit('trackPreview:previewMouseEnter', e)
},
previewMouseLeave(e) {
EventBus.$emit('trackPreview:previewMouseLeave', e)
},
convertDuration: Utils.convertDuration, convertDuration: Utils.convertDuration,
addToQueue(e) { addToQueue(e) {
e.stopPropagation() e.stopPropagation()

View file

@ -185,7 +185,6 @@
import { socket } from '@/js/socket.js' import { socket } from '@/js/socket.js'
import { showView, changeTab } from '@/js/tabs.js' import { showView, changeTab } from '@/js/tabs.js'
import Downloads from '@/js/downloads.js' import Downloads from '@/js/downloads.js'
import TrackPreview from '@/js/track-preview.js'
import Utils from '@/js/utils.js' import Utils from '@/js/utils.js'
import { toast } from '@/js/toasts' import { toast } from '@/js/toasts'
@ -205,9 +204,15 @@ export default {
albumView: showView.bind(null, 'album'), albumView: showView.bind(null, 'album'),
playlistView: showView.bind(null, 'playlist'), playlistView: showView.bind(null, 'playlist'),
spotifyPlaylistView: showView.bind(null, 'spotifyplaylist'), spotifyPlaylistView: showView.bind(null, 'spotifyplaylist'),
playPausePreview: TrackPreview.playPausePreview, playPausePreview(e) {
previewMouseEnter: TrackPreview.previewMouseEnter, EventBus.$emit('trackPreview:playPausePreview', e)
previewMouseLeave: TrackPreview.previewMouseLeave, },
previewMouseEnter(e) {
EventBus.$emit('trackPreview:previewMouseEnter', e)
},
previewMouseLeave(e) {
EventBus.$emit('trackPreview:previewMouseLeave', e)
},
convertDuration: Utils.convertDuration, convertDuration: Utils.convertDuration,
handleFavoritesTabClick(event) { handleFavoritesTabClick(event) {
const { const {

View file

@ -440,7 +440,6 @@
import { socket } from '@/js/socket.js' import { socket } from '@/js/socket.js'
import { showView } from '@/js/tabs.js' import { showView } from '@/js/tabs.js'
import Downloads from '@/js/downloads.js' import Downloads from '@/js/downloads.js'
import TrackPreview from '@/js/track-preview.js'
import Utils from '@/js/utils.js' import Utils from '@/js/utils.js'
import BaseLoadingPlaceholder from '@components/BaseLoadingPlaceholder.vue' import BaseLoadingPlaceholder from '@components/BaseLoadingPlaceholder.vue'
@ -515,9 +514,15 @@ export default {
artistView: showView.bind(null, 'artist'), artistView: showView.bind(null, 'artist'),
albumView: showView.bind(null, 'album'), albumView: showView.bind(null, 'album'),
playlistView: showView.bind(null, 'playlist'), playlistView: showView.bind(null, 'playlist'),
playPausePreview: TrackPreview.playPausePreview, playPausePreview(e) {
previewMouseEnter: TrackPreview.previewMouseEnter, EventBus.$emit('trackPreview:playPausePreview', e)
previewMouseLeave: TrackPreview.previewMouseLeave, },
previewMouseEnter(e) {
EventBus.$emit('trackPreview:previewMouseEnter', e)
},
previewMouseLeave(e) {
EventBus.$emit('trackPreview:previewMouseLeave', e)
},
handleSearchTabClick(event) { handleSearchTabClick(event) {
const { const {
target, target,

View file

@ -1,29 +1,38 @@
<template> <template>
<audio id="preview-track" @canplay="onCanPlay" @timeupdate="onTimeUpdate" ref="previewEl"> <audio id="preview-track" @canplay="onCanPlay" @timeupdate="onTimeUpdate" ref="preview">
<source id="preview-track_source" src="" type="audio/mpeg" /> <source id="preview-track_source" src="" type="audio/mpeg" />
</audio> </audio>
</template> </template>
<script> <script>
import $ from 'jquery' import $ from 'jquery'
import EventBus from '@/js/EventBus'
export default { export default {
data: () => ({ data: () => ({
previewStopped: false previewStopped: false
}), }),
mounted() {
this.$refs.preview.volume = 1
EventBus.$on('trackPreview:playPausePreview', this.playPausePreview)
EventBus.$on('trackPreview:stopStackedTabsPreview', this.stopStackedTabsPreview)
EventBus.$on('trackPreview:previewMouseEnter', this.previewMouseEnter)
EventBus.$on('trackPreview:previewMouseLeave', this.previewMouseLeave)
},
methods: { methods: {
async onCanPlay() { async onCanPlay() {
await this.$refs.previewEl.play() await this.$refs.preview.play()
this.previewStopped = false this.previewStopped = false
$(this.$refs.previewEl).animate({ volume: vol.preview_max_volume / 100 }, 500) $(this.$refs.preview).animate({ volume: vol.preview_max_volume / 100 }, 500)
}, },
onTimeUpdate() { onTimeUpdate() {
// Prevents first time entering in this function // Prevents first time entering in this function
if (isNaN(this.$refs.previewEl.duration)) return if (isNaN(this.$refs.preview.duration)) return
if (this.$refs.previewEl.currentTime <= this.$refs.previewEl.duration - 1) return if (this.$refs.preview.currentTime <= this.$refs.preview.duration - 1) return
$(this.$refs.previewEl).animate({ volume: 0 }, 800) $(this.$refs.preview).animate({ volume: 0 }, 800)
this.previewStopped = true this.previewStopped = true
@ -31,6 +40,80 @@ export default {
$('*').removeAttr('playing') $('*').removeAttr('playing')
$('.preview_controls').text('play_arrow') $('.preview_controls').text('play_arrow')
$('.preview_playlist_controls').text('play_arrow') $('.preview_playlist_controls').text('play_arrow')
},
playPausePreview(e) {
e.preventDefault()
const { currentTarget: obj } = event
var $icon = obj.tagName == 'I' ? $(obj) : $(obj).children('i')
if ($(obj).attr('playing')) {
if (this.$refs.preview.paused) {
this.$refs.preview.play()
this.previewStopped = false
$icon.text('pause')
$(this.$refs.preview).animate({ volume: vol.preview_max_volume / 100 }, 500)
} else {
this.previewStopped = true
$icon.text('play_arrow')
$(this.$refs.preview).animate({ volume: 0 }, 250, 'swing', () => {
this.$refs.preview.pause()
})
}
} else {
$('*').removeAttr('playing')
$(obj).attr('playing', true)
$('.preview_controls').text('play_arrow')
$('.preview_playlist_controls').text('play_arrow')
$('.preview_controls').css({ opacity: 0 })
$icon.text('pause')
$icon.css({ opacity: 1 })
this.previewStopped = false
$(this.$refs.preview).animate({ volume: 0 }, 250, 'swing', () => {
this.$refs.preview.pause()
$('#preview-track_source').prop('src', $(obj).data('preview'))
this.$refs.preview.load()
})
}
},
stopStackedTabsPreview() {
if (
$('.preview_playlist_controls').filter(function() {
return $(this).attr('playing')
}).length > 0
) {
$(this.$refs.preview).animate({ volume: 0 }, 800)
this.previewStopped = true
$('.preview_playlist_controls').removeAttr('playing')
$('.preview_playlist_controls').text('play_arrow')
}
},
previewMouseEnter(e) {
$(e.currentTarget).css({ opacity: 1 })
},
previewMouseLeave(event) {
const { currentTarget: obj } = event
if (
($(obj)
.parent()
.attr('playing') &&
this.previewStopped) ||
!$(obj)
.parent()
.attr('playing')
) {
$(obj).css({ opacity: 0 }, 200)
}
} }
} }
} }

View file

@ -151,7 +151,6 @@ import { isEmpty } from 'lodash-es'
import { socket } from '@/js/socket.js' import { socket } from '@/js/socket.js'
import { showView } from '@/js/tabs.js' import { showView } from '@/js/tabs.js'
import Downloads from '@/js/downloads.js' import Downloads from '@/js/downloads.js'
import TrackPreview from '@/js/track-preview.js'
import Utils from '@/js/utils.js' import Utils from '@/js/utils.js'
import EventBus from '@/js/EventBus' import EventBus from '@/js/EventBus'
@ -171,7 +170,9 @@ export default {
methods: { methods: {
artistView: showView.bind(null, 'artist'), artistView: showView.bind(null, 'artist'),
albumView: showView.bind(null, 'album'), albumView: showView.bind(null, 'album'),
playPausePreview: TrackPreview.playPausePreview, playPausePreview(e) {
EventBus.$emit('trackPreview:playPausePreview', e)
},
reset() { reset() {
this.title = 'Loading...' this.title = 'Loading...'
this.image = '' this.image = ''

View file

@ -1,4 +1,3 @@
import TrackPreview from '@/js/track-preview.js'
import { socket } from '@/js/socket.js' import { socket } from '@/js/socket.js'
import EventBus from '@/js/EventBus' import EventBus from '@/js/EventBus'
@ -91,7 +90,7 @@ export function changeTab(sidebarEl, section, tabName) {
/** /**
* Shows the passed tab, keeping track of the one that the user is coming from. * Shows the passed tab, keeping track of the one that the user is coming from.
* *
* Needs TrackPreview and EventBus * Needs EventBus
*/ */
function showTab(type, id, back = false) { function showTab(type, id, back = false) {
if (window.windows_stack.length === 0) { if (window.windows_stack.length === 0) {
@ -115,13 +114,13 @@ function showTab(type, id, back = false) {
document.getElementById(window.tab).style.display = 'block' document.getElementById(window.tab).style.display = 'block'
TrackPreview.stopStackedTabsPreview() EventBus.$emit('trackPreview:stopStackedTabsPreview')
} }
/** /**
* Goes back to the previous tab according to the global window stack. * Goes back to the previous tab according to the global window stack.
* *
* Needs TrackPreview, EventBus and socket * Needs EventBus and socket
*/ */
function backTab() { function backTab() {
if (window.windows_stack.length == 1) { if (window.windows_stack.length == 1) {
@ -145,7 +144,7 @@ function backTab() {
showTab(type, id, true) showTab(type, id, true)
} }
TrackPreview.stopStackedTabsPreview() EventBus.$emit('trackPreview:stopStackedTabsPreview')
} }
function _linkListeners() { function _linkListeners() {

View file

@ -1,104 +0,0 @@
import $ from 'jquery'
/* ===== Locals ===== */
let preview_track
let preview_stopped = true
// init stuff
function init() {
preview_track = document.getElementById('preview-track')
preview_track.volume = 1
// start playing when track loaded
preview_track.addEventListener('canplay', function() {
preview_stopped = false
})
// auto fadeout when at the end of the song
preview_track.addEventListener('timeupdate', function() {
if (preview_track.currentTime > preview_track.duration - 1) {
preview_stopped = true
}
})
}
// on modal closing
function stopStackedTabsPreview() {
if (
$('.preview_playlist_controls').filter(function() {
return $(this).attr('playing')
}).length > 0
) {
$(preview_track).animate({ volume: 0 }, 800)
preview_stopped = true
$('.preview_playlist_controls').removeAttr('playing')
$('.preview_playlist_controls').text('play_arrow')
}
}
// on hover event
function previewMouseEnter(e) {
$(e.currentTarget).css({ opacity: 1 })
}
function previewMouseLeave(event) {
const { currentTarget: obj } = event
if (
($(obj)
.parent()
.attr('playing') &&
preview_stopped) ||
!$(obj)
.parent()
.attr('playing')
) {
$(obj).css({ opacity: 0 }, 200)
}
}
// on click event
function playPausePreview(e) {
e.preventDefault()
const { currentTarget: obj } = event
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)
} else {
preview_stopped = true
$icon.text('play_arrow')
$(preview_track).animate({ volume: 0 }, 250, 'swing', () => {
preview_track.pause()
})
}
} else {
$('*').removeAttr('playing')
$(obj).attr('playing', true)
$('.preview_controls').text('play_arrow')
$('.preview_playlist_controls').text('play_arrow')
$('.preview_controls').css({ opacity: 0 })
$icon.text('pause')
$icon.css({ opacity: 1 })
preview_stopped = false
$(preview_track).animate({ volume: 0 }, 250, 'swing', () => {
preview_track.pause()
$('#preview-track_source').prop('src', $(obj).data('preview'))
preview_track.load()
})
}
}
export default {
init,
stopStackedTabsPreview,
previewMouseEnter,
previewMouseLeave,
playPausePreview
}