diff --git a/android/app/src/main/java/com/audiobookshelf/app/AudioDownloader.kt b/android/app/src/main/java/com/audiobookshelf/app/AudioDownloader.kt index e6cb33ef..fb89c86a 100644 --- a/android/app/src/main/java/com/audiobookshelf/app/AudioDownloader.kt +++ b/android/app/src/main/java/com/audiobookshelf/app/AudioDownloader.kt @@ -146,7 +146,7 @@ class AudioDownloader : Plugin() { Log.d(tag, "Audio File Server Path $serverPath | AF RelPath ${audioFile.metadata.relPath} | LocalFolder Path ${localFolder.absolutePath} | DestName ${destinationFilename}") var destinationFile = File("$itemFolderPath/$destinationFilename") var destinationUri = Uri.fromFile(destinationFile) - var downloadUri = Uri.parse("${apiHandler.serverUrl}${serverPath}?token=${apiHandler.token}") + var downloadUri = Uri.parse("${DeviceManager.serverAddress}${serverPath}?token=${DeviceManager.token}") Log.d(tag, "Audio File Destination Uri $destinationUri | Download URI $downloadUri") var downloadItemPart = DownloadItemPart(UUID.randomUUID().toString(), destinationFilename, bookTitle, serverPath, localFolder.name ?: "", localFolder.id, downloadUri, destinationUri, null, 0) diff --git a/android/app/src/main/java/com/audiobookshelf/app/data/DbManager.kt b/android/app/src/main/java/com/audiobookshelf/app/data/DbManager.kt index ada9639b..2522ed9f 100644 --- a/android/app/src/main/java/com/audiobookshelf/app/data/DbManager.kt +++ b/android/app/src/main/java/com/audiobookshelf/app/data/DbManager.kt @@ -2,6 +2,7 @@ package com.audiobookshelf.app.data import android.util.Log import androidx.documentfile.provider.DocumentFile +import com.audiobookshelf.app.device.DeviceManager import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper import com.getcapacitor.JSObject import com.getcapacitor.Plugin @@ -19,19 +20,19 @@ import java.io.File class DbManager : Plugin() { val tag = "DbManager" - fun loadDeviceData(): DeviceData { + fun getDeviceData(): DeviceData { return Paper.book("device").read("data") ?: DeviceData(mutableListOf(), null) } - fun saveDeviceData(deviceData:DeviceData) { Paper.book("device").write("data", deviceData) } - fun loadLocalMediaItems():MutableList { + fun getLocalMediaItems():MutableList { var localMediaItems:MutableList = mutableListOf() Paper.book("localMediaItems").allKeys.forEach { var localMediaItem:LocalMediaItem? = Paper.book("localMediaItems").read(it) if (localMediaItem != null) { + // TODO: Check to make sure all file paths exist // if (localMediaItem.coverContentUrl != null) { // var file = DocumentFile.fromSingleUri(ctx) // if (!file.exists()) { @@ -45,15 +46,11 @@ class DbManager : Plugin() { // } } } -// localMediaItems = localMediaItems.filter { -// -// file.exists() -// } return localMediaItems } fun getLocalMediaItemsInFolder(folderId:String):List { - var localMediaItems = loadLocalMediaItems() + var localMediaItems = getLocalMediaItems() return localMediaItems.filter { it.folderId == folderId } @@ -111,37 +108,17 @@ class DbManager : Plugin() { return json } + // + // Database calls from webview + // @PluginMethod - fun saveFromWebview(call: PluginCall) { - var db = call.getString("db", "").toString() - var key = call.getString("key", "").toString() - var value = call.getObject("value") - + fun getDeviceData_WV(call:PluginCall) { GlobalScope.launch(Dispatchers.IO) { - if (db == "" || key == "" || value == null) { - Log.d(tag, "saveFromWebview Invalid key/value") - } else { - var json = value as JSONObject - saveObject(db, key, json) - } - call.resolve() + var deviceData = getDeviceData() + call.resolve(JSObject(jacksonObjectMapper().writeValueAsString(deviceData))) } } - @PluginMethod - fun loadFromWebview(call:PluginCall) { - var db = call.getString("db", "").toString() - var key = call.getString("key", "").toString() - if (db == "" || key == "") { - Log.d(tag, "loadFromWebview Invalid Key") - call.resolve() - return - } - var json = loadObject(db, key) - var jsobj = JSObject.fromJSONObject(json) - call.resolve(jsobj) - } - @PluginMethod fun getLocalFolders_WV(call:PluginCall) { GlobalScope.launch(Dispatchers.IO) { @@ -175,4 +152,108 @@ class DbManager : Plugin() { call.resolve(jsobj) } } + + @PluginMethod + fun setCurrentServerConnectionConfig_WV(call:PluginCall) { + var serverConnectionConfigId = call.getString("id", "").toString() + var serverConnectionConfig = DeviceManager.deviceData.serverConnectionConfigs.find { it.id == serverConnectionConfigId } + + var username = call.getString("username", "").toString() + var token = call.getString("token", "").toString() + + GlobalScope.launch(Dispatchers.IO) { + if (serverConnectionConfig == null) { // New Server Connection + var serverAddress = call.getString("address", "").toString() + + // Create new server connection config + var sscId = DeviceManager.getBase64Id("$serverAddress@$username") + var sscIndex = DeviceManager.deviceData.serverConnectionConfigs.size + serverConnectionConfig = ServerConnectionConfig(sscId, sscIndex, "$serverAddress ($username)", serverAddress, username, token) + + // Add and save + DeviceManager.deviceData.serverConnectionConfigs.add(serverConnectionConfig!!) + DeviceManager.deviceData.lastServerConnectionConfigId = serverConnectionConfig?.id + saveDeviceData(DeviceManager.deviceData) + } else { + var shouldSave = false + if (serverConnectionConfig?.username != username || serverConnectionConfig?.token != token) { + serverConnectionConfig?.username = username + serverConnectionConfig?.name = "${serverConnectionConfig?.address} (${serverConnectionConfig?.username})" + serverConnectionConfig?.token = token + shouldSave = true + } + + // Set last connection config + if (DeviceManager.deviceData.lastServerConnectionConfigId != serverConnectionConfigId) { + DeviceManager.deviceData.lastServerConnectionConfigId = serverConnectionConfigId + shouldSave = true + } + + if (shouldSave) saveDeviceData(DeviceManager.deviceData) + } + + DeviceManager.serverConnectionConfig = serverConnectionConfig + call.resolve(JSObject(jacksonObjectMapper().writeValueAsString(DeviceManager.serverConnectionConfig))) + } + } + + @PluginMethod + fun removeServerConnectionConfig_WV(call:PluginCall) { + GlobalScope.launch(Dispatchers.IO) { + var serverConnectionConfigId = call.getString("serverConnectionConfigId", "").toString() + DeviceManager.deviceData.serverConnectionConfigs = DeviceManager.deviceData.serverConnectionConfigs.filter { it.id != serverConnectionConfigId } as MutableList + if (DeviceManager.deviceData.lastServerConnectionConfigId == serverConnectionConfigId) { + DeviceManager.deviceData.lastServerConnectionConfigId = null + } + saveDeviceData(DeviceManager.deviceData) + if (DeviceManager.serverConnectionConfig?.id == serverConnectionConfigId) { + DeviceManager.serverConnectionConfig = null + } + call.resolve() + } + } + + @PluginMethod + fun logout_WV(call:PluginCall) { + GlobalScope.launch(Dispatchers.IO) { + DeviceManager.serverConnectionConfig = null + DeviceManager.deviceData.lastServerConnectionConfigId = null + saveDeviceData(DeviceManager.deviceData) + call.resolve() + } + } + + // + // Generic Webview calls to db + // + @PluginMethod + fun saveFromWebview(call: PluginCall) { + var db = call.getString("db", "").toString() + var key = call.getString("key", "").toString() + var value = call.getObject("value") + + GlobalScope.launch(Dispatchers.IO) { + if (db == "" || key == "" || value == null) { + Log.d(tag, "saveFromWebview Invalid key/value") + } else { + var json = value as JSONObject + saveObject(db, key, json) + } + call.resolve() + } + } + + @PluginMethod + fun loadFromWebview(call:PluginCall) { + var db = call.getString("db", "").toString() + var key = call.getString("key", "").toString() + if (db == "" || key == "") { + Log.d(tag, "loadFromWebview Invalid Key") + call.resolve() + return + } + var json = loadObject(db, key) + var jsobj = JSObject.fromJSONObject(json) + call.resolve(jsobj) + } } diff --git a/android/app/src/main/java/com/audiobookshelf/app/data/DeviceClasses.kt b/android/app/src/main/java/com/audiobookshelf/app/data/DeviceClasses.kt index afa63ea3..a2885278 100644 --- a/android/app/src/main/java/com/audiobookshelf/app/data/DeviceClasses.kt +++ b/android/app/src/main/java/com/audiobookshelf/app/data/DeviceClasses.kt @@ -4,7 +4,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore import com.fasterxml.jackson.annotation.JsonIgnoreProperties import java.util.* -data class ServerConfig( +data class ServerConnectionConfig( var id:String, var index:Int, var name:String, @@ -14,8 +14,8 @@ data class ServerConfig( ) data class DeviceData( - var serverConfigs:MutableList, - var lastServerConfigId:String? + var serverConnectionConfigs:MutableList, + var lastServerConnectionConfigId:String? ) @JsonIgnoreProperties(ignoreUnknown = true) diff --git a/android/app/src/main/java/com/audiobookshelf/app/device/DeviceManager.kt b/android/app/src/main/java/com/audiobookshelf/app/device/DeviceManager.kt index 0dad8609..8955df16 100644 --- a/android/app/src/main/java/com/audiobookshelf/app/device/DeviceManager.kt +++ b/android/app/src/main/java/com/audiobookshelf/app/device/DeviceManager.kt @@ -1,19 +1,18 @@ package com.audiobookshelf.app.device import android.util.Log -import com.anggrayudi.storage.file.id import com.audiobookshelf.app.data.DbManager import com.audiobookshelf.app.data.DeviceData -import com.audiobookshelf.app.data.ServerConfig +import com.audiobookshelf.app.data.ServerConnectionConfig object DeviceManager { val tag = "DeviceManager" val dbManager:DbManager = DbManager() - var deviceData:DeviceData = dbManager.loadDeviceData() - var currentServerConfig: ServerConfig? = null + var deviceData:DeviceData = dbManager.getDeviceData() + var serverConnectionConfig: ServerConnectionConfig? = null - val serverAddress get() = currentServerConfig?.address ?: "" - val token get() = currentServerConfig?.token ?: "" + val serverAddress get() = serverConnectionConfig?.address ?: "" + val token get() = serverConnectionConfig?.token ?: "" init { Log.d(tag, "Device Manager Singleton invoked") diff --git a/android/app/src/main/java/com/audiobookshelf/app/server/ApiHandler.kt b/android/app/src/main/java/com/audiobookshelf/app/server/ApiHandler.kt index c7e02e10..2d8ff56e 100644 --- a/android/app/src/main/java/com/audiobookshelf/app/server/ApiHandler.kt +++ b/android/app/src/main/java/com/audiobookshelf/app/server/ApiHandler.kt @@ -1,13 +1,12 @@ package com.audiobookshelf.app.server -import android.app.Activity import android.content.Context import android.content.SharedPreferences import android.util.Log import com.audiobookshelf.app.data.Library import com.audiobookshelf.app.data.LibraryItem -import com.audiobookshelf.app.data.MediaTypeMetadata import com.audiobookshelf.app.data.PlaybackSession +import com.audiobookshelf.app.device.DeviceManager import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper import com.fasterxml.jackson.module.kotlin.readValue import com.getcapacitor.JSArray @@ -21,26 +20,15 @@ class ApiHandler { val tag = "ApiHandler" private var client = OkHttpClient() var ctx: Context - var serverUrl = "" - var token = "" var storageSharedPreferences: SharedPreferences? = null constructor(_ctx: Context) { ctx = _ctx - init() - } - - fun init() { - storageSharedPreferences = ctx.getSharedPreferences("CapacitorStorage", Activity.MODE_PRIVATE) - serverUrl = storageSharedPreferences?.getString("serverUrl", "").toString() - Log.d(tag, "SHARED PREF SERVERURL $serverUrl") - token = storageSharedPreferences?.getString("token", "").toString() - Log.d(tag, "SHARED PREF TOKEN $token") } fun getRequest(endpoint:String, cb: (JSObject) -> Unit) { val request = Request.Builder() - .url("$serverUrl$endpoint").addHeader("Authorization", "Bearer $token") + .url("${DeviceManager.serverAddress}$endpoint").addHeader("Authorization", "Bearer ${DeviceManager.token}") .build() makeRequest(request, cb) } @@ -49,7 +37,7 @@ class ApiHandler { val mediaType = "application/json; charset=utf-8".toMediaType() val requestBody = payload.toString().toRequestBody(mediaType) val request = Request.Builder().post(requestBody) - .url("$serverUrl$endpoint").addHeader("Authorization", "Bearer $token") + .url("${DeviceManager.serverAddress}$endpoint").addHeader("Authorization", "Bearer ${DeviceManager.token}") .build() makeRequest(request, cb) } @@ -125,8 +113,8 @@ class ApiHandler { else payload.put("forceTranscode", true) postRequest("/api/items/$libraryItemId/play", payload) { - it.put("serverUrl", serverUrl) - it.put("token", token) + it.put("serverUrl", DeviceManager.serverAddress) + it.put("token", DeviceManager.token) val playbackSession = mapper.readValue(it.toString()) cb(playbackSession) } diff --git a/components/app/AudioPlayerContainer.vue b/components/app/AudioPlayerContainer.vue index 52877c4a..d3dac020 100644 --- a/components/app/AudioPlayerContainer.vue +++ b/components/app/AudioPlayerContainer.vue @@ -151,15 +151,15 @@ export default { } }, setListeners() { - if (!this.$server.socket) { - console.error('Invalid server socket not set') - return - } - this.$server.socket.on('stream_open', this.streamOpen) - this.$server.socket.on('stream_closed', this.streamClosed) - this.$server.socket.on('stream_progress', this.streamProgress) - this.$server.socket.on('stream_ready', this.streamReady) - this.$server.socket.on('stream_reset', this.streamReset) + // if (!this.$server.socket) { + // console.error('Invalid server socket not set') + // return + // } + // this.$server.socket.on('stream_open', this.streamOpen) + // this.$server.socket.on('stream_closed', this.streamClosed) + // this.$server.socket.on('stream_progress', this.streamProgress) + // this.$server.socket.on('stream_ready', this.streamReady) + // this.$server.socket.on('stream_reset', this.streamReset) }, closeStreamOnly() { // If user logs out or disconnects from server and not playing local @@ -203,13 +203,13 @@ export default { if (this.onSleepTimerEndedListener) this.onSleepTimerEndedListener.remove() if (this.onSleepTimerSetListener) this.onSleepTimerSetListener.remove() - if (this.$server.socket) { - this.$server.socket.off('stream_open', this.streamOpen) - this.$server.socket.off('stream_closed', this.streamClosed) - this.$server.socket.off('stream_progress', this.streamProgress) - this.$server.socket.off('stream_ready', this.streamReady) - this.$server.socket.off('stream_reset', this.streamReset) - } + // if (this.$server.socket) { + // this.$server.socket.off('stream_open', this.streamOpen) + // this.$server.socket.off('stream_closed', this.streamClosed) + // this.$server.socket.off('stream_progress', this.streamProgress) + // this.$server.socket.off('stream_ready', this.streamReady) + // this.$server.socket.off('stream_reset', this.streamReset) + // } this.$eventBus.$off('play-item', this.playLibraryItem) this.$eventBus.$off('play-local-item', this.playLocalItem) this.$eventBus.$off('close-stream', this.closeStreamOnly) diff --git a/components/app/SideDrawer.vue b/components/app/SideDrawer.vue index cd39fb84..8aaf3e47 100644 --- a/components/app/SideDrawer.vue +++ b/components/app/SideDrawer.vue @@ -3,7 +3,7 @@
-

+

Welcome, {{ username }}

@@ -16,12 +16,17 @@
-
-

{{ $config.version }}

-
-
-

Logout

- logout +
+
+

{{ serverConnectionConfig.address }}

+
+
+

{{ $config.version }}

+
+
+

Logout

+ logout +
@@ -62,6 +67,9 @@ export default { user() { return this.$store.state.user.user }, + serverConnectionConfig() { + return this.$store.state.user.serverConnectionConfig + }, username() { return this.user ? this.user.username : '' }, @@ -112,7 +120,9 @@ export default { await this.$axios.$post('/logout').catch((error) => { console.error(error) }) - this.$server.logout() + this.$socket.logout() + await this.$db.logout() + this.$store.commit('user/logout') this.$router.push('/connect') }, touchstart(e) { diff --git a/components/bookshelf/LazyBookshelf.vue b/components/bookshelf/LazyBookshelf.vue index 0874849b..24b87168 100644 --- a/components/bookshelf/LazyBookshelf.vue +++ b/components/bookshelf/LazyBookshelf.vue @@ -448,15 +448,15 @@ export default { this.$eventBus.$on('downloads-loaded', this.downloadsLoaded) this.$store.commit('user/addSettingsListener', { id: 'lazy-bookshelf', meth: this.settingsUpdated }) - if (this.$server.socket) { - this.$server.socket.on('item_updated', this.libraryItemUpdated) - this.$server.socket.on('item_added', this.libraryItemAdded) - this.$server.socket.on('item_removed', this.libraryItemRemoved) - this.$server.socket.on('items_updated', this.libraryItemsUpdated) - this.$server.socket.on('items_added', this.libraryItemsAdded) - } else { - console.error('Bookshelf - Socket not initialized') - } + // if (this.$server.socket) { + // this.$server.socket.on('item_updated', this.libraryItemUpdated) + // this.$server.socket.on('item_added', this.libraryItemAdded) + // this.$server.socket.on('item_removed', this.libraryItemRemoved) + // this.$server.socket.on('items_updated', this.libraryItemsUpdated) + // this.$server.socket.on('items_added', this.libraryItemsAdded) + // } else { + // console.error('Bookshelf - Socket not initialized') + // } }, removeListeners() { var bookshelf = document.getElementById('bookshelf-wrapper') @@ -468,28 +468,28 @@ export default { this.$eventBus.$off('downloads-loaded', this.downloadsLoaded) this.$store.commit('user/removeSettingsListener', 'lazy-bookshelf') - if (this.$server.socket) { - this.$server.socket.off('item_updated', this.libraryItemUpdated) - this.$server.socket.off('item_added', this.libraryItemAdded) - this.$server.socket.off('item_removed', this.libraryItemRemoved) - this.$server.socket.off('items_updated', this.libraryItemsUpdated) - this.$server.socket.off('items_added', this.libraryItemsAdded) - } else { - console.error('Bookshelf - Socket not initialized') - } + // if (this.$server.socket) { + // this.$server.socket.off('item_updated', this.libraryItemUpdated) + // this.$server.socket.off('item_added', this.libraryItemAdded) + // this.$server.socket.off('item_removed', this.libraryItemRemoved) + // this.$server.socket.off('items_updated', this.libraryItemsUpdated) + // this.$server.socket.off('items_added', this.libraryItemsAdded) + // } else { + // console.error('Bookshelf - Socket not initialized') + // } } }, mounted() { - if (this.$server.initialized) { - this.init() - } else { - this.initDownloads() - } - this.$server.on('initialized', this.socketInit) + // if (this.$server.initialized) { + // this.init() + // } else { + // this.initDownloads() + // } + this.$socket.on('initialized', this.socketInit) this.initListeners() }, beforeDestroy() { - this.$server.off('initialized', this.socketInit) + this.$socket.off('initialized', this.socketInit) this.removeListeners() } } diff --git a/components/connection/ServerConnectForm.vue b/components/connection/ServerConnectForm.vue new file mode 100644 index 00000000..976e5219 --- /dev/null +++ b/components/connection/ServerConnectForm.vue @@ -0,0 +1,312 @@ + + + \ No newline at end of file diff --git a/components/modals/DownloadsModal.vue b/components/modals/DownloadsModal.vue deleted file mode 100644 index 212c1e23..00000000 --- a/components/modals/DownloadsModal.vue +++ /dev/null @@ -1,254 +0,0 @@ - - - - - \ No newline at end of file diff --git a/components/modals/LibrariesModal.vue b/components/modals/LibrariesModal.vue index ff783032..1175a7b0 100644 --- a/components/modals/LibrariesModal.vue +++ b/components/modals/LibrariesModal.vue @@ -55,7 +55,6 @@ export default { this.show = false await this.$store.dispatch('libraries/fetch', lib.id) this.$eventBus.$emit('library-changed', lib.id) - this.$localStore.setCurrentLibrary(lib) } }, mounted() {} diff --git a/components/modals/SelectLocalFolderModal.vue b/components/modals/SelectLocalFolderModal.vue index 2470a34f..36cc2b17 100644 --- a/components/modals/SelectLocalFolderModal.vue +++ b/components/modals/SelectLocalFolderModal.vue @@ -53,7 +53,7 @@ export default { this.$emit('select', folder) }, async init() { - var localFolders = (await this.$db.loadFolders()) || [] + var localFolders = (await this.$db.getLocalFolders()) || [] this.localFolders = localFolders.filter((lf) => lf.mediaType == this.mediaType) } }, diff --git a/layouts/default.vue b/layouts/default.vue index 943d4743..e13a878d 100644 --- a/layouts/default.vue +++ b/layouts/default.vue @@ -40,6 +40,9 @@ export default { networkConnected() { return this.$store.state.networkConnected }, + user() { + return this.$store.state.user.user + }, currentLibraryId() { return this.$store.state.libraries.currentLibraryId }, @@ -48,24 +51,6 @@ export default { } }, methods: { - async connected(isConnected) { - if (isConnected) { - console.log('[Default] Connected socket sync user ab data') - // this.$store.dispatch('user/syncUserAudiobookData') - - this.initSocketListeners() - - // Load libraries - await this.$store.dispatch('libraries/load') - this.$eventBus.$emit('library-changed') - this.$store.dispatch('libraries/fetch', this.currentLibraryId) - } else { - this.removeSocketListeners() - } - }, - socketConnectionFailed(err) { - this.$toast.error('Socket connection error: ' + err.message) - }, currentUserAudiobookUpdate({ id, data }) { if (data) { console.log(`Current User Audiobook Updated ${id} ${JSON.stringify(data)}`) @@ -218,41 +203,41 @@ export default { return {} } }, - async syncDownloads(downloads, downloadFolder) { - console.log('Syncing downloads ' + downloads.length) - var mediaScanResults = await this.searchFolder(downloadFolder) + // async syncDownloads(downloads, downloadFolder) { + // console.log('Syncing downloads ' + downloads.length) + // var mediaScanResults = await this.searchFolder(downloadFolder) - this.$store.commit('downloads/setMediaScanResults', mediaScanResults) + // this.$store.commit('downloads/setMediaScanResults', mediaScanResults) - // Filter out media folders without any audio files - var mediaFolders = mediaScanResults.folders.filter((sr) => { - if (!sr.files) return false - var audioFiles = sr.files.filter((mf) => !!mf.isAudio) - return audioFiles.length - }) + // // Filter out media folders without any audio files + // var mediaFolders = mediaScanResults.folders.filter((sr) => { + // if (!sr.files) return false + // var audioFiles = sr.files.filter((mf) => !!mf.isAudio) + // return audioFiles.length + // }) - downloads.forEach((download) => { - var mediaFolder = mediaFolders.find((mf) => mf.name === download.folderName) - if (mediaFolder) { - console.log('Found download ' + download.folderName) - if (download.isMissing) { - download.isMissing = false - this.$store.commit('downloads/addUpdateDownload', download) - } - } else { - console.error('Download not found ' + download.folderName) - if (!download.isMissing) { - download.isMissing = true - this.$store.commit('downloads/addUpdateDownload', download) - } - } - }) + // downloads.forEach((download) => { + // var mediaFolder = mediaFolders.find((mf) => mf.name === download.folderName) + // if (mediaFolder) { + // console.log('Found download ' + download.folderName) + // if (download.isMissing) { + // download.isMissing = false + // this.$store.commit('downloads/addUpdateDownload', download) + // } + // } else { + // console.error('Download not found ' + download.folderName) + // if (!download.isMissing) { + // download.isMissing = true + // this.$store.commit('downloads/addUpdateDownload', download) + // } + // } + // }) - // Match media scanned folders with books from server - if (this.isSocketConnected) { - await this.$store.dispatch('downloads/linkOrphanDownloads') - } - }, + // // Match media scanned folders with books from server + // if (this.isSocketConnected) { + // await this.$store.dispatch('downloads/linkOrphanDownloads') + // } + // }, onItemDownloadUpdate(data) { console.log('ON ITEM DOWNLOAD UPDATE', JSON.stringify(data)) }, @@ -274,22 +259,18 @@ export default { // this.onDownloadProgress(data) // }) - var downloads = await this.$store.dispatch('downloads/loadFromStorage') - var downloadFolder = await this.$localStore.getDownloadFolder() + // var downloads = await this.$store.dispatch('downloads/loadFromStorage') + // var downloadFolder = await this.$localStore.getDownloadFolder() + // this.$eventBus.$emit('downloads-loaded') - if (downloadFolder) { - // await this.syncDownloads(downloads, downloadFolder) - } - this.$eventBus.$emit('downloads-loaded') - - var checkPermission = await StorageManager.checkStoragePermission() - console.log('Storage Permission is' + checkPermission.value) - if (!checkPermission.value) { - console.log('Will require permissions') - } else { - console.log('Has Storage Permission') - this.$store.commit('setHasStoragePermission', true) - } + // var checkPermission = await StorageManager.checkStoragePermission() + // console.log('Storage Permission is' + checkPermission.value) + // if (!checkPermission.value) { + // console.log('Will require permissions') + // } else { + // console.log('Has Storage Permission') + // this.$store.commit('setHasStoragePermission', true) + // } }, async loadSavedSettings() { var userSavedServerSettings = await this.$localStore.getServerSettings() @@ -305,42 +286,44 @@ export default { console.log('Loading offline user audiobook data') await this.$store.dispatch('user/loadOfflineUserAudiobookData') }, - showErrorToast(message) { - this.$toast.error(message) - }, - showSuccessToast(message) { - this.$toast.success(message) - }, async attemptConnection() { - if (!this.$server) return if (!this.networkConnected) { console.warn('No network connection') return } - var localServerUrl = await this.$localStore.getServerUrl() - var localUserToken = await this.$localStore.getToken() - if (localServerUrl) { - // Server and Token are stored - if (localUserToken) { - var isSocketAlreadyEstablished = this.$server.socket - var success = await this.$server.connect(localServerUrl, localUserToken) - if (!success && !this.$server.url) { - // Bad URL - } else if (!success) { - // Failed to connect - } else if (isSocketAlreadyEstablished) { - // No need to wait for connect event - } - } + var deviceData = await this.$db.getDeviceData() + var serverConfig = null + if (deviceData && deviceData.lastServerConnectionConfigId && deviceData.serverConnectionConfigs.length) { + serverConfig = deviceData.serverConnectionConfigs.find((scc) => scc.id == deviceData.lastServerConnectionConfigId) } + if (!serverConfig) { + // No last server config set + return + } + + var authRes = await this.$axios.$post(`${serverConfig.address}/api/authorize`, null, { headers: { Authorization: `Bearer ${serverConfig.token}` } }).catch((error) => { + console.error('[Server] Server auth failed', error) + var errorMsg = error.response ? error.response.data || 'Unknown Error' : 'Unknown Error' + this.error = errorMsg + return false + }) + if (!authRes) return + + const { user, userDefaultLibraryId } = authRes + if (userDefaultLibraryId) { + this.$store.commit('libraries/setCurrentLibrary', userDefaultLibraryId) + } + var serverConnectionConfig = await this.$db.setServerConnectionConfig(serverConfig) + + this.$store.commit('user/setUser', user) + this.$store.commit('user/setServerConnectionConfig', serverConnectionConfig) + + this.$socket.connect(serverConnectionConfig.address, serverConnectionConfig.token) + + console.log('Successful connection on last saved connection config', JSON.stringify(serverConnectionConfig)) + await this.initLibraries() }, - // audiobookAdded(audiobook) { - // this.$store.commit('libraries/updateFilterDataWithAudiobook', audiobook) - // }, - // audiobookUpdated(audiobook) { - // this.$store.commit('libraries/updateFilterDataWithAudiobook', audiobook) - // }, itemRemoved(libraryItem) { if (this.$route.name.startsWith('item')) { if (this.$route.params.id === libraryItem.id) { @@ -348,60 +331,45 @@ export default { } } }, - // audiobooksAdded(audiobooks) { - // audiobooks.forEach((ab) => { - // this.audiobookAdded(ab) - // }) - // }, - // audiobooksUpdated(audiobooks) { - // audiobooks.forEach((ab) => { - // this.audiobookUpdated(ab) - // }) - // }, userLoggedOut() { // Only cancels stream if streamining not playing downloaded this.$eventBus.$emit('close-stream') }, - initSocketListeners() { - if (this.$server.socket) { - // this.$server.socket.on('audiobook_updated', this.audiobookUpdated) - // this.$server.socket.on('audiobook_added', this.audiobookAdded) - this.$server.socket.on('item_removed', this.itemRemoved) - // this.$server.socket.on('audiobooks_updated', this.audiobooksUpdated) - // this.$server.socket.on('audiobooks_added', this.audiobooksAdded) - } + socketConnectionUpdate(isConnected) { + console.log('Socket connection update', isConnected) }, - removeSocketListeners() { - if (this.$server.socket) { - // this.$server.socket.off('audiobook_updated', this.audiobookUpdated) - // this.$server.socket.off('audiobook_added', this.audiobookAdded) - this.$server.socket.off('item_removed', this.itemRemoved) - // this.$server.socket.off('audiobooks_updated', this.audiobooksUpdated) - // this.$server.socket.off('audiobooks_added', this.audiobooksAdded) - } + socketConnectionFailed(err) { + this.$toast.error('Socket connection error: ' + err.message) + }, + socketInit(data) {}, + async initLibraries() { + await this.$store.dispatch('libraries/load') + this.$eventBus.$emit('library-changed') + this.$store.dispatch('libraries/fetch', this.currentLibraryId) } }, async mounted() { - if (!this.$server) return console.error('No Server') - // console.log(`Default Mounted set SOCKET listeners ${this.$server.connected}`) + // this.$server.on('logout', this.userLoggedOut) + // this.$server.on('connected', this.connected) + // this.$server.on('connectionFailed', this.socketConnectionFailed) + // this.$server.on('initialStream', this.initialStream) + // this.$server.on('currentUserAudiobookUpdate', this.currentUserAudiobookUpdate) + // this.$server.on('show_error_toast', this.showErrorToast) + // this.$server.on('show_success_toast', this.showSuccessToast) - if (this.$server.connected) { - console.log('Syncing on default mount') - this.connected(true) - } - - this.$server.on('logout', this.userLoggedOut) - this.$server.on('connected', this.connected) - this.$server.on('connectionFailed', this.socketConnectionFailed) - this.$server.on('initialStream', this.initialStream) - this.$server.on('currentUserAudiobookUpdate', this.currentUserAudiobookUpdate) - this.$server.on('show_error_toast', this.showErrorToast) - this.$server.on('show_success_toast', this.showSuccessToast) + this.$socket.on('connection-update', this.socketConnectionUpdate) + this.$socket.on('initialized', this.socketInit) if (this.$store.state.isFirstLoad) { this.$store.commit('setIsFirstLoad', false) await this.$store.dispatch('setupNetworkListener') - this.attemptConnection() + + if (this.$store.state.user.serverConnectionConfig) { + await this.initLibraries() + } else { + await this.attemptConnection() + } + this.checkForUpdate() this.loadSavedSettings() this.initMediaStore() @@ -412,13 +380,9 @@ export default { console.error('No Server beforeDestroy') return } - this.removeSocketListeners() - this.$server.off('logout', this.userLoggedOut) - this.$server.off('connected', this.connected) - this.$server.off('connectionFailed', this.socketConnectionFailed) - this.$server.off('initialStream', this.initialStream) - this.$server.off('show_error_toast', this.showErrorToast) - this.$server.off('show_success_toast', this.showSuccessToast) + + this.$socket.off('connection-update', this.socketConnectionUpdate) + this.$socket.off('initialized', this.socketInit) } } diff --git a/pages/audiobook/_id/index.vue b/pages/audiobook/_id/index.vue deleted file mode 100644 index d00aca5f..00000000 --- a/pages/audiobook/_id/index.vue +++ /dev/null @@ -1,442 +0,0 @@ - - - \ No newline at end of file diff --git a/pages/bookshelf/index.vue b/pages/bookshelf/index.vue index 3f2d6a59..3d72868a 100644 --- a/pages/bookshelf/index.vue +++ b/pages/bookshelf/index.vue @@ -8,20 +8,20 @@

Bookshelf empty - + for library {{ currentLibraryName }}

-
+
cloud_off

Audiobookshelf server not connected.

-

Important! This app requires that you are running your own server and does not provide any content.

+
- Connect + Connect
@@ -46,6 +46,9 @@ export default { return ab }) }, + user() { + return this.$store.state.user.user + }, isSocketConnected() { return this.$store.state.socketConnected }, @@ -133,16 +136,16 @@ export default { this.shelves = categories console.log('Shelves', this.shelves) }, - async socketInit(isConnected) { - if (isConnected && this.currentLibraryId) { - console.log('Connected - Load from server') - await this.fetchCategories() - } else { - console.log('Disconnected - Reset to local storage') - this.shelves = this.downloadOnlyShelves - } - this.loading = false - }, + // async socketInit(isConnected) { + // if (isConnected && this.currentLibraryId) { + // console.log('Connected - Load from server') + // await this.fetchCategories() + // } else { + // console.log('Disconnected - Reset to local storage') + // this.shelves = this.downloadOnlyShelves + // } + // this.loading = false + // }, async libraryChanged(libid) { if (this.isSocketConnected && this.currentLibraryId) { await this.fetchCategories() @@ -211,43 +214,24 @@ export default { }) }, initListeners() { - this.$server.on('initialized', this.socketInit) + // this.$server.on('initialized', this.socketInit) this.$eventBus.$on('library-changed', this.libraryChanged) this.$eventBus.$on('downloads-loaded', this.downloadsLoaded) - - if (this.$server.socket) { - this.$server.socket.on('audiobook_updated', this.audiobookUpdated) - this.$server.socket.on('audiobook_added', this.audiobookAdded) - this.$server.socket.on('audiobook_removed', this.audiobookRemoved) - this.$server.socket.on('audiobooks_updated', this.audiobooksUpdated) - this.$server.socket.on('audiobooks_added', this.audiobooksAdded) - } else { - console.error('Error socket not initialized') - } }, removeListeners() { - this.$server.off('initialized', this.socketInit) + // this.$server.off('initialized', this.socketInit) this.$eventBus.$off('library-changed', this.libraryChanged) this.$eventBus.$off('downloads-loaded', this.downloadsLoaded) - - if (this.$server.socket) { - this.$server.socket.off('audiobook_updated', this.audiobookUpdated) - this.$server.socket.off('audiobook_added', this.audiobookAdded) - this.$server.socket.off('audiobook_removed', this.audiobookRemoved) - this.$server.socket.off('audiobooks_updated', this.audiobooksUpdated) - this.$server.socket.off('audiobooks_added', this.audiobooksAdded) - } else { - console.error('Error socket not initialized') - } } }, mounted() { this.initListeners() - if (this.$server.initialized && this.currentLibraryId) { - this.fetchCategories() - } else { - this.shelves = this.downloadOnlyShelves - } + this.fetchCategories() + // if (this.$server.initialized && this.currentLibraryId) { + // this.fetchCategories() + // } else { + // this.shelves = this.downloadOnlyShelves + // } }, beforeDestroy() { this.removeListeners() diff --git a/pages/connect.vue b/pages/connect.vue index 94e7b209..e0c88514 100644 --- a/pages/connect.vue +++ b/pages/connect.vue @@ -10,53 +10,11 @@
-

Important! This app requires that you are running your own server and does not provide any content.

+ -
-
-

Login Success!

-

Connecting socket..

-
-
-

Server address

-
- -
- {{ networkConnected ? 'Submit' : 'No Internet' }} -
- - - -
- warning -

{{ error }}

-
-
-
-
-
-
-
- -
- - - -
+
+
Follow the project on Github \ No newline at end of file diff --git a/pages/downloads.vue b/pages/downloads.vue index c08a69f8..3915f9d1 100644 --- a/pages/downloads.vue +++ b/pages/downloads.vue @@ -277,7 +277,7 @@ export default { } }, async init() { - this.localFolders = (await this.$db.loadFolders()) || [] + this.localFolders = (await this.$db.getLocalFolders()) || [] AudioDownloader.addListener('onDownloadProgress', this.onDownloadProgress) } }, diff --git a/pages/item/_id.vue b/pages/item/_id.vue index d2ebd3bd..62fbb7fe 100644 --- a/pages/item/_id.vue +++ b/pages/item/_id.vue @@ -61,7 +61,7 @@ export default { var libraryItemId = params.id var libraryItem = null - if (app.$server.connected) { + if (store.state.user.serverConnectionConfig) { libraryItem = await app.$axios.$get(`/api/items/${libraryItemId}?expanded=1`).catch((error) => { console.error('Failed', error) return false @@ -218,10 +218,10 @@ export default { // } }, async clearProgressClick() { - if (!this.$server.connected) { - this.$toast.info('Clear downloaded book progress not yet implemented') - return - } + // if (!this.$server.connected) { + // this.$toast.info('Clear downloaded book progress not yet implemented') + // return + // } const { value } = await Dialog.confirm({ title: 'Confirm', @@ -264,9 +264,6 @@ export default { this.download() }, async download(selectedLocalFolder = null) { - console.log('downloadClick ' + this.$server.connected + ' | ' + !!this.downloadObj) - if (!this.$server.connected) return - if (!this.numTracks || this.downloadObj) { return } @@ -274,7 +271,7 @@ export default { // Get the local folder to download to var localFolder = selectedLocalFolder if (!localFolder) { - var localFolders = (await this.$db.loadFolders()) || [] + var localFolders = (await this.$db.getLocalFolders()) || [] console.log('Local folders loaded', localFolders.length) var foldersWithMediaType = localFolders.filter((lf) => { console.log('Checking local folder', lf.mediaType) @@ -468,24 +465,24 @@ export default { } }, mounted() { - if (!this.$server.socket) { - console.warn('Library Item Page mounted: Server socket not set') - } else { - this.$server.socket.on('download_ready', this.downloadReady) - this.$server.socket.on('download_killed', this.downloadKilled) - this.$server.socket.on('download_failed', this.downloadFailed) - this.$server.socket.on('item_updated', this.itemUpdated) - } + // if (!this.$server.socket) { + // console.warn('Library Item Page mounted: Server socket not set') + // } else { + // this.$server.socket.on('download_ready', this.downloadReady) + // this.$server.socket.on('download_killed', this.downloadKilled) + // this.$server.socket.on('download_failed', this.downloadFailed) + // this.$server.socket.on('item_updated', this.itemUpdated) + // } }, beforeDestroy() { - if (!this.$server.socket) { - console.warn('Library Item Page beforeDestroy: Server socket not set') - } else { - this.$server.socket.off('download_ready', this.downloadReady) - this.$server.socket.off('download_killed', this.downloadKilled) - this.$server.socket.off('download_failed', this.downloadFailed) - this.$server.socket.off('item_updated', this.itemUpdated) - } + // if (!this.$server.socket) { + // console.warn('Library Item Page beforeDestroy: Server socket not set') + // } else { + // this.$server.socket.off('download_ready', this.downloadReady) + // this.$server.socket.off('download_killed', this.downloadKilled) + // this.$server.socket.off('download_failed', this.downloadFailed) + // this.$server.socket.off('item_updated', this.itemUpdated) + // } } } \ No newline at end of file diff --git a/pages/localMedia/folders/index.vue b/pages/localMedia/folders/index.vue index 689850d3..b18282ce 100644 --- a/pages/localMedia/folders/index.vue +++ b/pages/localMedia/folders/index.vue @@ -82,7 +82,7 @@ export default { this.$router.push(`/localMedia/folders/${folderObj.id}?scan=1`) }, async init() { - this.localFolders = (await this.$db.loadFolders()) || [] + this.localFolders = (await this.$db.getLocalFolders()) || [] } }, mounted() { diff --git a/pages/search.vue b/pages/search.vue index 6c9153f5..e76af041 100644 --- a/pages/search.vue +++ b/pages/search.vue @@ -13,7 +13,7 @@

Books