mirror of
https://github.com/kiwix/kiwix-android.git
synced 2025-09-30 16:43:38 -04:00
#1990 rewrite of HistoryActivity WORK IN PROGRESS
This commit is contained in:
parent
faa8e272a4
commit
de88dd6c55
@ -0,0 +1,108 @@
|
||||
package org.kiwix.kiwixmobile.core.history
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.Menu
|
||||
import android.widget.ImageView
|
||||
import androidx.appcompat.widget.SearchView
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
import kotlinx.android.synthetic.main.activity_history.recycler_view
|
||||
import org.kiwix.kiwixmobile.core.R
|
||||
import org.kiwix.kiwixmobile.core.R.id
|
||||
import org.kiwix.kiwixmobile.core.R.string
|
||||
import org.kiwix.kiwixmobile.core.base.BaseActivity
|
||||
import org.kiwix.kiwixmobile.core.di.components.CoreComponent
|
||||
import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.coreActivityComponent
|
||||
import org.kiwix.kiwixmobile.core.history.HistoryAdapter.OnItemClickListener
|
||||
import org.kiwix.kiwixmobile.core.history.HistoryDelegate.HistoryItemDelegate
|
||||
import org.kiwix.kiwixmobile.core.history.HistoryListItem.HistoryItem
|
||||
import org.kiwix.kiwixmobile.core.history.ViewModel.HistoryViewModel
|
||||
import org.kiwix.kiwixmobile.core.search.adapter.SearchListItem
|
||||
import org.kiwix.kiwixmobile.core.search.viewmodel.Action.OnItemClick
|
||||
import org.kiwix.kiwixmobile.core.search.viewmodel.State
|
||||
import org.kiwix.kiwixmobile.core.utils.SimpleTextListener
|
||||
import java.util.ArrayList
|
||||
import javax.inject.Inject
|
||||
|
||||
class HistoryActivity : OnItemClickListener, BaseActivity(){
|
||||
|
||||
val activityComponent by lazy { coreActivityComponent }
|
||||
private val historyList: List<HistoryListItem> = ArrayList()
|
||||
private val fullHistory: List<HistoryListItem> = ArrayList()
|
||||
private val deleteList: List<HistoryListItem> = ArrayList()
|
||||
@Inject lateinit var viewModelFactory: ViewModelProvider.Factory
|
||||
private val recyclerView: RecyclerView = recycler_view
|
||||
private val historyViewModel by lazy { viewMdel<HistoryViewModel>(viewModelFactory) }
|
||||
private val compositeDisposable = CompositeDisposable()
|
||||
private val historyAdapter: HistoryAdapter2 by lazy {
|
||||
HistoryAdapter2(
|
||||
HistoryItemDelegate(deleteList,this){
|
||||
historyViewModel.actions.offer(OnItemLongClick(it))
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
override fun injection(coreComponent: CoreComponent) {
|
||||
coreComponent.activityComponentBuilder()
|
||||
.activity(this)
|
||||
.build()
|
||||
.inject(this)
|
||||
activityComponent.inject(this);
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_history)
|
||||
setSupportActionBar(toolbar)
|
||||
val actionBar = supportActionBar
|
||||
if (actionBar != null) {
|
||||
actionBar.setDisplayHomeAsUpEnabled(true)
|
||||
actionBar.setTitle(string.history)
|
||||
}
|
||||
recyclerView.run{
|
||||
adapter = historyAdapter
|
||||
layoutManager = LinearLayoutManager(context, RecyclerView.VERTICAL, false);
|
||||
setHasFixedSize(true)
|
||||
}
|
||||
compositeDisposable.add(historyViewModel.effects.subcribe{ it.invokeWith(this) })
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
compositeDisposable.clear()
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||
menuInflater.inflate(R.menu.menu_history, menu)
|
||||
val search = menu.findItem(id.menu_history_search).actionView as SearchView
|
||||
search.queryHint = getString(string.search_history)
|
||||
search.setOnQueryTextListener(SimpleTextListener{historyViewModel.actions.offer(Filter(it))})
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
private fun render(state: State) {
|
||||
|
||||
}
|
||||
|
||||
private fun onItemClick(it: SearchListItem) {
|
||||
searchViewModel.actions.offer(OnItemClick(it))
|
||||
}
|
||||
|
||||
override fun onItemClick(
|
||||
favicon: ImageView,
|
||||
history: HistoryItem
|
||||
) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun onItemLongClick(
|
||||
favicon: ImageView,
|
||||
history: HistoryItem
|
||||
): Boolean {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
package org.kiwix.kiwixmobile.core.history
|
||||
|
||||
import org.kiwix.kiwixmobile.core.base.adapter.AdapterDelegate
|
||||
import org.kiwix.kiwixmobile.core.base.adapter.BaseDelegateAdapter
|
||||
|
||||
class HistoryAdapter2(
|
||||
vararg delegates: AdapterDelegate<HistoryListItem>
|
||||
) : BaseDelegateAdapter<HistoryListItem>(*delegates){
|
||||
override fun getIdFor(item: HistoryListItem): Long = item.id
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package org.kiwix.kiwixmobile.core.history
|
||||
|
||||
import android.content.DialogInterface.OnClickListener
|
||||
import android.view.ViewGroup
|
||||
import org.kiwix.kiwixmobile.core.base.adapter.AbsDelegateAdapter
|
||||
import org.kiwix.kiwixmobile.core.extensions.ViewGroupExtensions.inflate
|
||||
import org.kiwix.kiwixmobile.core.history.HistoryAdapter.OnItemClickListener
|
||||
import org.kiwix.kiwixmobile.core.history.HistoryListItem.HistoryItem
|
||||
|
||||
sealed class HistoryDelegate<I : HistoryListItem, out VH : HistoryItemViewHolder2<I>> :
|
||||
AbsDelegateAdapter<I, HistoryListItem, VH> {
|
||||
|
||||
class HistoryItemDelegate(
|
||||
private val deleteList: List<HistoryListItem>,
|
||||
private val itemClickListener: OnItemClickListener
|
||||
) : HistoryDelegate<HistoryItem, HistoryItemViewHolder2.HistoryItemViewHolder>(){
|
||||
override val itemClass = HistoryItem::class.java
|
||||
|
||||
override fun createViewHolder(parent: ViewGroup) = HistoryItemViewHolder2.HistoryItemViewHolder(parent.inflate(android.R.layout.simple_selectable_list_item, false),
|
||||
deleteList, itemClickListener)
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package org.kiwix.kiwixmobile.core.history
|
||||
|
||||
import android.view.View
|
||||
import kotlinx.android.synthetic.main.item_bookmark_history.favicon
|
||||
import kotlinx.android.synthetic.main.item_bookmark_history.title
|
||||
import org.kiwix.kiwixmobile.core.R
|
||||
import org.kiwix.kiwixmobile.core.base.adapter.BaseViewHolder
|
||||
import org.kiwix.kiwixmobile.core.downloader.model.Base64String
|
||||
import org.kiwix.kiwixmobile.core.extensions.setBitmap
|
||||
import org.kiwix.kiwixmobile.core.extensions.setImageDrawableCompat
|
||||
import org.kiwix.kiwixmobile.core.history.HistoryAdapter.OnItemClickListener
|
||||
import org.kiwix.kiwixmobile.core.history.HistoryListItem.HistoryItem
|
||||
import org.kiwix.kiwixmobile.core.search.adapter.SearchListItem
|
||||
|
||||
sealed class HistoryItemViewHolder2 <in T : HistoryListItem>(containerView: View):
|
||||
BaseViewHolder<T>(containerView){
|
||||
|
||||
class HistoryItemViewHolder(
|
||||
override val containerView: View,
|
||||
private val deleteList: List<HistoryListItem>,
|
||||
private val itemClickListener: OnItemClickListener
|
||||
) : HistoryItemViewHolder2<HistoryItem>(containerView){
|
||||
override fun bind(item: HistoryItem) {
|
||||
title.text = item.historyTitle
|
||||
if (deleteList.contains(item)) {
|
||||
favicon.setImageDrawableCompat(R.drawable.ic_check_circle_blue_24dp)
|
||||
} else {
|
||||
favicon.setBitmap(Base64String(item.favicon))
|
||||
}
|
||||
itemView.setOnClickListener { itemClickListener.onItemClick(favicon, item) }
|
||||
itemView.setOnLongClickListener { itemClickListener.onItemLongClick(favicon, item) }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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.history.ViewModel
|
||||
|
||||
import android.content.Intent
|
||||
import org.kiwix.kiwixmobile.core.history.HistoryListItem
|
||||
import org.kiwix.kiwixmobile.core.search.adapter.SearchListItem
|
||||
|
||||
sealed class Action {
|
||||
object ExitedSearch : Action()
|
||||
object ClickedSearchInText : Action()
|
||||
object ReceivedPromptForSpeechInput : Action()
|
||||
object StartSpeechInputFailed : Action()
|
||||
|
||||
data class OnItemClick(val historyListItem: HistoryListItem) : Action()
|
||||
data class OnItemLongClick(val historyListItem: HistoryListItem) : Action()
|
||||
data class Filter(val term: String) : Action()
|
||||
data class ConfirmedDelete(val historyListItem: HistoryListItem) : Action()
|
||||
data class CreatedWithIntent(val intent: Intent?) : Action()
|
||||
data class ActivityResultReceived(val requestCode: Int, val resultCode: Int, val data: Intent?) :
|
||||
Action()
|
||||
}
|
@ -0,0 +1,113 @@
|
||||
package org.kiwix.kiwixmobile.core.history.ViewModel
|
||||
|
||||
import Finish
|
||||
import ProcessActivityResult
|
||||
import SearchIntentProcessing
|
||||
import ShowToast
|
||||
import StartSpeechInput
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
import io.reactivex.processors.BehaviorProcessor
|
||||
import io.reactivex.processors.PublishProcessor
|
||||
import org.kiwix.kiwixmobile.core.R
|
||||
import org.kiwix.kiwixmobile.core.base.SideEffect
|
||||
import org.kiwix.kiwixmobile.core.history.ViewModel.Action.ActivityResultReceived
|
||||
import org.kiwix.kiwixmobile.core.history.ViewModel.Action.ClickedSearchInText
|
||||
import org.kiwix.kiwixmobile.core.history.ViewModel.Action.ConfirmedDelete
|
||||
import org.kiwix.kiwixmobile.core.history.ViewModel.Action.CreatedWithIntent
|
||||
import org.kiwix.kiwixmobile.core.history.ViewModel.Action.ExitedSearch
|
||||
import org.kiwix.kiwixmobile.core.history.ViewModel.Action.Filter
|
||||
import org.kiwix.kiwixmobile.core.history.ViewModel.Action.OnItemClick
|
||||
import org.kiwix.kiwixmobile.core.history.ViewModel.Action.OnItemLongClick
|
||||
import org.kiwix.kiwixmobile.core.history.ViewModel.Action.ReceivedPromptForSpeechInput
|
||||
import org.kiwix.kiwixmobile.core.history.ViewModel.Action.StartSpeechInputFailed
|
||||
import org.kiwix.kiwixmobile.core.history.ViewModel.State.NoResults
|
||||
import javax.inject.Inject
|
||||
|
||||
class HistoryViewModel @Inject constructor() : ViewModel(){
|
||||
val state = MutableLiveData<State>().apply{ value = NoResults("")}
|
||||
val effects = PublishProcessor.create<SideEffect<*>>()
|
||||
val actions = PublishProcessor.create<Action>()
|
||||
private val filter = BehaviorProcessor.createDefault("")
|
||||
private val compositeDisposable = CompositeDisposable()
|
||||
|
||||
init {
|
||||
compositeDisposable.addAll(viwStateRduce(),actionMapper())
|
||||
}
|
||||
|
||||
override fun onCleared() {
|
||||
compositeDisposable.clear()
|
||||
super.onCleared()
|
||||
}
|
||||
|
||||
private fun actionMapper() = actions.map {
|
||||
when (it) {
|
||||
ExitedSearch -> effects.offer(Finish)
|
||||
is OnItemClick -> saveSearchAndOpenItem(it)
|
||||
is OnItemLongClick -> showDeleteDialog(it)
|
||||
is Filter -> filter.offer(it.term)
|
||||
ClickedSearchInText -> searchPreviousScreenWhenStateIsValid()
|
||||
is ConfirmedDelete -> deleteItemAndShowToast(it)
|
||||
is CreatedWithIntent -> effects.offer(SearchIntentProcessing(it.intent, actions))
|
||||
ReceivedPromptForSpeechInput -> effects.offer(StartSpeechInput(actions))
|
||||
StartSpeechInputFailed -> effects.offer(ShowToast(R.string.speech_not_supported))
|
||||
is ActivityResultReceived ->
|
||||
effects.offer(ProcessActivityResult(it.requestCode, it.resultCode, it.data, actions))
|
||||
}
|
||||
}.subscribe(
|
||||
{},
|
||||
Throwable::printStackTrace
|
||||
)
|
||||
|
||||
private fun deleteItemAndShowToast(it: ConfirmedDelete) {
|
||||
effects.offer(DeleteRecentSearch(it.searchListItem, recentSearchDao))
|
||||
effects.offer(ShowToast(R.string.delete_specific_search_toast))
|
||||
}
|
||||
|
||||
private fun searchPreviousScreenWhenStateIsValid(): Any =
|
||||
effects.offer(SearchInPreviousScreen(state.value!!.searchString))
|
||||
|
||||
private fun showDeleteDialog(longClick: OnItemLongClick) {
|
||||
effects.offer(ShowDeleteSearchDialog(longClick.searchListItem, actions))
|
||||
}
|
||||
|
||||
private fun saveSearchAndOpenItem(it: OnItemClick) {
|
||||
effects.offer(
|
||||
SaveSearchToRecents(recentSearchDao, it.searchListItem, zimReaderContainer.id)
|
||||
)
|
||||
effects.offer(
|
||||
OpenSearchItem(it.searchListItem)
|
||||
)
|
||||
}
|
||||
|
||||
private fun viewStateReducer() =
|
||||
Flowable.combineLatest(
|
||||
recentSearchDao.recentSearches(zimReaderContainer.id),
|
||||
searchResultsFromZimReader(),
|
||||
filter,
|
||||
searchOrigin,
|
||||
Function4(this::reduce)
|
||||
).subscribe(state::postValue, Throwable::printStackTrace)
|
||||
|
||||
private fun reduce(
|
||||
recentSearchResults: List<SearchListItem>,
|
||||
zimSearchResults: List<SearchListItem>,
|
||||
searchString: String,
|
||||
searchOrigin: SearchOrigin
|
||||
) = when {
|
||||
searchString.isNotEmpty() && zimSearchResults.isNotEmpty() ->
|
||||
Results(searchString, zimSearchResults, searchOrigin)
|
||||
searchString.isEmpty() && recentSearchResults.isNotEmpty() ->
|
||||
Results(searchString, recentSearchResults, searchOrigin)
|
||||
else -> NoResults(searchString, searchOrigin)
|
||||
}
|
||||
|
||||
private fun searchResultsFromZimReader() = filter
|
||||
.distinctUntilChanged()
|
||||
.switchMap(::searchResults)
|
||||
|
||||
private fun searchResults(it: String) = Flowable.fromCallable {
|
||||
searchResultGenerator.generateSearchResults(it)
|
||||
}.subscribeOn(Schedulers.io())
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* 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.history.ViewModel
|
||||
|
||||
import org.kiwix.kiwixmobile.core.history.HistoryListItem
|
||||
import org.kiwix.kiwixmobile.core.search.adapter.SearchListItem
|
||||
|
||||
|
||||
|
||||
sealed class State {
|
||||
abstract val searchString: String
|
||||
|
||||
data class Results(
|
||||
override val searchString: String,
|
||||
val selectedItems: List<HistoryListItem>,
|
||||
val viewAllHistoryToggle: Boolean
|
||||
) : State()
|
||||
|
||||
data class NoResults(override val searchString: String) :
|
||||
State()
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import org.kiwix.kiwixmobile.core.base.SideEffect
|
||||
import org.kiwix.kiwixmobile.core.dao.NewRecentSearchDao
|
||||
import org.kiwix.kiwixmobile.core.search.adapter.SearchListItem
|
||||
|
||||
data class DeleteRecentSearch(
|
||||
private val searchListItem: SearchListItem,
|
||||
private val recentSearchDao: NewRecentSearchDao
|
||||
) : SideEffect<Unit> {
|
||||
override fun invokeWith(activity: AppCompatActivity) {
|
||||
recentSearchDao.deleteSearchString(searchListItem.value)
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import org.kiwix.kiwixmobile.core.base.SideEffect
|
||||
|
||||
object Finish : SideEffect<Unit> {
|
||||
override fun invokeWith(activity: AppCompatActivity) {
|
||||
activity.finish()
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import org.kiwix.kiwixmobile.core.base.SideEffect
|
||||
import org.kiwix.kiwixmobile.core.search.adapter.SearchListItem
|
||||
import org.kiwix.kiwixmobile.core.utils.TAG_FILE_SEARCHED
|
||||
|
||||
data class OpenSearchItem(private val searchListItem: SearchListItem) : SideEffect<Unit> {
|
||||
override fun invokeWith(activity: AppCompatActivity) {
|
||||
activity.setResult(
|
||||
Activity.RESULT_OK,
|
||||
Intent().putExtra(TAG_FILE_SEARCHED, searchListItem.value)
|
||||
)
|
||||
activity.finish()
|
||||
}
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.speech.RecognizerIntent
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import io.reactivex.processors.PublishProcessor
|
||||
import org.kiwix.kiwixmobile.core.base.SideEffect
|
||||
import org.kiwix.kiwixmobile.core.search.viewmodel.Action
|
||||
import org.kiwix.kiwixmobile.core.search.viewmodel.Action.Filter
|
||||
|
||||
data class ProcessActivityResult(
|
||||
private val requestCode: Int,
|
||||
private val resultCode: Int,
|
||||
private val data: Intent?,
|
||||
private val actions: PublishProcessor<Action>
|
||||
) : SideEffect<Unit> {
|
||||
override fun invokeWith(activity: AppCompatActivity) {
|
||||
if (requestCode == StartSpeechInput.REQ_CODE_SPEECH_INPUT &&
|
||||
resultCode == Activity.RESULT_OK &&
|
||||
data != null
|
||||
) {
|
||||
actions.offer(Filter(data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS)[0]))
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import org.kiwix.kiwixmobile.core.base.SideEffect
|
||||
import org.kiwix.kiwixmobile.core.dao.NewRecentSearchDao
|
||||
import org.kiwix.kiwixmobile.core.search.adapter.SearchListItem
|
||||
|
||||
data class SaveSearchToRecents(
|
||||
private val recentSearchDao: NewRecentSearchDao,
|
||||
private val searchListItem: SearchListItem,
|
||||
private val id: String?
|
||||
) : SideEffect<Unit> {
|
||||
override fun invokeWith(activity: AppCompatActivity) {
|
||||
id?.let { recentSearchDao.saveSearch(searchListItem.value, it) }
|
||||
}
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import org.kiwix.kiwixmobile.core.base.SideEffect
|
||||
import org.kiwix.kiwixmobile.core.utils.TAG_FILE_SEARCHED
|
||||
|
||||
data class SearchInPreviousScreen(private val searchString: String) : SideEffect<Unit> {
|
||||
override fun invokeWith(activity: AppCompatActivity) {
|
||||
activity.setResult(
|
||||
Activity.RESULT_OK,
|
||||
Intent().apply {
|
||||
putExtra(EXTRA_SEARCH_IN_TEXT, true)
|
||||
putExtra(TAG_FILE_SEARCHED, searchString)
|
||||
}
|
||||
)
|
||||
activity.finish()
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val EXTRA_SEARCH_IN_TEXT = "bool_searchintext"
|
||||
}
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
import android.annotation.TargetApi
|
||||
import android.content.Intent
|
||||
import android.os.Build.VERSION_CODES
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import io.reactivex.processors.PublishProcessor
|
||||
import org.kiwix.kiwixmobile.core.base.SideEffect
|
||||
import org.kiwix.kiwixmobile.core.search.viewmodel.Action
|
||||
import org.kiwix.kiwixmobile.core.search.viewmodel.Action.Filter
|
||||
import org.kiwix.kiwixmobile.core.search.viewmodel.Action.ReceivedPromptForSpeechInput
|
||||
import org.kiwix.kiwixmobile.core.search.viewmodel.Action.ScreenWasStartedFrom
|
||||
import org.kiwix.kiwixmobile.core.search.viewmodel.SearchOrigin.FromTabView
|
||||
import org.kiwix.kiwixmobile.core.search.viewmodel.SearchOrigin.FromWebView
|
||||
import org.kiwix.kiwixmobile.core.utils.EXTRA_SEARCH
|
||||
import org.kiwix.kiwixmobile.core.utils.EXTRA_IS_WIDGET_VOICE
|
||||
import org.kiwix.kiwixmobile.core.utils.TAG_FROM_TAB_SWITCHER
|
||||
|
||||
data class SearchIntentProcessing(
|
||||
private val intent: Intent?,
|
||||
private val actions: PublishProcessor<Action>
|
||||
) : SideEffect<Unit> {
|
||||
@TargetApi(VERSION_CODES.M)
|
||||
override fun invokeWith(activity: AppCompatActivity) {
|
||||
intent?.let {
|
||||
actions.offer(
|
||||
ScreenWasStartedFrom(
|
||||
if (it.getBooleanExtra(TAG_FROM_TAB_SWITCHER, false)) FromTabView
|
||||
else FromWebView
|
||||
)
|
||||
)
|
||||
if (it.hasExtra(Intent.EXTRA_PROCESS_TEXT)) {
|
||||
actions.offer(Filter(it.getStringExtra(Intent.EXTRA_PROCESS_TEXT)))
|
||||
}
|
||||
if (intent.hasExtra(EXTRA_SEARCH)) {
|
||||
actions.offer(Filter(intent.getStringExtra(EXTRA_SEARCH)))
|
||||
}
|
||||
if (intent.getBooleanExtra(EXTRA_IS_WIDGET_VOICE, false)) {
|
||||
actions.offer(ReceivedPromptForSpeechInput)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import io.reactivex.processors.PublishProcessor
|
||||
import org.kiwix.kiwixmobile.core.base.SideEffect
|
||||
import org.kiwix.kiwixmobile.core.search.SearchActivity
|
||||
import org.kiwix.kiwixmobile.core.search.adapter.SearchListItem
|
||||
import org.kiwix.kiwixmobile.core.search.viewmodel.Action
|
||||
import org.kiwix.kiwixmobile.core.utils.DialogShower
|
||||
import org.kiwix.kiwixmobile.core.utils.KiwixDialog.DeleteSearch
|
||||
import javax.inject.Inject
|
||||
|
||||
data class ShowDeleteSearchDialog(
|
||||
private val searchListItem: SearchListItem,
|
||||
private val actions: PublishProcessor<Action>
|
||||
) : SideEffect<Unit> {
|
||||
|
||||
@Inject lateinit var dialogShower: DialogShower
|
||||
|
||||
override fun invokeWith(activity: AppCompatActivity) {
|
||||
(activity as SearchActivity).activityComponent.inject(this)
|
||||
dialogShower.show(DeleteSearch, { actions.offer(Action.ConfirmedDelete(searchListItem)) })
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
import android.widget.Toast
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import org.kiwix.kiwixmobile.core.base.SideEffect
|
||||
import org.kiwix.kiwixmobile.core.extensions.toast
|
||||
|
||||
data class ShowToast(@StringRes private val stringId: Int) : SideEffect<Unit> {
|
||||
override fun invokeWith(activity: AppCompatActivity) {
|
||||
activity.toast(stringId, Toast.LENGTH_SHORT)
|
||||
}
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
import android.content.ActivityNotFoundException
|
||||
import android.content.Intent
|
||||
import android.speech.RecognizerIntent
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import io.reactivex.processors.PublishProcessor
|
||||
import org.kiwix.kiwixmobile.core.R
|
||||
import org.kiwix.kiwixmobile.core.base.SideEffect
|
||||
import org.kiwix.kiwixmobile.core.search.viewmodel.Action
|
||||
import org.kiwix.kiwixmobile.core.search.viewmodel.Action.StartSpeechInputFailed
|
||||
import java.util.Locale
|
||||
|
||||
data class StartSpeechInput(private val actions: PublishProcessor<Action>) : SideEffect<Unit> {
|
||||
|
||||
override fun invokeWith(activity: AppCompatActivity) {
|
||||
try {
|
||||
activity.startActivityForResult(
|
||||
Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH).apply {
|
||||
putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM)
|
||||
putExtra(RecognizerIntent.EXTRA_LANGUAGE, Locale.getDefault())
|
||||
putExtra(
|
||||
RecognizerIntent.EXTRA_PROMPT,
|
||||
activity.getString(R.string.speech_prompt_text, activity.getString(R.string.app_name))
|
||||
)
|
||||
},
|
||||
REQ_CODE_SPEECH_INPUT
|
||||
)
|
||||
} catch (a: ActivityNotFoundException) {
|
||||
actions.offer(StartSpeechInputFailed)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val REQ_CODE_SPEECH_INPUT = 100
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user