Add new connection page to support multiple server connection configs

This commit is contained in:
advplyr
2022-04-03 14:24:17 -05:00
parent 7a091dd428
commit f57f0e4e0d
30 changed files with 789 additions and 1284 deletions
@@ -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)
@@ -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<LocalMediaItem> {
fun getLocalMediaItems():MutableList<LocalMediaItem> {
var localMediaItems:MutableList<LocalMediaItem> = 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<LocalMediaItem> {
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<ServerConnectionConfig>
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)
}
}
@@ -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<ServerConfig>,
var lastServerConfigId:String?
var serverConnectionConfigs:MutableList<ServerConnectionConfig>,
var lastServerConnectionConfigId:String?
)
@JsonIgnoreProperties(ignoreUnknown = true)
@@ -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")
@@ -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<PlaybackSession>(it.toString())
cb(playbackSession)
}