mirror of
https://github.com/kiwix/kiwix-android.git
synced 2025-08-03 10:46:53 -04:00
Merge pull request #4231 from kiwix/Fixes#4165
Added support for Android 16.
This commit is contained in:
commit
e939ff770d
24
.github/workflows/ci.yml
vendored
24
.github/workflows/ci.yml
vendored
@ -12,7 +12,7 @@ jobs:
|
||||
name: Automated tests
|
||||
strategy:
|
||||
matrix:
|
||||
api-level: [ 25, 30, 33, 34, 35 ]
|
||||
api-level: [ 25, 30, 33, 34, 35, 36 ]
|
||||
fail-fast: true
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
@ -57,7 +57,7 @@ jobs:
|
||||
uses: reactivecircus/android-emulator-runner@v2
|
||||
with:
|
||||
api-level: ${{ matrix.api-level }}
|
||||
target: ${{ (matrix.api-level == 35) && 'google_apis' || 'default' }}
|
||||
target: ${{ (matrix.api-level >= 35) && 'google_apis' || 'default' }}
|
||||
arch: x86_64
|
||||
profile: pixel_2
|
||||
ram-size: 3072M
|
||||
@ -76,7 +76,7 @@ jobs:
|
||||
GRADLE_OPTS: "-Dorg.gradle.internal.http.connectionTimeout=60000 -Dorg.gradle.internal.http.socketTimeout=60000 -Dorg.gradle.internal.network.retry.max.attempts=6 -Dorg.gradle.internal.network.retry.initial.backOff=2000"
|
||||
with:
|
||||
api-level: ${{ matrix.api-level }}
|
||||
target: ${{ (matrix.api-level == 35) && 'google_apis' || 'default' }}
|
||||
target: ${{ (matrix.api-level >= 35) && 'google_apis' || 'default' }}
|
||||
arch: x86_64
|
||||
profile: pixel_2
|
||||
ram-size: 3072M
|
||||
@ -118,7 +118,7 @@ jobs:
|
||||
name: Automated tests for PlayStore variant
|
||||
strategy:
|
||||
matrix:
|
||||
api-level: [ 25, 30, 33, 34, 35 ]
|
||||
api-level: [ 25, 30, 33, 34, 35, 36 ]
|
||||
fail-fast: true
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
@ -163,7 +163,7 @@ jobs:
|
||||
uses: reactivecircus/android-emulator-runner@v2
|
||||
with:
|
||||
api-level: ${{ matrix.api-level }}
|
||||
target: ${{ (matrix.api-level == 35) && 'google_apis' || 'default' }}
|
||||
target: ${{ (matrix.api-level >= 35) && 'google_apis' || 'default' }}
|
||||
arch: x86_64
|
||||
profile: pixel_2
|
||||
ram-size: 2048M
|
||||
@ -182,7 +182,7 @@ jobs:
|
||||
GRADLE_OPTS: "-Dorg.gradle.internal.http.connectionTimeout=60000 -Dorg.gradle.internal.http.socketTimeout=60000 -Dorg.gradle.internal.network.retry.max.attempts=6 -Dorg.gradle.internal.network.retry.initial.backOff=2000"
|
||||
with:
|
||||
api-level: ${{ matrix.api-level }}
|
||||
target: ${{ (matrix.api-level == 35) && 'google_apis' || 'default' }}
|
||||
target: ${{ (matrix.api-level >= 35) && 'google_apis' || 'default' }}
|
||||
arch: x86_64
|
||||
profile: pixel_2
|
||||
ram-size: 2048M
|
||||
@ -199,7 +199,7 @@ jobs:
|
||||
name: Automated tests for Custom app
|
||||
strategy:
|
||||
matrix:
|
||||
api-level: [ 25, 30, 33, 34, 35 ]
|
||||
api-level: [ 25, 30, 33, 34, 35, 36 ]
|
||||
fail-fast: true
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
@ -244,7 +244,7 @@ jobs:
|
||||
uses: reactivecircus/android-emulator-runner@v2
|
||||
with:
|
||||
api-level: ${{ matrix.api-level }}
|
||||
target: ${{ (matrix.api-level == 35) && 'google_apis' || 'default' }}
|
||||
target: ${{ (matrix.api-level >= 35) && 'google_apis' || 'default' }}
|
||||
arch: x86_64
|
||||
profile: pixel_2
|
||||
ram-size: 2048M
|
||||
@ -263,7 +263,7 @@ jobs:
|
||||
GRADLE_OPTS: "-Dorg.gradle.internal.http.connectionTimeout=60000 -Dorg.gradle.internal.http.socketTimeout=60000 -Dorg.gradle.internal.network.retry.max.attempts=6 -Dorg.gradle.internal.network.retry.initial.backOff=2000"
|
||||
with:
|
||||
api-level: ${{ matrix.api-level }}
|
||||
target: ${{ (matrix.api-level == 35) && 'google_apis' || 'default' }}
|
||||
target: ${{ (matrix.api-level >= 35) && 'google_apis' || 'default' }}
|
||||
arch: x86_64
|
||||
profile: pixel_2
|
||||
ram-size: 2048M
|
||||
@ -280,7 +280,7 @@ jobs:
|
||||
name: Automated tests on Tablet
|
||||
strategy:
|
||||
matrix:
|
||||
api-level: [ 25, 30, 33, 34, 35 ]
|
||||
api-level: [ 25, 30, 33, 34, 35, 36 ]
|
||||
fail-fast: true
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
@ -325,7 +325,7 @@ jobs:
|
||||
uses: reactivecircus/android-emulator-runner@v2
|
||||
with:
|
||||
api-level: ${{ matrix.api-level }}
|
||||
target: ${{ (matrix.api-level == 35) && 'google_apis' || 'default' }}
|
||||
target: ${{ (matrix.api-level >= 35) && 'google_apis' || 'default' }}
|
||||
arch: x86_64
|
||||
profile: pixel_2
|
||||
ram-size: 2048M
|
||||
@ -344,7 +344,7 @@ jobs:
|
||||
GRADLE_OPTS: "-Dorg.gradle.internal.http.connectionTimeout=60000 -Dorg.gradle.internal.http.socketTimeout=60000 -Dorg.gradle.internal.network.retry.max.attempts=6 -Dorg.gradle.internal.network.retry.initial.backOff=2000"
|
||||
with:
|
||||
api-level: ${{ matrix.api-level }}
|
||||
target: ${{ (matrix.api-level == 35) && 'google_apis' || 'default' }}
|
||||
target: ${{ (matrix.api-level >= 35) && 'google_apis' || 'default' }}
|
||||
arch: x86_64
|
||||
profile: pixel_c
|
||||
ram-size: 2048M
|
||||
|
@ -1,3 +1,4 @@
|
||||
import com.android.build.gradle.internal.tasks.factory.dependsOn
|
||||
import com.slack.keeper.optInToKeeper
|
||||
import org.w3c.dom.Element
|
||||
import plugin.KiwixConfigurationPlugin
|
||||
@ -29,12 +30,12 @@ android {
|
||||
// it directly in the AndroidManifest file.
|
||||
namespace = "org.kiwix.kiwixmobile"
|
||||
defaultConfig {
|
||||
base.archivesName.set(apkPrefix)
|
||||
resValue("string", "app_name", "Kiwix")
|
||||
resValue("string", "app_search_string", "Search Kiwix")
|
||||
versionCode = "".getVersionCode()
|
||||
versionName = generateVersionName()
|
||||
manifestPlaceholders["permission"] = "android.permission.MANAGE_EXTERNAL_STORAGE"
|
||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
lint {
|
||||
checkDependencies = true
|
||||
@ -130,7 +131,7 @@ dependencies {
|
||||
androidTestImplementation(Libs.leakcanary_android_instrumentation)
|
||||
testImplementation(Libs.kotlinx_coroutines_test)
|
||||
}
|
||||
task("generateVersionCodeAndName") {
|
||||
tasks.register("generateVersionCodeAndName") {
|
||||
val file = File("VERSION_INFO")
|
||||
if (!file.exists()) file.createNewFile()
|
||||
file.printWriter().use {
|
||||
@ -138,7 +139,7 @@ task("generateVersionCodeAndName") {
|
||||
}
|
||||
}
|
||||
|
||||
task("renameTarakFile") {
|
||||
tasks.register("renameTarakFile") {
|
||||
val taraskFile = File("$rootDir/core/src/main/res/values-b+be+tarask/strings.xml")
|
||||
val mainStringsFile = File("$rootDir/core/src/main/res/values/strings.xml")
|
||||
|
||||
@ -214,6 +215,10 @@ fun elementToString(element: Element): String {
|
||||
return result.writer.toString()
|
||||
}
|
||||
|
||||
tasks.build {
|
||||
dependsOn("renameTarakFile")
|
||||
gradle.projectsEvaluated {
|
||||
tasks.forEach { task ->
|
||||
if (task.name != "renameTarakFile") {
|
||||
task.dependsOn("renameTarakFile")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -119,8 +119,11 @@ class ObjectBoxToRoomMigratorTest {
|
||||
val expectedSearchTerm = "test search"
|
||||
val expectedZimId = "8812214350305159407L"
|
||||
val expectedUrl = "http://kiwix.app/mainPage"
|
||||
val recentSearchEntity =
|
||||
RecentSearchEntity(searchTerm = expectedSearchTerm, zimId = expectedZimId, url = expectedUrl)
|
||||
val recentSearchEntity = RecentSearchEntity(
|
||||
searchTerm = expectedSearchTerm,
|
||||
zimId = expectedZimId,
|
||||
url = expectedUrl
|
||||
)
|
||||
// insert into object box
|
||||
box.put(recentSearchEntity)
|
||||
// migrate data into room database
|
||||
|
@ -68,7 +68,9 @@ class DownloadRobot : BaseRobot() {
|
||||
clickOn(ViewId(R.id.downloadsFragment))
|
||||
}
|
||||
|
||||
fun waitForDataToLoad(retryCountForDataToLoad: Int = 10) {
|
||||
// Increasing the default timeout for data loading because, on the Android 16 Emulator,
|
||||
// the internet connection is slow, and the library download takes longer.
|
||||
fun waitForDataToLoad(retryCountForDataToLoad: Int = 20) {
|
||||
try {
|
||||
isVisible(TextId(string.your_languages))
|
||||
} catch (e: RuntimeException) {
|
||||
|
@ -56,7 +56,9 @@ class InitialDownloadRobot : BaseRobot() {
|
||||
refresh(R.id.librarySwipeRefresh)
|
||||
}
|
||||
|
||||
fun waitForDataToLoad(retryCountForDataToLoad: Int = 10) {
|
||||
// Increasing the default timeout for data loading because, on the Android 16 Emulator,
|
||||
// the internet connection is slow, and the library download takes longer.
|
||||
fun waitForDataToLoad(retryCountForDataToLoad: Int = 20) {
|
||||
try {
|
||||
isVisible(TextId(string.your_languages))
|
||||
} catch (e: RuntimeException) {
|
||||
|
@ -21,6 +21,7 @@ import android.animation.Animator
|
||||
import android.animation.AnimatorListenerAdapter
|
||||
import android.animation.AnimatorSet
|
||||
import android.animation.ValueAnimator
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.database.DataSetObserver
|
||||
import android.graphics.Canvas
|
||||
@ -776,13 +777,17 @@ class CustomPageIndicator @JvmOverloads constructor(
|
||||
val density = context.resources.displayMetrics.density.toInt()
|
||||
|
||||
// Load attributes
|
||||
val a =
|
||||
getContext().obtainStyledAttributes(attrs, R.styleable.CustomPageIndicator, defStyle, 0)
|
||||
dotDiameter =
|
||||
a.getDimensionPixelSize(
|
||||
R.styleable.CustomPageIndicator_ipi_dotDiameter,
|
||||
DEFAULT_DOT_SIZE * density
|
||||
)
|
||||
@SuppressLint("UseKtx")
|
||||
val a = getContext().obtainStyledAttributes(
|
||||
attrs,
|
||||
R.styleable.CustomPageIndicator,
|
||||
defStyle,
|
||||
0
|
||||
)
|
||||
dotDiameter = a.getDimensionPixelSize(
|
||||
R.styleable.CustomPageIndicator_ipi_dotDiameter,
|
||||
DEFAULT_DOT_SIZE * density
|
||||
)
|
||||
dotRadius = (dotDiameter / 2).toFloat()
|
||||
halfDotRadius = dotRadius / 2
|
||||
gap =
|
||||
|
@ -366,18 +366,17 @@ class LocalLibraryFragment : BaseFragment(), CopyMoveFileHandler.FileCopyMoveCal
|
||||
}
|
||||
|
||||
private fun showFileChooser() {
|
||||
val intent =
|
||||
Intent().apply {
|
||||
action = Intent.ACTION_OPEN_DOCUMENT
|
||||
type = "*/*"
|
||||
addCategory(Intent.CATEGORY_OPENABLE)
|
||||
if (sharedPreferenceUtil.prefIsTest) {
|
||||
putExtra(
|
||||
"android.provider.extra.INITIAL_URI",
|
||||
"content://com.android.externalstorage.documents/document/primary:Download".toUri()
|
||||
)
|
||||
}
|
||||
val intent = Intent().apply {
|
||||
action = Intent.ACTION_OPEN_DOCUMENT
|
||||
type = "*/*"
|
||||
addCategory(Intent.CATEGORY_OPENABLE)
|
||||
if (sharedPreferenceUtil.prefIsTest) {
|
||||
putExtra(
|
||||
"android.provider.extra.INITIAL_URI",
|
||||
"content://com.android.externalstorage.documents/document/primary:Download".toUri()
|
||||
)
|
||||
}
|
||||
}
|
||||
try {
|
||||
fileSelectLauncher.launch(Intent.createChooser(intent, "Select a zim file"))
|
||||
} catch (_: ActivityNotFoundException) {
|
||||
|
@ -135,11 +135,10 @@ class KiwixReaderFragment : CoreReaderFragment() {
|
||||
// Update the reader screen title to prevent showing the previously set title
|
||||
// when creating the new archive object.
|
||||
updateTitle()
|
||||
val filePath =
|
||||
FileUtils.getLocalFilePathByUri(
|
||||
requireActivity().applicationContext,
|
||||
zimFileUri.toUri()
|
||||
)
|
||||
val filePath = FileUtils.getLocalFilePathByUri(
|
||||
requireActivity().applicationContext,
|
||||
zimFileUri.toUri()
|
||||
)
|
||||
if (filePath == null || !File(filePath).isFileExist()) {
|
||||
// Close the previously opened book in the reader. Since this file is not found,
|
||||
// it will not be set in the zimFileReader. The previously opened ZIM file
|
||||
|
@ -42,6 +42,7 @@ import org.kiwix.kiwixmobile.BuildConfig.DEBUG
|
||||
import org.kiwix.kiwixmobile.core.R
|
||||
import org.kiwix.kiwixmobile.core.StorageObserver
|
||||
import org.kiwix.kiwixmobile.core.base.SideEffect
|
||||
import org.kiwix.kiwixmobile.core.compat.CompatHelper.Companion.convertToLocal
|
||||
import org.kiwix.kiwixmobile.core.compat.CompatHelper.Companion.isWifi
|
||||
import org.kiwix.kiwixmobile.core.dao.DownloadRoomDao
|
||||
import org.kiwix.kiwixmobile.core.dao.NewBookDao
|
||||
@ -475,7 +476,7 @@ class ZimManageViewModel @Inject constructor(
|
||||
networkLanguageCounts: MutableMap<String, Int>,
|
||||
listToActivateBy: List<Language>
|
||||
) = Locale.getISOLanguages()
|
||||
.map(::Locale)
|
||||
.map { it.convertToLocal() }
|
||||
.filter { networkLanguageCounts.containsKey(it.isO3Language) }
|
||||
.map { locale ->
|
||||
Language(
|
||||
|
@ -1,25 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Kiwix Android
|
||||
~ Copyright (c) 2020 Kiwix <android.kiwix.org>
|
||||
~ This program is free software: you can redistribute it and/or modify
|
||||
~ it under the terms of the GNU General Public License as published by
|
||||
~ the Free Software Foundation, either version 3 of the License, or
|
||||
~ (at your option) any later version.
|
||||
~
|
||||
~ This program is distributed in the hope that it will be useful,
|
||||
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
~ GNU General Public License for more details.
|
||||
~
|
||||
~ You should have received a copy of the GNU General Public License
|
||||
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
~
|
||||
-->
|
||||
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<alpha
|
||||
android:duration="300"
|
||||
android:fromAlpha="0.0"
|
||||
android:interpolator="@android:anim/accelerate_interpolator"
|
||||
android:toAlpha="1.0" />
|
||||
</set>
|
@ -1,25 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Kiwix Android
|
||||
~ Copyright (c) 2020 Kiwix <android.kiwix.org>
|
||||
~ This program is free software: you can redistribute it and/or modify
|
||||
~ it under the terms of the GNU General Public License as published by
|
||||
~ the Free Software Foundation, either version 3 of the License, or
|
||||
~ (at your option) any later version.
|
||||
~
|
||||
~ This program is distributed in the hope that it will be useful,
|
||||
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
~ GNU General Public License for more details.
|
||||
~
|
||||
~ You should have received a copy of the GNU General Public License
|
||||
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
~
|
||||
-->
|
||||
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<alpha
|
||||
android:duration="300"
|
||||
android:fromAlpha="1.0"
|
||||
android:interpolator="@android:anim/accelerate_interpolator"
|
||||
android:toAlpha="0.0" />
|
||||
</set>
|
@ -1,25 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Kiwix Android
|
||||
~ Copyright (c) 2020 Kiwix <android.kiwix.org>
|
||||
~ This program is free software: you can redistribute it and/or modify
|
||||
~ it under the terms of the GNU General Public License as published by
|
||||
~ the Free Software Foundation, either version 3 of the License, or
|
||||
~ (at your option) any later version.
|
||||
~
|
||||
~ This program is distributed in the hope that it will be useful,
|
||||
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
~ GNU General Public License for more details.
|
||||
~
|
||||
~ You should have received a copy of the GNU General Public License
|
||||
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
~
|
||||
-->
|
||||
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<alpha
|
||||
android:duration="300"
|
||||
android:fromAlpha="0.0"
|
||||
android:interpolator="@android:anim/accelerate_interpolator"
|
||||
android:toAlpha="1.0" />
|
||||
</set>
|
@ -1,25 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Kiwix Android
|
||||
~ Copyright (c) 2020 Kiwix <android.kiwix.org>
|
||||
~ This program is free software: you can redistribute it and/or modify
|
||||
~ it under the terms of the GNU General Public License as published by
|
||||
~ the Free Software Foundation, either version 3 of the License, or
|
||||
~ (at your option) any later version.
|
||||
~
|
||||
~ This program is distributed in the hope that it will be useful,
|
||||
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
~ GNU General Public License for more details.
|
||||
~
|
||||
~ You should have received a copy of the GNU General Public License
|
||||
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
~
|
||||
-->
|
||||
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<alpha
|
||||
android:duration="300"
|
||||
android:fromAlpha="1.0"
|
||||
android:interpolator="@android:anim/accelerate_interpolator"
|
||||
android:toAlpha="0.0" />
|
||||
</set>
|
@ -1,3 +1,5 @@
|
||||
import org.gradle.kotlin.dsl.register
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
google()
|
||||
@ -28,6 +30,6 @@ allprojects {
|
||||
}
|
||||
}
|
||||
|
||||
tasks.create<Delete>("clean") {
|
||||
tasks.register<Delete>("clean") {
|
||||
delete(rootProject.layout.buildDirectory)
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ repositories {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation("com.android.tools.build:gradle:8.7.2")
|
||||
implementation("com.android.tools.build:gradle:8.11.0-alpha03")
|
||||
implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:2.0.0")
|
||||
implementation("com.google.devtools.ksp:com.google.devtools.ksp.gradle.plugin:2.0.0-1.0.24")
|
||||
implementation("org.jacoco:org.jacoco.core:0.8.12")
|
||||
@ -23,8 +23,8 @@ dependencies {
|
||||
exclude(group = "com.google.guava", module = "guava")
|
||||
}
|
||||
implementation("io.gitlab.arturbosch.detekt:detekt-gradle-plugin:1.23.8")
|
||||
implementation("com.googlecode.json-simple:json-simple:1.1")
|
||||
implementation("com.squareup.okhttp3:okhttp:4.10.0")
|
||||
implementation("com.googlecode.json-simple:json-simple:1.1.1")
|
||||
implementation("com.squareup.okhttp3:okhttp:4.12.0")
|
||||
|
||||
implementation(gradleApi())
|
||||
implementation(localGroovy())
|
||||
|
@ -22,9 +22,9 @@ object Config {
|
||||
|
||||
// Here is a list of all Android versions with their corresponding API
|
||||
// levels: https://apilevels.com/
|
||||
const val compileSdk = 35 // SDK version used by Gradle to compile our app.
|
||||
const val compileSdk = 36 // SDK version used by Gradle to compile our app.
|
||||
const val minSdk = 25 // Minimum SDK (Minimum Support Device) is 25 (Android 7.1 Nougat).
|
||||
const val targetSdk = 35 // Target SDK (Maximum Support Device) is 34 (Android 14).
|
||||
const val targetSdk = 36 // Target SDK (Maximum Support Device) is 36 (Android 16).
|
||||
|
||||
val javaVersion = JavaVersion.VERSION_17
|
||||
|
||||
|
@ -16,7 +16,7 @@ object Versions {
|
||||
|
||||
const val org_jetbrains_kotlinx_kotlinx_coroutines: String = "1.10.1"
|
||||
|
||||
const val kotlinx_coroutines_rx3: String = "1.3.9"
|
||||
const val kotlinx_coroutines_rx3: String = "1.10.1"
|
||||
|
||||
const val androidx_test_espresso: String = "3.6.1"
|
||||
|
||||
@ -40,7 +40,7 @@ object Versions {
|
||||
|
||||
const val androidx_test_core: String = "1.6.1"
|
||||
|
||||
const val androidx_test_orchestrator: String = "1.5.0"
|
||||
const val androidx_test_orchestrator: String = "1.5.1"
|
||||
|
||||
const val io_objectbox: String = "4.0.3"
|
||||
|
||||
@ -48,7 +48,7 @@ object Versions {
|
||||
|
||||
const val android_arch_lifecycle_extensions: String = "1.1.1"
|
||||
|
||||
const val com_android_tools_build_gradle: String = "8.7.2"
|
||||
const val com_android_tools_build_gradle: String = "8.11.0-alpha03"
|
||||
|
||||
const val de_fayard_buildsrcversions_gradle_plugin: String = "0.7.0"
|
||||
|
||||
@ -58,7 +58,7 @@ object Versions {
|
||||
|
||||
const val leakcanary_android: String = "2.14"
|
||||
|
||||
const val constraintlayout: String = "2.1.4"
|
||||
const val constraintlayout: String = "2.2.0"
|
||||
|
||||
const val swipe_refresh_layout: String = "1.1.0"
|
||||
|
||||
|
@ -24,7 +24,7 @@ import org.json.simple.JSONObject
|
||||
import org.json.simple.parser.JSONParser
|
||||
import java.io.File
|
||||
|
||||
typealias ProductFlavors = NamedDomainObjectContainer<ProductFlavor>
|
||||
typealias ProductFlavors = NamedDomainObjectContainer<out ProductFlavor>
|
||||
|
||||
object CustomApps {
|
||||
|
||||
|
@ -58,6 +58,7 @@ class AllProjectConfigurer {
|
||||
if (isLibrary) {
|
||||
namespace = "org.kiwix.kiwixmobile.core"
|
||||
}
|
||||
|
||||
setCompileSdkVersion(Config.compileSdk)
|
||||
defaultConfig {
|
||||
minSdk = Config.minSdk
|
||||
@ -161,6 +162,9 @@ class AllProjectConfigurer {
|
||||
add("UnusedResources")
|
||||
add("NonConstantResourceId")
|
||||
add("NotifyDataSetChanged")
|
||||
add("Aligned16KB") // TODO Remove when properly migrated to Android 16.
|
||||
add("AndroidGradlePluginVersion")
|
||||
add("MemberExtensionConflict")
|
||||
}
|
||||
lintConfig = target.rootProject.file("lintConfig.xml")
|
||||
}
|
||||
|
@ -21,6 +21,10 @@
|
||||
# Enable Wi-Fi on the emulator
|
||||
adb shell svc wifi enable
|
||||
adb logcat -c
|
||||
# Check if the stylus_handwriting_enabled setting exists before disabling
|
||||
if adb shell settings list secure | grep -q "stylus_handwriting_enabled"; then
|
||||
adb shell settings put secure stylus_handwriting_enabled 0
|
||||
fi
|
||||
# shellcheck disable=SC2035
|
||||
adb logcat *:E -v color &
|
||||
|
||||
@ -61,6 +65,10 @@ while [ $retry -le 3 ]; do
|
||||
# Enable Wi-Fi on the emulator
|
||||
adb shell svc wifi enable
|
||||
adb logcat -c
|
||||
# Check if the stylus_handwriting_enabled setting exists before disabling
|
||||
if adb shell settings list secure | grep -q "stylus_handwriting_enabled"; then
|
||||
adb shell settings put secure stylus_handwriting_enabled 0
|
||||
fi
|
||||
# shellcheck disable=SC2035
|
||||
adb logcat *:E -v color &
|
||||
|
||||
|
@ -3,6 +3,10 @@
|
||||
# Enable Wi-Fi on the emulator
|
||||
adb shell svc wifi enable
|
||||
adb logcat -c
|
||||
# Check if the stylus_handwriting_enabled setting exists before disabling
|
||||
if adb shell settings list secure | grep -q "stylus_handwriting_enabled"; then
|
||||
adb shell settings put secure stylus_handwriting_enabled 0
|
||||
fi
|
||||
# shellcheck disable=SC2035
|
||||
adb logcat *:E -v color &
|
||||
|
||||
@ -42,6 +46,10 @@ while [ $retry -le 3 ]; do
|
||||
# Enable Wi-Fi on the emulator
|
||||
adb shell svc wifi enable
|
||||
adb logcat -c
|
||||
# Check if the stylus_handwriting_enabled setting exists before disabling
|
||||
if adb shell settings list secure | grep -q "stylus_handwriting_enabled"; then
|
||||
adb shell settings put secure stylus_handwriting_enabled 0
|
||||
fi
|
||||
# shellcheck disable=SC2035
|
||||
adb logcat *:E -v color &
|
||||
|
||||
|
@ -3,6 +3,10 @@
|
||||
# Enable Wi-Fi on the emulator
|
||||
adb shell svc wifi enable
|
||||
adb logcat -c
|
||||
# Check if the stylus_handwriting_enabled setting exists before disabling
|
||||
if adb shell settings list secure | grep -q "stylus_handwriting_enabled"; then
|
||||
adb shell settings put secure stylus_handwriting_enabled 0
|
||||
fi
|
||||
# shellcheck disable=SC2035
|
||||
adb logcat *:E -v color &
|
||||
|
||||
@ -42,6 +46,10 @@ while [ $retry -le 3 ]; do
|
||||
# Enable Wi-Fi on the emulator
|
||||
adb shell svc wifi enable
|
||||
adb logcat -c
|
||||
# Check if the stylus_handwriting_enabled setting exists before disabling
|
||||
if adb shell settings list secure | grep -q "stylus_handwriting_enabled"; then
|
||||
adb shell settings put secure stylus_handwriting_enabled 0
|
||||
fi
|
||||
# shellcheck disable=SC2035
|
||||
adb logcat *:E -v color &
|
||||
|
||||
|
@ -3,6 +3,10 @@
|
||||
# Enable Wi-Fi on the emulator
|
||||
adb shell svc wifi enable
|
||||
adb logcat -c
|
||||
# Check if the stylus_handwriting_enabled setting exists before disabling
|
||||
if adb shell settings list secure | grep -q "stylus_handwriting_enabled"; then
|
||||
adb shell settings put secure stylus_handwriting_enabled 0
|
||||
fi
|
||||
# shellcheck disable=SC2035
|
||||
adb logcat *:E -v color &
|
||||
|
||||
@ -43,6 +47,10 @@ while [ $retry -le 3 ]; do
|
||||
# Enable Wi-Fi on the emulator
|
||||
adb shell svc wifi enable
|
||||
adb logcat -c
|
||||
# Check if the stylus_handwriting_enabled setting exists before disabling
|
||||
if adb shell settings list secure | grep -q "stylus_handwriting_enabled"; then
|
||||
adb shell settings put secure stylus_handwriting_enabled 0
|
||||
fi
|
||||
# shellcheck disable=SC2035
|
||||
adb logcat *:E -v color &
|
||||
|
||||
|
@ -20,6 +20,7 @@ apply(plugin = "io.objectbox")
|
||||
android {
|
||||
defaultConfig {
|
||||
buildConfigField("long", "VERSION_CODE", "".getVersionCode().toString())
|
||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
buildTypes {
|
||||
getByName("release") {
|
||||
|
@ -52,12 +52,13 @@
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:dataExtractionRules="@xml/data_extraction_rules"
|
||||
android:enableOnBackInvokedCallback="false"
|
||||
android:fullBackupContent="@xml/backup_rules"
|
||||
android:hardwareAccelerated="true"
|
||||
android:hasFragileUserData="true"
|
||||
android:largeHeap="true"
|
||||
android:requestLegacyExternalStorage="true"
|
||||
android:resizeableActivity="true"
|
||||
android:hasFragileUserData="true"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/KiwixTheme"
|
||||
tools:targetApi="tiramisu">
|
||||
@ -91,6 +92,7 @@
|
||||
<activity
|
||||
android:name=".error.DiagnosticReportActivity"
|
||||
android:exported="false" />
|
||||
|
||||
<service android:name=".read_aloud.ReadAloudService" />
|
||||
<service
|
||||
android:name=".downloader.downloadManager.DownloadMonitorService"
|
||||
|
@ -23,6 +23,7 @@ import android.content.pm.PackageInfo
|
||||
import android.content.pm.PackageManager
|
||||
import android.content.pm.ResolveInfo
|
||||
import android.net.ConnectivityManager
|
||||
import java.util.Locale
|
||||
|
||||
/**
|
||||
* This interface defines a set of functions that are not available on all platforms.
|
||||
@ -76,4 +77,6 @@ interface Compat {
|
||||
fun isNetworkAvailable(connectivity: ConnectivityManager): Boolean
|
||||
|
||||
fun isWifi(connectivity: ConnectivityManager): Boolean
|
||||
|
||||
fun convertToLocal(language: String): Locale
|
||||
}
|
||||
|
@ -28,7 +28,8 @@ import android.os.Build
|
||||
class CompatHelper private constructor() {
|
||||
// Note: Needs ": Compat" or the type system assumes `Compat21`
|
||||
private val compatValue: Compat = when {
|
||||
sdkVersion >= Build.VERSION_CODES.TIRAMISU -> CompatV33()
|
||||
Build.VERSION.SDK_INT >= Build.VERSION_CODES.BAKLAVA -> CompatV36()
|
||||
Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU -> CompatV33()
|
||||
else -> CompatV25()
|
||||
}
|
||||
|
||||
@ -36,10 +37,6 @@ class CompatHelper private constructor() {
|
||||
/** Singleton instance of [CompatHelper] */
|
||||
private val instance by lazy(::CompatHelper)
|
||||
|
||||
/** Get the current Android API level. */
|
||||
val sdkVersion: Int
|
||||
get() = Build.VERSION.SDK_INT
|
||||
|
||||
val compat get() = instance.compatValue
|
||||
|
||||
/**
|
||||
@ -79,5 +76,7 @@ class CompatHelper private constructor() {
|
||||
|
||||
fun ConnectivityManager.isWifi(): Boolean =
|
||||
compat.isWifi(this)
|
||||
|
||||
fun String.convertToLocal() = compat.convertToLocal(this)
|
||||
}
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ import android.content.pm.ResolveInfo
|
||||
import android.net.ConnectivityManager
|
||||
import android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET
|
||||
import android.net.NetworkCapabilities.TRANSPORT_WIFI
|
||||
import java.util.Locale
|
||||
|
||||
open class CompatV25 : Compat {
|
||||
override fun queryIntentActivities(
|
||||
@ -61,4 +62,6 @@ open class CompatV25 : Compat {
|
||||
return connectivity.getNetworkCapabilities(connectivity.activeNetwork)
|
||||
?.hasTransport(TRANSPORT_WIFI) == true
|
||||
}
|
||||
|
||||
override fun convertToLocal(language: String): Locale = Locale(language)
|
||||
}
|
||||
|
@ -18,17 +18,17 @@
|
||||
|
||||
package org.kiwix.kiwixmobile.core.compat
|
||||
|
||||
import android.annotation.TargetApi
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageInfo
|
||||
import android.content.pm.PackageManager
|
||||
import android.content.pm.PackageManager.PackageInfoFlags
|
||||
import android.content.pm.ResolveInfo
|
||||
import android.net.ConnectivityManager
|
||||
import android.os.Build.VERSION_CODES.TIRAMISU
|
||||
import androidx.annotation.RequiresApi
|
||||
import java.util.Locale
|
||||
|
||||
const val API_33 = 33
|
||||
|
||||
@TargetApi(API_33)
|
||||
@RequiresApi(TIRAMISU)
|
||||
open class CompatV33 : Compat {
|
||||
private val compatV25 = CompatV25()
|
||||
override fun queryIntentActivities(
|
||||
@ -52,4 +52,6 @@ open class CompatV33 : Compat {
|
||||
|
||||
override fun isWifi(connectivity: ConnectivityManager): Boolean =
|
||||
compatV25.isWifi(connectivity)
|
||||
|
||||
override fun convertToLocal(language: String): Locale = compatV25.convertToLocal(language)
|
||||
}
|
||||
|
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Kiwix Android
|
||||
* Copyright (c) 2025 Kiwix <android.kiwix.org>
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.kiwix.kiwixmobile.core.compat
|
||||
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageInfo
|
||||
import android.content.pm.PackageManager
|
||||
import android.content.pm.ResolveInfo
|
||||
import android.net.ConnectivityManager
|
||||
import android.os.Build.VERSION_CODES.BAKLAVA
|
||||
import androidx.annotation.RequiresApi
|
||||
import java.util.Locale
|
||||
|
||||
@RequiresApi(BAKLAVA)
|
||||
open class CompatV36 : Compat {
|
||||
private val compatV33 = CompatV33()
|
||||
override fun queryIntentActivities(
|
||||
packageManager: PackageManager,
|
||||
intent: Intent,
|
||||
flags: ResolveInfoFlagsCompat
|
||||
): List<ResolveInfo> = compatV33.queryIntentActivities(packageManager, intent, flags)
|
||||
|
||||
override fun getPackageInformation(
|
||||
packageName: String,
|
||||
packageManager: PackageManager,
|
||||
flag: Int
|
||||
): PackageInfo =
|
||||
compatV33.getPackageInformation(packageName, packageManager, flag)
|
||||
|
||||
override fun isNetworkAvailable(connectivity: ConnectivityManager): Boolean =
|
||||
compatV33.isNetworkAvailable(connectivity)
|
||||
|
||||
override fun isWifi(connectivity: ConnectivityManager): Boolean =
|
||||
compatV33.isWifi(connectivity)
|
||||
|
||||
override fun convertToLocal(language: String): Locale = Locale.of(language)
|
||||
}
|
@ -22,6 +22,7 @@ import io.objectbox.annotation.Convert
|
||||
import io.objectbox.annotation.Entity
|
||||
import io.objectbox.annotation.Id
|
||||
import io.objectbox.converter.PropertyConverter
|
||||
import org.kiwix.kiwixmobile.core.compat.CompatHelper.Companion.convertToLocal
|
||||
import org.kiwix.kiwixmobile.core.zim_manager.Language
|
||||
import java.util.Locale
|
||||
|
||||
@ -35,7 +36,7 @@ data class LanguageEntity(
|
||||
) {
|
||||
constructor(language: Language) : this(
|
||||
0,
|
||||
Locale(language.languageCode),
|
||||
language.languageCode.convertToLocal(),
|
||||
language.active,
|
||||
language.occurencesOfLanguage
|
||||
)
|
||||
@ -49,5 +50,5 @@ class StringToLocaleConverter : PropertyConverter<Locale, String> {
|
||||
entityProperty?.isO3Language ?: Locale.ENGLISH.isO3Language
|
||||
|
||||
override fun convertToEntityProperty(databaseValue: String?): Locale =
|
||||
databaseValue?.let(::Locale) ?: Locale.ENGLISH
|
||||
databaseValue?.convertToLocal() ?: Locale.ENGLISH
|
||||
}
|
||||
|
@ -33,6 +33,9 @@ import android.util.TypedValue
|
||||
import android.widget.Toast
|
||||
import androidx.annotation.AttrRes
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.graphics.createBitmap
|
||||
import androidx.core.graphics.drawable.toDrawable
|
||||
import androidx.core.graphics.scale
|
||||
import org.kiwix.kiwixmobile.core.base.BaseBroadcastReceiver
|
||||
import java.util.Locale
|
||||
|
||||
@ -87,14 +90,9 @@ fun Context.getResizedDrawable(resourceId: Int, width: Int, height: Int): Drawab
|
||||
val drawable = ContextCompat.getDrawable(this, resourceId)
|
||||
|
||||
return if (drawable != null) {
|
||||
val bitmap = Bitmap.createScaledBitmap(
|
||||
getBitmapFromDrawable(drawable),
|
||||
width,
|
||||
height,
|
||||
false
|
||||
)
|
||||
val bitmap = getBitmapFromDrawable(drawable).scale(width, height, false)
|
||||
|
||||
BitmapDrawable(resources, bitmap).apply {
|
||||
bitmap.toDrawable(resources).apply {
|
||||
bounds = drawable.bounds
|
||||
}
|
||||
} else {
|
||||
@ -107,11 +105,7 @@ fun Context.getBitmapFromDrawable(drawable: Drawable): Bitmap {
|
||||
return drawable.bitmap
|
||||
}
|
||||
|
||||
val bitmap = Bitmap.createBitmap(
|
||||
drawable.intrinsicWidth,
|
||||
drawable.intrinsicHeight,
|
||||
Bitmap.Config.ARGB_8888
|
||||
)
|
||||
val bitmap = createBitmap(drawable.intrinsicWidth, drawable.intrinsicHeight)
|
||||
val canvas = Canvas(bitmap)
|
||||
drawable.setBounds(0, 0, canvas.width, canvas.height)
|
||||
drawable.draw(canvas)
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
package org.kiwix.kiwixmobile.core.extensions
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.view.ViewGroup.LayoutParams
|
||||
import android.widget.EditText
|
||||
@ -29,6 +30,7 @@ import org.kiwix.kiwixmobile.core.R
|
||||
|
||||
const val CLOSE_ICON_PADDING = 30
|
||||
|
||||
@SuppressLint("PrivateResource")
|
||||
fun SearchView.setUpSearchView(context: Context) {
|
||||
val heightAndWidth = context.resources.getDimensionPixelSize(
|
||||
R.dimen.material_minimum_height_and_width
|
||||
|
@ -72,6 +72,7 @@ import androidx.constraintlayout.widget.Group
|
||||
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
import androidx.core.app.ActivityCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.content.edit
|
||||
import androidx.core.net.toUri
|
||||
import androidx.core.view.GravityCompat
|
||||
import androidx.core.view.MenuHost
|
||||
@ -2516,7 +2517,6 @@ abstract class CoreReaderFragment :
|
||||
SharedPreferenceUtil.PREF_KIWIX_MOBILE,
|
||||
0
|
||||
)
|
||||
val editor = settings.edit()
|
||||
val webViewHistoryEntityList = arrayListOf<WebViewHistoryEntity>()
|
||||
webViewList.forEachIndexed { index, view ->
|
||||
if (view.url == null) return@forEachIndexed
|
||||
@ -2525,9 +2525,10 @@ abstract class CoreReaderFragment :
|
||||
withContext(Dispatchers.IO) {
|
||||
repositoryActions?.saveWebViewPageHistory(webViewHistoryEntityList)
|
||||
}
|
||||
editor.putString(TAG_CURRENT_FILE, zimReaderContainer?.zimReaderSource?.toDatabase())
|
||||
editor.putInt(TAG_CURRENT_TAB, currentWebViewIndex)
|
||||
editor.apply()
|
||||
settings.edit {
|
||||
putString(TAG_CURRENT_FILE, zimReaderContainer?.zimReaderSource?.toDatabase())
|
||||
putInt(TAG_CURRENT_TAB, currentWebViewIndex)
|
||||
}
|
||||
Log.d(
|
||||
TAG_KIWIX,
|
||||
"Save current zim file to preferences: " +
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
package org.kiwix.kiwixmobile.core.qr
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.Color
|
||||
import com.google.zxing.BarcodeFormat
|
||||
@ -39,6 +40,7 @@ class GenerateQR @Inject constructor() {
|
||||
* @param foregroundColor The color of the QR code.
|
||||
* @param backgroundColor The background color of the QR code.
|
||||
*/
|
||||
@SuppressLint("UseKtx")
|
||||
fun createQR(
|
||||
code: String,
|
||||
size: Int = 512,
|
||||
|
@ -46,6 +46,7 @@ import org.kiwix.kiwixmobile.core.CoreApp.Companion.coreComponent
|
||||
import org.kiwix.kiwixmobile.core.CoreApp.Companion.instance
|
||||
import org.kiwix.kiwixmobile.core.DarkModeConfig
|
||||
import org.kiwix.kiwixmobile.core.R
|
||||
import org.kiwix.kiwixmobile.core.compat.CompatHelper.Companion.convertToLocal
|
||||
import org.kiwix.kiwixmobile.core.compat.CompatHelper.Companion.getPackageInformation
|
||||
import org.kiwix.kiwixmobile.core.compat.CompatHelper.Companion.getVersionCode
|
||||
import org.kiwix.kiwixmobile.core.dao.LibkiwixBookmarks
|
||||
@ -169,9 +170,7 @@ abstract class CorePrefsFragment :
|
||||
if (selectedLang == Locale.ROOT.toString()) {
|
||||
getString(R.string.device_default)
|
||||
} else {
|
||||
Locale(
|
||||
selectedLang
|
||||
).displayLanguage
|
||||
selectedLang.convertToLocal().displayLanguage
|
||||
}
|
||||
languagePref.onPreferenceChangeListener =
|
||||
Preference.OnPreferenceChangeListener { _, newValue ->
|
||||
@ -206,7 +205,7 @@ abstract class CorePrefsFragment :
|
||||
val entries = arrayOfNulls<String>(languageCodeList.size)
|
||||
entries[0] = getString(R.string.device_default)
|
||||
for (i in 1 until languageCodeList.size) {
|
||||
val locale = Locale(languageCodeList[i])
|
||||
val locale = languageCodeList[i].convertToLocal()
|
||||
entries[i] = locale.displayLanguage + " (" + locale.getDisplayLanguage(locale) + ") "
|
||||
}
|
||||
return entries
|
||||
@ -389,7 +388,7 @@ abstract class CorePrefsFragment :
|
||||
}
|
||||
try {
|
||||
fileSelectLauncher.launch(Intent.createChooser(intent, "Select a bookmark file"))
|
||||
} catch (ex: ActivityNotFoundException) {
|
||||
} catch (_: ActivityNotFoundException) {
|
||||
activity.toast(
|
||||
resources.getString(R.string.no_app_found_to_select_bookmark_file),
|
||||
Toast.LENGTH_SHORT
|
||||
|
@ -17,13 +17,15 @@
|
||||
*/
|
||||
package org.kiwix.kiwixmobile.core.utils
|
||||
|
||||
import org.kiwix.kiwixmobile.core.compat.CompatHelper.Companion.convertToLocal
|
||||
import java.util.Locale
|
||||
|
||||
/**
|
||||
* Created by mhutti1 on 19/04/17.
|
||||
*/
|
||||
class BookUtils {
|
||||
val localeMap = Locale.getISOLanguages().map(::Locale).associateBy { it.isO3Language }
|
||||
val localeMap =
|
||||
Locale.getISOLanguages().map { it.convertToLocal() }.associateBy { it.isO3Language }
|
||||
|
||||
// Get the language from the language codes of the parsed xml stream
|
||||
@Suppress("MagicNumber")
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
package org.kiwix.kiwixmobile.core.utils
|
||||
|
||||
import org.kiwix.kiwixmobile.core.compat.CompatHelper.Companion.convertToLocal
|
||||
import java.util.Locale
|
||||
|
||||
class LanguageContainer private constructor(val languageCode: String, val languageName: String) {
|
||||
@ -25,7 +26,7 @@ class LanguageContainer private constructor(val languageCode: String, val langua
|
||||
|
||||
companion object {
|
||||
private fun chooseLanguageName(languageCode: String): String {
|
||||
val displayLanguage = Locale(languageCode).displayLanguage
|
||||
val displayLanguage = languageCode.convertToLocal().displayLanguage
|
||||
return if (displayLanguage.length == 2 || displayLanguage.isEmpty()) {
|
||||
Locale.ENGLISH.displayLanguage
|
||||
} else {
|
||||
|
@ -21,6 +21,7 @@ import android.content.Context
|
||||
import android.content.ContextWrapper
|
||||
import android.content.SharedPreferences
|
||||
import android.os.Build
|
||||
import androidx.annotation.ChecksSdkIntAtLeast
|
||||
import androidx.appcompat.app.AppCompatDelegate
|
||||
import androidx.core.content.edit
|
||||
import androidx.preference.PreferenceManager
|
||||
@ -136,9 +137,6 @@ class SharedPreferenceUtil @Inject constructor(val context: Context) {
|
||||
ContextWrapper(context).externalMediaDirs[0]?.path
|
||||
?: context.filesDir.path // a workaround for emulators
|
||||
|
||||
fun getPrefStorageTitle(defaultTitle: String): String =
|
||||
sharedPreferences.getString(PREF_STORAGE_TITLE, defaultTitle) ?: defaultTitle
|
||||
|
||||
fun putPrefBookMarkMigrated(isMigrated: Boolean) =
|
||||
sharedPreferences.edit { putBoolean(PREF_BOOKMARKS_MIGRATED, isMigrated) }
|
||||
|
||||
@ -168,9 +166,6 @@ class SharedPreferenceUtil @Inject constructor(val context: Context) {
|
||||
_prefWifiOnlys.onNext(wifiOnly)
|
||||
}
|
||||
|
||||
fun putPrefStorageTitle(storageTitle: String) =
|
||||
sharedPreferences.edit { putString(PREF_STORAGE_TITLE, storageTitle) }
|
||||
|
||||
fun putPrefStorage(storage: String) {
|
||||
sharedPreferences.edit { putString(PREF_STORAGE, storage) }
|
||||
_prefStorages.onNext(storage)
|
||||
@ -294,9 +289,11 @@ class SharedPreferenceUtil @Inject constructor(val context: Context) {
|
||||
path.substringBefore(context.getString(R.string.android_directory_seperator))
|
||||
}
|
||||
|
||||
@ChecksSdkIntAtLeast(api = Build.VERSION_CODES.R)
|
||||
fun isPlayStoreBuildWithAndroid11OrAbove(): Boolean =
|
||||
isPlayStoreBuild && Build.VERSION.SDK_INT >= Build.VERSION_CODES.R
|
||||
|
||||
@ChecksSdkIntAtLeast(api = Build.VERSION_CODES.R)
|
||||
fun isNotPlayStoreBuildWithAndroid11OrAbove(): Boolean =
|
||||
!isPlayStoreBuild && Build.VERSION.SDK_INT >= Build.VERSION_CODES.R
|
||||
|
||||
@ -316,7 +313,6 @@ class SharedPreferenceUtil @Inject constructor(val context: Context) {
|
||||
private const val PREF_BACK_TO_TOP = "pref_backtotop"
|
||||
private const val PREF_FULLSCREEN = "pref_fullscreen"
|
||||
private const val PREF_NEW_TAB_BACKGROUND = "pref_newtab_background"
|
||||
private const val PREF_STORAGE_TITLE = "pref_selected_title"
|
||||
const val PREF_EXTERNAL_LINK_POPUP = "pref_external_link_popup"
|
||||
const val PREF_SHOW_STORAGE_OPTION = "show_storgae_option"
|
||||
private const val PREF_IS_FIRST_RUN = "isFirstRun"
|
||||
|
@ -1,38 +0,0 @@
|
||||
/*
|
||||
* Kiwix Android
|
||||
* Copyright (c) 2020 Kiwix <android.kiwix.org>
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.kiwix.kiwixmobile.core.utils
|
||||
|
||||
import android.text.Editable
|
||||
import android.text.TextWatcher
|
||||
|
||||
class SimpleTextWatcher(
|
||||
private val onTextWatcherChangeAction: (CharSequence?, Int, Int, Int) -> Unit
|
||||
) : TextWatcher {
|
||||
@SuppressWarnings("EmptyFunctionBlock")
|
||||
override fun afterTextChanged(p0: Editable?) {
|
||||
}
|
||||
|
||||
@SuppressWarnings("EmptyFunctionBlock")
|
||||
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
|
||||
}
|
||||
|
||||
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
|
||||
onTextWatcherChangeAction.invoke(s, start, before, count)
|
||||
}
|
||||
}
|
@ -20,6 +20,7 @@ package org.kiwix.kiwixmobile.core.zim_manager
|
||||
|
||||
import android.os.Parcelable
|
||||
import kotlinx.parcelize.Parcelize
|
||||
import org.kiwix.kiwixmobile.core.compat.CompatHelper.Companion.convertToLocal
|
||||
import java.util.Locale
|
||||
|
||||
@Parcelize
|
||||
@ -51,7 +52,7 @@ data class Language constructor(
|
||||
languageCode: String,
|
||||
active: Boolean,
|
||||
occurrencesOfLanguage: Int
|
||||
) : this(Locale(languageCode), active, occurrencesOfLanguage)
|
||||
) : this(languageCode.convertToLocal(), active, occurrencesOfLanguage)
|
||||
|
||||
override fun equals(other: Any?): Boolean =
|
||||
(other as Language).language == language && other.active == active
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
package org.kiwix.kiwixmobile.core.zim_manager.fileselect_view
|
||||
|
||||
import org.kiwix.kiwixmobile.core.compat.CompatHelper.Companion.convertToLocal
|
||||
import org.kiwix.kiwixmobile.core.dao.entities.BookOnDiskEntity
|
||||
import org.kiwix.kiwixmobile.core.dao.entities.DownloadRoomEntity
|
||||
import org.kiwix.kiwixmobile.core.entity.LibraryNetworkEntity
|
||||
@ -50,7 +51,7 @@ sealed class BooksOnDiskListItem {
|
||||
override val id: Long = databaseId
|
||||
) : BooksOnDiskListItem() {
|
||||
val locale: Locale by lazy {
|
||||
Locale(book.language)
|
||||
book.language.convertToLocal()
|
||||
}
|
||||
|
||||
constructor(bookOnDiskEntity: BookOnDiskEntity) : this(
|
||||
|
@ -1,5 +0,0 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="48dp" android:tint="#000000" android:viewportHeight="24" android:viewportWidth="24" android:width="48dp">
|
||||
|
||||
<path android:fillColor="@android:color/white" android:pathData="M15,21h-2v-2h2V21zM13,14h-2v5h2V14zM21,12h-2v4h2V12zM19,10h-2v2h2V10zM7,12H5v2h2V12zM5,10H3v2h2V10zM12,5h2V3h-2V5zM4.5,4.5v3h3v-3H4.5zM9,9H3V3h6V9zM4.5,16.5v3h3v-3H4.5zM9,21H3v-6h6V21zM16.5,4.5v3h3v-3H16.5zM21,9h-6V3h6V9zM19,19v-3l-4,0v2h2v3h4v-2H19zM17,12l-4,0v2h4V12zM13,10H7v2h2v2h2v-2h2V10zM14,9V7h-2V5h-2v4L14,9zM6.75,5.25h-1.5v1.5h1.5V5.25zM6.75,17.25h-1.5v1.5h1.5V17.25zM18.75,5.25h-1.5v1.5h1.5V5.25z"/>
|
||||
|
||||
</vector>
|
@ -1,17 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/header_language"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/activity_horizontal_margin"
|
||||
android:textAppearance="?textAppearanceSubtitle1"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="English" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
@ -1,130 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/card_margin">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.constraintlayout.widget.Guideline
|
||||
android:id="@+id/horizontal_padding"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintGuide_begin="@dimen/activity_horizontal_margin" />
|
||||
|
||||
<androidx.constraintlayout.widget.Guideline
|
||||
android:id="@+id/vertical_padding"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
app:layout_constraintGuide_begin="@dimen/activity_vertical_margin" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/itemBookCheckbox"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingEnd="10dp"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="@+id/horizontal_padding"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:ignore="RtlSymmetry" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/item_book_icon"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:contentDescription="@string/fav_icon"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/itemBookCheckbox"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:src="@mipmap/ic_launcher_round" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/item_book_title"
|
||||
style="@style/list_item_title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/activity_horizontal_margin"
|
||||
android:layout_marginEnd="@dimen/activity_horizontal_margin"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/item_book_icon"
|
||||
app:layout_constraintTop_toBottomOf="@+id/vertical_padding"
|
||||
tools:text="Wikipedia" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/item_book_description"
|
||||
style="@style/list_item_body"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="2"
|
||||
android:textColor="?textSecondary"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="@id/item_book_title"
|
||||
app:layout_constraintTop_toBottomOf="@id/item_book_title"
|
||||
tools:text="All wikipedia articles" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/item_book_date"
|
||||
style="@style/list_item_body"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="?textTertiary"
|
||||
app:layout_constraintStart_toStartOf="@id/item_book_title"
|
||||
app:layout_constraintTop_toBottomOf="@id/item_book_description"
|
||||
tools:text="1 Jan 2018" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/item_book_size"
|
||||
style="@style/list_item_body"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/activity_horizontal_margin"
|
||||
android:layout_marginEnd="@dimen/activity_horizontal_margin"
|
||||
android:textColor="?textTertiary"
|
||||
app:layout_constraintStart_toEndOf="@id/item_book_date"
|
||||
app:layout_constraintTop_toTopOf="@id/item_book_date"
|
||||
tools:text="20 GB" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/item_book_article_count"
|
||||
style="@style/list_item_body"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/activity_horizontal_margin"
|
||||
android:layout_marginEnd="@dimen/activity_horizontal_margin"
|
||||
android:textColor="?textTertiary"
|
||||
app:layout_constraintStart_toEndOf="@id/item_book_size"
|
||||
app:layout_constraintTop_toTopOf="@id/item_book_size"
|
||||
tools:text="10.1 K articles" />
|
||||
|
||||
<org.kiwix.kiwixmobile.core.zim_manager.TagsView
|
||||
android:id="@+id/tags"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="@+id/item_book_description"
|
||||
app:layout_constraintTop_toBottomOf="@id/item_book_date" />
|
||||
|
||||
<View
|
||||
android:id="@+id/item_book_clickable_area"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
android:contentDescription="@string/zim_file_content_description"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:visibility="gone" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</com.google.android.material.card.MaterialCardView>
|
@ -1,23 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<item
|
||||
android:id="@+id/delete_note"
|
||||
android:icon="@drawable/ic_delete_white_24dp"
|
||||
android:title="@string/delete"
|
||||
app:showAsAction="ifRoom" />
|
||||
|
||||
<item
|
||||
android:id="@+id/share_note"
|
||||
android:icon="@drawable/baseline_share_24"
|
||||
android:title="@string/share"
|
||||
app:showAsAction="ifRoom" />
|
||||
|
||||
<item
|
||||
android:id="@+id/save_note"
|
||||
android:icon="@drawable/ic_save"
|
||||
android:title="@string/save"
|
||||
app:showAsAction="ifRoom" />
|
||||
|
||||
</menu>
|
@ -91,7 +91,9 @@ internal class NewBookDaoTest {
|
||||
}
|
||||
}
|
||||
|
||||
private fun expectEmissionOfExistingAndNotExistingBook(isInTrashFolder: Boolean = false): Pair<BookOnDiskEntity, BookOnDiskEntity> {
|
||||
private fun expectEmissionOfExistingAndNotExistingBook(
|
||||
isInTrashFolder: Boolean = false
|
||||
): Pair<BookOnDiskEntity, BookOnDiskEntity> {
|
||||
val query: Query<BookOnDiskEntity> = mockk()
|
||||
every { box.query().build() } returns query
|
||||
val zimReaderSourceThatExists = mockk<ZimReaderSource>()
|
||||
|
@ -18,17 +18,17 @@
|
||||
|
||||
package org.kiwix.kiwixmobile.core.dao
|
||||
|
||||
import org.junit.jupiter.api.Test
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import io.mockk.verify
|
||||
import io.objectbox.Box
|
||||
import io.objectbox.query.Query
|
||||
import io.objectbox.query.QueryBuilder
|
||||
import org.kiwix.kiwixmobile.core.dao.entities.BookmarkEntity_
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.kiwix.kiwixmobile.core.dao.entities.BookmarkEntity
|
||||
import org.kiwix.kiwixmobile.core.page.bookmark
|
||||
import org.kiwix.kiwixmobile.core.dao.entities.BookmarkEntity_
|
||||
import org.kiwix.kiwixmobile.core.page.adapter.Page
|
||||
import org.kiwix.kiwixmobile.core.page.bookmark
|
||||
import org.kiwix.kiwixmobile.core.page.bookmark.adapter.BookmarkItem
|
||||
import org.kiwix.kiwixmobile.core.reader.ZimFileReader
|
||||
|
||||
@ -69,7 +69,6 @@ internal class NewBookmarksDaoTest {
|
||||
every { bookmarkItem.zimName } returns ""
|
||||
every { bookmarkItem.databaseId } returns 0L
|
||||
newBookmarksDao.getCurrentZimBookmarksUrl(zimFileReader)
|
||||
val bookmarkEntity: BookmarkEntity = mockk()
|
||||
every {
|
||||
query.property(BookmarkEntity_.bookmarkUrl).findStrings().toList().distinct()
|
||||
} returns listOf("")
|
||||
|
@ -27,13 +27,12 @@ class MetaLinkNetworkEntityTest {
|
||||
@Throws(Exception::class)
|
||||
fun testDeserialize() {
|
||||
val serializer = Persister()
|
||||
val result =
|
||||
serializer.read(
|
||||
MetaLinkNetworkEntity::class.java,
|
||||
MetaLinkNetworkEntityTest::class.java.classLoader!!.getResourceAsStream(
|
||||
"wikipedia_af_all_nopic_2016-05.zim.meta4"
|
||||
)
|
||||
val result = serializer.read(
|
||||
MetaLinkNetworkEntity::class.java,
|
||||
MetaLinkNetworkEntityTest::class.java.classLoader!!.getResourceAsStream(
|
||||
"wikipedia_af_all_nopic_2016-05.zim.meta4"
|
||||
)
|
||||
)
|
||||
result?.urls?.let {
|
||||
MetaLinkNetworkEntityUrlAssert(it).hasItems(
|
||||
listOf(
|
||||
@ -68,9 +67,7 @@ class MetaLinkNetworkEntityTest {
|
||||
}
|
||||
// Basic file attributes
|
||||
assertThat(result.file?.name).isEqualTo("wikipedia_af_all_nopic_2016-05.zim")
|
||||
|
||||
assertThat(result.file?.size).isEqualTo(63973123L)
|
||||
|
||||
// File hashes
|
||||
assertThat(result.file?.getHash("md5")).isEqualTo("6f06866b61c4a921b57f28cfd4307220")
|
||||
assertThat(
|
||||
@ -103,21 +100,17 @@ class MetaLinkNetworkEntityTest {
|
||||
*/
|
||||
class MetaLinkNetworkEntityUrlAssert(
|
||||
actual: List<MetaLinkNetworkEntity.Url>
|
||||
) :
|
||||
AbstractAssert<MetaLinkNetworkEntityUrlAssert, List<MetaLinkNetworkEntity.Url>>(
|
||||
actual,
|
||||
MetaLinkNetworkEntityUrlAssert::class.java
|
||||
) {
|
||||
) : AbstractAssert<MetaLinkNetworkEntityUrlAssert, List<MetaLinkNetworkEntity.Url>>(
|
||||
actual,
|
||||
MetaLinkNetworkEntityUrlAssert::class.java
|
||||
) {
|
||||
private fun <S, T> intersectionWith(
|
||||
first: List<S>,
|
||||
second: List<T>,
|
||||
function: (S, T) -> Boolean
|
||||
): Boolean {
|
||||
val filtered = first.filter { a -> second.any { b -> function(a, b) } }
|
||||
if (filtered.isNotEmpty()) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
return filtered.isNotEmpty()
|
||||
}
|
||||
|
||||
fun hasItems(items: List<DummyUrl>): Boolean {
|
||||
|
@ -43,8 +43,9 @@ internal class SearchStateTest {
|
||||
val estimatedMatches = 100
|
||||
every { suggestionSearchWrapper.estimatedMatches } returns estimatedMatches.toLong()
|
||||
// Settings list to hasNext() to ensure it returns true only for the first call.
|
||||
// Otherwise, if we do not set this, the method will always return true when checking if the iterator has a next value,
|
||||
// causing our test case to get stuck in an infinite loop due to this explicit setting.
|
||||
// Otherwise, if we do not set this, the method will always return true when
|
||||
// checking if the iterator has a next value, causing our test case to get stuck
|
||||
// in an infinite loop due to this explicit setting.
|
||||
every { searchIteratorWrapper.hasNext() } returnsMany listOf(true, false)
|
||||
every { searchIteratorWrapper.next() } returns entryWrapper
|
||||
every { entryWrapper.title } returns searchTerm
|
||||
@ -119,7 +120,8 @@ internal class SearchStateTest {
|
||||
every { entryWrapper.path } returns "path"
|
||||
every { suggestionSearchWrapper.getResults(any(), any()) } returns searchIteratorWrapper
|
||||
|
||||
val searchResultsWithTerm = SearchResultsWithTerm(searchTerm, suggestionSearchWrapper, mockk())
|
||||
val searchResultsWithTerm =
|
||||
SearchResultsWithTerm(searchTerm, suggestionSearchWrapper, mockk())
|
||||
val searchState = SearchState(searchTerm, searchResultsWithTerm, emptyList(), FromWebView)
|
||||
var list: List<SearchListItem.RecentSearchListItem>? = emptyList()
|
||||
var list1: List<SearchListItem.RecentSearchListItem>? = emptyList()
|
||||
|
@ -50,7 +50,6 @@ import org.kiwix.kiwixmobile.core.dao.RecentSearchRoomDao
|
||||
import org.kiwix.kiwixmobile.core.reader.ZimFileReader
|
||||
import org.kiwix.kiwixmobile.core.reader.ZimReaderContainer
|
||||
import org.kiwix.kiwixmobile.core.search.adapter.SearchListItem.RecentSearchListItem
|
||||
import org.kiwix.kiwixmobile.core.search.adapter.SearchListItem.ZimSearchResultListItem
|
||||
import org.kiwix.kiwixmobile.core.search.viewmodel.Action.ActivityResultReceived
|
||||
import org.kiwix.kiwixmobile.core.search.viewmodel.Action.ClickedSearchInText
|
||||
import org.kiwix.kiwixmobile.core.search.viewmodel.Action.ConfirmedDelete
|
||||
@ -123,7 +122,6 @@ internal class SearchViewModelTest {
|
||||
@Test
|
||||
fun `SearchState combines sources from inputs`() =
|
||||
runTest {
|
||||
val item = ZimSearchResultListItem("", "")
|
||||
val searchTerm = "searchTerm"
|
||||
val searchOrigin = FromWebView
|
||||
val suggestionSearch: SuggestionSearch = mockk()
|
||||
|
@ -21,7 +21,9 @@ package org.kiwix.kiwixmobile.core.search.viewmodel
|
||||
import org.kiwix.libzim.SuggestionIterator
|
||||
|
||||
class SuggestionIteratorWrapper : SuggestionIterator() {
|
||||
override fun remove() {}
|
||||
override fun remove() {
|
||||
// Do nothing just to ignore the EmptyFunctionBlock detekt error.
|
||||
}
|
||||
|
||||
override fun hasNext(): Boolean = super.hasNext()
|
||||
override fun next(): SuggestionItemWrapper = super.next() as SuggestionItemWrapper
|
||||
|
@ -4,16 +4,16 @@ import com.android.build.gradle.internal.dsl.ProductFlavor
|
||||
import custom.CustomApps
|
||||
import custom.createPublisher
|
||||
import custom.transactionWithCommit
|
||||
import plugin.KiwixConfigurationPlugin
|
||||
import java.net.URI
|
||||
import java.net.URLDecoder
|
||||
import java.util.Locale
|
||||
import java.util.Base64
|
||||
import java.io.FileOutputStream
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.Request
|
||||
import okhttp3.ResponseBody
|
||||
import plugin.KiwixConfigurationPlugin
|
||||
import java.io.FileNotFoundException
|
||||
import java.io.FileOutputStream
|
||||
import java.net.URI
|
||||
import java.net.URLDecoder
|
||||
import java.util.Base64
|
||||
import java.util.Locale
|
||||
|
||||
plugins {
|
||||
android
|
||||
@ -24,6 +24,7 @@ plugins.apply(KiwixConfigurationPlugin::class)
|
||||
android {
|
||||
defaultConfig {
|
||||
applicationId = "org.kiwix"
|
||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
|
||||
flavorDimensions += "default"
|
||||
@ -59,8 +60,8 @@ android {
|
||||
}
|
||||
}
|
||||
|
||||
fun ProductFlavor.createDownloadTask(file: File): Task {
|
||||
return tasks.create(
|
||||
fun ProductFlavor.createDownloadTask(file: File): TaskProvider<Task> {
|
||||
return tasks.register(
|
||||
"download${
|
||||
name.replaceFirstChar {
|
||||
if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else "$it"
|
||||
@ -156,8 +157,8 @@ fun writeZimFileDataInChunk(
|
||||
outputStream?.close()
|
||||
}
|
||||
|
||||
fun ProductFlavor.createDownloadTaskForPlayAssetDelivery(file: File): Task {
|
||||
return tasks.create(
|
||||
fun ProductFlavor.createDownloadTaskForPlayAssetDelivery(file: File): TaskProvider<Task> {
|
||||
return tasks.register(
|
||||
"download${
|
||||
name.replaceFirstChar {
|
||||
if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else "$it"
|
||||
@ -205,10 +206,10 @@ val String.removeAuthenticationFromUrl: String
|
||||
fun ProductFlavor.createPublishApkWithExpansionTask(
|
||||
file: File,
|
||||
applicationVariants: DomainObjectSet<ApplicationVariant>
|
||||
): Task {
|
||||
): TaskProvider<Task> {
|
||||
val capitalizedName =
|
||||
name.replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else "$it" }
|
||||
return tasks.create("publish${capitalizedName}ReleaseApkWithExpansionFile") {
|
||||
return tasks.register("publish${capitalizedName}ReleaseApkWithExpansionFile") {
|
||||
group = "publishing"
|
||||
description = "Uploads $capitalizedName to the Play Console with an Expansion file"
|
||||
doLast {
|
||||
@ -236,10 +237,10 @@ fun DomainObjectSet<ApplicationVariant>.releaseVariantsFor(productFlavor: Produc
|
||||
.filter { !it.outputFileName.contains("universal") }
|
||||
.sortedBy { it.versionCodeOverride }
|
||||
|
||||
fun ProductFlavor.createPublishBundleWithAssetPlayDelivery(): Task {
|
||||
fun ProductFlavor.createPublishBundleWithAssetPlayDelivery(): TaskProvider<Task> {
|
||||
val capitalizedName =
|
||||
name.replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else "$it" }
|
||||
return tasks.create("publish${capitalizedName}ReleaseBundleWithPlayAssetDelivery") {
|
||||
return tasks.register("publish${capitalizedName}ReleaseBundleWithPlayAssetDelivery") {
|
||||
group = "publishing"
|
||||
description = "Uploads $capitalizedName to the Play Console with an Play Asset delivery mode"
|
||||
doLast {
|
||||
@ -249,7 +250,7 @@ fun ProductFlavor.createPublishBundleWithAssetPlayDelivery(): Task {
|
||||
.transactionWithCommit(packageName) {
|
||||
val generatedBundleFile =
|
||||
File(
|
||||
"$buildDir/outputs/bundle/${capitalizedName.lowercase(Locale.getDefault())}" +
|
||||
"${layout.buildDirectory}/outputs/bundle/${capitalizedName.lowercase(Locale.getDefault())}" +
|
||||
"Release/custom-${capitalizedName.lowercase(Locale.getDefault())}-release.aab"
|
||||
)
|
||||
if (generatedBundleFile.exists()) {
|
||||
|
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@ -1,6 +1,6 @@
|
||||
#Mon Dec 19 16:13:45 IST 2022
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip
|
||||
distributionPath=wrapper/dists
|
||||
zipStorePath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
Loading…
x
Reference in New Issue
Block a user