mirror of
https://github.com/advplyr/audiobookshelf-app.git
synced 2026-07-26 14:38:39 +02:00
Compare commits
6
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1f60a552e5 | ||
|
|
3b34029ca2 | ||
|
|
5f6a1ef7e9 | ||
|
|
b51f65d2a4 | ||
|
|
dc9526beb3 | ||
|
|
7188089f63 |
@@ -29,8 +29,8 @@ android {
|
||||
applicationId "com.audiobookshelf.app"
|
||||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
versionCode 83
|
||||
versionName "0.9.52-beta"
|
||||
versionCode 84
|
||||
versionName "0.9.53-beta"
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
aaptOptions {
|
||||
// Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps.
|
||||
@@ -111,7 +111,7 @@ dependencies {
|
||||
implementation 'io.github.pilgr:paperdb:2.7.2'
|
||||
|
||||
// Simple Storage
|
||||
implementation "com.anggrayudi:storage:1.3.0"
|
||||
implementation "com.anggrayudi:storage:0.14.0"
|
||||
|
||||
// OK HTTP
|
||||
implementation 'com.squareup.okhttp3:okhttp:4.9.2'
|
||||
|
||||
@@ -109,11 +109,23 @@ class MediaProgressSyncer(val playerNotificationService:PlayerNotificationServic
|
||||
// Local library item is linked to a server library item
|
||||
// Send sync to server also if connected to this server and local item belongs to this server
|
||||
if (!it.libraryItemId.isNullOrEmpty() && it.serverConnectionConfigId != null && DeviceManager.serverConnectionConfig?.id == it.serverConnectionConfigId) {
|
||||
apiHandler.sendLocalProgressSync(it) {
|
||||
apiHandler.sendLocalProgressSync(it) { syncSuccess ->
|
||||
Log.d(
|
||||
tag,
|
||||
"Local progress sync data sent to server $currentDisplayTitle for time $currentTime"
|
||||
)
|
||||
if (syncSuccess) {
|
||||
failedSyncs = 0
|
||||
playerNotificationService.alertSyncSuccess()
|
||||
} else {
|
||||
failedSyncs++
|
||||
if (failedSyncs == 2) {
|
||||
playerNotificationService.alertSyncFailing() // Show alert in client
|
||||
failedSyncs = 0
|
||||
}
|
||||
Log.e(tag, "Local Progress sync failed ($failedSyncs) to send to server $currentDisplayTitle for time $currentTime")
|
||||
}
|
||||
|
||||
cb()
|
||||
}
|
||||
} else {
|
||||
@@ -125,13 +137,14 @@ class MediaProgressSyncer(val playerNotificationService:PlayerNotificationServic
|
||||
if (it) {
|
||||
Log.d(tag, "Progress sync data sent to server $currentDisplayTitle for time $currentTime")
|
||||
failedSyncs = 0
|
||||
playerNotificationService.alertSyncSuccess()
|
||||
} else {
|
||||
failedSyncs++
|
||||
if (failedSyncs == 2) {
|
||||
playerNotificationService.alertSyncFailing() // Show alert in client
|
||||
failedSyncs = 0
|
||||
}
|
||||
Log.d(tag, "Progress sync failed ($failedSyncs) to send to server $currentDisplayTitle for time $currentTime")
|
||||
Log.e(tag, "Progress sync failed ($failedSyncs) to send to server $currentDisplayTitle for time $currentTime")
|
||||
}
|
||||
cb()
|
||||
}
|
||||
|
||||
@@ -58,6 +58,7 @@ class PlayerNotificationService : MediaBrowserServiceCompat() {
|
||||
fun onPlaybackFailed(errorMessage:String)
|
||||
fun onMediaPlayerChanged(mediaPlayer:String)
|
||||
fun onProgressSyncFailing()
|
||||
fun onProgressSyncSuccess()
|
||||
}
|
||||
|
||||
private val tag = "PlayerService"
|
||||
@@ -670,6 +671,11 @@ class PlayerNotificationService : MediaBrowserServiceCompat() {
|
||||
|
||||
fun closePlayback() {
|
||||
Log.d(tag, "closePlayback")
|
||||
if (mediaProgressSyncer.listeningTimerRunning) {
|
||||
Log.i(tag, "About to close playback so stopping media progress syncer first")
|
||||
mediaProgressSyncer.stop()
|
||||
}
|
||||
|
||||
try {
|
||||
currentPlayer.stop()
|
||||
currentPlayer.clearMediaItems()
|
||||
@@ -717,6 +723,10 @@ class PlayerNotificationService : MediaBrowserServiceCompat() {
|
||||
clientEventEmitter?.onProgressSyncFailing()
|
||||
}
|
||||
|
||||
fun alertSyncSuccess() {
|
||||
clientEventEmitter?.onProgressSyncSuccess()
|
||||
}
|
||||
|
||||
//
|
||||
// MEDIA BROWSER STUFF (ANDROID AUTO)
|
||||
//
|
||||
|
||||
@@ -80,6 +80,10 @@ class AbsAudioPlayer : Plugin() {
|
||||
override fun onProgressSyncFailing() {
|
||||
emit("onProgressSyncFailing", "")
|
||||
}
|
||||
|
||||
override fun onProgressSyncSuccess() {
|
||||
emit("onProgressSyncSuccess", "")
|
||||
}
|
||||
})
|
||||
}
|
||||
mainActivity.pluginCallback = foregroundServiceReady
|
||||
|
||||
@@ -230,11 +230,15 @@ class ApiHandler(var ctx:Context) {
|
||||
}
|
||||
}
|
||||
|
||||
fun sendLocalProgressSync(playbackSession:PlaybackSession, cb: () -> Unit) {
|
||||
fun sendLocalProgressSync(playbackSession:PlaybackSession, cb: (Boolean) -> Unit) {
|
||||
val payload = JSObject(jacksonMapper.writeValueAsString(playbackSession))
|
||||
|
||||
postRequest("/api/session/local", payload) {
|
||||
cb()
|
||||
if (!it.getString("error").isNullOrEmpty()) {
|
||||
cb(false)
|
||||
} else {
|
||||
cb(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -34,6 +34,10 @@
|
||||
<div class="cover-container bookCoverWrapper bg-black bg-opacity-75 w-full h-full">
|
||||
<covers-book-cover v-if="libraryItem || localLibraryItemCoverSrc" :library-item="libraryItem" :download-cover="localLibraryItemCoverSrc" :width="bookCoverWidth" :book-cover-aspect-ratio="bookCoverAspectRatio" />
|
||||
</div>
|
||||
|
||||
<div v-if="syncStatus === $constants.SyncStatus.FAILED" class="absolute top-0 left-0 w-full h-full flex items-center justify-center z-30">
|
||||
<span class="material-icons text-error text-3xl">error</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="title-author-texts absolute z-30 left-0 right-0 overflow-hidden" @click="clickTitleAndAuthor">
|
||||
@@ -129,13 +133,16 @@ export default {
|
||||
onPlaybackClosedListener: null,
|
||||
onPlayingUpdateListener: null,
|
||||
onMetadataListener: null,
|
||||
onProgressSyncFailing: null,
|
||||
onProgressSyncSuccess: null,
|
||||
touchStartY: 0,
|
||||
touchStartTime: 0,
|
||||
touchEndY: 0,
|
||||
useChapterTrack: false,
|
||||
isLoading: false,
|
||||
touchTrackStart: false,
|
||||
dragPercent: 0
|
||||
dragPercent: 0,
|
||||
syncStatus: 0
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
@@ -675,6 +682,7 @@ export default {
|
||||
|
||||
this.isEnded = false
|
||||
this.isLoading = true
|
||||
this.syncStatus = 0
|
||||
this.$store.commit('setPlayerItem', this.playbackSession)
|
||||
|
||||
// Set track width
|
||||
@@ -703,6 +711,8 @@ export default {
|
||||
this.onPlaybackFailedListener = AbsAudioPlayer.addListener('onPlaybackFailed', this.onPlaybackFailed)
|
||||
this.onPlayingUpdateListener = AbsAudioPlayer.addListener('onPlayingUpdate', this.onPlayingUpdate)
|
||||
this.onMetadataListener = AbsAudioPlayer.addListener('onMetadata', this.onMetadata)
|
||||
this.onProgressSyncFailing = AbsAudioPlayer.addListener('onProgressSyncFailing', this.showProgressSyncIsFailing)
|
||||
this.onProgressSyncSuccess = AbsAudioPlayer.addListener('onProgressSyncSuccess', this.showProgressSyncSuccess)
|
||||
},
|
||||
screenOrientationChange() {
|
||||
setTimeout(this.updateScreenSize, 50)
|
||||
@@ -716,6 +726,12 @@ export default {
|
||||
minimizePlayerEvt() {
|
||||
console.log('Minimize Player Evt')
|
||||
this.showFullscreen = false
|
||||
},
|
||||
showProgressSyncIsFailing() {
|
||||
this.syncStatus = this.$constants.SyncStatus.FAILED
|
||||
},
|
||||
showProgressSyncSuccess() {
|
||||
this.syncStatus = this.$constants.SyncStatus.SUCCESS
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
@@ -751,6 +767,8 @@ export default {
|
||||
if (this.onPlaybackSessionListener) this.onPlaybackSessionListener.remove()
|
||||
if (this.onPlaybackClosedListener) this.onPlaybackClosedListener.remove()
|
||||
if (this.onPlaybackFailedListener) this.onPlaybackFailedListener.remove()
|
||||
if (this.onProgressSyncFailing) this.onProgressSyncFailing.remove()
|
||||
if (this.onProgressSyncSuccess) this.onProgressSyncSuccess.remove()
|
||||
clearInterval(this.playInterval)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,11 +30,9 @@ export default {
|
||||
onSleepTimerEndedListener: null,
|
||||
onSleepTimerSetListener: null,
|
||||
onMediaPlayerChangedListener: null,
|
||||
onProgressSyncFailing: null,
|
||||
sleepInterval: null,
|
||||
currentEndOfChapterTime: 0,
|
||||
serverLibraryItemId: null,
|
||||
syncFailedToast: null
|
||||
serverLibraryItemId: null
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
@@ -255,10 +253,6 @@ export default {
|
||||
onMediaPlayerChanged(data) {
|
||||
var mediaPlayer = data.value
|
||||
this.$store.commit('setMediaPlayer', mediaPlayer)
|
||||
},
|
||||
showProgressSyncIsFailing() {
|
||||
if (!isNaN(this.syncFailedToast)) this.$toast.dismiss(this.syncFailedToast)
|
||||
this.syncFailedToast = this.$toast('Progress is not being synced', { timeout: false, type: 'error' })
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
@@ -266,7 +260,6 @@ export default {
|
||||
this.onSleepTimerEndedListener = AbsAudioPlayer.addListener('onSleepTimerEnded', this.onSleepTimerEnded)
|
||||
this.onSleepTimerSetListener = AbsAudioPlayer.addListener('onSleepTimerSet', this.onSleepTimerSet)
|
||||
this.onMediaPlayerChangedListener = AbsAudioPlayer.addListener('onMediaPlayerChanged', this.onMediaPlayerChanged)
|
||||
this.onProgressSyncFailing = AbsAudioPlayer.addListener('onProgressSyncFailing', this.showProgressSyncIsFailing)
|
||||
|
||||
this.playbackSpeed = this.$store.getters['user/getUserSetting']('playbackRate')
|
||||
console.log(`[AudioPlayerContainer] Init Playback Speed: ${this.playbackSpeed}`)
|
||||
@@ -283,7 +276,6 @@ export default {
|
||||
if (this.onSleepTimerEndedListener) this.onSleepTimerEndedListener.remove()
|
||||
if (this.onSleepTimerSetListener) this.onSleepTimerSetListener.remove()
|
||||
if (this.onMediaPlayerChangedListener) this.onMediaPlayerChangedListener.remove()
|
||||
if (this.onProgressSyncFailing) this.onProgressSyncFailing.remove()
|
||||
|
||||
// if (this.$server.socket) {
|
||||
// this.$server.socket.off('stream_open', this.streamOpen)
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
</template>
|
||||
<div v-else class="w-full">
|
||||
<form v-show="!showAuth" @submit.prevent="submit" novalidate class="w-full">
|
||||
<div v-if="serverConnectionConfigs.length" class="flex items-center mb-4" @click="showServerList">
|
||||
<span class="material-icons text-gray-300">arrow_back</span>
|
||||
</div>
|
||||
<h2 class="text-lg leading-7 mb-2">Server address</h2>
|
||||
<ui-text-input v-model="serverConfig.address" :disabled="processing || !networkConnected || !!serverConfig.id" placeholder="http://55.55.55.55:13378" type="url" class="w-full h-10" />
|
||||
<div class="flex justify-end items-center mt-6">
|
||||
@@ -149,7 +152,7 @@ export default {
|
||||
var payload = await this.authenticateToken()
|
||||
|
||||
if (payload) {
|
||||
this.setUserAndConnection(payload.user, payload.userDefaultLibraryId)
|
||||
this.setUserAndConnection(payload)
|
||||
} else {
|
||||
this.showAuth = true
|
||||
}
|
||||
@@ -273,7 +276,8 @@ export default {
|
||||
this.error = 'Invalid username'
|
||||
return
|
||||
}
|
||||
const duplicateConfig = this.serverConnectionConfigs.find((scc) => scc.address === this.serverConfig.address && scc.username === this.serverConfig.username)
|
||||
|
||||
const duplicateConfig = this.serverConnectionConfigs.find((scc) => scc.address === this.serverConfig.address && scc.username === this.serverConfig.username && this.serverConfig.id !== scc.id)
|
||||
if (duplicateConfig) {
|
||||
this.error = 'Config already exists for this address and username'
|
||||
return
|
||||
@@ -285,14 +289,16 @@ export default {
|
||||
var payload = await this.requestServerLogin()
|
||||
this.processing = false
|
||||
if (payload) {
|
||||
this.setUserAndConnection(payload.user, payload.userDefaultLibraryId)
|
||||
this.setUserAndConnection(payload)
|
||||
}
|
||||
},
|
||||
async setUserAndConnection(user, userDefaultLibraryId) {
|
||||
async setUserAndConnection({ user, userDefaultLibraryId, serverSettings }) {
|
||||
if (!user) return
|
||||
|
||||
console.log('Successfully logged in', JSON.stringify(user))
|
||||
|
||||
this.$store.commit('setServerSettings', serverSettings)
|
||||
|
||||
// Set library - Use last library if set and available fallback to default user library
|
||||
var lastLibraryId = await this.$localStore.getLastLibraryId()
|
||||
if (lastLibraryId && (!user.librariesAccessible.length || user.librariesAccessible.includes(lastLibraryId))) {
|
||||
|
||||
@@ -154,9 +154,6 @@ export default {
|
||||
socketConnectionFailed(err) {
|
||||
this.$toast.error('Socket connection error: ' + err.message)
|
||||
},
|
||||
socketInit(data) {
|
||||
console.log('Socket init', data)
|
||||
},
|
||||
async initLibraries() {
|
||||
if (this.inittingLibraries) {
|
||||
return
|
||||
@@ -255,7 +252,6 @@ export default {
|
||||
}
|
||||
},
|
||||
async mounted() {
|
||||
this.$socket.on('initialized', this.socketInit)
|
||||
this.$socket.on('user_updated', this.userUpdated)
|
||||
this.$socket.on('user_media_progress_updated', this.userMediaProgressUpdated)
|
||||
|
||||
@@ -283,7 +279,6 @@ export default {
|
||||
}
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.$socket.off('initialized', this.socketInit)
|
||||
this.$socket.off('user_updated', this.userUpdated)
|
||||
this.$socket.off('user_media_progress_updated', this.userMediaProgressUpdated)
|
||||
}
|
||||
|
||||
Generated
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "audiobookshelf-app",
|
||||
"version": "0.9.52-beta",
|
||||
"version": "0.9.53-beta",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "audiobookshelf-app",
|
||||
"version": "0.9.52-beta",
|
||||
"version": "0.9.53-beta",
|
||||
"author": "advplyr",
|
||||
"scripts": {
|
||||
"dev": "nuxt --hostname 0.0.0.0 --port 1337",
|
||||
|
||||
@@ -183,12 +183,10 @@ export default {
|
||||
})
|
||||
},
|
||||
initListeners() {
|
||||
// this.$server.on('initialized', this.socketInit)
|
||||
this.$eventBus.$on('library-changed', this.libraryChanged)
|
||||
// this.$eventBus.$on('downloads-loaded', this.downloadsLoaded)
|
||||
},
|
||||
removeListeners() {
|
||||
// this.$server.off('initialized', this.socketInit)
|
||||
this.$eventBus.$off('library-changed', this.libraryChanged)
|
||||
// this.$eventBus.$off('downloads-loaded', this.downloadsLoaded)
|
||||
}
|
||||
|
||||
@@ -5,6 +5,12 @@ const DownloadStatus = {
|
||||
FAILED: 3
|
||||
}
|
||||
|
||||
const SyncStatus = {
|
||||
UNSET: 0,
|
||||
SUCCESS: 1,
|
||||
FAILED: 2
|
||||
}
|
||||
|
||||
const CoverDestination = {
|
||||
METADATA: 0,
|
||||
AUDIOBOOK: 1
|
||||
@@ -31,6 +37,7 @@ const PlayerState = {
|
||||
|
||||
const Constants = {
|
||||
DownloadStatus,
|
||||
SyncStatus,
|
||||
CoverDestination,
|
||||
BookCoverAspectRatio,
|
||||
PlayMethod,
|
||||
|
||||
@@ -80,9 +80,6 @@ class ServerSocket extends EventEmitter {
|
||||
|
||||
onInit(data) {
|
||||
console.log('[SOCKET] Initial socket data received', data)
|
||||
if (data.serverSettings) {
|
||||
this.$store.commit('setServerSettings', data.serverSettings)
|
||||
}
|
||||
this.emit('initialized', true)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user