Merge remote-tracking branch 'origin/develop' into feature3/macgills/2303-service-worker-unregistration

This commit is contained in:
Sean Mac Gillicuddy 2020-11-24 09:22:14 +00:00
commit f3324f221b
21 changed files with 263 additions and 73 deletions

View File

@ -45,3 +45,11 @@ jobs:
- name: Upload coverage to Codecov
run: |
bash <(curl -s https://codecov.io/bash)
- name: Upload Coverage to GH-Actions
uses: actions/upload-artifact@v2.2.0
if: ${{ always() }}
with:
name: Tests Coverage Report
path: |
**/reports/

View File

@ -16,6 +16,15 @@ jobs:
- name: Static Analysis
run: ./gradlew ktlintCheck detekt app:lintDebug custom:lintCustomexampleDebug
- name: Upload Static Analysis Report
uses: actions/upload-artifact@v2.2.0
if: ${{ always() }}
with:
name: Static Analysis Report
path: |
**/reports/
build:
runs-on: ubuntu-latest

View File

@ -2,7 +2,7 @@
NEW: Overhauled navigation
NEW: Updated translations
NEW: Support resizing Kiwix
NEW: Open search in ne wtab
NEW: Open search in new tab
BUGFIX: Search speed increased and loading state added
BUGFIX: Memory leaks patched
BUGFIX: More consistent labelling drives internal/external

View File

@ -116,7 +116,7 @@ To generate coverage reports for your automated tests run:
Code coverage results can be seen under `[module]/build/reports/`
### Continous Integration
### Continuous Integration
All PRs will have all these tests run and a combined coverage report will be attached, if coverage is to go down the PR will be marked failed. On Travis CI the automated tests are run on an emulator. To
learn more about the commands run on the CI please refer to [.github/workflows](https://github.com/kiwix/kiwix-android/tree/develop/.github/workflows).

View File

@ -21,14 +21,15 @@ package org.kiwix.kiwixmobile.di.modules
import android.content.Context
import android.location.LocationManager
import android.net.wifi.WifiManager
import android.net.wifi.p2p.WifiP2pManager
import dagger.Module
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.core.zim_manager.MountPointProducer
@Module
object KiwixModule {
@ -52,4 +53,12 @@ object KiwixModule {
sharedPreferenceUtil,
listOf(MountFileSystemChecker(mountPointProducer), FileWritingFileSystemChecker())
)
@Provides
@KiwixScope
// We are forced to use the nullable type because of a
// crash on our nightly builds running on an emulator API 27
// See: https://github.com/kiwix/kiwix-android/issues/2488
fun providesWiFiP2pManager(context: Context): WifiP2pManager? =
context.getSystemService(Context.WIFI_P2P_SERVICE) as WifiP2pManager?
}

View File

@ -23,8 +23,8 @@ import android.app.Service
import android.content.Context
import dagger.Module
import dagger.Provides
import org.kiwix.kiwixlib.Library
import org.kiwix.kiwixlib.JNIKiwixServer
import org.kiwix.kiwixlib.Library
import org.kiwix.kiwixmobile.di.ServiceScope
import org.kiwix.kiwixmobile.webserver.WebServerHelper
import org.kiwix.kiwixmobile.webserver.wifi_hotspot.HotspotNotificationManager

View File

@ -17,7 +17,7 @@
*/
package org.kiwix.kiwixmobile.localFileTransfer
import android.app.Activity
import android.content.Context
import android.util.Log
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
@ -45,7 +45,7 @@ import java.net.Socket
private const val TIME_OUT = 15000
internal class SenderDevice(
private val activity: Activity,
private val context: Context,
private val wifiDirectManager: WifiDirectManager,
private val fileReceiverDeviceAddress: InetAddress
) {
@ -59,7 +59,7 @@ internal class SenderDevice(
.forEachIndexed { fileIndex, fileItem ->
try {
Socket().use { socket ->
activity.contentResolver.openInputStream(fileItem?.fileUri!!).use { fileInputStream ->
context.contentResolver.openInputStream(fileItem?.fileUri!!).use { fileInputStream ->
socket.bind(null)
socket.connect(
InetSocketAddress(hostAddress, WifiDirectManager.FILE_TRANSFER_PORT),

View File

@ -17,7 +17,6 @@
*/
package org.kiwix.kiwixmobile.localFileTransfer
import android.app.Activity
import android.content.BroadcastReceiver
import android.content.Context
import android.content.IntentFilter
@ -35,7 +34,7 @@ import android.net.wifi.p2p.WifiP2pManager.ConnectionInfoListener
import android.net.wifi.p2p.WifiP2pManager.PeerListListener
import android.os.Build.VERSION
import android.os.Build.VERSION_CODES
import android.os.Looper
import android.os.Looper.getMainLooper
import android.util.Log
import android.widget.Toast
import androidx.lifecycle.LifecycleCoroutineScope
@ -59,9 +58,10 @@ import javax.inject.Inject
*/
@SuppressWarnings("MissingPermission", "ProtectedMemberInFinalClass")
class WifiDirectManager @Inject constructor(
private val activity: Activity,
private val context: Context,
private val sharedPreferenceUtil: SharedPreferenceUtil,
private val alertDialogShower: AlertDialogShower
private val alertDialogShower: AlertDialogShower,
private val manager: WifiP2pManager?
) : ChannelListener, PeerListListener, ConnectionInfoListener, P2pEventListener {
var callbacks: Callbacks? = null
@ -74,11 +74,8 @@ class WifiDirectManager @Inject constructor(
// Whether channel has retried connecting previously
private var shouldRetry = true
// Overall manager of Wifi p2p connections for the module
private lateinit var manager: WifiP2pManager
// Interface to the device's underlying wifi-p2p framework
private lateinit var channel: Channel
private var channel: Channel? = null
// For receiving the broadcasts given by above filter
private lateinit var receiver: BroadcastReceiver
@ -94,8 +91,7 @@ class WifiDirectManager @Inject constructor(
fun startWifiDirectManager(filesForTransfer: List<FileItem>) {
this.filesForTransfer = filesForTransfer
isFileSender = filesForTransfer.isNotEmpty()
manager = activity.getSystemService(Context.WIFI_P2P_SERVICE) as WifiP2pManager
channel = manager.initialize(activity, Looper.getMainLooper(), null)
channel = manager?.initialize(context, getMainLooper(), null)
registerWifiDirectBroadcastReceiver()
}
@ -110,20 +106,20 @@ class WifiDirectManager @Inject constructor(
addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION)
addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION)
}
activity.registerReceiver(receiver, intentFilter)
context.registerReceiver(receiver, intentFilter)
}
private fun unregisterWifiDirectBroadcastReceiver() = activity.unregisterReceiver(receiver)
private fun unregisterWifiDirectBroadcastReceiver() = context.unregisterReceiver(receiver)
fun discoverPeerDevices() {
manager.discoverPeers(channel, object : ActionListener {
manager?.discoverPeers(channel, object : ActionListener {
override fun onSuccess() {
activity.toast(R.string.discovery_initiated, Toast.LENGTH_SHORT)
context.toast(R.string.discovery_initiated, Toast.LENGTH_SHORT)
}
override fun onFailure(reason: Int) {
Log.d(TAG, "${activity.getString(R.string.discovery_failed)}: ${getErrorMessage(reason)}")
activity.toast(R.string.discovery_failed, Toast.LENGTH_SHORT)
Log.d(TAG, "${context.getString(R.string.discovery_failed)}: ${getErrorMessage(reason)}")
context.toast(R.string.discovery_failed, Toast.LENGTH_SHORT)
}
})
}
@ -132,7 +128,7 @@ class WifiDirectManager @Inject constructor(
override fun onWifiP2pStateChanged(isEnabled: Boolean) {
isWifiP2pEnabled = isEnabled
if (!isWifiP2pEnabled) {
activity.toast(R.string.discovery_needs_wifi, Toast.LENGTH_SHORT)
context.toast(R.string.discovery_needs_wifi, Toast.LENGTH_SHORT)
callbacks?.onConnectionToPeersLost()
}
Log.d(TAG, "WiFi P2P state changed - $isWifiP2pEnabled")
@ -141,14 +137,14 @@ class WifiDirectManager @Inject constructor(
override fun onPeersChanged() {
/* List of available peers has changed, so request & use the new list through
* PeerListListener.requestPeers() callback */
manager.requestPeers(channel, this)
manager?.requestPeers(channel, this)
Log.d(TAG, "P2P peers changed")
}
override fun onConnectionChanged(isConnected: Boolean) {
if (isConnected) {
// Request connection info about the wifi p2p group formed upon connection
manager.requestConnectionInfo(channel, this)
manager?.requestConnectionInfo(channel, this)
} else {
// Not connected after connection change -> Disconnected
callbacks?.onConnectionToPeersLost()
@ -167,9 +163,9 @@ class WifiDirectManager @Inject constructor(
Log.d(TAG, "Channel lost, trying again")
callbacks?.onConnectionToPeersLost()
shouldRetry = false
manager.initialize(activity, Looper.getMainLooper(), this)
manager?.initialize(context, getMainLooper(), this)
} else {
activity.toast(R.string.severe_loss_error, Toast.LENGTH_LONG)
context.toast(R.string.severe_loss_error, Toast.LENGTH_LONG)
}
}
@ -191,7 +187,7 @@ class WifiDirectManager @Inject constructor(
FileTransferConfirmation(senderSelectedPeerDevice.deviceName), {
hasSenderStartedConnection = true
connect(senderSelectedPeerDevice)
activity.toast(R.string.performing_handshake, Toast.LENGTH_LONG)
context.toast(R.string.performing_handshake, Toast.LENGTH_LONG)
})
}
}
@ -201,15 +197,15 @@ class WifiDirectManager @Inject constructor(
deviceAddress = senderSelectedPeerDevice.deviceAddress
wps.setup = WpsInfo.PBC
}
manager.connect(channel, config, object : ActionListener {
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, activity.getString(R.string.connection_failed) + ": " + errorMessage)
activity.toast(R.string.connection_failed, Toast.LENGTH_LONG)
Log.d(TAG, context.getString(R.string.connection_failed) + ": " + errorMessage)
context.toast(R.string.connection_failed, Toast.LENGTH_LONG)
}
})
}
@ -232,7 +228,7 @@ class WifiDirectManager @Inject constructor(
Log.d(TAG, "InetAddress is null")
}
onFileTransferAsyncTaskComplete(false)
activity.toast(R.string.connection_refused)
context.toast(R.string.connection_refused)
}
}
}
@ -254,8 +250,8 @@ class WifiDirectManager @Inject constructor(
Log.d(LocalFileTransferFragment.TAG, "Starting file transfer")
val fileReceiverDeviceAddress =
if (groupInfo.isGroupOwner) inetAddress else groupInfo.groupOwnerAddress
activity.toast(R.string.preparing_files, Toast.LENGTH_LONG)
val senderDevice = SenderDevice(activity, this, fileReceiverDeviceAddress)
context.toast(R.string.preparing_files, Toast.LENGTH_LONG)
val senderDevice = SenderDevice(context, this, fileReceiverDeviceAddress)
val isFileSendSuccessfully = senderDevice.send(filesForTransfer)
onFileTransferAsyncTaskComplete(isFileSendSuccessfully)
if (BuildConfig.DEBUG) {
@ -277,8 +273,8 @@ class WifiDirectManager @Inject constructor(
filesForTransfer[itemIndex].fileStatus = status
callbacks?.onFileStatusChanged(itemIndex)
if (status == FileStatus.ERROR) {
activity.toast(
activity.getString(
context.toast(
context.getString(
R.string.error_transferring, filesForTransfer[itemIndex].fileName
)
)
@ -295,7 +291,7 @@ class WifiDirectManager @Inject constructor(
}
private fun disconnect() {
manager.removeGroup(channel, object : ActionListener {
manager?.removeGroup(channel, object : ActionListener {
override fun onFailure(reasonCode: Int) {
Log.d(TAG, "Disconnect failed. Reason: $reasonCode")
closeChannel()
@ -310,7 +306,7 @@ class WifiDirectManager @Inject constructor(
private fun closeChannel() {
if (VERSION.SDK_INT >= VERSION_CODES.O_MR1) {
channel.close()
channel?.close()
}
}
@ -325,9 +321,9 @@ class WifiDirectManager @Inject constructor(
private fun onFileTransferAsyncTaskComplete(wereAllFilesTransferred: Boolean) {
if (wereAllFilesTransferred) {
activity.toast(R.string.file_transfer_complete, Toast.LENGTH_LONG)
context.toast(R.string.file_transfer_complete, Toast.LENGTH_LONG)
} else {
activity.toast(R.string.error_during_transfer, Toast.LENGTH_LONG)
context.toast(R.string.error_during_transfer, Toast.LENGTH_LONG)
}
callbacks?.onFileTransferComplete()
}

View File

@ -32,6 +32,7 @@ import com.google.android.material.navigation.NavigationView
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.R
import org.kiwix.kiwixmobile.core.base.FragmentActivityExtensions
import org.kiwix.kiwixmobile.core.di.components.CoreComponent
@ -48,6 +49,7 @@ class KiwixMainActivity : CoreMainActivity() {
override val navController by lazy { findNavController(R.id.nav_host_fragment) }
override val drawerContainerLayout: DrawerLayout by lazy { navigation_container }
override val drawerNavView: NavigationView by lazy { drawer_nav_view }
override val readerTableOfContentsDrawer: NavigationView by lazy { reader_drawer_nav_view }
override val bookmarksFragmentResId: Int = R.id.bookmarksFragment
override val settingsFragmentResId: Int = R.id.kiwixSettingsFragment
override val historyFragmentResId: Int = R.id.historyFragment

View File

@ -26,8 +26,8 @@ import java.util.ArrayList;
import java.util.concurrent.TimeUnit;
import javax.inject.Inject;
import org.kiwix.kiwixlib.JNIKiwixException;
import org.kiwix.kiwixlib.Library;
import org.kiwix.kiwixlib.JNIKiwixServer;
import org.kiwix.kiwixlib.Library;
import org.kiwix.kiwixmobile.core.utils.ServerUtils;
import org.kiwix.kiwixmobile.webserver.wifi_hotspot.IpAddressCallbacks;

View File

@ -6,4 +6,6 @@
<string name="file_system_does_not_support_4gb">\'U file system tune non ge supporte le file cchiù granne de 4GB</string>
<string name="detecting_file_system">Stoche a condrolle ce \'u file system tune pò ccrejà le file cchiù granne de 4GB</string>
<string name="cannot_open_file">Aprture du fail sciute a male\nPe piacere pruève arrete a cercà stu fail jndrà Schede d\'u despositive d\'a libbreria toje.</string>
<string name="send_files_title">Manne le file</string>
<string name="receive_files_title">Pigghie le file</string>
</resources>

View File

@ -6,4 +6,6 @@
<string name="file_system_does_not_support_4gb">Su sistema de documentos (file system) tuo non suportat documentos prus mannos de 4GB</string>
<string name="detecting_file_system">Verifichende si su sistema de documentos podet creare documentos de 4GB</string>
<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>
</resources>

View File

@ -326,7 +326,7 @@ object Libs {
Versions.xfetch2okhttp
/**
* http://assertj.org
* https://assertj.github.io/doc/
*/
const val assertj_core: String = "org.assertj:assertj-core:" + Versions.assertj_core

View File

@ -1,4 +1,3 @@
import kotlin.String
import org.gradle.plugin.use.PluginDependenciesSpec
import org.gradle.plugin.use.PluginDependencySpec
@ -12,35 +11,35 @@ import org.gradle.plugin.use.PluginDependencySpec
* YOU are responsible for updating manually the dependency version.
*/
object Versions {
const val org_jetbrains_kotlinx_kotlinx_coroutines: String = "1.3.9"
const val org_jetbrains_kotlinx_kotlinx_coroutines: String = "1.4.1"
const val androidx_test_espresso: String = "3.2.0" // available: "3.3.0"
const val androidx_test_espresso: 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.3.72" // available: "1.4.10"
const val org_jetbrains_kotlin: String = "1.4.20"
const val androidx_navigation: String = "2.3.0"
const val androidx_navigation: String = "2.3.1"
const val com_google_dagger: String = "2.28.3" // available: "2.29.1"
const val com_google_dagger: String = "2.29.1"
const val com_yahoo_squidb: String = "2.0.0" // available: "3.2.3"
const val com_jakewharton: String = "10.2.2" // available: "10.2.3"
const val com_jakewharton: String = "10.2.3"
const val androidx_test: String = "1.2.0" // available: "1.3.0"
const val androidx_test: String = "1.3.0"
const val io_objectbox: String = "2.7.0" // available: "2.7.1"
const val io_objectbox: String = "2.8.1"
const val org_jacoco: String = "0.7.9"
const val io_mockk: String = "1.10.0" // available: "1.10.2"
const val io_mockk: String = "1.10.2"
const val android_arch_lifecycle_extensions: String = "1.1.1"
const val com_android_tools_build_gradle: String = "4.0.1" // available: "4.0.2"
const val com_android_tools_build_gradle: String = "4.0.1" // available: "4.1.1"
const val de_fayard_buildsrcversions_gradle_plugin: String = "0.7.0"
@ -50,29 +49,29 @@ object Versions {
const val ink_page_indicator: String = "1.3.0"
const val leakcanary_android: String = "2.4" // available: "2.5"
const val leakcanary_android: String = "2.5"
const val constraintlayout: String = "1.1.3" // available: "2.0.2"
const val constraintlayout: String = "2.0.4"
const val collection_ktx: String = "1.1.0"
const val preference_ktx: String = "1.1.1"
const val junit_jupiter: String = "5.6.2" // available: "5.7.0"
const val junit_jupiter: String = "5.7.0"
const val xfetch2okhttp: String = "3.1.5"
const val assertj_core: String = "3.16.1" // available: "3.17.2"
const val assertj_core: String = "3.18.1"
const val core_testing: String = "2.1.0"
const val fragment_ktx: String = "1.2.5"
const val lint_gradle: String = "27.0.1" // available: "27.0.2"
const val lint_gradle: String = "27.1.1"
const val testing_ktx: String = "1.1.2"
const val threetenabp: String = "1.2.4"
const val threetenabp: String = "1.3.0"
const val uiautomator: String = "2.2.0"
@ -84,11 +83,11 @@ object Versions {
const val rxandroid: String = "2.1.1"
const val core_ktx: String = "1.3.1" // available: "1.3.2"
const val core_ktx: String = "1.3.2"
const val kiwixlib: String = "9.4.0"
const val kiwixlib: String = "9.4.1"
const val material: String = "1.2.0" // available: "1.2.1"
const val material: String = "1.2.1"
const val multidex: String = "2.0.1"
@ -98,22 +97,22 @@ object Versions {
const val jsr305: String = "3.0.2"
const val ktlint: String = "0.36.0" // available: "0.39.0"
const val ktlint: String = "0.39.0"
const val rxjava: String = "2.2.19" // available: "2.2.20"
const val rxjava: String = "2.2.20"
const val webkit: String = "1.2.0" // available: "1.3.0"
const val webkit: String = "1.3.0"
const val aapt2: String = "4.0.1-6197926" // available: "4.0.2-6197926"
const val aapt2: String = "4.1.1-6503028"
const val junit: String = "1.1.1" // available: "1.1.2"
const val junit: String = "1.1.2"
/**
* Current version: "6.2"
* See issue 19: How to update Gradle itself?
* https://github.com/jmfayard/buildSrcVersions/issues/19
*/
const val gradleLatestVersion: String = "6.6.1"
const val gradleLatestVersion: String = "6.7.1"
}
/**

View File

@ -28,6 +28,8 @@ import androidx.appcompat.widget.Toolbar
import androidx.core.net.toUri
import androidx.core.os.bundleOf
import androidx.drawerlayout.widget.DrawerLayout
import androidx.drawerlayout.widget.DrawerLayout.LOCK_MODE_LOCKED_CLOSED
import androidx.drawerlayout.widget.DrawerLayout.LOCK_MODE_UNLOCKED
import androidx.fragment.app.Fragment
import androidx.navigation.NavController
import androidx.navigation.NavDestination
@ -66,6 +68,7 @@ abstract class CoreMainActivity : BaseActivity(), WebViewProvider {
abstract val navController: NavController
abstract val drawerContainerLayout: DrawerLayout
abstract val drawerNavView: NavigationView
abstract val readerTableOfContentsDrawer: NavigationView
abstract val bookmarksFragmentResId: Int
abstract val settingsFragmentResId: Int
abstract val historyFragmentResId: Int
@ -109,6 +112,14 @@ abstract class CoreMainActivity : BaseActivity(), WebViewProvider {
if (destination.id !in topLevelDestinations) {
handleDrawerOnNavigation()
}
readerTableOfContentsDrawer.setLockMode(
if (destination.id == readerFragmentResId) LOCK_MODE_UNLOCKED
else LOCK_MODE_LOCKED_CLOSED
)
}
private fun NavigationView.setLockMode(lockMode: Int) {
drawerContainerLayout.setDrawerLockMode(lockMode, this)
}
override fun onRequestPermissionsResult(

View File

@ -28,11 +28,12 @@ import org.kiwix.kiwixmobile.core.R
import org.kiwix.kiwixmobile.core.base.BaseFragment
abstract class CoreSettingsFragment : BaseFragment() {
private lateinit var prefsFragment: Fragment
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
prefsFragment = createPreferenceFragment()
requireActivity().supportFragmentManager
.beginTransaction().replace(R.id.content_frame, createPreferenceFragment())
.beginTransaction().replace(R.id.content_frame, prefsFragment)
.commit()
setUpToolbar()
}
@ -52,4 +53,12 @@ abstract class CoreSettingsFragment : BaseFragment() {
activity.supportActionBar!!.setHomeButtonEnabled(true)
activity.supportActionBar!!.setDisplayHomeAsUpEnabled(true)
}
override fun onDestroyView() {
requireActivity().supportFragmentManager
.beginTransaction()
.remove(prefsFragment)
.commitNowAllowingStateLoss()
super.onDestroyView()
}
}

View File

@ -29,6 +29,7 @@
<string name="open_in_new_tab">Gıre xıldayışo newe de abo?</string>
<string name="hotspot_service_channel_name">Kanalê xızmeti Hotspot</string>
<string name="hotspot_failed_title">Serkewtışê hotspoti nêbiyo</string>
<string name="hotspot_failed_message">Hotspotê şıma xora akerde aseno. Dewma kerdışi rê kerem kerê nuqtay resayışê Wi-Fi dewre ra vecê.</string>
<string name="go_to_wifi_settings_label">Ravêrê eyaranê Wi-Fi</string>
<string name="connection_refused">Gırebiyayış biyo red</string>
<string name="hotspot_running">Hotspoto gureyneyino</string>
@ -43,12 +44,14 @@
<string name="progress_dialog_starting_server">Server gureyneyino</string>
<string name="hotspot_dialog_title">Telimatê meymandariya kıtaban</string>
<string name="wifi_dialog_title">Gırey Wi-fi tesbit biya</string>
<string name="wifi_dialog_body">Kıtabanê cihazanê binan mocnayışi rê gani cihazi pêro wa eyni torra Wi-Fi ya gıre bı</string>
<string name="hotspot_dialog_message">Seba ena xısusiyeti gureynayışi rê gani veri hotspotê WIFI peydeatana akerê ya zi esas cihaz u gırote cihazi eyni torra Wi-Fi gırebiyayışê cı kontrol kerê.</string>
<string name="hotspot_dialog_neutral_button">RAVÊR Şİ</string>
<string name="hotspot_channel_description">Heqa Hotspot/server eleqeyın rocaney .</string>
<string name="hotspot_notification_content_title">Kiwix Hotspot</string>
<string name="start_server_label">Serveri serkewtış</string>
<string name="stop_server_label">Serveri vındardış</string>
<string name="server_started_message">Seba resayışê serverê %s re browseri rê ena adresê ip cı kerê</string>
<string name="error_file_not_found">Xeta: Dosyaya ZIMia weçinıtiye nêvêniye.</string>
<string name="zim_not_opened">Dosyay Zimi nêabiyena</string>
<string name="error_file_invalid">Xeta: Dosyaya weçinıtiye yew dosyaya ZIMia vêrdiye niya.</string>
@ -80,6 +83,7 @@
<string name="delete">Bestere</string>
<string name="cancel">Bıtexelne</string>
<string name="delete_specific_search_toast">Cıgeyrayışo peyên wedariya</string>
<string name="hint_contents_drawer_message">Zerrey nê meqaley vinayışi rê peta hetê çepiya xuz kerê</string>
<string name="got_it">Mı fehm kerd</string>
<string name="did_you_know">Şıma zanenê?</string>
<string name="undo">Peyser biya</string>
@ -99,6 +103,7 @@
<string name="new_tab_snack_bar">Meqale tabê neweyi de bi a</string>
<string name="search_widget_text">Kiwix\'i cıgeyre</string>
<string name="speech_prompt_text">Serva cıgeyrayışi %s vacê</string>
<string name="speech_not_supported">Malesef, cihazê şımayo dekerderê qısekerdışi rê desteg nêdano</string>
<string name="local_zims">Cihaz</string>
<string name="remote_zims">Online</string>
<string name="library">Kıtıbxane</string>
@ -113,10 +118,18 @@
<string name="zim_no_vid">Videoyi çıniyê</string>
<string name="no_network_connection">Gıreyê torre çıniyo</string>
<string name="help_2">Kiwix se keno ?</string>
<string name="help_3">Kiwix offline wanayoğê zerrekiyo. Eyni zey browserê torro lakin pelanê webi vera online resayışi, zerrekê dosyayan formatê ZIMi de waneno.</string>
<string name="help_4">Kiwix normalde Wikipedia offline wanayışi rê dizayn biya lakin zerrekê online zi şeno bıwano.</string>
<string name="help_5">Zerrek kam ca de yo?</string>
<string name="help_6">Zerrekê ma pela websita Kiwixi de yo.</string>
<string name="help_7">Zey dosyayanê ZIMi benê. İnan ra zeder estê :</string>
<string name="help_8">• Wikipedia seba herg zıwani weziyetê gureynayışi dera.</string>
<string name="help_9">• Çımey zey Wikileaks yana Wikiçıme enewke weziyetê gureynayışi derê.</string>
<string name="help_10">Weçinyayey dosyay ZIMi zerrey aplikasyoni de roniyenê yana waştenanê ho verê transferê SD kart kerdışi şenê komputeri ra desktopi ra ronê</string>
<string name="help_11">Zerrey aplikasyon miyan de roniyaye dosyay ZIM dosyaları cihazê depoy teberi de be namey klasorê sernamey Kiwix dero</string>
<string name="pref_storage">Depo kerdış</string>
<string name="pref_current_folder">Klasoro Mewcud</string>
<string name="delete_zim_failed">Malesef ma nêşa tay dosyayan esterê. Belka şıma şenê yew idarekari ra peşti bıgêrê.</string>
<string name="tts_pause">bıvındarne</string>
<string name="tts_resume">devam kerê</string>
<string name="stop">bıvındarne</string>
@ -127,8 +140,13 @@
<string name="confirm_stop_download_title">Wa ronayış vındero?</string>
<string name="confirm_stop_download_msg">Şıma qayılê nê ronayışi vındarne?</string>
<string name="download_change_storage">Weçinoğê cihazê depokerdışi</string>
<string name="tts_not_enabled">Seba na dosyay ZIM tetbiqiya wanayışê metini hewl niya</string>
<string name="texttospeech_initialization_failed">Metin ra wanayıi sernêkewto. Reyna bıcerrebnê</string>
<string name="texttospeech_error">Metin ra wanayışi de xeta. Reyna bıcerrebnê</string>
<string name="next">Bahdoyên</string>
<string name="previous">Verên</string>
<string name="wifi_only_title">Zerrek wa torra mobiliya gureynayışiya roneyo?</string>
<string name="wifi_only_msg">Eger ke şıma “Eya”\'içy weçinê se şıma do bahdo iqaz nêvinê. Lakin Eyaran ra tım zi şıma şenê eney bıvurnê</string>
<string name="pref_wifi_only">Zerreki teyna pê Wifi ya rone</string>
<string name="time_day">roce</string>
<string name="time_hour">sa</string>
@ -138,12 +156,15 @@
<string name="time_today">Ewro</string>
<string name="time_yesterday">Vızêr</string>
<string name="pref_external_link_popup_title">Gırey teberi cıkerdış de iqaz bıde</string>
<string name="pref_external_link_popup_summary">Ekstra ucret ya zi gırey offline nêgureyê se akerde teqa mocnayışiya iqaz bıdê.</string>
<string name="external_link_popup_dialog_title">Gıreyê teberi beno cı!</string>
<string name="external_link_popup_dialog_message">Şımayê kenê ke şırê gırey teberi. No seba transferê ekstra ucreta tabiyo yana weziyetê offline de nêgureniyeno. Şıma qayılê dewam bıkerê?</string>
<string name="do_not_ask_anymore">Endi meperse</string>
<string name="your_languages">Weçinaye zıwan :</string>
<string name="other_languages">Zıwano bin:</string>
<string name="no_items_msg">Karneyaye obce çıniyo</string>
<string name="crash_title">Ey… No teneyê ariyeya</string>
<string name="crash_description">Ze ke ma kewte.\n\nMelumatê cêri rışiyayışa nê problemi baş kerdışi rê şenê peşti bıdê?</string>
<string name="crash_checkbox_language">Eyarê zıwanê şıma</string>
<string name="crash_checkbox_zimfiles">Lista Dosyayanê Zıme Şıma</string>
<string name="crash_checkbox_exception">Detayê Rızyayışi</string>
@ -186,6 +207,7 @@
<string name="note">Note</string>
<string name="wiki_article_title">Serekê Meqaley Wiki</string>
<string name="ext_storage_permission_rationale_add_note">Serva nota resayışê depoyê ganşyoı</string>
<string name="ext_storage_write_permission_denied_add_note">Noti mısadey resayışê depoy nêbo se nêgureniyeno</string>
<string name="note_save_unsuccessful">Qeyd kerdışê noti nêbiyo</string>
<string name="note_delete_successful">Not esteriyaya</string>
<string name="note_delete_unsuccessful">Not nêesteriyê</string>
@ -203,22 +225,37 @@
<string name="discovery_failed">Kaşır nêşayo</string>
<string name="severe_loss_error">Xetaya gıran! WiFi P2P\'yi Dewre ra vec/Retnanaltiv kerê bıcerrebnê</string>
<string name="connection_failed">Gıreyin nêbiya</string>
<string name="permission_rationale_location">Cihazê takêşan ra ferq bıyayışi rê terefê Androidi ra mısadey mehali ganiyo.</string>
<string name="permission_rationale_location_on_host_zim_file">Dosyayanê ZIMi darênayışê aplikasyoni rê terefê Androidi ra mısadey mehali ganiyo.</string>
<string name="permission_refused_location">Bêmısadey mehali cihazanê takêşi nêvineyênê</string>
<string name="permission_refused_storage">Bêmısadey depo kerdışi nêresiyeno dosyayanê ZIMi</string>
<string name="request_enable_location">Taypêyan his kerdışi rê seba mısade dayışi mehali aktiv kerê</string>
<string name="discovery_needs_location">Servisê mehali taypêyi nêvineyênê</string>
<string name="request_enable_wifi">WiFi P2P\'yi eyaranê sistemi ra aktiv ke</string>
<string name="discovery_needs_wifi">WiFi AKERDE nêbo se tekê cı keşf nêbeno</string>
<string name="transfer_to">%s ya wa dosya transfer vo?</string>
<string name="device_not_cooperating">Weçineyaye cihazo seba transferi piya nêguriyeno</string>
<string name="file_transfer_complete">Transferê dosya biyo temam</string>
<string name="error_during_transfer">Çerğa transferi de yew xeta veciyê</string>
<string name="error_transferring">Dosyay %s transfer kerdış de xeta veciyê</string>
<string name="get_content_from_nearby_device">Cihazê nezdiy ra zerrek bıgêrê</string>
<string name="search_for_peers">Zey pêyan cıgeyre</string>
<string name="your_device">Cihazê Şıma:</string>
<string name="nearby_devices">NEZDI CİHAZİ</string>
<string name="no_devices_found">Cihaz nêvineya. Reyna cerbnayışi rê maka cıgeyrayışi bıploğne</string>
<string name="files_for_transfer">TRANSFERÊ DOSYAYAN</string>
<string name="preparing_files">Keno ke dosyaya transfer kero…</string>
<string name="performing_handshake">Dest dano destan…</string>
<string name="status">Weziyet</string>
<string name="pref_clear_all_notes_summary">Meqaleya pêroyın de nota pêroyın pak ke</string>
<string name="pref_clear_all_notes_title">Nota pêroyın pak ke</string>
<string name="pref_text_zoom_summary">Ebatê metin %25 zeydnayışana bıvurnê</string>
<string name="tag_pic">Resım</string>
<string name="tag_vid">Video</string>
<string name="tag_text_only">Teyna metin</string>
<string name="tag_short_text">Metino kılm</string>
<string name="storage_permission_denied">İcazetê depoy red biyo</string>
<string name="grant_read_storage_permission">Aplikasyoni seba gurenayışê depoy rê hunerê wanayışi icab keno</string>
<string name="go_to_settings">Şo eyaranê Hotspoti</string>
<string name="no_results">Neticeyi çıniyê</string>
<string name="no_bookmarks">Nişani çıniyê</string>
@ -234,6 +271,7 @@
<string name="send_report">Rapora teşhisi bırışê</string>
<string name="crash_checkbox_file_system">Detayê Sistemê Dosya</string>
<string name="diagnostic_report">Rapora Teşhisi</string>
<string name="diagnostic_report_message">Problemi fahm kerdışi rê detayanê cêrêna pêroyın kontrol kerê</string>
<string name="percentage">%d%%</string>
<string name="pref_text_zoom_title">Nazdiyiya metini</string>
<string name="search_open_in_new_tab">Taba newiye de ake</string>
@ -244,4 +282,5 @@
<string name="open_drawer">Antergey akerê</string>
<string name="close_drawer">Antergey bıqefelne</string>
<string name="how_to_update_content">Zerrek seni rocane beno?</string>
<string name="update_content_description">Seba rocane kerdışê zerreki (yu dosyay zimi), etni zerrekiya versiyonê tewr peyêni ronayış ganiyo. Ney kışta ronayışi ra şenê bıkerê.</string>
</resources>

View File

@ -27,6 +27,7 @@
<string name="hotspot_failed_title">Aviamentu de s\'hotspot fallidu</string>
<string name="hotspot_failed_message">Paret chi s\'hotspot tuo siat allutu. Pro praghere disabìlita s\'hotspot wifi tuo pro sighire.</string>
<string name="go_to_wifi_settings_label">Bae a sas impostatziones de su WIFI</string>
<string name="connection_refused">Connessione negada.</string>
<string name="hotspot_running">Hotspot ativu</string>
<string name="no_books_selected_toast_message">In antis ischerta libros</string>
<string name="server_failed_message">Aviamentu de su servidore fallidu. Pro praghere allughe s\'hotspot tuo</string>
@ -221,6 +222,7 @@
<string name="severe_loss_error">Faddina manna! Proa a Disabilitare/Torrare a abilitare su P2P WiFi</string>
<string name="connection_failed">Connessione fallida</string>
<string name="permission_rationale_location">Android tenet bisòngiu de su permissu de localizatzione pro rilevare dispositivos pares (peers)</string>
<string name="permission_rationale_location_on_host_zim_file">Android tenet bisòngiu de su permissu de localizatzione pro permìtere a s\'aplicatzione de istrangiare documentos Zim</string>
<string name="permission_refused_location">Impossìbile localizare dispositivos pares (peers) chene sos permissos de localizatzione</string>
<string name="permission_refused_storage">Impossìbile tènnere atzessu a sos documentos zim chene su permissu de archiviatzione</string>
<string name="request_enable_location">Abìlita sa localizatzione pro permìtere su rilevamentu de pares (peers)</string>
@ -243,6 +245,7 @@
<string name="status">Istadu</string>
<string name="pref_clear_all_notes_summary">Iscantzella totu sas notas in totu sos artìculos</string>
<string name="pref_clear_all_notes_title">Iscantzella totu sas notas</string>
<string name="pref_text_zoom_summary">Càmbia sa mannària de su testu cun ismanniamentos de su 25%.</string>
<string name="tag_pic">Immàgine</string>
<string name="tag_vid">Vìdeu</string>
<string name="tag_text_only">Testu ebbia</string>
@ -267,4 +270,13 @@
<string name="diagnostic_report_message">Pro praghere imbia totu sos detàllios chi sighent, in manera chi amus a pòdere diagnosticare su problema</string>
<string name="percentage">%d%%</string>
<string name="pref_text_zoom_title">Ismanniamentu de su testu</string>
<string name="search_open_in_new_tab">Aberi in un\'ischeda noa</string>
<string name="reader">Leghidore</string>
<string name="no_open_book">Perunu libru abertu</string>
<string name="open_library">Aberi sa biblioteca</string>
<string name="tab_restored">Ischeda ripristinada</string>
<string name="open_drawer">Aberi su pannellu</string>
<string name="close_drawer">Serra su pannellu</string>
<string name="how_to_update_content">Comente agiornare su cuntenutu?</string>
<string name="update_content_description">Pro agiornare su cuntenutu (unu documentu zim) tenes bisòngiu de iscarrigare s\'ùtrima versione intrea de su matessi cuntenutu. Lu podes fàghere pro mèdiu de sa setzione de iscarrigamentu.</string>
</resources>

View File

@ -0,0 +1,90 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Authors:
* Saraiki
-->
<resources>
<string name="menu_help">مدد</string>
<string name="menu_home">گھر</string>
<string name="menu_settings">ترتیباں</string>
<string name="menu_search_in_text">ورقے وچ لبھو</string>
<string name="bookmarks">بک مارک</string>
<string name="menu_random_article">کُݨے نال چوݨواں مضمون</string>
<string name="menu_full_screen">پوری سکرین</string>
<string name="menu_exit_full_screen">پوری سکرین توں نکلو</string>
<string name="menu_read_aloud">اُچی آواز نال پڑھو</string>
<string name="save_media">میڈیا بچاؤ</string>
<string name="search_label">ڳولو</string>
<string name="pref_display_title">ڈسپلے</string>
<string name="pref_info_title">معلومات</string>
<string name="pref_info_version">ورژن</string>
<string name="pref_night_mode">رات آلا مزاج</string>
<string name="pref_back_to_top">واپس اُتے ون٘ڄو</string>
<string name="pref_language_title">زبان</string>
<string name="pref_language_chooser">زبان چݨو</string>
<string name="delete_recent_search_item">ایہ ائٹم مٹاؤں؟</string>
<string name="pref_clear_all_history_title">تاریخچہ مٹاؤ</string>
<string name="clear_all_history_dialog_title">ساری تاریخ صاف کروں؟</string>
<string name="share">شیئر</string>
<string name="delete">مٹاؤ</string>
<string name="cancel">منسوخ</string>
<string name="got_it">گھن گھندا</string>
<string name="did_you_know">بھلا تساں ڄاݨدے ہو؟</string>
<string name="undo">واپس</string>
<string name="tab_closed">ٹیب بند تھی ڳئی</string>
<string name="bookmark_added">بک مارک شامل تھی ڳیا</string>
<string name="no_thanks">کو، شکریہ</string>
<string name="rate_dialog_neutral">بعد وچ</string>
<string name="open">کھولو</string>
<string name="pref_extras">فالتو</string>
<string name="search_widget_text">کیوکس وچ ڳولو</string>
<string name="local_zims">مشین، ڈیوائس</string>
<string name="remote_zims">آن لائن</string>
<string name="library">لائبریری</string>
<string name="no_files_here">اتھ کوئی فائلاں کائنی</string>
<string name="download">ڈاؤن لوڈ</string>
<string name="zim_simple">سادہ</string>
<string name="zim_no_vid">ویڈیو کائنی</string>
<string name="help_2">کِوِکس کیا کریندے؟</string>
<string name="pref_storage">ذخیرہ</string>
<string name="pref_current_folder">حالیہ فولڈر</string>
<string name="tts_pause">جمبو، اجھکو</string>
<string name="tts_resume">ولدا شروع کرو</string>
<string name="stop">اختتام</string>
<string name="internal_storage">اندرونی</string>
<string name="external_storage">ٻاہر آلا</string>
<string name="yes">ڄیا</string>
<string name="no">کو</string>
<string name="confirm_stop_download_title">ڈاؤن لوڈ روکوں؟</string>
<string name="next">اڳلا</string>
<string name="previous">پچھلا</string>
<string name="time_day">ݙینہ</string>
<string name="time_hour">گھ</string>
<string name="time_minute">منٹ</string>
<string name="time_second">سیک</string>
<string name="time_left">باقی</string>
<string name="time_today">اڄ</string>
<string name="time_yesterday">کل</string>
<string name="your_languages">چُݨیاں ہویاں زباناں:</string>
<string name="other_languages">ٻیاں زباناں:</string>
<string name="new_tab_shortcut_label">نویں ٹیب</string>
<string name="get_started">شروع کرو</string>
<string name="expand">ودھاؤ</string>
<string name="history">تاریخ</string>
<string name="pending_state">وچار ہیٹھ</string>
<string name="running_state">تھیندا پئے</string>
<string name="complete">مکمل</string>
<string name="paused_state">جمب ڳیا</string>
<string name="save">بچاؤ</string>
<string name="note">نوٹ</string>
<string name="status">حیثیت</string>
<string name="tag_pic">تصویر</string>
<string name="tag_vid">وڈیو</string>
<string name="tag_text_only">صرف عبارت</string>
<string name="no_bookmarks">بک مارک کائنی</string>
<string name="on">آن</string>
<string name="off">بند</string>
<string name="auto">خود بخود</string>
<string name="open_library">مفت لائبریری</string>
<string name="open_drawer">دراز کھولو</string>
<string name="close_drawer">دراز بند کرو</string>
</resources>

View File

@ -70,7 +70,7 @@ internal class ProcessActivityResultTest {
@Test
fun `invoke with sends filter action with data`() {
every { data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS)[0] } returns ""
every { data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS) } returns arrayListOf("")
successfulResult.invokeWith(activity)
verify { actions.offer(Filter("")) }
}

View File

@ -24,6 +24,7 @@ import androidx.drawerlayout.widget.DrawerLayout
import androidx.navigation.NavController
import androidx.navigation.findNavController
import com.google.android.material.navigation.NavigationView
import kotlinx.android.synthetic.main.activity_custom_main.activity_main_nav_view
import kotlinx.android.synthetic.main.activity_custom_main.custom_drawer_container
import kotlinx.android.synthetic.main.activity_custom_main.drawer_nav_view
import org.kiwix.kiwixmobile.core.di.components.CoreComponent
@ -40,6 +41,7 @@ class CustomMainActivity : CoreMainActivity() {
}
override val drawerContainerLayout: DrawerLayout by lazy { custom_drawer_container }
override val drawerNavView: NavigationView by lazy { drawer_nav_view }
override val readerTableOfContentsDrawer: NavigationView by lazy { activity_main_nav_view }
override val searchFragmentResId: Int = R.id.searchFragment
override val bookmarksFragmentResId: Int = R.id.bookmarksFragment
override val settingsFragmentResId: Int = R.id.customSettingsFragment