mirror of
https://github.com/kiwix/kiwix-android.git
synced 2025-09-18 11:55:38 -04:00
commit
96b032c57e
18
.codecov.yml
Normal file
18
.codecov.yml
Normal file
@ -0,0 +1,18 @@
|
||||
codecov:
|
||||
notify:
|
||||
require_ci_to_pass: yes
|
||||
|
||||
coverage:
|
||||
status:
|
||||
project:
|
||||
default:
|
||||
threshold: 1%
|
||||
patch:
|
||||
default:
|
||||
target: 90%
|
||||
threshold: 0%
|
||||
|
||||
ignore:
|
||||
- "docs"
|
||||
- "fastlane"
|
||||
- "core/src/test/java/"
|
27
.github/move.yml
vendored
27
.github/move.yml
vendored
@ -1,27 +0,0 @@
|
||||
# Configuration for Move Issues - https://github.com/dessant/move-issues
|
||||
|
||||
# Delete the command comment when it contains no other content
|
||||
deleteCommand: true
|
||||
|
||||
# Close the source issue after moving
|
||||
closeSourceIssue: true
|
||||
|
||||
# Lock the source issue after moving
|
||||
lockSourceIssue: false
|
||||
|
||||
# Mention issue and comment authors
|
||||
mentionAuthors: true
|
||||
|
||||
# Preserve mentions in the issue content
|
||||
keepContentMentions: true
|
||||
|
||||
# Move labels that also exist on the target repository
|
||||
moveLabels: true
|
||||
|
||||
# Set custom aliases for targets
|
||||
# aliases:
|
||||
# r: repo
|
||||
# or: owner/repo
|
||||
|
||||
# Repository to extend settings from
|
||||
# _extends: repo
|
11
.github/workflows/coverage.yml
vendored
11
.github/workflows/coverage.yml
vendored
@ -24,6 +24,11 @@ jobs:
|
||||
with:
|
||||
fetch-depth: 1
|
||||
|
||||
- name: Set up JDK 11
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: 11
|
||||
|
||||
- name: create instrumentation coverage
|
||||
uses: ReactiveCircus/android-emulator-runner@v2.23.0
|
||||
env:
|
||||
@ -32,9 +37,10 @@ jobs:
|
||||
api-level: ${{ matrix.api-level }}
|
||||
arch: x86_64
|
||||
ndk: 21.4.7075529
|
||||
sdcard-path-or-size: '1000M'
|
||||
disable-animations: false
|
||||
script: bash contrib/instrumentation.sh
|
||||
|
||||
|
||||
- name: Upload screenshot result
|
||||
uses: actions/upload-artifact@v1
|
||||
if: failure()
|
||||
@ -48,8 +54,7 @@ jobs:
|
||||
|
||||
- name: Upload coverage to Codecov
|
||||
if: ${{ matrix.api-level==21 }}
|
||||
run: |
|
||||
bash <(curl -s https://codecov.io/bash)
|
||||
uses: codecov/codecov-action@v2
|
||||
|
||||
- name: Upload Coverage to GH-Actions
|
||||
uses: actions/upload-artifact@v2.2.0
|
||||
|
17
.github/workflows/nightly.yml
vendored
17
.github/workflows/nightly.yml
vendored
@ -20,6 +20,11 @@ jobs:
|
||||
with:
|
||||
fetch-depth: 1
|
||||
|
||||
- name: Set up JDK 11
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: 11
|
||||
|
||||
- name: run instrumentation tests
|
||||
uses: ReactiveCircus/android-emulator-runner@v2.19.1
|
||||
with:
|
||||
@ -44,6 +49,11 @@ jobs:
|
||||
with:
|
||||
fetch-depth: 1
|
||||
|
||||
- name: Set up JDK 11
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: 11
|
||||
|
||||
- name: Install NDK
|
||||
run: echo "y" | sudo ${ANDROID_HOME}/tools/bin/sdkmanager --install "ndk;22.0.7026061" --sdk_root=${ANDROID_SDK_ROOT}
|
||||
|
||||
@ -71,3 +81,10 @@ jobs:
|
||||
cp $UNIVERSAL_DEBUG_APK $DATE
|
||||
scp -P 30022 -vrp -i ssh_key -o StrictHostKeyChecking=no $DATE ci@master.download.kiwix.org:/data/download/nightly/
|
||||
|
||||
- name: fdroid nightly
|
||||
run: |
|
||||
sudo add-apt-repository ppa:fdroid/fdroidserver
|
||||
sudo apt-get update
|
||||
sudo apt-get install apksigner fdroidserver --no-install-recommends
|
||||
export DEBUG_KEYSTORE=$\{\{ secrets.DEBUG_KEYSTORE \}\}
|
||||
fdroid nightly --archive-older 10
|
||||
|
10
.github/workflows/pull_request.yml
vendored
10
.github/workflows/pull_request.yml
vendored
@ -13,6 +13,11 @@ jobs:
|
||||
with:
|
||||
fetch-depth: 1
|
||||
|
||||
- name: Set up JDK 11
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: 11
|
||||
|
||||
- name: Static Analysis
|
||||
run: ./gradlew ktlintCheck detekt app:lintDebug custom:lintCustomexampleDebug
|
||||
|
||||
@ -34,6 +39,11 @@ jobs:
|
||||
with:
|
||||
fetch-depth: 1
|
||||
|
||||
- name: Set up JDK 11
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: 11
|
||||
|
||||
- name: Install NDK
|
||||
run: echo "y" | sudo ${ANDROID_HOME}/tools/bin/sdkmanager --install "ndk;22.0.7026061" --sdk_root=${ANDROID_SDK_ROOT}
|
||||
|
||||
|
26
.github/workflows/release.yml
vendored
26
.github/workflows/release.yml
vendored
@ -17,6 +17,11 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
|
||||
- name: Set up JDK 11
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: 11
|
||||
|
||||
- name: Decrypt files
|
||||
env:
|
||||
keystore: ${{ secrets.keystore }}
|
||||
@ -42,13 +47,18 @@ jobs:
|
||||
cp $UNIVERSAL_RELEASE_APK kiwix-${TAG}.apk
|
||||
scp -P 30022 -vrp -i ssh_key -o StrictHostKeyChecking=no kiwix-${TAG}.apk ci@master.download.kiwix.org:/data/download/release/kiwix-android/
|
||||
|
||||
- name: Publish to github releases
|
||||
uses: ncipollo/release-action@v1
|
||||
with:
|
||||
artifacts: "app/build/outputs/apk/release/**"
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
draft: true
|
||||
prerelease: true
|
||||
- name: Publish versionInfo to download.kiwix.org
|
||||
run: |
|
||||
./gradlew generateVersionCodeAndName
|
||||
scp -P 30022 -vrp -i ssh_key -o StrictHostKeyChecking=no VERSION_INFO ci@master.download.kiwix.org:/data/download/release/kiwix-android/
|
||||
|
||||
- name: Publish to github releases
|
||||
uses: ncipollo/release-action@v1
|
||||
with:
|
||||
artifacts: "app/build/outputs/apk/release/**"
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
draft: true
|
||||
prerelease: true
|
||||
|
||||
|
||||
- name: Publish app to play store
|
||||
@ -56,4 +66,4 @@ jobs:
|
||||
KEY_ALIAS: ${{ secrets.KEY_ALIAS }}
|
||||
KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}
|
||||
KEY_STORE_PASSWORD: ${{ secrets.KEY_STORE_PASSWORD }}
|
||||
run: ./gradlew publishReleaseBundle
|
||||
run: ./gradlew publishPlayStoreBundle
|
||||
|
16
CHANGELOG
16
CHANGELOG
@ -1,3 +1,19 @@
|
||||
3.6.0
|
||||
* FIX: Upgrade to Kotlin 1.7.0.
|
||||
* FIX: Introduce google play build variant.
|
||||
* FIX: Upgrade project environment from java 8 to java 11.
|
||||
* FIX: Upgrade detekt lib to 1.20.0.
|
||||
* FIX: Upgrade klint lib to 10.3.0.
|
||||
* FIX: Google play publisher upgrade to 3.7.0.
|
||||
* FIX: Pdf/Epub files opening issue fixes.
|
||||
* FIX: Same pictures are saved multiple times.
|
||||
* FIX: Introductory screen hangup issue fixed.
|
||||
* FIX: Search Widget navigation issue fixed.
|
||||
* FIX: Search screen were missing while pressing back fixed.
|
||||
* FIX: Unsatisfied Link error fixed.
|
||||
* FIX: IllegalStateException report in core reader fragment fixed.
|
||||
|
||||
|
||||
3.5.0
|
||||
* FIX: Storing Zim/Book files inside the public Kiwix Directory on internal storage.
|
||||
* FIX: Storing Zim/Book files inside the public Kiwix Directory on external storage in android 11 and above.
|
||||
|
@ -8,10 +8,10 @@
|
||||
|
||||
# Kiwix Android
|
||||
|
||||
Kiwix is an offline reader for Web content. One of its main purpose
|
||||
Kiwix is an offline reader for Web content. One of its main purposes
|
||||
is to make Wikipedia available offline. This is done by reading the
|
||||
content of a file in the ZIM format, a highly compressed open format
|
||||
with additional meta-data. This is the version for Android.
|
||||
with additional metadata. This is the version for Android.
|
||||
|
||||
Kiwix Android is written in [Kotlin](https://kotlinlang.org/) (with a few old
|
||||
pieces in Java).
|
||||
|
2
VERSION_INFO
Normal file
2
VERSION_INFO
Normal file
@ -0,0 +1,2 @@
|
||||
3.6.0
|
||||
7230600
|
@ -10,7 +10,7 @@ apply(from = rootProject.file("jacoco.gradle"))
|
||||
|
||||
ext {
|
||||
set("versionMajor", 3)
|
||||
set("versionMinor", 5)
|
||||
set("versionMinor", 6)
|
||||
set("versionPatch", 0)
|
||||
}
|
||||
|
||||
@ -30,8 +30,8 @@ fun generateVersionName() = "${ext["versionMajor"]}.${ext["versionMinor"]}.${ext
|
||||
|
||||
fun generateVersionCode() =
|
||||
20 * 10000 +
|
||||
((ext["versionMajor"] as Int) * 10000) +
|
||||
((ext["versionMinor"] as Int) * 100) +
|
||||
ext["versionMajor"] as Int * 10000 +
|
||||
ext["versionMinor"] as Int * 100 +
|
||||
ext["versionPatch"] as Int
|
||||
|
||||
val apkPrefix get() = System.getenv("TAG") ?: "dev"
|
||||
@ -44,8 +44,8 @@ android {
|
||||
resValue("string", "app_search_string", "Search Kiwix")
|
||||
versionCode = generateVersionCode()
|
||||
versionName = generateVersionName()
|
||||
manifestPlaceholders["permission"] = "android.permission.MANAGE_EXTERNAL_STORAGE"
|
||||
}
|
||||
|
||||
lintOptions {
|
||||
isCheckDependencies = true
|
||||
}
|
||||
@ -54,14 +54,22 @@ android {
|
||||
getByName("debug") {
|
||||
multiDexKeepProguard = file("multidex-instrumentation-config.pro")
|
||||
buildConfigField("boolean", "KIWIX_ERROR_ACTIVITY", "false")
|
||||
buildConfigField("boolean", "IS_PLAYSTORE", "false")
|
||||
}
|
||||
|
||||
getByName("release") {
|
||||
buildConfigField("boolean", "KIWIX_ERROR_ACTIVITY", "true")
|
||||
buildConfigField("boolean", "IS_PLAYSTORE", "false")
|
||||
if (properties.containsKey("disableSigning")) {
|
||||
signingConfig = null
|
||||
}
|
||||
}
|
||||
create("playStore") {
|
||||
initWith(getByName("release"))
|
||||
setMatchingFallbacks("release")
|
||||
buildConfigField("boolean", "IS_PLAYSTORE", "true")
|
||||
manifestPlaceholders["permission"] = "android.permission.placeholder"
|
||||
}
|
||||
}
|
||||
bundle {
|
||||
language {
|
||||
@ -78,13 +86,23 @@ android {
|
||||
}
|
||||
|
||||
play {
|
||||
isEnabled = true
|
||||
serviceAccountCredentials = file("../google.json")
|
||||
track = "alpha"
|
||||
releaseStatus = "draft"
|
||||
resolutionStrategy = "fail"
|
||||
enabled.set(true)
|
||||
serviceAccountCredentials.set(file("../google.json"))
|
||||
track.set("alpha")
|
||||
releaseStatus.set(com.github.triplet.gradle.androidpublisher.ReleaseStatus.DRAFT)
|
||||
resolutionStrategy.set(com.github.triplet.gradle.androidpublisher.ResolutionStrategy.FAIL)
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(Libs.squidb)
|
||||
}
|
||||
task("generateVersionCodeAndName") {
|
||||
val file = File("VERSION_INFO")
|
||||
if (!file.exists()) file.createNewFile()
|
||||
file.printWriter().use {
|
||||
it.print(
|
||||
"${generateVersionName()}\n" +
|
||||
"7${generateVersionCode()}"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -1,42 +1,52 @@
|
||||
<?xml version="1.0" ?>
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<SmellBaseline>
|
||||
<Blacklist></Blacklist>
|
||||
<Whitelist>
|
||||
<ManuallySuppressedIssues/>
|
||||
<CurrentIssues>
|
||||
<ID>EmptyFunctionBlock:None.kt$None${ }</ID>
|
||||
<ID>EmptyFunctionBlock:SimplePageChangeListener.kt$SimplePageChangeListener${ }</ID>
|
||||
<ID>LongParameterList:ZimManageViewModel.kt$ZimManageViewModel$( booksOnFileSystem: List<BookOnDisk>, activeDownloads: List<DownloadModel>, allLanguages: List<Language>, libraryNetworkEntity: LibraryNetworkEntity, filter: String, fileSystemState: FileSystemState )</ID>
|
||||
<ID>LongParameterList:ZimManageViewModel.kt$ZimManageViewModel$( booksOnFileSystem: List<BookOnDisk>, activeDownloads: List<DownloadModel>, allLanguages: List<Language>, libraryNetworkEntity: LibraryNetworkEntity, filter: String, fileSystemState: FileSystemState )</ID>
|
||||
<ID>LongParameterList:ZimManageViewModel.kt$ZimManageViewModel$( private val downloadDao: FetchDownloadDao, private val bookDao: NewBookDao, private val languageDao: NewLanguagesDao, private val storageObserver: StorageObserver, private val kiwixService: KiwixService, private val context: Application, private val connectivityBroadcastReceiver: ConnectivityBroadcastReceiver, private val bookUtils: BookUtils, private val fat32Checker: Fat32Checker, private val defaultLanguageProvider: DefaultLanguageProvider, private val dataSource: DataSource, private val connectivityManager: ConnectivityManager, private val sharedPreferenceUtil: SharedPreferenceUtil )</ID>
|
||||
<ID>MagicNumber:LibraryListItem.kt$LibraryListItem.LibraryDownloadItem$1000L</ID>
|
||||
<ID>MagicNumber:PeerGroupHandshake.kt$PeerGroupHandshake$15000</ID>
|
||||
<ID>MagicNumber:ShareFiles.kt$ShareFiles$24</ID>
|
||||
<ID>MagicNumber:ZimManageViewModel.kt$ZimManageViewModel$5</ID>
|
||||
<ID>MagicNumber:ZimManageViewModel.kt$ZimManageViewModel$500</ID>
|
||||
<ID>NestedBlockDepth:LocalLibraryFragment.kt$LocalLibraryFragment$checkPermissions</ID>
|
||||
<ID>NestedBlockDepth:PeerGroupHandshake.kt$PeerGroupHandshake$readHandshakeAndExchangeMetaData</ID>
|
||||
<ID>NestedBlockDepth:ReceiverHandShake.kt$ReceiverHandShake$exchangeFileTransferMetadata</ID>
|
||||
<ID>PackageNaming:AvailableSpaceCalculator.kt$package org.kiwix.kiwixmobile.zim_manager.library_view</ID>
|
||||
<ID>PackageNaming:ConnectivityBroadcastReceiver.kt$package org.kiwix.kiwixmobile.zim_manager</ID>
|
||||
<ID>PackageNaming:DefaultLanguageProvider.kt$package org.kiwix.kiwixmobile.zim_manager</ID>
|
||||
<ID>PackageNaming:DeleteFiles.kt$package org.kiwix.kiwixmobile.zim_manager.fileselect_view.effects</ID>
|
||||
<ID>PackageNaming:Fat32Checker.kt$package org.kiwix.kiwixmobile.zim_manager</ID>
|
||||
<ID>PackageNaming:FileSelectListState.kt$package org.kiwix.kiwixmobile.zim_manager.fileselect_view</ID>
|
||||
<ID>PackageNaming:FileSystemChecker.kt$package org.kiwix.kiwixmobile.zim_manager</ID>
|
||||
<ID>PackageNaming:FileWritingFileSystemChecker.kt$package org.kiwix.kiwixmobile.zim_manager</ID>
|
||||
<ID>NestedBlockDepth:LocalLibraryFragment.kt$LocalLibraryFragment$private fun checkPermissions()</ID>
|
||||
<ID>NestedBlockDepth:PeerGroupHandshake.kt$PeerGroupHandshake$private fun readHandshakeAndExchangeMetaData(): InetAddress?</ID>
|
||||
<ID>NestedBlockDepth:ReceiverHandShake.kt$ReceiverHandShake$override fun exchangeFileTransferMetadata(inputStream: InputStream, outputStream: OutputStream)</ID>
|
||||
<ID>PackageNaming:AvailableSpaceCalculator.kt$package
|
||||
org.kiwix.kiwixmobile.zimManager.libraryView</ID>
|
||||
<ID>PackageNaming:ConnectivityBroadcastReceiver.kt$package org.kiwix.kiwixmobile.zimManager</ID>
|
||||
<ID>PackageNaming:DefaultLanguageProvider.kt$package org.kiwix.kiwixmobile.zimManager</ID>
|
||||
<ID>PackageNaming:DeleteFiles.kt$package
|
||||
org.kiwix.kiwixmobile.zimManager.fileselectView.effects</ID>
|
||||
<ID>PackageNaming:Fat32Checker.kt$package org.kiwix.kiwixmobile.zimManager</ID>
|
||||
<ID>PackageNaming:FileSelectListState.kt$package
|
||||
org.kiwix.kiwixmobile.zimManager.fileselectView</ID>
|
||||
<ID>PackageNaming:FileSystemChecker.kt$package org.kiwix.kiwixmobile.zimManager</ID>
|
||||
<ID>PackageNaming:FileWritingFileSystemChecker.kt$package org.kiwix.kiwixmobile.zimManager</ID>
|
||||
<ID>PackageNaming:HotspotNotificationManager.kt$package org.kiwix.kiwixmobile.webserver.wifi_hotspot</ID>
|
||||
<ID>PackageNaming:HotspotStateReceiver.kt$package org.kiwix.kiwixmobile.webserver.wifi_hotspot</ID>
|
||||
<ID>PackageNaming:LibraryAdapter.kt$package org.kiwix.kiwixmobile.zim_manager.library_view.adapter</ID>
|
||||
<ID>PackageNaming:LibraryDelegate.kt$package org.kiwix.kiwixmobile.zim_manager.library_view.adapter</ID>
|
||||
<ID>PackageNaming:LibraryListItem.kt$package org.kiwix.kiwixmobile.zim_manager.library_view.adapter</ID>
|
||||
<ID>PackageNaming:LibraryViewHolder.kt$package org.kiwix.kiwixmobile.zim_manager.library_view.adapter</ID>
|
||||
<ID>PackageNaming:MountFileSystemChecker.kt$package org.kiwix.kiwixmobile.zim_manager</ID>
|
||||
<ID>PackageNaming:NavigateToDownloads.kt$package org.kiwix.kiwixmobile.zim_manager.fileselect_view.effects</ID>
|
||||
<ID>PackageNaming:NetworkState.kt$package org.kiwix.kiwixmobile.zim_manager</ID>
|
||||
<ID>PackageNaming:None.kt$package org.kiwix.kiwixmobile.zim_manager.fileselect_view.effects</ID>
|
||||
<ID>PackageNaming:OpenFileWithNavigation.kt$package org.kiwix.kiwixmobile.zim_manager.fileselect_view.effects</ID>
|
||||
<ID>PackageNaming:ShareFiles.kt$package org.kiwix.kiwixmobile.zim_manager.fileselect_view.effects</ID>
|
||||
<ID>PackageNaming:SimplePageChangeListener.kt$package org.kiwix.kiwixmobile.zim_manager</ID>
|
||||
<ID>PackageNaming:StartMultiSelection.kt$package org.kiwix.kiwixmobile.zim_manager.fileselect_view.effects</ID>
|
||||
<ID>PackageNaming:ZimManageViewModel.kt$package org.kiwix.kiwixmobile.zim_manager</ID>
|
||||
<ID>PackageNaming:LibraryAdapter.kt$package
|
||||
org.kiwix.kiwixmobile.zimManager.libraryView.adapter</ID>
|
||||
<ID>PackageNaming:LibraryDelegate.kt$package
|
||||
org.kiwix.kiwixmobile.zimManager.libraryView.adapter</ID>
|
||||
<ID>PackageNaming:LibraryListItem.kt$package
|
||||
org.kiwix.kiwixmobile.zimManager.libraryView.adapter</ID>
|
||||
<ID>PackageNaming:LibraryViewHolder.kt$package
|
||||
org.kiwix.kiwixmobile.zimManager.libraryView.adapter</ID>
|
||||
<ID>PackageNaming:MountFileSystemChecker.kt$package org.kiwix.kiwixmobile.zimManager</ID>
|
||||
<ID>PackageNaming:NavigateToDownloads.kt$package
|
||||
org.kiwix.kiwixmobile.zimManager.fileselectView.effects</ID>
|
||||
<ID>PackageNaming:NetworkState.kt$package org.kiwix.kiwixmobile.zimManager</ID>
|
||||
<ID>PackageNaming:None.kt$package org.kiwix.kiwixmobile.zimManager.fileselectView.effects</ID>
|
||||
<ID>PackageNaming:OpenFileWithNavigation.kt$package
|
||||
org.kiwix.kiwixmobile.zimManager.fileselectView.effects</ID>
|
||||
<ID>PackageNaming:ShareFiles.kt$package org.kiwix.kiwixmobile.zimManager.fileselectView.effects</ID>
|
||||
<ID>PackageNaming:SimplePageChangeListener.kt$package org.kiwix.kiwixmobile.zimManager</ID>
|
||||
<ID>PackageNaming:StartMultiSelection.kt$package
|
||||
org.kiwix.kiwixmobile.zimManager.fileselectView.effects</ID>
|
||||
<ID>PackageNaming:ZimManageViewModel.kt$package org.kiwix.kiwixmobile.zimManager</ID>
|
||||
<ID>ReturnCount:Fat32Checker.kt$Fat32Checker$private fun canCreate4GbFile(storage: String): Boolean</ID>
|
||||
<ID>TooGenericExceptionCaught:FileWritingFileSystemChecker.kt$FileWritingFileSystemChecker$e: Exception</ID>
|
||||
<ID>TooGenericExceptionCaught:PeerGroupHandshake.kt$PeerGroupHandshake$ex: Exception</ID>
|
||||
@ -46,5 +56,5 @@
|
||||
<ID>TooGenericExceptionThrown:LibraryViewHolder.kt$LibraryViewHolder.LibraryBookViewHolder$throw RuntimeException("impossible invalid state: ${item.fileSystemState}")</ID>
|
||||
<ID>TooGenericExceptionThrown:ZimManageViewModel.kt$ZimManageViewModel$throw RuntimeException("Impossible state")</ID>
|
||||
<ID>VariableNaming:PeerGroupHandshake.kt$PeerGroupHandshake$private val HANDSHAKE_MESSAGE = "Request Kiwix File Sharing"</ID>
|
||||
</Whitelist>
|
||||
</CurrentIssues>
|
||||
</SmellBaseline>
|
||||
|
@ -108,4 +108,4 @@ private fun resourceId(view: View) =
|
||||
if (view.id > 0 && view.resources != null) " id:${view.resources.getResourceName(view.id)}"
|
||||
else ""
|
||||
|
||||
private fun numSpaces(marginOffset: Int) = (0..marginOffset).fold("", { acc, _ -> "$acc-" })
|
||||
private fun numSpaces(marginOffset: Int) = (0..marginOffset).fold("") { acc, _ -> "$acc-" }
|
||||
|
@ -48,7 +48,7 @@ abstract class BaseActivityTest {
|
||||
getInstrumentation().targetContext.applicationContext
|
||||
}
|
||||
|
||||
inline fun <reified T : Activity> activityTestRule(
|
||||
protected inline fun <reified T : Activity> activityTestRule(
|
||||
noinline beforeActivityAction: (() -> Unit)? = null
|
||||
) =
|
||||
object : ActivityTestRule<T>(T::class.java) {
|
||||
|
@ -70,14 +70,17 @@ public class KiwixDatabaseTest {
|
||||
kiwixDatabase.migrateBookmarksVersion6();
|
||||
|
||||
ArrayList<String> bookmarkTitles = new ArrayList<>();
|
||||
try (SquidCursor<Bookmark> bookmarkCursor = kiwixDatabase.query(Bookmark.class,
|
||||
Query.selectDistinct(Bookmark.BOOKMARK_TITLE)
|
||||
.where(Bookmark.ZIM_ID.eq(testId)
|
||||
.or(Bookmark.ZIM_NAME.eq("")))
|
||||
.orderBy(Bookmark.BOOKMARK_TITLE.asc()))) {
|
||||
try {
|
||||
SquidCursor<Bookmark> bookmarkCursor = kiwixDatabase.query(Bookmark.class,
|
||||
Query.selectDistinct(Bookmark.BOOKMARK_TITLE)
|
||||
.where(Bookmark.ZIM_ID.eq(testId)
|
||||
.or(Bookmark.ZIM_NAME.eq("")))
|
||||
.orderBy(Bookmark.BOOKMARK_TITLE.asc()));
|
||||
while (bookmarkCursor.moveToNext()) {
|
||||
bookmarkTitles.add(bookmarkCursor.get(Bookmark.BOOKMARK_TITLE));
|
||||
}
|
||||
} catch (Exception exception) {
|
||||
exception.printStackTrace();
|
||||
}
|
||||
assertArrayEquals(testBookmarks, bookmarkTitles.toArray());
|
||||
|
||||
|
@ -20,7 +20,6 @@ package org.kiwix.kiwixmobile.data.local.dao
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import com.yahoo.squidb.data.AbstractModel
|
||||
import com.yahoo.squidb.data.SquidCursor
|
||||
import com.yahoo.squidb.sql.Query
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import io.mockk.verify
|
||||
@ -37,7 +36,7 @@ class RecentSearchDaoTest {
|
||||
every {
|
||||
kiwixDatabase.query(any<Class<AbstractModel>>(), any())
|
||||
} returns mockk<SquidCursor<AbstractModel>>(relaxed = true)
|
||||
RecentSearchDao(kiwixDatabase).recentSearches
|
||||
verify { kiwixDatabase.query(any<Class<AbstractModel>>(), Query.select()) }
|
||||
RecentSearchDao(kiwixDatabase).getRecentSearches()
|
||||
verify { kiwixDatabase.query(any<Class<AbstractModel>>(), any()) }
|
||||
}
|
||||
}
|
||||
|
@ -17,19 +17,75 @@
|
||||
*/
|
||||
package org.kiwix.kiwixmobile.search
|
||||
|
||||
import androidx.core.content.edit
|
||||
import androidx.core.net.toUri
|
||||
import androidx.preference.PreferenceManager
|
||||
import androidx.test.internal.runner.junit4.statement.UiThreadStatement
|
||||
import com.adevinta.android.barista.assertion.BaristaVisibilityAssertions.assertDisplayed
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import androidx.test.rule.ActivityTestRule
|
||||
import androidx.test.uiautomator.UiDevice
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.kiwix.kiwixmobile.BaseActivityTest
|
||||
import org.kiwix.kiwixmobile.R
|
||||
import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil
|
||||
import org.kiwix.kiwixmobile.main.KiwixMainActivity
|
||||
import org.kiwix.kiwixmobile.nav.destination.library.LocalLibraryFragmentDirections.actionNavigationLibraryToNavigationReader
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import java.io.OutputStream
|
||||
|
||||
class SearchFragmentTest : BaseActivityTest() {
|
||||
@Before fun setUp() {
|
||||
UiThreadStatement.runOnUiThread { activityRule.activity.navigate(R.id.searchFragment) }
|
||||
override var activityRule: ActivityTestRule<KiwixMainActivity> = activityTestRule {
|
||||
PreferenceManager.getDefaultSharedPreferences(context).edit {
|
||||
putBoolean(SharedPreferenceUtil.PREF_SHOW_INTRO, false)
|
||||
putBoolean(SharedPreferenceUtil.PREF_WIFI_ONLY, false)
|
||||
}
|
||||
}
|
||||
|
||||
@Before
|
||||
fun waitForIdle() {
|
||||
UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()).waitForIdle()
|
||||
}
|
||||
|
||||
@Test fun searchFragmentSimple() {
|
||||
assertDisplayed(R.string.menu_search_in_text)
|
||||
UiThreadStatement.runOnUiThread { activityRule.activity.navigate(R.id.libraryFragment) }
|
||||
val loadFileStream =
|
||||
SearchFragmentTest::class.java.classLoader.getResourceAsStream("testzim.zim")
|
||||
val zimFile = File(context.cacheDir, "testzim.zim")
|
||||
if (zimFile.exists()) zimFile.delete()
|
||||
zimFile.createNewFile()
|
||||
loadFileStream.use { inputStream ->
|
||||
val outputStream: OutputStream = FileOutputStream(zimFile)
|
||||
outputStream.use { it ->
|
||||
val buffer = ByteArray(inputStream.available())
|
||||
var length: Int
|
||||
while (inputStream.read(buffer).also { length = it } > 0) {
|
||||
it.write(buffer, 0, length)
|
||||
}
|
||||
}
|
||||
}
|
||||
UiThreadStatement.runOnUiThread {
|
||||
activityRule.activity.navigate(
|
||||
actionNavigationLibraryToNavigationReader()
|
||||
.apply { zimFileUri = zimFile.toUri().toString() }
|
||||
)
|
||||
}
|
||||
search { checkZimFileSearchSuccessful(R.id.readerFragment) }
|
||||
UiThreadStatement.runOnUiThread {
|
||||
if (zimFile.canRead()) {
|
||||
activityRule.activity.openSearch(searchString = "Android")
|
||||
} else {
|
||||
throw RuntimeException(
|
||||
"File $zimFile is not readable." +
|
||||
" Original File $zimFile is readable = ${zimFile.canRead()}" +
|
||||
" Size ${zimFile.length()}"
|
||||
)
|
||||
}
|
||||
}
|
||||
search {
|
||||
clickOnSearchItemInSearchList()
|
||||
checkZimFileSearchSuccessful(R.id.readerFragment)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Kiwix Android
|
||||
* Copyright (c) 2022 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.search
|
||||
|
||||
import applyWithViewHierarchyPrinting
|
||||
import com.adevinta.android.barista.interaction.BaristaSleepInteractions
|
||||
import org.kiwix.kiwixmobile.BaseRobot
|
||||
import org.kiwix.kiwixmobile.Findable.ViewId
|
||||
import org.kiwix.kiwixmobile.core.R
|
||||
import org.kiwix.kiwixmobile.testutils.TestUtils
|
||||
|
||||
fun search(func: SearchRobot.() -> Unit) = SearchRobot().applyWithViewHierarchyPrinting(func)
|
||||
|
||||
class SearchRobot : BaseRobot() {
|
||||
|
||||
fun clickOnSearchItemInSearchList() {
|
||||
BaristaSleepInteractions.sleep(TestUtils.TEST_PAUSE_MS_FOR_SEARCH_TEST.toLong())
|
||||
isVisible(ViewId(R.id.search_list))
|
||||
clickOn(ViewId(R.id.list_item_search_text))
|
||||
}
|
||||
|
||||
fun checkZimFileSearchSuccessful(readerFragment: Int) {
|
||||
BaristaSleepInteractions.sleep(TestUtils.TEST_PAUSE_MS_FOR_SEARCH_TEST.toLong())
|
||||
isVisible(ViewId(readerFragment))
|
||||
}
|
||||
}
|
@ -40,8 +40,8 @@ class Matcher {
|
||||
public override fun matchesSafely(view: View): Boolean {
|
||||
val parent = view.parent
|
||||
return parent is ViewGroup && parentMatcher.matches(parent) && view == parent.getChildAt(
|
||||
position
|
||||
)
|
||||
position
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -49,6 +49,7 @@ import org.kiwix.kiwixmobile.core.entity.LibraryNetworkEntity.Book;
|
||||
public class TestUtils {
|
||||
private static final String TAG = "TESTUTILS";
|
||||
public static int TEST_PAUSE_MS = 250;
|
||||
public static int TEST_PAUSE_MS_FOR_SEARCH_TEST = 1000;
|
||||
/*
|
||||
TEST_PAUSE_MS is used as such:
|
||||
BaristaSleepInteractions.sleep(TEST_PAUSE_MS);
|
||||
@ -143,4 +144,3 @@ public class TestUtils {
|
||||
return targetContext.getResources().getString(id);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,70 +0,0 @@
|
||||
/*
|
||||
* Kiwix Android
|
||||
* Copyright (c) 2019 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.utils;
|
||||
|
||||
import androidx.test.espresso.IdlingResource;
|
||||
import org.kiwix.kiwixmobile.core.utils.TestingUtils;
|
||||
import org.kiwix.kiwixmobile.core.utils.TestingUtils.IdleListener;
|
||||
|
||||
/**
|
||||
* Created by mhutti1 on 19/04/17.
|
||||
*/
|
||||
|
||||
public class KiwixIdlingResource implements IdlingResource, IdleListener {
|
||||
|
||||
private static KiwixIdlingResource kiwixIdlingResource;
|
||||
private boolean idle = true;
|
||||
private ResourceCallback resourceCallback;
|
||||
|
||||
public static KiwixIdlingResource getInstance() {
|
||||
if (kiwixIdlingResource == null) {
|
||||
kiwixIdlingResource = new KiwixIdlingResource();
|
||||
}
|
||||
kiwixIdlingResource.idle = true;
|
||||
TestingUtils.registerIdleCallback(kiwixIdlingResource);
|
||||
return kiwixIdlingResource;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Standard Kiwix Idling Resource";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isIdleNow() {
|
||||
return idle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerIdleTransitionCallback(ResourceCallback callback) {
|
||||
this.resourceCallback = callback;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startTask() {
|
||||
idle = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finishTask() {
|
||||
idle = true;
|
||||
if (resourceCallback != null) {
|
||||
resourceCallback.onTransitionToIdle();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Kiwix Android
|
||||
* Copyright (c) 2019 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.utils
|
||||
|
||||
import androidx.test.espresso.IdlingResource
|
||||
import androidx.test.espresso.IdlingResource.ResourceCallback
|
||||
import org.kiwix.kiwixmobile.core.utils.TestingUtils
|
||||
import org.kiwix.kiwixmobile.core.utils.TestingUtils.IdleListener
|
||||
|
||||
/**
|
||||
* Created by mhutti1 on 19/04/17.
|
||||
*/
|
||||
|
||||
class KiwixIdlingResource : IdlingResource, IdleListener {
|
||||
private var idle = true
|
||||
private var resourceCallback: ResourceCallback? = null
|
||||
|
||||
override fun getName(): String = "Standard Kiwix Idling Resource"
|
||||
|
||||
override fun isIdleNow(): Boolean = idle
|
||||
|
||||
override fun registerIdleTransitionCallback(callback: ResourceCallback) {
|
||||
resourceCallback = callback
|
||||
}
|
||||
|
||||
override fun startTask() {
|
||||
idle = false
|
||||
}
|
||||
|
||||
override fun finishTask() {
|
||||
idle = true
|
||||
if (resourceCallback != null) {
|
||||
resourceCallback?.onTransitionToIdle()
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private var kiwixIdlingResource: KiwixIdlingResource? = null
|
||||
|
||||
@JvmStatic
|
||||
fun getInstance(): KiwixIdlingResource? {
|
||||
if (kiwixIdlingResource == null) {
|
||||
kiwixIdlingResource = KiwixIdlingResource()
|
||||
}
|
||||
if (kiwixIdlingResource != null) {
|
||||
kiwixIdlingResource!!.idle = true
|
||||
}
|
||||
TestingUtils.registerIdleCallback(kiwixIdlingResource)
|
||||
return kiwixIdlingResource
|
||||
}
|
||||
}
|
||||
}
|
@ -16,7 +16,7 @@
|
||||
// *
|
||||
// */
|
||||
//
|
||||
package org.kiwix.kiwixmobile.zim_manager
|
||||
package org.kiwix.kiwixmobile.zimManager
|
||||
//
|
||||
// import androidx.test.filters.SdkSuppress
|
||||
// import attempt
|
@ -15,7 +15,7 @@
|
||||
// * along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
// *
|
||||
// */
|
||||
package org.kiwix.kiwixmobile.zim_manager
|
||||
package org.kiwix.kiwixmobile.zimManager
|
||||
//
|
||||
// import applyWithViewHierarchyPrinting
|
||||
// import org.kiwix.kiwixmobile.BaseRobot
|
@ -4,10 +4,15 @@
|
||||
package="org.kiwix.kiwixmobile">
|
||||
|
||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||
<uses-permission
|
||||
android:name="android.permission.ACCESS_FINE_LOCATION"
|
||||
android:maxSdkVersion="32" />
|
||||
<uses-permission
|
||||
android:name="android.permission.NEARBY_WIFI_DEVICES"
|
||||
android:usesPermissionFlags="neverForLocation"
|
||||
tools:targetApi="s" />
|
||||
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
|
||||
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
|
||||
tools:ignore="ScopedStorage" />
|
||||
<uses-permission android:name="${permission}" />
|
||||
|
||||
<queries>
|
||||
<intent>
|
||||
@ -29,6 +34,7 @@
|
||||
<activity
|
||||
android:name=".main.KiwixMainActivity"
|
||||
android:configChanges="orientation|keyboardHidden|screenSize"
|
||||
android:exported="true"
|
||||
android:label="@string/app_name"
|
||||
android:launchMode="singleTop"
|
||||
android:theme="@style/KiwixTheme.Launcher"
|
||||
@ -145,7 +151,9 @@
|
||||
|
||||
<service android:name=".webserver.wifi_hotspot.HotspotService" />
|
||||
|
||||
<receiver android:name=".main.KiwixSearchWidget">
|
||||
<receiver
|
||||
android:name=".main.KiwixSearchWidget"
|
||||
android:exported="true">
|
||||
<meta-data
|
||||
android:name="android.appwidget.provider"
|
||||
android:resource="@xml/kiwix_widget_provider_info" />
|
||||
|
@ -19,9 +19,9 @@
|
||||
package org.kiwix.kiwixmobile
|
||||
|
||||
import android.net.ConnectivityManager
|
||||
import org.kiwix.kiwixmobile.zim_manager.NetworkState
|
||||
import org.kiwix.kiwixmobile.zim_manager.NetworkState.CONNECTED
|
||||
import org.kiwix.kiwixmobile.zim_manager.NetworkState.NOT_CONNECTED
|
||||
import org.kiwix.kiwixmobile.zimManager.NetworkState
|
||||
import org.kiwix.kiwixmobile.zimManager.NetworkState.CONNECTED
|
||||
import org.kiwix.kiwixmobile.zimManager.NetworkState.NOT_CONNECTED
|
||||
|
||||
val ConnectivityManager.networkState: NetworkState
|
||||
get() = if (activeNetworkInfo?.isConnected == true)
|
||||
|
@ -34,7 +34,7 @@ import org.kiwix.kiwixmobile.nav.destination.reader.KiwixReaderFragment
|
||||
import org.kiwix.kiwixmobile.settings.KiwixSettingsFragment
|
||||
import org.kiwix.kiwixmobile.webserver.ZimHostFragment
|
||||
import org.kiwix.kiwixmobile.webserver.ZimHostModule
|
||||
import org.kiwix.kiwixmobile.zim_manager.fileselect_view.effects.DeleteFiles
|
||||
import org.kiwix.kiwixmobile.zimManager.fileselectView.effects.DeleteFiles
|
||||
|
||||
@ActivityScope
|
||||
@Subcomponent(
|
||||
|
@ -27,9 +27,9 @@ import dagger.Provides
|
||||
import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil
|
||||
import org.kiwix.kiwixmobile.core.zim_manager.MountPointProducer
|
||||
import org.kiwix.kiwixmobile.di.KiwixScope
|
||||
import org.kiwix.kiwixmobile.zim_manager.Fat32Checker
|
||||
import org.kiwix.kiwixmobile.zim_manager.FileWritingFileSystemChecker
|
||||
import org.kiwix.kiwixmobile.zim_manager.MountFileSystemChecker
|
||||
import org.kiwix.kiwixmobile.zimManager.Fat32Checker
|
||||
import org.kiwix.kiwixmobile.zimManager.FileWritingFileSystemChecker
|
||||
import org.kiwix.kiwixmobile.zimManager.MountFileSystemChecker
|
||||
|
||||
@Module
|
||||
object KiwixModule {
|
||||
|
@ -25,7 +25,7 @@ import dagger.multibindings.IntoMap
|
||||
import org.kiwix.kiwixmobile.core.di.ViewModelKey
|
||||
import org.kiwix.kiwixmobile.core.di.modules.CoreViewModelModule
|
||||
import org.kiwix.kiwixmobile.language.viewmodel.LanguageViewModel
|
||||
import org.kiwix.kiwixmobile.zim_manager.ZimManageViewModel
|
||||
import org.kiwix.kiwixmobile.zimManager.ZimManageViewModel
|
||||
|
||||
@Module(includes = [CoreViewModelModule::class])
|
||||
abstract class KiwixViewModelModule {
|
||||
|
@ -35,7 +35,7 @@ import org.kiwix.kiwixmobile.cachedComponent
|
||||
import org.kiwix.kiwixmobile.core.base.BaseActivity
|
||||
import org.kiwix.kiwixmobile.core.base.BaseFragment
|
||||
import org.kiwix.kiwixmobile.core.base.FragmentActivityExtensions
|
||||
import org.kiwix.kiwixmobile.zim_manager.SimplePageChangeListener
|
||||
import org.kiwix.kiwixmobile.zimManager.SimplePageChangeListener
|
||||
import java.util.Timer
|
||||
import java.util.TimerTask
|
||||
import javax.inject.Inject
|
||||
@ -72,14 +72,18 @@ class IntroFragment : BaseFragment(), IntroContract.View, FragmentActivityExtens
|
||||
addOnPageChangeListener(SimplePageChangeListener(::updateView, ::handleDraggingState))
|
||||
}
|
||||
tab_indicator.setViewPager(view_pager)
|
||||
timer?.schedule(object : TimerTask() {
|
||||
override fun run() {
|
||||
handler.post {
|
||||
if (currentPage == views.size) currentPage = 0
|
||||
view_pager.setCurrentItem(currentPage++, true)
|
||||
timer?.schedule(
|
||||
object : TimerTask() {
|
||||
override fun run() {
|
||||
handler.post {
|
||||
if (currentPage == views.size) currentPage = 0
|
||||
view_pager.setCurrentItem(currentPage++, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}, timerDelay, timerPeriod)
|
||||
},
|
||||
timerDelay,
|
||||
timerPeriod
|
||||
)
|
||||
views.forEach {
|
||||
it.setOnClickListener { dismissAutoRotate() }
|
||||
}
|
||||
|
@ -125,9 +125,11 @@ class LanguageFragment : BaseFragment() {
|
||||
super.onCreateOptionsMenu(menu, inflater)
|
||||
inflater.inflate(R.menu.menu_language, menu)
|
||||
val search = menu.findItem(R.id.menu_language_search)
|
||||
(search.actionView as SearchView).setOnQueryTextListener(SimpleTextListener {
|
||||
languageViewModel.actions.offer(Filter(it))
|
||||
})
|
||||
(search.actionView as SearchView).setOnQueryTextListener(
|
||||
SimpleTextListener {
|
||||
languageViewModel.actions.offer(Filter(it))
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
|
@ -19,6 +19,7 @@ package org.kiwix.kiwixmobile.localFileTransfer
|
||||
|
||||
import android.Manifest
|
||||
import android.Manifest.permission.ACCESS_FINE_LOCATION
|
||||
import android.Manifest.permission.NEARBY_WIFI_DEVICES
|
||||
import android.Manifest.permission.WRITE_EXTERNAL_STORAGE
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Intent
|
||||
@ -40,6 +41,7 @@ import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.Toast
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import androidx.core.app.ActivityCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
@ -57,12 +59,13 @@ import org.kiwix.kiwixmobile.core.base.BaseFragment
|
||||
import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.popNavigationBackstack
|
||||
import org.kiwix.kiwixmobile.core.extensions.toast
|
||||
import org.kiwix.kiwixmobile.core.main.CoreMainActivity
|
||||
import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil
|
||||
import org.kiwix.kiwixmobile.core.utils.dialog.AlertDialogShower
|
||||
import org.kiwix.kiwixmobile.core.utils.dialog.KiwixDialog
|
||||
import org.kiwix.kiwixmobile.localFileTransfer.WifiDirectManager.Companion.getDeviceStatus
|
||||
import org.kiwix.kiwixmobile.localFileTransfer.adapter.WifiP2pDelegate
|
||||
import org.kiwix.kiwixmobile.localFileTransfer.adapter.WifiPeerListAdapter
|
||||
import java.util.ArrayList
|
||||
import org.kiwix.kiwixmobile.webserver.ZimHostFragment.Companion.PERMISSION_REQUEST_CODE_COARSE_LOCATION
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
@ -82,7 +85,8 @@ import javax.inject.Inject
|
||||
const val URIS_KEY = "uris"
|
||||
|
||||
@SuppressLint("GoogleAppIndexingApiWarning", "Registered")
|
||||
class LocalFileTransferFragment : BaseFragment(),
|
||||
class LocalFileTransferFragment :
|
||||
BaseFragment(),
|
||||
WifiDirectManager.Callbacks {
|
||||
@Inject
|
||||
lateinit var alertDialogShower: AlertDialogShower
|
||||
@ -93,6 +97,9 @@ class LocalFileTransferFragment : BaseFragment(),
|
||||
@Inject
|
||||
lateinit var locationManager: LocationManager
|
||||
|
||||
@Inject
|
||||
lateinit var sharedPreferenceUtil: SharedPreferenceUtil
|
||||
|
||||
private var fileListAdapter: FileListAdapter? = null
|
||||
private var wifiPeerListAdapter: WifiPeerListAdapter? = null
|
||||
|
||||
@ -223,6 +230,20 @@ class LocalFileTransferFragment : BaseFragment(),
|
||||
/* Helper methods used for checking permissions and states of services */
|
||||
private fun checkFineLocationAccessPermission(): Boolean {
|
||||
// Required by Android to detect wifi-p2p peers
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
return permissionIsGranted(NEARBY_WIFI_DEVICES).also { permissionGranted ->
|
||||
if (!permissionGranted) {
|
||||
if (shouldShowRationale(NEARBY_WIFI_DEVICES)) {
|
||||
alertDialogShower.show(
|
||||
KiwixDialog.NearbyWifiPermissionRationaleOnHostZimFile,
|
||||
::askNearbyWifiDevicesPermission
|
||||
)
|
||||
} else {
|
||||
askNearbyWifiDevicesPermission()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return permissionIsGranted(ACCESS_FINE_LOCATION).also { permissionGranted ->
|
||||
if (!permissionGranted) {
|
||||
if (shouldShowRationale(ACCESS_FINE_LOCATION)) {
|
||||
@ -237,23 +258,36 @@ class LocalFileTransferFragment : BaseFragment(),
|
||||
}
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
|
||||
private fun askNearbyWifiDevicesPermission() {
|
||||
ActivityCompat.requestPermissions(
|
||||
requireActivity(), arrayOf(Manifest.permission.NEARBY_WIFI_DEVICES),
|
||||
PERMISSION_REQUEST_CODE_COARSE_LOCATION
|
||||
)
|
||||
}
|
||||
|
||||
private fun requestLocationPermission() {
|
||||
requestPermission(Manifest.permission.ACCESS_FINE_LOCATION, PERMISSION_REQUEST_FINE_LOCATION)
|
||||
}
|
||||
|
||||
private fun checkExternalStorageWritePermission(): Boolean { // To access and store the zims
|
||||
return permissionIsGranted(WRITE_EXTERNAL_STORAGE).also { permissionGranted ->
|
||||
if (!permissionGranted) {
|
||||
if (shouldShowRationale(WRITE_EXTERNAL_STORAGE)) {
|
||||
alertDialogShower.show(
|
||||
KiwixDialog.StoragePermissionRationale,
|
||||
::requestStoragePermissionPermission
|
||||
)
|
||||
} else {
|
||||
requestStoragePermissionPermission()
|
||||
if (!sharedPreferenceUtil.isPlayStoreBuildWithAndroid11OrAbove() &&
|
||||
Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU
|
||||
) {
|
||||
return permissionIsGranted(WRITE_EXTERNAL_STORAGE).also { permissionGranted ->
|
||||
if (!permissionGranted) {
|
||||
if (shouldShowRationale(WRITE_EXTERNAL_STORAGE)) {
|
||||
alertDialogShower.show(
|
||||
KiwixDialog.StoragePermissionRationale,
|
||||
::requestStoragePermissionPermission
|
||||
)
|
||||
} else {
|
||||
requestStoragePermissionPermission()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
private fun shouldShowRationale(writeExternalStorage: String) =
|
||||
@ -294,7 +328,11 @@ class LocalFileTransferFragment : BaseFragment(),
|
||||
}
|
||||
|
||||
private val isLocationServiceEnabled: Boolean
|
||||
get() = isProviderEnabled(GPS_PROVIDER) || isProviderEnabled(NETWORK_PROVIDER)
|
||||
get() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
true
|
||||
} else {
|
||||
isProviderEnabled(GPS_PROVIDER) || isProviderEnabled(NETWORK_PROVIDER)
|
||||
}
|
||||
|
||||
private fun isProviderEnabled(locationProvider: String): Boolean {
|
||||
return try {
|
||||
|
@ -66,7 +66,8 @@ abstract class PeerGroupHandshake(private var groupInfo: WifiP2pInfo) {
|
||||
InetSocketAddress(
|
||||
groupInfo.groupOwnerAddress.hostAddress,
|
||||
PEER_HANDSHAKE_PORT
|
||||
), 15000
|
||||
),
|
||||
15000
|
||||
)
|
||||
val objectOutputStream = ObjectOutputStream(client.getOutputStream())
|
||||
// Send message for the peer device to verify
|
||||
|
@ -33,7 +33,7 @@ class SenderHandShake(private val wifiDirectManager: WifiDirectManager, groupInf
|
||||
// Send total number of files which will be transferred
|
||||
objectOutputStream.writeObject(wifiDirectManager.totalFilesForTransfer)
|
||||
// Send the names of each of those files, in order
|
||||
wifiDirectManager.getFilesForTransfer().forEach { fileItem ->
|
||||
wifiDirectManager.getFilesForTransfer().iterator().forEach { fileItem ->
|
||||
objectOutputStream.writeObject(fileItem.fileName)
|
||||
Log.d(TAG, "Sending " + fileItem.fileUri.toString())
|
||||
}
|
||||
|
@ -112,16 +112,19 @@ class WifiDirectManager @Inject constructor(
|
||||
private fun unregisterWifiDirectBroadcastReceiver() = context.unregisterReceiver(receiver)
|
||||
|
||||
fun discoverPeerDevices() {
|
||||
manager?.discoverPeers(channel, object : ActionListener {
|
||||
override fun onSuccess() {
|
||||
context.toast(R.string.discovery_initiated, Toast.LENGTH_SHORT)
|
||||
}
|
||||
manager?.discoverPeers(
|
||||
channel,
|
||||
object : ActionListener {
|
||||
override fun onSuccess() {
|
||||
context.toast(R.string.discovery_initiated, Toast.LENGTH_SHORT)
|
||||
}
|
||||
|
||||
override fun onFailure(reason: Int) {
|
||||
Log.d(TAG, "${context.getString(R.string.discovery_failed)}: ${getErrorMessage(reason)}")
|
||||
context.toast(R.string.discovery_failed, Toast.LENGTH_SHORT)
|
||||
override fun onFailure(reason: Int) {
|
||||
Log.d(TAG, "${context.getString(R.string.discovery_failed)}: ${getErrorMessage(reason)}")
|
||||
context.toast(R.string.discovery_failed, Toast.LENGTH_SHORT)
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
/* From KiwixWifiP2pBroadcastReceiver.P2pEventListener callback-interface*/
|
||||
@ -188,7 +191,8 @@ class WifiDirectManager @Inject constructor(
|
||||
hasSenderStartedConnection = true
|
||||
connect(senderSelectedPeerDevice)
|
||||
context.toast(R.string.performing_handshake, Toast.LENGTH_LONG)
|
||||
})
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -197,17 +201,21 @@ class WifiDirectManager @Inject constructor(
|
||||
deviceAddress = senderSelectedPeerDevice.deviceAddress
|
||||
wps.setup = WpsInfo.PBC
|
||||
}
|
||||
manager?.connect(channel, config, object : ActionListener {
|
||||
override fun onSuccess() {
|
||||
// UI updated from broadcast receiver
|
||||
}
|
||||
manager?.connect(
|
||||
channel,
|
||||
config,
|
||||
object : ActionListener {
|
||||
override fun onSuccess() {
|
||||
// UI updated from broadcast receiver
|
||||
}
|
||||
|
||||
override fun onFailure(reason: Int) {
|
||||
val errorMessage = getErrorMessage(reason)
|
||||
Log.d(TAG, context.getString(R.string.connection_failed) + ": " + errorMessage)
|
||||
context.toast(R.string.connection_failed, Toast.LENGTH_LONG)
|
||||
override fun onFailure(reason: Int) {
|
||||
val errorMessage = getErrorMessage(reason)
|
||||
Log.d(TAG, context.getString(R.string.connection_failed) + ": " + errorMessage)
|
||||
context.toast(R.string.connection_failed, Toast.LENGTH_LONG)
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
private fun performHandshakeWith(groupInfo: WifiP2pInfo) {
|
||||
@ -291,17 +299,20 @@ class WifiDirectManager @Inject constructor(
|
||||
}
|
||||
|
||||
private fun disconnect() {
|
||||
manager?.removeGroup(channel, object : ActionListener {
|
||||
override fun onFailure(reasonCode: Int) {
|
||||
Log.d(TAG, "Disconnect failed. Reason: $reasonCode")
|
||||
closeChannel()
|
||||
}
|
||||
manager?.removeGroup(
|
||||
channel,
|
||||
object : ActionListener {
|
||||
override fun onFailure(reasonCode: Int) {
|
||||
Log.d(TAG, "Disconnect failed. Reason: $reasonCode")
|
||||
closeChannel()
|
||||
}
|
||||
|
||||
override fun onSuccess() {
|
||||
Log.d(TAG, "Disconnect successful")
|
||||
closeChannel()
|
||||
override fun onSuccess() {
|
||||
Log.d(TAG, "Disconnect successful")
|
||||
closeChannel()
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
private fun closeChannel() {
|
||||
|
@ -33,6 +33,7 @@ import kotlinx.android.synthetic.main.activity_kiwix_main.bottom_nav_view
|
||||
import kotlinx.android.synthetic.main.activity_kiwix_main.drawer_nav_view
|
||||
import kotlinx.android.synthetic.main.activity_kiwix_main.navigation_container
|
||||
import kotlinx.android.synthetic.main.activity_kiwix_main.reader_drawer_nav_view
|
||||
import org.kiwix.kiwixmobile.BuildConfig
|
||||
import org.kiwix.kiwixmobile.R
|
||||
import org.kiwix.kiwixmobile.core.base.FragmentActivityExtensions
|
||||
import org.kiwix.kiwixmobile.core.di.components.CoreComponent
|
||||
@ -54,11 +55,13 @@ class KiwixMainActivity : CoreMainActivity() {
|
||||
override val bookmarksFragmentResId: Int = R.id.bookmarksFragment
|
||||
override val settingsFragmentResId: Int = R.id.kiwixSettingsFragment
|
||||
override val historyFragmentResId: Int = R.id.historyFragment
|
||||
override val notesFragmentResId: Int = R.id.notesFragment
|
||||
override val readerFragmentResId: Int = R.id.readerFragment
|
||||
override val helpFragmentResId: Int = R.id.helpFragment
|
||||
override val topLevelDestinations =
|
||||
setOf(R.id.downloadsFragment, R.id.libraryFragment, R.id.readerFragment)
|
||||
|
||||
private var isIntroScreenVisible: Boolean = false
|
||||
override fun injection(coreComponent: CoreComponent) {
|
||||
cachedComponent.inject(this)
|
||||
}
|
||||
@ -97,11 +100,15 @@ class KiwixMainActivity : CoreMainActivity() {
|
||||
handleDrawerOnNavigation()
|
||||
}
|
||||
}
|
||||
if (sharedPreferenceUtil.showIntro()) {
|
||||
if (sharedPreferenceUtil.showIntro() && !isIntroScreenNotVisible()) {
|
||||
navigate(KiwixReaderFragmentDirections.actionReaderFragmentToIntroFragment())
|
||||
}
|
||||
sharedPreferenceUtil.setIsPlayStoreBuildType(BuildConfig.IS_PLAYSTORE)
|
||||
}
|
||||
|
||||
private fun isIntroScreenNotVisible(): Boolean =
|
||||
isIntroScreenVisible.also { isIntroScreenVisible = true }
|
||||
|
||||
override fun onSupportActionModeStarted(mode: ActionMode) {
|
||||
super.onSupportActionModeStarted(mode)
|
||||
actionMode = mode
|
||||
|
@ -26,6 +26,7 @@ import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.os.Environment
|
||||
import android.provider.Settings
|
||||
import android.view.LayoutInflater
|
||||
import android.view.Menu
|
||||
import android.view.MenuInflater
|
||||
@ -69,12 +70,12 @@ import org.kiwix.kiwixmobile.core.utils.files.FileUtils
|
||||
import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.adapter.BookOnDiskDelegate
|
||||
import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.adapter.BooksOnDiskAdapter
|
||||
import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.adapter.BooksOnDiskListItem
|
||||
import org.kiwix.kiwixmobile.zim_manager.ZimManageViewModel
|
||||
import org.kiwix.kiwixmobile.zim_manager.ZimManageViewModel.FileSelectActions
|
||||
import org.kiwix.kiwixmobile.zim_manager.ZimManageViewModel.FileSelectActions.RequestMultiSelection
|
||||
import org.kiwix.kiwixmobile.zim_manager.ZimManageViewModel.FileSelectActions.RequestNavigateTo
|
||||
import org.kiwix.kiwixmobile.zim_manager.ZimManageViewModel.FileSelectActions.RequestSelect
|
||||
import org.kiwix.kiwixmobile.zim_manager.fileselect_view.FileSelectListState
|
||||
import org.kiwix.kiwixmobile.zimManager.ZimManageViewModel
|
||||
import org.kiwix.kiwixmobile.zimManager.ZimManageViewModel.FileSelectActions
|
||||
import org.kiwix.kiwixmobile.zimManager.ZimManageViewModel.FileSelectActions.RequestMultiSelection
|
||||
import org.kiwix.kiwixmobile.zimManager.ZimManageViewModel.FileSelectActions.RequestNavigateTo
|
||||
import org.kiwix.kiwixmobile.zimManager.ZimManageViewModel.FileSelectActions.RequestSelect
|
||||
import org.kiwix.kiwixmobile.zimManager.fileselectView.FileSelectListState
|
||||
import java.io.File
|
||||
import javax.inject.Inject
|
||||
|
||||
@ -94,10 +95,12 @@ class LocalLibraryFragment : BaseFragment() {
|
||||
}
|
||||
|
||||
private val bookDelegate: BookOnDiskDelegate.BookDelegate by lazy {
|
||||
BookOnDiskDelegate.BookDelegate(sharedPreferenceUtil,
|
||||
BookOnDiskDelegate.BookDelegate(
|
||||
sharedPreferenceUtil,
|
||||
{ offerAction(RequestNavigateTo(it)) },
|
||||
{ offerAction(RequestMultiSelection(it)) },
|
||||
{ offerAction(RequestSelect(it)) })
|
||||
{ offerAction(RequestSelect(it)) }
|
||||
)
|
||||
}
|
||||
private val booksOnDiskAdapter: BooksOnDiskAdapter by lazy {
|
||||
BooksOnDiskAdapter(bookDelegate, BookOnDiskDelegate.LanguageDelegate)
|
||||
@ -138,9 +141,9 @@ class LocalLibraryFragment : BaseFragment() {
|
||||
}
|
||||
zimManageViewModel.fileSelectListStates.observe(viewLifecycleOwner, Observer(::render))
|
||||
disposable.add(sideEffects())
|
||||
zimManageViewModel.deviceListIsRefreshing.observe(viewLifecycleOwner, Observer {
|
||||
zimManageViewModel.deviceListIsRefreshing.observe(viewLifecycleOwner) {
|
||||
zim_swiperefresh.isRefreshing = it!!
|
||||
})
|
||||
}
|
||||
if (savedInstanceState != null && savedInstanceState.getBoolean(WAS_IN_ACTION_MODE)) {
|
||||
zimManageViewModel.fileSelectActions.offer(FileSelectActions.RestartActionMode)
|
||||
}
|
||||
@ -148,6 +151,15 @@ class LocalLibraryFragment : BaseFragment() {
|
||||
go_to_downloads_button_no_files.setOnClickListener {
|
||||
offerAction(FileSelectActions.UserClickedDownloadBooksButton)
|
||||
}
|
||||
hideFilePickerButton()
|
||||
}
|
||||
|
||||
private fun hideFilePickerButton() {
|
||||
if (sharedPreferenceUtil.isPlayStoreBuild) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
select_file.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
|
||||
select_file.setOnClickListener {
|
||||
showFileChooser()
|
||||
@ -229,7 +241,8 @@ class LocalLibraryFragment : BaseFragment() {
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
checkPermissions()
|
||||
if (!sharedPreferenceUtil.isPlayStoreBuildWithAndroid11OrAbove())
|
||||
checkPermissions()
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
@ -273,39 +286,59 @@ class LocalLibraryFragment : BaseFragment() {
|
||||
Manifest.permission.READ_EXTERNAL_STORAGE
|
||||
) != PackageManager.PERMISSION_GRANTED
|
||||
) {
|
||||
context.toast(R.string.request_storage)
|
||||
requestPermissions(
|
||||
arrayOf(
|
||||
Manifest.permission.READ_EXTERNAL_STORAGE,
|
||||
Manifest.permission.WRITE_EXTERNAL_STORAGE
|
||||
),
|
||||
REQUEST_STORAGE_PERMISSION
|
||||
)
|
||||
} else {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
if (Environment.isExternalStorageManager()) {
|
||||
// We already have permission!!
|
||||
requestFileSystemCheck()
|
||||
} else {
|
||||
if (sharedPreferenceUtil.manageExternalFilesPermissionDialog) {
|
||||
// We should only ask for first time, If the users wants to revoke settings
|
||||
// then they can directly toggle this feature from settings screen
|
||||
sharedPreferenceUtil.manageExternalFilesPermissionDialog = false
|
||||
// Show Dialog and Go to settings to give permission
|
||||
dialogShower.show(
|
||||
KiwixDialog.ManageExternalFilesPermissionDialog,
|
||||
{
|
||||
this.activity?.let(FragmentActivity::navigateToSettings)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
dialogShower.show(
|
||||
KiwixDialog.StoragePermissionRationale,
|
||||
::openAppSettings
|
||||
)
|
||||
} else {
|
||||
context.toast(R.string.request_storage)
|
||||
requestPermissions(
|
||||
arrayOf(
|
||||
Manifest.permission.READ_EXTERNAL_STORAGE,
|
||||
Manifest.permission.WRITE_EXTERNAL_STORAGE
|
||||
),
|
||||
REQUEST_STORAGE_PERMISSION
|
||||
)
|
||||
}
|
||||
} else {
|
||||
if (sharedPreferenceUtil.isPlayStoreBuild) {
|
||||
requestFileSystemCheck()
|
||||
} else {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
if (Environment.isExternalStorageManager()) {
|
||||
// We already have permission!!
|
||||
requestFileSystemCheck()
|
||||
} else {
|
||||
if (sharedPreferenceUtil.manageExternalFilesPermissionDialog) {
|
||||
// We should only ask for first time, If the users wants to revoke settings
|
||||
// then they can directly toggle this feature from settings screen
|
||||
sharedPreferenceUtil.manageExternalFilesPermissionDialog = false
|
||||
// Show Dialog and Go to settings to give permission
|
||||
dialogShower.show(
|
||||
KiwixDialog.ManageExternalFilesPermissionDialog,
|
||||
{
|
||||
this.activity?.let(FragmentActivity::navigateToSettings)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
requestFileSystemCheck()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun openAppSettings() {
|
||||
val uri: Uri = Uri.fromParts("package", requireActivity().packageName, null)
|
||||
val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply {
|
||||
flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
data = uri
|
||||
}
|
||||
startActivity(intent)
|
||||
}
|
||||
|
||||
private fun requestFileSystemCheck() {
|
||||
zimManageViewModel.requestFileSystemCheck.onNext(Unit)
|
||||
}
|
||||
|
@ -43,10 +43,13 @@ import androidx.core.app.ActivityCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.observe
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.tonyodev.fetch2.Status
|
||||
import eu.mhutti1.utils.storage.StorageDevice
|
||||
import eu.mhutti1.utils.storage.StorageSelectDialog
|
||||
import kotlinx.android.synthetic.main.fragment_destination_download.allowInternetPermissionButton
|
||||
import kotlinx.android.synthetic.main.fragment_destination_download.libraryErrorText
|
||||
import kotlinx.android.synthetic.main.fragment_destination_download.libraryList
|
||||
import kotlinx.android.synthetic.main.fragment_destination_download.librarySwipeRefresh
|
||||
@ -78,12 +81,12 @@ import org.kiwix.kiwixmobile.core.utils.dialog.KiwixDialog
|
||||
import org.kiwix.kiwixmobile.core.utils.dialog.KiwixDialog.SelectFolder
|
||||
import org.kiwix.kiwixmobile.core.utils.dialog.KiwixDialog.YesNoDialog.WifiOnly
|
||||
import org.kiwix.kiwixmobile.core.utils.files.FileUtils.getPathFromUri
|
||||
import org.kiwix.kiwixmobile.zim_manager.NetworkState
|
||||
import org.kiwix.kiwixmobile.zim_manager.ZimManageViewModel
|
||||
import org.kiwix.kiwixmobile.zim_manager.library_view.AvailableSpaceCalculator
|
||||
import org.kiwix.kiwixmobile.zim_manager.library_view.adapter.LibraryAdapter
|
||||
import org.kiwix.kiwixmobile.zim_manager.library_view.adapter.LibraryDelegate
|
||||
import org.kiwix.kiwixmobile.zim_manager.library_view.adapter.LibraryListItem
|
||||
import org.kiwix.kiwixmobile.zimManager.NetworkState
|
||||
import org.kiwix.kiwixmobile.zimManager.ZimManageViewModel
|
||||
import org.kiwix.kiwixmobile.zimManager.libraryView.AvailableSpaceCalculator
|
||||
import org.kiwix.kiwixmobile.zimManager.libraryView.adapter.LibraryAdapter
|
||||
import org.kiwix.kiwixmobile.zimManager.libraryView.adapter.LibraryDelegate
|
||||
import org.kiwix.kiwixmobile.zimManager.libraryView.adapter.LibraryListItem
|
||||
import javax.inject.Inject
|
||||
|
||||
class OnlineLibraryFragment : BaseFragment(), FragmentActivityExtensions {
|
||||
@ -91,11 +94,11 @@ class OnlineLibraryFragment : BaseFragment(), FragmentActivityExtensions {
|
||||
@Inject lateinit var conMan: ConnectivityManager
|
||||
@Inject lateinit var downloader: Downloader
|
||||
@Inject lateinit var dialogShower: DialogShower
|
||||
@Inject lateinit var alertDialogShower: AlertDialogShower
|
||||
@Inject lateinit var sharedPreferenceUtil: SharedPreferenceUtil
|
||||
@Inject lateinit var viewModelFactory: ViewModelProvider.Factory
|
||||
@Inject lateinit var bookUtils: BookUtils
|
||||
@Inject lateinit var availableSpaceCalculator: AvailableSpaceCalculator
|
||||
@Inject lateinit var alertDialogShower: AlertDialogShower
|
||||
private val zimManageViewModel by lazy {
|
||||
requireActivity().viewModel<ZimManageViewModel>(viewModelFactory)
|
||||
}
|
||||
@ -104,9 +107,18 @@ class OnlineLibraryFragment : BaseFragment(), FragmentActivityExtensions {
|
||||
LibraryAdapter(
|
||||
LibraryDelegate.BookDelegate(bookUtils, ::onBookItemClick),
|
||||
LibraryDelegate.DownloadDelegate {
|
||||
dialogShower.show(
|
||||
KiwixDialog.YesNoDialog.StopDownload,
|
||||
{ downloader.cancelDownload(it.downloadId) })
|
||||
if (it.currentDownloadState == Status.FAILED) {
|
||||
if (isNotConnected) {
|
||||
noInternetSnackbar()
|
||||
} else {
|
||||
downloader.retryDownload(it.downloadId)
|
||||
}
|
||||
} else {
|
||||
dialogShower.show(
|
||||
KiwixDialog.YesNoDialog.StopDownload,
|
||||
{ downloader.cancelDownload(it.downloadId) }
|
||||
)
|
||||
}
|
||||
},
|
||||
LibraryDelegate.DividerDelegate
|
||||
)
|
||||
@ -152,31 +164,49 @@ class OnlineLibraryFragment : BaseFragment(), FragmentActivityExtensions {
|
||||
viewLifecycleOwner, Observer(::onRefreshStateChange)
|
||||
)
|
||||
zimManageViewModel.networkStates.observe(viewLifecycleOwner, Observer(::onNetworkStateChange))
|
||||
zimManageViewModel.shouldShowWifiOnlyDialog.observe(viewLifecycleOwner, Observer {
|
||||
zimManageViewModel.shouldShowWifiOnlyDialog.observe(
|
||||
viewLifecycleOwner
|
||||
) {
|
||||
if (it) {
|
||||
dialogShower.show(
|
||||
WifiOnly,
|
||||
{
|
||||
sharedPreferenceUtil.putPrefWifiOnly(false)
|
||||
zimManageViewModel.shouldShowWifiOnlyDialog.value = false
|
||||
},
|
||||
{
|
||||
onRefreshStateChange(false)
|
||||
context.toast(
|
||||
resources.getString(R.string.denied_internet_permission_message),
|
||||
Toast.LENGTH_SHORT
|
||||
)
|
||||
}
|
||||
)
|
||||
showInternetPermissionDialog()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// hides keyboard when scrolled
|
||||
libraryList.addOnScrollListener(SimpleRecyclerViewScrollListener { _, newState ->
|
||||
if (newState == RecyclerView.SCROLL_STATE_DRAGGING) {
|
||||
libraryList.closeKeyboard()
|
||||
libraryList.addOnScrollListener(
|
||||
SimpleRecyclerViewScrollListener { _, newState ->
|
||||
if (newState == RecyclerView.SCROLL_STATE_DRAGGING) {
|
||||
libraryList.closeKeyboard()
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
allowInternetPermissionButton.setOnClickListener {
|
||||
showInternetPermissionDialog()
|
||||
}
|
||||
}
|
||||
|
||||
private fun showInternetPermissionDialog() {
|
||||
dialogShower.show(
|
||||
WifiOnly,
|
||||
{
|
||||
onRefreshStateChange(true)
|
||||
libraryErrorText.visibility = View.GONE
|
||||
allowInternetPermissionButton.visibility = View.GONE
|
||||
sharedPreferenceUtil.putPrefWifiOnly(false)
|
||||
zimManageViewModel.shouldShowWifiOnlyDialog.value = false
|
||||
},
|
||||
{
|
||||
onRefreshStateChange(false)
|
||||
context.toast(
|
||||
resources.getString(R.string.denied_internet_permission_message),
|
||||
Toast.LENGTH_SHORT
|
||||
)
|
||||
libraryErrorText.setText(R.string.allow_internet_permission_message)
|
||||
libraryErrorText.visibility = View.VISIBLE
|
||||
allowInternetPermissionButton.visibility = View.VISIBLE
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||
@ -227,8 +257,10 @@ class OnlineLibraryFragment : BaseFragment(), FragmentActivityExtensions {
|
||||
libraryErrorText.setText(R.string.no_network_connection)
|
||||
libraryErrorText.visibility = View.VISIBLE
|
||||
}
|
||||
allowInternetPermissionButton.visibility = View.GONE
|
||||
librarySwipeRefresh.isRefreshing = false
|
||||
}
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
|
||||
@ -255,6 +287,7 @@ class OnlineLibraryFragment : BaseFragment(), FragmentActivityExtensions {
|
||||
} else {
|
||||
libraryErrorText.visibility = View.GONE
|
||||
}
|
||||
allowInternetPermissionButton.visibility = View.GONE
|
||||
}
|
||||
|
||||
private fun refreshFragment() {
|
||||
@ -277,16 +310,24 @@ class OnlineLibraryFragment : BaseFragment(), FragmentActivityExtensions {
|
||||
)
|
||||
sharedPreferenceUtil.putStoragePosition(INTERNAL_SELECT_POSITION)
|
||||
} else {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
val view = LayoutInflater.from(activity).inflate(R.layout.select_folder_dialog, null)
|
||||
dialogShower.show(SelectFolder { view }, ::selectFolder)
|
||||
if (sharedPreferenceUtil.isPlayStoreBuild) {
|
||||
setExternalStoragePath(storageDevice)
|
||||
} else {
|
||||
sharedPreferenceUtil.putPrefStorage(storageDevice.name)
|
||||
sharedPreferenceUtil.putStoragePosition(EXTERNAL_SELECT_POSITION)
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
val view = LayoutInflater.from(activity).inflate(R.layout.select_folder_dialog, null)
|
||||
dialogShower.show(SelectFolder { view }, ::selectFolder)
|
||||
} else {
|
||||
setExternalStoragePath(storageDevice)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun setExternalStoragePath(storageDevice: StorageDevice) {
|
||||
sharedPreferenceUtil.putPrefStorage(storageDevice.name)
|
||||
sharedPreferenceUtil.putStoragePosition(EXTERNAL_SELECT_POSITION)
|
||||
}
|
||||
|
||||
private fun selectFolder() {
|
||||
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)
|
||||
intent.addFlags(
|
||||
@ -319,21 +360,24 @@ class OnlineLibraryFragment : BaseFragment(), FragmentActivityExtensions {
|
||||
}
|
||||
|
||||
private fun checkExternalStorageWritePermission(): Boolean {
|
||||
return hasPermission(WRITE_EXTERNAL_STORAGE).also { permissionGranted ->
|
||||
if (!permissionGranted) {
|
||||
if (shouldShowRationale(WRITE_EXTERNAL_STORAGE)) {
|
||||
alertDialogShower.show(
|
||||
KiwixDialog.WriteStoragePermissionRationale,
|
||||
::requestExternalStoragePermission
|
||||
)
|
||||
} else {
|
||||
alertDialogShower.show(
|
||||
KiwixDialog.WriteStoragePermissionRationale,
|
||||
::openAppSettings
|
||||
)
|
||||
if (!sharedPreferenceUtil.isPlayStoreBuildWithAndroid11OrAbove()) {
|
||||
return hasPermission(WRITE_EXTERNAL_STORAGE).also { permissionGranted ->
|
||||
if (!permissionGranted) {
|
||||
if (shouldShowRationale(WRITE_EXTERNAL_STORAGE)) {
|
||||
alertDialogShower.show(
|
||||
KiwixDialog.WriteStoragePermissionRationale,
|
||||
::requestExternalStoragePermission
|
||||
)
|
||||
} else {
|
||||
alertDialogShower.show(
|
||||
KiwixDialog.WriteStoragePermissionRationale,
|
||||
::openAppSettings
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
private fun openAppSettings() {
|
||||
@ -366,7 +410,8 @@ class OnlineLibraryFragment : BaseFragment(), FragmentActivityExtensions {
|
||||
permissions[0] == Manifest.permission.WRITE_EXTERNAL_STORAGE
|
||||
) {
|
||||
if (grantResults[0] != PERMISSION_GRANTED) {
|
||||
checkExternalStorageWritePermission()
|
||||
if (!sharedPreferenceUtil.isPlayStoreBuildWithAndroid11OrAbove())
|
||||
checkExternalStorageWritePermission()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -388,17 +433,24 @@ class OnlineLibraryFragment : BaseFragment(), FragmentActivityExtensions {
|
||||
})
|
||||
return
|
||||
}
|
||||
else -> availableSpaceCalculator.hasAvailableSpaceFor(item,
|
||||
{ downloadFile(item.book) },
|
||||
{
|
||||
libraryList.snack(
|
||||
getString(R.string.download_no_space) +
|
||||
"\n" + getString(R.string.space_available) + " " +
|
||||
it,
|
||||
R.string.download_change_storage,
|
||||
::showStorageSelectDialog
|
||||
)
|
||||
})
|
||||
else -> if (sharedPreferenceUtil.showStorageOption) {
|
||||
showStorageConfigureDialog()
|
||||
} else {
|
||||
availableSpaceCalculator.hasAvailableSpaceFor(
|
||||
item,
|
||||
{ downloadFile(item.book) },
|
||||
{
|
||||
libraryList.snack(
|
||||
"""
|
||||
${getString(R.string.download_no_space)}
|
||||
${getString(R.string.space_available)} $it
|
||||
""".trimIndent(),
|
||||
R.string.download_change_storage,
|
||||
::showStorageSelectDialog
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -408,4 +460,17 @@ class OnlineLibraryFragment : BaseFragment(), FragmentActivityExtensions {
|
||||
onSelectAction = ::storeDeviceInPreferences
|
||||
}
|
||||
.show(requireFragmentManager(), getString(R.string.pref_storage))
|
||||
|
||||
private fun showStorageConfigureDialog() {
|
||||
alertDialogShower.show(
|
||||
KiwixDialog.StorageConfigure,
|
||||
{
|
||||
showStorageSelectDialog()
|
||||
sharedPreferenceUtil.showStorageOption = false
|
||||
},
|
||||
{
|
||||
sharedPreferenceUtil.showStorageOption = false
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -268,7 +268,7 @@ class KiwixReaderFragment : CoreReaderFragment() {
|
||||
override fun createWebView(attrs: AttributeSet): ToolbarScrollingKiwixWebView {
|
||||
return ToolbarScrollingKiwixWebView(
|
||||
requireContext(), this, attrs, activityMainRoot as ViewGroup, videoView,
|
||||
CoreWebViewClient(this, zimReaderContainer),
|
||||
CoreWebViewClient(this, zimReaderContainer, sharedPreferenceUtil),
|
||||
toolbarContainer, bottomToolbar, sharedPreferenceUtil = sharedPreferenceUtil,
|
||||
parentNavigationBar = requireActivity().bottom_nav_view
|
||||
)
|
||||
|
@ -41,8 +41,9 @@ class KiwixPrefsFragment : CorePrefsFragment() {
|
||||
|
||||
override fun setStorage() {
|
||||
findPreference<Preference>(PREF_STORAGE)?.title = getString(
|
||||
if (sharedPreferenceUtil.prefStorage == internalStorage()?.let
|
||||
(sharedPreferenceUtil::getPublicDirectoryPath)
|
||||
if (sharedPreferenceUtil.prefStorage == internalStorage()?.let(
|
||||
sharedPreferenceUtil::getPublicDirectoryPath
|
||||
)
|
||||
) R.string.internal_storage
|
||||
else R.string.external_storage
|
||||
)
|
||||
@ -54,7 +55,7 @@ class KiwixPrefsFragment : CorePrefsFragment() {
|
||||
|
||||
private fun setMangeExternalStoragePermission() {
|
||||
val permissionPref = findPreference<Preference>(PREF_MANAGE_EXTERNAL_STORAGE_PERMISSION)
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && !sharedPreferenceUtil.isPlayStoreBuild) {
|
||||
showPermissionPreference()
|
||||
val externalStorageManager = Environment.isExternalStorageManager()
|
||||
if (externalStorageManager) {
|
||||
|
@ -35,6 +35,7 @@ import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.Toast
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.app.ActivityCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
@ -62,7 +63,6 @@ import org.kiwix.kiwixmobile.webserver.wifi_hotspot.HotspotService
|
||||
import org.kiwix.kiwixmobile.webserver.wifi_hotspot.HotspotService.ACTION_CHECK_IP_ADDRESS
|
||||
import org.kiwix.kiwixmobile.webserver.wifi_hotspot.HotspotService.ACTION_START_SERVER
|
||||
import org.kiwix.kiwixmobile.webserver.wifi_hotspot.HotspotService.ACTION_STOP_SERVER
|
||||
import java.util.ArrayList
|
||||
import javax.inject.Inject
|
||||
|
||||
class ZimHostFragment : BaseFragment(), ZimHostCallbacks, ZimHostContract.View {
|
||||
@ -140,7 +140,13 @@ class ZimHostFragment : BaseFragment(), ZimHostCallbacks, ZimHostContract.View {
|
||||
}
|
||||
|
||||
startServerButton.setOnClickListener {
|
||||
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P || checkCoarseLocationAccessPermission()) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU ||
|
||||
checkNearbyWifiDevicesPermission()
|
||||
) {
|
||||
startStopServer()
|
||||
} else if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P ||
|
||||
checkCoarseLocationAccessPermission()
|
||||
) {
|
||||
startStopServer()
|
||||
}
|
||||
}
|
||||
@ -169,6 +175,33 @@ class ZimHostFragment : BaseFragment(), ZimHostCallbacks, ZimHostContract.View {
|
||||
true
|
||||
}
|
||||
|
||||
private fun checkNearbyWifiDevicesPermission(): Boolean =
|
||||
if (ContextCompat.checkSelfPermission(
|
||||
requireActivity(),
|
||||
Manifest.permission.NEARBY_WIFI_DEVICES
|
||||
) == PackageManager.PERMISSION_DENIED
|
||||
) {
|
||||
if (ActivityCompat.shouldShowRequestPermissionRationale(
|
||||
requireActivity(),
|
||||
Manifest.permission.NEARBY_WIFI_DEVICES
|
||||
)
|
||||
) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
alertDialogShower.show(
|
||||
KiwixDialog.NearbyWifiPermissionRationaleOnHostZimFile,
|
||||
::askNearbyWifiDevicesPermission
|
||||
)
|
||||
}
|
||||
} else {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
askNearbyWifiDevicesPermission()
|
||||
}
|
||||
}
|
||||
false
|
||||
} else {
|
||||
true
|
||||
}
|
||||
|
||||
override fun onRequestPermissionsResult(
|
||||
requestCode: Int,
|
||||
permissions: Array<out String>,
|
||||
@ -189,6 +222,14 @@ class ZimHostFragment : BaseFragment(), ZimHostCallbacks, ZimHostContract.View {
|
||||
)
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
|
||||
private fun askNearbyWifiDevicesPermission() {
|
||||
ActivityCompat.requestPermissions(
|
||||
requireActivity(), arrayOf(Manifest.permission.NEARBY_WIFI_DEVICES),
|
||||
PERMISSION_REQUEST_CODE_COARSE_LOCATION
|
||||
)
|
||||
}
|
||||
|
||||
private fun startStopServer() {
|
||||
when {
|
||||
ServerUtils.isServerStarted -> stopServer()
|
||||
@ -391,6 +432,6 @@ class ZimHostFragment : BaseFragment(), ZimHostCallbacks, ZimHostContract.View {
|
||||
|
||||
companion object {
|
||||
const val SELECTED_ZIM_PATHS_KEY = "selected_zim_paths"
|
||||
private const val PERMISSION_REQUEST_CODE_COARSE_LOCATION = 10
|
||||
const val PERMISSION_REQUEST_CODE_COARSE_LOCATION = 10
|
||||
}
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ class ZimHostPresenter @Inject internal constructor(private val dataSource: Data
|
||||
Presenter {
|
||||
|
||||
override fun loadBooks(previouslyHostedBooks: Set<String>) {
|
||||
dataSource.languageCategorizedBooks
|
||||
dataSource.getLanguageCategorizedBooks()
|
||||
.map { books ->
|
||||
books
|
||||
.filterIsInstance<BooksOnDiskListItem.BookOnDisk>()
|
||||
|
@ -17,6 +17,7 @@
|
||||
*/
|
||||
package org.kiwix.kiwixmobile.webserver.wifi_hotspot
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Notification
|
||||
import android.app.NotificationChannel
|
||||
import android.app.NotificationManager
|
||||
@ -38,18 +39,20 @@ class HotspotNotificationManager @Inject constructor(
|
||||
|
||||
private fun hotspotNotificationChannel() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
notificationManager.createNotificationChannel(NotificationChannel(
|
||||
HOTSPOT_SERVICE_CHANNEL_ID,
|
||||
context.getString(R.string.hotspot_service_channel_name),
|
||||
NotificationManager.IMPORTANCE_DEFAULT
|
||||
).apply {
|
||||
description = context.getString(R.string.hotspot_channel_description)
|
||||
setSound(null, null)
|
||||
})
|
||||
notificationManager.createNotificationChannel(
|
||||
NotificationChannel(
|
||||
HOTSPOT_SERVICE_CHANNEL_ID,
|
||||
context.getString(R.string.hotspot_service_channel_name),
|
||||
NotificationManager.IMPORTANCE_DEFAULT
|
||||
).apply {
|
||||
description = context.getString(R.string.hotspot_channel_description)
|
||||
setSound(null, null)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun buildForegroundNotification(): Notification {
|
||||
@SuppressLint("UnspecifiedImmutableFlag") fun buildForegroundNotification(): Notification {
|
||||
val contentIntent = NavDeepLinkBuilder(context).setComponentName(
|
||||
KiwixMainActivity::class.java
|
||||
)
|
||||
@ -60,8 +63,16 @@ class HotspotNotificationManager @Inject constructor(
|
||||
val stopIntent = Intent(context, HotspotService::class.java).setAction(
|
||||
HotspotService.ACTION_STOP_SERVER
|
||||
)
|
||||
val stopHotspot =
|
||||
val stopHotspot = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
PendingIntent.getService(
|
||||
context,
|
||||
0,
|
||||
stopIntent,
|
||||
PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
|
||||
)
|
||||
} else {
|
||||
PendingIntent.getService(context, 0, stopIntent, PendingIntent.FLAG_UPDATE_CURRENT)
|
||||
}
|
||||
return NotificationCompat.Builder(context)
|
||||
.setContentTitle(context.getString(R.string.hotspot_notification_content_title))
|
||||
.setContentText(context.getString(R.string.hotspot_running))
|
||||
|
@ -16,7 +16,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package org.kiwix.kiwixmobile.zim_manager
|
||||
package org.kiwix.kiwixmobile.zimManager
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
@ -16,7 +16,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package org.kiwix.kiwixmobile.zim_manager
|
||||
package org.kiwix.kiwixmobile.zimManager
|
||||
|
||||
import android.content.Context
|
||||
import org.kiwix.kiwixmobile.core.zim_manager.Language
|
@ -15,7 +15,7 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package org.kiwix.kiwixmobile.zim_manager
|
||||
package org.kiwix.kiwixmobile.zimManager
|
||||
|
||||
import android.os.FileObserver
|
||||
import io.reactivex.Flowable
|
||||
@ -23,13 +23,13 @@ import io.reactivex.functions.BiFunction
|
||||
import io.reactivex.processors.BehaviorProcessor
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil
|
||||
import org.kiwix.kiwixmobile.zim_manager.Fat32Checker.FileSystemState.CanWrite4GbFile
|
||||
import org.kiwix.kiwixmobile.zim_manager.Fat32Checker.FileSystemState.CannotWrite4GbFile
|
||||
import org.kiwix.kiwixmobile.zim_manager.Fat32Checker.FileSystemState.NotEnoughSpaceFor4GbFile
|
||||
import org.kiwix.kiwixmobile.zim_manager.Fat32Checker.FileSystemState.Unknown
|
||||
import org.kiwix.kiwixmobile.zim_manager.FileSystemCapability.CANNOT_WRITE_4GB
|
||||
import org.kiwix.kiwixmobile.zim_manager.FileSystemCapability.CAN_WRITE_4GB
|
||||
import org.kiwix.kiwixmobile.zim_manager.FileSystemCapability.INCONCLUSIVE
|
||||
import org.kiwix.kiwixmobile.zimManager.Fat32Checker.FileSystemState.CanWrite4GbFile
|
||||
import org.kiwix.kiwixmobile.zimManager.Fat32Checker.FileSystemState.CannotWrite4GbFile
|
||||
import org.kiwix.kiwixmobile.zimManager.Fat32Checker.FileSystemState.NotEnoughSpaceFor4GbFile
|
||||
import org.kiwix.kiwixmobile.zimManager.Fat32Checker.FileSystemState.Unknown
|
||||
import org.kiwix.kiwixmobile.zimManager.FileSystemCapability.CANNOT_WRITE_4GB
|
||||
import org.kiwix.kiwixmobile.zimManager.FileSystemCapability.CAN_WRITE_4GB
|
||||
import org.kiwix.kiwixmobile.zimManager.FileSystemCapability.INCONCLUSIVE
|
||||
import java.io.File
|
||||
|
||||
class Fat32Checker constructor(
|
||||
@ -77,7 +77,7 @@ class Fat32Checker constructor(
|
||||
}
|
||||
|
||||
private fun canCreate4GbFile(storage: String): Boolean {
|
||||
fileSystemCheckers.forEach {
|
||||
fileSystemCheckers.iterator().forEach {
|
||||
when (it.checkFilesystemSupports4GbFiles(storage)) {
|
||||
CAN_WRITE_4GB -> return@canCreate4GbFile true
|
||||
CANNOT_WRITE_4GB -> return@canCreate4GbFile false
|
@ -16,7 +16,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package org.kiwix.kiwixmobile.zim_manager
|
||||
package org.kiwix.kiwixmobile.zimManager
|
||||
|
||||
interface FileSystemChecker {
|
||||
fun checkFilesystemSupports4GbFiles(path: String): FileSystemCapability
|
@ -16,12 +16,12 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package org.kiwix.kiwixmobile.zim_manager
|
||||
package org.kiwix.kiwixmobile.zimManager
|
||||
|
||||
import android.util.Log
|
||||
import org.kiwix.kiwixmobile.zim_manager.FileSystemCapability.CANNOT_WRITE_4GB
|
||||
import org.kiwix.kiwixmobile.zim_manager.FileSystemCapability.CAN_WRITE_4GB
|
||||
import org.kiwix.kiwixmobile.zim_manager.FileSystemCapability.INCONCLUSIVE
|
||||
import org.kiwix.kiwixmobile.zimManager.FileSystemCapability.CANNOT_WRITE_4GB
|
||||
import org.kiwix.kiwixmobile.zimManager.FileSystemCapability.CAN_WRITE_4GB
|
||||
import org.kiwix.kiwixmobile.zimManager.FileSystemCapability.INCONCLUSIVE
|
||||
import java.io.File
|
||||
import java.io.RandomAccessFile
|
||||
|
||||
@ -32,9 +32,10 @@ class FileWritingFileSystemChecker : FileSystemChecker {
|
||||
when (val capability = readCapability(resultFile)) {
|
||||
CAN_WRITE_4GB,
|
||||
CANNOT_WRITE_4GB -> return capability
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
return with(File("$path/large_file_test.txt"), {
|
||||
return with(File("$path/large_file_test.txt")) {
|
||||
deleteIfExists()
|
||||
try {
|
||||
RandomAccessFile(this.path, "rw").use {
|
||||
@ -50,7 +51,7 @@ class FileWritingFileSystemChecker : FileSystemChecker {
|
||||
} finally {
|
||||
deleteIfExists()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
private fun readCapability(resultFile: File) =
|
@ -16,13 +16,13 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package org.kiwix.kiwixmobile.zim_manager
|
||||
package org.kiwix.kiwixmobile.zimManager
|
||||
|
||||
import org.kiwix.kiwixmobile.core.zim_manager.MountInfo
|
||||
import org.kiwix.kiwixmobile.core.zim_manager.MountPointProducer
|
||||
import org.kiwix.kiwixmobile.zim_manager.FileSystemCapability.CANNOT_WRITE_4GB
|
||||
import org.kiwix.kiwixmobile.zim_manager.FileSystemCapability.CAN_WRITE_4GB
|
||||
import org.kiwix.kiwixmobile.zim_manager.FileSystemCapability.INCONCLUSIVE
|
||||
import org.kiwix.kiwixmobile.zimManager.FileSystemCapability.CANNOT_WRITE_4GB
|
||||
import org.kiwix.kiwixmobile.zimManager.FileSystemCapability.CAN_WRITE_4GB
|
||||
import org.kiwix.kiwixmobile.zimManager.FileSystemCapability.INCONCLUSIVE
|
||||
import javax.inject.Inject
|
||||
|
||||
class MountFileSystemChecker @Inject constructor(
|
@ -16,7 +16,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package org.kiwix.kiwixmobile.zim_manager
|
||||
package org.kiwix.kiwixmobile.zimManager
|
||||
|
||||
enum class NetworkState {
|
||||
CONNECTED,
|
@ -16,7 +16,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package org.kiwix.kiwixmobile.zim_manager
|
||||
package org.kiwix.kiwixmobile.zimManager
|
||||
|
||||
import androidx.viewpager.widget.ViewPager.OnPageChangeListener
|
||||
|
@ -16,7 +16,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package org.kiwix.kiwixmobile.zim_manager
|
||||
package org.kiwix.kiwixmobile.zimManager
|
||||
|
||||
import android.app.Application
|
||||
import android.net.ConnectivityManager
|
||||
@ -51,27 +51,27 @@ import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.SelectionMode.MULT
|
||||
import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.SelectionMode.NORMAL
|
||||
import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.adapter.BooksOnDiskListItem
|
||||
import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.adapter.BooksOnDiskListItem.BookOnDisk
|
||||
import org.kiwix.kiwixmobile.zim_manager.Fat32Checker.FileSystemState
|
||||
import org.kiwix.kiwixmobile.zim_manager.NetworkState.CONNECTED
|
||||
import org.kiwix.kiwixmobile.zim_manager.ZimManageViewModel.FileSelectActions.MultiModeFinished
|
||||
import org.kiwix.kiwixmobile.zim_manager.ZimManageViewModel.FileSelectActions.RequestDeleteMultiSelection
|
||||
import org.kiwix.kiwixmobile.zim_manager.ZimManageViewModel.FileSelectActions.RequestMultiSelection
|
||||
import org.kiwix.kiwixmobile.zim_manager.ZimManageViewModel.FileSelectActions.RequestNavigateTo
|
||||
import org.kiwix.kiwixmobile.zim_manager.ZimManageViewModel.FileSelectActions.RequestSelect
|
||||
import org.kiwix.kiwixmobile.zim_manager.ZimManageViewModel.FileSelectActions.RequestShareMultiSelection
|
||||
import org.kiwix.kiwixmobile.zim_manager.ZimManageViewModel.FileSelectActions.RestartActionMode
|
||||
import org.kiwix.kiwixmobile.zim_manager.ZimManageViewModel.FileSelectActions.UserClickedDownloadBooksButton
|
||||
import org.kiwix.kiwixmobile.zim_manager.fileselect_view.FileSelectListState
|
||||
import org.kiwix.kiwixmobile.zim_manager.fileselect_view.effects.DeleteFiles
|
||||
import org.kiwix.kiwixmobile.zim_manager.fileselect_view.effects.NavigateToDownloads
|
||||
import org.kiwix.kiwixmobile.zim_manager.fileselect_view.effects.None
|
||||
import org.kiwix.kiwixmobile.zim_manager.fileselect_view.effects.OpenFileWithNavigation
|
||||
import org.kiwix.kiwixmobile.zim_manager.fileselect_view.effects.ShareFiles
|
||||
import org.kiwix.kiwixmobile.zim_manager.fileselect_view.effects.StartMultiSelection
|
||||
import org.kiwix.kiwixmobile.zim_manager.library_view.adapter.LibraryListItem
|
||||
import org.kiwix.kiwixmobile.zim_manager.library_view.adapter.LibraryListItem.BookItem
|
||||
import org.kiwix.kiwixmobile.zim_manager.library_view.adapter.LibraryListItem.DividerItem
|
||||
import org.kiwix.kiwixmobile.zim_manager.library_view.adapter.LibraryListItem.LibraryDownloadItem
|
||||
import org.kiwix.kiwixmobile.zimManager.Fat32Checker.FileSystemState
|
||||
import org.kiwix.kiwixmobile.zimManager.NetworkState.CONNECTED
|
||||
import org.kiwix.kiwixmobile.zimManager.ZimManageViewModel.FileSelectActions.MultiModeFinished
|
||||
import org.kiwix.kiwixmobile.zimManager.ZimManageViewModel.FileSelectActions.RequestDeleteMultiSelection
|
||||
import org.kiwix.kiwixmobile.zimManager.ZimManageViewModel.FileSelectActions.RequestMultiSelection
|
||||
import org.kiwix.kiwixmobile.zimManager.ZimManageViewModel.FileSelectActions.RequestNavigateTo
|
||||
import org.kiwix.kiwixmobile.zimManager.ZimManageViewModel.FileSelectActions.RequestSelect
|
||||
import org.kiwix.kiwixmobile.zimManager.ZimManageViewModel.FileSelectActions.RequestShareMultiSelection
|
||||
import org.kiwix.kiwixmobile.zimManager.ZimManageViewModel.FileSelectActions.RestartActionMode
|
||||
import org.kiwix.kiwixmobile.zimManager.ZimManageViewModel.FileSelectActions.UserClickedDownloadBooksButton
|
||||
import org.kiwix.kiwixmobile.zimManager.fileselectView.FileSelectListState
|
||||
import org.kiwix.kiwixmobile.zimManager.fileselectView.effects.DeleteFiles
|
||||
import org.kiwix.kiwixmobile.zimManager.fileselectView.effects.NavigateToDownloads
|
||||
import org.kiwix.kiwixmobile.zimManager.fileselectView.effects.None
|
||||
import org.kiwix.kiwixmobile.zimManager.fileselectView.effects.OpenFileWithNavigation
|
||||
import org.kiwix.kiwixmobile.zimManager.fileselectView.effects.ShareFiles
|
||||
import org.kiwix.kiwixmobile.zimManager.fileselectView.effects.StartMultiSelection
|
||||
import org.kiwix.kiwixmobile.zimManager.libraryView.adapter.LibraryListItem
|
||||
import org.kiwix.kiwixmobile.zimManager.libraryView.adapter.LibraryListItem.BookItem
|
||||
import org.kiwix.kiwixmobile.zimManager.libraryView.adapter.LibraryListItem.DividerItem
|
||||
import org.kiwix.kiwixmobile.zimManager.libraryView.adapter.LibraryListItem.LibraryDownloadItem
|
||||
import java.util.LinkedList
|
||||
import java.util.Locale
|
||||
import java.util.concurrent.TimeUnit.MILLISECONDS
|
||||
@ -409,7 +409,7 @@ class ZimManageViewModel @Inject constructor(
|
||||
) = if (filter.isEmpty()) {
|
||||
unDownloadedBooks
|
||||
} else {
|
||||
unDownloadedBooks.forEach { it.calculateSearchMatches(filter, bookUtils) }
|
||||
unDownloadedBooks.iterator().forEach { it.calculateSearchMatches(filter, bookUtils) }
|
||||
unDownloadedBooks.filter { it.searchMatches > 0 }
|
||||
}
|
||||
|
||||
@ -462,15 +462,16 @@ class ZimManageViewModel @Inject constructor(
|
||||
|
||||
private fun updateBookItems() =
|
||||
dataSource.booksOnDiskAsListItems()
|
||||
.subscribe(
|
||||
{ newList ->
|
||||
fileSelectListStates.postValue(
|
||||
fileSelectListStates.value?.let { inheritSelections(it, newList) }
|
||||
?: FileSelectListState(newList)
|
||||
)
|
||||
},
|
||||
Throwable::printStackTrace
|
||||
)
|
||||
.subscribe({ newList ->
|
||||
fileSelectListStates.postValue(
|
||||
fileSelectListStates.value?.let {
|
||||
inheritSelections(
|
||||
it,
|
||||
newList.toMutableList()
|
||||
)
|
||||
} ?: FileSelectListState(newList)
|
||||
)
|
||||
}, Throwable::printStackTrace)
|
||||
|
||||
private fun inheritSelections(
|
||||
oldState: FileSelectListState,
|
||||
@ -483,6 +484,7 @@ class ZimManageViewModel @Inject constructor(
|
||||
oldBookOnDisk.id == newBookOnDisk.id
|
||||
}
|
||||
newBookOnDisk.apply { isSelected = firstOrNull?.isSelected ?: false }
|
||||
})
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
@ -15,7 +15,7 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package org.kiwix.kiwixmobile.zim_manager.fileselect_view
|
||||
package org.kiwix.kiwixmobile.zimManager.fileselectView
|
||||
|
||||
import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.SelectionMode
|
||||
import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.SelectionMode.NORMAL
|
@ -16,7 +16,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package org.kiwix.kiwixmobile.zim_manager.fileselect_view.effects
|
||||
package org.kiwix.kiwixmobile.zimManager.fileselectView.effects
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import org.kiwix.kiwixmobile.R
|
@ -16,7 +16,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package org.kiwix.kiwixmobile.zim_manager.fileselect_view.effects
|
||||
package org.kiwix.kiwixmobile.zimManager.fileselectView.effects
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import org.kiwix.kiwixmobile.core.base.SideEffect
|
@ -16,7 +16,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package org.kiwix.kiwixmobile.zim_manager.fileselect_view.effects
|
||||
package org.kiwix.kiwixmobile.zimManager.fileselectView.effects
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import org.kiwix.kiwixmobile.core.base.SideEffect
|
@ -16,7 +16,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package org.kiwix.kiwixmobile.zim_manager.fileselect_view.effects
|
||||
package org.kiwix.kiwixmobile.zimManager.fileselectView.effects
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.net.toUri
|
@ -16,7 +16,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package org.kiwix.kiwixmobile.zim_manager.fileselect_view.effects
|
||||
package org.kiwix.kiwixmobile.zimManager.fileselectView.effects
|
||||
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
@ -16,7 +16,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package org.kiwix.kiwixmobile.zim_manager.fileselect_view.effects
|
||||
package org.kiwix.kiwixmobile.zimManager.fileselectView.effects
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.appcompat.view.ActionMode
|
||||
@ -24,10 +24,10 @@ import io.reactivex.processors.PublishProcessor
|
||||
import org.kiwix.kiwixmobile.R
|
||||
import org.kiwix.kiwixmobile.core.base.SideEffect
|
||||
import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.startActionMode
|
||||
import org.kiwix.kiwixmobile.zim_manager.ZimManageViewModel.FileSelectActions
|
||||
import org.kiwix.kiwixmobile.zim_manager.ZimManageViewModel.FileSelectActions.MultiModeFinished
|
||||
import org.kiwix.kiwixmobile.zim_manager.ZimManageViewModel.FileSelectActions.RequestDeleteMultiSelection
|
||||
import org.kiwix.kiwixmobile.zim_manager.ZimManageViewModel.FileSelectActions.RequestShareMultiSelection
|
||||
import org.kiwix.kiwixmobile.zimManager.ZimManageViewModel.FileSelectActions
|
||||
import org.kiwix.kiwixmobile.zimManager.ZimManageViewModel.FileSelectActions.MultiModeFinished
|
||||
import org.kiwix.kiwixmobile.zimManager.ZimManageViewModel.FileSelectActions.RequestDeleteMultiSelection
|
||||
import org.kiwix.kiwixmobile.zimManager.ZimManageViewModel.FileSelectActions.RequestShareMultiSelection
|
||||
|
||||
data class StartMultiSelection(
|
||||
val fileSelectActions: PublishProcessor<FileSelectActions>
|
@ -16,7 +16,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package org.kiwix.kiwixmobile.zim_manager.library_view
|
||||
package org.kiwix.kiwixmobile.zimManager.libraryView
|
||||
|
||||
import eu.mhutti1.utils.storage.Bytes
|
||||
import eu.mhutti1.utils.storage.Kb
|
||||
@ -25,7 +25,7 @@ import io.reactivex.schedulers.Schedulers
|
||||
import org.kiwix.kiwixmobile.core.dao.FetchDownloadDao
|
||||
import org.kiwix.kiwixmobile.core.downloader.model.DownloadModel
|
||||
import org.kiwix.kiwixmobile.core.settings.StorageCalculator
|
||||
import org.kiwix.kiwixmobile.zim_manager.library_view.adapter.LibraryListItem
|
||||
import org.kiwix.kiwixmobile.zimManager.libraryView.adapter.LibraryListItem
|
||||
import javax.inject.Inject
|
||||
|
||||
class AvailableSpaceCalculator @Inject constructor(
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Kiwix Android
|
||||
* Copyright (c) 2019 Kiwix <android.kiwix.org>
|
||||
* Copyright (c) 2022 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
|
||||
@ -15,30 +15,21 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package org.kiwix.kiwixmobile.zim_manager.library_view;
|
||||
package org.kiwix.kiwixmobile.zimManager.libraryView
|
||||
|
||||
import java.util.LinkedList;
|
||||
import org.kiwix.kiwixmobile.core.base.BaseContract;
|
||||
import org.kiwix.kiwixmobile.core.entity.LibraryNetworkEntity;
|
||||
import org.kiwix.kiwixmobile.core.entity.LibraryNetworkEntity.Book;
|
||||
import org.kiwix.kiwixmobile.core.base.BaseContract
|
||||
import org.kiwix.kiwixmobile.core.entity.LibraryNetworkEntity
|
||||
import java.util.LinkedList
|
||||
|
||||
/**
|
||||
* Created by EladKeyshawn on 06/04/2017.
|
||||
*/
|
||||
|
||||
public interface LibraryViewCallback extends BaseContract.View {
|
||||
|
||||
void showBooks(LinkedList<Book> books);
|
||||
|
||||
void displayNoNetworkConnection();
|
||||
|
||||
void displayNoItemsFound();
|
||||
|
||||
void displayNoItemsAvailable();
|
||||
|
||||
void displayScanningContent();
|
||||
|
||||
void stopScanningContent();
|
||||
|
||||
void downloadFile(LibraryNetworkEntity.Book book);
|
||||
interface LibraryViewCallback : BaseContract.View<Any?> {
|
||||
fun showBooks(books: LinkedList<LibraryNetworkEntity.Book?>?)
|
||||
fun displayNoNetworkConnection()
|
||||
fun displayNoItemsFound()
|
||||
fun displayNoItemsAvailable()
|
||||
fun displayScanningContent()
|
||||
fun stopScanningContent()
|
||||
fun downloadFile(book: LibraryNetworkEntity.Book?)
|
||||
}
|
@ -16,7 +16,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package org.kiwix.kiwixmobile.zim_manager.library_view.adapter
|
||||
package org.kiwix.kiwixmobile.zimManager.libraryView.adapter
|
||||
|
||||
import org.kiwix.kiwixmobile.core.base.adapter.AdapterDelegate
|
||||
import org.kiwix.kiwixmobile.core.base.adapter.BaseDelegateAdapter
|
@ -15,19 +15,19 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package org.kiwix.kiwixmobile.zim_manager.library_view.adapter
|
||||
package org.kiwix.kiwixmobile.zimManager.libraryView.adapter
|
||||
|
||||
import android.view.ViewGroup
|
||||
import org.kiwix.kiwixmobile.R
|
||||
import org.kiwix.kiwixmobile.core.base.adapter.AbsDelegateAdapter
|
||||
import org.kiwix.kiwixmobile.core.extensions.ViewGroupExtensions.inflate
|
||||
import org.kiwix.kiwixmobile.core.utils.BookUtils
|
||||
import org.kiwix.kiwixmobile.zim_manager.library_view.adapter.LibraryListItem.BookItem
|
||||
import org.kiwix.kiwixmobile.zim_manager.library_view.adapter.LibraryListItem.DividerItem
|
||||
import org.kiwix.kiwixmobile.zim_manager.library_view.adapter.LibraryListItem.LibraryDownloadItem
|
||||
import org.kiwix.kiwixmobile.zim_manager.library_view.adapter.LibraryViewHolder.DownloadViewHolder
|
||||
import org.kiwix.kiwixmobile.zim_manager.library_view.adapter.LibraryViewHolder.LibraryBookViewHolder
|
||||
import org.kiwix.kiwixmobile.zim_manager.library_view.adapter.LibraryViewHolder.LibraryDividerViewHolder
|
||||
import org.kiwix.kiwixmobile.zimManager.libraryView.adapter.LibraryListItem.BookItem
|
||||
import org.kiwix.kiwixmobile.zimManager.libraryView.adapter.LibraryListItem.DividerItem
|
||||
import org.kiwix.kiwixmobile.zimManager.libraryView.adapter.LibraryListItem.LibraryDownloadItem
|
||||
import org.kiwix.kiwixmobile.zimManager.libraryView.adapter.LibraryViewHolder.DownloadViewHolder
|
||||
import org.kiwix.kiwixmobile.zimManager.libraryView.adapter.LibraryViewHolder.LibraryBookViewHolder
|
||||
import org.kiwix.kiwixmobile.zimManager.libraryView.adapter.LibraryViewHolder.LibraryDividerViewHolder
|
||||
|
||||
sealed class LibraryDelegate<I : LibraryListItem, out VH : LibraryViewHolder<I>> :
|
||||
AbsDelegateAdapter<I, LibraryListItem, VH> {
|
@ -16,21 +16,22 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package org.kiwix.kiwixmobile.zim_manager.library_view.adapter
|
||||
package org.kiwix.kiwixmobile.zimManager.libraryView.adapter
|
||||
|
||||
import androidx.annotation.StringRes
|
||||
import com.tonyodev.fetch2.Status
|
||||
import org.kiwix.kiwixmobile.core.downloader.model.Base64String
|
||||
import org.kiwix.kiwixmobile.core.downloader.model.DownloadModel
|
||||
import org.kiwix.kiwixmobile.core.downloader.model.DownloadState
|
||||
import org.kiwix.kiwixmobile.core.downloader.model.Seconds
|
||||
import org.kiwix.kiwixmobile.core.entity.LibraryNetworkEntity.Book
|
||||
import org.kiwix.kiwixmobile.core.zim_manager.KiwixTag
|
||||
import org.kiwix.kiwixmobile.zim_manager.Fat32Checker
|
||||
import org.kiwix.kiwixmobile.zim_manager.Fat32Checker.FileSystemState
|
||||
import org.kiwix.kiwixmobile.zim_manager.Fat32Checker.FileSystemState.CanWrite4GbFile
|
||||
import org.kiwix.kiwixmobile.zim_manager.Fat32Checker.FileSystemState.CannotWrite4GbFile
|
||||
import org.kiwix.kiwixmobile.zim_manager.Fat32Checker.FileSystemState.NotEnoughSpaceFor4GbFile
|
||||
import org.kiwix.kiwixmobile.zim_manager.Fat32Checker.FileSystemState.Unknown
|
||||
import org.kiwix.kiwixmobile.zimManager.Fat32Checker
|
||||
import org.kiwix.kiwixmobile.zimManager.Fat32Checker.FileSystemState
|
||||
import org.kiwix.kiwixmobile.zimManager.Fat32Checker.FileSystemState.CanWrite4GbFile
|
||||
import org.kiwix.kiwixmobile.zimManager.Fat32Checker.FileSystemState.CannotWrite4GbFile
|
||||
import org.kiwix.kiwixmobile.zimManager.Fat32Checker.FileSystemState.NotEnoughSpaceFor4GbFile
|
||||
import org.kiwix.kiwixmobile.zimManager.Fat32Checker.FileSystemState.Unknown
|
||||
|
||||
sealed class LibraryListItem {
|
||||
abstract val id: Long
|
||||
@ -69,7 +70,8 @@ sealed class LibraryListItem {
|
||||
val progress: Int,
|
||||
val eta: Seconds,
|
||||
val downloadState: DownloadState,
|
||||
override val id: Long
|
||||
override val id: Long,
|
||||
val currentDownloadState: Status
|
||||
) : LibraryListItem() {
|
||||
|
||||
val readableEta: CharSequence = eta.takeIf { it.seconds > 0L }?.toHumanReadableTime() ?: ""
|
||||
@ -84,7 +86,8 @@ sealed class LibraryListItem {
|
||||
downloadModel.progress,
|
||||
Seconds(downloadModel.etaInMilliSeconds / 1000L),
|
||||
DownloadState.from(downloadModel.state, downloadModel.error),
|
||||
downloadModel.book.id.hashCode().toLong()
|
||||
downloadModel.book.id.hashCode().toLong(),
|
||||
downloadModel.state
|
||||
)
|
||||
}
|
||||
}
|
@ -16,13 +16,15 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package org.kiwix.kiwixmobile.zim_manager.library_view.adapter
|
||||
package org.kiwix.kiwixmobile.zimManager.libraryView.adapter
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.view.Gravity
|
||||
import android.view.View
|
||||
import android.view.View.MeasureSpec
|
||||
import android.widget.Toast
|
||||
import androidx.annotation.StringRes
|
||||
import com.tonyodev.fetch2.Status
|
||||
import kotlinx.android.synthetic.main.item_download.downloadProgress
|
||||
import kotlinx.android.synthetic.main.item_download.downloadState
|
||||
import kotlinx.android.synthetic.main.item_download.eta
|
||||
@ -47,11 +49,11 @@ import org.kiwix.kiwixmobile.core.extensions.setBitmap
|
||||
import org.kiwix.kiwixmobile.core.extensions.setTextAndVisibility
|
||||
import org.kiwix.kiwixmobile.core.utils.BookUtils
|
||||
import org.kiwix.kiwixmobile.core.zim_manager.KiloByte
|
||||
import org.kiwix.kiwixmobile.zim_manager.Fat32Checker.FileSystemState.CannotWrite4GbFile
|
||||
import org.kiwix.kiwixmobile.zim_manager.Fat32Checker.FileSystemState.Unknown
|
||||
import org.kiwix.kiwixmobile.zim_manager.library_view.adapter.LibraryListItem.BookItem
|
||||
import org.kiwix.kiwixmobile.zim_manager.library_view.adapter.LibraryListItem.DividerItem
|
||||
import org.kiwix.kiwixmobile.zim_manager.library_view.adapter.LibraryListItem.LibraryDownloadItem
|
||||
import org.kiwix.kiwixmobile.zimManager.Fat32Checker.FileSystemState.CannotWrite4GbFile
|
||||
import org.kiwix.kiwixmobile.zimManager.Fat32Checker.FileSystemState.Unknown
|
||||
import org.kiwix.kiwixmobile.zimManager.libraryView.adapter.LibraryListItem.BookItem
|
||||
import org.kiwix.kiwixmobile.zimManager.libraryView.adapter.LibraryListItem.DividerItem
|
||||
import org.kiwix.kiwixmobile.zimManager.libraryView.adapter.LibraryListItem.LibraryDownloadItem
|
||||
|
||||
sealed class LibraryViewHolder<in T : LibraryListItem>(containerView: View) :
|
||||
BaseViewHolder<T>(containerView) {
|
||||
@ -99,6 +101,9 @@ sealed class LibraryViewHolder<in T : LibraryListItem>(containerView: View) :
|
||||
downloadProgress.progress = item.progress
|
||||
stop.setOnClickListener { clickAction.invoke(item) }
|
||||
downloadState.text = item.downloadState.toReadableState(containerView.context)
|
||||
if (item.currentDownloadState == Status.FAILED) {
|
||||
clickAction.invoke(item)
|
||||
}
|
||||
eta.text = item.readableEta
|
||||
}
|
||||
}
|
||||
@ -110,6 +115,7 @@ sealed class LibraryViewHolder<in T : LibraryListItem>(containerView: View) :
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("ShowToast")
|
||||
private fun View.centreToast(@StringRes id: Int) {
|
||||
val locationXAndY = intArrayOf(0, 0)
|
||||
getLocationOnScreen(locationXAndY)
|
@ -61,7 +61,20 @@
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintVertical_bias="0.45" />
|
||||
app:layout_constraintVertical_bias="0.45"
|
||||
tools:ignore="RequiredSize" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/allowInternetPermissionButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="@string/allow"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/libraryErrorText" />
|
||||
|
||||
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
@ -64,6 +64,7 @@
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:ignore="RequiredSize"
|
||||
app:layout_constraintVertical_bias="0.45" />
|
||||
|
||||
<Button
|
||||
|
@ -86,6 +86,11 @@
|
||||
android:name="org.kiwix.kiwixmobile.core.page.bookmark.BookmarksFragment"
|
||||
android:label="BookmarksFragment"
|
||||
tools:layout="@layout/fragment_page" />
|
||||
<fragment
|
||||
android:id="@+id/notesFragment"
|
||||
android:name="org.kiwix.kiwixmobile.core.page.notes.NotesFragment"
|
||||
android:label="NotesFragment"
|
||||
tools:layout="@layout/fragment_page" />
|
||||
<fragment
|
||||
android:id="@+id/introFragment"
|
||||
android:name="org.kiwix.kiwixmobile.intro.IntroFragment"
|
||||
|
@ -10,4 +10,5 @@
|
||||
<string name="cannot_open_file">Échec de l’ouverture du fichier.\nEssayez de chercher ce fichier dans l’onglet Appareils de votre Bibliothèque.</string>
|
||||
<string name="send_files_title">Envoyer des fichiers</string>
|
||||
<string name="receive_files_title">Recevoir des fichiers</string>
|
||||
<string name="no_app_found_to_open">Aucune application trouvée pour sélectionner le fichier ZIM !</string>
|
||||
</resources>
|
||||
|
@ -9,4 +9,5 @@
|
||||
<string name="cannot_open_file">פתיחת הקובץ נכשלה\nנא לנסות לחפש את הקובץ הזה בלשונית \"מכשיר\" בספרייה שלך</string>
|
||||
<string name="send_files_title">שליחת קבצים</string>
|
||||
<string name="receive_files_title">קבלת קבצים</string>
|
||||
<string name="no_app_found_to_open">לא נמצא יישום שיכול לבחור קובץ zim!</string>
|
||||
</resources>
|
||||
|
@ -8,4 +8,5 @@
|
||||
<string name="cannot_open_file">Vekirina dosyeyê têk çû\nJi kerema xwe biceribîne ku vê dosyeyê di Hilpekîna Cîhazê ya Kitêbxaneya xwe de vekî</string>
|
||||
<string name="send_files_title">Dosyeyan Bişîne</string>
|
||||
<string name="receive_files_title">Dosyeyan Werbigire</string>
|
||||
<string name="no_app_found_to_open">Ji bo bijartina dosyeya zim-ê ti sepanekê nehate dîtin!</string>
|
||||
</resources>
|
||||
|
@ -8,4 +8,5 @@
|
||||
<string name="cannot_open_file">Не можев да ја отворам податотеката\nВидете дали можете да ја најдете во јазичето „Уред“ на вашата Библиотека</string>
|
||||
<string name="send_files_title">Испраќање на податотеки</string>
|
||||
<string name="receive_files_title">Примање на податотеки</string>
|
||||
<string name="no_app_found_to_open">Не пронајдов прилог за избирање на ZIM-податотека!</string>
|
||||
</resources>
|
||||
|
12
app/src/main/res/values-nqo/strings.xml
Normal file
12
app/src/main/res/values-nqo/strings.xml
Normal file
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Authors:
|
||||
* Aboubacar.banamoridou.toure
|
||||
* Lancine.kounfantoh.fofana
|
||||
-->
|
||||
<resources>
|
||||
<string name="file_system_does_not_support_4gb">ߌ ߟߊ߫ ߞߐߕߐ߮ ߞߊ߲ߞߋ ߕߴߊ߬ ߛߐ߲߬ ߠߊ߫ ߘߏ߬ߣߌ߲߬ ߘߐ߫ ߞߊ߬ ߕߊ߬ߡߌ߲߬ 4GB ߟߊ߫</string>
|
||||
<string name="detecting_file_system">ߡߊ߬ߟߐ߲߬ߠߌ߲ ߦߴߌ ߘߐ߫ ߣߴߌ ߟߊ߫ ߞߊ߲ߞߋ ߘߌ߫ ߛߋ߫ 4GB ߞߐߕߐ߮ ߛߌ߲ߘߌ߫ ߟߊ߫</string>
|
||||
<string name="send_files_title">ߞߐߕߐ߮ ߟߎ߬ ߟߊߕߊ߯</string>
|
||||
<string name="receive_files_title">ߞߐߕߐ߮ ߟߎ߬ ߟߊߛߣߍ߫</string>
|
||||
<string name="no_app_found_to_open">ߟߥߊ߬ߟߌ߬ߟߊ߲߫ ߡߊ߫ ߛߐ߬ߘߐ߲߫ ߞߊ߬ ߛߋ߫ ߖ߭ߌߡ ߞߐߕߐ߮ ߛߎߥߊ߲ߘߌ߫ ߟߊ߫߹</string>
|
||||
</resources>
|
@ -1,5 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Authors:
|
||||
* Strebski
|
||||
* WaldiSt
|
||||
-->
|
||||
<resources>
|
||||
@ -8,4 +9,5 @@
|
||||
<string name="cannot_open_file">Nie można otworzyć pliku\nSpróbuj wyszukać ten plik na karcie Urządzenia twojej biblioteki</string>
|
||||
<string name="send_files_title">Wyślij pliki</string>
|
||||
<string name="receive_files_title">Odbierz pliki</string>
|
||||
<string name="no_app_found_to_open">Nie znaleziono aplikacji do wybrania pliku zim!</string>
|
||||
</resources>
|
||||
|
@ -1,5 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Authors:
|
||||
* Fenixs-ru
|
||||
* Smavrina
|
||||
-->
|
||||
<resources>
|
||||
@ -8,4 +9,5 @@
|
||||
<string name="cannot_open_file">Невозможно открыть файл\nПожалуйста, попытайтесь найти этот файл во вкладке “Устройство” в вашей библиотеке</string>
|
||||
<string name="send_files_title">Послать файлы</string>
|
||||
<string name="receive_files_title">Получить файлы</string>
|
||||
<string name="no_app_found_to_open">Не найдено приложение для выбора ZIM-файла!</string>
|
||||
</resources>
|
||||
|
@ -8,4 +8,5 @@
|
||||
<string name="cannot_open_file">Abertura de su documentu fallida\nPro praghere proa a chircare custu documentu in s\'Ischeda de sos Dispositivos de sa Biblioteca tua</string>
|
||||
<string name="send_files_title">Imbia documentos</string>
|
||||
<string name="receive_files_title">Retzi documentos</string>
|
||||
<string name="no_app_found_to_open">Peruna aplicatzione atzapada pro seletzionare s\'archìviu zim!</string>
|
||||
</resources>
|
||||
|
@ -8,4 +8,5 @@
|
||||
<string name="cannot_open_file">Nepodarilo sa otvoriť súbor\nProsím skúste tento súbor nájsť na karte zariadenia vo vašej knižnici</string>
|
||||
<string name="send_files_title">Poslať súbory</string>
|
||||
<string name="receive_files_title">Prijať súbory</string>
|
||||
<string name="no_app_found_to_open">Nepodarilo sa nájsť aplikáciu pre výber súboru zim!</string>
|
||||
</resources>
|
||||
|
@ -1,6 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Authors:
|
||||
* BaRaN6161 TURK
|
||||
* Hedda
|
||||
* MuratTheTurkish
|
||||
-->
|
||||
<resources>
|
||||
@ -9,4 +10,5 @@
|
||||
<string name="cannot_open_file">Dosya açılamadı\nLütfen bu dosyayı Kitaplığınızın Cihaz Sekmesinde aramayı deneyin</string>
|
||||
<string name="send_files_title">Dosya Yükle</string>
|
||||
<string name="receive_files_title">Dosya Al</string>
|
||||
<string name="no_app_found_to_open">zim dosyasını seçecek uygulama bulunamadı!</string>
|
||||
</resources>
|
||||
|
@ -8,4 +8,5 @@
|
||||
<string name="cannot_open_file">檔案開啟失敗\n請嘗試查看在您圖書館設備分頁裡的該檔案</string>
|
||||
<string name="send_files_title">發送檔案</string>
|
||||
<string name="receive_files_title">接收檔案</string>
|
||||
<string name="no_app_found_to_open">沒有找到選擇 zim 檔案的應用程式!</string>
|
||||
</resources>
|
||||
|
@ -1,5 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Authors:
|
||||
* GuoPC
|
||||
* Lynzrand
|
||||
* StarrySky
|
||||
-->
|
||||
@ -9,4 +10,5 @@
|
||||
<string name="cannot_open_file">未能打开文件\n请尝试在图书馆界面的“设备”选项卡中寻找这个文件</string>
|
||||
<string name="send_files_title">发送文件</string>
|
||||
<string name="receive_files_title">接收文件</string>
|
||||
<string name="no_app_found_to_open">没有找到选择 ZIM 文件的应用程序!</string>
|
||||
</resources>
|
||||
|
@ -16,7 +16,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package org.kiwix.kiwixmobile.zim_manager
|
||||
package org.kiwix.kiwixmobile.zimManager
|
||||
|
||||
import android.app.Application
|
||||
import android.net.ConnectivityManager
|
||||
@ -50,23 +50,23 @@ import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.SelectionMode.MULT
|
||||
import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.SelectionMode.NORMAL
|
||||
import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.adapter.BooksOnDiskListItem
|
||||
import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.adapter.BooksOnDiskListItem.BookOnDisk
|
||||
import org.kiwix.kiwixmobile.zim_manager.Fat32Checker.FileSystemState
|
||||
import org.kiwix.kiwixmobile.zim_manager.Fat32Checker.FileSystemState.CanWrite4GbFile
|
||||
import org.kiwix.kiwixmobile.zim_manager.Fat32Checker.FileSystemState.CannotWrite4GbFile
|
||||
import org.kiwix.kiwixmobile.zim_manager.NetworkState.CONNECTED
|
||||
import org.kiwix.kiwixmobile.zim_manager.NetworkState.NOT_CONNECTED
|
||||
import org.kiwix.kiwixmobile.zim_manager.ZimManageViewModel.FileSelectActions.MultiModeFinished
|
||||
import org.kiwix.kiwixmobile.zim_manager.ZimManageViewModel.FileSelectActions.RequestDeleteMultiSelection
|
||||
import org.kiwix.kiwixmobile.zim_manager.ZimManageViewModel.FileSelectActions.RequestMultiSelection
|
||||
import org.kiwix.kiwixmobile.zim_manager.ZimManageViewModel.FileSelectActions.RequestSelect
|
||||
import org.kiwix.kiwixmobile.zim_manager.ZimManageViewModel.FileSelectActions.RequestShareMultiSelection
|
||||
import org.kiwix.kiwixmobile.zim_manager.ZimManageViewModel.FileSelectActions.RestartActionMode
|
||||
import org.kiwix.kiwixmobile.zim_manager.fileselect_view.FileSelectListState
|
||||
import org.kiwix.kiwixmobile.zim_manager.fileselect_view.effects.DeleteFiles
|
||||
import org.kiwix.kiwixmobile.zim_manager.fileselect_view.effects.None
|
||||
import org.kiwix.kiwixmobile.zim_manager.fileselect_view.effects.ShareFiles
|
||||
import org.kiwix.kiwixmobile.zim_manager.fileselect_view.effects.StartMultiSelection
|
||||
import org.kiwix.kiwixmobile.zim_manager.library_view.adapter.LibraryListItem
|
||||
import org.kiwix.kiwixmobile.zimManager.Fat32Checker.FileSystemState
|
||||
import org.kiwix.kiwixmobile.zimManager.Fat32Checker.FileSystemState.CanWrite4GbFile
|
||||
import org.kiwix.kiwixmobile.zimManager.Fat32Checker.FileSystemState.CannotWrite4GbFile
|
||||
import org.kiwix.kiwixmobile.zimManager.NetworkState.CONNECTED
|
||||
import org.kiwix.kiwixmobile.zimManager.NetworkState.NOT_CONNECTED
|
||||
import org.kiwix.kiwixmobile.zimManager.ZimManageViewModel.FileSelectActions.MultiModeFinished
|
||||
import org.kiwix.kiwixmobile.zimManager.ZimManageViewModel.FileSelectActions.RequestDeleteMultiSelection
|
||||
import org.kiwix.kiwixmobile.zimManager.ZimManageViewModel.FileSelectActions.RequestMultiSelection
|
||||
import org.kiwix.kiwixmobile.zimManager.ZimManageViewModel.FileSelectActions.RequestSelect
|
||||
import org.kiwix.kiwixmobile.zimManager.ZimManageViewModel.FileSelectActions.RequestShareMultiSelection
|
||||
import org.kiwix.kiwixmobile.zimManager.ZimManageViewModel.FileSelectActions.RestartActionMode
|
||||
import org.kiwix.kiwixmobile.zimManager.fileselectView.FileSelectListState
|
||||
import org.kiwix.kiwixmobile.zimManager.fileselectView.effects.DeleteFiles
|
||||
import org.kiwix.kiwixmobile.zimManager.fileselectView.effects.None
|
||||
import org.kiwix.kiwixmobile.zimManager.fileselectView.effects.ShareFiles
|
||||
import org.kiwix.kiwixmobile.zimManager.fileselectView.effects.StartMultiSelection
|
||||
import org.kiwix.kiwixmobile.zimManager.libraryView.adapter.LibraryListItem
|
||||
import org.kiwix.sharedFunctions.InstantExecutorExtension
|
||||
import org.kiwix.sharedFunctions.book
|
||||
import org.kiwix.sharedFunctions.bookOnDisk
|
@ -16,7 +16,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package org.kiwix.kiwixmobile.zim_manager.library_view.adapter
|
||||
package org.kiwix.kiwixmobile.zimManager.libraryView.adapter
|
||||
|
||||
import io.mockk.clearAllMocks
|
||||
import io.mockk.every
|
||||
@ -25,13 +25,13 @@ import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.kiwix.kiwixmobile.core.entity.LibraryNetworkEntity.Book
|
||||
import org.kiwix.kiwixmobile.zim_manager.Fat32Checker
|
||||
import org.kiwix.kiwixmobile.zim_manager.Fat32Checker.FileSystemState
|
||||
import org.kiwix.kiwixmobile.zim_manager.Fat32Checker.FileSystemState.CanWrite4GbFile
|
||||
import org.kiwix.kiwixmobile.zim_manager.Fat32Checker.FileSystemState.CannotWrite4GbFile
|
||||
import org.kiwix.kiwixmobile.zim_manager.Fat32Checker.FileSystemState.NotEnoughSpaceFor4GbFile
|
||||
import org.kiwix.kiwixmobile.zim_manager.Fat32Checker.FileSystemState.Unknown
|
||||
import org.kiwix.kiwixmobile.zim_manager.library_view.adapter.LibraryListItem.BookItem
|
||||
import org.kiwix.kiwixmobile.zimManager.Fat32Checker
|
||||
import org.kiwix.kiwixmobile.zimManager.Fat32Checker.FileSystemState
|
||||
import org.kiwix.kiwixmobile.zimManager.Fat32Checker.FileSystemState.CanWrite4GbFile
|
||||
import org.kiwix.kiwixmobile.zimManager.Fat32Checker.FileSystemState.CannotWrite4GbFile
|
||||
import org.kiwix.kiwixmobile.zimManager.Fat32Checker.FileSystemState.NotEnoughSpaceFor4GbFile
|
||||
import org.kiwix.kiwixmobile.zimManager.Fat32Checker.FileSystemState.Unknown
|
||||
import org.kiwix.kiwixmobile.zimManager.libraryView.adapter.LibraryListItem.BookItem
|
||||
|
||||
internal class LibraryListItemTest {
|
||||
|
@ -12,12 +12,13 @@ repositories {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation("com.android.tools.build:gradle:4.0.1")
|
||||
implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.72")
|
||||
implementation("com.hiya:jacoco-android:0.2")
|
||||
implementation("org.jlleitschuh.gradle:ktlint-gradle:9.2.1")
|
||||
implementation("com.android.tools.build:gradle:7.1.0")
|
||||
implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.0")
|
||||
implementation("com.dicedmelon.gradle:jacoco-android:0.1.5")
|
||||
implementation("org.jlleitschuh.gradle:ktlint-gradle:10.3.0")
|
||||
implementation("com.google.apis:google-api-services-androidpublisher:v3-rev129-1.25.0")
|
||||
implementation("io.gitlab.arturbosch.detekt:detekt-gradle-plugin:1.9.1")
|
||||
implementation("io.gitlab.arturbosch.detekt:detekt-gradle-plugin:1.20.0")
|
||||
implementation("com.googlecode.json-simple:json-simple:1.1")
|
||||
|
||||
implementation(gradleApi())
|
||||
implementation(localGroovy())
|
||||
|
@ -19,8 +19,8 @@
|
||||
import org.gradle.api.JavaVersion
|
||||
|
||||
object Config {
|
||||
const val compileSdk = 30
|
||||
const val compileSdk = 33
|
||||
const val minSdk = 21
|
||||
const val targetSdk = 30
|
||||
const val targetSdk = 33
|
||||
val javaVersion = JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ object Libs {
|
||||
* https://developer.android.com/testing
|
||||
*/
|
||||
const val espresso_contrib: String = "androidx.test.espresso:espresso-contrib:" +
|
||||
Versions.androidx_test_espresso
|
||||
Versions.androidx_test_espresso_contrib
|
||||
|
||||
/**
|
||||
* https://developer.android.com/testing
|
||||
@ -138,7 +138,7 @@ object Libs {
|
||||
* https://developer.android.com/topic/libraries/architecture/index.html
|
||||
*/
|
||||
const val navigation_ui_ktx: String = "androidx.navigation:navigation-ui-ktx:" +
|
||||
Versions.androidx_navigation
|
||||
Versions.navigation_ui_ktx
|
||||
|
||||
/**
|
||||
* https://github.com/google/dagger
|
||||
@ -420,4 +420,10 @@ object Libs {
|
||||
* https://developer.android.com/testing
|
||||
*/
|
||||
const val junit: String = "androidx.test.ext:junit:" + Versions.junit
|
||||
|
||||
/**
|
||||
* https://developer.android.com/reference/com/google/android/play/core/release-notes
|
||||
*/
|
||||
const val google_android_play_core: String =
|
||||
"com.google.android.play:core:" + Versions.google_android_play_core
|
||||
}
|
||||
|
@ -12,23 +12,29 @@ import org.gradle.plugin.use.PluginDependencySpec
|
||||
*/
|
||||
object Versions {
|
||||
|
||||
const val google_android_play_core: String = "1.7.3"
|
||||
|
||||
const val document_file_version: String = "1.0.1"
|
||||
|
||||
const val org_jetbrains_kotlinx_kotlinx_coroutines: String = "1.4.1"
|
||||
|
||||
const val androidx_test_espresso: String = "3.3.0"
|
||||
const val androidx_test_espresso: String = "3.4.0"
|
||||
|
||||
const val androidx_test_espresso_contrib: String = "3.3.0"
|
||||
|
||||
const val com_squareup_retrofit2: String = "2.9.0"
|
||||
|
||||
const val com_squareup_okhttp3: String = "4.9.0"
|
||||
|
||||
const val org_jetbrains_kotlin: String = "1.4.20"
|
||||
const val org_jetbrains_kotlin: String = "1.7.0"
|
||||
|
||||
const val androidx_navigation: String = "2.3.1"
|
||||
|
||||
const val com_google_dagger: String = "2.29.1"
|
||||
const val navigation_ui_ktx: String = "2.4.1"
|
||||
|
||||
const val com_yahoo_squidb: String = "2.0.0" // available: "3.2.3"
|
||||
const val com_google_dagger: String = "2.42"
|
||||
|
||||
const val com_yahoo_squidb: String = "4.0.0-beta.2" // available: "3.2.3"
|
||||
|
||||
const val com_jakewharton: String = "10.2.3"
|
||||
|
||||
@ -42,15 +48,15 @@ object Versions {
|
||||
|
||||
const val android_arch_lifecycle_extensions: String = "1.1.1"
|
||||
|
||||
const val com_android_tools_build_gradle: String = "4.0.1" // available: "4.1.1"
|
||||
const val com_android_tools_build_gradle: String = "7.1.0"
|
||||
|
||||
const val de_fayard_buildsrcversions_gradle_plugin: String = "0.7.0"
|
||||
|
||||
const val com_github_triplet_play_gradle_plugin: String = "2.8.0" // available: "3.0.0"
|
||||
const val com_github_triplet_play_gradle_plugin: String = "3.7.0"
|
||||
|
||||
const val javax_annotation_api: String = "1.3.2"
|
||||
|
||||
const val leakcanary_android: String = "2.5"
|
||||
const val leakcanary_android: String = "2.9.1"
|
||||
|
||||
const val constraintlayout: String = "2.0.4"
|
||||
|
||||
|
@ -23,8 +23,6 @@ import Libs
|
||||
import com.android.build.gradle.BaseExtension
|
||||
import io.gitlab.arturbosch.detekt.extensions.DetektExtension
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.tasks.testing.Test
|
||||
import org.gradle.kotlin.dsl.KotlinClosure1
|
||||
import org.gradle.kotlin.dsl.apply
|
||||
import org.gradle.kotlin.dsl.dependencies
|
||||
import org.gradle.testing.jacoco.plugins.JacocoPluginExtension
|
||||
@ -39,7 +37,7 @@ class AllProjectConfigurer {
|
||||
target.plugins.apply("kotlin-android")
|
||||
target.plugins.apply("kotlin-android-extensions")
|
||||
target.plugins.apply("kotlin-kapt")
|
||||
target.plugins.apply("com.hiya.jacoco-android")
|
||||
target.plugins.apply("com.dicedmelon.gradle.jacoco-android")
|
||||
target.plugins.apply("org.jlleitschuh.gradle.ktlint")
|
||||
target.plugins.apply("io.gitlab.arturbosch.detekt")
|
||||
target.plugins.apply("androidx.navigation.safeargs")
|
||||
@ -75,19 +73,21 @@ class AllProjectConfigurer {
|
||||
execution = "ANDROIDX_TEST_ORCHESTRATOR"
|
||||
unitTests.apply {
|
||||
isReturnDefaultValues = true
|
||||
all(KotlinClosure1<Any, Test>({
|
||||
(this as Test).also { testTask ->
|
||||
all {
|
||||
it.also { testTask ->
|
||||
testTask.useJUnitPlatform()
|
||||
testTask.testLogging {
|
||||
setEvents(setOf("passed", "skipped", "failed", "standardOut", "standardError"))
|
||||
outputs.upToDateWhen { false }
|
||||
testTask.outputs.upToDateWhen { false }
|
||||
showStandardStreams = true
|
||||
}
|
||||
testTask.extensions
|
||||
.getByType(JacocoTaskExtension::class.java)
|
||||
.isIncludeNoLocationClasses = true
|
||||
.getByType(JacocoTaskExtension::class.java).apply {
|
||||
isIncludeNoLocationClasses = true
|
||||
excludes = listOf("jdk.internal.*")
|
||||
}
|
||||
}
|
||||
}, this))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -104,16 +104,18 @@ class AllProjectConfigurer {
|
||||
"CheckResult",
|
||||
"LabelFor",
|
||||
"LogConditional",
|
||||
"ConvertToWebp"
|
||||
)
|
||||
|
||||
warning(
|
||||
"ConvertToWebp",
|
||||
//TODO remove this when we remove jcenter from gradle
|
||||
"JcenterRepositoryObsolete",
|
||||
"UnknownNullness",
|
||||
"SelectableText",
|
||||
"MissingTranslation",
|
||||
"IconDensities",
|
||||
"ContentDescription",
|
||||
"IconDipSize"
|
||||
"IconDipSize",
|
||||
"UnusedResources",
|
||||
"NonConstantResourceId",
|
||||
"NotifyDataSetChanged"
|
||||
)
|
||||
lintConfig = target.rootProject.file("lintConfig.xml")
|
||||
}
|
||||
@ -138,15 +140,29 @@ class AllProjectConfigurer {
|
||||
}
|
||||
}
|
||||
|
||||
fun configureJacoco(target: Project) {
|
||||
target.configurations.all {
|
||||
resolutionStrategy {
|
||||
eachDependency {
|
||||
if ("org.jacoco" == this.requested.group) {
|
||||
useVersion("0.8.7")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun configurePlugins(target: Project) {
|
||||
target.run {
|
||||
configureExtension<AndroidExtensionsExtension> { isExperimental = true }
|
||||
configureExtension<JacocoPluginExtension> { toolVersion = "0.8.7" }
|
||||
configureExtension<KtlintExtension> { android.set(true) }
|
||||
configureExtension<DetektExtension> {
|
||||
buildUponDefaultConfig = true
|
||||
allRules = false
|
||||
config = target.files("${target.rootDir}/config/detekt/detekt.yml")
|
||||
baseline = project.file("detekt_baseline.xml")
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -188,6 +204,7 @@ class AllProjectConfigurer {
|
||||
implementation(Libs.rxandroid)
|
||||
implementation(Libs.rxjava)
|
||||
implementation(Libs.preference_ktx)
|
||||
implementation(Libs.google_android_play_core)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -44,6 +44,7 @@ class KiwixConfigurationPlugin : Plugin<Project> {
|
||||
allProjectConfigurer.configurePlugins(target)
|
||||
allProjectConfigurer.applyScripts(target)
|
||||
allProjectConfigurer.configureDependencies(target)
|
||||
allProjectConfigurer.configureJacoco(target)
|
||||
}
|
||||
|
||||
private fun doDefaultConfiguration(target: Project) {
|
||||
|
@ -2,10 +2,10 @@ build:
|
||||
maxIssues: 0
|
||||
excludeCorrectable: false
|
||||
weights:
|
||||
# complexity: 2
|
||||
# LongParameterList: 1
|
||||
# style: 1
|
||||
# comments: 1
|
||||
# complexity: 2
|
||||
# LongParameterList: 1
|
||||
# style: 1
|
||||
# comments: 1
|
||||
|
||||
config:
|
||||
validation: true
|
||||
@ -25,11 +25,11 @@ processors:
|
||||
console-reports:
|
||||
active: true
|
||||
exclude:
|
||||
- 'ProjectStatisticsReport'
|
||||
- 'ComplexityReport'
|
||||
- 'NotificationReport'
|
||||
# - 'FindingsReport'
|
||||
- 'FileBasedFindingsReport'
|
||||
- 'ProjectStatisticsReport'
|
||||
- 'ComplexityReport'
|
||||
- 'NotificationReport'
|
||||
# - 'FindingsReport'
|
||||
- 'FileBasedFindingsReport'
|
||||
|
||||
comments:
|
||||
active: true
|
||||
@ -180,130 +180,22 @@ exceptions:
|
||||
active: true
|
||||
excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt"
|
||||
exceptionNames:
|
||||
- ArrayIndexOutOfBoundsException
|
||||
- Error
|
||||
- Exception
|
||||
- IllegalMonitorStateException
|
||||
- NullPointerException
|
||||
- IndexOutOfBoundsException
|
||||
- RuntimeException
|
||||
- Throwable
|
||||
- ArrayIndexOutOfBoundsException
|
||||
- Error
|
||||
- Exception
|
||||
- IllegalMonitorStateException
|
||||
- NullPointerException
|
||||
- IndexOutOfBoundsException
|
||||
- RuntimeException
|
||||
- Throwable
|
||||
allowedExceptionNameRegex: "^(_|(ignore|expected).*)"
|
||||
TooGenericExceptionThrown:
|
||||
active: true
|
||||
exceptionNames:
|
||||
- Error
|
||||
- Exception
|
||||
- Throwable
|
||||
- RuntimeException
|
||||
|
||||
formatting:
|
||||
active: true
|
||||
android: false
|
||||
autoCorrect: true
|
||||
AnnotationOnSeparateLine:
|
||||
active: false
|
||||
autoCorrect: true
|
||||
ChainWrapping:
|
||||
active: true
|
||||
autoCorrect: true
|
||||
CommentSpacing:
|
||||
active: true
|
||||
autoCorrect: true
|
||||
EnumEntryNameCase:
|
||||
active: false
|
||||
autoCorrect: true
|
||||
Filename:
|
||||
active: true
|
||||
FinalNewline:
|
||||
active: true
|
||||
autoCorrect: true
|
||||
ImportOrdering:
|
||||
active: false
|
||||
autoCorrect: true
|
||||
Indentation:
|
||||
active: false
|
||||
autoCorrect: true
|
||||
indentSize: 4
|
||||
continuationIndentSize: 4
|
||||
MaximumLineLength:
|
||||
active: true
|
||||
maxLineLength: 120
|
||||
ModifierOrdering:
|
||||
active: true
|
||||
autoCorrect: true
|
||||
MultiLineIfElse:
|
||||
active: true
|
||||
autoCorrect: true
|
||||
NoBlankLineBeforeRbrace:
|
||||
active: true
|
||||
autoCorrect: true
|
||||
NoConsecutiveBlankLines:
|
||||
active: true
|
||||
autoCorrect: true
|
||||
NoEmptyClassBody:
|
||||
active: true
|
||||
autoCorrect: true
|
||||
NoEmptyFirstLineInMethodBlock:
|
||||
active: false
|
||||
autoCorrect: true
|
||||
NoLineBreakAfterElse:
|
||||
active: true
|
||||
autoCorrect: true
|
||||
NoLineBreakBeforeAssignment:
|
||||
active: true
|
||||
autoCorrect: true
|
||||
NoMultipleSpaces:
|
||||
active: true
|
||||
autoCorrect: true
|
||||
NoSemicolons:
|
||||
active: true
|
||||
autoCorrect: true
|
||||
NoTrailingSpaces:
|
||||
active: true
|
||||
autoCorrect: true
|
||||
NoUnitReturn:
|
||||
active: true
|
||||
autoCorrect: true
|
||||
NoUnusedImports:
|
||||
active: true
|
||||
autoCorrect: true
|
||||
NoWildcardImports:
|
||||
active: true
|
||||
PackageName:
|
||||
active: true
|
||||
autoCorrect: true
|
||||
ParameterListWrapping:
|
||||
active: true
|
||||
autoCorrect: true
|
||||
indentSize: 4
|
||||
SpacingAroundColon:
|
||||
active: true
|
||||
autoCorrect: true
|
||||
SpacingAroundComma:
|
||||
active: true
|
||||
autoCorrect: true
|
||||
SpacingAroundCurly:
|
||||
active: true
|
||||
autoCorrect: true
|
||||
SpacingAroundDot:
|
||||
active: true
|
||||
autoCorrect: true
|
||||
SpacingAroundKeyword:
|
||||
active: true
|
||||
autoCorrect: true
|
||||
SpacingAroundOperators:
|
||||
active: true
|
||||
autoCorrect: true
|
||||
SpacingAroundParens:
|
||||
active: true
|
||||
autoCorrect: true
|
||||
SpacingAroundRangeOperator:
|
||||
active: true
|
||||
autoCorrect: true
|
||||
StringTemplate:
|
||||
active: true
|
||||
autoCorrect: true
|
||||
- Error
|
||||
- Exception
|
||||
- Throwable
|
||||
- RuntimeException
|
||||
|
||||
naming:
|
||||
active: true
|
||||
|
@ -19,8 +19,34 @@ plugins {
|
||||
plugins.apply(KiwixConfigurationPlugin::class)
|
||||
apply(plugin = "io.objectbox")
|
||||
apply(plugin = "com.jakewharton.butterknife")
|
||||
ext {
|
||||
set("versionMajor", 3)
|
||||
set("versionMinor", 6)
|
||||
set("versionPatch", 0)
|
||||
}
|
||||
|
||||
/*
|
||||
* max version code: 21-0-0-00-00-00
|
||||
* our template : UU-D-A-ZZ-YY-XX
|
||||
* where:
|
||||
* X = patch version
|
||||
* Y = minor version
|
||||
* Z = major version (+ 20 to distinguish from previous, non semantic, versions of the app)
|
||||
* A = number representing ABI split
|
||||
* D = number representing density split
|
||||
* U = unused
|
||||
*/
|
||||
|
||||
fun generateVersionCode() =
|
||||
20 * 10000 +
|
||||
ext["versionMajor"] as Int * 10000 +
|
||||
ext["versionMinor"] as Int * 100 +
|
||||
ext["versionPatch"] as Int
|
||||
|
||||
android {
|
||||
defaultConfig {
|
||||
buildConfigField("long", "VERSION_CODE", "${generateVersionCode()}")
|
||||
}
|
||||
buildTypes {
|
||||
getByName("release") {
|
||||
isMinifyEnabled = false
|
||||
@ -31,7 +57,6 @@ android {
|
||||
fun shouldUseLocalVersion() = File(projectDir, "libs").exists()
|
||||
|
||||
dependencies {
|
||||
|
||||
// use jdk8 java.time backport, as long app < Build.VERSION_CODES.O
|
||||
implementation(Libs.threetenabp)
|
||||
|
||||
|
@ -1,18 +1,20 @@
|
||||
<?xml version="1.0" ?>
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<SmellBaseline>
|
||||
<Blacklist></Blacklist>
|
||||
<Whitelist>
|
||||
<ManuallySuppressedIssues/>
|
||||
<CurrentIssues>
|
||||
<ID>EmptyFunctionBlock:BooksOnDiskViewHolder.kt$BookOnDiskViewHolder.BookViewHolder${ }</ID>
|
||||
<ID>EmptyFunctionBlock:FetchDownloadMonitor.kt$FetchDownloadMonitor.<no name provided>${}</ID>
|
||||
<ID>EmptyFunctionBlock:FetchDownloadMonitor.kt$FetchDownloadMonitor.<no name provided>${}</ID>
|
||||
<ID>EmptyFunctionBlock:OnSwipeTouchListener.kt$OnSwipeTouchListener${}</ID>
|
||||
<ID>ForbiddenComment:JNIInitialiser.kt$JNIInitialiser$// TODO: Consider surfacing to user</ID>
|
||||
<ID>LongMethod:TabsAdapter.kt$TabsAdapter$onCreateViewHolder</ID>
|
||||
<ID>LongParameterList:KiwixDialog.kt$KiwixDialog$( val title: Int?, val message: Int?, val positiveMessage: Int, val negativeMessage: Int?, val cancelable: Boolean = true, val icon: Int? = null, val neutralMessage: Int? = null, val getView: (() -> View)? = null )</ID>
|
||||
<ID>LongParameterList:MainMenu.kt$MainMenu$( private val activity: Activity, zimFileReader: ZimFileReader?, menu: Menu, webViews: MutableList<KiwixWebView>, urlIsValid: Boolean, disableReadAloud: Boolean = false, disableTabs: Boolean = false, private val menuClickListener: MenuClickListener )</ID>
|
||||
<ID>LongParameterList:MainMenu.kt$MainMenu.Factory$( menu: Menu, webViews: MutableList<KiwixWebView>, urlIsValid: Boolean, menuClickListener: MenuClickListener, disableReadAloud: Boolean, disableTabs: Boolean )</ID>
|
||||
<ID>ForbiddenComment:NetworkUtilsTest.kt$NetworkUtilsTest$// TODO: find a way to assert regex matching via JUnit and rewrite the test</ID>
|
||||
<ID>LongMethod:ChunkUtilsTest.kt$ChunkUtilsTest$@Test fun testGetChunks()</ID>
|
||||
<ID>LongMethod:TabsAdapter.kt$TabsAdapter$@SuppressLint("ResourceType") override fun onCreateViewHolder( parent: ViewGroup, viewType: Int ): ViewHolder</ID>
|
||||
<ID>LongParameterList:KiwixDialog.kt$KiwixDialog$( val title: Int?, val message: Int?, val positiveMessage: Int, val negativeMessage: Int?, val cancelable: Boolean = true, val icon: Int? = null, val neutralMessage: Int? = null, val getView: (() -> View)? = null )</ID>
|
||||
<ID>LongParameterList:MainMenu.kt$MainMenu$( private val activity: Activity, zimFileReader: ZimFileReader?, menu: Menu, webViews: MutableList<KiwixWebView>, urlIsValid: Boolean, disableReadAloud: Boolean = false, disableTabs: Boolean = false, private val menuClickListener: MenuClickListener )</ID>
|
||||
<ID>LongParameterList:MainMenu.kt$MainMenu.Factory$( menu: Menu, webViews: MutableList<KiwixWebView>, urlIsValid: Boolean, menuClickListener: MenuClickListener, disableReadAloud: Boolean, disableTabs: Boolean )</ID>
|
||||
<ID>LongParameterList:PageTestHelpers.kt$( bookmarkTitle: String = "bookmarkTitle", isSelected: Boolean = false, id: Long = 2, zimId: String = "zimId", zimName: String = "zimName", zimFilePath: String = "zimFilePath", bookmarkUrl: String = "bookmarkUrl", favicon: String = "favicon" )</ID>
|
||||
<ID>LongParameterList:Repository.kt$Repository$( @param:IO private val io: Scheduler, @param:MainThread private val mainThread: Scheduler, private val bookDao: NewBookDao, private val bookmarksDao: NewBookmarksDao, private val historyDao: HistoryDao, private val languageDao: NewLanguagesDao, private val recentSearchDao: NewRecentSearchDao, private val zimReaderContainer: ZimReaderContainer )</ID>
|
||||
<ID>LongParameterList:ToolbarScrollingKiwixWebView.kt$ToolbarScrollingKiwixWebView$( context: Context, callback: WebViewCallback, attrs: AttributeSet, nonVideoView: ViewGroup, videoView: ViewGroup, webViewClient: CoreWebViewClient, private val toolbarView: View, private val bottomBarView: View, sharedPreferenceUtil: SharedPreferenceUtil, private val parentNavigationBar: View? = null )</ID>
|
||||
<ID>MagicNumber:ArticleCount.kt$ArticleCount$1000.0</ID>
|
||||
<ID>MagicNumber:ArticleCount.kt$ArticleCount$3</ID>
|
||||
<ID>MagicNumber:CompatFindActionModeCallback.kt$CompatFindActionModeCallback$100</ID>
|
||||
<ID>MagicNumber:DownloadItem.kt$DownloadItem$1000L</ID>
|
||||
@ -29,11 +31,15 @@
|
||||
<ID>MagicNumber:Seconds.kt$Seconds$60</ID>
|
||||
<ID>MagicNumber:Seconds.kt$Seconds$60.0</ID>
|
||||
<ID>MagicNumber:TabsAdapter.kt$TabsAdapter$8</ID>
|
||||
<ID>NestedBlockDepth:FileUtils.kt$FileUtils$deleteZimFile</ID>
|
||||
<ID>NestedBlockDepth:ImageUtils.kt$ImageUtils$getBitmapFromView</ID>
|
||||
<ID>NestedBlockDepth:JNIInitialiser.kt$JNIInitialiser$loadICUData</ID>
|
||||
<ID>NestedBlockDepth:OnSwipeTouchListener.kt$OnSwipeTouchListener.GestureListener$onFling</ID>
|
||||
<ID>NestedBlockDepth:StorageDeviceUtils.kt$StorageDeviceUtils$canWrite</ID>
|
||||
<ID>MatchingDeclarationName:PageTestHelpers.kt$PageImpl : Page</ID>
|
||||
<ID>MaxLineLength:BookUtilsTest.kt$BookUtilsTest$// this case uses the result from the container nested class inside LanguageUtils. It will be tested in LanguageUtilsTest</ID>
|
||||
<ID>MaxLineLength:MetaLinkNetworkEntityTest.kt$MetaLinkNetworkEntityTest$"http://www.mirrorservice.org/sites/download.kiwix.org/zim/wikipedia/wikipedia_af_all_nopic_2016-05.zim"</ID>
|
||||
<ID>MaxLineLength:NetworkUtilsTest.kt$NetworkUtilsTest$// Here the Method should return the substring between the first '?' character and the nearest '/' character preceeding it</ID>
|
||||
<ID>NestedBlockDepth:FileUtils.kt$FileUtils$@JvmStatic @Synchronized fun deleteZimFile(path: String)</ID>
|
||||
<ID>NestedBlockDepth:ImageUtils.kt$ImageUtils$private fun getBitmapFromView(width: Int, height: Int, viewToDrawFrom: View): Bitmap?</ID>
|
||||
<ID>NestedBlockDepth:JNIInitialiser.kt$JNIInitialiser$private fun loadICUData(context: Context): String?</ID>
|
||||
<ID>NestedBlockDepth:OnSwipeTouchListener.kt$OnSwipeTouchListener.GestureListener$override fun onFling( e1: MotionEvent, e2: MotionEvent, velocityX: Float, velocityY: Float ): Boolean</ID>
|
||||
<ID>NestedBlockDepth:StorageDeviceUtils.kt$StorageDeviceUtils$// Amazingly file.canWrite() does not always return the correct value private fun canWrite(file: File): Boolean</ID>
|
||||
<ID>PackageNaming:ArticleCount.kt$package org.kiwix.kiwixmobile.core.zim_manager.fileselect_view</ID>
|
||||
<ID>PackageNaming:BookOnDiskDelegate.kt$package org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.adapter</ID>
|
||||
<ID>PackageNaming:BooksOnDiskAdapter.kt$package org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.adapter</ID>
|
||||
@ -45,7 +51,7 @@
|
||||
<ID>PackageNaming:MountPointProducer.kt$package org.kiwix.kiwixmobile.core.zim_manager</ID>
|
||||
<ID>PackageNaming:SelectionMode.kt$package org.kiwix.kiwixmobile.core.zim_manager.fileselect_view</ID>
|
||||
<ID>PackageNaming:TagsView.kt$package org.kiwix.kiwixmobile.core.zim_manager</ID>
|
||||
<ID>ReturnCount:FileUtils.kt$FileUtils$@JvmStatic fun getAllZimParts(book: Book): List<File></ID>
|
||||
<ID>ReturnCount:FileUtils.kt$FileUtils$@JvmStatic fun getAllZimParts(book: Book): List<File></ID>
|
||||
<ID>ReturnCount:FileUtils.kt$FileUtils$@JvmStatic fun getLocalFilePathByUri( context: Context, uri: Uri ): String?</ID>
|
||||
<ID>ReturnCount:FileUtils.kt$FileUtils$@JvmStatic fun hasPart(file: File): Boolean</ID>
|
||||
<ID>ReturnCount:FileUtils.kt$FileUtils$@Synchronized private fun deleteZimFileParts(path: String): Boolean</ID>
|
||||
@ -68,5 +74,5 @@
|
||||
<ID>TopLevelPropertyNaming:Bytes.kt$const val Mb = Kb * 1024</ID>
|
||||
<ID>TopLevelPropertyNaming:Bytes.kt$const val Pb = Tb * 1024</ID>
|
||||
<ID>TopLevelPropertyNaming:Bytes.kt$const val Tb = Gb * 1024</ID>
|
||||
</Whitelist>
|
||||
</CurrentIssues>
|
||||
</SmellBaseline>
|
||||
|
@ -376,9 +376,53 @@
|
||||
}
|
||||
],
|
||||
"relations": []
|
||||
},
|
||||
{
|
||||
"id": "10:3205842982118792800",
|
||||
"lastPropertyId": "9:5286545520416917562",
|
||||
"name": "NotesEntity",
|
||||
"properties": [
|
||||
{
|
||||
"id": "1:7685155280711004546",
|
||||
"name": "id",
|
||||
"type": 6,
|
||||
"flags": 1
|
||||
},
|
||||
{
|
||||
"id": "2:4525352813855835976",
|
||||
"name": "zimId",
|
||||
"type": 9
|
||||
},
|
||||
{
|
||||
"id": "4:4488566778591049174",
|
||||
"name": "zimFilePath",
|
||||
"type": 9
|
||||
},
|
||||
{
|
||||
"id": "5:7998345745727500384",
|
||||
"name": "noteTitle",
|
||||
"type": 9
|
||||
},
|
||||
{
|
||||
"id": "7:2160052450778801841",
|
||||
"name": "favicon",
|
||||
"type": 9
|
||||
},
|
||||
{
|
||||
"id": "8:4304230668306976620",
|
||||
"name": "noteFilePath",
|
||||
"type": 9
|
||||
},
|
||||
{
|
||||
"id": "9:5286545520416917562",
|
||||
"name": "zimUrl",
|
||||
"type": 9
|
||||
}
|
||||
],
|
||||
"relations": []
|
||||
}
|
||||
],
|
||||
"lastEntityId": "8:8093454424037540087",
|
||||
"lastEntityId": "10:3205842982118792800",
|
||||
"lastIndexId": "4:4868787482832538530",
|
||||
"lastRelationId": "0:0",
|
||||
"lastSequenceId": "0:0",
|
||||
@ -386,7 +430,8 @@
|
||||
"modelVersionParserMinimum": 5,
|
||||
"retiredEntityUids": [
|
||||
349148274283701276,
|
||||
7257718270326155947
|
||||
7257718270326155947,
|
||||
7394649290555378565
|
||||
],
|
||||
"retiredIndexUids": [
|
||||
1293695782925933448,
|
||||
@ -428,7 +473,16 @@
|
||||
3550975911715416030,
|
||||
8949996430663588693,
|
||||
7554483297276446029,
|
||||
8085320504542486236
|
||||
8085320504542486236,
|
||||
2542527583182293894,
|
||||
3541826612160879182,
|
||||
1761651285457480725,
|
||||
8027872860151528568,
|
||||
3582932035787057158,
|
||||
8819082642546094709,
|
||||
7233601933599801875,
|
||||
4335394620556092321,
|
||||
1899740026144478138
|
||||
],
|
||||
"retiredRelationUids": [],
|
||||
"version": 1
|
||||
|
@ -376,9 +376,53 @@
|
||||
}
|
||||
],
|
||||
"relations": []
|
||||
},
|
||||
{
|
||||
"id": "10:3205842982118792800",
|
||||
"lastPropertyId": "8:4304230668306976620",
|
||||
"name": "NotesEntity",
|
||||
"properties": [
|
||||
{
|
||||
"id": "1:7685155280711004546",
|
||||
"name": "id",
|
||||
"type": 6,
|
||||
"flags": 1
|
||||
},
|
||||
{
|
||||
"id": "2:4525352813855835976",
|
||||
"name": "zimId",
|
||||
"type": 9
|
||||
},
|
||||
{
|
||||
"id": "4:4488566778591049174",
|
||||
"name": "zimFilePath",
|
||||
"type": 9
|
||||
},
|
||||
{
|
||||
"id": "5:7998345745727500384",
|
||||
"name": "noteTitle",
|
||||
"type": 9
|
||||
},
|
||||
{
|
||||
"id": "6:1899740026144478138",
|
||||
"name": "noteBody",
|
||||
"type": 9
|
||||
},
|
||||
{
|
||||
"id": "7:2160052450778801841",
|
||||
"name": "favicon",
|
||||
"type": 9
|
||||
},
|
||||
{
|
||||
"id": "8:4304230668306976620",
|
||||
"name": "noteFilePath",
|
||||
"type": 9
|
||||
}
|
||||
],
|
||||
"relations": []
|
||||
}
|
||||
],
|
||||
"lastEntityId": "8:8093454424037540087",
|
||||
"lastEntityId": "10:3205842982118792800",
|
||||
"lastIndexId": "4:4868787482832538530",
|
||||
"lastRelationId": "0:0",
|
||||
"lastSequenceId": "0:0",
|
||||
@ -386,7 +430,8 @@
|
||||
"modelVersionParserMinimum": 5,
|
||||
"retiredEntityUids": [
|
||||
349148274283701276,
|
||||
7257718270326155947
|
||||
7257718270326155947,
|
||||
7394649290555378565
|
||||
],
|
||||
"retiredIndexUids": [
|
||||
1293695782925933448,
|
||||
@ -428,7 +473,15 @@
|
||||
3550975911715416030,
|
||||
8949996430663588693,
|
||||
7554483297276446029,
|
||||
8085320504542486236
|
||||
8085320504542486236,
|
||||
2542527583182293894,
|
||||
3541826612160879182,
|
||||
1761651285457480725,
|
||||
8027872860151528568,
|
||||
3582932035787057158,
|
||||
8819082642546094709,
|
||||
7233601933599801875,
|
||||
4335394620556092321
|
||||
],
|
||||
"retiredRelationUids": [],
|
||||
"version": 1
|
||||
|
@ -3,28 +3,34 @@
|
||||
package="org.kiwix.kiwixmobile.core"
|
||||
android:installLocation="auto">
|
||||
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission
|
||||
android:name="android.permission.READ_EXTERNAL_STORAGE"
|
||||
android:maxSdkVersion="32" />
|
||||
<uses-permission
|
||||
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
|
||||
tools:ignore="ScopedStorage" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
||||
|
||||
<!-- Device with versions >= Pie need this permission -->
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"
|
||||
<uses-permission
|
||||
android:name="android.permission.QUERY_ALL_PACKAGES"
|
||||
tools:ignore="QueryAllPackagesPermission" />
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:extractNativeLibs="false"
|
||||
android:fullBackupContent="@xml/backup_rules"
|
||||
android:dataExtractionRules = "@xml/data_extraction_rules"
|
||||
android:hardwareAccelerated="true"
|
||||
android:requestLegacyExternalStorage="true"
|
||||
android:resizeableActivity="true"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/KiwixTheme"
|
||||
android:usesCleartextTraffic="true"
|
||||
android:requestLegacyExternalStorage="true"
|
||||
tools:targetApi="q">
|
||||
tools:targetApi="s">
|
||||
|
||||
<!-- Version < 3.0. DeX Mode and Screen Mirroring support -->
|
||||
<meta-data
|
||||
@ -37,6 +43,7 @@
|
||||
|
||||
<activity
|
||||
android:name=".error.ErrorActivity"
|
||||
android:exported="false"
|
||||
android:process=":error_activity" />
|
||||
|
||||
<provider
|
||||
@ -49,7 +56,9 @@
|
||||
android:resource="@xml/provider_paths" />
|
||||
</provider>
|
||||
|
||||
<activity android:name=".error.DiagnosticReportActivity" />
|
||||
<activity
|
||||
android:name=".error.DiagnosticReportActivity"
|
||||
android:exported="false" />
|
||||
|
||||
</application>
|
||||
</manifest>
|
||||
|
@ -17,6 +17,7 @@
|
||||
*/
|
||||
package org.kiwix.kiwixmobile.core
|
||||
|
||||
import android.app.AlertDialog
|
||||
import android.app.Application
|
||||
import android.content.Context
|
||||
import android.os.Build
|
||||
@ -25,6 +26,7 @@ import android.os.Environment.getExternalStorageState
|
||||
import android.os.StrictMode
|
||||
import android.os.StrictMode.VmPolicy
|
||||
import androidx.multidex.MultiDex
|
||||
import com.google.android.play.core.missingsplits.MissingSplitsManagerFactory
|
||||
import com.jakewharton.threetenabp.AndroidThreeTen
|
||||
import org.kiwix.kiwixmobile.core.data.local.KiwixDatabase
|
||||
import org.kiwix.kiwixmobile.core.di.components.CoreComponent
|
||||
@ -76,6 +78,15 @@ abstract class CoreApp : Application() {
|
||||
}
|
||||
|
||||
override fun onCreate() {
|
||||
if (MissingSplitsManagerFactory.create(this).disableAppIfMissingRequiredSplits()) {
|
||||
AlertDialog.Builder(this)
|
||||
.setMessage(R.string.missing_split_version_for_objectbox)
|
||||
.setPositiveButton(R.string.yes) { _, _ ->
|
||||
android.os.Process.killProcess(android.os.Process.myPid())
|
||||
}
|
||||
.show()
|
||||
return
|
||||
}
|
||||
super.onCreate()
|
||||
instance = this
|
||||
coreComponent = DaggerCoreComponent.builder()
|
||||
|
@ -22,8 +22,10 @@ import android.view.View
|
||||
import androidx.recyclerview.widget.RecyclerView.ViewHolder
|
||||
import kotlinx.android.extensions.LayoutContainer
|
||||
|
||||
abstract class BaseViewHolder<in ITEM>(override val containerView: View) : ViewHolder(
|
||||
containerView
|
||||
), LayoutContainer {
|
||||
abstract class BaseViewHolder<in ITEM>(override val containerView: View) :
|
||||
ViewHolder(
|
||||
containerView
|
||||
),
|
||||
LayoutContainer {
|
||||
abstract fun bind(item: ITEM)
|
||||
}
|
||||
|
@ -30,9 +30,11 @@ import org.kiwix.kiwixmobile.core.reader.ZimFileReader
|
||||
import javax.inject.Inject
|
||||
|
||||
class NewBookmarksDao @Inject constructor(val box: Box<BookmarkEntity>) : PageDao {
|
||||
fun bookmarks(): Flowable<List<Page>> = box.asFlowable(box.query {
|
||||
order(BookmarkEntity_.bookmarkTitle)
|
||||
}).map { it.map(::BookmarkItem) }
|
||||
fun bookmarks(): Flowable<List<Page>> = box.asFlowable(
|
||||
box.query {
|
||||
order(BookmarkEntity_.bookmarkTitle)
|
||||
}
|
||||
).map { it.map(::BookmarkItem) }
|
||||
|
||||
override fun pages(): Flowable<List<Page>> = bookmarks()
|
||||
override fun deletePages(pagesToDelete: List<Page>) =
|
||||
@ -55,7 +57,8 @@ class NewBookmarksDao @Inject constructor(val box: Box<BookmarkEntity>) : PageDa
|
||||
.or()
|
||||
.equal(BookmarkEntity_.zimName, zimFileReader?.name ?: "")
|
||||
order(BookmarkEntity_.bookmarkTitle)
|
||||
}).map { it.map(BookmarkEntity::bookmarkUrl) }
|
||||
}
|
||||
).map { it.map(BookmarkEntity::bookmarkUrl) }
|
||||
.subscribeOn(Schedulers.io())
|
||||
|
||||
fun saveBookmark(bookmarkItem: BookmarkItem) {
|
||||
|
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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.dao
|
||||
|
||||
import io.objectbox.Box
|
||||
import io.objectbox.kotlin.query
|
||||
import io.reactivex.Flowable
|
||||
import org.kiwix.kiwixmobile.core.dao.entities.NotesEntity
|
||||
import org.kiwix.kiwixmobile.core.dao.entities.NotesEntity_
|
||||
import org.kiwix.kiwixmobile.core.page.adapter.Page
|
||||
import org.kiwix.kiwixmobile.core.page.notes.adapter.NoteListItem
|
||||
import javax.inject.Inject
|
||||
|
||||
class NewNoteDao @Inject constructor(val box: Box<NotesEntity>) : PageDao {
|
||||
fun notes(): Flowable<List<Page>> = box.asFlowable(
|
||||
box.query {
|
||||
order(NotesEntity_.noteTitle)
|
||||
}
|
||||
).map { it.map(::NoteListItem) }
|
||||
|
||||
override fun pages(): Flowable<List<Page>> = notes()
|
||||
|
||||
override fun deletePages(pagesToDelete: List<Page>) =
|
||||
deleteNotes(pagesToDelete as List<NoteListItem>)
|
||||
|
||||
fun saveNote(noteItem: NoteListItem) {
|
||||
box.put(NotesEntity(noteItem))
|
||||
}
|
||||
|
||||
fun deleteNotes(noteList: List<NoteListItem>) {
|
||||
box.remove(noteList.map(::NotesEntity))
|
||||
}
|
||||
|
||||
fun deleteNote(noteUniqueKey: String) {
|
||||
box.query {
|
||||
equal(NotesEntity_.noteTitle, noteUniqueKey)
|
||||
}.remove()
|
||||
}
|
||||
}
|
@ -19,7 +19,6 @@ package org.kiwix.kiwixmobile.core.dao
|
||||
|
||||
import io.objectbox.Box
|
||||
import io.objectbox.kotlin.query
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.map
|
||||
import org.kiwix.kiwixmobile.core.dao.entities.RecentSearchEntity
|
||||
import org.kiwix.kiwixmobile.core.dao.entities.RecentSearchEntity_
|
||||
@ -31,7 +30,6 @@ class NewRecentSearchDao @Inject constructor(
|
||||
private val box: Box<RecentSearchEntity>,
|
||||
private val flowBuilder: FlowBuilder
|
||||
) {
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
fun recentSearches(zimId: String?) = flowBuilder.buildCallbackFlow(
|
||||
box.query {
|
||||
equal(RecentSearchEntity_.zimId, zimId ?: "")
|
||||
|
@ -19,8 +19,8 @@ package org.kiwix.kiwixmobile.core.dao.entities
|
||||
|
||||
import io.objectbox.annotation.Entity
|
||||
import io.objectbox.annotation.Id
|
||||
import org.kiwix.kiwixmobile.core.page.bookmark.adapter.BookmarkItem
|
||||
import org.kiwix.kiwixmobile.core.data.local.entity.Bookmark
|
||||
import org.kiwix.kiwixmobile.core.page.bookmark.adapter.BookmarkItem
|
||||
|
||||
@Entity
|
||||
data class BookmarkEntity(
|
||||
|
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Kiwix Android
|
||||
* Copyright (c) 2022 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.dao.entities
|
||||
|
||||
import io.objectbox.annotation.Entity
|
||||
import io.objectbox.annotation.Id
|
||||
import io.objectbox.annotation.Unique
|
||||
import org.kiwix.kiwixmobile.core.page.notes.adapter.NoteListItem
|
||||
|
||||
@Entity
|
||||
data class NotesEntity(
|
||||
@Id var id: Long = 0L,
|
||||
val zimId: String,
|
||||
var zimFilePath: String?,
|
||||
val zimUrl: String,
|
||||
@Unique
|
||||
var noteTitle: String,
|
||||
var noteFilePath: String,
|
||||
var favicon: String?
|
||||
) {
|
||||
constructor(item: NoteListItem) : this(
|
||||
id = item.databaseId,
|
||||
zimId = item.zimId,
|
||||
zimFilePath = item.zimFilePath,
|
||||
zimUrl = item.zimUrl,
|
||||
noteTitle = item.title,
|
||||
noteFilePath = item.noteFilePath,
|
||||
favicon = item.favicon
|
||||
)
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user