WIP: Big settings cleaning.
This commit is contained in:
@ -1,18 +1,21 @@
|
||||
package bou.amine.apps.readerforselfossv2.utils
|
||||
|
||||
import android.text.format.DateUtils
|
||||
import bou.amine.apps.readerforselfossv2.service.ApiDetailsService
|
||||
import java.time.Instant
|
||||
import java.time.LocalDateTime
|
||||
import java.time.OffsetDateTime
|
||||
import java.time.ZoneOffset
|
||||
import java.time.format.DateTimeFormatter
|
||||
|
||||
actual class DateUtils actual constructor(private val apiMajorVersion: Int) {
|
||||
actual class DateUtils actual constructor(apiDetailsService: ApiDetailsService) {
|
||||
val ads: ApiDetailsService = apiDetailsService // TODO: why is this needed now ?
|
||||
|
||||
actual fun parseDate(dateString: String): Long {
|
||||
|
||||
val FORMATTERV1 = "yyyy-MM-dd HH:mm:ss"
|
||||
|
||||
return if (apiMajorVersion >= 4) {
|
||||
return if (ads.getApiVersion() >= 4) {
|
||||
OffsetDateTime.parse(dateString).toInstant().toEpochMilli()
|
||||
} else {
|
||||
LocalDateTime.parse(dateString, DateTimeFormatter.ofPattern(FORMATTERV1)).toInstant(
|
||||
|
@ -2,13 +2,12 @@ package bou.amine.apps.readerforselfossv2.DI
|
||||
|
||||
import bou.amine.apps.readerforselfossv2.rest.SelfossApi
|
||||
import bou.amine.apps.readerforselfossv2.service.ApiDetailsService
|
||||
import bou.amine.apps.readerforselfossv2.service.ApiDetailsServiceImpl
|
||||
import org.kodein.di.DI
|
||||
import org.kodein.di.bind
|
||||
import org.kodein.di.instance
|
||||
import org.kodein.di.singleton
|
||||
|
||||
val networkModule by DI.Module {
|
||||
bind<ApiDetailsService>() with singleton { ApiDetailsServiceImpl() }
|
||||
bind<ApiDetailsService>() with singleton { ApiDetailsService() }
|
||||
bind<SelfossApi>() with singleton { SelfossApi(instance()) }
|
||||
}
|
@ -32,7 +32,6 @@ class Repository(private val api: SelfossApi, private val apiDetails: ApiDetails
|
||||
var itemsCaching = settings.getBoolean("items_caching", false)
|
||||
var offlineOverride = false
|
||||
|
||||
var apiMajorVersion = 0
|
||||
var badgeUnread = 0
|
||||
set(value) {field = if (value < 0) { 0 } else { value } }
|
||||
var badgeAll = 0
|
||||
@ -44,6 +43,7 @@ class Repository(private val api: SelfossApi, private val apiDetails: ApiDetails
|
||||
// TODO: Dispatchers.IO not available in KMM, an alternative solution should be found
|
||||
CoroutineScope(Dispatchers.Main).launch {
|
||||
updateApiVersion()
|
||||
dateUtils = DateUtils(apiDetails)
|
||||
reloadBadges()
|
||||
}
|
||||
}
|
||||
@ -54,7 +54,6 @@ class Repository(private val api: SelfossApi, private val apiDetails: ApiDetails
|
||||
if (isNetworkAvailable()) {
|
||||
fetchedItems = api.getItems(
|
||||
displayedItems.type,
|
||||
settings.getString("prefer_api_items_number", "200").toInt(),
|
||||
offset = 0,
|
||||
tagFilter?.tag,
|
||||
sourceFilter?.id?.toLong(),
|
||||
@ -84,7 +83,6 @@ class Repository(private val api: SelfossApi, private val apiDetails: ApiDetails
|
||||
val offset = items.size
|
||||
fetchedItems = api.getItems(
|
||||
displayedItems.type,
|
||||
settings.getString("prefer_api_items_number", "200").toInt(),
|
||||
offset,
|
||||
tagFilter?.tag,
|
||||
sourceFilter?.id?.toLong(),
|
||||
@ -104,12 +102,12 @@ class Repository(private val api: SelfossApi, private val apiDetails: ApiDetails
|
||||
return if (isNetworkAvailable()) {
|
||||
api.getItems(
|
||||
itemType.type,
|
||||
200,
|
||||
0,
|
||||
tagFilter?.tag,
|
||||
sourceFilter?.id?.toLong(),
|
||||
searchFilter,
|
||||
null
|
||||
null,
|
||||
200
|
||||
)
|
||||
} else {
|
||||
emptyList()
|
||||
@ -309,7 +307,7 @@ class Repository(private val api: SelfossApi, private val apiDetails: ApiDetails
|
||||
spout,
|
||||
tags,
|
||||
filter,
|
||||
apiMajorVersion
|
||||
apiDetails.getApiVersion()
|
||||
)?.isSuccess == true
|
||||
}
|
||||
|
||||
@ -366,13 +364,13 @@ class Repository(private val api: SelfossApi, private val apiDetails: ApiDetails
|
||||
}
|
||||
|
||||
private suspend fun updateApiVersion() {
|
||||
apiMajorVersion = settings.getInt("apiVersionMajor", 0)
|
||||
val apiMajorVersion = apiDetails.getApiVersion()
|
||||
|
||||
if (isNetworkAvailable()) {
|
||||
val fetchedVersion = api.version()
|
||||
if (fetchedVersion != null) {
|
||||
apiMajorVersion = fetchedVersion.getApiMajorVersion()
|
||||
settings.putInt("apiVersionMajor", apiMajorVersion)
|
||||
if (fetchedVersion != null && fetchedVersion.getApiMajorVersion() != apiMajorVersion) {
|
||||
settings.putInt("apiVersionMajor", fetchedVersion.getApiMajorVersion())
|
||||
apiDetails.refreshApiVersion()
|
||||
}
|
||||
}
|
||||
dateUtils = DateUtils(apiMajorVersion)
|
||||
|
@ -4,6 +4,7 @@ import bou.amine.apps.readerforselfossv2.model.SelfossModel
|
||||
import bou.amine.apps.readerforselfossv2.service.ApiDetailsService
|
||||
import io.ktor.client.*
|
||||
import io.ktor.client.call.*
|
||||
import io.ktor.client.plugins.*
|
||||
import io.ktor.client.plugins.cache.*
|
||||
import io.ktor.client.request.*
|
||||
import io.ktor.client.request.forms.*
|
||||
@ -35,6 +36,9 @@ class SelfossApi(private val apiDetailsService: ApiDetailsService) {
|
||||
}
|
||||
level = LogLevel.ALL
|
||||
}
|
||||
install(HttpTimeout) {
|
||||
requestTimeoutMillis = apiDetailsService.getApiTimeout()
|
||||
}
|
||||
/* TODO: Auth as basic
|
||||
if (apiDetailsService.getUserName().isNotEmpty() && apiDetailsService.getPassword().isNotEmpty()) {
|
||||
|
||||
@ -69,12 +73,12 @@ class SelfossApi(private val apiDetailsService: ApiDetailsService) {
|
||||
|
||||
suspend fun getItems(
|
||||
type: String,
|
||||
items: Int,
|
||||
offset: Int,
|
||||
tag: String?,
|
||||
source: Long?,
|
||||
search: String?,
|
||||
updatedSince: String?
|
||||
updatedSince: String?,
|
||||
items: Int? = null
|
||||
): List<SelfossModel.Item>? =
|
||||
client.get(url("/items")) {
|
||||
parameter("username", apiDetailsService.getUserName())
|
||||
@ -84,7 +88,7 @@ class SelfossApi(private val apiDetailsService: ApiDetailsService) {
|
||||
parameter("source", source)
|
||||
parameter("search", search)
|
||||
parameter("updatedsince", updatedSince)
|
||||
parameter("items", items)
|
||||
parameter("items", items ?: apiDetailsService.getItemsNumber())
|
||||
parameter("offset", offset)
|
||||
}.body()
|
||||
|
||||
|
@ -1,10 +1,97 @@
|
||||
package bou.amine.apps.readerforselfossv2.service
|
||||
|
||||
interface ApiDetailsService {
|
||||
fun logApiCalls(message: String)
|
||||
fun getApiVersion(): Int
|
||||
fun getBaseUrl(): String
|
||||
fun getUserName(): String
|
||||
fun getPassword(): String
|
||||
fun refresh()
|
||||
import com.russhwolf.settings.Settings
|
||||
import io.github.aakira.napier.Napier
|
||||
import io.ktor.client.plugins.*
|
||||
|
||||
class ApiDetailsService {
|
||||
val settings: Settings = Settings()
|
||||
private var _apiVersion: Int = -1
|
||||
private var _baseUrl: String = ""
|
||||
private var _userName: String = ""
|
||||
private var _password: String = ""
|
||||
private var _itemsNumber: Int? = null
|
||||
private var _apiTimeout: Long? = null
|
||||
|
||||
fun logApiCalls(message: String) {
|
||||
Napier.d(message, tag = "LogApiCalls")
|
||||
}
|
||||
|
||||
|
||||
fun getApiVersion(): Int {
|
||||
if (_apiVersion == -1) {
|
||||
refreshApiVersion()
|
||||
return _apiVersion
|
||||
}
|
||||
return _apiVersion
|
||||
}
|
||||
|
||||
fun refreshApiVersion() {
|
||||
_apiVersion = settings.getInt("apiVersionMajor", -1)
|
||||
}
|
||||
|
||||
fun getBaseUrl(): String {
|
||||
if (_baseUrl.isEmpty()) {
|
||||
_baseUrl = settings.getString("url", "")
|
||||
}
|
||||
return _baseUrl
|
||||
}
|
||||
|
||||
fun getUserName(): String {
|
||||
if (_userName.isEmpty()) {
|
||||
_userName = settings.getString("login", "")
|
||||
}
|
||||
return _userName
|
||||
}
|
||||
|
||||
fun getPassword(): String {
|
||||
if (_password.isEmpty()) {
|
||||
_password = settings.getString("password", "")
|
||||
}
|
||||
return _password
|
||||
}
|
||||
|
||||
fun getItemsNumber(): Int {
|
||||
if (_itemsNumber == null) {
|
||||
refreshItemsNumber()
|
||||
}
|
||||
return _itemsNumber!!
|
||||
}
|
||||
|
||||
fun refreshItemsNumber() {
|
||||
_itemsNumber = settings.getString("prefer_api_items_number", "200").toInt()
|
||||
}
|
||||
|
||||
fun getApiTimeout(): Long {
|
||||
if (_apiTimeout == null) {
|
||||
refreshApiTimeout()
|
||||
}
|
||||
return _apiTimeout!!
|
||||
}
|
||||
|
||||
fun refreshApiTimeout() {
|
||||
val settingsTimeout = settings.getLong("api_timeout", HttpTimeout.INFINITE_TIMEOUT_MS)
|
||||
_apiTimeout = if (settingsTimeout > 0) settingsTimeout else HttpTimeout.INFINITE_TIMEOUT_MS
|
||||
}
|
||||
|
||||
fun refresh() {
|
||||
_password = settings.getString("password", "")
|
||||
_userName = settings.getString("login", "")
|
||||
_baseUrl = settings.getString("url", "")
|
||||
refreshApiVersion()
|
||||
refreshItemsNumber()
|
||||
refreshApiTimeout()
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val translationUrl = "https://crwd.in/readerforselfoss"
|
||||
|
||||
const val sourceUrl = "https://gitea.amine-louveau.fr/Louvorg/ReaderForSelfoss-multiplatform"
|
||||
|
||||
const val trackerUrl = "https://gitea.amine-louveau.fr/Louvorg/ReaderForSelfoss-multiplatform/issues"
|
||||
|
||||
const val syncChannelId = "sync-channel-id"
|
||||
|
||||
const val newItemsChannelId = "new-items-channel-id"
|
||||
}
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
package bou.amine.apps.readerforselfossv2.service
|
||||
|
||||
import com.russhwolf.settings.Settings
|
||||
import io.github.aakira.napier.Napier
|
||||
|
||||
class ApiDetailsServiceImpl : ApiDetailsService {
|
||||
val settings: Settings = Settings()
|
||||
private var _apiVersion: Int = -1
|
||||
private var _baseUrl: String = ""
|
||||
private var _userName: String = ""
|
||||
private var _password: String = ""
|
||||
override fun logApiCalls(message: String) {
|
||||
Napier.d(message, tag = "LogApiCalls")
|
||||
}
|
||||
|
||||
|
||||
override fun getApiVersion(): Int {
|
||||
if (_apiVersion == -1) {
|
||||
_apiVersion = settings.getInt("apiVersionMajor", -1)
|
||||
return _apiVersion
|
||||
}
|
||||
return _apiVersion
|
||||
}
|
||||
|
||||
override fun getBaseUrl(): String {
|
||||
if (_baseUrl.isEmpty()) {
|
||||
_baseUrl = settings.getString("url", "")
|
||||
}
|
||||
return _baseUrl
|
||||
}
|
||||
|
||||
override fun getUserName(): String {
|
||||
if (_userName.isEmpty()) {
|
||||
_userName = settings.getString("login", "")
|
||||
}
|
||||
return _userName
|
||||
}
|
||||
|
||||
override fun getPassword(): String {
|
||||
if (_password.isEmpty()) {
|
||||
_password = settings.getString("password", "")
|
||||
}
|
||||
return _password
|
||||
}
|
||||
|
||||
override fun refresh() {
|
||||
_password = settings.getString("password", "")
|
||||
_userName = settings.getString("login", "")
|
||||
_baseUrl = settings.getString("url", "")
|
||||
_apiVersion = settings.getInt("apiVersionMajor", -1)
|
||||
}
|
||||
}
|
@ -1,12 +1,13 @@
|
||||
package bou.amine.apps.readerforselfossv2.utils
|
||||
|
||||
import bou.amine.apps.readerforselfossv2.model.SelfossModel
|
||||
import bou.amine.apps.readerforselfossv2.service.ApiDetailsService
|
||||
|
||||
|
||||
fun SelfossModel.Item.parseDate(dateUtils: DateUtils): Long =
|
||||
dateUtils.parseDate(this.datetime)
|
||||
|
||||
expect class DateUtils(apiMajorVersion: Int) {
|
||||
expect class DateUtils(apiDetailsService: ApiDetailsService) {
|
||||
fun parseDate(dateString: String): Long
|
||||
|
||||
fun parseRelativeDate(dateString: String): String
|
||||
|
@ -1,6 +1,8 @@
|
||||
package bou.amine.apps.readerforselfossv2.utils
|
||||
|
||||
actual class DateUtils actual constructor(apiMajorVersion: Int) {
|
||||
import bou.amine.apps.readerforselfossv2.service.ApiDetailsService
|
||||
|
||||
actual class DateUtils actual constructor(apiDetailsService: ApiDetailsService) {
|
||||
actual fun parseDate(dateString: String): Long {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
package bou.amine.apps.readerforselfossv2.utils
|
||||
|
||||
actual class DateUtils actual constructor(apiMajorVersion: Int) {
|
||||
import bou.amine.apps.readerforselfossv2.service.ApiDetailsService
|
||||
|
||||
actual class DateUtils actual constructor(apiDetailsService: ApiDetailsService) {
|
||||
actual fun parseDate(dateString: String): Long {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
Reference in New Issue
Block a user