mirror of
https://github.com/advplyr/audiobookshelf-app.git
synced 2026-08-29 22:57:16 +02:00
Add:Player setting to scale elapsed time by playback speed #1028
- Moved player settings to new playerSettings key in storage preferences
This commit is contained in:
@@ -15,7 +15,7 @@
|
|||||||
<p class="top-4 absolute left-0 right-0 mx-auto text-center uppercase tracking-widest text-opacity-75" :class="{ 'text-black text-opacity-75': coverBgIsLight }" style="font-size: 10px">{{ isDirectPlayMethod ? $strings.LabelPlaybackDirect : isLocalPlayMethod ? $strings.LabelPlaybackLocal : $strings.LabelPlaybackTranscode }}</p>
|
<p class="top-4 absolute left-0 right-0 mx-auto text-center uppercase tracking-widest text-opacity-75" :class="{ 'text-black text-opacity-75': coverBgIsLight }" style="font-size: 10px">{{ isDirectPlayMethod ? $strings.LabelPlaybackDirect : isLocalPlayMethod ? $strings.LabelPlaybackLocal : $strings.LabelPlaybackTranscode }}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="useChapterTrack && useTotalTrack && showFullscreen" class="absolute total-track w-full z-30 px-6">
|
<div v-if="playerSettings.useChapterTrack && playerSettings.useTotalTrack && showFullscreen" class="absolute total-track w-full z-30 px-6">
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<p class="font-mono text-fg" style="font-size: 0.8rem">{{ currentTimePretty }}</p>
|
<p class="font-mono text-fg" style="font-size: 0.8rem">{{ currentTimePretty }}</p>
|
||||||
<div class="flex-grow" />
|
<div class="flex-grow" />
|
||||||
@@ -66,17 +66,17 @@
|
|||||||
<div v-else class="w-full h-full absolute top-0 left-0 pointer-events-none" style="background: var(--gradient-minimized-audio-player)" />
|
<div v-else class="w-full h-full absolute top-0 left-0 pointer-events-none" style="background: var(--gradient-minimized-audio-player)" />
|
||||||
|
|
||||||
<div id="playerControls" class="absolute right-0 bottom-0 mx-auto" style="max-width: 414px">
|
<div id="playerControls" class="absolute right-0 bottom-0 mx-auto" style="max-width: 414px">
|
||||||
<div class="flex items-center max-w-full" :class="lockUi ? 'justify-center' : 'justify-between'">
|
<div class="flex items-center max-w-full" :class="playerSettings.lockUi ? 'justify-center' : 'justify-between'">
|
||||||
<span v-show="showFullscreen && !lockUi" class="material-icons next-icon text-fg cursor-pointer" :class="isLoading ? 'text-opacity-10' : 'text-opacity-75'" @click.stop="jumpChapterStart">first_page</span>
|
<span v-show="showFullscreen && !playerSettings.lockUi" class="material-icons next-icon text-fg cursor-pointer" :class="isLoading ? 'text-opacity-10' : 'text-opacity-75'" @click.stop="jumpChapterStart">first_page</span>
|
||||||
<span v-show="!lockUi" class="material-icons jump-icon text-fg cursor-pointer" :class="isLoading ? 'text-opacity-10' : 'text-opacity-75'" @click.stop="jumpBackwards">{{ jumpBackwardsIcon }}</span>
|
<span v-show="!playerSettings.lockUi" class="material-icons jump-icon text-fg cursor-pointer" :class="isLoading ? 'text-opacity-10' : 'text-opacity-75'" @click.stop="jumpBackwards">{{ jumpBackwardsIcon }}</span>
|
||||||
<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 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" />
|
<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-icons" :class="{ 'text-white': coverRgb && !coverBgIsLight }">{{ seekLoading ? 'autorenew' : !isPlaying ? 'play_arrow' : 'pause' }}</span>
|
<span v-if="!isLoading" class="material-icons" :class="{ 'text-white': coverRgb && !coverBgIsLight }">{{ seekLoading ? 'autorenew' : !isPlaying ? 'play_arrow' : 'pause' }}</span>
|
||||||
<widgets-spinner-icon v-else class="h-8 w-8" />
|
<widgets-spinner-icon v-else class="h-8 w-8" />
|
||||||
</div>
|
</div>
|
||||||
<span v-show="!lockUi" class="material-icons jump-icon text-fg cursor-pointer" :class="isLoading ? 'text-opacity-10' : 'text-opacity-75'" @click.stop="jumpForward">{{ jumpForwardIcon }}</span>
|
<span v-show="!playerSettings.lockUi" class="material-icons jump-icon text-fg cursor-pointer" :class="isLoading ? 'text-opacity-10' : 'text-opacity-75'" @click.stop="jumpForward">{{ jumpForwardIcon }}</span>
|
||||||
<span v-show="showFullscreen && !lockUi" class="material-icons next-icon text-fg cursor-pointer" :class="nextChapter && !isLoading ? 'text-opacity-75' : 'text-opacity-10'" @click.stop="jumpNextChapter">last_page</span>
|
<span v-show="showFullscreen && !playerSettings.lockUi" class="material-icons next-icon text-fg cursor-pointer" :class="nextChapter && !isLoading ? 'text-opacity-75' : 'text-opacity-10'" @click.stop="jumpNextChapter">last_page</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -90,7 +90,7 @@
|
|||||||
<div ref="readyTrack" class="h-full bg-track-buffered absolute top-0 left-0 rounded-full pointer-events-none" />
|
<div ref="readyTrack" class="h-full bg-track-buffered absolute top-0 left-0 rounded-full pointer-events-none" />
|
||||||
<div ref="bufferedTrack" class="h-full bg-track absolute top-0 left-0 rounded-full pointer-events-none" />
|
<div ref="bufferedTrack" class="h-full bg-track absolute top-0 left-0 rounded-full pointer-events-none" />
|
||||||
<div ref="playedTrack" class="h-full bg-track-cursor absolute top-0 left-0 rounded-full pointer-events-none" />
|
<div ref="playedTrack" class="h-full bg-track-cursor absolute top-0 left-0 rounded-full pointer-events-none" />
|
||||||
<div ref="trackCursor" class="h-7 w-7 rounded-full absolute pointer-events-auto flex items-center justify-center" :style="{ top: '-11px' }" :class="{ 'opacity-0': lockUi || !showFullscreen }" @touchstart="touchstartCursor">
|
<div ref="trackCursor" class="h-7 w-7 rounded-full absolute pointer-events-auto flex items-center justify-center" :style="{ top: '-11px' }" :class="{ 'opacity-0': playerSettings.lockUi || !showFullscreen }" @touchstart="touchstartCursor">
|
||||||
<div class="bg-track-cursor rounded-full w-3.5 h-3.5 pointer-events-none" />
|
<div class="bg-track-cursor rounded-full w-3.5 h-3.5 pointer-events-none" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -98,7 +98,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<modals-chapters-modal v-model="showChapterModal" :current-chapter="currentChapter" :chapters="chapters" :playback-rate="currentPlaybackRate" @select="selectChapter" />
|
<modals-chapters-modal v-model="showChapterModal" :current-chapter="currentChapter" :chapters="chapters" :playback-rate="currentPlaybackRate" @select="selectChapter" />
|
||||||
<modals-dialog v-model="showMoreMenuDialog" :items="menuItems" @action="clickMenuAction" />
|
<modals-dialog v-model="showMoreMenuDialog" :items="menuItems" width="80vw" @action="clickMenuAction" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -146,9 +146,12 @@ export default {
|
|||||||
touchStartY: 0,
|
touchStartY: 0,
|
||||||
touchStartTime: 0,
|
touchStartTime: 0,
|
||||||
touchEndY: 0,
|
touchEndY: 0,
|
||||||
useChapterTrack: false,
|
playerSettings: {
|
||||||
useTotalTrack: true,
|
useChapterTrack: false,
|
||||||
lockUi: false,
|
useTotalTrack: true,
|
||||||
|
scaleElapsedTimeBySpeed: true,
|
||||||
|
lockUi: false
|
||||||
|
},
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
isDraggingCursor: false,
|
isDraggingCursor: false,
|
||||||
draggingTouchStartX: 0,
|
draggingTouchStartX: 0,
|
||||||
@@ -164,7 +167,7 @@ export default {
|
|||||||
showFullscreen(val) {
|
showFullscreen(val) {
|
||||||
this.updateScreenSize()
|
this.updateScreenSize()
|
||||||
this.$store.commit('setPlayerFullscreen', !!val)
|
this.$store.commit('setPlayerFullscreen', !!val)
|
||||||
document.querySelector('body').style.backgroundColor = this.showFullscreen ? this.coverRgb : ""
|
document.querySelector('body').style.backgroundColor = this.showFullscreen ? this.coverRgb : ''
|
||||||
},
|
},
|
||||||
bookCoverAspectRatio() {
|
bookCoverAspectRatio() {
|
||||||
this.updateScreenSize()
|
this.updateScreenSize()
|
||||||
@@ -187,17 +190,22 @@ export default {
|
|||||||
{
|
{
|
||||||
text: this.$strings.LabelTotalTrack,
|
text: this.$strings.LabelTotalTrack,
|
||||||
value: 'total_track',
|
value: 'total_track',
|
||||||
icon: this.useTotalTrack ? 'check_box' : 'check_box_outline_blank'
|
icon: this.playerSettings.useTotalTrack ? 'check_box' : 'check_box_outline_blank'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: this.$strings.LabelChapterTrack,
|
text: this.$strings.LabelChapterTrack,
|
||||||
value: 'chapter_track',
|
value: 'chapter_track',
|
||||||
icon: this.useChapterTrack ? 'check_box' : 'check_box_outline_blank'
|
icon: this.playerSettings.useChapterTrack ? 'check_box' : 'check_box_outline_blank'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: this.lockUi ? this.$strings.LabelUnlockPlayer : this.$strings.LabelLockPlayer,
|
text: this.$strings.LabelScaleElapsedTimeBySpeed,
|
||||||
|
value: 'scale_elapsed_time',
|
||||||
|
icon: this.playerSettings.scaleElapsedTimeBySpeed ? 'check_box' : 'check_box_outline_blank'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: this.playerSettings.lockUi ? this.$strings.LabelUnlockPlayer : this.$strings.LabelLockPlayer,
|
||||||
value: 'lock',
|
value: 'lock',
|
||||||
icon: this.lockUi ? 'lock' : 'lock_open'
|
icon: this.playerSettings.lockUi ? 'lock' : 'lock_open'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: this.$strings.LabelClosePlayer,
|
text: this.$strings.LabelClosePlayer,
|
||||||
@@ -322,11 +330,14 @@ export default {
|
|||||||
},
|
},
|
||||||
currentTimePretty() {
|
currentTimePretty() {
|
||||||
let currentTimeToUse = this.isDraggingCursor ? this.draggingCurrentTime : this.currentTime
|
let currentTimeToUse = this.isDraggingCursor ? this.draggingCurrentTime : this.currentTime
|
||||||
return this.$secondsToTimestamp(currentTimeToUse / this.currentPlaybackRate)
|
if (this.playerSettings.scaleElapsedTimeBySpeed) {
|
||||||
|
currentTimeToUse = currentTimeToUse / this.currentPlaybackRate
|
||||||
|
}
|
||||||
|
return this.$secondsToTimestamp(currentTimeToUse)
|
||||||
},
|
},
|
||||||
timeRemaining() {
|
timeRemaining() {
|
||||||
let currentTimeToUse = this.isDraggingCursor ? this.draggingCurrentTime : this.currentTime
|
let currentTimeToUse = this.isDraggingCursor ? this.draggingCurrentTime : this.currentTime
|
||||||
if (this.useChapterTrack && this.currentChapter) {
|
if (this.playerSettings.useChapterTrack && this.currentChapter) {
|
||||||
var currChapTime = currentTimeToUse - this.currentChapter.start
|
var currChapTime = currentTimeToUse - this.currentChapter.start
|
||||||
return (this.currentChapterDuration - currChapTime) / this.currentPlaybackRate
|
return (this.currentChapterDuration - currChapTime) / this.currentPlaybackRate
|
||||||
}
|
}
|
||||||
@@ -494,7 +505,7 @@ export default {
|
|||||||
this.updateReadyTrack()
|
this.updateReadyTrack()
|
||||||
},
|
},
|
||||||
updateReadyTrack() {
|
updateReadyTrack() {
|
||||||
if (this.useChapterTrack) {
|
if (this.playerSettings.useChapterTrack) {
|
||||||
if (this.$refs.totalReadyTrack) {
|
if (this.$refs.totalReadyTrack) {
|
||||||
this.$refs.totalReadyTrack.style.width = this.readyTrackWidth + 'px'
|
this.$refs.totalReadyTrack.style.width = this.readyTrackWidth + 'px'
|
||||||
}
|
}
|
||||||
@@ -511,11 +522,14 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let currentTime = this.isDraggingCursor ? this.draggingCurrentTime : this.currentTime
|
let currentTime = this.isDraggingCursor ? this.draggingCurrentTime : this.currentTime
|
||||||
if (this.useChapterTrack && this.currentChapter) {
|
if (this.playerSettings.useChapterTrack && this.currentChapter) {
|
||||||
currentTime = Math.max(0, currentTime - this.currentChapter.start)
|
currentTime = Math.max(0, currentTime - this.currentChapter.start)
|
||||||
}
|
}
|
||||||
|
if (this.playerSettings.scaleElapsedTimeBySpeed) {
|
||||||
|
currentTime = currentTime / this.currentPlaybackRate
|
||||||
|
}
|
||||||
|
|
||||||
ts.innerText = this.$secondsToTimestamp(currentTime / this.currentPlaybackRate)
|
ts.innerText = this.$secondsToTimestamp(currentTime)
|
||||||
},
|
},
|
||||||
timeupdate() {
|
timeupdate() {
|
||||||
if (!this.$refs.playedTrack) {
|
if (!this.$refs.playedTrack) {
|
||||||
@@ -543,7 +557,7 @@ export default {
|
|||||||
let bufferedPercent = this.bufferedTime / this.totalDuration
|
let bufferedPercent = this.bufferedTime / this.totalDuration
|
||||||
const totalBufferedPercent = bufferedPercent
|
const totalBufferedPercent = bufferedPercent
|
||||||
|
|
||||||
if (this.useChapterTrack && this.currentChapter) {
|
if (this.playerSettings.useChapterTrack && this.currentChapter) {
|
||||||
const currChapTime = currentTimeToUse - this.currentChapter.start
|
const currChapTime = currentTimeToUse - this.currentChapter.start
|
||||||
percentDone = currChapTime / this.currentChapterDuration
|
percentDone = currChapTime / this.currentChapterDuration
|
||||||
bufferedPercent = Math.max(0, Math.min(1, (this.bufferedTime - this.currentChapter.start) / this.currentChapterDuration))
|
bufferedPercent = Math.max(0, Math.min(1, (this.bufferedTime - this.currentChapter.start) / this.currentChapterDuration))
|
||||||
@@ -557,7 +571,7 @@ export default {
|
|||||||
this.$refs.trackCursor.style.left = ptWidth - 14 + 'px'
|
this.$refs.trackCursor.style.left = ptWidth - 14 + 'px'
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.useChapterTrack) {
|
if (this.playerSettings.useChapterTrack) {
|
||||||
if (this.$refs.totalPlayedTrack) this.$refs.totalPlayedTrack.style.width = Math.round(totalPercentDone * this.trackWidth) + 'px'
|
if (this.$refs.totalPlayedTrack) this.$refs.totalPlayedTrack.style.width = Math.round(totalPercentDone * this.trackWidth) + 'px'
|
||||||
if (this.$refs.totalBufferedTrack) this.$refs.totalBufferedTrack.style.width = Math.round(totalBufferedPercent * this.trackWidth) + 'px'
|
if (this.$refs.totalBufferedTrack) this.$refs.totalBufferedTrack.style.width = Math.round(totalBufferedPercent * this.trackWidth) + 'px'
|
||||||
}
|
}
|
||||||
@@ -584,7 +598,7 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
async touchstartCursor(e) {
|
async touchstartCursor(e) {
|
||||||
if (!e || !e.touches || !this.$refs.track || !this.showFullscreen || this.lockUi) return
|
if (!e || !e.touches || !this.$refs.track || !this.showFullscreen || this.playerSettings.lockUi) return
|
||||||
|
|
||||||
await this.$hapticsImpact()
|
await this.$hapticsImpact()
|
||||||
this.isDraggingCursor = true
|
this.isDraggingCursor = true
|
||||||
@@ -670,7 +684,7 @@ export default {
|
|||||||
let duration = this.totalDuration
|
let duration = this.totalDuration
|
||||||
let minTime = 0
|
let minTime = 0
|
||||||
let maxTime = duration
|
let maxTime = duration
|
||||||
if (this.useChapterTrack && this.currentChapter) {
|
if (this.playerSettings.useChapterTrack && this.currentChapter) {
|
||||||
duration = this.currentChapterDuration
|
duration = this.currentChapterDuration
|
||||||
minTime = this.currentChapter.start
|
minTime = this.currentChapter.start
|
||||||
maxTime = minTime + duration
|
maxTime = minTime + duration
|
||||||
@@ -690,37 +704,40 @@ export default {
|
|||||||
if (action === 'history') {
|
if (action === 'history') {
|
||||||
this.$router.push(`/media/${this.mediaId}/history?title=${this.title}`)
|
this.$router.push(`/media/${this.mediaId}/history?title=${this.title}`)
|
||||||
this.showFullscreen = false
|
this.showFullscreen = false
|
||||||
|
} else if (action === 'scale_elapsed_time') {
|
||||||
|
this.playerSettings.scaleElapsedTimeBySpeed = !this.playerSettings.scaleElapsedTimeBySpeed
|
||||||
|
this.updateTimestamp()
|
||||||
|
this.savePlayerSettings()
|
||||||
} else if (action === 'lock') {
|
} else if (action === 'lock') {
|
||||||
this.lockUi = !this.lockUi
|
this.playerSettings.lockUi = !this.playerSettings.lockUi
|
||||||
this.$localStore.setPlayerLock(this.lockUi)
|
this.savePlayerSettings()
|
||||||
} else if (action === 'chapter_track') {
|
} else if (action === 'chapter_track') {
|
||||||
this.useChapterTrack = !this.useChapterTrack
|
this.playerSettings.useChapterTrack = !this.playerSettings.useChapterTrack
|
||||||
this.useTotalTrack = !this.useChapterTrack || this.useTotalTrack
|
this.playerSettings.useTotalTrack = !this.playerSettings.useChapterTrack || this.playerSettings.useTotalTrack
|
||||||
|
|
||||||
this.updateTimestamp()
|
this.updateTimestamp()
|
||||||
this.updateTrack()
|
this.updateTrack()
|
||||||
this.updateReadyTrack()
|
this.updateReadyTrack()
|
||||||
this.updateUseChapterTrack()
|
this.updateUseChapterTrack()
|
||||||
this.$localStore.setUseTotalTrack(this.useTotalTrack)
|
this.savePlayerSettings()
|
||||||
} else if (action === 'total_track') {
|
} else if (action === 'total_track') {
|
||||||
this.useTotalTrack = !this.useTotalTrack
|
this.playerSettings.useTotalTrack = !this.playerSettings.useTotalTrack
|
||||||
this.useChapterTrack = !this.useTotalTrack || this.useChapterTrack
|
this.playerSettings.useChapterTrack = !this.playerSettings.useTotalTrack || this.playerSettings.useChapterTrack
|
||||||
|
|
||||||
this.updateTimestamp()
|
this.updateTimestamp()
|
||||||
this.updateTrack()
|
this.updateTrack()
|
||||||
this.updateReadyTrack()
|
this.updateReadyTrack()
|
||||||
this.updateUseChapterTrack()
|
this.updateUseChapterTrack()
|
||||||
this.$localStore.setUseTotalTrack(this.useTotalTrack)
|
this.savePlayerSettings()
|
||||||
} else if (action === 'close') {
|
} else if (action === 'close') {
|
||||||
this.closePlayback()
|
this.closePlayback()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
updateUseChapterTrack() {
|
updateUseChapterTrack() {
|
||||||
this.$localStore.setUseChapterTrack(this.useChapterTrack)
|
|
||||||
// Chapter track in NowPlaying only supported on iOS for now
|
// Chapter track in NowPlaying only supported on iOS for now
|
||||||
if (this.$platform === 'ios') {
|
if (this.$platform === 'ios') {
|
||||||
AbsAudioPlayer.setChapterTrack({ enabled: this.useChapterTrack })
|
AbsAudioPlayer.setChapterTrack({ enabled: this.playerSettings.useChapterTrack })
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
forceCloseDropdownMenu() {
|
forceCloseDropdownMenu() {
|
||||||
@@ -739,6 +756,30 @@ export default {
|
|||||||
this.isLoading = false
|
this.isLoading = false
|
||||||
this.playbackSession = null
|
this.playbackSession = null
|
||||||
},
|
},
|
||||||
|
async loadPlayerSettings() {
|
||||||
|
const savedPlayerSettings = await this.$localStore.getPlayerSettings()
|
||||||
|
if (!savedPlayerSettings) {
|
||||||
|
// In 0.9.72-beta 'useChapterTrack', 'useTotalTrack' and 'playerLock' was replaced with 'playerSettings' JSON object
|
||||||
|
// Check if this old key was set and if so migrate them over to 'playerSettings'
|
||||||
|
const chapterTrackPref = await this.$localStore.getPreferenceByKey('useChapterTrack')
|
||||||
|
if (chapterTrackPref) {
|
||||||
|
this.playerSettings.useChapterTrack = chapterTrackPref === '1'
|
||||||
|
const totalTrackPref = await this.$localStore.getPreferenceByKey('useTotalTrack')
|
||||||
|
this.playerSettings.useTotalTrack = totalTrackPref === '1'
|
||||||
|
const playerLockPref = await this.$localStore.getPreferenceByKey('playerLock')
|
||||||
|
this.playerSettings.lockUi = playerLockPref === '1'
|
||||||
|
}
|
||||||
|
this.savePlayerSettings()
|
||||||
|
} else {
|
||||||
|
this.playerSettings.useChapterTrack = !!savedPlayerSettings.useChapterTrack
|
||||||
|
this.playerSettings.useTotalTrack = !!savedPlayerSettings.useTotalTrack
|
||||||
|
this.playerSettings.lockUi = !!savedPlayerSettings.lockUi
|
||||||
|
this.playerSettings.scaleElapsedTimeBySpeed = !!savedPlayerSettings.scaleElapsedTimeBySpeed
|
||||||
|
}
|
||||||
|
},
|
||||||
|
savePlayerSettings() {
|
||||||
|
return this.$localStore.setPlayerSettings({ ...this.playerSettings })
|
||||||
|
},
|
||||||
//
|
//
|
||||||
// Listeners from audio AbsAudioPlayer
|
// Listeners from audio AbsAudioPlayer
|
||||||
//
|
//
|
||||||
@@ -805,9 +846,7 @@ export default {
|
|||||||
this.updateTimestamp()
|
this.updateTimestamp()
|
||||||
},
|
},
|
||||||
async init() {
|
async init() {
|
||||||
this.useChapterTrack = await this.$localStore.getUseChapterTrack()
|
await this.loadPlayerSettings()
|
||||||
this.useTotalTrack = await this.$localStore.getUseTotalTrack()
|
|
||||||
this.lockUi = await this.$localStore.getPlayerLock()
|
|
||||||
|
|
||||||
this.onPlaybackSessionListener = AbsAudioPlayer.addListener('onPlaybackSession', this.onPlaybackSession)
|
this.onPlaybackSessionListener = AbsAudioPlayer.addListener('onPlaybackSession', this.onPlaybackSession)
|
||||||
this.onPlaybackClosedListener = AbsAudioPlayer.addListener('onPlaybackClosed', this.onPlaybackClosed)
|
this.onPlaybackClosedListener = AbsAudioPlayer.addListener('onPlaybackClosed', this.onPlaybackClosed)
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ export default {
|
|||||||
default: '16px'
|
default: '16px'
|
||||||
},
|
},
|
||||||
width: {
|
width: {
|
||||||
type: Number,
|
type: [String, Number],
|
||||||
default: 300
|
default: 300
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
+23
-43
@@ -42,56 +42,20 @@ class LocalStorage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async setUseChapterTrack(useChapterTrack) {
|
async setPlayerSettings(playerSettings) {
|
||||||
try {
|
try {
|
||||||
await Preferences.set({ key: 'useChapterTrack', value: useChapterTrack ? '1' : '0' })
|
await Preferences.set({ key: 'playerSettings', value: JSON.stringify(playerSettings) })
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[LocalStorage] Failed to set use chapter track', error)
|
console.error('[LocalStorage] Failed to set player settings', error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async getUseChapterTrack() {
|
async getPlayerSettings() {
|
||||||
try {
|
try {
|
||||||
var obj = await Preferences.get({ key: 'useChapterTrack' }) || {}
|
const playerSettingsObj = await Preferences.get({ key: 'playerSettings' }) || {}
|
||||||
return obj.value === '1'
|
return playerSettingsObj.value ? JSON.parse(playerSettingsObj.value) : null
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[LocalStorage] Failed to get use chapter track', error)
|
console.error('[LocalStorage] Failed to get player settings', error)
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async setUseTotalTrack(useTotalTrack) {
|
|
||||||
try {
|
|
||||||
await Preferences.set({ key: 'useTotalTrack', value: useTotalTrack ? '1' : '0' })
|
|
||||||
} catch (error) {
|
|
||||||
console.error('[LocalStorage] Failed to set use total track', error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async getUseTotalTrack() {
|
|
||||||
try {
|
|
||||||
var obj = await Preferences.get({ key: 'useTotalTrack' }) || {}
|
|
||||||
return obj.value === '1'
|
|
||||||
} catch (error) {
|
|
||||||
console.error('[LocalStorage] Failed to get use total track', error)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async setPlayerLock(lock) {
|
|
||||||
try {
|
|
||||||
await Preferences.set({ key: 'playerLock', value: lock ? '1' : '0' })
|
|
||||||
} catch (error) {
|
|
||||||
console.error('[LocalStorage] Failed to set player lock', error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async getPlayerLock() {
|
|
||||||
try {
|
|
||||||
var obj = await Preferences.get({ key: 'playerLock' }) || {}
|
|
||||||
return obj.value === '1'
|
|
||||||
} catch (error) {
|
|
||||||
console.error('[LocalStorage] Failed to get player lock', error)
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -179,6 +143,22 @@ class LocalStorage {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get preference value by key
|
||||||
|
*
|
||||||
|
* @param {string} key
|
||||||
|
* @returns {Promise<string>}
|
||||||
|
*/
|
||||||
|
async getPreferenceByKey(key) {
|
||||||
|
try {
|
||||||
|
const obj = await Preferences.get({ key }) || {}
|
||||||
|
return obj.value || null
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`[LocalStorage] Failed to get preference "${key}"`, error)
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -194,6 +194,7 @@
|
|||||||
"LabelRSSFeedCustomOwnerName": "Vlastní jméno vlastníka",
|
"LabelRSSFeedCustomOwnerName": "Vlastní jméno vlastníka",
|
||||||
"LabelRSSFeedPreventIndexing": "Zabránit indexování",
|
"LabelRSSFeedPreventIndexing": "Zabránit indexování",
|
||||||
"LabelRSSFeedSlug": "RSS kanál Slug",
|
"LabelRSSFeedSlug": "RSS kanál Slug",
|
||||||
|
"LabelScaleElapsedTimeBySpeed": "Scale Elapsed Time by Speed",
|
||||||
"LabelSeason": "Sezóna",
|
"LabelSeason": "Sezóna",
|
||||||
"LabelSelectADevice": "Select a device",
|
"LabelSelectADevice": "Select a device",
|
||||||
"LabelSeries": "Série",
|
"LabelSeries": "Série",
|
||||||
|
|||||||
@@ -194,6 +194,7 @@
|
|||||||
"LabelRSSFeedCustomOwnerName": "Brugerdefineret ejerens navn",
|
"LabelRSSFeedCustomOwnerName": "Brugerdefineret ejerens navn",
|
||||||
"LabelRSSFeedPreventIndexing": "Forhindrer indeksering",
|
"LabelRSSFeedPreventIndexing": "Forhindrer indeksering",
|
||||||
"LabelRSSFeedSlug": "RSS-feed-slug",
|
"LabelRSSFeedSlug": "RSS-feed-slug",
|
||||||
|
"LabelScaleElapsedTimeBySpeed": "Scale Elapsed Time by Speed",
|
||||||
"LabelSeason": "Sæson",
|
"LabelSeason": "Sæson",
|
||||||
"LabelSelectADevice": "Select a device",
|
"LabelSelectADevice": "Select a device",
|
||||||
"LabelSeries": "Serie",
|
"LabelSeries": "Serie",
|
||||||
|
|||||||
@@ -194,6 +194,7 @@
|
|||||||
"LabelRSSFeedCustomOwnerName": "Benutzerdefinierter Name des Eigentümers",
|
"LabelRSSFeedCustomOwnerName": "Benutzerdefinierter Name des Eigentümers",
|
||||||
"LabelRSSFeedPreventIndexing": "Indizierung verhindern",
|
"LabelRSSFeedPreventIndexing": "Indizierung verhindern",
|
||||||
"LabelRSSFeedSlug": "RSS Feed Schlagwort",
|
"LabelRSSFeedSlug": "RSS Feed Schlagwort",
|
||||||
|
"LabelScaleElapsedTimeBySpeed": "Scale Elapsed Time by Speed",
|
||||||
"LabelSeason": "Staffel",
|
"LabelSeason": "Staffel",
|
||||||
"LabelSelectADevice": "Wähle ein Gerät",
|
"LabelSelectADevice": "Wähle ein Gerät",
|
||||||
"LabelSeries": "Serien",
|
"LabelSeries": "Serien",
|
||||||
|
|||||||
@@ -194,6 +194,7 @@
|
|||||||
"LabelRSSFeedCustomOwnerName": "Custom owner Name",
|
"LabelRSSFeedCustomOwnerName": "Custom owner Name",
|
||||||
"LabelRSSFeedPreventIndexing": "Prevent Indexing",
|
"LabelRSSFeedPreventIndexing": "Prevent Indexing",
|
||||||
"LabelRSSFeedSlug": "RSS Feed Slug",
|
"LabelRSSFeedSlug": "RSS Feed Slug",
|
||||||
|
"LabelScaleElapsedTimeBySpeed": "Scale Elapsed Time by Speed",
|
||||||
"LabelSeason": "Season",
|
"LabelSeason": "Season",
|
||||||
"LabelSelectADevice": "Select a device",
|
"LabelSelectADevice": "Select a device",
|
||||||
"LabelSeries": "Series",
|
"LabelSeries": "Series",
|
||||||
|
|||||||
@@ -194,6 +194,7 @@
|
|||||||
"LabelRSSFeedCustomOwnerName": "Nombre de dueño personalizado",
|
"LabelRSSFeedCustomOwnerName": "Nombre de dueño personalizado",
|
||||||
"LabelRSSFeedPreventIndexing": "Prevenir Indexado",
|
"LabelRSSFeedPreventIndexing": "Prevenir Indexado",
|
||||||
"LabelRSSFeedSlug": "Fuente RSS Slug",
|
"LabelRSSFeedSlug": "Fuente RSS Slug",
|
||||||
|
"LabelScaleElapsedTimeBySpeed": "Scale Elapsed Time by Speed",
|
||||||
"LabelSeason": "Temporada",
|
"LabelSeason": "Temporada",
|
||||||
"LabelSelectADevice": "Select a device",
|
"LabelSelectADevice": "Select a device",
|
||||||
"LabelSeries": "Series",
|
"LabelSeries": "Series",
|
||||||
|
|||||||
@@ -194,6 +194,7 @@
|
|||||||
"LabelRSSFeedCustomOwnerName": "Nom propriétaire personnalisé",
|
"LabelRSSFeedCustomOwnerName": "Nom propriétaire personnalisé",
|
||||||
"LabelRSSFeedPreventIndexing": "Empêcher l’indexation",
|
"LabelRSSFeedPreventIndexing": "Empêcher l’indexation",
|
||||||
"LabelRSSFeedSlug": "Identificateur d’adresse du Flux RSS ",
|
"LabelRSSFeedSlug": "Identificateur d’adresse du Flux RSS ",
|
||||||
|
"LabelScaleElapsedTimeBySpeed": "Scale Elapsed Time by Speed",
|
||||||
"LabelSeason": "Saison",
|
"LabelSeason": "Saison",
|
||||||
"LabelSelectADevice": "Select a device",
|
"LabelSelectADevice": "Select a device",
|
||||||
"LabelSeries": "Séries",
|
"LabelSeries": "Séries",
|
||||||
|
|||||||
@@ -194,6 +194,7 @@
|
|||||||
"LabelRSSFeedCustomOwnerName": "Custom owner Name",
|
"LabelRSSFeedCustomOwnerName": "Custom owner Name",
|
||||||
"LabelRSSFeedPreventIndexing": "Prevent Indexing",
|
"LabelRSSFeedPreventIndexing": "Prevent Indexing",
|
||||||
"LabelRSSFeedSlug": "RSS Feed Slug",
|
"LabelRSSFeedSlug": "RSS Feed Slug",
|
||||||
|
"LabelScaleElapsedTimeBySpeed": "Scale Elapsed Time by Speed",
|
||||||
"LabelSeason": "Season",
|
"LabelSeason": "Season",
|
||||||
"LabelSelectADevice": "Select a device",
|
"LabelSelectADevice": "Select a device",
|
||||||
"LabelSeries": "Series",
|
"LabelSeries": "Series",
|
||||||
|
|||||||
@@ -194,6 +194,7 @@
|
|||||||
"LabelRSSFeedCustomOwnerName": "Custom owner Name",
|
"LabelRSSFeedCustomOwnerName": "Custom owner Name",
|
||||||
"LabelRSSFeedPreventIndexing": "Prevent Indexing",
|
"LabelRSSFeedPreventIndexing": "Prevent Indexing",
|
||||||
"LabelRSSFeedSlug": "RSS Feed Slug",
|
"LabelRSSFeedSlug": "RSS Feed Slug",
|
||||||
|
"LabelScaleElapsedTimeBySpeed": "Scale Elapsed Time by Speed",
|
||||||
"LabelSeason": "Season",
|
"LabelSeason": "Season",
|
||||||
"LabelSelectADevice": "Select a device",
|
"LabelSelectADevice": "Select a device",
|
||||||
"LabelSeries": "Series",
|
"LabelSeries": "Series",
|
||||||
|
|||||||
@@ -194,6 +194,7 @@
|
|||||||
"LabelRSSFeedCustomOwnerName": "Custom owner Name",
|
"LabelRSSFeedCustomOwnerName": "Custom owner Name",
|
||||||
"LabelRSSFeedPreventIndexing": "Prevent Indexing",
|
"LabelRSSFeedPreventIndexing": "Prevent Indexing",
|
||||||
"LabelRSSFeedSlug": "RSS Feed Slug",
|
"LabelRSSFeedSlug": "RSS Feed Slug",
|
||||||
|
"LabelScaleElapsedTimeBySpeed": "Scale Elapsed Time by Speed",
|
||||||
"LabelSeason": "Sezona",
|
"LabelSeason": "Sezona",
|
||||||
"LabelSelectADevice": "Select a device",
|
"LabelSelectADevice": "Select a device",
|
||||||
"LabelSeries": "Serije",
|
"LabelSeries": "Serije",
|
||||||
|
|||||||
@@ -194,6 +194,7 @@
|
|||||||
"LabelRSSFeedCustomOwnerName": "Nome del proprietario personalizzato",
|
"LabelRSSFeedCustomOwnerName": "Nome del proprietario personalizzato",
|
||||||
"LabelRSSFeedPreventIndexing": "Impedisci l'indicizzazione",
|
"LabelRSSFeedPreventIndexing": "Impedisci l'indicizzazione",
|
||||||
"LabelRSSFeedSlug": "RSS Feed Slug",
|
"LabelRSSFeedSlug": "RSS Feed Slug",
|
||||||
|
"LabelScaleElapsedTimeBySpeed": "Scale Elapsed Time by Speed",
|
||||||
"LabelSeason": "Stagione",
|
"LabelSeason": "Stagione",
|
||||||
"LabelSelectADevice": "Select a device",
|
"LabelSelectADevice": "Select a device",
|
||||||
"LabelSeries": "Serie",
|
"LabelSeries": "Serie",
|
||||||
|
|||||||
@@ -194,6 +194,7 @@
|
|||||||
"LabelRSSFeedCustomOwnerName": "Pasirinktinis savininko vardas",
|
"LabelRSSFeedCustomOwnerName": "Pasirinktinis savininko vardas",
|
||||||
"LabelRSSFeedPreventIndexing": "Neleisti indeksuoti",
|
"LabelRSSFeedPreventIndexing": "Neleisti indeksuoti",
|
||||||
"LabelRSSFeedSlug": "RSS srauto identifikatorius",
|
"LabelRSSFeedSlug": "RSS srauto identifikatorius",
|
||||||
|
"LabelScaleElapsedTimeBySpeed": "Scale Elapsed Time by Speed",
|
||||||
"LabelSeason": "Sezonas",
|
"LabelSeason": "Sezonas",
|
||||||
"LabelSelectADevice": "Select a device",
|
"LabelSelectADevice": "Select a device",
|
||||||
"LabelSeries": "Serija",
|
"LabelSeries": "Serija",
|
||||||
|
|||||||
@@ -194,6 +194,7 @@
|
|||||||
"LabelRSSFeedCustomOwnerName": "Aangepaste naam eigenaar",
|
"LabelRSSFeedCustomOwnerName": "Aangepaste naam eigenaar",
|
||||||
"LabelRSSFeedPreventIndexing": "Voorkom indexering",
|
"LabelRSSFeedPreventIndexing": "Voorkom indexering",
|
||||||
"LabelRSSFeedSlug": "RSS-feed slug",
|
"LabelRSSFeedSlug": "RSS-feed slug",
|
||||||
|
"LabelScaleElapsedTimeBySpeed": "Scale Elapsed Time by Speed",
|
||||||
"LabelSeason": "Seizoen",
|
"LabelSeason": "Seizoen",
|
||||||
"LabelSelectADevice": "Select a device",
|
"LabelSelectADevice": "Select a device",
|
||||||
"LabelSeries": "Serie",
|
"LabelSeries": "Serie",
|
||||||
|
|||||||
@@ -194,6 +194,7 @@
|
|||||||
"LabelRSSFeedCustomOwnerName": "Tilpasset eier Navn",
|
"LabelRSSFeedCustomOwnerName": "Tilpasset eier Navn",
|
||||||
"LabelRSSFeedPreventIndexing": "Forhindre indeksering",
|
"LabelRSSFeedPreventIndexing": "Forhindre indeksering",
|
||||||
"LabelRSSFeedSlug": "RSS Feed Slug",
|
"LabelRSSFeedSlug": "RSS Feed Slug",
|
||||||
|
"LabelScaleElapsedTimeBySpeed": "Scale Elapsed Time by Speed",
|
||||||
"LabelSeason": "Sesong",
|
"LabelSeason": "Sesong",
|
||||||
"LabelSelectADevice": "Select a device",
|
"LabelSelectADevice": "Select a device",
|
||||||
"LabelSeries": "Serier",
|
"LabelSeries": "Serier",
|
||||||
|
|||||||
@@ -194,6 +194,7 @@
|
|||||||
"LabelRSSFeedCustomOwnerName": "Custom owner Name",
|
"LabelRSSFeedCustomOwnerName": "Custom owner Name",
|
||||||
"LabelRSSFeedPreventIndexing": "Prevent Indexing",
|
"LabelRSSFeedPreventIndexing": "Prevent Indexing",
|
||||||
"LabelRSSFeedSlug": "RSS Feed Slug",
|
"LabelRSSFeedSlug": "RSS Feed Slug",
|
||||||
|
"LabelScaleElapsedTimeBySpeed": "Scale Elapsed Time by Speed",
|
||||||
"LabelSeason": "Sezon",
|
"LabelSeason": "Sezon",
|
||||||
"LabelSelectADevice": "Select a device",
|
"LabelSelectADevice": "Select a device",
|
||||||
"LabelSeries": "Serie",
|
"LabelSeries": "Serie",
|
||||||
|
|||||||
@@ -194,6 +194,7 @@
|
|||||||
"LabelRSSFeedCustomOwnerName": "Пользовательское Имя владельца",
|
"LabelRSSFeedCustomOwnerName": "Пользовательское Имя владельца",
|
||||||
"LabelRSSFeedPreventIndexing": "Запретить индексирование",
|
"LabelRSSFeedPreventIndexing": "Запретить индексирование",
|
||||||
"LabelRSSFeedSlug": "Встроить RSS-канал",
|
"LabelRSSFeedSlug": "Встроить RSS-канал",
|
||||||
|
"LabelScaleElapsedTimeBySpeed": "Scale Elapsed Time by Speed",
|
||||||
"LabelSeason": "Сезон",
|
"LabelSeason": "Сезон",
|
||||||
"LabelSelectADevice": "Выбор девайса",
|
"LabelSelectADevice": "Выбор девайса",
|
||||||
"LabelSeries": "Серия",
|
"LabelSeries": "Серия",
|
||||||
|
|||||||
@@ -194,6 +194,7 @@
|
|||||||
"LabelRSSFeedCustomOwnerName": "Anpassat ägarnamn",
|
"LabelRSSFeedCustomOwnerName": "Anpassat ägarnamn",
|
||||||
"LabelRSSFeedPreventIndexing": "Förhindra indexering",
|
"LabelRSSFeedPreventIndexing": "Förhindra indexering",
|
||||||
"LabelRSSFeedSlug": "RSS-flödesslag",
|
"LabelRSSFeedSlug": "RSS-flödesslag",
|
||||||
|
"LabelScaleElapsedTimeBySpeed": "Scale Elapsed Time by Speed",
|
||||||
"LabelSeason": "Säsong",
|
"LabelSeason": "Säsong",
|
||||||
"LabelSelectADevice": "Select a device",
|
"LabelSelectADevice": "Select a device",
|
||||||
"LabelSeries": "Serie",
|
"LabelSeries": "Serie",
|
||||||
|
|||||||
@@ -194,6 +194,7 @@
|
|||||||
"LabelRSSFeedCustomOwnerName": "自定义所有者名称",
|
"LabelRSSFeedCustomOwnerName": "自定义所有者名称",
|
||||||
"LabelRSSFeedPreventIndexing": "防止索引",
|
"LabelRSSFeedPreventIndexing": "防止索引",
|
||||||
"LabelRSSFeedSlug": "RSS 源段",
|
"LabelRSSFeedSlug": "RSS 源段",
|
||||||
|
"LabelScaleElapsedTimeBySpeed": "Scale Elapsed Time by Speed",
|
||||||
"LabelSeason": "季",
|
"LabelSeason": "季",
|
||||||
"LabelSelectADevice": "选择设备",
|
"LabelSelectADevice": "选择设备",
|
||||||
"LabelSeries": "系列",
|
"LabelSeries": "系列",
|
||||||
|
|||||||
Reference in New Issue
Block a user