mirror of
https://github.com/kiwix/kiwix-android.git
synced 2025-09-24 05:04:50 -04:00
Merge remote-tracking branch 'origin/develop' into feature/macgills/1301-night-mode
# Conflicts: # core/src/main/java/org/kiwix/kiwixmobile/core/utils/AlertDialogShower.kt # core/src/main/java/org/kiwix/kiwixmobile/core/utils/SharedPreferenceUtil.java # core/src/main/res/layout/activity_zim_host.xml
This commit is contained in:
commit
b79fe60dba
2
.idea/codeStyles/Project.xml
generated
2
.idea/codeStyles/Project.xml
generated
@ -331,4 +331,4 @@
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
</code_scheme>
|
||||
</component>
|
||||
</component>
|
@ -2,6 +2,8 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="org.kiwix.kiwixmobile">
|
||||
|
||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
||||
|
||||
<application
|
||||
android:name=".KiwixApp"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
@ -160,5 +162,8 @@
|
||||
<data android:host="*" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity android:name=".webserver.ZimHostActivity" />
|
||||
|
||||
<service android:name=".webserver.wifi_hotspot.HotspotService" />
|
||||
</application>
|
||||
</manifest>
|
||||
|
@ -15,7 +15,7 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package org.kiwix.kiwixmobile.core.di
|
||||
package org.kiwix.kiwixmobile.di
|
||||
|
||||
import javax.inject.Scope
|
||||
import kotlin.annotation.AnnotationRetention.RUNTIME
|
@ -29,6 +29,8 @@ import org.kiwix.kiwixmobile.local_file_transfer.LocalFileTransferActivity
|
||||
import org.kiwix.kiwixmobile.main.KiwixMainActivity
|
||||
import org.kiwix.kiwixmobile.settings.KiwixSettingsActivity
|
||||
import org.kiwix.kiwixmobile.splash.KiwixSplashActivity
|
||||
import org.kiwix.kiwixmobile.webserver.ZimHostActivity
|
||||
import org.kiwix.kiwixmobile.webserver.ZimHostModule
|
||||
import org.kiwix.kiwixmobile.zim_manager.ZimManageActivity
|
||||
import org.kiwix.kiwixmobile.zim_manager.download_view.DownloadFragment
|
||||
import org.kiwix.kiwixmobile.zim_manager.fileselect_view.ZimFileSelectFragment
|
||||
@ -36,7 +38,13 @@ import org.kiwix.kiwixmobile.zim_manager.fileselect_view.effects.DeleteFiles
|
||||
import org.kiwix.kiwixmobile.zim_manager.library_view.LibraryFragment
|
||||
|
||||
@ActivityScope
|
||||
@Subcomponent(modules = [KiwixActivityModule::class, IntroModule::class])
|
||||
@Subcomponent(
|
||||
modules = [
|
||||
KiwixActivityModule::class,
|
||||
ZimHostModule::class,
|
||||
IntroModule::class
|
||||
]
|
||||
)
|
||||
interface KiwixActivityComponent {
|
||||
fun inject(downloadFragment: DownloadFragment)
|
||||
fun inject(libraryFragment: LibraryFragment)
|
||||
@ -47,6 +55,7 @@ interface KiwixActivityComponent {
|
||||
fun inject(languageActivity: LanguageActivity)
|
||||
fun inject(kiwixMainActivity: KiwixMainActivity)
|
||||
fun inject(kiwixSettingsActivity: KiwixSettingsActivity)
|
||||
fun inject(zimHostActivity: ZimHostActivity)
|
||||
fun inject(introActivity: IntroActivity)
|
||||
fun inject(kiwixSplashActivity: KiwixSplashActivity)
|
||||
|
||||
|
@ -19,9 +19,10 @@
|
||||
package org.kiwix.kiwixmobile.di.components
|
||||
|
||||
import dagger.Component
|
||||
import org.kiwix.kiwixmobile.core.di.components.CoreComponent
|
||||
import org.kiwix.kiwixmobile.di.modules.KiwixModule
|
||||
import org.kiwix.kiwixmobile.di.KiwixScope
|
||||
import org.kiwix.kiwixmobile.core.di.components.CoreComponent
|
||||
import org.kiwix.kiwixmobile.di.components.ServiceComponent.Builder
|
||||
import org.kiwix.kiwixmobile.di.modules.KiwixModule
|
||||
import org.kiwix.kiwixmobile.di.modules.ViewModelModule
|
||||
|
||||
@KiwixScope
|
||||
@ -31,4 +32,5 @@ import org.kiwix.kiwixmobile.di.modules.ViewModelModule
|
||||
)
|
||||
interface KiwixComponent {
|
||||
fun activityComponentBuilder(): KiwixActivityComponent.Builder
|
||||
fun serviceComponent(): Builder
|
||||
}
|
||||
|
@ -16,14 +16,14 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package org.kiwix.kiwixmobile.core.di.components
|
||||
package org.kiwix.kiwixmobile.di.components
|
||||
|
||||
import android.app.Service
|
||||
import dagger.BindsInstance
|
||||
import dagger.Subcomponent
|
||||
import org.kiwix.kiwixmobile.core.di.ServiceScope
|
||||
import org.kiwix.kiwixmobile.core.di.modules.ServiceModule
|
||||
import org.kiwix.kiwixmobile.core.wifi_hotspot.HotspotService
|
||||
import org.kiwix.kiwixmobile.di.ServiceScope
|
||||
import org.kiwix.kiwixmobile.di.modules.ServiceModule
|
||||
import org.kiwix.kiwixmobile.webserver.wifi_hotspot.HotspotService
|
||||
|
||||
@Subcomponent(modules = [ServiceModule::class])
|
||||
@ServiceScope
|
@ -16,7 +16,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package org.kiwix.kiwixmobile.core.di.modules
|
||||
package org.kiwix.kiwixmobile.di.modules
|
||||
|
||||
import android.app.NotificationManager
|
||||
import android.app.Service
|
||||
@ -25,12 +25,12 @@ import dagger.Module
|
||||
import dagger.Provides
|
||||
import org.kiwix.kiwixlib.JNIKiwixLibrary
|
||||
import org.kiwix.kiwixlib.JNIKiwixServer
|
||||
import org.kiwix.kiwixmobile.core.di.ServiceScope
|
||||
import org.kiwix.kiwixmobile.core.webserver.WebServerHelper
|
||||
import org.kiwix.kiwixmobile.core.wifi_hotspot.HotspotNotificationManager
|
||||
import org.kiwix.kiwixmobile.core.wifi_hotspot.HotspotStateReceiver
|
||||
import org.kiwix.kiwixmobile.core.wifi_hotspot.HotspotStateReceiver.Callback
|
||||
import org.kiwix.kiwixmobile.core.wifi_hotspot.IpAddressCallbacks
|
||||
import org.kiwix.kiwixmobile.di.ServiceScope
|
||||
import org.kiwix.kiwixmobile.webserver.WebServerHelper
|
||||
import org.kiwix.kiwixmobile.webserver.wifi_hotspot.HotspotNotificationManager
|
||||
import org.kiwix.kiwixmobile.webserver.wifi_hotspot.HotspotStateReceiver
|
||||
import org.kiwix.kiwixmobile.webserver.wifi_hotspot.HotspotStateReceiver.Callback
|
||||
import org.kiwix.kiwixmobile.webserver.wifi_hotspot.IpAddressCallbacks
|
||||
|
||||
@Module
|
||||
class ServiceModule {
|
||||
@ -41,12 +41,7 @@ class ServiceModule {
|
||||
jniKiwixLibrary: JNIKiwixLibrary,
|
||||
kiwixServer: JNIKiwixServer,
|
||||
ipAddressCallbacks: IpAddressCallbacks
|
||||
): WebServerHelper =
|
||||
WebServerHelper(
|
||||
jniKiwixLibrary,
|
||||
kiwixServer,
|
||||
ipAddressCallbacks
|
||||
)
|
||||
): WebServerHelper = WebServerHelper(jniKiwixLibrary, kiwixServer, ipAddressCallbacks)
|
||||
|
||||
@Provides
|
||||
@ServiceScope
|
||||
@ -67,19 +62,15 @@ class ServiceModule {
|
||||
fun providesHotspotNotificationManager(
|
||||
notificationManager: NotificationManager,
|
||||
context: Context
|
||||
): HotspotNotificationManager =
|
||||
HotspotNotificationManager(notificationManager, context)
|
||||
): HotspotNotificationManager = HotspotNotificationManager(notificationManager, context)
|
||||
|
||||
@Provides
|
||||
@ServiceScope
|
||||
fun providesHotspotStateReceiver(
|
||||
callback: Callback
|
||||
): HotspotStateReceiver =
|
||||
fun providesHotspotStateReceiver(callback: Callback): HotspotStateReceiver =
|
||||
HotspotStateReceiver(callback)
|
||||
|
||||
@Provides
|
||||
@ServiceScope
|
||||
fun providesHotspotStateReceiverCallback(
|
||||
service: Service
|
||||
): HotspotStateReceiver.Callback = service as Callback
|
||||
fun providesHotspotStateReceiverCallback(service: Service): HotspotStateReceiver.Callback =
|
||||
service as Callback
|
||||
}
|
@ -25,7 +25,7 @@ import dagger.Module
|
||||
import dagger.multibindings.IntoMap
|
||||
import org.kiwix.kiwixmobile.KiwixViewModelFactory
|
||||
import org.kiwix.kiwixmobile.language.viewmodel.LanguageViewModel
|
||||
import org.kiwix.kiwixmobile.di.ViewModelKey
|
||||
import org.kiwix.kiwixmobile.core.di.ViewModelKey
|
||||
import org.kiwix.kiwixmobile.zim_manager.ZimManageViewModel
|
||||
|
||||
@Module
|
||||
|
@ -42,6 +42,7 @@ import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil.PREF_KIWIX_MOBILE
|
||||
import org.kiwix.kiwixmobile.core.utils.UpdateUtils.reformatProviderUrl
|
||||
import org.kiwix.kiwixmobile.core.utils.files.FileUtils
|
||||
import org.kiwix.kiwixmobile.kiwixActivityComponent
|
||||
import org.kiwix.kiwixmobile.webserver.ZimHostActivity
|
||||
import org.kiwix.kiwixmobile.zim_manager.ZimManageActivity
|
||||
import java.io.File
|
||||
|
||||
@ -168,4 +169,8 @@ class KiwixMainActivity : CoreMainActivity() {
|
||||
openZimFile(intent.data.toFile())
|
||||
}
|
||||
}
|
||||
|
||||
override fun onHostBooksMenuClicked() {
|
||||
start<ZimHostActivity>()
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package org.kiwix.kiwixmobile.core.webserver;
|
||||
package org.kiwix.kiwixmobile.webserver;
|
||||
|
||||
import android.util.Log;
|
||||
import androidx.annotation.NonNull;
|
||||
@ -29,7 +29,7 @@ import org.kiwix.kiwixlib.JNIKiwixException;
|
||||
import org.kiwix.kiwixlib.JNIKiwixLibrary;
|
||||
import org.kiwix.kiwixlib.JNIKiwixServer;
|
||||
import org.kiwix.kiwixmobile.core.utils.ServerUtils;
|
||||
import org.kiwix.kiwixmobile.core.wifi_hotspot.IpAddressCallbacks;
|
||||
import org.kiwix.kiwixmobile.webserver.wifi_hotspot.IpAddressCallbacks;
|
||||
|
||||
import static org.kiwix.kiwixmobile.core.utils.ServerUtils.INVALID_IP;
|
||||
|
@ -0,0 +1,295 @@
|
||||
/*
|
||||
* Kiwix Android
|
||||
* Copyright (c) 2019 Kiwix <android.kiwix.org>
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.kiwix.kiwixmobile.webserver
|
||||
|
||||
import android.app.ProgressDialog
|
||||
import android.content.ComponentName
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.ServiceConnection
|
||||
import android.os.Bundle
|
||||
import android.os.IBinder
|
||||
import android.util.Log
|
||||
import android.widget.Button
|
||||
import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import org.kiwix.kiwixmobile.R
|
||||
import org.kiwix.kiwixmobile.core.BuildConfig
|
||||
import org.kiwix.kiwixmobile.core.base.BaseActivity
|
||||
import org.kiwix.kiwixmobile.core.extensions.toast
|
||||
import org.kiwix.kiwixmobile.core.utils.AlertDialogShower
|
||||
import org.kiwix.kiwixmobile.core.utils.KiwixDialog
|
||||
import org.kiwix.kiwixmobile.core.utils.ServerUtils
|
||||
import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.SelectionMode
|
||||
import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.adapter.BookOnDiskDelegate
|
||||
import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.adapter.BooksOnDiskAdapter
|
||||
import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.adapter.BooksOnDiskListItem
|
||||
import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.adapter.BooksOnDiskListItem.BookOnDisk
|
||||
import org.kiwix.kiwixmobile.kiwixActivityComponent
|
||||
import org.kiwix.kiwixmobile.webserver.wifi_hotspot.HotspotService
|
||||
import org.kiwix.kiwixmobile.webserver.wifi_hotspot.HotspotService.ACTION_CHECK_IP_ADDRESS
|
||||
import org.kiwix.kiwixmobile.webserver.wifi_hotspot.HotspotService.ACTION_START_SERVER
|
||||
import org.kiwix.kiwixmobile.webserver.wifi_hotspot.HotspotService.ACTION_STOP_SERVER
|
||||
import java.util.ArrayList
|
||||
import javax.inject.Inject
|
||||
|
||||
class ZimHostActivity : BaseActivity(), ZimHostCallbacks, ZimHostContract.View {
|
||||
@Inject
|
||||
internal lateinit var presenter: ZimHostContract.Presenter
|
||||
@Inject
|
||||
internal lateinit var alertDialogShower: AlertDialogShower
|
||||
private lateinit var recyclerViewZimHost: RecyclerView
|
||||
private lateinit var toolbar: Toolbar
|
||||
private lateinit var startServerButton: Button
|
||||
private lateinit var serverTextView: TextView
|
||||
private lateinit var booksAdapter: BooksOnDiskAdapter
|
||||
private lateinit var bookDelegate: BookOnDiskDelegate.BookDelegate
|
||||
private var hotspotService: HotspotService? = null
|
||||
private var ip: String? = null
|
||||
private var serviceConnection: ServiceConnection? = null
|
||||
private var progressDialog: ProgressDialog? = null
|
||||
private val tag = "ZimHostActivity"
|
||||
private val ipStateKey = "ip_state_key"
|
||||
|
||||
private val selectedBooksPath: ArrayList<String>
|
||||
get() {
|
||||
return booksAdapter.items
|
||||
.filter(BooksOnDiskListItem::isSelected)
|
||||
.filterIsInstance<BookOnDisk>()
|
||||
.map {
|
||||
it.file.absolutePath
|
||||
}
|
||||
.also {
|
||||
if (BuildConfig.DEBUG) {
|
||||
it.forEach { path ->
|
||||
Log.v(tag, "ZIM PATH : $path")
|
||||
}
|
||||
}
|
||||
}
|
||||
as ArrayList<String>
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_zim_host)
|
||||
recyclerViewZimHost = findViewById(R.id.recyclerViewZimHost)
|
||||
toolbar = findViewById(R.id.toolbar)
|
||||
startServerButton = findViewById(R.id.startServerButton)
|
||||
serverTextView = findViewById(R.id.serverTextView)
|
||||
setUpToolbar()
|
||||
|
||||
bookDelegate =
|
||||
BookOnDiskDelegate.BookDelegate(sharedPreferenceUtil, multiSelectAction = ::select)
|
||||
bookDelegate.selectionMode = SelectionMode.MULTI
|
||||
booksAdapter = BooksOnDiskAdapter(
|
||||
bookDelegate,
|
||||
BookOnDiskDelegate.LanguageDelegate
|
||||
)
|
||||
if (savedInstanceState != null) {
|
||||
ip = savedInstanceState.getString(ipStateKey)
|
||||
layoutServerStarted()
|
||||
}
|
||||
recyclerViewZimHost.adapter = booksAdapter
|
||||
presenter.attachView(this)
|
||||
|
||||
serviceConnection = object : ServiceConnection {
|
||||
|
||||
override fun onServiceConnected(className: ComponentName, service: IBinder) {
|
||||
hotspotService = (service as HotspotService.HotspotBinder).service
|
||||
hotspotService!!.registerCallBack(this@ZimHostActivity)
|
||||
}
|
||||
|
||||
override fun onServiceDisconnected(arg0: ComponentName) {}
|
||||
}
|
||||
|
||||
startServerButton.setOnClickListener { startStopServer() }
|
||||
}
|
||||
|
||||
override fun injection() {
|
||||
kiwixActivityComponent.inject(this)
|
||||
}
|
||||
|
||||
private fun startStopServer() {
|
||||
when {
|
||||
ServerUtils.isServerStarted -> stopServer()
|
||||
selectedBooksPath.size > 0 -> startHotspotManuallyDialog()
|
||||
else -> toast(R.string.no_books_selected_toast_message, Toast.LENGTH_SHORT)
|
||||
}
|
||||
}
|
||||
|
||||
private fun stopServer() {
|
||||
startService(createHotspotIntent(ACTION_STOP_SERVER))
|
||||
}
|
||||
|
||||
private fun select(bookOnDisk: BooksOnDiskListItem.BookOnDisk) {
|
||||
val booksList: List<BooksOnDiskListItem> = booksAdapter.items.map {
|
||||
if (it == bookOnDisk) {
|
||||
it.isSelected = !it.isSelected
|
||||
}
|
||||
it
|
||||
}
|
||||
booksAdapter.items = booksList
|
||||
saveHostedBooks(booksList)
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
bindService()
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
unbindService()
|
||||
}
|
||||
|
||||
private fun bindService() {
|
||||
bindService(
|
||||
Intent(this, HotspotService::class.java), serviceConnection,
|
||||
Context.BIND_AUTO_CREATE
|
||||
)
|
||||
}
|
||||
|
||||
private fun unbindService() {
|
||||
hotspotService?.let {
|
||||
unbindService(serviceConnection)
|
||||
it.registerCallBack(null)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
presenter.loadBooks(sharedPreferenceUtil.hostedBooks)
|
||||
if (ServerUtils.isServerStarted) {
|
||||
ip = ServerUtils.getSocketAddress()
|
||||
layoutServerStarted()
|
||||
}
|
||||
}
|
||||
|
||||
private fun saveHostedBooks(booksList: List<BooksOnDiskListItem>) {
|
||||
sharedPreferenceUtil.hostedBooks = booksList.asSequence()
|
||||
.filter(BooksOnDiskListItem::isSelected)
|
||||
.filterIsInstance<BookOnDisk>()
|
||||
.mapNotNull { it.book.title }
|
||||
.toSet()
|
||||
}
|
||||
|
||||
private fun layoutServerStarted() {
|
||||
serverTextView.text = getString(R.string.server_started_message, ip)
|
||||
startServerButton.text = getString(R.string.stop_server_label)
|
||||
startServerButton.setBackgroundColor(resources.getColor(R.color.stopServer))
|
||||
bookDelegate.selectionMode = SelectionMode.NORMAL
|
||||
booksAdapter.notifyDataSetChanged()
|
||||
}
|
||||
|
||||
private fun layoutServerStopped() {
|
||||
serverTextView.text = getString(R.string.server_textview_default_message)
|
||||
startServerButton.text = getString(R.string.start_server_label)
|
||||
startServerButton.setBackgroundColor(resources.getColor(R.color.greenTick))
|
||||
bookDelegate.selectionMode = SelectionMode.MULTI
|
||||
booksAdapter.notifyDataSetChanged()
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
presenter.detachView()
|
||||
}
|
||||
|
||||
private fun setUpToolbar() {
|
||||
setSupportActionBar(toolbar)
|
||||
supportActionBar!!.title = getString(R.string.menu_host_books)
|
||||
supportActionBar!!.setHomeButtonEnabled(true)
|
||||
supportActionBar!!.setDisplayHomeAsUpEnabled(true)
|
||||
|
||||
toolbar.setNavigationOnClickListener { onBackPressed() }
|
||||
}
|
||||
|
||||
// Advice user to turn on hotspot manually for API<26
|
||||
private fun startHotspotManuallyDialog() {
|
||||
|
||||
alertDialogShower.show(KiwixDialog.StartHotspotManually(),
|
||||
::launchTetheringSettingsScreen,
|
||||
{},
|
||||
{
|
||||
progressDialog = ProgressDialog.show(
|
||||
this,
|
||||
getString(R.string.progress_dialog_starting_server), "",
|
||||
true
|
||||
)
|
||||
startService(createHotspotIntent(ACTION_CHECK_IP_ADDRESS))
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
private fun createHotspotIntent(action: String): Intent =
|
||||
Intent(this, HotspotService::class.java).setAction(action)
|
||||
|
||||
override fun onServerStarted(ip: String) {
|
||||
this.ip = ip
|
||||
layoutServerStarted()
|
||||
}
|
||||
|
||||
override fun onServerStopped() {
|
||||
layoutServerStopped()
|
||||
}
|
||||
|
||||
override fun onServerFailedToStart() {
|
||||
toast(R.string.server_failed_toast_message)
|
||||
}
|
||||
|
||||
private fun launchTetheringSettingsScreen() {
|
||||
startActivity(
|
||||
Intent(Intent.ACTION_MAIN, null).apply {
|
||||
addCategory(Intent.CATEGORY_LAUNCHER)
|
||||
component = ComponentName("com.android.settings", "com.android.settings.TetherSettings")
|
||||
flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
if (ServerUtils.isServerStarted) {
|
||||
outState!!.putString(ipStateKey, ip)
|
||||
}
|
||||
}
|
||||
|
||||
override fun addBooks(books: List<BooksOnDiskListItem>) {
|
||||
booksAdapter.items = books
|
||||
}
|
||||
|
||||
override fun onIpAddressValid() {
|
||||
progressDialog!!.dismiss()
|
||||
startService(
|
||||
createHotspotIntent(ACTION_START_SERVER).putStringArrayListExtra(
|
||||
SELECTED_ZIM_PATHS_KEY, selectedBooksPath
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
override fun onIpAddressInvalid() {
|
||||
progressDialog!!.dismiss()
|
||||
toast(R.string.server_failed_message, Toast.LENGTH_SHORT)
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val SELECTED_ZIM_PATHS_KEY = "selected_zim_paths"
|
||||
}
|
||||
}
|
@ -15,20 +15,12 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package org.kiwix.kiwixmobile.webserver
|
||||
|
||||
package org.kiwix.kiwixmobile.core.webserver;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
public interface ZimHostCallbacks {
|
||||
|
||||
void onServerStarted(@NonNull String ip);
|
||||
|
||||
void onServerStopped();
|
||||
|
||||
void onServerFailedToStart();
|
||||
|
||||
void onIpAddressValid();
|
||||
|
||||
void onIpAddressInvalid();
|
||||
interface ZimHostCallbacks {
|
||||
fun onServerStarted(ip: String)
|
||||
fun onServerStopped()
|
||||
fun onServerFailedToStart()
|
||||
fun onIpAddressValid()
|
||||
fun onIpAddressInvalid()
|
||||
}
|
@ -15,22 +15,17 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package org.kiwix.kiwixmobile.webserver
|
||||
|
||||
package org.kiwix.kiwixmobile.core.webserver;
|
||||
|
||||
import java.util.List;
|
||||
import org.kiwix.kiwixmobile.core.base.BaseContract;
|
||||
import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.adapter.BooksOnDiskListItem;
|
||||
import org.kiwix.kiwixmobile.core.base.BaseContract
|
||||
import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.adapter.BooksOnDiskListItem
|
||||
|
||||
class ZimHostContract {
|
||||
|
||||
interface View
|
||||
extends BaseContract.View<ZimHostContract.Presenter> {
|
||||
void addBooks(List<BooksOnDiskListItem> books);
|
||||
interface View : BaseContract.View<Presenter> {
|
||||
fun addBooks(books: List<BooksOnDiskListItem>)
|
||||
}
|
||||
|
||||
interface Presenter
|
||||
extends BaseContract.Presenter<ZimHostContract.View> {
|
||||
void loadBooks();
|
||||
interface Presenter : BaseContract.Presenter<View> {
|
||||
fun loadBooks(previouslyHostedBooks: Set<String>)
|
||||
}
|
||||
}
|
@ -15,26 +15,14 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package org.kiwix.kiwixmobile.webserver
|
||||
|
||||
package org.kiwix.kiwixmobile.core.webserver;
|
||||
|
||||
import android.app.Activity;
|
||||
import dagger.Module;
|
||||
import dagger.Provides;
|
||||
import org.kiwix.kiwixmobile.core.di.ActivityScope;
|
||||
import dagger.Binds
|
||||
import dagger.Module
|
||||
import org.kiwix.kiwixmobile.core.di.ActivityScope
|
||||
|
||||
@Module
|
||||
public class ZimHostModule {
|
||||
|
||||
@ActivityScope
|
||||
@Provides
|
||||
ZimHostContract.Presenter provideZimHostPresenter(ZimHostPresenter zimHostPresenter) {
|
||||
return zimHostPresenter;
|
||||
}
|
||||
|
||||
@ActivityScope
|
||||
@Provides Activity providesActivity(ZimHostActivity zimHostActivity) {
|
||||
return zimHostActivity;
|
||||
}
|
||||
abstract class ZimHostModule {
|
||||
@ActivityScope @Binds
|
||||
abstract fun bindsZimHostPresenter(zimHostPresenter: ZimHostPresenter): ZimHostContract.Presenter
|
||||
}
|
||||
|
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Kiwix Android
|
||||
* Copyright (c) 2019 Kiwix <android.kiwix.org>
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package org.kiwix.kiwixmobile.webserver
|
||||
|
||||
import android.util.Log
|
||||
import io.reactivex.SingleObserver
|
||||
import io.reactivex.disposables.Disposable
|
||||
import org.kiwix.kiwixmobile.core.base.BasePresenter
|
||||
import org.kiwix.kiwixmobile.core.data.DataSource
|
||||
import org.kiwix.kiwixmobile.core.di.ActivityScope
|
||||
import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.adapter.BooksOnDiskListItem
|
||||
import org.kiwix.kiwixmobile.webserver.ZimHostContract.Presenter
|
||||
import org.kiwix.kiwixmobile.webserver.ZimHostContract.View
|
||||
import javax.inject.Inject
|
||||
|
||||
@ActivityScope
|
||||
class ZimHostPresenter @Inject internal constructor(private val dataSource: DataSource) :
|
||||
BasePresenter<View>(),
|
||||
Presenter {
|
||||
|
||||
override fun loadBooks(previouslyHostedBooks: Set<String>) {
|
||||
dataSource.languageCategorizedBooks
|
||||
.map { books ->
|
||||
books
|
||||
.filterIsInstance<BooksOnDiskListItem.BookOnDisk>()
|
||||
.forEach {
|
||||
it.isSelected = (
|
||||
previouslyHostedBooks.contains(it.book.title) || previouslyHostedBooks.isEmpty()
|
||||
)
|
||||
}
|
||||
books
|
||||
}
|
||||
.subscribe(object : SingleObserver<List<BooksOnDiskListItem>> {
|
||||
override fun onSubscribe(d: Disposable) {
|
||||
compositeDisposable.add(d)
|
||||
}
|
||||
|
||||
override fun onSuccess(books: List<BooksOnDiskListItem>) {
|
||||
view!!.addBooks(books)
|
||||
}
|
||||
|
||||
override fun onError(e: Throwable) {
|
||||
Log.e(TAG, "Unable to load books", e)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val TAG = "ZimHostPresenter"
|
||||
}
|
||||
}
|
@ -16,7 +16,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package org.kiwix.kiwixmobile.core.wifi_hotspot;
|
||||
package org.kiwix.kiwixmobile.webserver.wifi_hotspot;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationChannel;
|
||||
@ -30,7 +30,7 @@ import androidx.core.app.NotificationCompat;
|
||||
import javax.inject.Inject;
|
||||
import org.kiwix.kiwixmobile.core.R;
|
||||
import org.kiwix.kiwixmobile.core.utils.Constants;
|
||||
import org.kiwix.kiwixmobile.core.webserver.ZimHostActivity;
|
||||
import org.kiwix.kiwixmobile.webserver.ZimHostActivity;
|
||||
|
||||
public class HotspotNotificationManager {
|
||||
|
@ -16,7 +16,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package org.kiwix.kiwixmobile.core.wifi_hotspot;
|
||||
package org.kiwix.kiwixmobile.webserver.wifi_hotspot;
|
||||
|
||||
import android.app.Service;
|
||||
import android.content.Intent;
|
||||
@ -26,15 +26,15 @@ import android.widget.Toast;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
import org.kiwix.kiwixmobile.core.CoreApp;
|
||||
import org.kiwix.kiwixmobile.KiwixApp;
|
||||
import org.kiwix.kiwixmobile.core.R;
|
||||
import org.kiwix.kiwixmobile.core.extensions.ContextExtensionsKt;
|
||||
import org.kiwix.kiwixmobile.core.utils.ServerUtils;
|
||||
import org.kiwix.kiwixmobile.core.webserver.WebServerHelper;
|
||||
import org.kiwix.kiwixmobile.core.webserver.ZimHostCallbacks;
|
||||
import org.kiwix.kiwixmobile.webserver.WebServerHelper;
|
||||
import org.kiwix.kiwixmobile.webserver.ZimHostCallbacks;
|
||||
|
||||
import static org.kiwix.kiwixmobile.core.webserver.ZimHostActivity.SELECTED_ZIM_PATHS_KEY;
|
||||
import static org.kiwix.kiwixmobile.core.wifi_hotspot.HotspotNotificationManager.HOTSPOT_NOTIFICATION_ID;
|
||||
import static org.kiwix.kiwixmobile.webserver.ZimHostActivity.SELECTED_ZIM_PATHS_KEY;
|
||||
import static org.kiwix.kiwixmobile.webserver.wifi_hotspot.HotspotNotificationManager.HOTSPOT_NOTIFICATION_ID;
|
||||
|
||||
/**
|
||||
* HotspotService is used to add a foreground service for the wifi hotspot.
|
||||
@ -59,7 +59,7 @@ public class HotspotService extends Service
|
||||
HotspotStateReceiver hotspotStateReceiver;
|
||||
|
||||
@Override public void onCreate() {
|
||||
CoreApp.getCoreComponent()
|
||||
((KiwixApp) this.getApplicationContext()).getKiwixComponent()
|
||||
.serviceComponent()
|
||||
.service(this)
|
||||
.build()
|
@ -15,12 +15,12 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package org.kiwix.kiwixmobile.core.wifi_hotspot
|
||||
package org.kiwix.kiwixmobile.webserver.wifi_hotspot
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import org.kiwix.kiwixmobile.core.wifi_hotspot.HotspotStateReceiver.HotspotState.DISABLED
|
||||
import org.kiwix.kiwixmobile.core.base.BaseBroadcastReceiver
|
||||
import org.kiwix.kiwixmobile.webserver.wifi_hotspot.HotspotStateReceiver.HotspotState.DISABLED
|
||||
import javax.inject.Inject
|
||||
|
||||
const val EXTRA_WIFI_AP_STATE = "wifi_state"
|
||||
@ -32,7 +32,8 @@ const val WIFI_AP_STATE_ENABLING = 12
|
||||
const val WIFI_AP_STATE_ENABLED = 13
|
||||
const val WIFI_AP_STATE_FAILED = 14
|
||||
|
||||
class HotspotStateReceiver @Inject constructor(val callback: Callback) : BaseBroadcastReceiver() {
|
||||
class HotspotStateReceiver @Inject constructor(private val callback: Callback) :
|
||||
BaseBroadcastReceiver() {
|
||||
override val action: String = ACTION_WIFI_AP_STATE
|
||||
|
||||
override fun onIntentWithActionReceived(context: Context, intent: Intent) {
|
@ -16,7 +16,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package org.kiwix.kiwixmobile.core.wifi_hotspot;
|
||||
package org.kiwix.kiwixmobile.webserver.wifi_hotspot;
|
||||
|
||||
public interface IpAddressCallbacks {
|
||||
|
@ -10,7 +10,7 @@
|
||||
<include layout="@layout/layout_standard_app_bar" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/server_textView"
|
||||
android:id="@+id/serverTextView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
@ -21,7 +21,7 @@
|
||||
app:layout_constraintTop_toBottomOf="@+id/app_bar" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recycler_view_zim_host"
|
||||
android:id="@+id/recyclerViewZimHost"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginTop="16dp"
|
||||
@ -30,7 +30,7 @@
|
||||
app:layout_constraintBottom_toTopOf="@+id/startServerButton"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/server_textView" />
|
||||
app:layout_constraintTop_toBottomOf="@+id/serverTextView" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/startServerButton"
|
@ -8,8 +8,6 @@
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
||||
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
|
||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
||||
|
||||
<!-- Device with versions >= Pie need this permission -->
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||
@ -27,7 +25,6 @@
|
||||
|
||||
<activity android:name=".search.SearchActivity" />
|
||||
<activity android:name=".bookmark.BookmarksActivity" />
|
||||
<activity android:name=".webserver.ZimHostActivity" />
|
||||
|
||||
<provider
|
||||
android:name=".reader.ZimContentProvider"
|
||||
@ -48,7 +45,6 @@
|
||||
android:resource="@xml/kiwix_widget_provider_info" />
|
||||
</receiver>
|
||||
|
||||
<service android:name=".wifi_hotspot.HotspotService" />
|
||||
|
||||
<activity
|
||||
android:name=".error.ErrorActivity"
|
||||
|
@ -16,7 +16,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package org.kiwix.kiwixmobile.di
|
||||
package org.kiwix.kiwixmobile.core.di
|
||||
|
||||
import androidx.lifecycle.ViewModel
|
||||
import dagger.MapKey
|
@ -18,12 +18,14 @@
|
||||
package org.kiwix.kiwixmobile.core.di.components
|
||||
|
||||
import android.app.Application
|
||||
import android.app.NotificationManager
|
||||
import android.content.Context
|
||||
import android.net.ConnectivityManager
|
||||
import dagger.BindsInstance
|
||||
import dagger.Component
|
||||
import eu.mhutti1.utils.storage.StorageSelectDialog
|
||||
import org.kiwix.kiwixmobile.core.CoreApp
|
||||
import org.kiwix.kiwixmobile.core.StorageObserver
|
||||
import org.kiwix.kiwixmobile.core.dao.FetchDownloadDao
|
||||
import org.kiwix.kiwixmobile.core.dao.NewBookDao
|
||||
import org.kiwix.kiwixmobile.core.dao.NewLanguagesDao
|
||||
@ -43,7 +45,6 @@ import org.kiwix.kiwixmobile.core.search.AutoCompleteAdapter
|
||||
import org.kiwix.kiwixmobile.core.settings.CorePrefsFragment
|
||||
import org.kiwix.kiwixmobile.core.utils.BookUtils
|
||||
import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil
|
||||
import org.kiwix.kiwixmobile.core.StorageObserver
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Singleton
|
||||
@ -64,7 +65,6 @@ interface CoreComponent {
|
||||
fun build(): CoreComponent
|
||||
}
|
||||
|
||||
fun serviceComponent(): ServiceComponent.Builder
|
||||
fun zimReaderContainer(): ZimReaderContainer
|
||||
fun sharedPrefUtil(): SharedPreferenceUtil
|
||||
fun zimFileReaderFactory(): ZimFileReader.Factory
|
||||
@ -79,6 +79,7 @@ interface CoreComponent {
|
||||
fun connectivityManager(): ConnectivityManager
|
||||
fun context(): Context
|
||||
fun downloader(): Downloader
|
||||
fun notificationManager(): NotificationManager
|
||||
|
||||
fun inject(application: CoreApp)
|
||||
fun inject(zimContentProvider: ZimContentProvider)
|
||||
|
@ -28,9 +28,6 @@ import org.kiwix.kiwixmobile.core.help.HelpActivity;
|
||||
import org.kiwix.kiwixmobile.core.history.HistoryActivity;
|
||||
import org.kiwix.kiwixmobile.core.history.HistoryModule;
|
||||
import org.kiwix.kiwixmobile.core.search.SearchActivity;
|
||||
import org.kiwix.kiwixmobile.core.splash.CoreSplashActivity;
|
||||
import org.kiwix.kiwixmobile.core.webserver.ZimHostActivity;
|
||||
import org.kiwix.kiwixmobile.core.webserver.ZimHostModule;
|
||||
|
||||
/**
|
||||
* Dagger.Android annotation processor will create the sub-components. We also specify the modules
|
||||
@ -60,8 +57,4 @@ public abstract class ActivityBindingModule {
|
||||
@ActivityScope
|
||||
@ContributesAndroidInjector
|
||||
public abstract HelpActivity provideHelpActivity();
|
||||
|
||||
@ActivityScope
|
||||
@ContributesAndroidInjector(modules = ZimHostModule.class)
|
||||
public abstract ZimHostActivity provideZimHostActivity();
|
||||
}
|
||||
|
@ -885,6 +885,10 @@ public abstract class CoreMainActivity extends BaseActivity
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void onHostBooksMenuClicked() {
|
||||
// to be implemented in subclasses
|
||||
}
|
||||
|
||||
protected abstract void createNewTab();
|
||||
|
||||
/** Creates the full screen AddNoteDialog, which is a DialogFragment */
|
||||
@ -1132,8 +1136,8 @@ public abstract class CoreMainActivity extends BaseActivity
|
||||
tabsAdapter.notifyDataSetChanged();
|
||||
openHomeScreen();
|
||||
}
|
||||
|
||||
//opens home screen when user closes all tabs
|
||||
|
||||
private void openHomeScreen() {
|
||||
new Handler().postDelayed(() -> {
|
||||
if (webViewList.size() == 0) {
|
||||
|
@ -33,7 +33,6 @@ import org.kiwix.kiwixmobile.core.search.SearchActivity
|
||||
import org.kiwix.kiwixmobile.core.settings.CoreSettingsActivity
|
||||
import org.kiwix.kiwixmobile.core.utils.Constants
|
||||
import org.kiwix.kiwixmobile.core.utils.Constants.EXTRA_ZIM_FILE
|
||||
import org.kiwix.kiwixmobile.core.webserver.ZimHostActivity
|
||||
|
||||
const val REQUEST_FILE_SEARCH = 1236
|
||||
|
||||
@ -65,6 +64,7 @@ class MainMenu(
|
||||
fun onReadAloudMenuClicked()
|
||||
fun onFullscreenMenuClicked()
|
||||
fun onSupportKiwixMenuClicked()
|
||||
fun onHostBooksMenuClicked()
|
||||
}
|
||||
|
||||
init {
|
||||
@ -108,7 +108,7 @@ class MainMenu(
|
||||
Constants.REQUEST_HISTORY_ITEM_CHOSEN
|
||||
)
|
||||
}
|
||||
hostBooks.menuItemClickListener { activity.start<ZimHostActivity>() }
|
||||
hostBooks.menuItemClickListener { menuClickListener.onHostBooksMenuClicked() }
|
||||
addNote.menuItemClickListener { menuClickListener.onAddNoteMenuClicked() }
|
||||
bookmarks.menuItemClickListener { menuClickListener.onBookmarksMenuClicked() }
|
||||
randomArticle.menuItemClickListener { menuClickListener.onRandomArticleMenuClicked() }
|
||||
|
@ -20,6 +20,6 @@ package org.kiwix.kiwixmobile.core.utils
|
||||
interface DialogShower {
|
||||
fun show(
|
||||
dialog: KiwixDialog,
|
||||
vararg clickListeners: () -> Unit
|
||||
vararg clickListeners: (() -> Unit)
|
||||
)
|
||||
}
|
||||
|
@ -26,6 +26,8 @@ import androidx.appcompat.app.AppCompatDelegate;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import io.reactivex.Flowable;
|
||||
import io.reactivex.processors.PublishProcessor;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import org.kiwix.kiwixmobile.core.CoreApp;
|
||||
@ -42,18 +44,19 @@ public class SharedPreferenceUtil {
|
||||
public static final String PREF_STORAGE = "pref_select_folder";
|
||||
public static final String PREF_WIFI_ONLY = "pref_wifi_only";
|
||||
public static final String PREF_KIWIX_MOBILE = "kiwix-mobile";
|
||||
public static final String PREF_BACK_TO_TOP = "pref_backtotop";
|
||||
public static final String PREF_HIDE_TOOLBAR = "pref_hidetoolbar";
|
||||
public static final String PREF_ZOOM = "pref_zoom_slider";
|
||||
public static final String PREF_ZOOM_ENABLED = "pref_zoom_enabled";
|
||||
public static final String PREF_FULLSCREEN = "pref_fullscreen";
|
||||
public static final String PREF_NEW_TAB_BACKGROUND = "pref_newtab_background";
|
||||
public static final String PREF_STORAGE_TITLE = "pref_selected_title";
|
||||
public static final String PREF_EXTERNAL_LINK_POPUP = "pref_external_link_popup";
|
||||
public static final String PREF_IS_FIRST_RUN = "isFirstRun";
|
||||
public static final String PREF_SHOW_INTRO = "showIntro";
|
||||
private static final String PREF_BACK_TO_TOP = "pref_backtotop";
|
||||
private static final String PREF_HIDE_TOOLBAR = "pref_hidetoolbar";
|
||||
private static final String PREF_FULLSCREEN = "pref_fullscreen";
|
||||
private static final String PREF_NEW_TAB_BACKGROUND = "pref_newtab_background";
|
||||
private static final String PREF_STORAGE_TITLE = "pref_selected_title";
|
||||
private static final String PREF_EXTERNAL_LINK_POPUP = "pref_external_link_popup";
|
||||
private static final String PREF_IS_FIRST_RUN = "isFirstRun";
|
||||
private static final String PREF_SHOW_BOOKMARKS_CURRENT_BOOK = "show_bookmarks_current_book";
|
||||
private static final String PREF_SHOW_HISTORY_CURRENT_BOOK = "show_history_current_book";
|
||||
private static final String PREF_HOSTED_BOOKS = "hosted_books";
|
||||
public static final String PREF_NIGHT_MODE = "pref_night_mode";
|
||||
private SharedPreferences sharedPreferences;
|
||||
private final PublishProcessor<String> prefStorages = PublishProcessor.create();
|
||||
@ -203,4 +206,14 @@ public class SharedPreferenceUtil {
|
||||
public void updateNightMode() {
|
||||
nightModes.offer(getNightMode());
|
||||
}
|
||||
|
||||
public Set<String> getHostedBooks() {
|
||||
return sharedPreferences.getStringSet(PREF_HOSTED_BOOKS, new HashSet<>());
|
||||
}
|
||||
|
||||
public void setHostedBooks(Set<String> hostedBooks) {
|
||||
sharedPreferences.edit()
|
||||
.putStringSet(PREF_HOSTED_BOOKS, hostedBooks)
|
||||
.apply();
|
||||
}
|
||||
}
|
||||
|
@ -1,308 +0,0 @@
|
||||
/*
|
||||
* Kiwix Android
|
||||
* Copyright (c) 2019 Kiwix <android.kiwix.org>
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.kiwix.kiwixmobile.core.webserver;
|
||||
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.ServiceConnection;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.util.Log;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import butterknife.BindView;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.inject.Inject;
|
||||
import kotlin.Unit;
|
||||
import org.kiwix.kiwixmobile.core.R;
|
||||
import org.kiwix.kiwixmobile.core.R2;
|
||||
import org.kiwix.kiwixmobile.core.base.BaseActivity;
|
||||
import org.kiwix.kiwixmobile.core.utils.AlertDialogShower;
|
||||
import org.kiwix.kiwixmobile.core.utils.KiwixDialog;
|
||||
import org.kiwix.kiwixmobile.core.utils.ServerUtils;
|
||||
import org.kiwix.kiwixmobile.core.wifi_hotspot.HotspotService;
|
||||
import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.SelectionMode;
|
||||
import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.adapter.BookOnDiskDelegate;
|
||||
import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.adapter.BooksOnDiskAdapter;
|
||||
import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.adapter.BooksOnDiskListItem;
|
||||
|
||||
import static org.kiwix.kiwixmobile.core.wifi_hotspot.HotspotService.ACTION_CHECK_IP_ADDRESS;
|
||||
import static org.kiwix.kiwixmobile.core.wifi_hotspot.HotspotService.ACTION_START_SERVER;
|
||||
import static org.kiwix.kiwixmobile.core.wifi_hotspot.HotspotService.ACTION_STOP_SERVER;
|
||||
|
||||
public class ZimHostActivity extends BaseActivity implements
|
||||
ZimHostCallbacks, ZimHostContract.View {
|
||||
|
||||
@BindView(R2.id.startServerButton)
|
||||
Button startServerButton;
|
||||
@BindView(R2.id.server_textView)
|
||||
TextView serverTextView;
|
||||
@BindView(R2.id.recycler_view_zim_host)
|
||||
RecyclerView recyclerViewZimHost;
|
||||
|
||||
@Inject
|
||||
ZimHostContract.Presenter presenter;
|
||||
|
||||
@Inject
|
||||
AlertDialogShower alertDialogShower;
|
||||
|
||||
private static final String TAG = "ZimHostActivity";
|
||||
private static final String IP_STATE_KEY = "ip_state_key";
|
||||
public static final String SELECTED_ZIM_PATHS_KEY = "selected_zim_paths";
|
||||
|
||||
private BooksOnDiskAdapter booksAdapter;
|
||||
private BookOnDiskDelegate.BookDelegate bookDelegate;
|
||||
private HotspotService hotspotService;
|
||||
private String ip;
|
||||
private ServiceConnection serviceConnection;
|
||||
private ProgressDialog progressDialog;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_zim_host);
|
||||
|
||||
setUpToolbar();
|
||||
|
||||
bookDelegate =
|
||||
new BookOnDiskDelegate.BookDelegate(sharedPreferenceUtil,
|
||||
null,
|
||||
null,
|
||||
bookOnDiskItem -> {
|
||||
select(bookOnDiskItem);
|
||||
return Unit.INSTANCE;
|
||||
});
|
||||
bookDelegate.setSelectionMode(SelectionMode.MULTI);
|
||||
booksAdapter = new BooksOnDiskAdapter(bookDelegate,
|
||||
BookOnDiskDelegate.LanguageDelegate.INSTANCE
|
||||
);
|
||||
if (savedInstanceState != null) {
|
||||
ip = savedInstanceState.getString(IP_STATE_KEY);
|
||||
layoutServerStarted();
|
||||
}
|
||||
recyclerViewZimHost.setAdapter(booksAdapter);
|
||||
presenter.attachView(this);
|
||||
|
||||
presenter.loadBooks();
|
||||
|
||||
serviceConnection = new ServiceConnection() {
|
||||
|
||||
@Override
|
||||
public void onServiceConnected(ComponentName className, IBinder service) {
|
||||
hotspotService = ((HotspotService.HotspotBinder) service).getService();
|
||||
hotspotService.registerCallBack(ZimHostActivity.this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceDisconnected(ComponentName arg0) {
|
||||
}
|
||||
};
|
||||
|
||||
startServerButton.setOnClickListener(v -> {
|
||||
//Get the path of ZIMs user has selected
|
||||
if (!ServerUtils.isServerStarted) {
|
||||
if (getSelectedBooksPath().size() > 0) {
|
||||
startHotspotHelper();
|
||||
} else {
|
||||
Toast.makeText(ZimHostActivity.this, R.string.no_books_selected_toast_message,
|
||||
Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
} else {
|
||||
startHotspotHelper();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void startHotspotHelper() {
|
||||
if (ServerUtils.isServerStarted) {
|
||||
startService(createHotspotIntent(ACTION_STOP_SERVER));
|
||||
} else {
|
||||
startHotspotManuallyDialog();
|
||||
}
|
||||
}
|
||||
|
||||
private ArrayList<String> getSelectedBooksPath() {
|
||||
ArrayList<String> selectedBooksPath = new ArrayList<>();
|
||||
for (BooksOnDiskListItem item : booksAdapter.getItems()) {
|
||||
if (item.isSelected()) {
|
||||
BooksOnDiskListItem.BookOnDisk bookOnDisk = (BooksOnDiskListItem.BookOnDisk) item;
|
||||
File file = bookOnDisk.getFile();
|
||||
selectedBooksPath.add(file.getAbsolutePath());
|
||||
Log.v(TAG, "ZIM PATH : " + file.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
return selectedBooksPath;
|
||||
}
|
||||
|
||||
private void select(@NonNull BooksOnDiskListItem.BookOnDisk bookOnDisk) {
|
||||
ArrayList<BooksOnDiskListItem> booksList = new ArrayList<>();
|
||||
for (BooksOnDiskListItem item : booksAdapter.getItems()) {
|
||||
if (item.equals(bookOnDisk)) {
|
||||
item.setSelected(!item.isSelected());
|
||||
}
|
||||
booksList.add(item);
|
||||
}
|
||||
booksAdapter.setItems(booksList);
|
||||
}
|
||||
|
||||
@Override protected void onStart() {
|
||||
super.onStart();
|
||||
bindService();
|
||||
}
|
||||
|
||||
@Override protected void onStop() {
|
||||
super.onStop();
|
||||
unbindService();
|
||||
}
|
||||
|
||||
private void bindService() {
|
||||
bindService(new Intent(this, HotspotService.class), serviceConnection,
|
||||
Context.BIND_AUTO_CREATE);
|
||||
}
|
||||
|
||||
private void unbindService() {
|
||||
if (hotspotService != null) {
|
||||
unbindService(serviceConnection);
|
||||
hotspotService.registerCallBack(null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override protected void onResume() {
|
||||
super.onResume();
|
||||
presenter.loadBooks();
|
||||
if (ServerUtils.isServerStarted) {
|
||||
ip = ServerUtils.getSocketAddress();
|
||||
layoutServerStarted();
|
||||
}
|
||||
}
|
||||
|
||||
private void layoutServerStarted() {
|
||||
serverTextView.setText(getString(R.string.server_started_message, ip));
|
||||
startServerButton.setText(getString(R.string.stop_server_label));
|
||||
startServerButton.setBackgroundColor(getResources().getColor(R.color.stopServer));
|
||||
bookDelegate.setSelectionMode(SelectionMode.NORMAL);
|
||||
for (BooksOnDiskListItem item : booksAdapter.getItems()) {
|
||||
item.setSelected(false);
|
||||
}
|
||||
booksAdapter.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
private void layoutServerStopped() {
|
||||
serverTextView.setText(getString(R.string.server_textview_default_message));
|
||||
startServerButton.setText(getString(R.string.start_server_label));
|
||||
startServerButton.setBackgroundColor(getResources().getColor(R.color.greenTick));
|
||||
bookDelegate.setSelectionMode(SelectionMode.MULTI);
|
||||
booksAdapter.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
presenter.detachView();
|
||||
}
|
||||
|
||||
private void setUpToolbar() {
|
||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||
setSupportActionBar(toolbar);
|
||||
getSupportActionBar().setTitle(getString(R.string.menu_host_books));
|
||||
getSupportActionBar().setHomeButtonEnabled(true);
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
|
||||
toolbar.setNavigationOnClickListener(v -> onBackPressed());
|
||||
}
|
||||
|
||||
//Advice user to turn on hotspot manually for API<26
|
||||
private void startHotspotManuallyDialog() {
|
||||
|
||||
alertDialogShower.show(new KiwixDialog.StartHotspotManually(),
|
||||
() -> {
|
||||
launchTetheringSettingsScreen();
|
||||
return Unit.INSTANCE;
|
||||
},
|
||||
null,
|
||||
() -> {
|
||||
progressDialog =
|
||||
ProgressDialog.show(this,
|
||||
getString(R.string.progress_dialog_starting_server), "",
|
||||
true);
|
||||
startService(createHotspotIntent(ACTION_CHECK_IP_ADDRESS));
|
||||
return Unit.INSTANCE;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
private Intent createHotspotIntent(String action) {
|
||||
return new Intent(this, HotspotService.class).setAction(action);
|
||||
}
|
||||
|
||||
@Override public void onServerStarted(@NonNull String ipAddress) {
|
||||
this.ip = ipAddress;
|
||||
layoutServerStarted();
|
||||
}
|
||||
|
||||
@Override public void onServerStopped() {
|
||||
layoutServerStopped();
|
||||
}
|
||||
|
||||
@Override public void onServerFailedToStart() {
|
||||
Toast.makeText(this, R.string.server_failed_toast_message, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
private void launchTetheringSettingsScreen() {
|
||||
final Intent intent = new Intent(Intent.ACTION_MAIN, null);
|
||||
intent.addCategory(Intent.CATEGORY_LAUNCHER);
|
||||
final ComponentName cn =
|
||||
new ComponentName("com.android.settings", "com.android.settings.TetherSettings");
|
||||
intent.setComponent(cn);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
startActivity(intent);
|
||||
}
|
||||
|
||||
@Override protected void onSaveInstanceState(@Nullable Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
if (ServerUtils.isServerStarted) {
|
||||
outState.putString(IP_STATE_KEY, ip);
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void addBooks(@Nullable List<BooksOnDiskListItem> books) {
|
||||
booksAdapter.setItems(books);
|
||||
}
|
||||
|
||||
@Override public void onIpAddressValid() {
|
||||
progressDialog.dismiss();
|
||||
startService(createHotspotIntent(ACTION_START_SERVER).putStringArrayListExtra(
|
||||
SELECTED_ZIM_PATHS_KEY, getSelectedBooksPath()));
|
||||
}
|
||||
|
||||
@Override public void onIpAddressInvalid() {
|
||||
progressDialog.dismiss();
|
||||
Toast.makeText(this, R.string.server_failed_message,
|
||||
Toast.LENGTH_SHORT)
|
||||
.show();
|
||||
}
|
||||
}
|
@ -1,62 +0,0 @@
|
||||
/*
|
||||
* Kiwix Android
|
||||
* Copyright (c) 2019 Kiwix <android.kiwix.org>
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.kiwix.kiwixmobile.core.webserver;
|
||||
|
||||
import android.util.Log;
|
||||
import io.reactivex.SingleObserver;
|
||||
import io.reactivex.disposables.Disposable;
|
||||
import java.util.List;
|
||||
import javax.inject.Inject;
|
||||
import org.kiwix.kiwixmobile.core.base.BasePresenter;
|
||||
import org.kiwix.kiwixmobile.core.data.DataSource;
|
||||
import org.kiwix.kiwixmobile.core.di.ActivityScope;
|
||||
import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.adapter.BooksOnDiskListItem;
|
||||
|
||||
@ActivityScope
|
||||
class ZimHostPresenter extends BasePresenter<ZimHostContract.View>
|
||||
implements ZimHostContract.Presenter {
|
||||
|
||||
private static final String TAG = "ZimHostPresenter";
|
||||
private final DataSource dataSource;
|
||||
|
||||
@Inject ZimHostPresenter(DataSource dataSource) {
|
||||
this.dataSource = dataSource;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadBooks() {
|
||||
dataSource.getLanguageCategorizedBooks()
|
||||
.subscribe(new SingleObserver<List<BooksOnDiskListItem>>() {
|
||||
@Override
|
||||
public void onSubscribe(Disposable d) {
|
||||
compositeDisposable.add(d);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(List<BooksOnDiskListItem> books) {
|
||||
view.addBooks(books);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Throwable e) {
|
||||
Log.e(TAG, "Unable to load books", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -25,7 +25,7 @@ import dagger.Module
|
||||
import dagger.multibindings.IntoMap
|
||||
import org.kiwix.kiwixmobile.custom.CustomViewModelFactory
|
||||
import org.kiwix.kiwixmobile.custom.download.CustomDownloadViewModel
|
||||
import org.kiwix.kiwixmobile.di.ViewModelKey
|
||||
import org.kiwix.kiwixmobile.core.di.ViewModelKey
|
||||
|
||||
@Module
|
||||
abstract class CustomViewModelModule {
|
||||
|
@ -74,6 +74,7 @@ class CustomMainActivity : CoreMainActivity() {
|
||||
val onCreateOptionsMenu = super.onCreateOptionsMenu(menu)
|
||||
menu?.findItem(R.id.menu_help)?.isVisible = false
|
||||
menu?.findItem(R.id.menu_openfile)?.isVisible = false
|
||||
menu?.findItem(R.id.menu_host_books)?.isVisible = false
|
||||
return onCreateOptionsMenu
|
||||
}
|
||||
|
||||
@ -94,6 +95,6 @@ class CustomMainActivity : CoreMainActivity() {
|
||||
}
|
||||
|
||||
override fun manageZimFiles(tab: Int) {
|
||||
TODO("not implemented")
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user