Merge branch 'master' into repository_tests
Some checks failed
continuous-integration/drone/pr Build is failing
Some checks failed
continuous-integration/drone/pr Build is failing
This commit is contained in:
@ -28,12 +28,12 @@ kotlin {
|
||||
sourceSets {
|
||||
val commonMain by getting {
|
||||
dependencies {
|
||||
implementation("io.ktor:ktor-client-core:2.0.1")
|
||||
implementation("io.ktor:ktor-client-content-negotiation:2.0.1")
|
||||
implementation("io.ktor:ktor-serialization-kotlinx-json:2.0.1")
|
||||
implementation("io.ktor:ktor-client-logging:2.0.1")
|
||||
implementation("io.ktor:ktor-client-core:2.1.1")
|
||||
implementation("io.ktor:ktor-client-content-negotiation:2.1.1")
|
||||
implementation("io.ktor:ktor-serialization-kotlinx-json:2.1.1")
|
||||
implementation("io.ktor:ktor-client-logging:2.1.1")
|
||||
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.0")
|
||||
implementation("io.ktor:ktor-client-auth:2.0.1")
|
||||
implementation("io.ktor:ktor-client-auth:2.1.1")
|
||||
implementation("org.jsoup:jsoup:1.14.3")
|
||||
|
||||
//Dependency Injection
|
||||
@ -62,7 +62,7 @@ kotlin {
|
||||
}
|
||||
val androidMain by getting {
|
||||
dependencies {
|
||||
implementation("io.ktor:ktor-client-android:2.0.1")
|
||||
implementation("io.ktor:ktor-client-okhttp:2.1.1")
|
||||
|
||||
// Sql
|
||||
implementation(SqlDelight.android)
|
||||
@ -96,7 +96,7 @@ kotlin {
|
||||
iosX64Test.dependsOn(this)
|
||||
iosArm64Test.dependsOn(this)
|
||||
dependencies {
|
||||
implementation("io.ktor:ktor-client-ios:2.0.1")
|
||||
implementation("io.ktor:ktor-client-ios:2.1.1")
|
||||
}
|
||||
//iosSimulatorArm64Test.dependsOn(this)
|
||||
}
|
||||
|
@ -2,7 +2,14 @@ package bou.amine.apps.readerforselfossv2.model
|
||||
|
||||
import bou.amine.apps.readerforselfossv2.utils.DateUtils
|
||||
import bou.amine.apps.readerforselfossv2.utils.getHtmlDecoded
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.descriptors.PrimitiveKind
|
||||
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
|
||||
import kotlinx.serialization.descriptors.SerialDescriptor
|
||||
import kotlinx.serialization.encoding.Decoder
|
||||
import kotlinx.serialization.encoding.Encoder
|
||||
import kotlinx.serialization.json.*
|
||||
|
||||
class SelfossModel {
|
||||
|
||||
@ -50,6 +57,7 @@ class SelfossModel {
|
||||
data class Source(
|
||||
val id: Int,
|
||||
val title: String,
|
||||
@Serializable(with = TagsListSerializer::class)
|
||||
val tags: List<String>,
|
||||
val spout: String,
|
||||
val error: String,
|
||||
@ -62,12 +70,15 @@ class SelfossModel {
|
||||
val datetime: String,
|
||||
val title: String,
|
||||
val content: String,
|
||||
@Serializable(with = BooleanSerializer::class)
|
||||
var unread: Boolean,
|
||||
@Serializable(with = BooleanSerializer::class)
|
||||
var starred: Boolean,
|
||||
val thumbnail: String?,
|
||||
val icon: String?,
|
||||
val link: String,
|
||||
val sourcetitle: String,
|
||||
@Serializable(with = TagsListSerializer::class)
|
||||
val tags: List<String>
|
||||
) {
|
||||
// TODO: maybe find a better way to handle these kind of urls
|
||||
@ -106,6 +117,38 @@ class SelfossModel {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: this seems to be super slow.
|
||||
object TagsListSerializer : KSerializer<List<String>> {
|
||||
override fun deserialize(decoder: Decoder): List<String> {
|
||||
return when(val json = ((decoder as JsonDecoder).decodeJsonElement())) {
|
||||
is JsonArray -> json.toList().map { it.toString() }
|
||||
else -> json.toString().split(",")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override val descriptor: SerialDescriptor
|
||||
get() = PrimitiveSerialDescriptor("tags", PrimitiveKind.STRING)
|
||||
|
||||
override fun serialize(encoder: Encoder, value: List<String>) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
}
|
||||
|
||||
object BooleanSerializer : KSerializer<Boolean> {
|
||||
override fun deserialize(decoder: Decoder): Boolean {
|
||||
val json = ((decoder as JsonDecoder).decodeJsonElement()).jsonPrimitive
|
||||
return json.booleanOrNull ?: json.int == 1
|
||||
}
|
||||
|
||||
override val descriptor: SerialDescriptor
|
||||
get() = PrimitiveSerialDescriptor("b", PrimitiveKind.BOOLEAN)
|
||||
|
||||
override fun serialize(encoder: Encoder, value: Boolean) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
}
|
||||
|
||||
class StatusAndData<T>(val success: Boolean, val data: T? = null) {
|
||||
companion object {
|
||||
fun <T> succes(d: T): StatusAndData<T> {
|
||||
@ -117,4 +160,4 @@ class SelfossModel {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -49,6 +49,7 @@ class Repository(private val api: SelfossApi, private val appSettingsService: Ap
|
||||
suspend fun getNewerItems(): ArrayList<SelfossModel.Item> {
|
||||
// TODO: Use the updatedSince parameter
|
||||
var fetchedItems: SelfossModel.StatusAndData<List<SelfossModel.Item>> = SelfossModel.StatusAndData.error()
|
||||
var fromDB = false
|
||||
if (isNetworkAvailable()) {
|
||||
fetchedItems = api.getItems(
|
||||
displayedItems.type,
|
||||
@ -60,6 +61,7 @@ class Repository(private val api: SelfossApi, private val appSettingsService: Ap
|
||||
)
|
||||
} else {
|
||||
if (appSettingsService.isItemCachingEnabled()) {
|
||||
fromDB = true
|
||||
fetchedItems = SelfossModel.StatusAndData.succes(
|
||||
getDBItems().filter {
|
||||
displayedItems == ItemType.ALL ||
|
||||
@ -72,7 +74,9 @@ class Repository(private val api: SelfossApi, private val appSettingsService: Ap
|
||||
|
||||
if (fetchedItems.success && fetchedItems.data != null) {
|
||||
items = ArrayList(fetchedItems.data!!)
|
||||
sortItems()
|
||||
if (fromDB) {
|
||||
items.sortByDescending { dateUtils.parseDate(it.datetime) }
|
||||
}
|
||||
}
|
||||
return items
|
||||
}
|
||||
@ -93,7 +97,6 @@ class Repository(private val api: SelfossApi, private val appSettingsService: Ap
|
||||
|
||||
if (fetchedItems.success && fetchedItems.data != null) {
|
||||
items.addAll(fetchedItems.data!!)
|
||||
sortItems()
|
||||
}
|
||||
return items
|
||||
}
|
||||
@ -119,10 +122,6 @@ class Repository(private val api: SelfossApi, private val appSettingsService: Ap
|
||||
}
|
||||
}
|
||||
|
||||
private fun sortItems() {
|
||||
items.sortByDescending { dateUtils.parseDate(it.datetime) }
|
||||
}
|
||||
|
||||
suspend fun reloadBadges(): Boolean {
|
||||
var success = false
|
||||
if (isNetworkAvailable()) {
|
||||
|
@ -15,7 +15,6 @@ class AppSettingsService {
|
||||
|
||||
// User settings related
|
||||
private var _itemsCaching: Boolean? = null
|
||||
private var _internalBrowser: Boolean? = null
|
||||
private var _articleViewer: Boolean? = null
|
||||
private var _shouldBeCardView: Boolean? = null
|
||||
private var _displayUnreadCount: Boolean? = null
|
||||
@ -88,7 +87,7 @@ class AppSettingsService {
|
||||
}
|
||||
|
||||
fun refreshItemsNumber() {
|
||||
_itemsNumber = settings.getString("prefer_api_items_number", "200").toInt()
|
||||
_itemsNumber = settings.getString("prefer_api_items_number", "20").toInt()
|
||||
}
|
||||
|
||||
fun getApiTimeout(): Long {
|
||||
@ -115,17 +114,6 @@ class AppSettingsService {
|
||||
_password = settings.getString("password", "")
|
||||
}
|
||||
|
||||
private fun refreshInternalBrowserEnabled() {
|
||||
_internalBrowser = settings.getBoolean("prefer_internal_browser", true)
|
||||
}
|
||||
|
||||
fun isInternalBrowserEnabled(): Boolean {
|
||||
if (_internalBrowser != null) {
|
||||
refreshInternalBrowserEnabled()
|
||||
}
|
||||
return _internalBrowser == true
|
||||
}
|
||||
|
||||
private fun refreshArticleViewerEnabled() {
|
||||
_articleViewer = settings.getBoolean("prefer_article_viewer", true)
|
||||
}
|
||||
@ -340,7 +328,6 @@ class AppSettingsService {
|
||||
fun refreshUserSettings() {
|
||||
refreshItemsNumber()
|
||||
refreshApiTimeout()
|
||||
refreshInternalBrowserEnabled()
|
||||
refreshArticleViewerEnabled()
|
||||
refreshShouldBeCardViewEnabled()
|
||||
refreshDisplayUnreadCountEnabled()
|
||||
|
Reference in New Issue
Block a user