mirror of
https://github.com/advplyr/audiobookshelf-app.git
synced 2026-08-06 20:08:48 +02:00
Merge pull request #1767 from FreedomBen/add-more-backwards-forward-options
Expand time interval options for jump controls
This commit is contained in:
@@ -70,14 +70,20 @@
|
||||
<div id="playerControls" class="absolute right-0 bottom-0 mx-auto" style="max-width: 414px">
|
||||
<div class="flex items-center max-w-full" :class="playerSettings.lockUi ? 'justify-center' : 'justify-between'">
|
||||
<span v-show="showFullscreen && !playerSettings.lockUi" class="material-symbols next-icon text-fg cursor-pointer" :class="isLoading ? 'text-opacity-10' : 'text-opacity-75'" @click.stop="jumpChapterStart">first_page</span>
|
||||
<span v-show="!playerSettings.lockUi" class="material-symbols jump-icon text-fg cursor-pointer" :class="isLoading ? 'text-opacity-10' : 'text-opacity-75'" @click.stop="jumpBackwards">{{ jumpBackwardsIcon }}</span>
|
||||
<div v-show="!playerSettings.lockUi" class="jump-icon text-fg cursor-pointer flex flex-col items-center" :class="isLoading ? 'text-opacity-10' : 'text-opacity-75'" @click.stop="jumpBackwards">
|
||||
<span class="material-symbols text-3xl leading-none">replay</span>
|
||||
<span v-if="showFullscreen" class="jump-label text-[10px] font-semibold leading-tight">{{ jumpBackwardsLabel }}</span>
|
||||
</div>
|
||||
<div class="play-btn cursor-pointer shadow-sm flex items-center justify-center rounded-full text-primary mx-4 relative overflow-hidden" :style="{ backgroundColor: coverRgb }" :class="{ 'animate-spin': seekLoading }" @mousedown.prevent @mouseup.prevent @click.stop="playPauseClick">
|
||||
<div v-if="!coverBgIsLight" class="absolute top-0 left-0 w-full h-full bg-white bg-opacity-20 pointer-events-none" />
|
||||
|
||||
<span v-if="!isLoading" class="material-symbols fill" :class="{ 'text-white': coverRgb && !coverBgIsLight }">{{ seekLoading ? 'autorenew' : !isPlaying ? 'play_arrow' : 'pause' }}</span>
|
||||
<widgets-spinner-icon v-else class="h-8 w-8" />
|
||||
</div>
|
||||
<span v-show="!playerSettings.lockUi" class="material-symbols jump-icon text-fg cursor-pointer" :class="isLoading ? 'text-opacity-10' : 'text-opacity-75'" @click.stop="jumpForward">{{ jumpForwardIcon }}</span>
|
||||
<div v-show="!playerSettings.lockUi" class="jump-icon text-fg cursor-pointer flex flex-col items-center" :class="isLoading ? 'text-opacity-10' : 'text-opacity-75'" @click.stop="jumpForward">
|
||||
<span class="material-symbols text-3xl leading-none">forward_media</span>
|
||||
<span v-if="showFullscreen" class="jump-label text-[10px] font-semibold leading-tight">{{ jumpForwardLabel }}</span>
|
||||
</div>
|
||||
<span v-show="showFullscreen && !playerSettings.lockUi" class="material-symbols next-icon text-fg cursor-pointer" :class="nextChapter && !isLoading ? 'text-opacity-75' : 'text-opacity-10'" @click.stop="jumpNextChapter">last_page</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -110,6 +116,7 @@ import { AbsAudioPlayer } from '@/plugins/capacitor'
|
||||
import { Dialog } from '@capacitor/dialog'
|
||||
import { FastAverageColor } from 'fast-average-color'
|
||||
import WrappingMarquee from '@/assets/WrappingMarquee.js'
|
||||
import jumpLabelMixin from '@/mixins/jumpLabel'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
@@ -121,6 +128,7 @@ export default {
|
||||
sleepTimeRemaining: Number,
|
||||
serverLibraryItemId: String
|
||||
},
|
||||
mixins: [jumpLabelMixin],
|
||||
data() {
|
||||
return {
|
||||
windowHeight: 0,
|
||||
@@ -221,11 +229,11 @@ export default {
|
||||
|
||||
return items
|
||||
},
|
||||
jumpForwardIcon() {
|
||||
return this.$store.getters['globals/getJumpForwardIcon'](this.jumpForwardTime)
|
||||
jumpForwardLabel() {
|
||||
return this.getJumpLabel(this.jumpForwardTime)
|
||||
},
|
||||
jumpBackwardsIcon() {
|
||||
return this.$store.getters['globals/getJumpBackwardsIcon'](this.jumpBackwardsTime)
|
||||
jumpBackwardsLabel() {
|
||||
return this.getJumpLabel(this.jumpBackwardsTime)
|
||||
},
|
||||
jumpForwardTime() {
|
||||
return this.$store.getters['getJumpForwardTime']
|
||||
@@ -1091,6 +1099,9 @@ export default {
|
||||
margin: 0px 0px;
|
||||
font-size: 1.6rem;
|
||||
}
|
||||
#playerControls .jump-label {
|
||||
margin-top: 2px;
|
||||
}
|
||||
#playerControls .play-btn {
|
||||
transition: all 0.15s cubic-bezier(0.39, 0.575, 0.565, 1);
|
||||
transition-property: padding, margin, height, width, min-width, min-height;
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
export default {
|
||||
methods: {
|
||||
getJumpLabel(seconds) {
|
||||
const val = Number(seconds)
|
||||
if (isNaN(val)) return ''
|
||||
const useMinutes = val >= 120 // keep 60s as seconds
|
||||
const key = useMinutes ? 'UnitMinutesShort' : 'UnitSecondsShort'
|
||||
const unitValue = useMinutes ? val / 60 : val
|
||||
return this.$getString(key, [this.$formatNumber(unitValue)])
|
||||
}
|
||||
}
|
||||
}
|
||||
+61
-42
@@ -36,24 +36,24 @@
|
||||
|
||||
<!-- Playback settings -->
|
||||
<p class="uppercase text-xs font-semibold text-fg-muted mb-2 mt-10">{{ $strings.HeaderPlaybackSettings }}</p>
|
||||
<div class="py-3 flex items-center">
|
||||
<p class="pr-4 w-36">{{ $strings.LabelJumpBackwardsTime }}</p>
|
||||
<div @click.stop="showJumpBackwardsOptions">
|
||||
<ui-text-input :value="jumpBackwardsOption" readonly append-icon="expand_more" style="width: 145px; max-width: 145px" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="py-3 flex items-center">
|
||||
<p class="pr-4 w-36">{{ $strings.LabelJumpForwardsTime }}</p>
|
||||
<div @click.stop="showJumpForwardOptions">
|
||||
<ui-text-input :value="jumpForwardOption" readonly append-icon="expand_more" style="width: 145px; max-width: 145px" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center py-3">
|
||||
<div class="w-10 flex justify-center" @click="toggleDisableAutoRewind">
|
||||
<ui-toggle-switch v-model="settings.disableAutoRewind" @input="saveSettings" />
|
||||
</div>
|
||||
<p class="pl-4">{{ $strings.LabelDisableAutoRewind }}</p>
|
||||
</div>
|
||||
<div class="flex items-center py-3">
|
||||
<div class="w-10 flex justify-center" @click="toggleJumpBackwards">
|
||||
<span class="material-symbols text-4xl">{{ currentJumpBackwardsTimeIcon }}</span>
|
||||
</div>
|
||||
<p class="pl-4">{{ $strings.LabelJumpBackwardsTime }}</p>
|
||||
</div>
|
||||
<div class="flex items-center py-3">
|
||||
<div class="w-10 flex justify-center" @click="toggleJumpForward">
|
||||
<span class="material-symbols text-4xl">{{ currentJumpForwardTimeIcon }}</span>
|
||||
</div>
|
||||
<p class="pl-4">{{ $strings.LabelJumpForwardsTime }}</p>
|
||||
</div>
|
||||
<div v-if="!isiOS" class="flex items-center py-3">
|
||||
<div class="w-10 flex justify-center" @click="toggleEnableMp3IndexSeeking">
|
||||
<ui-toggle-switch v-model="settings.enableMp3IndexSeeking" @input="saveSettings" />
|
||||
@@ -179,7 +179,7 @@
|
||||
<ui-loading-indicator />
|
||||
</div>
|
||||
|
||||
<modals-dialog v-model="showMoreMenuDialog" :items="moreMenuItems" @action="clickMenuAction" />
|
||||
<modals-dialog v-model="showMoreMenuDialog" :items="moreMenuItems" :selected="moreMenuSelected" @action="clickMenuAction" />
|
||||
<modals-sleep-timer-length-modal v-model="showSleepTimerLengthModal" @change="sleepTimerLengthModalSelection" />
|
||||
<modals-auto-sleep-timer-rewind-length-modal v-model="showAutoSleepTimerRewindLengthModal" @change="showAutoSleepTimerRewindLengthModalSelection" />
|
||||
</div>
|
||||
@@ -187,8 +187,10 @@
|
||||
|
||||
<script>
|
||||
import { Dialog } from '@capacitor/dialog'
|
||||
import jumpLabelMixin from '@/mixins/jumpLabel'
|
||||
|
||||
export default {
|
||||
mixins: [jumpLabelMixin],
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
@@ -352,15 +354,21 @@ export default {
|
||||
isiOS() {
|
||||
return this.$platform === 'ios'
|
||||
},
|
||||
jumpForwardItems() {
|
||||
return this.$store.state.globals.jumpForwardItems || []
|
||||
jumpForwardSecondsOptions() {
|
||||
return this.$store.state.globals.jumpForwardSecondsOptions || []
|
||||
},
|
||||
jumpBackwardsItems() {
|
||||
return this.$store.state.globals.jumpBackwardsItems || []
|
||||
jumpBackwardsSecondsOptions() {
|
||||
return this.$store.state.globals.jumpBackwardsSecondsOptions || []
|
||||
},
|
||||
languageOptionItems() {
|
||||
return this.$languageCodeOptions || []
|
||||
},
|
||||
jumpForwardOption() {
|
||||
return this.getJumpLabel(this.settings.jumpForwardTime)
|
||||
},
|
||||
jumpBackwardsOption() {
|
||||
return this.getJumpLabel(this.settings.jumpBackwardsTime)
|
||||
},
|
||||
themeOptionItems() {
|
||||
return [
|
||||
{
|
||||
@@ -377,20 +385,6 @@ export default {
|
||||
}
|
||||
]
|
||||
},
|
||||
currentJumpForwardTimeIcon() {
|
||||
return this.jumpForwardItems[this.currentJumpForwardTimeIndex].icon
|
||||
},
|
||||
currentJumpForwardTimeIndex() {
|
||||
var index = this.jumpForwardItems.findIndex((jfi) => jfi.value === this.settings.jumpForwardTime)
|
||||
return index >= 0 ? index : 1
|
||||
},
|
||||
currentJumpBackwardsTimeIcon() {
|
||||
return this.jumpBackwardsItems[this.currentJumpBackwardsTimeIndex].icon
|
||||
},
|
||||
currentJumpBackwardsTimeIndex() {
|
||||
var index = this.jumpBackwardsItems.findIndex((jfi) => jfi.value === this.settings.jumpBackwardsTime)
|
||||
return index >= 0 ? index : 1
|
||||
},
|
||||
shakeSensitivityOption() {
|
||||
const item = this.shakeSensitivityItems.find((i) => i.value === this.settings.shakeSensitivity)
|
||||
return item?.text || 'Error'
|
||||
@@ -434,7 +428,29 @@ 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.jumpForwardSecondsOptions.map((value) => ({
|
||||
text: this.getJumpLabel(value),
|
||||
value: value
|
||||
}))
|
||||
else if (this.moreMenuSetting === 'jumpBackwards')
|
||||
return this.jumpBackwardsSecondsOptions.map((value) => ({
|
||||
text: this.getJumpLabel(value),
|
||||
value: value
|
||||
}))
|
||||
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 +484,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 +527,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 +628,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 })
|
||||
|
||||
+3
-37
@@ -5,34 +5,8 @@ export const state = () => ({
|
||||
series: null,
|
||||
localMediaProgress: [],
|
||||
lastSearch: null,
|
||||
jumpForwardItems: [
|
||||
{
|
||||
icon: 'forward_5',
|
||||
value: 5
|
||||
},
|
||||
{
|
||||
icon: 'forward_10',
|
||||
value: 10
|
||||
},
|
||||
{
|
||||
icon: 'forward_30',
|
||||
value: 30
|
||||
}
|
||||
],
|
||||
jumpBackwardsItems: [
|
||||
{
|
||||
icon: 'replay_5',
|
||||
value: 5
|
||||
},
|
||||
{
|
||||
icon: 'replay_10',
|
||||
value: 10
|
||||
},
|
||||
{
|
||||
icon: 'replay_30',
|
||||
value: 30
|
||||
}
|
||||
],
|
||||
jumpForwardSecondsOptions: [5, 10, 15, 30, 60, 120, 300],
|
||||
jumpBackwardsSecondsOptions: [5, 10, 15, 30, 60, 120, 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'],
|
||||
selectedPlaylistItems: [],
|
||||
showPlaylistsAddCreateModal: false,
|
||||
@@ -111,15 +85,7 @@ export const getters = {
|
||||
if (episodeId != null && lmp.episodeId != episodeId) return false
|
||||
return lmp.libraryItemId == libraryItemId
|
||||
})
|
||||
},
|
||||
getJumpForwardIcon: (state) => (jumpForwardTime) => {
|
||||
const item = state.jumpForwardItems.find((i) => i.value == jumpForwardTime)
|
||||
return item ? item.icon : 'forward_10'
|
||||
},
|
||||
getJumpBackwardsIcon: (state) => (jumpBackwardsTime) => {
|
||||
const item = state.jumpBackwardsItems.find((i) => i.value == jumpBackwardsTime)
|
||||
return item ? item.icon : 'replay_10'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const actions = {
|
||||
|
||||
+3
-1
@@ -359,5 +359,7 @@
|
||||
"ToastPodcastCreateSuccess": "Podcast created successfully",
|
||||
"ToastRSSFeedCloseFailed": "Failed to close RSS feed",
|
||||
"ToastRSSFeedCloseSuccess": "RSS feed closed",
|
||||
"ToastStreamingNotAllowedOnCellular": "Streaming is not allowed on cellular data"
|
||||
"ToastStreamingNotAllowedOnCellular": "Streaming is not allowed on cellular data",
|
||||
"UnitMinutesShort": "{0}m",
|
||||
"UnitSecondsShort": "{0}s"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user