mirror of
https://github.com/advplyr/audiobookshelf-app.git
synced 2025-07-21 19:25:00 +02:00
Add custom headers modal and model
This commit is contained in:
parent
cd4c280950
commit
317dc366e3
8 changed files with 193 additions and 59 deletions
|
@ -1,10 +1,13 @@
|
||||||
package com.audiobookshelf.app
|
package com.audiobookshelf.app
|
||||||
|
|
||||||
import android.Manifest
|
import android.Manifest
|
||||||
import android.app.DownloadManager
|
import android.content.ComponentName
|
||||||
import android.content.*
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.content.ServiceConnection
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.os.*
|
import android.os.Bundle
|
||||||
|
import android.os.IBinder
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import androidx.core.app.ActivityCompat
|
import androidx.core.app.ActivityCompat
|
||||||
import com.anggrayudi.storage.SimpleStorage
|
import com.anggrayudi.storage.SimpleStorage
|
||||||
|
@ -140,9 +143,4 @@ class MainActivity : BridgeActivity() {
|
||||||
// Mandatory for Activity, but not for Fragment & ComponentActivity
|
// Mandatory for Activity, but not for Fragment & ComponentActivity
|
||||||
storageHelper.onRequestPermissionsResult(requestCode, permissions, grantResults)
|
storageHelper.onRequestPermissionsResult(requestCode, permissions, grantResults)
|
||||||
}
|
}
|
||||||
|
|
||||||
// override fun onUserInteraction() {
|
|
||||||
// super.onUserInteraction()
|
|
||||||
// Log.d(tag, "USER INTERACTION")
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@ import com.fasterxml.jackson.annotation.JsonIgnore
|
||||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties
|
import com.fasterxml.jackson.annotation.JsonIgnoreProperties
|
||||||
import com.fasterxml.jackson.annotation.JsonSubTypes
|
import com.fasterxml.jackson.annotation.JsonSubTypes
|
||||||
import com.fasterxml.jackson.annotation.JsonTypeInfo
|
import com.fasterxml.jackson.annotation.JsonTypeInfo
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
data class ServerConnectionConfig(
|
data class ServerConnectionConfig(
|
||||||
var id:String,
|
var id:String,
|
||||||
|
@ -13,7 +12,8 @@ data class ServerConnectionConfig(
|
||||||
var address:String,
|
var address:String,
|
||||||
var userId:String,
|
var userId:String,
|
||||||
var username:String,
|
var username:String,
|
||||||
var token:String
|
var token:String,
|
||||||
|
var customHeaders:Map<String, String>?
|
||||||
)
|
)
|
||||||
|
|
||||||
data class DeviceData(
|
data class DeviceData(
|
||||||
|
|
|
@ -25,6 +25,7 @@ class AbsDatabase : Plugin() {
|
||||||
data class LocalMediaProgressPayload(val value:List<LocalMediaProgress>)
|
data class LocalMediaProgressPayload(val value:List<LocalMediaProgress>)
|
||||||
data class LocalLibraryItemsPayload(val value:List<LocalLibraryItem>)
|
data class LocalLibraryItemsPayload(val value:List<LocalLibraryItem>)
|
||||||
data class LocalFoldersPayload(val value:List<LocalFolder>)
|
data class LocalFoldersPayload(val value:List<LocalFolder>)
|
||||||
|
data class ServerConnConfigPayload(val id:String?, val index:Int, val name:String?, val userId:String, val username:String, val token:String, val address:String?, val customHeaders:Map<String,String>?)
|
||||||
|
|
||||||
override fun load() {
|
override fun load() {
|
||||||
mainActivity = (activity as MainActivity)
|
mainActivity = (activity as MainActivity)
|
||||||
|
@ -37,7 +38,7 @@ class AbsDatabase : Plugin() {
|
||||||
@PluginMethod
|
@PluginMethod
|
||||||
fun getDeviceData(call:PluginCall) {
|
fun getDeviceData(call:PluginCall) {
|
||||||
GlobalScope.launch(Dispatchers.IO) {
|
GlobalScope.launch(Dispatchers.IO) {
|
||||||
var deviceData = DeviceManager.dbManager.getDeviceData()
|
val deviceData = DeviceManager.dbManager.getDeviceData()
|
||||||
call.resolve(JSObject(jacksonMapper.writeValueAsString(deviceData)))
|
call.resolve(JSObject(jacksonMapper.writeValueAsString(deviceData)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,17 +46,17 @@ class AbsDatabase : Plugin() {
|
||||||
@PluginMethod
|
@PluginMethod
|
||||||
fun getLocalFolders(call:PluginCall) {
|
fun getLocalFolders(call:PluginCall) {
|
||||||
GlobalScope.launch(Dispatchers.IO) {
|
GlobalScope.launch(Dispatchers.IO) {
|
||||||
var folders = DeviceManager.dbManager.getAllLocalFolders()
|
val folders = DeviceManager.dbManager.getAllLocalFolders()
|
||||||
call.resolve(JSObject(jacksonMapper.writeValueAsString(LocalFoldersPayload(folders))))
|
call.resolve(JSObject(jacksonMapper.writeValueAsString(LocalFoldersPayload(folders))))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@PluginMethod
|
@PluginMethod
|
||||||
fun getLocalFolder(call:PluginCall) {
|
fun getLocalFolder(call:PluginCall) {
|
||||||
var folderId = call.getString("folderId", "").toString()
|
val folderId = call.getString("folderId", "").toString()
|
||||||
GlobalScope.launch(Dispatchers.IO) {
|
GlobalScope.launch(Dispatchers.IO) {
|
||||||
DeviceManager.dbManager.getLocalFolder(folderId)?.let {
|
DeviceManager.dbManager.getLocalFolder(folderId)?.let {
|
||||||
var folderObj = jacksonMapper.writeValueAsString(it)
|
val folderObj = jacksonMapper.writeValueAsString(it)
|
||||||
call.resolve(JSObject(folderObj))
|
call.resolve(JSObject(folderObj))
|
||||||
} ?: call.resolve()
|
} ?: call.resolve()
|
||||||
}
|
}
|
||||||
|
@ -63,10 +64,10 @@ class AbsDatabase : Plugin() {
|
||||||
|
|
||||||
@PluginMethod
|
@PluginMethod
|
||||||
fun getLocalLibraryItem(call:PluginCall) {
|
fun getLocalLibraryItem(call:PluginCall) {
|
||||||
var id = call.getString("id", "").toString()
|
val id = call.getString("id", "").toString()
|
||||||
|
|
||||||
GlobalScope.launch(Dispatchers.IO) {
|
GlobalScope.launch(Dispatchers.IO) {
|
||||||
var localLibraryItem = DeviceManager.dbManager.getLocalLibraryItem(id)
|
val localLibraryItem = DeviceManager.dbManager.getLocalLibraryItem(id)
|
||||||
if (localLibraryItem == null) {
|
if (localLibraryItem == null) {
|
||||||
call.resolve()
|
call.resolve()
|
||||||
} else {
|
} else {
|
||||||
|
@ -77,9 +78,9 @@ class AbsDatabase : Plugin() {
|
||||||
|
|
||||||
@PluginMethod
|
@PluginMethod
|
||||||
fun getLocalLibraryItemByLLId(call:PluginCall) {
|
fun getLocalLibraryItemByLLId(call:PluginCall) {
|
||||||
var libraryItemId = call.getString("libraryItemId", "").toString()
|
val libraryItemId = call.getString("libraryItemId", "").toString()
|
||||||
GlobalScope.launch(Dispatchers.IO) {
|
GlobalScope.launch(Dispatchers.IO) {
|
||||||
var localLibraryItem = DeviceManager.dbManager.getLocalLibraryItemByLLId(libraryItemId)
|
val localLibraryItem = DeviceManager.dbManager.getLocalLibraryItemByLLId(libraryItemId)
|
||||||
if (localLibraryItem == null) {
|
if (localLibraryItem == null) {
|
||||||
call.resolve()
|
call.resolve()
|
||||||
} else {
|
} else {
|
||||||
|
@ -90,40 +91,42 @@ class AbsDatabase : Plugin() {
|
||||||
|
|
||||||
@PluginMethod
|
@PluginMethod
|
||||||
fun getLocalLibraryItems(call:PluginCall) {
|
fun getLocalLibraryItems(call:PluginCall) {
|
||||||
var mediaType = call.getString("mediaType", "").toString()
|
val mediaType = call.getString("mediaType", "").toString()
|
||||||
|
|
||||||
GlobalScope.launch(Dispatchers.IO) {
|
GlobalScope.launch(Dispatchers.IO) {
|
||||||
var localLibraryItems = DeviceManager.dbManager.getLocalLibraryItems(mediaType)
|
val localLibraryItems = DeviceManager.dbManager.getLocalLibraryItems(mediaType)
|
||||||
call.resolve(JSObject(jacksonMapper.writeValueAsString(LocalLibraryItemsPayload(localLibraryItems))))
|
call.resolve(JSObject(jacksonMapper.writeValueAsString(LocalLibraryItemsPayload(localLibraryItems))))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@PluginMethod
|
@PluginMethod
|
||||||
fun getLocalLibraryItemsInFolder(call:PluginCall) {
|
fun getLocalLibraryItemsInFolder(call:PluginCall) {
|
||||||
var folderId = call.getString("folderId", "").toString()
|
val folderId = call.getString("folderId", "").toString()
|
||||||
GlobalScope.launch(Dispatchers.IO) {
|
GlobalScope.launch(Dispatchers.IO) {
|
||||||
var localLibraryItems = DeviceManager.dbManager.getLocalLibraryItemsInFolder(folderId)
|
val localLibraryItems = DeviceManager.dbManager.getLocalLibraryItemsInFolder(folderId)
|
||||||
call.resolve(JSObject(jacksonMapper.writeValueAsString(LocalLibraryItemsPayload(localLibraryItems))))
|
call.resolve(JSObject(jacksonMapper.writeValueAsString(LocalLibraryItemsPayload(localLibraryItems))))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@PluginMethod
|
@PluginMethod
|
||||||
fun setCurrentServerConnectionConfig(call:PluginCall) {
|
fun setCurrentServerConnectionConfig(call:PluginCall) {
|
||||||
var serverConnectionConfigId = call.getString("id", "").toString()
|
Log.d(tag, "setCurrentServerConnectionConfig ${call.data}")
|
||||||
var serverConnectionConfig = DeviceManager.deviceData.serverConnectionConfigs.find { it.id == serverConnectionConfigId }
|
val serverConfigPayload = jacksonMapper.readValue<ServerConnConfigPayload>(call.data.toString())
|
||||||
|
Log.d(tag, "[TEST] Check custom headers ${serverConfigPayload.customHeaders}")
|
||||||
|
var serverConnectionConfig = DeviceManager.deviceData.serverConnectionConfigs.find { it.id == serverConfigPayload.id }
|
||||||
|
|
||||||
var userId = call.getString("userId", "").toString()
|
val userId = serverConfigPayload.userId
|
||||||
var username = call.getString("username", "").toString()
|
val username = serverConfigPayload.username
|
||||||
var token = call.getString("token", "").toString()
|
val token = serverConfigPayload.token
|
||||||
|
|
||||||
GlobalScope.launch(Dispatchers.IO) {
|
GlobalScope.launch(Dispatchers.IO) {
|
||||||
if (serverConnectionConfig == null) { // New Server Connection
|
if (serverConnectionConfig == null) { // New Server Connection
|
||||||
var serverAddress = call.getString("address", "").toString()
|
val serverAddress = call.getString("address", "").toString()
|
||||||
|
|
||||||
// Create new server connection config
|
// Create new server connection config
|
||||||
var sscId = DeviceManager.getBase64Id("$serverAddress@$username")
|
val sscId = DeviceManager.getBase64Id("$serverAddress@$username")
|
||||||
var sscIndex = DeviceManager.deviceData.serverConnectionConfigs.size
|
val sscIndex = DeviceManager.deviceData.serverConnectionConfigs.size
|
||||||
serverConnectionConfig = ServerConnectionConfig(sscId, sscIndex, "$serverAddress ($username)", serverAddress, userId, username, token)
|
serverConnectionConfig = ServerConnectionConfig(sscId, sscIndex, "$serverAddress ($username)", serverAddress, userId, username, token, serverConfigPayload.customHeaders)
|
||||||
|
|
||||||
// Add and save
|
// Add and save
|
||||||
DeviceManager.deviceData.serverConnectionConfigs.add(serverConnectionConfig!!)
|
DeviceManager.deviceData.serverConnectionConfigs.add(serverConnectionConfig!!)
|
||||||
|
@ -140,8 +143,8 @@ class AbsDatabase : Plugin() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set last connection config
|
// Set last connection config
|
||||||
if (DeviceManager.deviceData.lastServerConnectionConfigId != serverConnectionConfigId) {
|
if (DeviceManager.deviceData.lastServerConnectionConfigId != serverConfigPayload.id) {
|
||||||
DeviceManager.deviceData.lastServerConnectionConfigId = serverConnectionConfigId
|
DeviceManager.deviceData.lastServerConnectionConfigId = serverConfigPayload.id
|
||||||
shouldSave = true
|
shouldSave = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,7 +159,7 @@ class AbsDatabase : Plugin() {
|
||||||
@PluginMethod
|
@PluginMethod
|
||||||
fun removeServerConnectionConfig(call:PluginCall) {
|
fun removeServerConnectionConfig(call:PluginCall) {
|
||||||
GlobalScope.launch(Dispatchers.IO) {
|
GlobalScope.launch(Dispatchers.IO) {
|
||||||
var serverConnectionConfigId = call.getString("serverConnectionConfigId", "").toString()
|
val serverConnectionConfigId = call.getString("serverConnectionConfigId", "").toString()
|
||||||
DeviceManager.deviceData.serverConnectionConfigs = DeviceManager.deviceData.serverConnectionConfigs.filter { it.id != serverConnectionConfigId } as MutableList<ServerConnectionConfig>
|
DeviceManager.deviceData.serverConnectionConfigs = DeviceManager.deviceData.serverConnectionConfigs.filter { it.id != serverConnectionConfigId } as MutableList<ServerConnectionConfig>
|
||||||
if (DeviceManager.deviceData.lastServerConnectionConfigId == serverConnectionConfigId) {
|
if (DeviceManager.deviceData.lastServerConnectionConfigId == serverConnectionConfigId) {
|
||||||
DeviceManager.deviceData.lastServerConnectionConfigId = null
|
DeviceManager.deviceData.lastServerConnectionConfigId = null
|
||||||
|
@ -182,7 +185,7 @@ class AbsDatabase : Plugin() {
|
||||||
@PluginMethod
|
@PluginMethod
|
||||||
fun getAllLocalMediaProgress(call:PluginCall) {
|
fun getAllLocalMediaProgress(call:PluginCall) {
|
||||||
GlobalScope.launch(Dispatchers.IO) {
|
GlobalScope.launch(Dispatchers.IO) {
|
||||||
var localMediaProgress = DeviceManager.dbManager.getAllLocalMediaProgress()
|
val localMediaProgress = DeviceManager.dbManager.getAllLocalMediaProgress()
|
||||||
call.resolve(JSObject(jacksonMapper.writeValueAsString(LocalMediaProgressPayload(localMediaProgress))))
|
call.resolve(JSObject(jacksonMapper.writeValueAsString(LocalMediaProgressPayload(localMediaProgress))))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -331,13 +334,13 @@ class AbsDatabase : Plugin() {
|
||||||
// Send update to server media progress is linked to a server and user is logged into that server
|
// Send update to server media progress is linked to a server and user is logged into that server
|
||||||
localMediaProgress.serverConnectionConfigId?.let { configId ->
|
localMediaProgress.serverConnectionConfigId?.let { configId ->
|
||||||
if (DeviceManager.serverConnectionConfigId == configId) {
|
if (DeviceManager.serverConnectionConfigId == configId) {
|
||||||
var libraryItemId = localMediaProgress.libraryItemId ?: ""
|
val libraryItemId = localMediaProgress.libraryItemId ?: ""
|
||||||
var episodeId = localMediaProgress.episodeId ?: ""
|
val episodeId = localMediaProgress.episodeId ?: ""
|
||||||
var updatePayload = JSObject()
|
val updatePayload = JSObject()
|
||||||
updatePayload.put("isFinished", isFinished)
|
updatePayload.put("isFinished", isFinished)
|
||||||
apiHandler.updateMediaProgress(libraryItemId,episodeId,updatePayload) {
|
apiHandler.updateMediaProgress(libraryItemId,episodeId,updatePayload) {
|
||||||
Log.d(tag, "updateLocalMediaProgressFinished: Updated media progress isFinished on server")
|
Log.d(tag, "updateLocalMediaProgressFinished: Updated media progress isFinished on server")
|
||||||
var jsobj = JSObject()
|
val jsobj = JSObject()
|
||||||
jsobj.put("local", true)
|
jsobj.put("local", true)
|
||||||
jsobj.put("server", true)
|
jsobj.put("server", true)
|
||||||
jsobj.put("localMediaProgress", JSObject(lmpstring))
|
jsobj.put("localMediaProgress", JSObject(lmpstring))
|
||||||
|
@ -346,7 +349,7 @@ class AbsDatabase : Plugin() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (localMediaProgress.serverConnectionConfigId == null || DeviceManager.serverConnectionConfigId != localMediaProgress.serverConnectionConfigId) {
|
if (localMediaProgress.serverConnectionConfigId == null || DeviceManager.serverConnectionConfigId != localMediaProgress.serverConnectionConfigId) {
|
||||||
var jsobj = JSObject()
|
val jsobj = JSObject()
|
||||||
jsobj.put("local", true)
|
jsobj.put("local", true)
|
||||||
jsobj.put("server", false)
|
jsobj.put("server", false)
|
||||||
jsobj.put("localMediaProgress", JSObject(lmpstring))
|
jsobj.put("localMediaProgress", JSObject(lmpstring))
|
||||||
|
@ -356,25 +359,25 @@ class AbsDatabase : Plugin() {
|
||||||
|
|
||||||
@PluginMethod
|
@PluginMethod
|
||||||
fun updateLocalTrackOrder(call:PluginCall) {
|
fun updateLocalTrackOrder(call:PluginCall) {
|
||||||
var localLibraryItemId = call.getString("localLibraryItemId", "") ?: ""
|
val localLibraryItemId = call.getString("localLibraryItemId", "") ?: ""
|
||||||
var localLibraryItem = DeviceManager.dbManager.getLocalLibraryItem(localLibraryItemId)
|
val localLibraryItem = DeviceManager.dbManager.getLocalLibraryItem(localLibraryItemId)
|
||||||
if (localLibraryItem == null) {
|
if (localLibraryItem == null) {
|
||||||
call.resolve()
|
call.resolve()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var audioTracks = localLibraryItem.media.getAudioTracks() as MutableList
|
val audioTracks = localLibraryItem.media.getAudioTracks() as MutableList
|
||||||
|
|
||||||
var tracks:JSArray = call.getArray("tracks") ?: JSArray()
|
val tracks:JSArray = call.getArray("tracks") ?: JSArray()
|
||||||
Log.d(tag, "updateLocalTrackOrder $tracks")
|
Log.d(tag, "updateLocalTrackOrder $tracks")
|
||||||
|
|
||||||
var index = 1
|
var index = 1
|
||||||
var hasUpdates = false
|
var hasUpdates = false
|
||||||
for (i in 0 until tracks.length()) {
|
for (i in 0 until tracks.length()) {
|
||||||
var track = tracks.getJSONObject(i)
|
val track = tracks.getJSONObject(i)
|
||||||
var localFileId = track.getString("localFileId")
|
val localFileId = track.getString("localFileId")
|
||||||
|
|
||||||
var existingTrack = audioTracks.find{ it.localFileId == localFileId }
|
val existingTrack = audioTracks.find{ it.localFileId == localFileId }
|
||||||
if (existingTrack != null) {
|
if (existingTrack != null) {
|
||||||
Log.d(tag, "Found existing track ${existingTrack.localFileId} that has index ${existingTrack.index} should be index $index")
|
Log.d(tag, "Found existing track ${existingTrack.localFileId} that has index ${existingTrack.index} should be index $index")
|
||||||
if (existingTrack.index != index) hasUpdates = true
|
if (existingTrack.index != index) hasUpdates = true
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="w-full max-w-md mx-auto px-4 sm:px-6 lg:px-8 z-10">
|
<div class="w-full max-w-md mx-auto px-2 sm:px-4 lg:px-8 z-10">
|
||||||
<div v-show="!loggedIn" class="mt-8 bg-primary overflow-hidden shadow rounded-lg p-6 w-full">
|
<div v-show="!loggedIn" class="mt-8 bg-primary overflow-hidden shadow rounded-lg px-4 py-6 w-full">
|
||||||
<template v-if="!showForm">
|
<template v-if="!showForm">
|
||||||
<div v-for="config in serverConnectionConfigs" :key="config.id" class="flex items-center py-4 my-1 border-b border-white border-opacity-10 relative" @click="connectToServer(config)">
|
<div v-for="config in serverConnectionConfigs" :key="config.id" class="flex items-center py-4 my-1 border-b border-white border-opacity-10 relative" @click="connectToServer(config)">
|
||||||
<span class="material-icons-outlined text-xl text-gray-300">dns</span>
|
<span class="material-icons-outlined text-xl text-gray-300">dns</span>
|
||||||
|
@ -17,9 +17,14 @@
|
||||||
<div v-else class="w-full">
|
<div v-else class="w-full">
|
||||||
<form v-show="!showAuth" @submit.prevent="submit" novalidate class="w-full">
|
<form v-show="!showAuth" @submit.prevent="submit" novalidate class="w-full">
|
||||||
<h2 class="text-lg leading-7 mb-2">Server address</h2>
|
<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 sm:w-72 h-10" />
|
<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">
|
<div class="flex justify-end items-center mt-6">
|
||||||
<ui-btn :disabled="processing || !networkConnected" type="submit" :padding-x="3" class="h-10 mt-4">{{ networkConnected ? 'Submit' : 'No Internet' }}</ui-btn>
|
<!-- <div class="relative flex">
|
||||||
|
<button class="outline-none uppercase tracking-wide font-semibold text-xs text-gray-300" type="button" @click="addCustomHeaders">Add Custom Headers</button>
|
||||||
|
<div v-if="numCustomHeaders" class="rounded-full h-5 w-5 flex items-center justify-center text-xs bg-success bg-opacity-40 leading-3 font-semibold font-mono ml-1">{{ numCustomHeaders }}</div>
|
||||||
|
</div> -->
|
||||||
|
|
||||||
|
<ui-btn :disabled="processing || !networkConnected" type="submit" :padding-x="3" class="h-10">{{ networkConnected ? 'Submit' : 'No Internet' }}</ui-btn>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
<template v-if="showAuth">
|
<template v-if="showAuth">
|
||||||
|
@ -62,6 +67,8 @@
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<modals-custom-headers-modal v-model="showAddCustomHeaders" :custom-headers.sync="serverConfig.customHeaders" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -78,11 +85,13 @@ export default {
|
||||||
processing: false,
|
processing: false,
|
||||||
serverConfig: {
|
serverConfig: {
|
||||||
address: null,
|
address: null,
|
||||||
username: null
|
username: null,
|
||||||
|
customHeaders: null
|
||||||
},
|
},
|
||||||
password: null,
|
password: null,
|
||||||
error: null,
|
error: null,
|
||||||
showForm: false
|
showForm: false,
|
||||||
|
showAddCustomHeaders: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -98,9 +107,16 @@ export default {
|
||||||
lastServerConnectionConfig() {
|
lastServerConnectionConfig() {
|
||||||
if (!this.lastServerConnectionConfigId || !this.serverConnectionConfigs.length) return null
|
if (!this.lastServerConnectionConfigId || !this.serverConnectionConfigs.length) return null
|
||||||
return this.serverConnectionConfigs.find((s) => s.id == this.lastServerConnectionConfigId)
|
return this.serverConnectionConfigs.find((s) => s.id == this.lastServerConnectionConfigId)
|
||||||
|
},
|
||||||
|
numCustomHeaders() {
|
||||||
|
if (!this.serverConfig.customHeaders) return 0
|
||||||
|
return Object.keys(this.serverConfig.customHeaders).length
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
addCustomHeaders() {
|
||||||
|
this.showAddCustomHeaders = true
|
||||||
|
},
|
||||||
showServerList() {
|
showServerList() {
|
||||||
this.showForm = false
|
this.showForm = false
|
||||||
this.showAuth = false
|
this.showAuth = false
|
||||||
|
@ -192,9 +208,13 @@ export default {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
pingServerAddress(address) {
|
pingServerAddress(address, customHeaders) {
|
||||||
|
const options = { timeout: 3000 }
|
||||||
|
if (customHeaders) {
|
||||||
|
options.headers = customHeaders
|
||||||
|
}
|
||||||
return this.$axios
|
return this.$axios
|
||||||
.$get(`${address}/ping`, { timeout: 3000 })
|
.$get(`${address}/ping`, options)
|
||||||
.then((data) => data.success)
|
.then((data) => data.success)
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error('Server check failed', error)
|
console.error('Server check failed', error)
|
||||||
|
@ -203,8 +223,12 @@ export default {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
requestServerLogin() {
|
requestServerLogin() {
|
||||||
|
const options = {}
|
||||||
|
if (this.serverConfig.customHeaders) {
|
||||||
|
options.headers = this.serverConfig.customHeaders
|
||||||
|
}
|
||||||
return this.$axios
|
return this.$axios
|
||||||
.$post(`${this.serverConfig.address}/login`, { username: this.serverConfig.username, password: this.password })
|
.$post(`${this.serverConfig.address}/login`, { username: this.serverConfig.username, password: this.password }, options)
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
if (!data.user) {
|
if (!data.user) {
|
||||||
console.error(data.error)
|
console.error(data.error)
|
||||||
|
@ -236,7 +260,7 @@ export default {
|
||||||
this.processing = true
|
this.processing = true
|
||||||
this.error = null
|
this.error = null
|
||||||
|
|
||||||
var success = await this.pingServerAddress(this.serverConfig.address)
|
var success = await this.pingServerAddress(this.serverConfig.address, this.serverConfig.customHeaders)
|
||||||
this.processing = false
|
this.processing = false
|
||||||
if (success) this.showAuth = true
|
if (success) this.showAuth = true
|
||||||
},
|
},
|
||||||
|
|
96
components/modals/CustomHeadersModal.vue
Normal file
96
components/modals/CustomHeadersModal.vue
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
<template>
|
||||||
|
<modals-modal v-model="show" :width="'90%'" :max-width="'420px'" height="100%">
|
||||||
|
<template #outer>
|
||||||
|
<div class="absolute top-5 left-4 z-40">
|
||||||
|
<p class="text-white text-2xl truncate">Custom Headers</p>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<div class="w-full h-full overflow-hidden absolute top-0 left-0 flex items-center justify-center" @click="show = false">
|
||||||
|
<div ref="container" class="w-full rounded-lg bg-primary border border-white border-opacity-20 overflow-y-auto overflow-x-hidden" style="max-height: 80vh" @click.stop>
|
||||||
|
<div class="w-full h-full p-4" v-if="showAddHeader">
|
||||||
|
<div class="mb-4">
|
||||||
|
<ui-icon-btn icon="arrow_back" borderless @click="showAddHeader = false" />
|
||||||
|
</div>
|
||||||
|
<form @submit.prevent="submitForm">
|
||||||
|
<ui-text-input-with-label v-model="newHeaderKey" label="Name" class="mb-2" />
|
||||||
|
<ui-text-input-with-label v-model="newHeaderValue" label="Value" class="mb-4" />
|
||||||
|
|
||||||
|
<ui-btn type="submit" class="w-full">Submit</ui-btn>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div class="w-full h-full p-4" v-else>
|
||||||
|
<template v-for="[key, value] in Object.entries(headersCopy)">
|
||||||
|
<div :key="key" class="w-full rounded-lg bg-white bg-opacity-5 py-2 pl-4 pr-12 relative mb-2">
|
||||||
|
<p class="text-base font-semibold text-gray-200 leading-5">{{ key }}</p>
|
||||||
|
<p class="text-sm text-gray-400">{{ value }}</p>
|
||||||
|
|
||||||
|
<div class="absolute top-0 bottom-0 right-0 h-full p-4 flex items-center justify-center text-error">
|
||||||
|
<button @click="removeHeader(key)"><span class="material-icons text-lg">delete</span></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<p v-if="!Object.keys(headersCopy).length" class="py-4 text-center">No Custom Headers</p>
|
||||||
|
|
||||||
|
<div class="w-full flex justify-center pt-4">
|
||||||
|
<ui-btn @click="showAddHeader = true" class="w-full">Add Custom Header</ui-btn>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</modals-modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
value: Boolean,
|
||||||
|
customHeaders: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
newHeaderKey: '',
|
||||||
|
newHeaderValue: '',
|
||||||
|
headersCopy: {},
|
||||||
|
showAddHeader: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
show(val) {
|
||||||
|
if (val) this.init()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
show: {
|
||||||
|
get() {
|
||||||
|
return this.value
|
||||||
|
},
|
||||||
|
set(val) {
|
||||||
|
this.$emit('input', val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
removeHeader(key) {
|
||||||
|
this.$delete(this.headersCopy, key)
|
||||||
|
this.$emit('update:customHeaders', { ...this.headersCopy })
|
||||||
|
},
|
||||||
|
submitForm() {
|
||||||
|
console.log('Submit form', this.newHeaderKey, this.newHeaderValue)
|
||||||
|
this.headersCopy[this.newHeaderKey] = this.newHeaderValue
|
||||||
|
this.newHeaderKey = ''
|
||||||
|
this.newHeaderValue = ''
|
||||||
|
this.showAddHeader = false
|
||||||
|
this.$emit('update:customHeaders', { ...this.headersCopy })
|
||||||
|
},
|
||||||
|
init() {
|
||||||
|
this.newHeaderKey = ''
|
||||||
|
this.newHeaderValue = ''
|
||||||
|
this.headersCopy = this.customHeaders ? { ...this.customHeaders } : {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {}
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -4,6 +4,14 @@ export default function ({ $axios, store }) {
|
||||||
if (config.url.startsWith('http:') || config.url.startsWith('https:')) {
|
if (config.url.startsWith('http:') || config.url.startsWith('https:')) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var customHeaders = store.getters['user/getCustomHeaders']
|
||||||
|
if (customHeaders) {
|
||||||
|
for (const key in customHeaders) {
|
||||||
|
config.headers.common[key] = customHeaders[key]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var bearerToken = store.getters['user/getToken']
|
var bearerToken = store.getters['user/getToken']
|
||||||
if (bearerToken) {
|
if (bearerToken) {
|
||||||
config.headers.common['Authorization'] = `Bearer ${bearerToken}`
|
config.headers.common['Authorization'] = `Bearer ${bearerToken}`
|
||||||
|
|
|
@ -28,6 +28,7 @@ class AbsDatabaseWeb extends WebPlugin {
|
||||||
ssc.token = serverConnectionConfig.token
|
ssc.token = serverConnectionConfig.token
|
||||||
ssc.userId = serverConnectionConfig.userId
|
ssc.userId = serverConnectionConfig.userId
|
||||||
ssc.username = serverConnectionConfig.username
|
ssc.username = serverConnectionConfig.username
|
||||||
|
ssc.customHeaders = serverConnectionConfig.customHeaders || {}
|
||||||
localStorage.setItem('device', JSON.stringify(deviceData))
|
localStorage.setItem('device', JSON.stringify(deviceData))
|
||||||
} else {
|
} else {
|
||||||
ssc = {
|
ssc = {
|
||||||
|
@ -37,7 +38,8 @@ class AbsDatabaseWeb extends WebPlugin {
|
||||||
userId: serverConnectionConfig.userId,
|
userId: serverConnectionConfig.userId,
|
||||||
username: serverConnectionConfig.username,
|
username: serverConnectionConfig.username,
|
||||||
address: serverConnectionConfig.address,
|
address: serverConnectionConfig.address,
|
||||||
token: serverConnectionConfig.token
|
token: serverConnectionConfig.token,
|
||||||
|
customHeaders: serverConnectionConfig.customHeaders || {}
|
||||||
}
|
}
|
||||||
deviceData.serverConnectionConfigs.push(ssc)
|
deviceData.serverConnectionConfigs.push(ssc)
|
||||||
deviceData.lastServerConnectionConfigId = ssc.id
|
deviceData.lastServerConnectionConfigId = ssc.id
|
||||||
|
|
|
@ -22,6 +22,9 @@ export const getters = {
|
||||||
getServerAddress: (state) => {
|
getServerAddress: (state) => {
|
||||||
return state.serverConnectionConfig ? state.serverConnectionConfig.address : null
|
return state.serverConnectionConfig ? state.serverConnectionConfig.address : null
|
||||||
},
|
},
|
||||||
|
getCustomHeaders: (state) => {
|
||||||
|
return state.serverConnectionConfig ? state.serverConnectionConfig.customHeaders : null
|
||||||
|
},
|
||||||
getUserMediaProgress: (state) => (libraryItemId, episodeId = null) => {
|
getUserMediaProgress: (state) => (libraryItemId, episodeId = null) => {
|
||||||
if (!state.user || !state.user.mediaProgress) return null
|
if (!state.user || !state.user.mediaProgress) return null
|
||||||
return state.user.mediaProgress.find(li => {
|
return state.user.mediaProgress.find(li => {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue