Search manga
This commit is contained in:
@@ -10,8 +10,6 @@ abstract class BaseMangaRepository(protected val loaderContext: MangaLoaderConte
|
||||
|
||||
override val sortOrders: Set<SortOrder> get() = emptySet()
|
||||
|
||||
override val isSearchAvailable get() = true
|
||||
|
||||
override suspend fun getPageFullUrl(page: MangaPage) : String = page.url
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> = emptySet()
|
||||
|
||||
@@ -6,8 +6,6 @@ interface MangaRepository {
|
||||
|
||||
val sortOrders: Set<SortOrder>
|
||||
|
||||
val isSearchAvailable: Boolean
|
||||
|
||||
suspend fun getList(offset: Int, query: String? = null, sortOrder: SortOrder? = null, tag: MangaTag? = null): List<Manga>
|
||||
|
||||
suspend fun getDetails(manga: Manga) : Manga
|
||||
|
||||
@@ -25,13 +25,11 @@ abstract class GroupleRepository(
|
||||
sortOrder: SortOrder?,
|
||||
tag: MangaTag?
|
||||
): List<Manga> {
|
||||
val url = if (tag == null) {
|
||||
"https://$domain/list?sortType=${getSortKey(sortOrder)}&offset=$offset"
|
||||
} else {
|
||||
"https://$domain/list/genre/${tag.key}?sortType=${getSortKey(sortOrder)}&offset=$offset"
|
||||
}
|
||||
val doc = loaderContext.get(url)
|
||||
.parseHtml()
|
||||
val doc = when {
|
||||
!query.isNullOrEmpty() -> loaderContext.post("https://$domain/search", mapOf("q" to query))
|
||||
tag == null -> loaderContext.get("https://$domain/list?sortType=${getSortKey(sortOrder)}&offset=$offset")
|
||||
else -> loaderContext.get( "https://$domain/list/genre/${tag.key}?sortType=${getSortKey(sortOrder)}&offset=$offset")
|
||||
}.parseHtml()
|
||||
val root = doc.body().getElementById("mangaBox")
|
||||
?.selectFirst("div.tiles.row") ?: throw ParseException("Cannot find root")
|
||||
return root.select("div.tile").mapNotNull { node ->
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
package org.koitharu.kotatsu.domain
|
||||
|
||||
import org.koin.core.KoinComponent
|
||||
import org.koin.core.get
|
||||
import org.koin.core.inject
|
||||
import org.koitharu.kotatsu.core.model.MangaSource
|
||||
import org.koitharu.kotatsu.core.parser.MangaRepository
|
||||
|
||||
object MangaProviderFactory : KoinComponent {
|
||||
|
||||
private val loaderContext get() = get<MangaLoaderContext>()
|
||||
private val loaderContext by inject<MangaLoaderContext>()
|
||||
|
||||
fun create(source: MangaSource): MangaRepository {
|
||||
val constructor = source.cls.getConstructor(MangaLoaderContext::class.java)
|
||||
|
||||
@@ -57,7 +57,6 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
return drawerToggle.onOptionsItemSelected(item) || when(item.itemId) {
|
||||
|
||||
else -> super.onOptionsItemSelected(item)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
package org.koitharu.kotatsu.ui.search
|
||||
|
||||
import android.app.SearchManager
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.ui.common.BaseActivity
|
||||
|
||||
class SearchActivity : BaseActivity() {
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_search)
|
||||
val query = if (Intent.ACTION_SEARCH == intent.action) {
|
||||
intent.getStringExtra(SearchManager.QUERY)?.trim()
|
||||
} else {
|
||||
null
|
||||
}
|
||||
if (query == null) {
|
||||
finish()
|
||||
return
|
||||
}
|
||||
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
||||
title = query
|
||||
supportActionBar?.setSubtitle(R.string.search_results)
|
||||
supportFragmentManager
|
||||
.beginTransaction()
|
||||
.replace(R.id.container, SearchFragment.newInstance(query))
|
||||
.commit()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package org.koitharu.kotatsu.ui.search
|
||||
|
||||
import moxy.ktx.moxyPresenter
|
||||
import org.koitharu.kotatsu.ui.main.list.MangaListFragment
|
||||
import org.koitharu.kotatsu.utils.ext.withArgs
|
||||
|
||||
class SearchFragment : MangaListFragment<Unit>() {
|
||||
|
||||
private val presenter by moxyPresenter(factory = ::SearchPresenter)
|
||||
|
||||
private val query by stringArg(ARG_QUERY)
|
||||
|
||||
override fun onRequestMoreItems(offset: Int) {
|
||||
presenter.loadList(query.orEmpty(), offset)
|
||||
}
|
||||
|
||||
override fun getTitle(): CharSequence? {
|
||||
return query
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private const val ARG_QUERY = "query"
|
||||
|
||||
fun newInstance(query: String) = SearchFragment().withArgs(1) {
|
||||
putString(ARG_QUERY, query)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package org.koitharu.kotatsu.ui.search
|
||||
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import moxy.InjectViewState
|
||||
import org.koitharu.kotatsu.BuildConfig
|
||||
import org.koitharu.kotatsu.core.model.MangaSource
|
||||
import org.koitharu.kotatsu.domain.MangaProviderFactory
|
||||
import org.koitharu.kotatsu.ui.common.BasePresenter
|
||||
import org.koitharu.kotatsu.ui.main.list.MangaListView
|
||||
|
||||
@InjectViewState
|
||||
class SearchPresenter : BasePresenter<MangaListView<Unit>>() {
|
||||
|
||||
private lateinit var sources: Array<MangaSource>
|
||||
|
||||
override fun onFirstViewAttach() {
|
||||
sources = MangaSource.values()
|
||||
super.onFirstViewAttach()
|
||||
}
|
||||
|
||||
fun loadList(query: String, offset: Int) {
|
||||
launch {
|
||||
viewState.onLoadingChanged(true)
|
||||
try {
|
||||
//TODO select source
|
||||
val list = withContext(Dispatchers.IO) {
|
||||
MangaProviderFactory.create(MangaSource.READMANGA_RU)
|
||||
.getList(offset, query = query)
|
||||
}
|
||||
if (offset == 0) {
|
||||
viewState.onListChanged(list)
|
||||
} else {
|
||||
viewState.onListAppended(list)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
if (BuildConfig.DEBUG) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
viewState.onError(e)
|
||||
} finally {
|
||||
viewState.onLoadingChanged(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,20 @@
|
||||
package org.koitharu.kotatsu.utils
|
||||
|
||||
import android.app.SearchManager
|
||||
import android.content.ComponentName
|
||||
import android.content.Context
|
||||
import android.view.MenuItem
|
||||
import androidx.appcompat.widget.SearchView
|
||||
import org.koitharu.kotatsu.ui.search.SearchActivity
|
||||
|
||||
object SearchHelper {
|
||||
|
||||
@JvmStatic
|
||||
fun setupSearchView(menuItem: MenuItem) {
|
||||
val view = menuItem.actionView as? SearchView ?: return
|
||||
//TODO
|
||||
val context = view.context
|
||||
val searchManager = context.applicationContext.getSystemService(Context.SEARCH_SERVICE) as SearchManager
|
||||
val info = searchManager.getSearchableInfo(ComponentName(context, SearchActivity::class.java))
|
||||
view.setSearchableInfo(info)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user