From d9c591b0ea6b8b8cf1b6f46fed525b3ca1c33d2d Mon Sep 17 00:00:00 2001 From: Benjamin Porter Date: Mon, 29 Dec 2025 12:55:18 -0700 Subject: [PATCH] Expand time interval options for Make jump controls Fixes #1445 - Added additional options for customizing jump forward/backward. Instead of just 5, 10, and 30 seconds, we now have 5s, 10s, 15s, 30s, 60s, 2m, and 5m. - Switched the jump interval to a list in the settings menu for better UX - Reordered "Disable auto rewind time" for aesthetics in settings menu (it looked out of place after backwards time and forwards time were turned to dropdowns The only downside of this (afaict), and what created the biggest challenge, is the lack of numeric glyphs in the Material Symbols font. They only have 5, 10, and 30, which we were previously using. Given that they don't have others, that means we had to change strategies for displaying. I switched all to generic backward and forward icons and added the time interval as a label next to it so the user can still tell at a glance what the setting is. For consistency we don't use the numbered glyphs anymore. For more info on the Material Symbols font, see: https://fonts.google.com/icons?icon.query=forward However this does feel like two steps forward, one step back, though I can't think of good options. Other possibility would be to create SVGs, though I'm not skilled enough to do that. Personally this feels like a good compromise, but others will probably differ. I considered using the numbered glyphs when the selected value was 5, 10, or 30, but when testing I found the inconsistency jarring and kind of janky. --- components/app/AudioPlayer.vue | 24 ++++++--- pages/settings.vue | 91 ++++++++++++++++++++++++---------- store/globals.js | 64 +++++++++++++++++++++--- 3 files changed, 139 insertions(+), 40 deletions(-) diff --git a/components/app/AudioPlayer.vue b/components/app/AudioPlayer.vue index 9c4c8a85..d4e1d5b3 100644 --- a/components/app/AudioPlayer.vue +++ b/components/app/AudioPlayer.vue @@ -70,14 +70,20 @@
first_page - {{ jumpBackwardsIcon }} +
+ {{ jumpBackwardsItem.icon }} + {{ jumpBackwardsItem.label }} +
{{ seekLoading ? 'autorenew' : !isPlaying ? 'play_arrow' : 'pause' }}
- {{ jumpForwardIcon }} +
+ {{ jumpForwardItem.icon }} + {{ jumpForwardItem.label }} +
last_page
@@ -221,11 +227,11 @@ export default { return items }, - jumpForwardIcon() { - return this.$store.getters['globals/getJumpForwardIcon'](this.jumpForwardTime) + jumpForwardItem() { + return this.$store.getters['globals/getJumpForwardItem'](this.jumpForwardTime) }, - jumpBackwardsIcon() { - return this.$store.getters['globals/getJumpBackwardsIcon'](this.jumpBackwardsTime) + jumpBackwardsItem() { + return this.$store.getters['globals/getJumpBackwardsItem'](this.jumpBackwardsTime) }, jumpForwardTime() { return this.$store.getters['getJumpForwardTime'] @@ -1080,8 +1086,10 @@ export default { #playerControls { transition: all 0.15s cubic-bezier(0.39, 0.575, 0.565, 1); transition-property: width, bottom; - width: 128px; - padding-right: 24px; + width: auto; + min-width: 150px; + padding-left: 8px; + padding-right: 8px; bottom: 70px; } #playerControls .jump-icon { diff --git a/pages/settings.vue b/pages/settings.vue index 63357548..05ffc376 100644 --- a/pages/settings.vue +++ b/pages/settings.vue @@ -36,24 +36,24 @@

{{ $strings.HeaderPlaybackSettings }}

+
+

{{ $strings.LabelJumpBackwardsTime }}

+
+ +
+
+
+

{{ $strings.LabelJumpForwardsTime }}

+
+ +
+

{{ $strings.LabelDisableAutoRewind }}

-
-
- {{ currentJumpBackwardsTimeIcon }} -
-

{{ $strings.LabelJumpBackwardsTime }}

-
-
-
- {{ currentJumpForwardTimeIcon }} -
-

{{ $strings.LabelJumpForwardsTime }}

-
@@ -179,7 +179,7 @@
- +
@@ -361,6 +361,12 @@ export default { languageOptionItems() { return this.$languageCodeOptions || [] }, + jumpForwardOption() { + return this.currentJumpForwardItem.label || '' + }, + jumpBackwardsOption() { + return this.currentJumpBackwardsItem.label || '' + }, themeOptionItems() { return [ { @@ -378,19 +384,25 @@ export default { ] }, currentJumpForwardTimeIcon() { - return this.jumpForwardItems[this.currentJumpForwardTimeIndex].icon + return this.currentJumpForwardItem.icon }, currentJumpForwardTimeIndex() { var index = this.jumpForwardItems.findIndex((jfi) => jfi.value === this.settings.jumpForwardTime) return index >= 0 ? index : 1 }, + currentJumpForwardItem() { + return this.jumpForwardItems[this.currentJumpForwardTimeIndex] || this.jumpForwardItems[0] || {} + }, currentJumpBackwardsTimeIcon() { - return this.jumpBackwardsItems[this.currentJumpBackwardsTimeIndex].icon + return this.currentJumpBackwardsItem.icon }, currentJumpBackwardsTimeIndex() { var index = this.jumpBackwardsItems.findIndex((jfi) => jfi.value === this.settings.jumpBackwardsTime) return index >= 0 ? index : 1 }, + currentJumpBackwardsItem() { + return this.jumpBackwardsItems[this.currentJumpBackwardsTimeIndex] || this.jumpBackwardsItems[0] || {} + }, shakeSensitivityOption() { const item = this.shakeSensitivityItems.find((i) => i.value === this.settings.shakeSensitivity) return item?.text || 'Error' @@ -434,7 +446,31 @@ export default { else if (this.moreMenuSetting === 'downloadUsingCellular') return this.downloadUsingCellularItems else if (this.moreMenuSetting === 'streamingUsingCellular') return this.streamingUsingCellularItems else if (this.moreMenuSetting === 'androidAutoBrowseSeriesSequenceOrder') return this.androidAutoBrowseSeriesSequenceOrderItems + else if (this.moreMenuSetting === 'jumpForward') + return this.jumpForwardItems.map((i) => ({ + text: i.label, + value: i.value, + icon: i.icon + })) + else if (this.moreMenuSetting === 'jumpBackwards') + return this.jumpBackwardsItems.map((i) => ({ + text: i.label, + value: i.value, + icon: i.icon + })) return [] + }, + moreMenuSelected() { + if (this.moreMenuSetting === 'jumpForward') return this.settings.jumpForwardTime + if (this.moreMenuSetting === 'jumpBackwards') return this.settings.jumpBackwardsTime + if (this.moreMenuSetting === 'language') return this.settings.languageCode + if (this.moreMenuSetting === 'theme') return this.theme + if (this.moreMenuSetting === 'downloadUsingCellular') return this.settings.downloadUsingCellular + if (this.moreMenuSetting === 'streamingUsingCellular') return this.settings.streamingUsingCellular + if (this.moreMenuSetting === 'androidAutoBrowseSeriesSequenceOrder') return this.settings.androidAutoBrowseSeriesSequenceOrder + if (this.moreMenuSetting === 'shakeSensitivity') return this.settings.shakeSensitivity + if (this.moreMenuSetting === 'hapticFeedback') return this.settings.hapticFeedback + return null } }, methods: { @@ -468,6 +504,14 @@ export default { this.moreMenuSetting = 'theme' this.showMoreMenuDialog = true }, + showJumpForwardOptions() { + this.moreMenuSetting = 'jumpForward' + this.showMoreMenuDialog = true + }, + showJumpBackwardsOptions() { + this.moreMenuSetting = 'jumpBackwards' + this.showMoreMenuDialog = true + }, showDownloadUsingCellularOptions() { this.moreMenuSetting = 'downloadUsingCellular' this.showMoreMenuDialog = true @@ -503,6 +547,12 @@ export default { } else if (this.moreMenuSetting === 'androidAutoBrowseSeriesSequenceOrder') { this.settings.androidAutoBrowseSeriesSequenceOrder = action this.saveSettings() + } else if (this.moreMenuSetting === 'jumpForward') { + this.settings.jumpForwardTime = action + this.saveSettings() + } else if (this.moreMenuSetting === 'jumpBackwards') { + this.settings.jumpBackwardsTime = action + this.saveSettings() } }, saveTheme(theme) { @@ -598,17 +648,6 @@ export default { this.$setOrientationLock(this.settings.lockOrientation) this.saveSettings() }, - toggleJumpForward() { - var next = (this.currentJumpForwardTimeIndex + 1) % 3 - this.settings.jumpForwardTime = this.jumpForwardItems[next].value - this.saveSettings() - }, - toggleJumpBackwards() { - var next = (this.currentJumpBackwardsTimeIndex + 4) % 3 - if (next > 2) return - this.settings.jumpBackwardsTime = this.jumpBackwardsItems[next].value - this.saveSettings() - }, async saveSettings() { await this.$hapticsImpact() const updatedDeviceData = await this.$db.updateDeviceSettings({ ...this.settings }) diff --git a/store/globals.js b/store/globals.js index d33a693a..ae281081 100644 --- a/store/globals.js +++ b/store/globals.js @@ -7,30 +7,76 @@ export const state = () => ({ lastSearch: null, jumpForwardItems: [ { - icon: 'forward_5', + icon: 'forward_media', + label: '5s', value: 5 }, { - icon: 'forward_10', + icon: 'forward_media', + label: '10s', value: 10 }, { - icon: 'forward_30', + icon: 'forward_media', + label: '15s', + value: 15 + }, + { + icon: 'forward_media', + label: '30s', value: 30 + }, + { + icon: 'forward_media', + label: '60s', + value: 60 + }, + { + icon: 'forward_media', + label: '2m', + value: 120 + }, + { + icon: 'forward_media', + label: '5m', + value: 300 } ], jumpBackwardsItems: [ { - icon: 'replay_5', + icon: 'replay', + label: '5s', value: 5 }, { - icon: 'replay_10', + icon: 'replay', + label: '10s', value: 10 }, { - icon: 'replay_30', + icon: 'replay', + label: '15s', + value: 15 + }, + { + icon: 'replay', + label: '30s', value: 30 + }, + { + icon: 'replay', + label: '60s', + value: 60 + }, + { + icon: 'replay', + label: '2m', + value: 120 + }, + { + icon: 'replay', + label: '5m', + value: 300 } ], libraryIcons: ['database', 'audiobookshelf', 'books-1', 'books-2', 'book-1', 'microphone-1', 'microphone-3', 'radio', 'podcast', 'rss', 'headphones', 'music', 'file-picture', 'rocket', 'power', 'star', 'heart'], @@ -119,6 +165,12 @@ export const getters = { getJumpBackwardsIcon: (state) => (jumpBackwardsTime) => { const item = state.jumpBackwardsItems.find((i) => i.value == jumpBackwardsTime) return item ? item.icon : 'replay_10' + }, + getJumpForwardItem: (state) => (jumpForwardTime) => { + return state.jumpForwardItems.find((i) => i.value == jumpForwardTime) || state.jumpForwardItems[1] + }, + getJumpBackwardsItem: (state) => (jumpBackwardsTime) => { + return state.jumpBackwardsItems.find((i) => i.value == jumpBackwardsTime) || state.jumpBackwardsItems[1] } }