Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
funkwhale
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Jeff
funkwhale
Commits
5a74d1d3
Commit
5a74d1d3
authored
3 years ago
by
Georg Krause
Browse files
Options
Downloads
Patches
Plain Diff
Fix linting errors in touched files
parent
9bef2304
No related branches found
No related tags found
No related merge requests found
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
front/src/components/Queue.vue
+47
-51
47 additions, 51 deletions
front/src/components/Queue.vue
front/src/components/audio/Player.vue
+134
-140
134 additions, 140 deletions
front/src/components/audio/Player.vue
front/src/store/player.js
+20
-21
20 additions, 21 deletions
front/src/store/player.js
with
201 additions
and
212 deletions
front/src/components/Queue.vue
+
47
−
51
View file @
5a74d1d3
...
...
@@ -207,20 +207,18 @@
</section>
</template>
<
script
>
import
{
mapState
,
mapGetters
,
mapActions
}
from
"
vuex
"
import
{
mapState
,
mapGetters
,
mapActions
}
from
'
vuex
'
import
$
from
'
jquery
'
import
moment
from
"
moment
"
import
moment
from
'
moment
'
import
lodash
from
'
@/lodash
'
import
time
from
"
@/utils/time
"
import
time
from
'
@/utils/time
'
import
createFocusTrap
from
'
focus-trap
'
import
store
from
"
@/store
"
export
default
{
components
:
{
TrackFavoriteIcon
:
()
=>
import
(
/* webpackChunkName: "auth-audio" */
"
@/components/favorites/TrackFavoriteIcon
"
),
TrackPlaylistIcon
:
()
=>
import
(
/* webpackChunkName: "auth-audio" */
"
@/components/playlists/TrackPlaylistIcon
"
),
VolumeControl
:
()
=>
import
(
/* webpackChunkName: "audio" */
"
@/components/audio/VolumeControl
"
),
draggable
:
()
=>
import
(
/* webpackChunkName: "draggable" */
"
vuedraggable
"
),
TrackFavoriteIcon
:
()
=>
import
(
/* webpackChunkName: "auth-audio" */
'
@/components/favorites/TrackFavoriteIcon
'
),
TrackPlaylistIcon
:
()
=>
import
(
/* webpackChunkName: "auth-audio" */
'
@/components/playlists/TrackPlaylistIcon
'
),
draggable
:
()
=>
import
(
/* webpackChunkName: "draggable" */
'
vuedraggable
'
)
},
data
()
{
return
{
...
...
@@ -232,14 +230,13 @@ export default {
}
},
mounted
()
{
let
self
=
this
this
.
focusTrap
=
createFocusTrap
(
this
.
$el
,
{
allowOutsideClick
:
()
=>
{
return
true
}
})
this
.
focusTrap
.
activate
()
this
.
$nextTick
(()
=>
{
setTimeout
(()
=>
{
this
.
scrollToCurrent
()
// delay is to let transition work
},
400
)
;
},
400
)
})
},
computed
:
{
...
...
@@ -256,12 +253,12 @@ export default {
queue
:
state
=>
state
.
queue
}),
...
mapGetters
({
currentTrack
:
"
queue/currentTrack
"
,
hasNext
:
"
queue/hasNext
"
,
emptyQueue
:
"
queue/isEmpty
"
,
durationFormatted
:
"
player/durationFormatted
"
,
currentTimeFormatted
:
"
player/currentTimeFormatted
"
,
progress
:
"
player/progress
"
currentTrack
:
'
queue/currentTrack
'
,
hasNext
:
'
queue/hasNext
'
,
emptyQueue
:
'
queue/isEmpty
'
,
durationFormatted
:
'
player/durationFormatted
'
,
currentTimeFormatted
:
'
player/currentTimeFormatted
'
,
progress
:
'
player/progress
'
}),
tracks
:
{
get
()
{
...
...
@@ -276,11 +273,11 @@ export default {
queue
:
this
.
$pgettext
(
'
*/*/*
'
,
'
Queue
'
),
duration
:
this
.
$pgettext
(
'
*/*/*
'
,
'
Duration
'
),
addArtistContentFilter
:
this
.
$pgettext
(
'
Sidebar/Player/Icon.Tooltip/Verb
'
,
'
Hide content from this artist…
'
),
restart
:
this
.
$pgettext
(
'
*/*/*
'
,
'
Restart track
'
)
,
restart
:
this
.
$pgettext
(
'
*/*/*
'
,
'
Restart track
'
)
}
},
timeLeft
()
{
le
t
seconds
=
lodash
.
sum
(
cons
t
seconds
=
lodash
.
sum
(
this
.
queue
.
tracks
.
slice
(
this
.
queue
.
currentIndex
).
map
((
t
)
=>
{
return
(
t
.
uploads
||
[]).
map
((
u
)
=>
{
return
u
.
duration
||
0
...
...
@@ -294,7 +291,7 @@ export default {
return
this
.
volume
},
set
(
v
)
{
this
.
$store
.
commit
(
"
player/volume
"
,
v
)
this
.
$store
.
commit
(
'
player/volume
'
,
v
)
}
},
playerFocused
()
{
...
...
@@ -303,58 +300,57 @@ export default {
},
methods
:
{
...
mapActions
({
cleanTrack
:
"
queue/cleanTrack
"
,
mute
:
"
player/mute
"
,
unmute
:
"
player/unmute
"
,
clean
:
"
queue/clean
"
,
toggleMute
:
"
player/toggleMute
"
,
resumePlayback
:
"
player/resumePlayback
"
,
pausePlayback
:
"
player/pausePlayback
"
,
cleanTrack
:
'
queue/cleanTrack
'
,
mute
:
'
player/mute
'
,
unmute
:
'
player/unmute
'
,
clean
:
'
queue/clean
'
,
toggleMute
:
'
player/toggleMute
'
,
resumePlayback
:
'
player/resumePlayback
'
,
pausePlayback
:
'
player/pausePlayback
'
}),
reorder
:
function
(
event
)
{
this
.
$store
.
commit
(
"
queue/reorder
"
,
{
this
.
$store
.
commit
(
'
queue/reorder
'
,
{
tracks
:
this
.
tracksChangeBuffer
,
oldIndex
:
event
.
oldIndex
,
newIndex
:
event
.
newIndex
})
},
scrollToCurrent
()
{
le
t
current
=
$
(
this
.
$el
).
find
(
'
.queue-item.active
'
)[
0
]
cons
t
current
=
$
(
this
.
$el
).
find
(
'
.queue-item.active
'
)[
0
]
if
(
!
current
)
{
return
}
const
elementRect
=
current
.
getBoundingClientRect
()
;
const
absoluteElementTop
=
elementRect
.
top
+
window
.
pageYOffset
;
const
middle
=
absoluteElementTop
-
(
window
.
innerHeight
/
2
)
;
window
.
scrollTo
({
top
:
middle
,
behaviour
:
'
smooth
'
})
;
const
elementRect
=
current
.
getBoundingClientRect
()
const
absoluteElementTop
=
elementRect
.
top
+
window
.
pageYOffset
const
middle
=
absoluteElementTop
-
(
window
.
innerHeight
/
2
)
window
.
scrollTo
({
top
:
middle
,
behaviour
:
'
smooth
'
})
},
touchProgress
(
e
)
{
let
time
let
target
=
this
.
$refs
.
progress
time
=
(
e
.
layerX
/
target
.
offsetWidth
)
*
this
.
duration
const
target
=
this
.
$refs
.
progress
const
time
=
(
e
.
layerX
/
target
.
offsetWidth
)
*
this
.
duration
this
.
$emit
(
'
touch-progress
'
,
time
)
},
shuffle
()
{
le
t
disabled
=
this
.
queue
.
tracks
.
length
===
0
cons
t
disabled
=
this
.
queue
.
tracks
.
length
===
0
if
(
this
.
isShuffling
||
disabled
)
{
return
}
le
t
self
=
this
le
t
msg
=
this
.
$pgettext
(
'
Content/Queue/Message
'
,
"
Queue shuffled!
"
)
cons
t
self
=
this
cons
t
msg
=
this
.
$pgettext
(
'
Content/Queue/Message
'
,
'
Queue shuffled!
'
)
this
.
isShuffling
=
true
setTimeout
(()
=>
{
self
.
$store
.
dispatch
(
"
queue/shuffle
"
,
()
=>
{
self
.
$store
.
dispatch
(
'
queue/shuffle
'
,
()
=>
{
self
.
isShuffling
=
false
self
.
$store
.
commit
(
"
ui/addMessage
"
,
{
self
.
$store
.
commit
(
'
ui/addMessage
'
,
{
content
:
msg
,
date
:
new
Date
()
})
})
},
100
)
}
,
}
},
watch
:
{
"
$store.state.ui.queueFocused
"
:
{
'
$store.state.ui.queueFocused
'
:
{
handler
(
v
)
{
if
(
v
===
'
queue
'
)
{
this
.
$nextTick
(()
=>
{
...
...
@@ -369,7 +365,7 @@ export default {
this
.
$nextTick
(()
=>
{
this
.
scrollToCurrent
()
})
}
,
}
},
'
$store.state.queue.tracks
'
:
{
handler
(
v
)
{
...
...
@@ -379,7 +375,7 @@ export default {
},
immediate
:
true
},
"
$route.fullPath
"
()
{
'
$route.fullPath
'
()
{
this
.
$store
.
commit
(
'
ui/queueFocused
'
,
null
)
}
}
...
...
This diff is collapsed.
Click to expand it.
front/src/components/audio/Player.vue
+
134
−
140
View file @
5a74d1d3
...
...
@@ -224,21 +224,20 @@
</template>
<
script
>
import
{
mapState
,
mapGetters
,
mapActions
}
from
"
vuex
"
import
GlobalEvents
from
"
@/components/utils/global-events
"
import
{
mapState
,
mapGetters
,
mapActions
}
from
'
vuex
'
import
GlobalEvents
from
'
@/components/utils/global-events
'
import
{
toLinearVolumeScale
}
from
'
@/audio/volume
'
import
{
Howl
}
from
"
howler
"
import
$
from
'
jquery
'
import
{
Howl
,
Howler
}
from
'
howler
'
import
_
from
'
@/lodash
'
import
url
from
'
@/utils/url
'
import
axios
from
'
axios
'
export
default
{
components
:
{
VolumeControl
:
()
=>
import
(
/* webpackChunkName: "audio" */
"
./VolumeControl
"
),
TrackFavoriteIcon
:
()
=>
import
(
/* webpackChunkName: "auth-audio" */
"
@/components/favorites/TrackFavoriteIcon
"
),
TrackPlaylistIcon
:
()
=>
import
(
/* webpackChunkName: "auth-audio" */
"
@/components/playlists/TrackPlaylistIcon
"
),
GlobalEvents
,
VolumeControl
:
()
=>
import
(
/* webpackChunkName: "audio" */
'
./VolumeControl
'
),
TrackFavoriteIcon
:
()
=>
import
(
/* webpackChunkName: "auth-audio" */
'
@/components/favorites/TrackFavoriteIcon
'
),
TrackPlaylistIcon
:
()
=>
import
(
/* webpackChunkName: "auth-audio" */
'
@/components/playlists/TrackPlaylistIcon
'
),
GlobalEvents
},
data
()
{
return
{
...
...
@@ -263,7 +262,7 @@ export default {
mounted
()
{
this
.
$store
.
dispatch
(
'
player/updateProgress
'
,
0
)
this
.
$store
.
commit
(
'
player/playing
'
,
false
)
this
.
$store
.
commit
(
"
player/isLoadingAudio
"
,
false
)
this
.
$store
.
commit
(
'
player/isLoadingAudio
'
,
false
)
Howler
.
unload
()
// clear existing cache, if any
this
.
nextTrackPreloaded
=
false
// this is needed to unlock audio playing under some browsers,
...
...
@@ -272,7 +271,7 @@ export default {
this
.
dummyAudio
=
new
Howl
({
preload
:
false
,
autoplay
:
false
,
src
:
[
"
noop.webm
"
,
"
noop.mp3
"
]
src
:
[
'
noop.webm
'
,
'
noop.mp3
'
]
})
if
(
this
.
currentTrack
)
{
this
.
getSound
(
this
.
currentTrack
)
...
...
@@ -280,12 +279,12 @@ export default {
}
// Add controls for notification drawer
if
(
'
mediaSession
'
in
navigator
)
{
navigator
.
mediaSession
.
setActionHandler
(
'
play
'
,
this
.
resumePlayback
)
;
navigator
.
mediaSession
.
setActionHandler
(
'
pause
'
,
this
.
pausePlayback
)
;
navigator
.
mediaSession
.
setActionHandler
(
'
seekforward
'
,
this
.
seekForward
)
;
navigator
.
mediaSession
.
setActionHandler
(
'
seekbackward
'
,
this
.
seekBackward
)
;
navigator
.
mediaSession
.
setActionHandler
(
'
nexttrack
'
,
this
.
next
)
;
navigator
.
mediaSession
.
setActionHandler
(
'
previoustrack
'
,
this
.
previous
)
;
navigator
.
mediaSession
.
setActionHandler
(
'
play
'
,
this
.
resumePlayback
)
navigator
.
mediaSession
.
setActionHandler
(
'
pause
'
,
this
.
pausePlayback
)
navigator
.
mediaSession
.
setActionHandler
(
'
seekforward
'
,
this
.
seekForward
)
navigator
.
mediaSession
.
setActionHandler
(
'
seekbackward
'
,
this
.
seekBackward
)
navigator
.
mediaSession
.
setActionHandler
(
'
nexttrack
'
,
this
.
next
)
navigator
.
mediaSession
.
setActionHandler
(
'
previoustrack
'
,
this
.
previous
)
}
},
beforeDestroy
()
{
...
...
@@ -296,13 +295,13 @@ export default {
},
methods
:
{
...
mapActions
({
resumePlayback
:
"
player/resumePlayback
"
,
pausePlayback
:
"
player/pausePlayback
"
,
togglePlayback
:
"
player/togglePlayback
"
,
mute
:
"
player/mute
"
,
unmute
:
"
player/unmute
"
,
clean
:
"
queue/clean
"
,
toggleMute
:
"
player/toggleMute
"
,
resumePlayback
:
'
player/resumePlayback
'
,
pausePlayback
:
'
player/pausePlayback
'
,
togglePlayback
:
'
player/togglePlayback
'
,
mute
:
'
player/mute
'
,
unmute
:
'
player/unmute
'
,
clean
:
'
queue/clean
'
,
toggleMute
:
'
player/toggleMute
'
}),
async
getTrackData
(
trackData
)
{
// use previously fetched trackData
...
...
@@ -312,21 +311,21 @@ export default {
return
axios
.
get
(
`tracks/
${
trackData
.
id
}
/`
)
.
then
(
response
=>
response
.
data
,
err
=>
null
()
=>
null
)
},
shuffle
()
{
le
t
disabled
=
this
.
queue
.
tracks
.
length
===
0
cons
t
disabled
=
this
.
queue
.
tracks
.
length
===
0
if
(
this
.
isShuffling
||
disabled
)
{
return
}
le
t
self
=
this
le
t
msg
=
this
.
$pgettext
(
'
Content/Queue/Message
'
,
"
Queue shuffled!
"
)
cons
t
self
=
this
cons
t
msg
=
this
.
$pgettext
(
'
Content/Queue/Message
'
,
'
Queue shuffled!
'
)
this
.
isShuffling
=
true
setTimeout
(()
=>
{
self
.
$store
.
dispatch
(
"
queue/shuffle
"
,
()
=>
{
self
.
$store
.
dispatch
(
'
queue/shuffle
'
,
()
=>
{
self
.
isShuffling
=
false
self
.
$store
.
commit
(
"
ui/addMessage
"
,
{
self
.
$store
.
commit
(
'
ui/addMessage
'
,
{
content
:
msg
,
date
:
new
Date
()
})
...
...
@@ -334,29 +333,29 @@ export default {
},
100
)
},
next
()
{
le
t
self
=
this
this
.
$store
.
dispatch
(
"
queue/next
"
).
then
(()
=>
{
self
.
$emit
(
"
next
"
)
cons
t
self
=
this
this
.
$store
.
dispatch
(
'
queue/next
'
).
then
(()
=>
{
self
.
$emit
(
'
next
'
)
})
},
previous
()
{
le
t
self
=
this
this
.
$store
.
dispatch
(
"
queue/previous
"
).
then
(()
=>
{
self
.
$emit
(
"
previous
"
)
cons
t
self
=
this
this
.
$store
.
dispatch
(
'
queue/previous
'
).
then
(()
=>
{
self
.
$emit
(
'
previous
'
)
})
},
handleError
({
sound
,
error
})
{
this
.
$store
.
commit
(
"
player/isLoadingAudio
"
,
false
)
this
.
$store
.
dispatch
(
"
player/trackErrored
"
)
this
.
$store
.
commit
(
'
player/isLoadingAudio
'
,
false
)
this
.
$store
.
dispatch
(
'
player/trackErrored
'
)
},
getSound
(
trackData
)
{
le
t
cached
=
this
.
getSoundFromCache
(
trackData
)
cons
t
cached
=
this
.
getSoundFromCache
(
trackData
)
if
(
cached
)
{
return
cached
.
sound
}
le
t
srcs
=
this
.
getSrcs
(
trackData
)
le
t
self
=
this
le
t
sound
=
new
Howl
({
cons
t
srcs
=
this
.
getSrcs
(
trackData
)
cons
t
self
=
this
cons
t
sound
=
new
Howl
({
src
:
srcs
.
map
((
s
)
=>
{
return
s
.
url
}),
format
:
srcs
.
map
((
s
)
=>
{
return
s
.
type
}),
autoplay
:
false
,
...
...
@@ -372,17 +371,17 @@ export default {
}
},
onload
:
function
()
{
le
t
sound
=
this
le
t
node
=
this
.
_sounds
[
0
].
_node
;
cons
t
sound
=
this
cons
t
node
=
this
.
_sounds
[
0
].
_node
node
.
addEventListener
(
'
progress
'
,
()
=>
{
if
(
sound
!=
self
.
currentSound
)
{
if
(
sound
!=
=
self
.
currentSound
)
{
return
}
self
.
updateBuffer
(
node
)
})
},
onplay
:
function
()
{
if
(
this
!=
self
.
currentSound
)
{
if
(
this
!=
=
self
.
currentSound
)
{
this
.
stop
()
return
}
...
...
@@ -390,30 +389,29 @@ export default {
self
.
$store
.
commit
(
'
player/resetErrorCount
'
)
self
.
$store
.
commit
(
'
player/errored
'
,
false
)
self
.
$store
.
commit
(
'
player/duration
'
,
this
.
duration
())
},
onloaderror
:
function
(
sound
,
error
)
{
self
.
removeFromCache
(
this
)
if
(
this
!=
self
.
currentSound
)
{
if
(
this
!=
=
self
.
currentSound
)
{
return
}
console
.
log
(
'
Error while playing:
'
,
sound
,
error
)
self
.
handleError
({
sound
,
error
})
}
,
}
})
this
.
addSoundToCache
(
sound
,
trackData
)
return
sound
},
getSrcs
:
function
(
trackData
)
{
le
t
a
=
document
.
createElement
(
'
audio
'
)
le
t
allowed
=
[
'
probably
'
,
'
maybe
'
]
le
t
sources
=
trackData
.
uploads
.
filter
(
u
=>
{
le
t
canPlay
=
a
.
canPlayType
(
u
.
mimetype
)
cons
t
a
=
document
.
createElement
(
'
audio
'
)
cons
t
allowed
=
[
'
probably
'
,
'
maybe
'
]
cons
t
sources
=
trackData
.
uploads
.
filter
(
u
=>
{
cons
t
canPlay
=
a
.
canPlayType
(
u
.
mimetype
)
return
allowed
.
indexOf
(
canPlay
)
>
-
1
}).
map
(
u
=>
{
return
{
type
:
u
.
extension
,
url
:
this
.
$store
.
getters
[
'
instance/absoluteUrl
'
](
u
.
listen_url
)
,
url
:
this
.
$store
.
getters
[
'
instance/absoluteUrl
'
](
u
.
listen_url
)
}
})
a
.
remove
()
...
...
@@ -433,12 +431,12 @@ export default {
// so authentication can be checked by the backend
// because for audio files we cannot use the regular Authentication
// header
let
param
=
"
jwt
"
let
param
=
'
jwt
'
let
value
=
this
.
$store
.
state
.
auth
.
token
if
(
this
.
$store
.
state
.
auth
.
scopedTokens
&&
this
.
$store
.
state
.
auth
.
scopedTokens
.
listen
)
{
// used scoped tokens instead of JWT to reduce the attack surface if the token
// is leaked
param
=
"
token
"
param
=
'
token
'
value
=
this
.
$store
.
state
.
auth
.
scopedTokens
.
listen
}
sources
.
forEach
(
e
=>
{
...
...
@@ -450,30 +448,30 @@ export default {
updateBuffer
(
node
)
{
// from https://github.com/goldfire/howler.js/issues/752#issuecomment-372083163
let
range
=
0
;
le
t
bf
=
node
.
buffered
;
le
t
time
=
node
.
currentTime
;
let
range
=
0
cons
t
bf
=
node
.
buffered
cons
t
time
=
node
.
currentTime
try
{
while
(
!
(
bf
.
start
(
range
)
<=
time
&&
time
<=
bf
.
end
(
range
)))
{
range
+=
1
;
range
+=
1
}
}
catch
(
IndexSizeError
)
{
return
}
let
loadPercentage
le
t
start
=
bf
.
start
(
range
)
le
t
end
=
bf
.
end
(
range
)
cons
t
start
=
bf
.
start
(
range
)
cons
t
end
=
bf
.
end
(
range
)
if
(
range
===
0
)
{
// easy case, no user-seek
le
t
loadStartPercentage
=
start
/
node
.
duration
;
le
t
loadEndPercentage
=
end
/
node
.
duration
;
loadPercentage
=
loadEndPercentage
-
loadStartPercentage
;
cons
t
loadStartPercentage
=
start
/
node
.
duration
cons
t
loadEndPercentage
=
end
/
node
.
duration
loadPercentage
=
loadEndPercentage
-
loadStartPercentage
}
else
{
le
t
loaded
=
end
-
start
le
t
remainingToLoad
=
node
.
duration
-
start
cons
t
loaded
=
end
-
start
cons
t
remainingToLoad
=
node
.
duration
-
start
// user seeked a specific position in the audio, our progress must be
// computed based on the remaining portion of the track
loadPercentage
=
loaded
/
remainingToLoad
;
loadPercentage
=
loaded
/
remainingToLoad
}
if
(
loadPercentage
*
100
===
this
.
bufferProgress
)
{
return
...
...
@@ -483,18 +481,17 @@ export default {
updateProgress
:
function
()
{
this
.
isUpdatingTime
=
true
if
(
this
.
currentSound
&&
this
.
currentSound
.
state
()
===
'
loaded
'
)
{
le
t
t
=
this
.
currentSound
.
seek
()
le
t
d
=
this
.
currentSound
.
duration
()
cons
t
t
=
this
.
currentSound
.
seek
()
cons
t
d
=
this
.
currentSound
.
duration
()
this
.
$store
.
dispatch
(
'
player/updateProgress
'
,
t
)
this
.
updateBuffer
(
this
.
currentSound
.
_sounds
[
0
].
_node
)
le
t
toPreload
=
this
.
$store
.
state
.
queue
.
tracks
[
this
.
currentIndex
+
1
]
cons
t
toPreload
=
this
.
$store
.
state
.
queue
.
tracks
[
this
.
currentIndex
+
1
]
if
(
!
this
.
nextTrackPreloaded
&&
toPreload
&&
!
this
.
getSoundFromCache
(
toPreload
)
&&
(
t
>
this
.
preloadDelay
||
d
-
t
<
30
))
{
this
.
getSound
(
toPreload
)
this
.
nextTrackPreloaded
=
true
}
if
(
t
>
(
d
/
2
))
{
let
onlyTrack
=
this
.
$store
.
state
.
queue
.
tracks
.
length
===
1
if
(
this
.
listeningRecorded
!=
this
.
currentTrack
)
{
if
(
this
.
listeningRecorded
!==
this
.
currentTrack
)
{
this
.
listeningRecorded
=
this
.
currentTrack
this
.
$store
.
dispatch
(
'
player/trackListened
'
,
this
.
currentTrack
)
}
...
...
@@ -509,10 +506,9 @@ export default {
}
else
{
this
.
next
()
// parenthesis where missing here
}
}
else
{
}
else
{
// seek left
le
t
position
=
Math
.
max
(
this
.
currentTime
+
step
,
0
)
cons
t
position
=
Math
.
max
(
this
.
currentTime
+
step
,
0
)
this
.
$store
.
dispatch
(
'
player/updateProgress
'
,
position
)
}
},
...
...
@@ -523,7 +519,7 @@ export default {
this
.
seek
(
-
5
)
},
observeProgress
:
function
(
enable
)
{
le
t
self
=
this
cons
t
self
=
this
if
(
enable
)
{
if
(
self
.
progressInterval
)
{
clearInterval
(
self
.
progressInterval
)
...
...
@@ -555,7 +551,7 @@ export default {
}
},
ended
:
function
()
{
le
t
onlyTrack
=
this
.
$store
.
state
.
queue
.
tracks
.
length
===
1
cons
t
onlyTrack
=
this
.
$store
.
state
.
queue
.
tracks
.
length
===
1
if
(
this
.
looping
===
1
||
(
onlyTrack
&&
this
.
looping
===
2
))
{
this
.
currentSound
.
seek
(
0
)
this
.
$store
.
dispatch
(
'
player/updateProgress
'
,
0
)
...
...
@@ -574,7 +570,7 @@ export default {
})[
0
]
},
addSoundToCache
(
sound
,
trackData
)
{
le
t
data
=
{
cons
t
data
=
{
date
:
new
Date
(),
track
:
trackData
,
sound
:
sound
...
...
@@ -583,20 +579,19 @@ export default {
this
.
checkCache
()
},
checkCache
()
{
le
t
self
=
this
le
t
toKeep
=
[]
cons
t
self
=
this
cons
t
toKeep
=
[]
_
.
reverse
(
this
.
soundsCache
).
forEach
((
e
)
=>
{
if
(
toKeep
.
length
<
self
.
maxPreloaded
)
{
toKeep
.
push
(
e
)
}
else
{
let
src
=
e
.
sound
.
_src
e
.
sound
.
unload
()
}
})
this
.
soundsCache
=
_
.
reverse
(
toKeep
)
},
removeFromCache
(
sound
)
{
le
t
toKeep
=
[]
cons
t
toKeep
=
[]
this
.
soundsCache
.
forEach
((
e
)
=>
{
if
(
e
.
sound
===
sound
)
{
e
.
sound
.
unload
()
...
...
@@ -608,7 +603,7 @@ export default {
},
async
loadSound
(
newValue
,
oldValue
)
{
let
trackData
=
newValue
le
t
oldSound
=
this
.
currentSound
cons
t
oldSound
=
this
.
currentSound
// stop all other sounds!
// we do this here (before the track has loaded) to get a predictable
// song order.
...
...
@@ -619,7 +614,7 @@ export default {
if
(
!
trackData
)
{
return
}
if
(
!
this
.
isShuffling
&&
trackData
!=
oldValue
)
{
if
(
!
this
.
isShuffling
&&
trackData
!=
=
oldValue
)
{
trackData
=
await
this
.
getTrackData
(
trackData
)
if
(
trackData
==
null
)
{
this
.
handleError
({})
...
...
@@ -645,16 +640,15 @@ export default {
this
.
$store
.
commit
(
'
ui/queueFocused
'
,
'
queue
'
)
}
else
{
this
.
$store
.
commit
(
'
ui/queueFocused
'
,
'
player
'
)
}
},
updateMetadata
()
{
// If the session is playing as a PWA, populate the notification
// with details from the track
if
(
this
.
currentTrack
&&
'
mediaSession
'
in
navigator
)
{
le
t
metadata
=
{
cons
t
metadata
=
{
title
:
this
.
currentTrack
.
title
,
artist
:
this
.
currentTrack
.
artist
.
name
,
artist
:
this
.
currentTrack
.
artist
.
name
}
if
(
this
.
currentTrack
.
album
&&
this
.
currentTrack
.
album
.
cover
)
{
metadata
.
album
=
this
.
currentTrack
.
album
.
title
...
...
@@ -664,10 +658,10 @@ export default {
{
src
:
this
.
currentTrack
.
album
.
cover
.
urls
.
original
,
sizes
:
'
192x192
'
,
type
:
'
image/png
'
},
{
src
:
this
.
currentTrack
.
album
.
cover
.
urls
.
original
,
sizes
:
'
256x256
'
,
type
:
'
image/png
'
},
{
src
:
this
.
currentTrack
.
album
.
cover
.
urls
.
original
,
sizes
:
'
384x384
'
,
type
:
'
image/png
'
},
{
src
:
this
.
currentTrack
.
album
.
cover
.
urls
.
original
,
sizes
:
'
512x512
'
,
type
:
'
image/png
'
}
,
{
src
:
this
.
currentTrack
.
album
.
cover
.
urls
.
original
,
sizes
:
'
512x512
'
,
type
:
'
image/png
'
}
]
}
navigator
.
mediaSession
.
metadata
=
new
MediaMetadata
(
metadata
)
navigator
.
mediaSession
.
metadata
=
new
window
.
MediaMetadata
(
metadata
)
}
}
},
...
...
@@ -685,38 +679,38 @@ export default {
queue
:
state
=>
state
.
queue
}),
...
mapGetters
({
currentTrack
:
"
queue/currentTrack
"
,
hasNext
:
"
queue/hasNext
"
,
hasPrevious
:
"
queue/hasPrevious
"
,
emptyQueue
:
"
queue/isEmpty
"
,
durationFormatted
:
"
player/durationFormatted
"
,
currentTimeFormatted
:
"
player/currentTimeFormatted
"
,
progress
:
"
player/progress
"
currentTrack
:
'
queue/currentTrack
'
,
hasNext
:
'
queue/hasNext
'
,
hasPrevious
:
'
queue/hasPrevious
'
,
emptyQueue
:
'
queue/isEmpty
'
,
durationFormatted
:
'
player/durationFormatted
'
,
currentTimeFormatted
:
'
player/currentTimeFormatted
'
,
progress
:
'
player/progress
'
}),
updateProgressThrottled
()
{
return
_
.
throttle
(
this
.
updateProgress
,
50
)
},
labels
()
{
le
t
audioPlayer
=
this
.
$pgettext
(
'
Sidebar/Player/Hidden text
'
,
"
Media player
"
)
le
t
previous
=
this
.
$pgettext
(
'
Sidebar/Player/Icon.Tooltip
'
,
"
Previous track
"
)
le
t
play
=
this
.
$pgettext
(
'
Sidebar/Player/Icon.Tooltip/Verb
'
,
"
Play
"
)
le
t
pause
=
this
.
$pgettext
(
'
Sidebar/Player/Icon.Tooltip/Verb
'
,
"
Pause
"
)
le
t
next
=
this
.
$pgettext
(
'
Sidebar/Player/Icon.Tooltip
'
,
"
Next track
"
)
le
t
unmute
=
this
.
$pgettext
(
'
Sidebar/Player/Icon.Tooltip/Verb
'
,
"
Unmute
"
)
le
t
mute
=
this
.
$pgettext
(
'
Sidebar/Player/Icon.Tooltip/Verb
'
,
"
Mute
"
)
le
t
expandQueue
=
this
.
$pgettext
(
'
Sidebar/Player/Icon.Tooltip/Verb
'
,
"
Expand queue
"
)
le
t
loopingDisabled
=
this
.
$pgettext
(
'
Sidebar/Player/Icon.Tooltip
'
,
"
Looping disabled. Click to switch to single-track looping.
"
cons
t
audioPlayer
=
this
.
$pgettext
(
'
Sidebar/Player/Hidden text
'
,
'
Media player
'
)
cons
t
previous
=
this
.
$pgettext
(
'
Sidebar/Player/Icon.Tooltip
'
,
'
Previous track
'
)
cons
t
play
=
this
.
$pgettext
(
'
Sidebar/Player/Icon.Tooltip/Verb
'
,
'
Play
'
)
cons
t
pause
=
this
.
$pgettext
(
'
Sidebar/Player/Icon.Tooltip/Verb
'
,
'
Pause
'
)
cons
t
next
=
this
.
$pgettext
(
'
Sidebar/Player/Icon.Tooltip
'
,
'
Next track
'
)
cons
t
unmute
=
this
.
$pgettext
(
'
Sidebar/Player/Icon.Tooltip/Verb
'
,
'
Unmute
'
)
cons
t
mute
=
this
.
$pgettext
(
'
Sidebar/Player/Icon.Tooltip/Verb
'
,
'
Mute
'
)
cons
t
expandQueue
=
this
.
$pgettext
(
'
Sidebar/Player/Icon.Tooltip/Verb
'
,
'
Expand queue
'
)
cons
t
loopingDisabled
=
this
.
$pgettext
(
'
Sidebar/Player/Icon.Tooltip
'
,
'
Looping disabled. Click to switch to single-track looping.
'
)
le
t
loopingSingle
=
this
.
$pgettext
(
'
Sidebar/Player/Icon.Tooltip
'
,
"
Looping on a single track. Click to switch to whole queue looping.
"
cons
t
loopingSingle
=
this
.
$pgettext
(
'
Sidebar/Player/Icon.Tooltip
'
,
'
Looping on a single track. Click to switch to whole queue looping.
'
)
le
t
loopingWhole
=
this
.
$pgettext
(
'
Sidebar/Player/Icon.Tooltip
'
,
"
Looping on whole queue. Click to disable looping.
"
cons
t
loopingWhole
=
this
.
$pgettext
(
'
Sidebar/Player/Icon.Tooltip
'
,
'
Looping on whole queue. Click to disable looping.
'
)
le
t
shuffle
=
this
.
$pgettext
(
'
Sidebar/Player/Icon.Tooltip/Verb
'
,
"
Shuffle your queue
"
)
le
t
clear
=
this
.
$pgettext
(
'
Sidebar/Player/Icon.Tooltip/Verb
'
,
"
Clear your queue
"
)
le
t
addArtistContentFilter
=
this
.
$pgettext
(
'
Sidebar/Player/Icon.Tooltip/Verb
'
,
'
Hide content from this artist…
'
)
cons
t
shuffle
=
this
.
$pgettext
(
'
Sidebar/Player/Icon.Tooltip/Verb
'
,
'
Shuffle your queue
'
)
cons
t
clear
=
this
.
$pgettext
(
'
Sidebar/Player/Icon.Tooltip/Verb
'
,
'
Clear your queue
'
)
cons
t
addArtistContentFilter
=
this
.
$pgettext
(
'
Sidebar/Player/Icon.Tooltip/Verb
'
,
'
Hide content from this artist…
'
)
return
{
audioPlayer
,
previous
,
...
...
@@ -731,9 +725,9 @@ export default {
shuffle
,
clear
,
expandQueue
,
addArtistContentFilter
,
addArtistContentFilter
}
}
},
},
watch
:
{
currentTrack
:
{
...
...
@@ -746,10 +740,10 @@ export default {
if
(
this
.
currentSound
)
{
this
.
currentSound
.
pause
()
}
this
.
$store
.
commit
(
"
player/isLoadingAudio
"
,
true
)
this
.
$store
.
commit
(
'
player/isLoadingAudio
'
,
true
)
this
.
playTimeout
=
setTimeout
(
async
()
=>
{
await
this
.
loadSound
(
newValue
,
oldValue
)
},
100
)
;
},
100
)
this
.
updateMetadata
()
},
immediate
:
false
...
...
@@ -759,10 +753,10 @@ export default {
handler
(
newValue
)
{
this
.
sliderVolume
=
newValue
Howler
.
volume
(
toLinearVolumeScale
(
newValue
))
}
,
}
},
sliderVolume
(
newValue
)
{
this
.
$store
.
commit
(
"
player/volume
"
,
newValue
)
this
.
$store
.
commit
(
'
player/volume
'
,
newValue
)
},
playing
:
async
function
(
newValue
)
{
if
(
this
.
currentSound
)
{
...
...
This diff is collapsed.
Click to expand it.
front/src/store/player.js
+
20
−
21
View file @
5a74d1d3
...
...
@@ -126,8 +126,7 @@ export default {
if
(
state
.
volume
>
0
)
{
commit
(
'
tempVolume
'
,
state
.
volume
)
commit
(
'
volume
'
,
0
)
}
else
{
}
else
{
commit
(
'
volume
'
,
state
.
tempVolume
)
}
},
...
...
@@ -135,12 +134,12 @@ export default {
if
(
!
rootState
.
auth
.
authenticated
)
{
return
}
return
axios
.
post
(
'
history/listenings/
'
,
{
'
track
'
:
track
.
id
}).
then
((
response
)
=>
{},
(
response
)
=>
{
return
axios
.
post
(
'
history/listenings/
'
,
{
track
:
track
.
id
}).
then
((
response
)
=>
{},
(
response
)
=>
{
logger
.
default
.
error
(
'
Could not record track in history
'
)
})
},
trackEnded
({
commit
,
dispatch
,
rootState
},
track
)
{
le
t
queueState
=
rootState
.
queue
cons
t
queueState
=
rootState
.
queue
if
(
queueState
.
currentIndex
===
queueState
.
tracks
.
length
-
1
)
{
// we've reached last track of queue, trigger a reload
// from radio if any
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment