From 5494978db8a2d56298457ad08a6222a2de65b252 Mon Sep 17 00:00:00 2001 From: aminecmi Date: Sat, 29 Oct 2022 20:50:44 +0200 Subject: [PATCH 1/7] Cleaning. --- androidApp/build.gradle.kts | 15 ++- .../android/AddSourceActivity.kt | 2 +- .../android/LoginActivity.kt | 4 +- .../android/SourcesActivity.kt | 2 +- androidApp/src/test/kotlin/RepositoryTest.kt | 116 +++++++++--------- gradle.properties | 1 - shared/build.gradle.kts | 1 + .../readerforselfossv2/utils/DateUtils.kt | 43 ++----- 8 files changed, 80 insertions(+), 104 deletions(-) diff --git a/androidApp/build.gradle.kts b/androidApp/build.gradle.kts index e76add7..cfed35a 100644 --- a/androidApp/build.gradle.kts +++ b/androidApp/build.gradle.kts @@ -54,9 +54,13 @@ fun versionNameFromGit(): String { android { compileOptions { // Flag to enable support for the new language APIs - isCoreLibraryDesugaringEnabled = true - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 + } + + // For Kotlin projects + kotlinOptions { + jvmTarget = "11" } compileSdk = 32 buildToolsVersion = "31.0.0" @@ -130,8 +134,6 @@ dependencies { implementation("androidx.constraintlayout:constraintlayout:2.1.3") implementation("org.jsoup:jsoup:1.14.3") - coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:1.1.5") - //multidex implementation("androidx.multidex:multidex:2.0.1") @@ -140,9 +142,6 @@ dependencies { implementation("com.mikepenz:aboutlibraries:8.9.4") implementation("com.mikepenz:aboutlibraries-definitions:8.9.4") - // Async - implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.0") - // Retrofit + http logging + okhttp implementation("com.squareup.retrofit2:retrofit:2.9.0") implementation("com.squareup.okhttp3:logging-interceptor:5.0.0-alpha.3") diff --git a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/AddSourceActivity.kt b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/AddSourceActivity.kt index 26b1239..b0bbf82 100644 --- a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/AddSourceActivity.kt +++ b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/AddSourceActivity.kt @@ -94,7 +94,7 @@ class AddSourceActivity : AppCompatActivity(), DIAware { CoroutineScope(Dispatchers.Main).launch { try { val items = repository.getSpouts() - if (items != null) { + if (items.isNotEmpty()) { val itemsStrings = items.map { it.value.name } for ((key, value) in items) { spoutsKV[value.name] = key diff --git a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/LoginActivity.kt b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/LoginActivity.kt index a5ad48e..376ec0e 100644 --- a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/LoginActivity.kt +++ b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/LoginActivity.kt @@ -101,7 +101,7 @@ class LoginActivity : AppCompatActivity(), DIAware { finish() } - private fun preferenceError(t: Throwable) { + private fun preferenceError() { appSettingsService.resetLoginInformation() binding.urlView.error = getString(R.string.wrong_infos) @@ -169,7 +169,7 @@ class LoginActivity : AppCompatActivity(), DIAware { goToMain() } else { CoroutineScope(Dispatchers.Main).launch { - preferenceError(Exception("Not success")) + preferenceError() } } } diff --git a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/SourcesActivity.kt b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/SourcesActivity.kt index 4a99f96..4cce83e 100644 --- a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/SourcesActivity.kt +++ b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/SourcesActivity.kt @@ -56,7 +56,7 @@ class SourcesActivity : AppCompatActivity(), DIAware { CoroutineScope(Dispatchers.Main).launch { val response = repository.getSources() - if (response != null) { + if (response.isNotEmpty()) { items = response val mAdapter = SourcesListAdapter( this@SourcesActivity, items diff --git a/androidApp/src/test/kotlin/RepositoryTest.kt b/androidApp/src/test/kotlin/RepositoryTest.kt index 6033d25..32f98b9 100644 --- a/androidApp/src/test/kotlin/RepositoryTest.kt +++ b/androidApp/src/test/kotlin/RepositoryTest.kt @@ -64,14 +64,14 @@ class RepositoryTest { } @Test - fun Instantiate_repository() { + fun instantiate_repository() { initializeRepository() coVerify(exactly = 1) { api.version() } } @Test - fun Instantiate_repository_without_api_version() { + fun instantiate_repository_without_api_version() { every { appSettingsService.getApiVersion() } returns -1 initializeRepository(MutableStateFlow(false)) @@ -81,7 +81,7 @@ class RepositoryTest { } @Test - fun Get_api_4_date_with_api_1_version_stored() { + fun get_api_4_date_with_api_1_version_stored() { every { appSettingsService.getApiVersion() } returns 1 coEvery { api.getItems(any(), any(), any(), any(), any(), any(), any()) } returns SelfossModel.StatusAndData(success = true, data = generateTestApiItem()) @@ -97,7 +97,7 @@ class RepositoryTest { } @Test - fun Get_api_1_date_with_api_4_version_stored() { + fun get_api_1_date_with_api_4_version_stored() { every { appSettingsService.getApiVersion() } returns 4 coEvery { api.version() } returns SelfossModel.StatusAndData(success = false, null) val itemParameters = FakeItemParameters() @@ -117,7 +117,7 @@ class RepositoryTest { } @Test - fun Get_newer_items() { + fun get_newer_items() { coEvery { api.getItems(any(), any(), any(), any(), any(), any(), any()) } returns SelfossModel.StatusAndData(success = true, data = generateTestApiItem()) @@ -132,7 +132,7 @@ class RepositoryTest { } @Test - fun Get_all_newer_items() { + fun get_all_newer_items() { coEvery { api.getItems(any(), any(), any(), any(), any(), any(), any()) } returns SelfossModel.StatusAndData(success = true, data = generateTestApiItem()) @@ -148,7 +148,7 @@ class RepositoryTest { } @Test - fun Get_newer_starred_items() { + fun get_newer_starred_items() { coEvery { api.getItems(any(), any(), any(), any(), any(), any(), any()) } returns SelfossModel.StatusAndData(success = true, data = generateTestApiItem()) @@ -164,7 +164,7 @@ class RepositoryTest { } @Test - fun Get_newer_items_without_connectivity() { + fun get_newer_items_without_connectivity() { every { appSettingsService.isItemCachingEnabled() } returns true initializeRepository(MutableStateFlow(false)) @@ -178,7 +178,7 @@ class RepositoryTest { } @Test - fun Get_newer_items_without_connectivity_and_tag_filter() { + fun get_newer_items_without_connectivity_and_tag_filter() { val itemParameter1 = FakeItemParameters() val itemParameter2 = FakeItemParameters() val itemParameter3 = FakeItemParameters() @@ -206,7 +206,7 @@ class RepositoryTest { } @Test - fun Get_newer_items_without_connectivity_and_source_filter() { + fun get_newer_items_without_connectivity_and_source_filter() { val itemParameter1 = FakeItemParameters() val itemParameter2 = FakeItemParameters() val itemParameter3 = FakeItemParameters() @@ -241,7 +241,7 @@ class RepositoryTest { } @Test - fun Get_older_items() { + fun get_older_items() { coEvery { api.getItems(any(), any(), any(), any(), any(), any(), any()) } returns SelfossModel.StatusAndData(success = true, data = generateTestApiItem()) @@ -257,7 +257,7 @@ class RepositoryTest { } @Test - fun Get_all_older_items() { + fun get_all_older_items() { coEvery { api.getItems(any(), any(), any(), any(), any(), any(), any()) } returns SelfossModel.StatusAndData(success = true, data = generateTestApiItem()) @@ -274,7 +274,7 @@ class RepositoryTest { } @Test - fun Get_older_starred_items() { + fun get_older_starred_items() { coEvery { api.getItems(any(), any(), any(), any(), any(), any(), any()) } returns SelfossModel.StatusAndData(success = true, data = generateTestApiItem()) @@ -291,8 +291,8 @@ class RepositoryTest { } @Test - fun Reload_badges() { - var success = false + fun reload_badges() { + var success: Boolean initializeRepository() runBlocking { @@ -308,10 +308,10 @@ class RepositoryTest { } @Test - fun Reload_badges_without_response() { + fun reload_badges_without_response() { coEvery { api.stats() } returns SelfossModel.StatusAndData(success = false, data = null) - var success = false + var success: Boolean initializeRepository() runBlocking { @@ -327,11 +327,11 @@ class RepositoryTest { } @Test - fun Reload_badges_without_connection() { + fun reload_badges_without_connection() { every { appSettingsService.isItemCachingEnabled() } returns true every { db.itemsQueries.items().executeAsList() } returns generateTestDBItems() - var success = false + var success: Boolean initializeRepository(MutableStateFlow(false)) runBlocking { @@ -347,11 +347,11 @@ class RepositoryTest { } @Test - fun Reload_badges_without_connection_and_items_caching_disabled() { + fun reload_badges_without_connection_and_items_caching_disabled() { every { appSettingsService.isItemCachingEnabled() } returns false every { appSettingsService.isUpdateSourcesEnabled() } returns true - var success = false + var success: Boolean initializeRepository(MutableStateFlow(false)) runBlocking { @@ -367,7 +367,7 @@ class RepositoryTest { } @Test - fun Get_tags() { + fun get_tags() { val tags = listOf( SelfossModel.Tag("test", "red", 6), SelfossModel.Tag("second", "yellow", 0) @@ -383,7 +383,7 @@ class RepositoryTest { every { appSettingsService.isItemCachingEnabled() } returns true initializeRepository() - var testTags: List? = null + var testTags: List? runBlocking { testTags = repository.getTags() } @@ -394,7 +394,7 @@ class RepositoryTest { } @Test - fun Get_tags_with_sources_update_disabled() { + fun get_tags_with_sources_update_disabled() { val tags = listOf( SelfossModel.Tag("test", "red", 6), SelfossModel.Tag("second", "yellow", 0) @@ -410,7 +410,7 @@ class RepositoryTest { every { appSettingsService.isItemCachingEnabled() } returns true initializeRepository() - var testTags: List = emptyList() + var testTags: List runBlocking { testTags = repository.getTags() // Tags will be fetched from the database on the second call, thus testTags != tags @@ -424,7 +424,7 @@ class RepositoryTest { } @Test - fun Get_tags_with_items_caching_disabled() { + fun get_tags_with_items_caching_disabled() { val tags = listOf( SelfossModel.Tag("test", "red", 6), SelfossModel.Tag("second", "yellow", 0) @@ -440,7 +440,7 @@ class RepositoryTest { every { appSettingsService.isItemCachingEnabled() } returns false initializeRepository() - var testTags: List = emptyList() + var testTags: List runBlocking { testTags = repository.getTags() } @@ -451,7 +451,7 @@ class RepositoryTest { } @Test - fun Get_tags_with_sources_update_and_items_caching_disabled() { + fun get_tags_with_sources_update_and_items_caching_disabled() { val tags = listOf( SelfossModel.Tag("test", "red", 6), SelfossModel.Tag("second", "yellow", 0) @@ -467,7 +467,7 @@ class RepositoryTest { every { appSettingsService.isItemCachingEnabled() } returns false initializeRepository() - var testTags: List = emptyList() + var testTags: List runBlocking { testTags = repository.getTags() testTags = repository.getTags() @@ -480,7 +480,7 @@ class RepositoryTest { } @Test - fun Get_tags_without_connection() { + fun get_tags_without_connection() { val tags = listOf( SelfossModel.Tag("test", "red", 6), SelfossModel.Tag("second", "yellow", 0) @@ -496,7 +496,7 @@ class RepositoryTest { every { appSettingsService.isItemCachingEnabled() } returns true initializeRepository(MutableStateFlow(false)) - var testTags: List = emptyList() + var testTags: List runBlocking { testTags = repository.getTags() } @@ -508,7 +508,7 @@ class RepositoryTest { } @Test - fun Get_tags_without_connection_and_items_caching_disabled() { + fun get_tags_without_connection_and_items_caching_disabled() { val tags = listOf( SelfossModel.Tag("test", "red", 6), SelfossModel.Tag("second", "yellow", 0) @@ -524,7 +524,7 @@ class RepositoryTest { every { appSettingsService.isUpdateSourcesEnabled() } returns true initializeRepository(MutableStateFlow(false)) - var testTags: List = emptyList() + var testTags: List runBlocking { testTags = repository.getTags() } @@ -535,7 +535,7 @@ class RepositoryTest { } @Test - fun Get_tags_without_connection_and_sources_update_disabled() { + fun get_tags_without_connection_and_sources_update_disabled() { val tags = listOf( SelfossModel.Tag("test", "red", 6), SelfossModel.Tag("second", "yellow", 0) @@ -551,7 +551,7 @@ class RepositoryTest { every { appSettingsService.isItemCachingEnabled() } returns true initializeRepository(MutableStateFlow(false)) - var testTags: List = emptyList() + var testTags: List runBlocking { testTags = repository.getTags() } @@ -563,7 +563,7 @@ class RepositoryTest { } @Test - fun Get_tags_without_connection_and_sources_update_and_items_caching_disabled() { + fun get_tags_without_connection_and_sources_update_and_items_caching_disabled() { val tags = listOf( SelfossModel.Tag("test", "red", 6), SelfossModel.Tag("second", "yellow", 0) @@ -579,7 +579,7 @@ class RepositoryTest { every { appSettingsService.isItemCachingEnabled() } returns false initializeRepository(MutableStateFlow(false)) - var testTags: List = emptyList() + var testTags: List runBlocking { testTags = repository.getTags() } @@ -631,7 +631,7 @@ class RepositoryTest { coEvery { api.sources() } returns SelfossModel.StatusAndData(success = true, data = sources) every { db.sourcesQueries.sources().executeAsList() } returns sourcesDB initializeRepository() - var testSources: List? = null + var testSources: List? runBlocking { testSources = repository.getSources() } @@ -685,7 +685,7 @@ class RepositoryTest { coEvery { api.sources() } returns SelfossModel.StatusAndData(success = true, data = sources) every { db.sourcesQueries.sources().executeAsList() } returns sourcesDB initializeRepository() - var testSources: List? = null + var testSources: List? runBlocking { testSources = repository.getSources() // Sources will be fetched from the database on the second call, thus testSources != sources @@ -742,7 +742,7 @@ class RepositoryTest { coEvery { api.sources() } returns SelfossModel.StatusAndData(success = true, data = sources) every { db.sourcesQueries.sources().executeAsList() } returns sourcesDB initializeRepository() - var testSources: List? = null + var testSources: List? runBlocking { testSources = repository.getSources() } @@ -796,7 +796,7 @@ class RepositoryTest { coEvery { api.sources() } returns SelfossModel.StatusAndData(success = true, data = sources) every { db.sourcesQueries.sources().executeAsList() } returns sourcesDB initializeRepository() - var testSources: List? = null + var testSources: List? runBlocking { testSources = repository.getSources() } @@ -848,7 +848,7 @@ class RepositoryTest { coEvery { api.sources() } returns SelfossModel.StatusAndData(success = true, data = sources) every { db.sourcesQueries.sources().executeAsList() } returns sourcesDB initializeRepository(MutableStateFlow(false)) - var testSources: List? = null + var testSources: List? runBlocking { testSources = repository.getSources() } @@ -902,7 +902,7 @@ class RepositoryTest { coEvery { api.sources() } returns SelfossModel.StatusAndData(success = true, data = sources) every { db.sourcesQueries.sources().executeAsList() } returns sourcesDB initializeRepository(MutableStateFlow(false)) - var testSources: List? = null + var testSources: List? runBlocking { testSources = repository.getSources() } @@ -956,7 +956,7 @@ class RepositoryTest { coEvery { api.sources() } returns SelfossModel.StatusAndData(success = true, data = sources) every { db.sourcesQueries.sources().executeAsList() } returns sourcesDB initializeRepository(MutableStateFlow(false)) - var testSources: List? = null + var testSources: List? runBlocking { testSources = repository.getSources() } @@ -1010,7 +1010,7 @@ class RepositoryTest { coEvery { api.sources() } returns SelfossModel.StatusAndData(success = true, data = sources) every { db.sourcesQueries.sources().executeAsList() } returns sourcesDB initializeRepository(MutableStateFlow(false)) - var testSources: List? = null + var testSources: List? runBlocking { testSources = repository.getSources() } @@ -1026,7 +1026,7 @@ class RepositoryTest { SelfossModel.SuccessResponse(true) initializeRepository() - var response = false + var response: Boolean runBlocking { response = repository.createSource( "test", @@ -1056,7 +1056,7 @@ class RepositoryTest { SelfossModel.SuccessResponse(false) initializeRepository() - var response = false + var response: Boolean runBlocking { response = repository.createSource( "test", @@ -1086,7 +1086,7 @@ class RepositoryTest { SelfossModel.SuccessResponse(true) initializeRepository(MutableStateFlow(false)) - var response = false + var response: Boolean runBlocking { response = repository.createSource( "test", @@ -1115,7 +1115,7 @@ class RepositoryTest { coEvery { api.deleteSource(any()) } returns SelfossModel.SuccessResponse(true) initializeRepository() - var response = false + var response: Boolean runBlocking { response = repository.deleteSource(5) } @@ -1129,7 +1129,7 @@ class RepositoryTest { coEvery { api.deleteSource(any()) } returns SelfossModel.SuccessResponse(false) initializeRepository() - var response = false + var response: Boolean runBlocking { response = repository.deleteSource(5) } @@ -1143,7 +1143,7 @@ class RepositoryTest { coEvery { api.deleteSource(any()) } returns SelfossModel.SuccessResponse(false) initializeRepository(MutableStateFlow(false)) - var response = false + var response: Boolean runBlocking { response = repository.deleteSource(5) } @@ -1160,7 +1160,7 @@ class RepositoryTest { ) initializeRepository() - var response = false + var response: Boolean runBlocking { response = repository.updateRemote() } @@ -1177,7 +1177,7 @@ class RepositoryTest { ) initializeRepository() - var response = false + var response: Boolean runBlocking { response = repository.updateRemote() } @@ -1194,7 +1194,7 @@ class RepositoryTest { ) initializeRepository() - var response = false + var response: Boolean runBlocking { response = repository.updateRemote() } @@ -1211,7 +1211,7 @@ class RepositoryTest { ) initializeRepository(MutableStateFlow(false)) - var response = false + var response: Boolean runBlocking { response = repository.updateRemote() } @@ -1225,7 +1225,7 @@ class RepositoryTest { coEvery { api.login() } returns SelfossModel.SuccessResponse(success = true) initializeRepository() - var response = false + var response: Boolean runBlocking { response = repository.login() } @@ -1239,7 +1239,7 @@ class RepositoryTest { coEvery { api.login() } returns SelfossModel.SuccessResponse(success = false) initializeRepository() - var response = false + var response: Boolean runBlocking { response = repository.login() } @@ -1253,7 +1253,7 @@ class RepositoryTest { coEvery { api.login() } returns SelfossModel.SuccessResponse(success = true) initializeRepository(MutableStateFlow(false)) - var response = false + var response: Boolean runBlocking { response = repository.login() } diff --git a/gradle.properties b/gradle.properties index 900f643..a7c8941 100644 --- a/gradle.properties +++ b/gradle.properties @@ -34,4 +34,3 @@ org.gradle.caching=true ignoreGitVersion=false kotlin.native.cacheKind.iosX64=none pushCache=true - diff --git a/shared/build.gradle.kts b/shared/build.gradle.kts index c650e50..a835343 100644 --- a/shared/build.gradle.kts +++ b/shared/build.gradle.kts @@ -58,6 +58,7 @@ kotlin { val androidMain by getting { dependencies { implementation("io.ktor:ktor-client-okhttp:2.1.1") + implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.4.0") // Sql implementation(SqlDelight.android) diff --git a/shared/src/androidMain/kotlin/bou/amine/apps/readerforselfossv2/utils/DateUtils.kt b/shared/src/androidMain/kotlin/bou/amine/apps/readerforselfossv2/utils/DateUtils.kt index 8ff8dda..a65d70c 100644 --- a/shared/src/androidMain/kotlin/bou/amine/apps/readerforselfossv2/utils/DateUtils.kt +++ b/shared/src/androidMain/kotlin/bou/amine/apps/readerforselfossv2/utils/DateUtils.kt @@ -1,49 +1,26 @@ package bou.amine.apps.readerforselfossv2.utils -import android.os.Build import android.text.format.DateUtils import bou.amine.apps.readerforselfossv2.service.AppSettingsService -import java.time.Instant -import java.time.LocalDateTime -import java.time.OffsetDateTime -import java.time.ZoneOffset -import java.time.format.DateTimeFormatter +import kotlinx.datetime.Clock +import kotlinx.datetime.Instant + actual class DateUtils actual constructor(actual val appSettingsService: AppSettingsService) { actual fun parseDate(dateString: String): Long { - - val FORMATTERV1 = "yyyy-MM-dd HH:mm:ss" - - return if (appSettingsService.getApiVersion() >= 4) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - OffsetDateTime.parse(dateString).toInstant().toEpochMilli() - } else { - TODO("VERSION.SDK_INT < O") - } - } else { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - LocalDateTime.parse(dateString, DateTimeFormatter.ofPattern(FORMATTERV1)).toInstant( - ZoneOffset.UTC).toEpochMilli() - } else { - TODO("VERSION.SDK_INT < O") - } - } + return Instant.parse(dateString).toEpochMilliseconds() } actual fun parseRelativeDate(dateString: String): String { val date = parseDate(dateString) - return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - " " + DateUtils.getRelativeTimeSpanString( - date, - Instant.now().toEpochMilli(), - DateUtils.MINUTE_IN_MILLIS, - DateUtils.FORMAT_ABBREV_RELATIVE - ) - } else { - TODO("VERSION.SDK_INT < O") - } + return " " + DateUtils.getRelativeTimeSpanString( + date, + Clock.System.now().toEpochMilliseconds(), + DateUtils.MINUTE_IN_MILLIS, + DateUtils.FORMAT_ABBREV_RELATIVE + ) } } \ No newline at end of file From 823a8c36924ff9d7152a2ceb3822de01f3fc5757 Mon Sep 17 00:00:00 2001 From: aminecmi Date: Sun, 30 Oct 2022 21:12:01 +0100 Subject: [PATCH 2/7] Date formatter --- androidApp/build.gradle.kts | 1 + androidApp/src/test/kotlin/DatesTest.kt | 38 +++++++++++++ androidApp/src/test/kotlin/RepositoryTest.kt | 54 +----------------- androidApp/src/test/kotlin/TestUtils.kt | 57 +++++++++++++++++++ .../readerforselfossv2/utils/DateUtils.kt | 10 +++- 5 files changed, 104 insertions(+), 56 deletions(-) create mode 100644 androidApp/src/test/kotlin/DatesTest.kt create mode 100644 androidApp/src/test/kotlin/TestUtils.kt diff --git a/androidApp/build.gradle.kts b/androidApp/build.gradle.kts index cfed35a..4f50057 100644 --- a/androidApp/build.gradle.kts +++ b/androidApp/build.gradle.kts @@ -194,6 +194,7 @@ dependencies { testImplementation("junit:junit:4.13.2") testImplementation("io.mockk:mockk:1.12.0") testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.0") + implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.4.0") } tasks.withType { diff --git a/androidApp/src/test/kotlin/DatesTest.kt b/androidApp/src/test/kotlin/DatesTest.kt new file mode 100644 index 0000000..cd91125 --- /dev/null +++ b/androidApp/src/test/kotlin/DatesTest.kt @@ -0,0 +1,38 @@ +package bou.amine.apps.readerforselfossv2.repository + +import bou.amine.apps.readerforselfossv2.service.AppSettingsService +import bou.amine.apps.readerforselfossv2.utils.DateUtils +import io.mockk.mockk +import junit.framework.TestCase.assertEquals +import kotlinx.datetime.LocalDateTime +import kotlinx.datetime.TimeZone +import kotlinx.datetime.toInstant +import org.junit.Test + +class DatesTest { + private val appSettingsService = mockk() + + private val dateUtils: DateUtils = DateUtils(appSettingsService) + + private val v3Date = "2013-04-07T13:43:00+01:00" + private val v4Date = "2013-04-07 13:43:00" + + @Test + fun v3_date_should_be_parsed() { + val date = dateUtils.parseDate(v3Date) + val expected = LocalDateTime(2013, 4, 7, 13, 43, 0, 0).toInstant(TimeZone.of("UTC+1")) .toEpochMilliseconds() + + assertEquals(date, expected) + } + + @Test + fun v4_date_should_be_parsed() { + val date = dateUtils.parseDate(v4Date) + val expected = + LocalDateTime(2013, 4, 7, 13, 43, 0, 0).toInstant(TimeZone.currentSystemDefault()) + .toEpochMilliseconds() + + assertEquals(date, expected) + } + +} diff --git a/androidApp/src/test/kotlin/RepositoryTest.kt b/androidApp/src/test/kotlin/RepositoryTest.kt index 32f98b9..347a0d5 100644 --- a/androidApp/src/test/kotlin/RepositoryTest.kt +++ b/androidApp/src/test/kotlin/RepositoryTest.kt @@ -1366,56 +1366,4 @@ class RepositoryTest { coVerify(exactly = 0) { api.getItems(any(), 0, null, null, null, null, 200) } } -} - -fun generateTestDBItems(item: FakeItemParameters = FakeItemParameters()): List { - return listOf( - ITEM( - id = item.id, - datetime = item.datetime, - title = item.title, - content = item.content, - unread = item.unread, - starred = item.starred, - thumbnail = item.thumbnail, - icon = item.icon, - link = item.link, - sourcetitle = item.sourcetitle, - tags = item.tags - ) - ) -} - -fun generateTestApiItem(item: FakeItemParameters = FakeItemParameters()): List { - return listOf( - SelfossModel.Item( - id = item.id.toInt(), - datetime = item.datetime, - title = item.title, - content = item.content, - unread = item.unread, - starred = item.starred, - thumbnail = item.thumbnail, - icon = item.icon, - link = item.link, - sourcetitle = item.sourcetitle, - tags = item.tags.split(',') - ) - ) -} - -class FakeItemParameters { - var id = "20" - var datetime = "2022-09-09T03:32:01-04:00" - val title = "Etica della ricerca sotto i riflettori." - val content = - "

Luigi Campanella, già Presidente SCI

\n

L’etica della scienza è di certo ambito di cui continuiamo a scoprire nuovi aspetti e risvolti.

\n

L’ultimo è quello delle intelligenze artificiali capaci di creare opere complesse basate su immagini e parole memorizzate con il rischio di fake news e di contenuti disturbanti.

\n

Per evitare che ciò accada si sta procedendo filtrando secondo criteri di autocensura i dati da cui l’intelligenza artificiale parte.

\n

Comincia ad intravedersi un futuro prossimo di competizione fra autori umani ed artificiali nel quale sarà importante, quando i loro prodotti saranno indistinguibili, dichiararne l’origine.

\n

Come si comprende, si conferma che gli aspetti etici dell’innovazione e della ricerca si diversificato sempre di più.

\n

La biologia molecolare e la genetica già in passato hanno posto all’attenzione comune aspetti di etica della scienza che hanno indotto a nuove riflessioni circa i limiti delle ricerche.

\n

L’argomento, sempre attuale, torna sulle prime pagine a seguito della pubblicazione di una ricerca della Università di Cambridge che ha sviluppato una struttura cellulare di un topo con un cuore che batte regolarmente.

\n\"\"\"\"

Magdalena Zernicka-Goetz

\n\"\"

Gianluca Amadei

\n

Del gruppo fa parte anche uno scienziato italiano Gianluca Amadei,che dinnanzi alle obiezioni di natura etica sulla realizzazione della vita artificiale si è affrettato a sostenere che non è creare nuove vite il fine primario della ricerca, ma quello di salvare quelle esistenti, di dare contributi essenziali alla medicina citando il caso del fallimento tuttora non interpretato di alcune gravidanze e di superare la sperimentazione animale, così contribuendo positivamente alla soluzione di un altro dilemma etico.

\n

L’embrione sintetico ha ovviamente come primo traguardo il contributo ai trapianti oggi drammaticamente carenti nell’offerta rispetto alla domanda, con attese fino a 4 anni per i trapianti di cuore ed a 2 anni per quelli di fegato. Il lavoro dovrebbe adesso continuare presso l’Ateneo di Padova per creare nuovi organi e nuovi farmaci.

" - var unread = true - var starred = true - val thumbnail = null - val icon = "ba79e238383ce83c23a169929c8906ef.png" - val link = - "https://ilblogdellasci.wordpress.com/2022/09/09/etica-della-ricerca-sotto-i-riflettori/" - var sourcetitle = "La Chimica e la Società" - var tags = "Chimica, Testing" -} +} \ No newline at end of file diff --git a/androidApp/src/test/kotlin/TestUtils.kt b/androidApp/src/test/kotlin/TestUtils.kt new file mode 100644 index 0000000..e568644 --- /dev/null +++ b/androidApp/src/test/kotlin/TestUtils.kt @@ -0,0 +1,57 @@ +package bou.amine.apps.readerforselfossv2.repository + +import bou.amine.apps.readerforselfossv2.dao.ITEM +import bou.amine.apps.readerforselfossv2.model.SelfossModel + + +fun generateTestDBItems(item: FakeItemParameters = FakeItemParameters()): List { + return listOf( + ITEM( + id = item.id, + datetime = item.datetime, + title = item.title, + content = item.content, + unread = item.unread, + starred = item.starred, + thumbnail = item.thumbnail, + icon = item.icon, + link = item.link, + sourcetitle = item.sourcetitle, + tags = item.tags + ) + ) +} + +fun generateTestApiItem(item: FakeItemParameters = FakeItemParameters()): List { + return listOf( + SelfossModel.Item( + id = item.id.toInt(), + datetime = item.datetime, + title = item.title, + content = item.content, + unread = item.unread, + starred = item.starred, + thumbnail = item.thumbnail, + icon = item.icon, + link = item.link, + sourcetitle = item.sourcetitle, + tags = item.tags.split(',') + ) + ) +} + +class FakeItemParameters { + var id = "20" + var datetime = "2022-09-09T03:32:01-04:00" + val title = "Etica della ricerca sotto i riflettori." + val content = + "

Luigi Campanella, già Presidente SCI

\n

L’etica della scienza è di certo ambito di cui continuiamo a scoprire nuovi aspetti e risvolti.

\n

L’ultimo è quello delle intelligenze artificiali capaci di creare opere complesse basate su immagini e parole memorizzate con il rischio di fake news e di contenuti disturbanti.

\n

Per evitare che ciò accada si sta procedendo filtrando secondo criteri di autocensura i dati da cui l’intelligenza artificiale parte.

\n

Comincia ad intravedersi un futuro prossimo di competizione fra autori umani ed artificiali nel quale sarà importante, quando i loro prodotti saranno indistinguibili, dichiararne l’origine.

\n

Come si comprende, si conferma che gli aspetti etici dell’innovazione e della ricerca si diversificato sempre di più.

\n

La biologia molecolare e la genetica già in passato hanno posto all’attenzione comune aspetti di etica della scienza che hanno indotto a nuove riflessioni circa i limiti delle ricerche.

\n

L’argomento, sempre attuale, torna sulle prime pagine a seguito della pubblicazione di una ricerca della Università di Cambridge che ha sviluppato una struttura cellulare di un topo con un cuore che batte regolarmente.

\n\"\"\"\"

Magdalena Zernicka-Goetz

\n\"\"

Gianluca Amadei

\n

Del gruppo fa parte anche uno scienziato italiano Gianluca Amadei,che dinnanzi alle obiezioni di natura etica sulla realizzazione della vita artificiale si è affrettato a sostenere che non è creare nuove vite il fine primario della ricerca, ma quello di salvare quelle esistenti, di dare contributi essenziali alla medicina citando il caso del fallimento tuttora non interpretato di alcune gravidanze e di superare la sperimentazione animale, così contribuendo positivamente alla soluzione di un altro dilemma etico.

\n

L’embrione sintetico ha ovviamente come primo traguardo il contributo ai trapianti oggi drammaticamente carenti nell’offerta rispetto alla domanda, con attese fino a 4 anni per i trapianti di cuore ed a 2 anni per quelli di fegato. Il lavoro dovrebbe adesso continuare presso l’Ateneo di Padova per creare nuovi organi e nuovi farmaci.

" + var unread = true + var starred = true + val thumbnail = null + val icon = "ba79e238383ce83c23a169929c8906ef.png" + val link = + "https://ilblogdellasci.wordpress.com/2022/09/09/etica-della-ricerca-sotto-i-riflettori/" + var sourcetitle = "La Chimica e la Società" + var tags = "Chimica, Testing" +} \ No newline at end of file diff --git a/shared/src/androidMain/kotlin/bou/amine/apps/readerforselfossv2/utils/DateUtils.kt b/shared/src/androidMain/kotlin/bou/amine/apps/readerforselfossv2/utils/DateUtils.kt index a65d70c..ce3121a 100644 --- a/shared/src/androidMain/kotlin/bou/amine/apps/readerforselfossv2/utils/DateUtils.kt +++ b/shared/src/androidMain/kotlin/bou/amine/apps/readerforselfossv2/utils/DateUtils.kt @@ -2,14 +2,18 @@ package bou.amine.apps.readerforselfossv2.utils import android.text.format.DateUtils import bou.amine.apps.readerforselfossv2.service.AppSettingsService -import kotlinx.datetime.Clock -import kotlinx.datetime.Instant +import kotlinx.datetime.* +import java.time.format.DateTimeFormatter actual class DateUtils actual constructor(actual val appSettingsService: AppSettingsService) { actual fun parseDate(dateString: String): Long { - return Instant.parse(dateString).toEpochMilliseconds() + return try { + Instant.parse(dateString).toEpochMilliseconds() + } catch (e: Exception) { + LocalDateTime.parse(dateString.replace(" ", "T")).toInstant(TimeZone.currentSystemDefault()).toEpochMilliseconds() + } } actual fun parseRelativeDate(dateString: String): String { From 7b40a31979f468f667d0f8f76a2a044e7ca8bd2d Mon Sep 17 00:00:00 2001 From: aminecmi Date: Sun, 30 Oct 2022 21:21:43 +0100 Subject: [PATCH 3/7] Cleaning. --- androidApp/src/test/kotlin/DatesTest.kt | 4 +--- androidApp/src/test/kotlin/RepositoryTest.kt | 1 - .../bou/amine/apps/readerforselfossv2/utils/DateUtils.kt | 4 +--- .../apps/readerforselfossv2/repository/RepositoryImpl.kt | 4 +--- .../bou/amine/apps/readerforselfossv2/utils/DateUtils.kt | 4 +--- 5 files changed, 4 insertions(+), 13 deletions(-) diff --git a/androidApp/src/test/kotlin/DatesTest.kt b/androidApp/src/test/kotlin/DatesTest.kt index cd91125..67d88d3 100644 --- a/androidApp/src/test/kotlin/DatesTest.kt +++ b/androidApp/src/test/kotlin/DatesTest.kt @@ -10,9 +10,7 @@ import kotlinx.datetime.toInstant import org.junit.Test class DatesTest { - private val appSettingsService = mockk() - - private val dateUtils: DateUtils = DateUtils(appSettingsService) + private val dateUtils: DateUtils = DateUtils() private val v3Date = "2013-04-07T13:43:00+01:00" private val v4Date = "2013-04-07 13:43:00" diff --git a/androidApp/src/test/kotlin/RepositoryTest.kt b/androidApp/src/test/kotlin/RepositoryTest.kt index 347a0d5..803c5a2 100644 --- a/androidApp/src/test/kotlin/RepositoryTest.kt +++ b/androidApp/src/test/kotlin/RepositoryTest.kt @@ -1,6 +1,5 @@ package bou.amine.apps.readerforselfossv2.repository -import bou.amine.apps.readerforselfossv2.dao.ITEM import bou.amine.apps.readerforselfossv2.dao.ReaderForSelfossDB import bou.amine.apps.readerforselfossv2.dao.SOURCE import bou.amine.apps.readerforselfossv2.dao.TAG diff --git a/shared/src/androidMain/kotlin/bou/amine/apps/readerforselfossv2/utils/DateUtils.kt b/shared/src/androidMain/kotlin/bou/amine/apps/readerforselfossv2/utils/DateUtils.kt index ce3121a..ef09558 100644 --- a/shared/src/androidMain/kotlin/bou/amine/apps/readerforselfossv2/utils/DateUtils.kt +++ b/shared/src/androidMain/kotlin/bou/amine/apps/readerforselfossv2/utils/DateUtils.kt @@ -1,12 +1,10 @@ package bou.amine.apps.readerforselfossv2.utils import android.text.format.DateUtils -import bou.amine.apps.readerforselfossv2.service.AppSettingsService import kotlinx.datetime.* -import java.time.format.DateTimeFormatter -actual class DateUtils actual constructor(actual val appSettingsService: AppSettingsService) { +actual class DateUtils { actual fun parseDate(dateString: String): Long { return try { diff --git a/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/repository/RepositoryImpl.kt b/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/repository/RepositoryImpl.kt index cf25229..bf48211 100644 --- a/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/repository/RepositoryImpl.kt +++ b/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/repository/RepositoryImpl.kt @@ -11,7 +11,6 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.launch -import kotlinx.coroutines.runBlocking class Repository(private val api: SelfossApi, private val appSettingsService: AppSettingsService, val isConnectionAvailable: MutableStateFlow, private val db: ReaderForSelfossDB) { @@ -19,7 +18,7 @@ class Repository(private val api: SelfossApi, private val appSettingsService: Ap var connectionMonitored = false var baseUrl = appSettingsService.getBaseUrl() - lateinit var dateUtils: DateUtils + var dateUtils: DateUtils = DateUtils() var displayedItems = ItemType.UNREAD @@ -394,7 +393,6 @@ class Repository(private val api: SelfossApi, private val appSettingsService: Ap appSettingsService.updateApiVersion(fetchedVersion.data.getApiMajorVersion()) } } - dateUtils = DateUtils(appSettingsService) } fun isNetworkAvailable() = isConnectionAvailable.value && !offlineOverride diff --git a/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/utils/DateUtils.kt b/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/utils/DateUtils.kt index d235b97..9856726 100644 --- a/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/utils/DateUtils.kt +++ b/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/utils/DateUtils.kt @@ -7,9 +7,7 @@ import bou.amine.apps.readerforselfossv2.service.AppSettingsService fun SelfossModel.Item.parseDate(dateUtils: DateUtils): Long = dateUtils.parseDate(this.datetime) -expect class DateUtils constructor(appSettingsService: AppSettingsService) { - val appSettingsService: AppSettingsService // This is needed because of https://stackoverflow.com/a/65249085 - +expect class DateUtils() { fun parseDate(dateString: String): Long fun parseRelativeDate(dateString: String): String From b0d1d9c29acf8a715ec6fa49ea5ab5012a50f8ee Mon Sep 17 00:00:00 2001 From: aminecmi Date: Sun, 30 Oct 2022 21:27:53 +0100 Subject: [PATCH 4/7] No daemon --- .drone.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.drone.yml b/.drone.yml index 6060363..b49d4d5 100644 --- a/.drone.yml +++ b/.drone.yml @@ -8,14 +8,14 @@ steps: commands: - echo "---------------------------------------------------------" - echo "Analysing..." - - ./gradlew sonarqube -Dsonar.projectKey=RFS2 -Dsonar.host.url=$SONAR_HOST_URL -Dsonar.login=$SONAR_LOGIN -PignoreGitVersion=true -P appLoginUrl="\"URL\"" -P appLoginUsername="\"LOGIN\"" -P appLoginPassword="\"PASS\"" + - ./gradlew sonarqube --no-daemon -Dsonar.projectKey=RFS2 -Dsonar.host.url=$SONAR_HOST_URL -Dsonar.login=$SONAR_LOGIN -PignoreGitVersion=true -P appLoginUrl="\"URL\"" -P appLoginUsername="\"LOGIN\"" -P appLoginPassword="\"PASS\"" - echo "---------------------------------------------------------" - echo "Building..." - - ./gradlew build -PignoreGitVersion=true -P appLoginUrl="\"URL\"" -P appLoginUsername="\"LOGIN\"" -P appLoginPassword="\"PASS\"" -P pushCache=false + - ./gradlew build --no-daemon -PignoreGitVersion=true -P appLoginUrl="\"URL\"" -P appLoginUsername="\"LOGIN\"" -P appLoginPassword="\"PASS\"" -P pushCache=false - echo "---------------------------------------------------------" - echo "Testing..." - echo "---------------------------------------------------------" - - ./gradlew test -PignoreGitVersion=true -P appLoginUrl="\"URL\"" -P appLoginUsername="\"LOGIN\"" -P appLoginPassword="\"PASS\"" -P pushCache=false + - ./gradlew test --no-daemon -PignoreGitVersion=true -P appLoginUrl="\"URL\"" -P appLoginUsername="\"LOGIN\"" -P appLoginPassword="\"PASS\"" -P pushCache=false environment: SONAR_HOST_URL: from_secret: sonarScannerHostUrl @@ -86,7 +86,7 @@ steps: image: mingc/android-build-box:latest commands: - echo "Generate APK" - - ./gradlew :androidApp:assembleGithubConfigRelease -PignoreGitVersion=true -P appLoginUrl="\"URL\"" -P appLoginUsername="\"LOGIN\"" -P appLoginPassword="\"PASS\"" -P pushCache=false + - ./gradlew :androidApp:assembleGithubConfigRelease --no-daemon -PignoreGitVersion=true -P appLoginUrl="\"URL\"" -P appLoginUsername="\"LOGIN\"" -P appLoginPassword="\"PASS\"" -P pushCache=false - echo "---------------------------------------------------------" - echo "Get Key" - wget https://amine-louveau.fr/key From d862bfba4f8a5a432ef07143b8dc8db98f6bbbf4 Mon Sep 17 00:00:00 2001 From: aminecmi Date: Sun, 30 Oct 2022 21:38:04 +0100 Subject: [PATCH 5/7] Still cleaning. --- .drone.yml | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/.drone.yml b/.drone.yml index b49d4d5..f127db4 100644 --- a/.drone.yml +++ b/.drone.yml @@ -6,16 +6,19 @@ steps: - name: AnylyseBuildTest image: mingc/android-build-box:latest commands: + - echo "---------------------------------------------------------" + - echo "Configure gradle..." + - mkdir -p ~/.gradle && echo "org.gradle.daemon=false\nignoreGitVersion=true\nappLoginUrl=\"URL\"\nappLoginUsername=\"LOGIN\"\nappLoginPassword=\"PASS\"\npushCache=false" >> ~/.gradle/gradle.properties - echo "---------------------------------------------------------" - echo "Analysing..." - - ./gradlew sonarqube --no-daemon -Dsonar.projectKey=RFS2 -Dsonar.host.url=$SONAR_HOST_URL -Dsonar.login=$SONAR_LOGIN -PignoreGitVersion=true -P appLoginUrl="\"URL\"" -P appLoginUsername="\"LOGIN\"" -P appLoginPassword="\"PASS\"" + - ./gradlew sonarqube -Dsonar.projectKey=RFS2 -Dsonar.host.url=$SONAR_HOST_URL -Dsonar.login=$SONAR_LOGIN - echo "---------------------------------------------------------" - echo "Building..." - - ./gradlew build --no-daemon -PignoreGitVersion=true -P appLoginUrl="\"URL\"" -P appLoginUsername="\"LOGIN\"" -P appLoginPassword="\"PASS\"" -P pushCache=false + - ./gradlew build - echo "---------------------------------------------------------" - echo "Testing..." - echo "---------------------------------------------------------" - - ./gradlew test --no-daemon -PignoreGitVersion=true -P appLoginUrl="\"URL\"" -P appLoginUsername="\"LOGIN\"" -P appLoginPassword="\"PASS\"" -P pushCache=false + - ./gradlew test environment: SONAR_HOST_URL: from_secret: sonarScannerHostUrl @@ -85,8 +88,12 @@ steps: - name: build image: mingc/android-build-box:latest commands: + - echo "---------------------------------------------------------" + - echo "Configure gradle..." + - mkdir -p ~/.gradle && echo "org.gradle.daemon=false\nignoreGitVersion=true\nappLoginUrl=\"URL\"\nappLoginUsername=\"LOGIN\"\nappLoginPassword=\"PASS\"\npushCache=false" >> ~/.gradle/gradle.properties + - echo "---------------------------------------------------------" - echo "Generate APK" - - ./gradlew :androidApp:assembleGithubConfigRelease --no-daemon -PignoreGitVersion=true -P appLoginUrl="\"URL\"" -P appLoginUsername="\"LOGIN\"" -P appLoginPassword="\"PASS\"" -P pushCache=false + - ./gradlew :androidApp:assembleGithubConfigRelease -P pushCache=false - echo "---------------------------------------------------------" - echo "Get Key" - wget https://amine-louveau.fr/key From 94a07479479beafdba114f87f8832a2b88ac8678 Mon Sep 17 00:00:00 2001 From: aminecmi Date: Sun, 30 Oct 2022 22:02:07 +0100 Subject: [PATCH 6/7] More cleaning. --- androidApp/build.gradle.kts | 2 +- build.gradle.kts | 2 +- shared/build.gradle.kts | 6 +++--- .../bou/amine/apps/readerforselfossv2/utils/DateUtils.kt | 4 +--- .../bou/amine/apps/readerforselfossv2/utils/DateUtils.kt | 2 +- 5 files changed, 7 insertions(+), 9 deletions(-) diff --git a/androidApp/build.gradle.kts b/androidApp/build.gradle.kts index 4f50057..dee5f0e 100644 --- a/androidApp/build.gradle.kts +++ b/androidApp/build.gradle.kts @@ -188,7 +188,7 @@ dependencies { implementation("com.github.ln-12:multiplatform-connectivity-status:1.3.0") // SQLDELIGHT - implementation("com.squareup.sqldelight:android-driver:1.5.3") + implementation("com.squareup.sqldelight:android-driver:1.5.4") //test testImplementation("junit:junit:4.13.2") diff --git a/build.gradle.kts b/build.gradle.kts index 49edef4..42ac4ce 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,7 +1,7 @@ buildscript { dependencies { // SqlDelight - classpath("com.squareup.sqldelight:gradle-plugin:1.5.3") + classpath("com.squareup.sqldelight:gradle-plugin:1.5.4") } } diff --git a/shared/build.gradle.kts b/shared/build.gradle.kts index a835343..c02b27b 100644 --- a/shared/build.gradle.kts +++ b/shared/build.gradle.kts @@ -1,7 +1,7 @@ object SqlDelight { - const val runtime = "com.squareup.sqldelight:runtime:1.5.3" - const val android = "com.squareup.sqldelight:android-driver:1.5.3" - const val native = "com.squareup.sqldelight:native-driver:1.5.3" + const val runtime = "com.squareup.sqldelight:runtime:1.5.4" + const val android = "com.squareup.sqldelight:android-driver:1.5.4" + const val native = "com.squareup.sqldelight:native-driver:1.5.4" } diff --git a/shared/src/iosArm64Main/kotlin/bou/amine/apps/readerforselfossv2/utils/DateUtils.kt b/shared/src/iosArm64Main/kotlin/bou/amine/apps/readerforselfossv2/utils/DateUtils.kt index b55ec14..8ee7f57 100644 --- a/shared/src/iosArm64Main/kotlin/bou/amine/apps/readerforselfossv2/utils/DateUtils.kt +++ b/shared/src/iosArm64Main/kotlin/bou/amine/apps/readerforselfossv2/utils/DateUtils.kt @@ -1,8 +1,6 @@ package bou.amine.apps.readerforselfossv2.utils -import bou.amine.apps.readerforselfossv2.service.AppSettingsService - -actual class DateUtils actual constructor(actual val appSettingsService: AppSettingsService) { +actual class DateUtils { actual fun parseDate(dateString: String): Long { TODO("Not yet implemented") } diff --git a/shared/src/iosX64Main/kotlin/bou/amine/apps/readerforselfossv2/utils/DateUtils.kt b/shared/src/iosX64Main/kotlin/bou/amine/apps/readerforselfossv2/utils/DateUtils.kt index b55ec14..76ef202 100644 --- a/shared/src/iosX64Main/kotlin/bou/amine/apps/readerforselfossv2/utils/DateUtils.kt +++ b/shared/src/iosX64Main/kotlin/bou/amine/apps/readerforselfossv2/utils/DateUtils.kt @@ -2,7 +2,7 @@ package bou.amine.apps.readerforselfossv2.utils import bou.amine.apps.readerforselfossv2.service.AppSettingsService -actual class DateUtils actual constructor(actual val appSettingsService: AppSettingsService) { +actual class DateUtils { actual fun parseDate(dateString: String): Long { TODO("Not yet implemented") } From 27c55e59a1d5b294322436e50176c9138ed54279 Mon Sep 17 00:00:00 2001 From: aminecmi Date: Mon, 31 Oct 2022 21:28:11 +0100 Subject: [PATCH 7/7] Cleaning still. --- .../android/adapters/ItemCardAdapter.kt | 7 ++-- .../android/adapters/ItemListAdapter.kt | 2 +- .../android/fragments/ArticleFragment.kt | 2 +- androidApp/src/test/kotlin/DatesTest.kt | 7 ++-- .../readerforselfossv2/utils/DateUtils.kt | 35 ++++++++++--------- .../readerforselfossv2/model/SelfossModel.kt | 4 +-- .../repository/RepositoryImpl.kt | 3 +- .../service/SearchService.kt | 27 -------------- .../readerforselfossv2/utils/DateUtils.kt | 13 +++---- .../readerforselfossv2/utils/DateUtils.kt | 13 +++---- .../readerforselfossv2/utils/DateUtils.kt | 12 ++++--- 11 files changed, 48 insertions(+), 77 deletions(-) delete mode 100644 shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/service/SearchService.kt diff --git a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/ItemCardAdapter.kt b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/ItemCardAdapter.kt index fa26bf4..cb2dcae 100644 --- a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/ItemCardAdapter.kt +++ b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/ItemCardAdapter.kt @@ -10,9 +10,12 @@ import androidx.recyclerview.widget.RecyclerView import bou.amine.apps.readerforselfossv2.android.R import bou.amine.apps.readerforselfossv2.android.databinding.CardItemBinding import bou.amine.apps.readerforselfossv2.android.model.toTextDrawableString -import bou.amine.apps.readerforselfossv2.android.utils.* +import bou.amine.apps.readerforselfossv2.android.utils.LinkOnTouchListener import bou.amine.apps.readerforselfossv2.android.utils.glide.bitmapCenterCrop import bou.amine.apps.readerforselfossv2.android.utils.glide.circularBitmapDrawable +import bou.amine.apps.readerforselfossv2.android.utils.openInBrowserAsNewTask +import bou.amine.apps.readerforselfossv2.android.utils.openItemUrl +import bou.amine.apps.readerforselfossv2.android.utils.shareLink import bou.amine.apps.readerforselfossv2.model.SelfossModel import bou.amine.apps.readerforselfossv2.repository.Repository import bou.amine.apps.readerforselfossv2.service.AppSettingsService @@ -59,7 +62,7 @@ class ItemCardAdapter( binding.title.setLinkTextColor(c.resources.getColor(R.color.colorAccent)) - binding.sourceTitleAndDate.text = itm.sourceAndDateText(repository.dateUtils) + binding.sourceTitleAndDate.text = itm.sourceAndDateText() if (!appSettingsService.isFullHeightCardsEnabled()) { binding.itemImage.maxHeight = imageMaxHeight diff --git a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/ItemListAdapter.kt b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/ItemListAdapter.kt index de6e91e..116c1e5 100644 --- a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/ItemListAdapter.kt +++ b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/ItemListAdapter.kt @@ -51,7 +51,7 @@ class ItemListAdapter( binding.title.setLinkTextColor(c.resources.getColor(R.color.colorAccent)) - binding.sourceTitleAndDate.text = itm.sourceAndDateText(repository.dateUtils) + binding.sourceTitleAndDate.text = itm.sourceAndDateText() if (itm.getThumbnail(repository.baseUrl).isEmpty()) { diff --git a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/fragments/ArticleFragment.kt b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/fragments/ArticleFragment.kt index cebefc9..5773335 100644 --- a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/fragments/ArticleFragment.kt +++ b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/fragments/ArticleFragment.kt @@ -101,7 +101,7 @@ class ArticleFragment : Fragment(), DIAware { contentText = item.content contentTitle = item.title.getHtmlDecoded() contentImage = item.getThumbnail(repository.baseUrl) - contentSource = item.sourceAndDateText(repository.dateUtils) + contentSource = item.sourceAndDateText() allImages = item.getImages() fontSize = appSettingsService.getFontSize() diff --git a/androidApp/src/test/kotlin/DatesTest.kt b/androidApp/src/test/kotlin/DatesTest.kt index 67d88d3..ad29ec7 100644 --- a/androidApp/src/test/kotlin/DatesTest.kt +++ b/androidApp/src/test/kotlin/DatesTest.kt @@ -1,8 +1,6 @@ package bou.amine.apps.readerforselfossv2.repository -import bou.amine.apps.readerforselfossv2.service.AppSettingsService import bou.amine.apps.readerforselfossv2.utils.DateUtils -import io.mockk.mockk import junit.framework.TestCase.assertEquals import kotlinx.datetime.LocalDateTime import kotlinx.datetime.TimeZone @@ -10,14 +8,13 @@ import kotlinx.datetime.toInstant import org.junit.Test class DatesTest { - private val dateUtils: DateUtils = DateUtils() private val v3Date = "2013-04-07T13:43:00+01:00" private val v4Date = "2013-04-07 13:43:00" @Test fun v3_date_should_be_parsed() { - val date = dateUtils.parseDate(v3Date) + val date = DateUtils.parseDate(v3Date) val expected = LocalDateTime(2013, 4, 7, 13, 43, 0, 0).toInstant(TimeZone.of("UTC+1")) .toEpochMilliseconds() assertEquals(date, expected) @@ -25,7 +22,7 @@ class DatesTest { @Test fun v4_date_should_be_parsed() { - val date = dateUtils.parseDate(v4Date) + val date = DateUtils.parseDate(v4Date) val expected = LocalDateTime(2013, 4, 7, 13, 43, 0, 0).toInstant(TimeZone.currentSystemDefault()) .toEpochMilliseconds() diff --git a/shared/src/androidMain/kotlin/bou/amine/apps/readerforselfossv2/utils/DateUtils.kt b/shared/src/androidMain/kotlin/bou/amine/apps/readerforselfossv2/utils/DateUtils.kt index ef09558..3cde9e2 100644 --- a/shared/src/androidMain/kotlin/bou/amine/apps/readerforselfossv2/utils/DateUtils.kt +++ b/shared/src/androidMain/kotlin/bou/amine/apps/readerforselfossv2/utils/DateUtils.kt @@ -5,24 +5,25 @@ import kotlinx.datetime.* actual class DateUtils { + actual companion object { + actual fun parseDate(dateString: String): Long { + return try { + Instant.parse(dateString).toEpochMilliseconds() + } catch (e: Exception) { + LocalDateTime.parse(dateString.replace(" ", "T")).toInstant(TimeZone.currentSystemDefault()).toEpochMilliseconds() + } + } - actual fun parseDate(dateString: String): Long { - return try { - Instant.parse(dateString).toEpochMilliseconds() - } catch (e: Exception) { - LocalDateTime.parse(dateString.replace(" ", "T")).toInstant(TimeZone.currentSystemDefault()).toEpochMilliseconds() + actual fun parseRelativeDate(dateString: String): String { + + val date = parseDate(dateString) + + return " " + DateUtils.getRelativeTimeSpanString( + date, + Clock.System.now().toEpochMilliseconds(), + DateUtils.MINUTE_IN_MILLIS, + DateUtils.FORMAT_ABBREV_RELATIVE + ) } } - - actual fun parseRelativeDate(dateString: String): String { - - val date = parseDate(dateString) - - return " " + DateUtils.getRelativeTimeSpanString( - date, - Clock.System.now().toEpochMilliseconds(), - DateUtils.MINUTE_IN_MILLIS, - DateUtils.FORMAT_ABBREV_RELATIVE - ) - } } \ No newline at end of file diff --git a/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/model/SelfossModel.kt b/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/model/SelfossModel.kt index e30d260..591ccdb 100644 --- a/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/model/SelfossModel.kt +++ b/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/model/SelfossModel.kt @@ -108,8 +108,8 @@ class SelfossModel { return stringUrl } - fun sourceAndDateText(dateUtils: DateUtils): String = - this.sourcetitle.getHtmlDecoded() + dateUtils.parseRelativeDate(this.datetime) + fun sourceAndDateText(): String = + this.sourcetitle.getHtmlDecoded() + DateUtils.parseRelativeDate(this.datetime) fun toggleStar(): Item { this.starred = !this.starred diff --git a/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/repository/RepositoryImpl.kt b/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/repository/RepositoryImpl.kt index bf48211..9b3b1ff 100644 --- a/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/repository/RepositoryImpl.kt +++ b/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/repository/RepositoryImpl.kt @@ -18,7 +18,6 @@ class Repository(private val api: SelfossApi, private val appSettingsService: Ap var connectionMonitored = false var baseUrl = appSettingsService.getBaseUrl() - var dateUtils: DateUtils = DateUtils() var displayedItems = ItemType.UNREAD @@ -74,7 +73,7 @@ class Repository(private val api: SelfossApi, private val appSettingsService: Ap if (fetchedItems.success && fetchedItems.data != null) { items = ArrayList(fetchedItems.data!!) if (fromDB) { - items.sortByDescending { dateUtils.parseDate(it.datetime) } + items.sortByDescending { DateUtils.parseDate(it.datetime) } } } return items diff --git a/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/service/SearchService.kt b/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/service/SearchService.kt deleted file mode 100644 index 0530104..0000000 --- a/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/service/SearchService.kt +++ /dev/null @@ -1,27 +0,0 @@ -package bou.amine.apps.readerforselfossv2.service - -import bou.amine.apps.readerforselfossv2.utils.DateUtils - -class SearchService(val dateUtils: DateUtils) { - var displayedItems: String = "unread" - set(value) { - field = when (value) { - "all" -> "all" - "unread" -> "unread" - "read" -> "read" - "starred" -> "starred" - else -> "all" - } - } - - var position = 0 - var searchFilter: String? = null - var sourceIDFilter: Long? = null - var sourceFilter: String? = null - var tagFilter: String? = null - var itemsCaching = false - - var badgeUnread = -1 - var badgeAll = -1 - var badgeStarred = -1 -} \ No newline at end of file diff --git a/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/utils/DateUtils.kt b/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/utils/DateUtils.kt index 9856726..0645a66 100644 --- a/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/utils/DateUtils.kt +++ b/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/utils/DateUtils.kt @@ -1,14 +1,9 @@ package bou.amine.apps.readerforselfossv2.utils -import bou.amine.apps.readerforselfossv2.model.SelfossModel -import bou.amine.apps.readerforselfossv2.service.AppSettingsService - - -fun SelfossModel.Item.parseDate(dateUtils: DateUtils): Long = - dateUtils.parseDate(this.datetime) - expect class DateUtils() { - fun parseDate(dateString: String): Long + companion object { + fun parseDate(dateString: String): Long - fun parseRelativeDate(dateString: String): String + fun parseRelativeDate(dateString: String): String + } } diff --git a/shared/src/iosArm64Main/kotlin/bou/amine/apps/readerforselfossv2/utils/DateUtils.kt b/shared/src/iosArm64Main/kotlin/bou/amine/apps/readerforselfossv2/utils/DateUtils.kt index 8ee7f57..f611167 100644 --- a/shared/src/iosArm64Main/kotlin/bou/amine/apps/readerforselfossv2/utils/DateUtils.kt +++ b/shared/src/iosArm64Main/kotlin/bou/amine/apps/readerforselfossv2/utils/DateUtils.kt @@ -1,12 +1,13 @@ package bou.amine.apps.readerforselfossv2.utils actual class DateUtils { - actual fun parseDate(dateString: String): Long { - TODO("Not yet implemented") - } + actual companion object { + actual fun parseDate(dateString: String): Long { + TODO("Not yet implemented") + } - actual fun parseRelativeDate(dateString: String): String { - TODO("Not yet implemented") + actual fun parseRelativeDate(dateString: String): String { + TODO("Not yet implemented") + } } - } \ No newline at end of file diff --git a/shared/src/iosX64Main/kotlin/bou/amine/apps/readerforselfossv2/utils/DateUtils.kt b/shared/src/iosX64Main/kotlin/bou/amine/apps/readerforselfossv2/utils/DateUtils.kt index 76ef202..df6a812 100644 --- a/shared/src/iosX64Main/kotlin/bou/amine/apps/readerforselfossv2/utils/DateUtils.kt +++ b/shared/src/iosX64Main/kotlin/bou/amine/apps/readerforselfossv2/utils/DateUtils.kt @@ -3,12 +3,14 @@ package bou.amine.apps.readerforselfossv2.utils import bou.amine.apps.readerforselfossv2.service.AppSettingsService actual class DateUtils { - actual fun parseDate(dateString: String): Long { - TODO("Not yet implemented") - } + actual companion object { + actual fun parseDate(dateString: String): Long { + TODO("Not yet implemented") + } - actual fun parseRelativeDate(dateString: String): String { - TODO("Not yet implemented") + actual fun parseRelativeDate(dateString: String): String { + TODO("Not yet implemented") + } } } \ No newline at end of file