Compare commits
11 Commits
4482234e1a
...
0aac2cba0b
Author | SHA1 | Date | |
---|---|---|---|
0aac2cba0b | |||
42e1c1ebbd | |||
a67a2a0927 | |||
24beee070c | |||
1e6bc57751 | |||
85d966f54b | |||
3fff8eeeb6 | |||
5eb5a5658f | |||
3646658cb1 | |||
b793301706 | |||
313042955c |
@ -8,7 +8,7 @@ plugins {
|
|||||||
kotlin("android")
|
kotlin("android")
|
||||||
kotlin("kapt")
|
kotlin("kapt")
|
||||||
id("com.mikepenz.aboutlibraries.plugin")
|
id("com.mikepenz.aboutlibraries.plugin")
|
||||||
id("org.jetbrains.kotlinx.kover") version "0.6.1"
|
id("org.jetbrains.kotlinx.kover")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Project.execWithOutput(cmd: String, ignore: Boolean = false): String {
|
fun Project.execWithOutput(cmd: String, ignore: Boolean = false): String {
|
||||||
@ -16,7 +16,7 @@ fun Project.execWithOutput(cmd: String, ignore: Boolean = false): String {
|
|||||||
project.exec {
|
project.exec {
|
||||||
commandLine = cmd.split(" ")
|
commandLine = cmd.split(" ")
|
||||||
standardOutput = outputStream
|
standardOutput = outputStream
|
||||||
isIgnoreExitValue = ignore ?: false
|
isIgnoreExitValue = ignore
|
||||||
}
|
}
|
||||||
outputStream.toString()
|
outputStream.toString()
|
||||||
}
|
}
|
||||||
@ -24,9 +24,8 @@ fun Project.execWithOutput(cmd: String, ignore: Boolean = false): String {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun gitVersion(): String {
|
fun gitVersion(): String {
|
||||||
var process = ""
|
|
||||||
val maybeTagOfCurrentCommit = execWithOutput("git -C ../ describe --contains HEAD", true)
|
val maybeTagOfCurrentCommit = execWithOutput("git -C ../ describe --contains HEAD", true)
|
||||||
process = if (maybeTagOfCurrentCommit.isEmpty()) {
|
var process = if (maybeTagOfCurrentCommit.isEmpty()) {
|
||||||
println("No tag on current commit. Will take the latest one.")
|
println("No tag on current commit. Will take the latest one.")
|
||||||
execWithOutput("git -C ../ for-each-ref refs/tags --sort=-refname --format='%(refname:short)' --count=1")
|
execWithOutput("git -C ../ for-each-ref refs/tags --sort=-refname --format='%(refname:short)' --count=1")
|
||||||
} else {
|
} else {
|
||||||
@ -171,7 +170,7 @@ dependencies {
|
|||||||
//PhotoView
|
//PhotoView
|
||||||
implementation("com.github.chrisbanes:PhotoView:2.3.0")
|
implementation("com.github.chrisbanes:PhotoView:2.3.0")
|
||||||
|
|
||||||
implementation("androidx.core:core-ktx:1.8.0")
|
implementation("androidx.core:core-ktx:1.10.1")
|
||||||
|
|
||||||
implementation("androidx.lifecycle:lifecycle-extensions:2.2.0")
|
implementation("androidx.lifecycle:lifecycle-extensions:2.2.0")
|
||||||
|
|
||||||
|
1
androidApp/proguard-rules.pro
vendored
1
androidApp/proguard-rules.pro
vendored
@ -55,6 +55,7 @@
|
|||||||
# maybe remove later ?
|
# maybe remove later ?
|
||||||
-keep class * extends androidx.fragment.app.Fragment
|
-keep class * extends androidx.fragment.app.Fragment
|
||||||
|
|
||||||
|
-dontwarn org.slf4j.impl.StaticLoggerBinder
|
||||||
|
|
||||||
# Keep `Companion` object fields of serializable classes.
|
# Keep `Companion` object fields of serializable classes.
|
||||||
# This avoids serializer lookup through `getDeclaredClasses` as done for named companion objects.
|
# This avoids serializer lookup through `getDeclaredClasses` as done for named companion objects.
|
||||||
|
@ -139,9 +139,12 @@ class LoginActivity : AppCompatActivity(), DIAware {
|
|||||||
|
|
||||||
showProgress(true)
|
showProgress(true)
|
||||||
|
|
||||||
|
appSettingsService.updateSelfSigned(binding.selfSigned.isChecked)
|
||||||
|
|
||||||
repository.refreshLoginInformation(url, login, password)
|
repository.refreshLoginInformation(url, login, password)
|
||||||
|
|
||||||
CoroutineScope(Dispatchers.Main).launch {
|
CoroutineScope(Dispatchers.Main).launch {
|
||||||
|
repository.updateApiInformation()
|
||||||
val result = repository.login()
|
val result = repository.login()
|
||||||
if (result) {
|
if (result) {
|
||||||
val (errorFetching, displaySelfossOnly) = repository.shouldBeSelfossInstance()
|
val (errorFetching, displaySelfossOnly) = repository.shouldBeSelfossInstance()
|
||||||
|
@ -82,7 +82,7 @@ class FilterSheetFragment : BottomSheetDialogFragment(), DIAware {
|
|||||||
) {
|
) {
|
||||||
val sourceGroup = binding.sourcesGroup
|
val sourceGroup = binding.sourcesGroup
|
||||||
|
|
||||||
repository.getSourcesDetailsOrStats().forEach { source ->
|
repository.getSourcesDetailsOrStats().forEachIndexed { _, source ->
|
||||||
val c = Chip(context)
|
val c = Chip(context)
|
||||||
c.ellipsize = TextUtils.TruncateAt.END
|
c.ellipsize = TextUtils.TruncateAt.END
|
||||||
|
|
||||||
@ -144,7 +144,7 @@ class FilterSheetFragment : BottomSheetDialogFragment(), DIAware {
|
|||||||
|
|
||||||
val tags = repository.getTags()
|
val tags = repository.getTags()
|
||||||
|
|
||||||
tags.forEach { tag ->
|
tags.forEachIndexed { _, tag ->
|
||||||
val c = Chip(context)
|
val c = Chip(context)
|
||||||
c.ellipsize = TextUtils.TruncateAt.END
|
c.ellipsize = TextUtils.TruncateAt.END
|
||||||
c.text = tag.tag
|
c.text = tag.tag
|
||||||
|
@ -55,7 +55,7 @@
|
|||||||
android:id="@+id/selfSigned"
|
android:id="@+id/selfSigned"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/disableSSL"
|
android:text="@string/disable_ssl"
|
||||||
android:textAlignment="viewStart" />
|
android:textAlignment="viewStart" />
|
||||||
|
|
||||||
<com.google.android.material.switchmaterial.SwitchMaterial
|
<com.google.android.material.switchmaterial.SwitchMaterial
|
||||||
|
@ -130,4 +130,5 @@
|
|||||||
<string name="update_source">Update source</string>
|
<string name="update_source">Update source</string>
|
||||||
<string name="confirm_disconnect_title">Disconnect ?</string>
|
<string name="confirm_disconnect_title">Disconnect ?</string>
|
||||||
<string name="confirm_disconnect_description">You will be disconnected from your selfoss instance.</string>
|
<string name="confirm_disconnect_description">You will be disconnected from your selfoss instance.</string>
|
||||||
|
<string name="disable_ssl">Disable SSL</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -130,4 +130,5 @@
|
|||||||
<string name="update_source">Update source</string>
|
<string name="update_source">Update source</string>
|
||||||
<string name="confirm_disconnect_title">Disconnect ?</string>
|
<string name="confirm_disconnect_title">Disconnect ?</string>
|
||||||
<string name="confirm_disconnect_description">You will be disconnected from your selfoss instance.</string>
|
<string name="confirm_disconnect_description">You will be disconnected from your selfoss instance.</string>
|
||||||
|
<string name="disable_ssl">Disable SSL</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -130,4 +130,5 @@
|
|||||||
<string name="update_source">Update source</string>
|
<string name="update_source">Update source</string>
|
||||||
<string name="confirm_disconnect_title">Disconnect ?</string>
|
<string name="confirm_disconnect_title">Disconnect ?</string>
|
||||||
<string name="confirm_disconnect_description">You will be disconnected from your selfoss instance.</string>
|
<string name="confirm_disconnect_description">You will be disconnected from your selfoss instance.</string>
|
||||||
|
<string name="disable_ssl">Disable SSL</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -130,4 +130,5 @@
|
|||||||
<string name="update_source">Update source</string>
|
<string name="update_source">Update source</string>
|
||||||
<string name="confirm_disconnect_title">Disconnect ?</string>
|
<string name="confirm_disconnect_title">Disconnect ?</string>
|
||||||
<string name="confirm_disconnect_description">You will be disconnected from your selfoss instance.</string>
|
<string name="confirm_disconnect_description">You will be disconnected from your selfoss instance.</string>
|
||||||
|
<string name="disable_ssl">Disable SSL</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -130,4 +130,5 @@
|
|||||||
<string name="update_source">Update source</string>
|
<string name="update_source">Update source</string>
|
||||||
<string name="confirm_disconnect_title">Disconnect ?</string>
|
<string name="confirm_disconnect_title">Disconnect ?</string>
|
||||||
<string name="confirm_disconnect_description">You will be disconnected from your selfoss instance.</string>
|
<string name="confirm_disconnect_description">You will be disconnected from your selfoss instance.</string>
|
||||||
|
<string name="disable_ssl">Disable SSL</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -130,4 +130,5 @@
|
|||||||
<string name="update_source">Update source</string>
|
<string name="update_source">Update source</string>
|
||||||
<string name="confirm_disconnect_title">Disconnect ?</string>
|
<string name="confirm_disconnect_title">Disconnect ?</string>
|
||||||
<string name="confirm_disconnect_description">You will be disconnected from your selfoss instance.</string>
|
<string name="confirm_disconnect_description">You will be disconnected from your selfoss instance.</string>
|
||||||
|
<string name="disable_ssl">Disable SSL</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -130,4 +130,5 @@
|
|||||||
<string name="update_source">Update source</string>
|
<string name="update_source">Update source</string>
|
||||||
<string name="confirm_disconnect_title">Disconnect ?</string>
|
<string name="confirm_disconnect_title">Disconnect ?</string>
|
||||||
<string name="confirm_disconnect_description">You will be disconnected from your selfoss instance.</string>
|
<string name="confirm_disconnect_description">You will be disconnected from your selfoss instance.</string>
|
||||||
|
<string name="disable_ssl">Disable SSL</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
<resources>
|
||||||
<string name="app_name">"Lettore RSS per Selfoss"</string>
|
<string name="app_name">"Lettore RSS per Selfoss"</string>
|
||||||
<string name="title_activity_login">"Accedi"</string>
|
<string name="title_activity_login">"Accedi"</string>
|
||||||
<string name="prompt_password">"Password"</string>
|
<string name="prompt_password">"Password"</string>
|
||||||
@ -130,4 +130,5 @@
|
|||||||
<string name="update_source">Update source</string>
|
<string name="update_source">Update source</string>
|
||||||
<string name="confirm_disconnect_title">Disconnect ?</string>
|
<string name="confirm_disconnect_title">Disconnect ?</string>
|
||||||
<string name="confirm_disconnect_description">You will be disconnected from your selfoss instance.</string>
|
<string name="confirm_disconnect_description">You will be disconnected from your selfoss instance.</string>
|
||||||
|
<string name="disable_ssl">Disable SSL</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -130,4 +130,5 @@
|
|||||||
<string name="update_source">Update source</string>
|
<string name="update_source">Update source</string>
|
||||||
<string name="confirm_disconnect_title">Disconnect ?</string>
|
<string name="confirm_disconnect_title">Disconnect ?</string>
|
||||||
<string name="confirm_disconnect_description">You will be disconnected from your selfoss instance.</string>
|
<string name="confirm_disconnect_description">You will be disconnected from your selfoss instance.</string>
|
||||||
|
<string name="disable_ssl">Disable SSL</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||||
<string name="gdpr_dialog_title">The app does not share any personal data about you.</string>
|
<string name="gdpr_dialog_title">The app does not share any personal data about you.</string>
|
||||||
<string name="gdpr_dialog_message"><![CDATA[Crash reports sending is now enabled. It can be disabled from the settings page. Keep in mind that crash reports are essential for the app development.]]></string>
|
<string name="gdpr_dialog_message"><![CDATA[Crash reports sending is now enabled. It can be disabled from the settings page. Keep in mind that crash reports are essential for the app development.]]></string>
|
||||||
<string name="crash_toast_text">A crash occured. Sending the details to the developper.</string>
|
<string name="crash_toast_text">A crash occured. Sending the details to the developper.</string>
|
||||||
|
@ -130,4 +130,5 @@
|
|||||||
<string name="update_source">Update source</string>
|
<string name="update_source">Update source</string>
|
||||||
<string name="confirm_disconnect_title">Disconnect ?</string>
|
<string name="confirm_disconnect_title">Disconnect ?</string>
|
||||||
<string name="confirm_disconnect_description">You will be disconnected from your selfoss instance.</string>
|
<string name="confirm_disconnect_description">You will be disconnected from your selfoss instance.</string>
|
||||||
|
<string name="disable_ssl">Disable SSL</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -130,4 +130,5 @@
|
|||||||
<string name="update_source">Update source</string>
|
<string name="update_source">Update source</string>
|
||||||
<string name="confirm_disconnect_title">Disconnect ?</string>
|
<string name="confirm_disconnect_title">Disconnect ?</string>
|
||||||
<string name="confirm_disconnect_description">You will be disconnected from your selfoss instance.</string>
|
<string name="confirm_disconnect_description">You will be disconnected from your selfoss instance.</string>
|
||||||
|
<string name="disable_ssl">Disable SSL</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -130,4 +130,5 @@
|
|||||||
<string name="update_source">Update source</string>
|
<string name="update_source">Update source</string>
|
||||||
<string name="confirm_disconnect_title">Disconnect ?</string>
|
<string name="confirm_disconnect_title">Disconnect ?</string>
|
||||||
<string name="confirm_disconnect_description">You will be disconnected from your selfoss instance.</string>
|
<string name="confirm_disconnect_description">You will be disconnected from your selfoss instance.</string>
|
||||||
|
<string name="disable_ssl">Disable SSL</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -130,4 +130,5 @@
|
|||||||
<string name="update_source">Update source</string>
|
<string name="update_source">Update source</string>
|
||||||
<string name="confirm_disconnect_title">Disconnect ?</string>
|
<string name="confirm_disconnect_title">Disconnect ?</string>
|
||||||
<string name="confirm_disconnect_description">You will be disconnected from your selfoss instance.</string>
|
<string name="confirm_disconnect_description">You will be disconnected from your selfoss instance.</string>
|
||||||
|
<string name="disable_ssl">Disable SSL</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -130,4 +130,5 @@
|
|||||||
<string name="update_source">Update source</string>
|
<string name="update_source">Update source</string>
|
||||||
<string name="confirm_disconnect_title">Disconnect ?</string>
|
<string name="confirm_disconnect_title">Disconnect ?</string>
|
||||||
<string name="confirm_disconnect_description">You will be disconnected from your selfoss instance.</string>
|
<string name="confirm_disconnect_description">You will be disconnected from your selfoss instance.</string>
|
||||||
|
<string name="disable_ssl">Disable SSL</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -130,4 +130,5 @@
|
|||||||
<string name="update_source">更新源</string>
|
<string name="update_source">更新源</string>
|
||||||
<string name="confirm_disconnect_title">Disconnect ?</string>
|
<string name="confirm_disconnect_title">Disconnect ?</string>
|
||||||
<string name="confirm_disconnect_description">You will be disconnected from your selfoss instance.</string>
|
<string name="confirm_disconnect_description">You will be disconnected from your selfoss instance.</string>
|
||||||
|
<string name="disable_ssl">Disable SSL</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -130,4 +130,5 @@
|
|||||||
<string name="update_source">Update source</string>
|
<string name="update_source">Update source</string>
|
||||||
<string name="confirm_disconnect_title">Disconnect ?</string>
|
<string name="confirm_disconnect_title">Disconnect ?</string>
|
||||||
<string name="confirm_disconnect_description">You will be disconnected from your selfoss instance.</string>
|
<string name="confirm_disconnect_description">You will be disconnected from your selfoss instance.</string>
|
||||||
|
<string name="disable_ssl">Disable SSL</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<resources>
|
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||||
<string name="app_name">"Reader for Selfoss"</string>
|
<string name="app_name">"Reader for Selfoss"</string>
|
||||||
<string name="title_activity_login">"Log in"</string>
|
<string name="title_activity_login">"Log in"</string>
|
||||||
<string name="prompt_password">"Password"</string>
|
<string name="prompt_password">"Password"</string>
|
||||||
@ -6,7 +6,7 @@
|
|||||||
<string name="error_invalid_password">"Password not long enough"</string>
|
<string name="error_invalid_password">"Password not long enough"</string>
|
||||||
<string name="error_field_required">"Field required"</string>
|
<string name="error_field_required">"Field required"</string>
|
||||||
<string name="prompt_url">"Url"</string>
|
<string name="prompt_url">"Url"</string>
|
||||||
<string name="disableSSL">"Disable SSL"</string>
|
<string name="disable_ssl">"Disable SSL"</string>
|
||||||
<string name="withLoginSwitch">"Login required ?"</string>
|
<string name="withLoginSwitch">"Login required ?"</string>
|
||||||
<string name="login_url_problem">"Oops. You may need to add a \"/\" at the end of the url."</string>
|
<string name="login_url_problem">"Oops. You may need to add a \"/\" at the end of the url."</string>
|
||||||
<string name="prompt_login">"Username"</string>
|
<string name="prompt_login">"Username"</string>
|
||||||
|
@ -7,12 +7,12 @@ buildscript {
|
|||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
//trick: for the same plugin versions in all sub-modules
|
//trick: for the same plugin versions in all sub-modules
|
||||||
id("com.android.application").version("7.4.0").apply(false)
|
id("com.android.application").version("8.1.0").apply(false)
|
||||||
id("com.android.library").version("7.4.0").apply(false)
|
id("com.android.library").version("8.1.0").apply(false)
|
||||||
kotlin("android").version("1.7.20").apply(false)
|
id("org.jetbrains.kotlin.android").version("1.9.10").apply(false)
|
||||||
kotlin("multiplatform").version("1.7.20").apply(false)
|
kotlin("multiplatform").version("1.9.10").apply(false)
|
||||||
id("com.mikepenz.aboutlibraries.plugin").version("10.5.1").apply(false)
|
id("com.mikepenz.aboutlibraries.plugin").version("10.5.1").apply(false)
|
||||||
id("org.jetbrains.kotlinx.kover") version "0.6.1"
|
id("org.jetbrains.kotlinx.kover").version("0.6.1").apply(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
|
@ -13,22 +13,15 @@
|
|||||||
#Tue Mar 22 16:50:00 CET 2022
|
#Tue Mar 22 16:50:00 CET 2022
|
||||||
#Gradle
|
#Gradle
|
||||||
org.gradle.jvmargs=-Xmx2048M -Dfile.encoding=UTF-8 -Dkotlin.daemon.jvm.options\="-Xmx2048M"
|
org.gradle.jvmargs=-Xmx2048M -Dfile.encoding=UTF-8 -Dkotlin.daemon.jvm.options\="-Xmx2048M"
|
||||||
|
|
||||||
#Kotlin
|
#Kotlin
|
||||||
kotlin.code.style=official
|
kotlin.code.style=official
|
||||||
|
|
||||||
#Android
|
#Android
|
||||||
android.useAndroidX=true
|
android.useAndroidX=true
|
||||||
kotlin.native.enableDependencyPropagation=false
|
|
||||||
#android.nonTransitiveRClass=true
|
#android.nonTransitiveRClass=true
|
||||||
android.enableJetifier=true
|
android.enableJetifier=true
|
||||||
|
android.nonTransitiveRClass=false
|
||||||
|
|
||||||
#MPP
|
#MPP
|
||||||
kotlin.mpp.enableCInteropCommonization=true
|
kotlin.mpp.enableCInteropCommonization=true
|
||||||
kotlin.mpp.enableGranularSourceSetsMetadata=true
|
|
||||||
|
|
||||||
|
|
||||||
org.gradle.parallel=true
|
org.gradle.parallel=true
|
||||||
org.gradle.caching=true
|
org.gradle.caching=true
|
||||||
ignoreGitVersion=false
|
ignoreGitVersion=false
|
||||||
|
6
gradle/wrapper/gradle-wrapper.properties
vendored
6
gradle/wrapper/gradle-wrapper.properties
vendored
@ -1,6 +1,6 @@
|
|||||||
#Mon Jan 23 20:47:46 CET 2023
|
#Thu Jul 13 11:41:19 CEST 2023
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip
|
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
zipStorePath=wrapper/dists
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.1-bin.zip
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
zipStorePath=wrapper/dists
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
val ktorVersion = "2.3.2"
|
||||||
|
|
||||||
object SqlDelight {
|
object SqlDelight {
|
||||||
const val runtime = "com.squareup.sqldelight:runtime:1.5.4"
|
const val runtime = "com.squareup.sqldelight:runtime:1.5.4"
|
||||||
const val android = "com.squareup.sqldelight:android-driver:1.5.4"
|
const val android = "com.squareup.sqldelight:android-driver:1.5.4"
|
||||||
@ -9,12 +11,13 @@ plugins {
|
|||||||
kotlin("multiplatform")
|
kotlin("multiplatform")
|
||||||
id("com.android.library")
|
id("com.android.library")
|
||||||
id("com.squareup.sqldelight")
|
id("com.squareup.sqldelight")
|
||||||
kotlin("plugin.serialization") version "1.4.10"
|
kotlin("plugin.serialization") version "1.9.0"
|
||||||
id("org.jetbrains.kotlinx.kover") version "0.6.1"
|
id("org.jetbrains.kotlinx.kover")
|
||||||
}
|
}
|
||||||
|
|
||||||
kotlin {
|
kotlin {
|
||||||
android()
|
androidTarget()
|
||||||
|
jvmToolchain(11)
|
||||||
|
|
||||||
listOf(
|
listOf(
|
||||||
iosX64(),
|
iosX64(),
|
||||||
@ -29,12 +32,14 @@ kotlin {
|
|||||||
sourceSets {
|
sourceSets {
|
||||||
val commonMain by getting {
|
val commonMain by getting {
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation("io.ktor:ktor-client-core:2.2.4")
|
implementation("io.ktor:ktor-client-core:$ktorVersion")
|
||||||
implementation("io.ktor:ktor-client-content-negotiation:2.2.4")
|
implementation("io.ktor:ktor-client-content-negotiation:$ktorVersion")
|
||||||
implementation("io.ktor:ktor-serialization-kotlinx-json:2.2.4")
|
implementation("io.ktor:ktor-serialization-kotlinx-json:$ktorVersion")
|
||||||
implementation("io.ktor:ktor-client-logging:2.2.4")
|
implementation("io.ktor:ktor-client-logging:$ktorVersion")
|
||||||
|
implementation("io.ktor:ktor-client-auth:$ktorVersion")
|
||||||
|
implementation("io.ktor:ktor-client-cio:$ktorVersion")
|
||||||
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.0")
|
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.0")
|
||||||
implementation("io.ktor:ktor-client-auth:2.2.4")
|
|
||||||
implementation("org.jsoup:jsoup:1.15.4")
|
implementation("org.jsoup:jsoup:1.15.4")
|
||||||
|
|
||||||
//Dependency Injection
|
//Dependency Injection
|
||||||
@ -58,15 +63,14 @@ kotlin {
|
|||||||
}
|
}
|
||||||
val androidMain by getting {
|
val androidMain by getting {
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation("com.squareup.okhttp3:okhttp:4.10.0")
|
implementation("com.squareup.okhttp3:okhttp:4.11.0")
|
||||||
implementation("io.ktor:ktor-client-okhttp:2.2.4")
|
|
||||||
implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.4.0")
|
implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.4.0")
|
||||||
|
|
||||||
// Sql
|
// Sql
|
||||||
implementation(SqlDelight.android)
|
implementation(SqlDelight.android)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val androidTest by getting {
|
val androidUnitTest by getting {
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation(kotlin("test-junit"))
|
implementation(kotlin("test-junit"))
|
||||||
implementation("junit:junit:4.13.2")
|
implementation("junit:junit:4.13.2")
|
||||||
@ -99,15 +103,14 @@ kotlin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdk = 32
|
compileSdk = 33
|
||||||
sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml")
|
sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml")
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
minSdk = 21
|
minSdk = 21
|
||||||
targetSdk = 32
|
|
||||||
}
|
}
|
||||||
compileOptions {
|
compileOptions {
|
||||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
sourceCompatibility = JavaVersion.VERSION_11
|
||||||
targetCompatibility = JavaVersion.VERSION_1_8
|
targetCompatibility = JavaVersion.VERSION_11
|
||||||
}
|
}
|
||||||
namespace = "bou.amine.apps.readerforselfossv2"
|
namespace = "bou.amine.apps.readerforselfossv2"
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,17 @@
|
|||||||
|
package bou.amine.apps.readerforselfossv2.rest
|
||||||
|
|
||||||
|
import io.ktor.client.engine.cio.CIOEngineConfig
|
||||||
|
import java.security.cert.X509Certificate
|
||||||
|
import javax.net.ssl.X509TrustManager
|
||||||
|
|
||||||
|
class NaiveTrustManager : X509TrustManager {
|
||||||
|
override fun checkClientTrusted(chain: Array<out X509Certificate>?, authType: String?) {}
|
||||||
|
|
||||||
|
override fun checkServerTrusted(chain: Array<out X509Certificate>?, authType: String?) {}
|
||||||
|
|
||||||
|
override fun getAcceptedIssuers(): Array<out X509Certificate> = arrayOf()
|
||||||
|
}
|
||||||
|
|
||||||
|
actual fun setupInsecureHTTPEngine(config: CIOEngineConfig) {
|
||||||
|
config.https.trustManager = NaiveTrustManager()
|
||||||
|
}
|
@ -1,82 +0,0 @@
|
|||||||
package bou.amine.apps.readerforselfossv2.rest
|
|
||||||
|
|
||||||
import bou.amine.apps.readerforselfossv2.service.AppSettingsService
|
|
||||||
import io.github.aakira.napier.Napier
|
|
||||||
import io.ktor.client.*
|
|
||||||
import io.ktor.client.engine.okhttp.*
|
|
||||||
import io.ktor.client.plugins.*
|
|
||||||
import io.ktor.client.plugins.cache.*
|
|
||||||
import io.ktor.client.plugins.contentnegotiation.*
|
|
||||||
import io.ktor.client.plugins.cookies.*
|
|
||||||
import io.ktor.client.plugins.logging.*
|
|
||||||
import io.ktor.http.*
|
|
||||||
import io.ktor.serialization.kotlinx.json.*
|
|
||||||
import kotlinx.coroutines.CoroutineScope
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import kotlinx.serialization.json.Json
|
|
||||||
import okhttp3.OkHttpClient
|
|
||||||
import org.apache.http.conn.ssl.AllowAllHostnameVerifier
|
|
||||||
import java.security.cert.X509Certificate
|
|
||||||
import javax.net.ssl.SSLContext
|
|
||||||
import javax.net.ssl.X509TrustManager
|
|
||||||
|
|
||||||
class NaiveTrustManager : X509TrustManager {
|
|
||||||
override fun checkClientTrusted(chain: Array<out X509Certificate>?, authType: String?) {}
|
|
||||||
|
|
||||||
override fun checkServerTrusted(chain: Array<out X509Certificate>?, authType: String?) {}
|
|
||||||
|
|
||||||
override fun getAcceptedIssuers(): Array<out X509Certificate> = arrayOf()
|
|
||||||
}
|
|
||||||
|
|
||||||
actual fun createHttpClient(appSettingsService: AppSettingsService, api: SelfossApi) =
|
|
||||||
HttpClient(OkHttp) {
|
|
||||||
engine {
|
|
||||||
val trustManager = NaiveTrustManager()
|
|
||||||
val sslContext = SSLContext.getInstance("TLS").apply {
|
|
||||||
init(null, arrayOf(trustManager), null)
|
|
||||||
}
|
|
||||||
preconfigured = OkHttpClient().newBuilder()
|
|
||||||
.sslSocketFactory(
|
|
||||||
sslSocketFactory = sslContext.socketFactory,
|
|
||||||
trustManager = trustManager
|
|
||||||
)
|
|
||||||
.hostnameVerifier(AllowAllHostnameVerifier())
|
|
||||||
.build()
|
|
||||||
}
|
|
||||||
install(ContentNegotiation) {
|
|
||||||
install(HttpCache)
|
|
||||||
json(Json {
|
|
||||||
prettyPrint = true
|
|
||||||
isLenient = true
|
|
||||||
ignoreUnknownKeys = true
|
|
||||||
})
|
|
||||||
}
|
|
||||||
install(Logging) {
|
|
||||||
logger = object : Logger {
|
|
||||||
override fun log(message: String) {
|
|
||||||
Napier.d(message, tag = "LogApiCalls")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
level = LogLevel.INFO
|
|
||||||
}
|
|
||||||
install(HttpTimeout) {
|
|
||||||
requestTimeoutMillis = appSettingsService.getApiTimeout()
|
|
||||||
}
|
|
||||||
install(HttpCookies)
|
|
||||||
install(HttpRequestRetry) {
|
|
||||||
maxRetries = 2
|
|
||||||
retryIf { _, response ->
|
|
||||||
response.status == HttpStatusCode.Forbidden && api.shouldHavePostLogin() && api.hasLoginInfo()
|
|
||||||
}
|
|
||||||
modifyRequest {
|
|
||||||
Napier.i("Will modify", tag = "HttpSend")
|
|
||||||
CoroutineScope(Dispatchers.Main).launch {
|
|
||||||
Napier.i("Will login", tag = "HttpSend")
|
|
||||||
api.login()
|
|
||||||
Napier.i("Did login", tag = "HttpSend")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
expectSuccess = false
|
|
||||||
}
|
|
@ -4,12 +4,83 @@ import bou.amine.apps.readerforselfossv2.model.SelfossModel
|
|||||||
import bou.amine.apps.readerforselfossv2.model.StatusAndData
|
import bou.amine.apps.readerforselfossv2.model.StatusAndData
|
||||||
import bou.amine.apps.readerforselfossv2.model.SuccessResponse
|
import bou.amine.apps.readerforselfossv2.model.SuccessResponse
|
||||||
import bou.amine.apps.readerforselfossv2.service.AppSettingsService
|
import bou.amine.apps.readerforselfossv2.service.AppSettingsService
|
||||||
import io.ktor.client.*
|
import io.github.aakira.napier.Napier
|
||||||
import io.ktor.client.request.*
|
import io.ktor.client.HttpClient
|
||||||
import io.ktor.client.statement.*
|
import io.ktor.client.engine.cio.CIO
|
||||||
import io.ktor.http.*
|
import io.ktor.client.engine.cio.CIOEngineConfig
|
||||||
|
import io.ktor.client.plugins.HttpRequestRetry
|
||||||
|
import io.ktor.client.plugins.HttpTimeout
|
||||||
|
import io.ktor.client.plugins.auth.providers.BasicAuthCredentials
|
||||||
|
import io.ktor.client.plugins.cache.HttpCache
|
||||||
|
import io.ktor.client.plugins.contentnegotiation.ContentNegotiation
|
||||||
|
import io.ktor.client.plugins.cookies.HttpCookies
|
||||||
|
import io.ktor.client.plugins.logging.LogLevel
|
||||||
|
import io.ktor.client.plugins.logging.Logger
|
||||||
|
import io.ktor.client.plugins.logging.Logging
|
||||||
|
import io.ktor.client.request.get
|
||||||
|
import io.ktor.client.request.headers
|
||||||
|
import io.ktor.client.request.parameter
|
||||||
|
import io.ktor.client.statement.HttpResponse
|
||||||
|
import io.ktor.http.HttpHeaders
|
||||||
|
import io.ktor.http.HttpStatusCode
|
||||||
|
import io.ktor.http.Parameters
|
||||||
|
import io.ktor.serialization.kotlinx.json.json
|
||||||
|
import io.ktor.util.encodeBase64
|
||||||
|
import io.ktor.utils.io.charsets.Charsets
|
||||||
|
import io.ktor.utils.io.core.toByteArray
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.serialization.json.Json
|
||||||
|
|
||||||
expect fun createHttpClient(appSettingsService: AppSettingsService, api: SelfossApi): HttpClient
|
expect fun setupInsecureHTTPEngine(config: CIOEngineConfig)
|
||||||
|
|
||||||
|
fun createHttpClient(
|
||||||
|
appSettingsService: AppSettingsService,
|
||||||
|
api: SelfossApi
|
||||||
|
) =
|
||||||
|
HttpClient(CIO) {
|
||||||
|
if (appSettingsService.getSelfSigned()) {
|
||||||
|
engine {
|
||||||
|
setupInsecureHTTPEngine(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
install(ContentNegotiation) {
|
||||||
|
install(HttpCache)
|
||||||
|
json(Json {
|
||||||
|
prettyPrint = true
|
||||||
|
isLenient = true
|
||||||
|
ignoreUnknownKeys = true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
install(Logging) {
|
||||||
|
logger = object : Logger {
|
||||||
|
override fun log(message: String) {
|
||||||
|
Napier.d(message, tag = "LogApiCalls")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
level = LogLevel.INFO
|
||||||
|
}
|
||||||
|
install(HttpTimeout) {
|
||||||
|
requestTimeoutMillis = appSettingsService.getApiTimeout()
|
||||||
|
}
|
||||||
|
install(HttpCookies)
|
||||||
|
install(HttpRequestRetry) {
|
||||||
|
maxRetries = 2
|
||||||
|
retryIf { _, response ->
|
||||||
|
response.status == HttpStatusCode.Forbidden && api.shouldHavePostLogin() && api.hasLoginInfo()
|
||||||
|
}
|
||||||
|
modifyRequest {
|
||||||
|
Napier.i("Will modify", tag = "HttpSend")
|
||||||
|
CoroutineScope(Dispatchers.Main).launch {
|
||||||
|
Napier.i("Will login", tag = "HttpSend")
|
||||||
|
api.login()
|
||||||
|
Napier.i("Did login", tag = "HttpSend")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expectSuccess = false
|
||||||
|
}
|
||||||
|
|
||||||
class SelfossApi(private val appSettingsService: AppSettingsService) {
|
class SelfossApi(private val appSettingsService: AppSettingsService) {
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ class AppSettingsService(acraSenderServiceProcess: Boolean = false) {
|
|||||||
// Api related
|
// Api related
|
||||||
private var _apiVersion: Int = -1
|
private var _apiVersion: Int = -1
|
||||||
private var _publicAccess: Boolean? = null
|
private var _publicAccess: Boolean? = null
|
||||||
|
private var _selfSigned: Boolean? = null
|
||||||
private var _baseUrl: String = ""
|
private var _baseUrl: String = ""
|
||||||
private var _userName: String = ""
|
private var _userName: String = ""
|
||||||
private var _basicUserName: String = ""
|
private var _basicUserName: String = ""
|
||||||
@ -77,6 +78,22 @@ class AppSettingsService(acraSenderServiceProcess: Boolean = false) {
|
|||||||
_publicAccess = settings.getBoolean(API_PUBLIC_ACCESS, false)
|
_publicAccess = settings.getBoolean(API_PUBLIC_ACCESS, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getSelfSigned(): Boolean {
|
||||||
|
if (_selfSigned == null) {
|
||||||
|
refreshSelfSigned()
|
||||||
|
}
|
||||||
|
return _selfSigned!!
|
||||||
|
}
|
||||||
|
|
||||||
|
fun updateSelfSigned(selfSigned: Boolean) {
|
||||||
|
settings.putBoolean(API_SELF_SIGNED, selfSigned)
|
||||||
|
refreshSelfSigned()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun refreshSelfSigned() {
|
||||||
|
_selfSigned = settings.getBoolean(API_SELF_SIGNED, false)
|
||||||
|
}
|
||||||
|
|
||||||
fun getBaseUrl(): String {
|
fun getBaseUrl(): String {
|
||||||
if (_baseUrl.isEmpty()) {
|
if (_baseUrl.isEmpty()) {
|
||||||
refreshBaseUrl()
|
refreshBaseUrl()
|
||||||
@ -383,6 +400,7 @@ class AppSettingsService(acraSenderServiceProcess: Boolean = false) {
|
|||||||
refreshBaseUrl()
|
refreshBaseUrl()
|
||||||
refreshApiVersion()
|
refreshApiVersion()
|
||||||
refreshPublicAccess()
|
refreshPublicAccess()
|
||||||
|
refreshSelfSigned()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun refreshUserSettings() {
|
fun refreshUserSettings() {
|
||||||
@ -468,6 +486,8 @@ class AppSettingsService(acraSenderServiceProcess: Boolean = false) {
|
|||||||
|
|
||||||
const val API_PUBLIC_ACCESS = "apiPublicAccess"
|
const val API_PUBLIC_ACCESS = "apiPublicAccess"
|
||||||
|
|
||||||
|
const val API_SELF_SIGNED = "apiSelfSigned"
|
||||||
|
|
||||||
const val API_ITEMS_NUMBER = "prefer_api_items_number"
|
const val API_ITEMS_NUMBER = "prefer_api_items_number"
|
||||||
|
|
||||||
const val API_TIMEOUT = "api_timeout"
|
const val API_TIMEOUT = "api_timeout"
|
||||||
|
Loading…
Reference in New Issue
Block a user