Basics for user prefs, logging in, etc

This commit is contained in:
Damontecres 2025-09-21 19:56:40 -04:00
parent 763521aabf
commit 76d78246db
No known key found for this signature in database
15 changed files with 613 additions and 35 deletions

View file

@ -0,0 +1,9 @@
package com.github.damontecres.dolphin.data
import androidx.room.Database
import androidx.room.RoomDatabase
@Database(entities = [JellyfinServer::class, JellyfinUser::class], version = 1, exportSchema = false)
abstract class DolphinDatabase : RoomDatabase() {
abstract fun serverDao(): JellyfinServerDao
}

View file

@ -0,0 +1,76 @@
package com.github.damontecres.dolphin.data
import androidx.room.ColumnInfo
import androidx.room.Dao
import androidx.room.Embedded
import androidx.room.Entity
import androidx.room.ForeignKey
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.PrimaryKey
import androidx.room.Query
import androidx.room.Relation
import androidx.room.Transaction
@Entity(tableName = "servers")
data class JellyfinServer(
@PrimaryKey val id: String,
val name: String,
val url: String,
)
@Entity(
tableName = "users",
primaryKeys = ["id", "serverId"],
foreignKeys = [
ForeignKey(
entity = JellyfinServer::class,
parentColumns = arrayOf("id"),
childColumns = arrayOf("serverId"),
onDelete = ForeignKey.CASCADE,
),
],
)
data class JellyfinUser(
@ColumnInfo(index = true)
val id: String,
val name: String?,
@ColumnInfo(index = true)
val serverId: String,
val accessToken: String,
)
data class JellyfinServerUsers(
@Embedded val server: JellyfinServer,
@Relation(
parentColumn = "id",
entityColumn = "serverId",
)
val users: List<JellyfinUser>,
)
@Dao
interface JellyfinServerDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun addServer(vararg servers: JellyfinServer)
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun addUser(vararg users: JellyfinUser)
@Query("DELETE FROM servers WHERE id = :serverId")
fun deleteServer(serverId: String)
@Query("DELETE FROM users WHERE serverId = :serverId AND id = :userId")
fun deleteUser(
serverId: String,
userId: String,
)
@Transaction
@Query("SELECT * FROM servers")
fun getServers(): List<JellyfinServerUsers>
@Transaction
@Query("SELECT * FROM servers WHERE id = :serverId")
fun getServer(serverId: String): JellyfinServerUsers?
}

View file

@ -0,0 +1,89 @@
package com.github.damontecres.dolphin.data
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import org.jellyfin.sdk.api.client.ApiClient
import org.jellyfin.sdk.api.client.exception.InvalidStatusException
import org.jellyfin.sdk.api.client.extensions.userApi
import javax.inject.Inject
class ServerRepository
@Inject
constructor(
val serverDao: JellyfinServerDao,
val apiClient: ApiClient,
) {
private var _currentServer by mutableStateOf<JellyfinServer?>(null)
val currentServer get() = _currentServer
private var _currentUser by mutableStateOf<JellyfinUser?>(null)
val currentUser get() = _currentUser
suspend fun addAndChangeServer(server: JellyfinServer) {
withContext(Dispatchers.IO) {
serverDao.addServer(server)
}
changeServer(server)
}
suspend fun addAndChangeUser(
server: JellyfinServer,
user: JellyfinUser,
) {
if (server.id != user.serverId) {
throw IllegalStateException()
}
withContext(Dispatchers.IO) {
serverDao.addServer(server)
serverDao.addUser(user)
}
changeUser(server, user)
}
fun changeServer(server: JellyfinServer) {
apiClient.update(baseUrl = server.url, accessToken = null)
_currentServer = server
}
suspend fun changeUser(
server: JellyfinServer,
user: JellyfinUser,
) {
apiClient.update(baseUrl = server.url, accessToken = user.accessToken)
try {
apiClient.userApi
.getCurrentUser()
.content.name
_currentServer = server
_currentUser = user
} catch (e: InvalidStatusException) {
// TODO
if (e.status == 401) {
// Unauthorized
_currentServer = null
_currentUser = null
return
}
}
}
suspend fun restoreSession(
serverId: String,
userId: String,
): Boolean {
val serverAndUsers =
withContext(Dispatchers.IO) {
serverDao.getServer(serverId)
}
if (serverAndUsers != null) {
val user = serverAndUsers.users.firstOrNull { it.id == userId }
if (user != null) {
changeUser(serverAndUsers.server, user)
return true
}
}
return false
}
}