From f4365f68c298f521f9895e41bb8f801db40c7834 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ciar=C3=A1n=20Ainsworth?= <ciaranainsworth@posteo.net> Date: Tue, 25 Jun 2019 17:48:01 +0200 Subject: [PATCH] Resolve "Add new keyboard shortcuts" --- changes/changelog.d/866.enhancement | 1 + front/src/components/ShortcutsModal.vue | 109 ++++++++++++++++++----- front/src/components/audio/Player.vue | 31 ++++++- front/src/components/audio/SearchBar.vue | 14 ++- front/src/store/player.js | 9 ++ 5 files changed, 137 insertions(+), 27 deletions(-) create mode 100644 changes/changelog.d/866.enhancement diff --git a/changes/changelog.d/866.enhancement b/changes/changelog.d/866.enhancement new file mode 100644 index 0000000000..9ebbd52ddd --- /dev/null +++ b/changes/changelog.d/866.enhancement @@ -0,0 +1 @@ +New keyboard shortcuts added for enhanced control over audio player (#866) \ No newline at end of file diff --git a/front/src/components/ShortcutsModal.vue b/front/src/components/ShortcutsModal.vue index 5b1a7349d4..06fb25ba4b 100644 --- a/front/src/components/ShortcutsModal.vue +++ b/front/src/components/ShortcutsModal.vue @@ -4,18 +4,36 @@ <translate translate-context="*/*/*/Noun">Keyboard shortcuts</translate> </header> <section class="scrolling content"> - <table - class="ui compact collapsing basic table" - v-for="section in sections" - :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 class="ui stackable two column grid"> + <div class="column"> + <table + class="ui compact basic table" + v-for="section in player" + :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 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> <footer class="actions"> <div class="ui cancel button"><translate translate-context="Popup/Keyboard shortcuts/Button.Label/Verb">Close</translate></div> @@ -32,7 +50,7 @@ export default { Modal, }, computed: { - sections () { + general () { return [ { title: this.$pgettext('Popup/Keyboard shortcuts/Title', 'General shortcuts'), @@ -40,17 +58,36 @@ export default { { key: 'h', 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" - // ctrl.left.prevent.exact="previous" - // ctrl.right.prevent.exact="next" - // ctrl.down.prevent.exact="$store.commit('player/incrementVolume', -0.1)" - // ctrl.up.prevent.exact="$store.commit('player/incrementVolume', 0.1)" + // ctrl.shift.left.prevent.exact="previous" + // ctrl.shift.right.prevent.exact="next" + // shift.down.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')" // 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'), shortcuts: [ @@ -59,21 +96,41 @@ export default { 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') }, { - key: 'ctrl right', + key: 'ctrl + shift + right', 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') }, { - key: 'ctrl down', + key: 'shift + down', 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', summary: this.$pgettext('Popup/Keyboard shortcuts/Table.Label/Verb', 'Toggle queue looping') @@ -82,6 +139,14 @@ export default { key: 's', 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') + }, ] } ] diff --git a/front/src/components/audio/Player.vue b/front/src/components/audio/Player.vue index 8faaf670c0..032be232de 100644 --- a/front/src/components/audio/Player.vue +++ b/front/src/components/audio/Player.vue @@ -206,12 +206,19 @@ </div> <GlobalEvents @keydown.space.prevent.exact="togglePlay" - @keydown.ctrl.left.prevent.exact="previous" - @keydown.ctrl.right.prevent.exact="next" - @keydown.ctrl.down.prevent.exact="$store.commit('player/incrementVolume', -0.1)" - @keydown.ctrl.up.prevent.exact="$store.commit('player/incrementVolume', 0.1)" + @keydown.ctrl.shift.left.prevent.exact="previous" + @keydown.ctrl.shift.right.prevent.exact="next" + @keydown.shift.down.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.s.prevent.exact="shuffle" + @keydown.f.prevent.exact="$store.dispatch('favorites/toggle', currentTrack.id)" + @keydown.q.prevent.exact="clean" /> </div> </section> @@ -294,6 +301,7 @@ export default { mute: "player/mute", unmute: "player/unmute", clean: "queue/clean", + toggleMute: "player/toggleMute", }), async getTrackData (trackData) { 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) { let self = this if (enable) { diff --git a/front/src/components/audio/SearchBar.vue b/front/src/components/audio/SearchBar.vue index 28b11b040d..998a668ecc 100644 --- a/front/src/components/audio/SearchBar.vue +++ b/front/src/components/audio/SearchBar.vue @@ -1,19 +1,26 @@ <template> <div class="ui fluid category search"> <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> </div> <div class="results"></div> <slot name="after"></slot> + <GlobalEvents + @keydown.shift.f.prevent.exact="focusSearch" + /> </div> </template> <script> import jQuery from 'jquery' import router from '@/router' +import GlobalEvents from "@/components/utils/global-events" export default { + components: { + GlobalEvents, + }, computed: { labels () { return { @@ -104,6 +111,11 @@ export default { url: this.$store.getters['instance/absoluteUrl']('api/v1/search?query={query}') } }) + }, + methods: { + focusSearch () { + this.$refs.search.focus() + }, } } </script> diff --git a/front/src/store/player.js b/front/src/store/player.js index fac17368d1..6757f0beef 100644 --- a/front/src/store/player.js +++ b/front/src/store/player.js @@ -109,6 +109,15 @@ export default { }, 3000) } }, + toggleMute({commit, state}) { + if (state.volume > 0) { + commit('tempVolume', state.volume) + commit('volume', 0) + } + else { + commit('volume', state.tempVolume) + } + }, trackListened ({commit, rootState}, track) { if (!rootState.auth.authenticated) { return -- GitLab