Update dependencies and improve server discovery
This commit is contained in:
parent
69503f504d
commit
e9e849d9e4
4 changed files with 85 additions and 31 deletions
|
@ -84,8 +84,8 @@ dependencies {
|
|||
implementation("androidx.preference:preference-ktx:$preferenceVersion")
|
||||
|
||||
// Jellyfin
|
||||
val jellyfinVersion = "1.0.3"
|
||||
implementation("org.jellyfin.sdk:jellyfin-platform-android:$jellyfinVersion")
|
||||
val jellyfinVersion = "1.1.0"
|
||||
implementation("org.jellyfin.sdk:jellyfin-core:$jellyfinVersion")
|
||||
|
||||
// Glide
|
||||
val glideVersion = "4.12.0"
|
||||
|
@ -93,12 +93,12 @@ dependencies {
|
|||
kapt("com.github.bumptech.glide:compiler:$glideVersion")
|
||||
|
||||
// Hilt
|
||||
val hiltVersion = "2.38.1"
|
||||
val hiltVersion = "2.39.1"
|
||||
implementation("com.google.dagger:hilt-android:$hiltVersion")
|
||||
kapt("com.google.dagger:hilt-compiler:$hiltVersion")
|
||||
|
||||
// ExoPlayer
|
||||
val exoplayerVersion = "2.15.0"
|
||||
val exoplayerVersion = "2.15.1"
|
||||
implementation("com.google.android.exoplayer:exoplayer-core:$exoplayerVersion")
|
||||
implementation("com.google.android.exoplayer:exoplayer-ui:$exoplayerVersion")
|
||||
implementation(files("libs/extension-ffmpeg-release.aar"))
|
||||
|
|
|
@ -2,9 +2,8 @@ package dev.jdtech.jellyfin.api
|
|||
|
||||
import android.content.Context
|
||||
import dev.jdtech.jellyfin.BuildConfig
|
||||
import org.jellyfin.sdk.Jellyfin
|
||||
import org.jellyfin.sdk.android
|
||||
import org.jellyfin.sdk.api.operations.*
|
||||
import org.jellyfin.sdk.api.client.extensions.*
|
||||
import org.jellyfin.sdk.createJellyfin
|
||||
import org.jellyfin.sdk.model.ClientInfo
|
||||
import java.util.*
|
||||
|
||||
|
@ -12,29 +11,29 @@ import java.util.*
|
|||
/**
|
||||
* Jellyfin API class using org.jellyfin.sdk:jellyfin-platform-android
|
||||
*
|
||||
* @param context The context
|
||||
* @param androidContext The context
|
||||
* @param baseUrl The url of the server
|
||||
* @constructor Creates a new [JellyfinApi] instance
|
||||
*/
|
||||
class JellyfinApi(context: Context, baseUrl: String) {
|
||||
val jellyfin = Jellyfin {
|
||||
class JellyfinApi(androidContext: Context, baseUrl: String) {
|
||||
val jellyfin = createJellyfin {
|
||||
clientInfo =
|
||||
ClientInfo(name = context.applicationInfo.loadLabel(context.packageManager).toString(), version = BuildConfig.VERSION_NAME)
|
||||
android(context)
|
||||
ClientInfo(name = androidContext.applicationInfo.loadLabel(androidContext.packageManager).toString(), version = BuildConfig.VERSION_NAME)
|
||||
context = androidContext
|
||||
}
|
||||
val api = jellyfin.createApi(baseUrl = baseUrl)
|
||||
var userId: UUID? = null
|
||||
|
||||
val systemApi = SystemApi(api)
|
||||
val userApi = UserApi(api)
|
||||
val viewsApi = UserViewsApi(api)
|
||||
val itemsApi = ItemsApi(api)
|
||||
val userLibraryApi = UserLibraryApi(api)
|
||||
val showsApi = TvShowsApi(api)
|
||||
val sessionApi = SessionApi(api)
|
||||
val videosApi = VideosApi(api)
|
||||
val mediaInfoApi = MediaInfoApi(api)
|
||||
val playStateApi = PlayStateApi(api)
|
||||
val systemApi = api.systemApi
|
||||
val userApi = api.userApi
|
||||
val viewsApi = api.userViewsApi
|
||||
val itemsApi = api.itemsApi
|
||||
val userLibraryApi = api.userLibraryApi
|
||||
val showsApi = api.tvShowsApi
|
||||
val sessionApi = api.sessionApi
|
||||
val videosApi = api.videosApi
|
||||
val mediaInfoApi = api.mediaInfoApi
|
||||
val playStateApi = api.playStateApi
|
||||
|
||||
companion object {
|
||||
@Volatile
|
||||
|
|
|
@ -1,19 +1,22 @@
|
|||
package dev.jdtech.jellyfin.viewmodels
|
||||
|
||||
import android.widget.Toast
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import dev.jdtech.jellyfin.BaseApplication
|
||||
import dev.jdtech.jellyfin.api.JellyfinApi
|
||||
import dev.jdtech.jellyfin.database.Server
|
||||
import dev.jdtech.jellyfin.database.ServerDatabaseDao
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.jellyfin.sdk.discovery.RecommendedServerInfo
|
||||
import org.jellyfin.sdk.discovery.RecommendedServerInfoScore
|
||||
import org.jellyfin.sdk.discovery.RecommendedServerIssue
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
|
@ -21,6 +24,7 @@ import javax.inject.Inject
|
|||
class AddServerViewModel
|
||||
@Inject
|
||||
constructor(
|
||||
private val application: BaseApplication,
|
||||
private val jellyfinApi: JellyfinApi,
|
||||
private val database: ServerDatabaseDao
|
||||
) : ViewModel() {
|
||||
|
@ -45,24 +49,45 @@ constructor(
|
|||
val candidates = jellyfinApi.jellyfin.discovery.getAddressCandidates(inputValue)
|
||||
val recommended = jellyfinApi.jellyfin.discovery.getRecommendedServers(
|
||||
candidates,
|
||||
RecommendedServerInfoScore.GOOD
|
||||
RecommendedServerInfoScore.OK
|
||||
)
|
||||
val recommendedServer: RecommendedServerInfo
|
||||
|
||||
try {
|
||||
recommendedServer = recommended.first()
|
||||
} catch (e: NoSuchElementException) {
|
||||
// Check if any servers have been found
|
||||
if (recommended.toList().isNullOrEmpty()) {
|
||||
throw Exception("Server not found")
|
||||
}
|
||||
|
||||
// Create separate flow of great, good and ok servers.
|
||||
val greatServers =
|
||||
recommended.filter { it.score == RecommendedServerInfoScore.GREAT }
|
||||
val goodServers = recommended.filter { it.score == RecommendedServerInfoScore.GOOD }
|
||||
val okServers = recommended.filter { it.score == RecommendedServerInfoScore.OK }
|
||||
|
||||
// Only allow connecting to great and good servers. Show toast of issues if good server
|
||||
val recommendedServer = if (greatServers.toList().isNotEmpty()) {
|
||||
greatServers.first()
|
||||
} else if (goodServers.toList().isNotEmpty()) {
|
||||
val issuesString = createIssuesString(goodServers.first())
|
||||
Toast.makeText(
|
||||
application,
|
||||
issuesString,
|
||||
Toast.LENGTH_LONG
|
||||
).show()
|
||||
goodServers.first()
|
||||
} else {
|
||||
val okServer = okServers.first()
|
||||
val issuesString = createIssuesString(okServer)
|
||||
throw Exception(issuesString)
|
||||
}
|
||||
|
||||
jellyfinApi.apply {
|
||||
api.baseUrl = recommendedServer.address
|
||||
api.accessToken = null
|
||||
}
|
||||
|
||||
Timber.d("Remote server: ${recommendedServer.systemInfo?.id}")
|
||||
Timber.d("Remote server: ${recommendedServer.systemInfo.getOrNull()?.id}")
|
||||
|
||||
if (serverAlreadyInDatabase(recommendedServer.systemInfo?.id)) {
|
||||
if (serverAlreadyInDatabase(recommendedServer.systemInfo.getOrNull()?.id)) {
|
||||
_error.value = "Server already added"
|
||||
_navigateToLogin.value = false
|
||||
} else {
|
||||
|
@ -77,6 +102,36 @@ constructor(
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a presentable string of issues with a server
|
||||
*
|
||||
* @param server The server with issues
|
||||
* @return A presentable string of issues separated with \n
|
||||
*/
|
||||
private fun createIssuesString(server: RecommendedServerInfo): String {
|
||||
val issues = mutableListOf<String>()
|
||||
server.issues.forEach {
|
||||
when (it) {
|
||||
is RecommendedServerIssue.OutdatedServerVersion -> {
|
||||
issues.add("Server version outdated: ${it.version} \nPlease update your server")
|
||||
}
|
||||
is RecommendedServerIssue.InvalidProductName -> {
|
||||
issues.add("Not a Jellyfin server: ${it.productName}")
|
||||
}
|
||||
is RecommendedServerIssue.UnsupportedServerVersion -> {
|
||||
issues.add("Unsupported server version: ${it.version} \nPlease update your server")
|
||||
}
|
||||
is RecommendedServerIssue.SlowResponse -> {
|
||||
issues.add("Server is too slow to respond: ${it.responseTime}")
|
||||
}
|
||||
else -> {
|
||||
issues.add("Unknown error")
|
||||
}
|
||||
}
|
||||
}
|
||||
return issues.joinToString("\n")
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if server is already in database using server ID
|
||||
*
|
||||
|
|
|
@ -9,7 +9,7 @@ buildscript {
|
|||
}
|
||||
}
|
||||
dependencies {
|
||||
classpath("com.android.tools.build:gradle:7.0.2")
|
||||
classpath("com.android.tools.build:gradle:7.0.3")
|
||||
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion")
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
|
|
Loading…
Reference in a new issue