mirror of
https://github.com/ultrasonic/ultrasonic
synced 2025-01-30 17:04:51 +01:00
Updated ServerSettingsModel to use Room for handling LiveData
This commit is contained in:
parent
5b0c9906f1
commit
102f3e8a04
@ -53,7 +53,7 @@ internal class ServerRowAdapter(
|
||||
}
|
||||
|
||||
override fun getCount(): Int {
|
||||
return if (manageMode) data.size - 1 else data.size
|
||||
return if (manageMode) data.size else data.size + 1
|
||||
}
|
||||
|
||||
override fun getItem(position: Int): Any {
|
||||
@ -81,8 +81,13 @@ internal class ServerRowAdapter(
|
||||
val image = vi?.findViewById<ImageView>(R.id.server_image)
|
||||
val serverMenu = vi?.findViewById<ImageButton>(R.id.server_menu)
|
||||
|
||||
text?.text = data.single { setting -> setting.index == index }.name
|
||||
description?.text = data.single { setting -> setting.index == index }.url
|
||||
if (index == 0) {
|
||||
text?.text = context.getString(R.string.main_offline)
|
||||
description?.text = ""
|
||||
} else {
|
||||
text?.text = data.singleOrNull { setting -> setting.index == index }?.name ?: ""
|
||||
description?.text = data.singleOrNull { setting -> setting.index == index }?.url ?: ""
|
||||
}
|
||||
|
||||
// Provide icons for the row
|
||||
if (index == 0) {
|
||||
|
@ -5,12 +5,10 @@ import android.content.SharedPreferences
|
||||
import android.preference.PreferenceManager
|
||||
import android.util.Log
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.moire.ultrasonic.R
|
||||
import org.moire.ultrasonic.data.ActiveServerProvider
|
||||
import org.moire.ultrasonic.data.ServerSetting
|
||||
import org.moire.ultrasonic.data.ServerSettingDao
|
||||
@ -23,7 +21,6 @@ class ServerSettingsModel(
|
||||
private val activeServerProvider: ActiveServerProvider,
|
||||
private val context: Context
|
||||
) : ViewModel() {
|
||||
private var serverList: MutableLiveData<List<ServerSetting>> = MutableLiveData()
|
||||
|
||||
companion object {
|
||||
private val TAG = ServerSettingsModel::class.simpleName
|
||||
@ -84,16 +81,13 @@ class ServerSettingsModel(
|
||||
* This function is asynchronous, uses LiveData to provide the Setting.
|
||||
*/
|
||||
fun getServerList(): LiveData<List<ServerSetting>> {
|
||||
viewModelScope.launch {
|
||||
var dbServerList = repository.loadAllServerSettings().toMutableList()
|
||||
if (areIndexesMissing(dbServerList)) {
|
||||
dbServerList = reindexSettings(dbServerList).toMutableList()
|
||||
// This check should run before returning any result
|
||||
runBlocking {
|
||||
if (areIndexesMissing()) {
|
||||
reindexSettings()
|
||||
}
|
||||
|
||||
dbServerList.add(0, ServerSetting(context.getString(R.string.main_offline), ""))
|
||||
serverList.value = dbServerList
|
||||
}
|
||||
return serverList
|
||||
return repository.loadAllServerSettings()
|
||||
}
|
||||
|
||||
/**
|
||||
@ -101,55 +95,47 @@ class ServerSettingsModel(
|
||||
* This function is asynchronous, uses LiveData to provide the Setting.
|
||||
*/
|
||||
fun getServerSetting(index: Int): LiveData<ServerSetting?> {
|
||||
val result = MutableLiveData<ServerSetting?>()
|
||||
viewModelScope.launch {
|
||||
val dbServer = repository.findByIndex(index)
|
||||
result.value = dbServer
|
||||
Log.d(TAG, "getServerSetting($index) returning $dbServer")
|
||||
}
|
||||
return result
|
||||
return repository.getLiveServerSettingByIndex(index)
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves a Setting up in the Server List by decreasing its index
|
||||
*/
|
||||
fun moveItemUp(index: Int) {
|
||||
if (index == 1) return
|
||||
|
||||
val itemToBeMoved = serverList.value?.single { setting -> setting.index == index }
|
||||
val previousItem = serverList.value?.single { setting -> setting.index == index - 1 }
|
||||
|
||||
itemToBeMoved?.index = previousItem!!.index
|
||||
previousItem.index = index
|
||||
if (index <= 1) return
|
||||
|
||||
viewModelScope.launch {
|
||||
repository.update(itemToBeMoved!!, previousItem)
|
||||
}
|
||||
val itemToBeMoved = repository.findByIndex(index)
|
||||
val previousItem = repository.findByIndex(index - 1)
|
||||
|
||||
if (itemToBeMoved != null && previousItem != null) {
|
||||
itemToBeMoved.index = previousItem.index
|
||||
previousItem.index = index
|
||||
|
||||
repository.update(itemToBeMoved, previousItem)
|
||||
activeServerProvider.invalidateCache()
|
||||
// Notify the observers of the changed values
|
||||
serverList.value = serverList.value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves a Setting down in the Server List by increasing its index
|
||||
*/
|
||||
fun moveItemDown(index: Int) {
|
||||
if (index == (serverList.value!!.size - 1)) return
|
||||
viewModelScope.launch {
|
||||
if (index < repository.getMaxIndex() ?: 0) {
|
||||
val itemToBeMoved = repository.findByIndex(index)
|
||||
val nextItem = repository.findByIndex(index + 1)
|
||||
|
||||
val itemToBeMoved = serverList.value?.single { setting -> setting.index == index }
|
||||
val nextItem = serverList.value?.single { setting -> setting.index == index + 1 }
|
||||
|
||||
itemToBeMoved?.index = nextItem!!.index
|
||||
if (itemToBeMoved != null && nextItem != null) {
|
||||
itemToBeMoved.index = nextItem.index
|
||||
nextItem.index = index
|
||||
|
||||
viewModelScope.launch {
|
||||
repository.update(itemToBeMoved!!, nextItem)
|
||||
}
|
||||
|
||||
repository.update(itemToBeMoved, nextItem)
|
||||
activeServerProvider.invalidateCache()
|
||||
// Notify the observers of the changed values
|
||||
serverList.value = serverList.value
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -158,24 +144,15 @@ class ServerSettingsModel(
|
||||
fun deleteItem(index: Int) {
|
||||
if (index == 0) return
|
||||
|
||||
val newList = serverList.value!!.toMutableList()
|
||||
val itemToBeDeleted = newList.single { setting -> setting.index == index }
|
||||
newList.remove(itemToBeDeleted)
|
||||
|
||||
for (x in index + 1 until newList.size + 1) {
|
||||
newList.single { setting -> setting.index == x }.index--
|
||||
}
|
||||
|
||||
viewModelScope.launch {
|
||||
val itemToBeDeleted = repository.findByIndex(index)
|
||||
if (itemToBeDeleted != null) {
|
||||
repository.delete(itemToBeDeleted)
|
||||
for (x in index until newList.size) {
|
||||
repository.update(newList.single { setting -> setting.index == x })
|
||||
}
|
||||
}
|
||||
|
||||
activeServerProvider.invalidateCache()
|
||||
serverList.value = newList
|
||||
Log.d(TAG, "deleteItem deleted index: $index")
|
||||
reindexSettings()
|
||||
activeServerProvider.invalidateCache()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -242,9 +219,9 @@ class ServerSettingsModel(
|
||||
* concurrency or migration errors) may get them out of order.
|
||||
* This would make the List Adapter crash, so it is best to prepare and check the list.
|
||||
*/
|
||||
private fun areIndexesMissing(settings: List<ServerSetting>): Boolean {
|
||||
for (i in 1 until settings.size + 1) {
|
||||
if (!settings.any { s -> s.index == i }) return true
|
||||
private suspend fun areIndexesMissing(): Boolean {
|
||||
for (i in 1 until getMaximumIndexToCheck() + 1) {
|
||||
if (repository.findByIndex(i) == null) return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
@ -252,13 +229,23 @@ class ServerSettingsModel(
|
||||
/**
|
||||
* This function updates all the Server Settings in the DB so their indexing is continuous.
|
||||
*/
|
||||
private suspend fun reindexSettings(settings: List<ServerSetting>): List<ServerSetting> {
|
||||
val sortedSettings = settings.sortedBy { t -> t.index }
|
||||
for (i in sortedSettings.indices) {
|
||||
sortedSettings[i].index = i + 1
|
||||
repository.update(sortedSettings[i])
|
||||
Log.d(TAG, "reindexSettings saved ${sortedSettings[i]}")
|
||||
private suspend fun reindexSettings() {
|
||||
var newIndex = 1
|
||||
for (i in 1 until getMaximumIndexToCheck() + 1) {
|
||||
var setting = repository.findByIndex(i)
|
||||
if (setting != null) {
|
||||
setting.index = newIndex
|
||||
newIndex++
|
||||
repository.update(setting)
|
||||
Log.d(TAG, "reindexSettings saved $setting")
|
||||
}
|
||||
return sortedSettings
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun getMaximumIndexToCheck(): Int {
|
||||
val rowsInDatabase = repository.count() ?: 0
|
||||
val indexesInDatabase = repository.getMaxIndex() ?: 0
|
||||
if (rowsInDatabase > indexesInDatabase) return rowsInDatabase
|
||||
return indexesInDatabase
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package org.moire.ultrasonic.data
|
||||
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Delete
|
||||
import androidx.room.Insert
|
||||
@ -35,7 +36,7 @@ interface ServerSettingDao {
|
||||
* Loads all Server Settings from the table
|
||||
*/
|
||||
@Query("SELECT * FROM serverSetting")
|
||||
suspend fun loadAllServerSettings(): Array<ServerSetting>
|
||||
fun loadAllServerSettings(): LiveData<List<ServerSetting>>
|
||||
|
||||
/**
|
||||
* Finds a Server Setting by its unique Id
|
||||
@ -49,6 +50,13 @@ interface ServerSettingDao {
|
||||
@Query("SELECT * FROM serverSetting WHERE [index] = :index")
|
||||
suspend fun findByIndex(index: Int): ServerSetting?
|
||||
|
||||
/**
|
||||
* Finds a Server Setting by its Index in the Select List
|
||||
* @return LiveData of the ServerSetting
|
||||
*/
|
||||
@Query("SELECT * FROM serverSetting WHERE [index] = :index")
|
||||
fun getLiveServerSettingByIndex(index: Int): LiveData<ServerSetting?>
|
||||
|
||||
/**
|
||||
* Retrieves the count of rows in the table
|
||||
*/
|
||||
@ -60,4 +68,10 @@ interface ServerSettingDao {
|
||||
*/
|
||||
@Query("SELECT MAX([id]) FROM serverSetting")
|
||||
suspend fun getMaxId(): Int?
|
||||
|
||||
/**
|
||||
* Retrieves the greatest value of the Index column in the table
|
||||
*/
|
||||
@Query("SELECT MAX([index]) FROM serverSetting")
|
||||
suspend fun getMaxIndex(): Int?
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user