Resolve "Add new keyboard shortcuts"

This commit is contained in:
Ciarán Ainsworth 2019-06-25 17:48:01 +02:00
parent dc26da8874
commit f4365f68c2
5 changed files with 137 additions and 27 deletions

View File

@ -0,0 +1 @@
New keyboard shortcuts added for enhanced control over audio player (#866)

View File

@ -4,9 +4,11 @@
<translate translate-context="*/*/*/Noun">Keyboard shortcuts</translate> <translate translate-context="*/*/*/Noun">Keyboard shortcuts</translate>
</header> </header>
<section class="scrolling content"> <section class="scrolling content">
<div class="ui stackable two column grid">
<div class="column">
<table <table
class="ui compact collapsing basic table" class="ui compact basic table"
v-for="section in sections" v-for="section in player"
:key="section.title"> :key="section.title">
<caption>{{ section.title }}</caption> <caption>{{ section.title }}</caption>
<tbody> <tbody>
@ -16,6 +18,22 @@
</tr> </tr>
</tbody> </tbody>
</table> </table>
</div>
<div class="column">
<table
class="ui compact basic table"
v-for="section in general"
:key="section.title">
<caption>{{ section.title }}</caption>
<tbody>
<tr v-for="shortcut in section.shortcuts" :key="shortcut.summary">
<td>{{ shortcut.summary }}</td>
<td><span class="ui label">{{ shortcut.key }}</span></td>
</tr>
</tbody>
</table>
</div>
</div>
</section> </section>
<footer class="actions"> <footer class="actions">
<div class="ui cancel button"><translate translate-context="Popup/Keyboard shortcuts/Button.Label/Verb">Close</translate></div> <div class="ui cancel button"><translate translate-context="Popup/Keyboard shortcuts/Button.Label/Verb">Close</translate></div>
@ -32,7 +50,7 @@ export default {
Modal, Modal,
}, },
computed: { computed: {
sections () { general () {
return [ return [
{ {
title: this.$pgettext('Popup/Keyboard shortcuts/Title', 'General shortcuts'), title: this.$pgettext('Popup/Keyboard shortcuts/Title', 'General shortcuts'),
@ -40,17 +58,36 @@ export default {
{ {
key: 'h', key: 'h',
summary: this.$pgettext('Popup/Keyboard shortcuts/Table.Label/Verb', 'Show available keyboard shortcuts') summary: this.$pgettext('Popup/Keyboard shortcuts/Table.Label/Verb', 'Show available keyboard shortcuts')
} },
{
key: 'shift + f',
summary: this.$pgettext('Popup/Keyboard shortcuts/Table.Label/Verb', 'Focus searchbar')
},
{
key: 'esc',
summary: this.$pgettext('Popup/Keyboard shortcuts/Table.Label/Verb', 'Unfocus searchbar')
},
]
},
] ]
}, },
// space.prevent.exact="togglePlay" // space.prevent.exact="togglePlay"
// ctrl.left.prevent.exact="previous" // ctrl.shift.left.prevent.exact="previous"
// ctrl.right.prevent.exact="next" // ctrl.shift.right.prevent.exact="next"
// ctrl.down.prevent.exact="$store.commit('player/incrementVolume', -0.1)" // shift.down.prevent.exact="$store.commit('player/incrementVolume', -0.1)"
// ctrl.up.prevent.exact="$store.commit('player/incrementVolume', 0.1)" // shift.up.prevent.exact="$store.commit('player/incrementVolume', 0.1)"
// right.prevent.exact="seek (5)"
// left.prevent.exact="seek (-5)"
// shift.right.prevent.exact="seek (30)"
// shift.left.prevent.exact="seek (-30)"
// m.prevent.exact="toggleMute"
// l.prevent.exact="$store.commit('player/toggleLooping')" // l.prevent.exact="$store.commit('player/toggleLooping')"
// s.prevent.exact="shuffle" // s.prevent.exact="shuffle"
// f.prevent.exact="$store.dispatch('favorites/toggle', currentTrack.id)"
// q.prevent.exact="clean"
player () {
return [
{ {
title: this.$pgettext('Popup/Keyboard shortcuts/Title', 'Audio player shortcuts'), title: this.$pgettext('Popup/Keyboard shortcuts/Title', 'Audio player shortcuts'),
shortcuts: [ shortcuts: [
@ -59,21 +96,41 @@ export default {
summary: this.$pgettext('Popup/Keyboard shortcuts/Table.Label/Verb', 'Pause/play the current track') summary: this.$pgettext('Popup/Keyboard shortcuts/Table.Label/Verb', 'Pause/play the current track')
}, },
{ {
key: 'ctrl left', key: 'left',
summary: this.$pgettext('Popup/Keyboard shortcuts/Table.Label/Verb', 'Seek backwards 5s')
},
{
key: 'right',
summary: this.$pgettext('Popup/Keyboard shortcuts/Table.Label/Verb', 'Seek forwards 5s')
},
{
key: 'shift + left',
summary: this.$pgettext('Popup/Keyboard shortcuts/Table.Label/Verb', 'Seek backwards 30s')
},
{
key: 'shift + right',
summary: this.$pgettext('Popup/Keyboard shortcuts/Table.Label/Verb', 'Seek forwards 30s')
},
{
key: 'ctrl + shift + left',
summary: this.$pgettext('Popup/Keyboard shortcuts/Table.Label/Verb', 'Play previous track') summary: this.$pgettext('Popup/Keyboard shortcuts/Table.Label/Verb', 'Play previous track')
}, },
{ {
key: 'ctrl right', key: 'ctrl + shift + right',
summary: this.$pgettext('Popup/Keyboard shortcuts/Table.Label/Verb', 'Play next track') summary: this.$pgettext('Popup/Keyboard shortcuts/Table.Label/Verb', 'Play next track')
}, },
{ {
key: 'ctrl up', key: 'shift + up',
summary: this.$pgettext('Popup/Keyboard shortcuts/Table.Label/Verb', 'Increase volume') summary: this.$pgettext('Popup/Keyboard shortcuts/Table.Label/Verb', 'Increase volume')
}, },
{ {
key: 'ctrl down', key: 'shift + down',
summary: this.$pgettext('Popup/Keyboard shortcuts/Table.Label/Verb', 'Decrease volume') summary: this.$pgettext('Popup/Keyboard shortcuts/Table.Label/Verb', 'Decrease volume')
}, },
{
key: 'm',
summary: this.$pgettext('Popup/Keyboard shortcuts/Table.Label/Verb', 'Toggle mute')
},
{ {
key: 'l', key: 'l',
summary: this.$pgettext('Popup/Keyboard shortcuts/Table.Label/Verb', 'Toggle queue looping') summary: this.$pgettext('Popup/Keyboard shortcuts/Table.Label/Verb', 'Toggle queue looping')
@ -82,6 +139,14 @@ export default {
key: 's', key: 's',
summary: this.$pgettext('Popup/Keyboard shortcuts/Table.Label/Verb', 'Shuffle queue') summary: this.$pgettext('Popup/Keyboard shortcuts/Table.Label/Verb', 'Shuffle queue')
}, },
{
key: 'q',
summary: this.$pgettext('Popup/Keyboard shortcuts/Table.Label/Verb', 'Clear queue')
},
{
key: 'f',
summary: this.$pgettext('Popup/Keyboard shortcuts/Table.Label/Verb', 'Toggle favorite')
},
] ]
} }
] ]

View File

@ -206,12 +206,19 @@
</div> </div>
<GlobalEvents <GlobalEvents
@keydown.space.prevent.exact="togglePlay" @keydown.space.prevent.exact="togglePlay"
@keydown.ctrl.left.prevent.exact="previous" @keydown.ctrl.shift.left.prevent.exact="previous"
@keydown.ctrl.right.prevent.exact="next" @keydown.ctrl.shift.right.prevent.exact="next"
@keydown.ctrl.down.prevent.exact="$store.commit('player/incrementVolume', -0.1)" @keydown.shift.down.prevent.exact="$store.commit('player/incrementVolume', -0.1)"
@keydown.ctrl.up.prevent.exact="$store.commit('player/incrementVolume', 0.1)" @keydown.shift.up.prevent.exact="$store.commit('player/incrementVolume', 0.1)"
@keydown.right.prevent.exact="seek (5)"
@keydown.left.prevent.exact="seek (-5)"
@keydown.shift.right.prevent.exact="seek (30)"
@keydown.shift.left.prevent.exact="seek (-30)"
@keydown.m.prevent.exact="toggleMute"
@keydown.l.prevent.exact="$store.commit('player/toggleLooping')" @keydown.l.prevent.exact="$store.commit('player/toggleLooping')"
@keydown.s.prevent.exact="shuffle" @keydown.s.prevent.exact="shuffle"
@keydown.f.prevent.exact="$store.dispatch('favorites/toggle', currentTrack.id)"
@keydown.q.prevent.exact="clean"
/> />
</div> </div>
</section> </section>
@ -294,6 +301,7 @@ export default {
mute: "player/mute", mute: "player/mute",
unmute: "player/unmute", unmute: "player/unmute",
clean: "queue/clean", clean: "queue/clean",
toggleMute: "player/toggleMute",
}), }),
async getTrackData (trackData) { async getTrackData (trackData) {
let data = null let data = null
@ -489,6 +497,21 @@ export default {
} }
} }
}, },
seek (step) {
if (step > 0) {
// seek right
if (this.currentTime + step < this.duration) {
this.$store.dispatch('player/updateProgress', (this.currentTime + step))
} else {
this.next() // parenthesis where missing here
}
}
else {
// seek left
let position = Math.max(this.currentTime + step, 0)
this.$store.dispatch('player/updateProgress', position)
}
},
observeProgress: function (enable) { observeProgress: function (enable) {
let self = this let self = this
if (enable) { if (enable) {

View File

@ -1,19 +1,26 @@
<template> <template>
<div class="ui fluid category search"> <div class="ui fluid category search">
<slot></slot><div class="ui icon input"> <slot></slot><div class="ui icon input">
<input class="prompt" name="search" :placeholder="labels.placeholder" type="text"> <input class="prompt" ref="search" name="search" :placeholder="labels.placeholder" type="text" @keydown.esc="$event.target.blur()">
<i class="search icon"></i> <i class="search icon"></i>
</div> </div>
<div class="results"></div> <div class="results"></div>
<slot name="after"></slot> <slot name="after"></slot>
<GlobalEvents
@keydown.shift.f.prevent.exact="focusSearch"
/>
</div> </div>
</template> </template>
<script> <script>
import jQuery from 'jquery' import jQuery from 'jquery'
import router from '@/router' import router from '@/router'
import GlobalEvents from "@/components/utils/global-events"
export default { export default {
components: {
GlobalEvents,
},
computed: { computed: {
labels () { labels () {
return { return {
@ -104,6 +111,11 @@ export default {
url: this.$store.getters['instance/absoluteUrl']('api/v1/search?query={query}') url: this.$store.getters['instance/absoluteUrl']('api/v1/search?query={query}')
} }
}) })
},
methods: {
focusSearch () {
this.$refs.search.focus()
},
} }
} }
</script> </script>

View File

@ -109,6 +109,15 @@ export default {
}, 3000) }, 3000)
} }
}, },
toggleMute({commit, state}) {
if (state.volume > 0) {
commit('tempVolume', state.volume)
commit('volume', 0)
}
else {
commit('volume', state.tempVolume)
}
},
trackListened ({commit, rootState}, track) { trackListened ({commit, rootState}, track) {
if (!rootState.auth.authenticated) { if (!rootState.auth.authenticated) {
return return