mirror of
https://github.com/kiwix/kiwix-android.git
synced 2025-09-09 07:16:04 -04:00
Resolved conflicts
This commit is contained in:
commit
eaf6b77664
3
.github/workflows/coverage.yml
vendored
3
.github/workflows/coverage.yml
vendored
@ -15,7 +15,7 @@ jobs:
|
||||
coverageReport:
|
||||
strategy:
|
||||
matrix:
|
||||
api-level: [21, 21]
|
||||
api-level: [21, 21]
|
||||
fail-fast: false
|
||||
runs-on: macOS-latest
|
||||
steps:
|
||||
@ -48,6 +48,7 @@ jobs:
|
||||
|
||||
- name: Upload Coverage to GH-Actions
|
||||
uses: actions/upload-artifact@v2.2.0
|
||||
if: ${{ always() }}
|
||||
with:
|
||||
name: Tests Coverage Report
|
||||
path: |
|
||||
|
1
.github/workflows/pull_request.yml
vendored
1
.github/workflows/pull_request.yml
vendored
@ -18,6 +18,7 @@ jobs:
|
||||
|
||||
- name: Upload Static Analysis Report
|
||||
uses: actions/upload-artifact@v2.2.0
|
||||
if: ${{ always() }}
|
||||
with:
|
||||
name: Static Analysis Report
|
||||
path: |
|
||||
|
@ -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
|
||||
|
@ -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).
|
||||
|
@ -29,11 +29,12 @@ import org.junit.Rule
|
||||
import org.junit.runner.RunWith
|
||||
import org.kiwix.kiwixmobile.core.di.components.DaggerTestComponent
|
||||
import org.kiwix.kiwixmobile.core.di.components.TestComponent
|
||||
import org.kiwix.kiwixmobile.main.KiwixMainActivity
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
abstract class BaseActivityTest<T : Activity> {
|
||||
abstract class BaseActivityTest {
|
||||
@get:Rule
|
||||
abstract var activityRule: ActivityTestRule<T>
|
||||
open var activityRule = ActivityTestRule(KiwixMainActivity::class.java)
|
||||
|
||||
@get:Rule
|
||||
var readPermissionRule: GrantPermissionRule =
|
||||
|
@ -18,18 +18,11 @@
|
||||
package org.kiwix.kiwixmobile.help
|
||||
|
||||
import androidx.test.internal.runner.junit4.statement.UiThreadStatement.runOnUiThread
|
||||
import androidx.test.rule.ActivityTestRule
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.kiwix.kiwixmobile.BaseActivityTest
|
||||
import org.kiwix.kiwixmobile.R
|
||||
import org.kiwix.kiwixmobile.main.KiwixMainActivity
|
||||
|
||||
class HelpFragmentTest : BaseActivityTest<KiwixMainActivity>() {
|
||||
|
||||
@get:Rule
|
||||
override var activityRule: ActivityTestRule<KiwixMainActivity> =
|
||||
ActivityTestRule(KiwixMainActivity::class.java)
|
||||
class HelpFragmentTest : BaseActivityTest() {
|
||||
|
||||
@Test
|
||||
fun verifyHelpActivity() {
|
||||
|
@ -21,11 +21,8 @@ import androidx.test.internal.runner.junit4.statement.UiThreadStatement.runOnUiT
|
||||
import org.junit.Test
|
||||
import org.kiwix.kiwixmobile.BaseActivityTest
|
||||
import org.kiwix.kiwixmobile.R
|
||||
import org.kiwix.kiwixmobile.main.KiwixMainActivity
|
||||
|
||||
class IntroFragmentTest : BaseActivityTest<KiwixMainActivity>() {
|
||||
|
||||
override var activityRule = activityTestRule<KiwixMainActivity>()
|
||||
class IntroFragmentTest : BaseActivityTest() {
|
||||
|
||||
@Test
|
||||
fun viewIsSwipeableAndNavigatesToMain() {
|
||||
|
@ -17,14 +17,20 @@
|
||||
*/
|
||||
package org.kiwix.kiwixmobile.main
|
||||
|
||||
import androidx.core.content.edit
|
||||
import androidx.preference.PreferenceManager
|
||||
import androidx.test.rule.ActivityTestRule
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.kiwix.kiwixmobile.BaseActivityTest
|
||||
import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil
|
||||
|
||||
class TopLevelDestinationTest {
|
||||
@Rule
|
||||
@JvmField
|
||||
var activityTestRule = ActivityTestRule(KiwixMainActivity::class.java)
|
||||
class TopLevelDestinationTest : BaseActivityTest() {
|
||||
|
||||
override var activityRule: ActivityTestRule<KiwixMainActivity> = activityTestRule {
|
||||
PreferenceManager.getDefaultSharedPreferences(context).edit {
|
||||
putBoolean(SharedPreferenceUtil.PREF_SHOW_INTRO, false)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testTopLevelDestination() {
|
||||
|
@ -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?
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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),
|
||||
|
@ -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()
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -73,7 +73,6 @@ import org.kiwix.kiwixmobile.zim_manager.library_view.adapter.LibraryListItem.Li
|
||||
import java.util.LinkedList
|
||||
import java.util.Locale
|
||||
import java.util.concurrent.TimeUnit.MILLISECONDS
|
||||
import java.util.concurrent.TimeUnit.SECONDS
|
||||
import javax.inject.Inject
|
||||
|
||||
class ZimManageViewModel @Inject constructor(
|
||||
@ -218,18 +217,15 @@ class ZimManageViewModel @Inject constructor(
|
||||
connectivityBroadcastReceiver.networkStates.distinctUntilChanged().filter(
|
||||
CONNECTED::equals
|
||||
),
|
||||
BiFunction<Unit, NetworkState, Unit> { _, _ -> Unit }
|
||||
BiFunction<Unit, NetworkState, Unit> { _, _ -> }
|
||||
)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(Schedulers.io())
|
||||
.subscribe(
|
||||
{
|
||||
kiwixService.library
|
||||
.timeout(60, SECONDS)
|
||||
.retry(5)
|
||||
.subscribe(
|
||||
library::onNext
|
||||
) {
|
||||
.subscribe(library::onNext) {
|
||||
it.printStackTrace()
|
||||
library.onNext(LibraryNetworkEntity().apply { book = LinkedList() })
|
||||
}
|
||||
|
@ -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 d‘u 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>
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
|
||||
|
@ -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"
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -65,8 +65,8 @@ abstract class CoreApp : Application() {
|
||||
* The init of this class does the work of initializing,
|
||||
* simply injecting it is all that there is to be done
|
||||
*/
|
||||
// @Inject
|
||||
// lateinit var serviceWorkerInitialiser: ServiceWorkerInitialiser
|
||||
@Inject
|
||||
lateinit var serviceWorkerInitialiser: ServiceWorkerInitialiser
|
||||
|
||||
override fun attachBaseContext(base: Context) {
|
||||
super.attachBaseContext(base)
|
||||
|
@ -32,15 +32,19 @@ import javax.inject.Singleton
|
||||
|
||||
private const val CONNECTION_TIMEOUT = 10L
|
||||
private const val READ_TIMEOUT = 60L
|
||||
private const val CALL_TIMEOUT = 60L
|
||||
private const val USER_AGENT = "kiwix-android-version:${BuildConfig.VERSION_CODE}"
|
||||
private const val KIWIX_DOWNLOAD_URL = "http://mirror.download.kiwix.org/"
|
||||
|
||||
@Module
|
||||
class NetworkModule {
|
||||
@Provides @Singleton fun provideOkHttpClient(): OkHttpClient {
|
||||
return OkHttpClient().newBuilder().followRedirects(true).followSslRedirects(true)
|
||||
return OkHttpClient().newBuilder()
|
||||
.followRedirects(true)
|
||||
.followSslRedirects(true)
|
||||
.connectTimeout(CONNECTION_TIMEOUT, SECONDS)
|
||||
.readTimeout(READ_TIMEOUT, SECONDS)
|
||||
.callTimeout(CALL_TIMEOUT, SECONDS)
|
||||
.addNetworkInterceptor(HttpLoggingInterceptor().apply {
|
||||
level = if (BuildConfig.DEBUG) BASIC else NONE
|
||||
})
|
||||
|
@ -25,7 +25,7 @@ import org.simpleframework.xml.Attribute;
|
||||
import org.simpleframework.xml.ElementList;
|
||||
import org.simpleframework.xml.Root;
|
||||
|
||||
@Root(name = "library", strict = false)
|
||||
@Root(name = "library")
|
||||
public class LibraryNetworkEntity {
|
||||
|
||||
@ElementList(name = "book", inline = true, required = false)
|
||||
|
@ -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(
|
||||
|
@ -123,6 +123,7 @@ import static android.content.pm.PackageManager.PERMISSION_GRANTED;
|
||||
import static org.kiwix.kiwixmobile.core.base.FragmentActivityExtensions.Super.ShouldCall;
|
||||
import static org.kiwix.kiwixmobile.core.base.FragmentActivityExtensions.Super.ShouldNotCall;
|
||||
import static org.kiwix.kiwixmobile.core.downloader.fetch.FetchDownloadNotificationManagerKt.DOWNLOAD_NOTIFICATION_TITLE;
|
||||
import static org.kiwix.kiwixmobile.core.main.ServiceWorkerUninitialiserKt.UNINITIALISER_ADDRESS;
|
||||
import static org.kiwix.kiwixmobile.core.page.history.adapter.HistoryListItem.HistoryItem;
|
||||
import static org.kiwix.kiwixmobile.core.utils.AnimationUtils.rotate;
|
||||
import static org.kiwix.kiwixmobile.core.utils.ConstantsKt.REQUEST_STORAGE_PERMISSION;
|
||||
@ -743,6 +744,12 @@ public abstract class CoreReaderFragment extends BaseFragment
|
||||
AttributeSet attrs = StyleUtils.getAttributes(requireActivity(), R.xml.webview);
|
||||
KiwixWebView webView = createWebView(attrs);
|
||||
loadUrl(url, webView);
|
||||
setUpWithTextToSpeech(webView);
|
||||
documentParser.initInterface(webView);
|
||||
new ServiceWorkerUninitialiser(() -> {
|
||||
openMainPage();
|
||||
return Unit.INSTANCE;
|
||||
}).initInterface(webView);
|
||||
return webView;
|
||||
}
|
||||
|
||||
@ -762,10 +769,20 @@ public abstract class CoreReaderFragment extends BaseFragment
|
||||
return newTab(contentUrl(zimReaderContainer.getMainPage()));
|
||||
}
|
||||
|
||||
protected KiwixWebView newTab(String url) {
|
||||
private KiwixWebView newTab(String url) {
|
||||
return newTab(url, true);
|
||||
}
|
||||
|
||||
private void newTabInBackground(String url) {
|
||||
newTab(url, false);
|
||||
}
|
||||
|
||||
private KiwixWebView newTab(String url, boolean selectTab) {
|
||||
KiwixWebView webView = initalizeWebView(url);
|
||||
webViewList.add(webView);
|
||||
selectTab(webViewList.size() - 1);
|
||||
if(selectTab) {
|
||||
selectTab(webViewList.size() - 1);
|
||||
}
|
||||
tabsAdapter.notifyDataSetChanged();
|
||||
setUpWebViewWithTextToSpeech();
|
||||
if (webView != null) {
|
||||
@ -774,14 +791,6 @@ public abstract class CoreReaderFragment extends BaseFragment
|
||||
return webView;
|
||||
}
|
||||
|
||||
private void newTabInBackground(String url) {
|
||||
KiwixWebView webView = initalizeWebView(url);
|
||||
webViewList.add(webView);
|
||||
tabsAdapter.notifyDataSetChanged();
|
||||
setUpWebViewWithTextToSpeech();
|
||||
documentParser.initInterface(webView);
|
||||
}
|
||||
|
||||
private void closeTab(int index) {
|
||||
tempZimFileForUndo = zimReaderContainer.getZimFile();
|
||||
tempWebViewForUndo = webViewList.get(index);
|
||||
@ -816,7 +825,7 @@ public abstract class CoreReaderFragment extends BaseFragment
|
||||
tabsAdapter.notifyDataSetChanged();
|
||||
|
||||
Snackbar.make(snackbarRoot, R.string.tab_restored, Snackbar.LENGTH_SHORT).show();
|
||||
setUpWebViewWithTextToSpeech();
|
||||
setUpWithTextToSpeech(tempWebViewForUndo);
|
||||
updateBottomToolbarVisibility();
|
||||
contentFrame.addView(tempWebViewForUndo);
|
||||
}
|
||||
@ -1048,7 +1057,7 @@ public abstract class CoreReaderFragment extends BaseFragment
|
||||
if (mainMenu != null) {
|
||||
mainMenu.onFileOpened(urlIsValid());
|
||||
}
|
||||
openMainPage();
|
||||
openArticle(UNINITIALISER_ADDRESS);
|
||||
safeDispose();
|
||||
bookmarkingDisposable = Flowable.combineLatest(
|
||||
newBookmarksDao.bookmarkUrlsForCurrentBook(zimFileReader),
|
||||
@ -1305,8 +1314,8 @@ public abstract class CoreReaderFragment extends BaseFragment
|
||||
openArticle(articleUrl);
|
||||
}
|
||||
|
||||
private void setUpWebViewWithTextToSpeech() {
|
||||
if (tts != null) tts.initWebView(getCurrentWebView());
|
||||
private void setUpWithTextToSpeech(KiwixWebView kiwixWebView) {
|
||||
tts.initWebView(kiwixWebView);
|
||||
}
|
||||
|
||||
@OnClick(R2.id.activity_main_back_to_top_fab)
|
||||
|
@ -22,6 +22,7 @@ import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.util.Log;
|
||||
import android.webkit.MimeTypeMap;
|
||||
import android.webkit.WebResourceRequest;
|
||||
import android.webkit.WebResourceResponse;
|
||||
import android.webkit.WebView;
|
||||
import android.webkit.WebViewClient;
|
||||
@ -42,6 +43,7 @@ public class CoreWebViewClient extends WebViewClient {
|
||||
protected final WebViewCallback callback;
|
||||
protected final ZimReaderContainer zimReaderContainer;
|
||||
private static String[] LEGACY_CONTENT_PREFIXES = new String[] {
|
||||
"zim://content/",
|
||||
Uri.parse("content://" + CoreApp.getInstance().getPackageName() + ".zim.base/").toString()
|
||||
};
|
||||
private String urlWithAnchor;
|
||||
@ -67,10 +69,6 @@ public class CoreWebViewClient extends WebViewClient {
|
||||
if (url.startsWith(CONTENT_PREFIX)) {
|
||||
return handleEpubAndPdf(url);
|
||||
}
|
||||
if (url.startsWith("file://")) {
|
||||
// To handle home page (loaded from resources)
|
||||
return true;
|
||||
}
|
||||
if (url.startsWith("javascript:")) {
|
||||
// Allow javascript for HTML functions and code execution (EX: night mode)
|
||||
return true;
|
||||
@ -116,8 +114,7 @@ public class CoreWebViewClient extends WebViewClient {
|
||||
|
||||
@Override
|
||||
public void onPageFinished(WebView view, String url) {
|
||||
boolean invalidUrl =
|
||||
url.equals(CONTENT_PREFIX + "null");
|
||||
boolean invalidUrl = url.equals(CONTENT_PREFIX + "null");
|
||||
|
||||
Log.d(TAG_KIWIX, "invalidUrl = " + invalidUrl);
|
||||
|
||||
@ -142,12 +139,15 @@ public class CoreWebViewClient extends WebViewClient {
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
|
||||
url = convertLegacyUrl(url);
|
||||
public WebResourceResponse shouldInterceptRequest(
|
||||
WebView view,
|
||||
WebResourceRequest request)
|
||||
{
|
||||
String url = convertLegacyUrl(request.getUrl().toString());
|
||||
if (url.startsWith(CONTENT_PREFIX)) {
|
||||
return zimReaderContainer.load(url);
|
||||
} else {
|
||||
return super.shouldInterceptRequest(view, url);
|
||||
return super.shouldInterceptRequest(view, request);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* 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.main
|
||||
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.webkit.JavascriptInterface
|
||||
import android.webkit.WebView
|
||||
|
||||
const val UNINITIALISER_ADDRESS = "A/remove_service_workers.html"
|
||||
private const val UNINITIALISER_INTERFACE = "ServiceWorkerUninitialiser"
|
||||
const val UNINITIALISE_HTML = """
|
||||
<html>
|
||||
<head>
|
||||
<script type="text/javascript">
|
||||
function do_unregister() {
|
||||
if (!navigator.serviceWorker) {
|
||||
$UNINITIALISER_INTERFACE.onUninitialised();
|
||||
return;
|
||||
}
|
||||
navigator.serviceWorker.getRegistrations().then(async function (registrations) {
|
||||
if (registrations.length) {
|
||||
console.debug('we do have ' + registrations.length + ' registration(s)');
|
||||
var registration = registrations[0];
|
||||
registration.unregister()
|
||||
.then(function (success) { $UNINITIALISER_INTERFACE.onUninitialised();})
|
||||
.catch(function (e) {alert("ERR:" + e)});
|
||||
}
|
||||
else {
|
||||
$UNINITIALISER_INTERFACE.onUninitialised();
|
||||
}
|
||||
});
|
||||
}
|
||||
do_unregister();
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="loading" style="width: 100%; text-align: center">
|
||||
<svg width="38" height="38" viewBox="0 0 38 38" xmlns="http://www.w3.org/2000/svg" stroke="#fff">
|
||||
<g fill="none" fill-rule="evenodd">
|
||||
<g transform="translate(1 1)" stroke-width="2">
|
||||
<path d="M36 18c0-9.94-8.06-18-18-18" stroke="gray">
|
||||
<animateTransform
|
||||
attributeName="transform"
|
||||
type="rotate"
|
||||
from="0 18 18"
|
||||
to="360 18 18"
|
||||
dur="1s"
|
||||
repeatCount="indefinite"/>
|
||||
</path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
"""
|
||||
|
||||
class ServiceWorkerUninitialiser(val onUninitialisedAction: () -> Unit) {
|
||||
|
||||
fun initInterface(webView: WebView) {
|
||||
webView.addJavascriptInterface(this, UNINITIALISER_INTERFACE)
|
||||
}
|
||||
|
||||
@JavascriptInterface
|
||||
fun onUninitialised() {
|
||||
Handler(Looper.getMainLooper()).post { onUninitialisedAction() }
|
||||
}
|
||||
}
|
@ -33,6 +33,8 @@ import org.kiwix.kiwixlib.Pair
|
||||
import org.kiwix.kiwixmobile.core.CoreApp
|
||||
import org.kiwix.kiwixmobile.core.NightModeConfig
|
||||
import org.kiwix.kiwixmobile.core.entity.LibraryNetworkEntity.Book
|
||||
import org.kiwix.kiwixmobile.core.main.UNINITIALISER_ADDRESS
|
||||
import org.kiwix.kiwixmobile.core.main.UNINITIALISE_HTML
|
||||
import org.kiwix.kiwixmobile.core.reader.ZimFileReader.Companion.CONTENT_PREFIX
|
||||
import org.kiwix.kiwixmobile.core.search.SearchSuggestion
|
||||
import org.kiwix.kiwixmobile.core.utils.files.FileUtils
|
||||
@ -136,7 +138,10 @@ class ZimFileReader constructor(
|
||||
fun getRedirect(url: String) = "${toRedirect(url)}"
|
||||
|
||||
fun isRedirect(url: String) =
|
||||
url.startsWith(CONTENT_PREFIX) && url != getRedirect(url)
|
||||
when {
|
||||
getRedirect(url).isEmpty() || url.endsWith(UNINITIALISER_ADDRESS) -> false
|
||||
else -> url.startsWith(CONTENT_PREFIX) && url != getRedirect(url)
|
||||
}
|
||||
|
||||
private fun toRedirect(url: String) =
|
||||
"$CONTENT_PREFIX${jniKiwixReader.checkUrl(url.toUri().filePath)}".toUri()
|
||||
@ -176,11 +181,15 @@ class ZimFileReader constructor(
|
||||
Completable.fromAction {
|
||||
try {
|
||||
outputStream.use {
|
||||
getContentAndMimeType(uri).let { (content: ByteArray, mimeType: String) ->
|
||||
if ("text/css" == mimeType && nightModeConfig.isNightModeActive()) {
|
||||
it.write(INVERT_IMAGES_VIDEO.toByteArray(Charsets.UTF_8))
|
||||
if (uri.endsWith(UNINITIALISER_ADDRESS)) {
|
||||
it.write(UNINITIALISE_HTML.toByteArray())
|
||||
} else {
|
||||
getContentAndMimeType(uri).let { (content: ByteArray, mimeType: String) ->
|
||||
if ("text/css" == mimeType && nightModeConfig.isNightModeActive()) {
|
||||
it.write(INVERT_IMAGES_VIDEO.toByteArray())
|
||||
}
|
||||
it.write(content)
|
||||
}
|
||||
it.write(content)
|
||||
}
|
||||
}
|
||||
} catch (ioException: IOException) {
|
||||
@ -236,7 +245,7 @@ class ZimFileReader constructor(
|
||||
@JvmField
|
||||
val UI_URI: Uri? = Uri.parse("content://org.kiwix.ui/")
|
||||
|
||||
const val CONTENT_PREFIX = "zim://content/"
|
||||
const val CONTENT_PREFIX = "https://kiwix.app/"
|
||||
|
||||
private val INVERT_IMAGES_VIDEO =
|
||||
"""
|
||||
|
@ -24,9 +24,7 @@ import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Singleton
|
||||
class ZimReaderContainer @Inject constructor(
|
||||
private val zimFileReaderFactory: Factory
|
||||
) {
|
||||
class ZimReaderContainer @Inject constructor(private val zimFileReaderFactory: Factory) {
|
||||
var zimFileReader: ZimFileReader? = null
|
||||
set(value) {
|
||||
field?.dispose()
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
@ -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ı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>
|
||||
|
@ -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>
|
||||
|
90
core/src/main/res/values-skr/strings.xml
Normal file
90
core/src/main/res/values-skr/strings.xml
Normal 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>
|
@ -31,6 +31,7 @@
|
||||
<string name="hotspot_failed_title">Misslyckades att starta surfpunkt</string>
|
||||
<string name="hotspot_failed_message">Det verkar som att din surfpunkt redan är aktiverad. Var god inaktivera din WiFi-surfpunkt för att fortsätta.</string>
|
||||
<string name="go_to_wifi_settings_label">Gå till WiFi-inställningar</string>
|
||||
<string name="connection_refused">Anslutning vägrades.</string>
|
||||
<string name="hotspot_running">Aktiv surfpunkt</string>
|
||||
<string name="no_books_selected_toast_message">Välj böcker först</string>
|
||||
<string name="server_failed_message">Kunde inte starta server. Var god aktivera din surfpunkt</string>
|
||||
@ -220,15 +221,25 @@
|
||||
<string name="notes_deletion_successful">Raderade hela anteckningsmappen</string>
|
||||
<string name="notes_deletion_unsuccessful">Vissa filer raderades inte</string>
|
||||
<string name="books_count">%d bok/böcker</string>
|
||||
<string name="discovery_initiated">Inleder upptäckt</string>
|
||||
<string name="discovery_failed">Upptäckt misslyckades</string>
|
||||
<string name="severe_loss_error">Allvarligt fel! Testa att starta om WiFi P2P</string>
|
||||
<string name="connection_failed">Anslutning misslyckades</string>
|
||||
<string name="permission_rationale_location">Platsåtkomst krävs från Android för att låta appen söka efter närliggande enheter.</string>
|
||||
<string name="permission_rationale_location_on_host_zim_file">Platsåtkomst krävs från Android för att låta appen hantera Host Zim-filer.</string>
|
||||
<string name="permission_refused_location">Kan inte hitta närliggande enheter utan platsåtkomst.</string>
|
||||
<string name="permission_refused_storage">Kan inte komma åt zim-filer utan lagringsbehörighet</string>
|
||||
<string name="request_enable_location">Aktivera plats för att tillåta sökning efter närliggande enheter</string>
|
||||
<string name="discovery_needs_location">Kan inte hitta närliggande enheter utan platstjänster</string>
|
||||
<string name="request_enable_wifi">Aktivera WiFi P2P i systeminställningar</string>
|
||||
<string name="discovery_needs_wifi">Kan inte hitta närliggande enheter utan WiFi</string>
|
||||
<string name="transfer_to">Överför filer till %s?</string>
|
||||
<string name="device_not_cooperating">Valda enheter samarbetar inte för överföring</string>
|
||||
<string name="file_transfer_complete">Filöverföring slutfördes</string>
|
||||
<string name="error_during_transfer">Ett fel uppstod under överförning</string>
|
||||
<string name="error_transferring">Fel uppstod när filen %s överfördes</string>
|
||||
<string name="get_content_from_nearby_device">Hämta innehåll från enheter i närheten</string>
|
||||
<string name="search_for_peers">Sök efter enheter</string>
|
||||
<string name="your_device">Din enhet:</string>
|
||||
<string name="nearby_devices">ENHETER I NÄRHETEN</string>
|
||||
<string name="no_devices_found">Inga enheter hittades. Tryck på sökknappen för att söka igen.</string>
|
||||
@ -238,6 +249,7 @@
|
||||
<string name="status">Status</string>
|
||||
<string name="pref_clear_all_notes_summary">Rensar alla anteckningar på alla artiklar</string>
|
||||
<string name="pref_clear_all_notes_title">Rensa alla anteckningar</string>
|
||||
<string name="pref_text_zoom_summary">Ändra textstorlek med steg på 25%.</string>
|
||||
<string name="tag_pic">Bild</string>
|
||||
<string name="tag_vid">Video</string>
|
||||
<string name="tag_text_only">Endast text</string>
|
||||
|
@ -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("")) }
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user