Merge remote-tracking branch 'origin/master'

# Conflicts:
#	app/src/main/java/io/legado/app/ui/sourcedebug/SourceDebugActivity.kt
pull/32/head
kunfei 5 years ago
commit bc37fb3204
  1. 41
      app/src/main/java/io/legado/app/base/adapter/CommonRecyclerAdapter.kt
  2. 50
      app/src/main/java/io/legado/app/help/EventMessage.kt
  3. 65
      app/src/main/java/io/legado/app/ui/sourcedebug/SourceDebugActivity.kt
  4. 31
      app/src/main/java/io/legado/app/ui/sourcedebug/SourceDebugAdapter.kt
  5. 51
      app/src/main/java/io/legado/app/ui/sourcedebug/SourceDebugModel.kt
  6. 2
      app/src/main/java/io/legado/app/ui/sourceedit/SourceEditActivity.kt

@ -53,11 +53,11 @@ abstract class CommonRecyclerAdapter<ITEM>(protected val context: Context) : Rec
}
fun <DELEGATE : ItemViewDelegate<ITEM>> addItemViewDelegate(viewType: Int, delegate: DELEGATE) {
itemDelegates.put(viewType, delegate)
itemDelegates[viewType] = delegate
}
fun <DELEGATE : ItemViewDelegate<ITEM>> addItemViewDelegate(delegate: DELEGATE) {
itemDelegates.put(itemDelegates.size, delegate)
itemDelegates[itemDelegates.size] = delegate
}
fun <DELEGATE : ItemViewDelegate<ITEM>> addItemViewDelegates(vararg delegates: DELEGATE) {
@ -148,26 +148,15 @@ abstract class CommonRecyclerAdapter<ITEM>(protected val context: Context) : Rec
synchronized(lock) {
val oldSize = getActualItemCount()
if (this.items.add(item)) {
if (oldSize == 0) {
notifyDataSetChanged()
} else {
notifyItemInserted(oldSize + getHeaderCount())
}
}
}
}
fun addItems(position: Int, newItems: List<ITEM>) {
synchronized(lock) {
val oldSize = getActualItemCount()
if (position in 0 until oldSize) {
if (if (oldSize == 0) this.items.addAll(newItems) else this.items.addAll(position, newItems)) {
if (oldSize == 0) {
notifyDataSetChanged()
} else {
notifyItemRangeChanged(position + getHeaderCount(), newItems.size)
}
}
if (this.items.addAll(position, newItems)) {
notifyItemRangeInserted(position + getHeaderCount(), newItems.size)
}
}
}
@ -176,35 +165,34 @@ abstract class CommonRecyclerAdapter<ITEM>(protected val context: Context) : Rec
synchronized(lock) {
val oldSize = getActualItemCount()
if (this.items.addAll(newItems)) {
if (oldSize == 0) {
notifyDataSetChanged()
} else {
notifyItemRangeChanged(oldSize + getHeaderCount(), newItems.size)
}
notifyItemRangeInserted(oldSize + getHeaderCount(), newItems.size)
}
}
}
fun removeItem(position: Int) {
synchronized(lock) {
if (this.items.removeAt(position) != null)
if (this.items.removeAt(position) != null) {
notifyItemRemoved(position + getHeaderCount())
}
}
}
fun removeItem(item: ITEM) {
synchronized(lock) {
if (this.items.remove(item))
if (this.items.remove(item)) {
notifyItemRemoved(this.items.indexOf(item) + getHeaderCount())
}
}
}
fun removeItems(items: List<ITEM>) {
synchronized(lock) {
if (this.items.removeAll(items))
if (this.items.removeAll(items)) {
notifyDataSetChanged()
}
}
}
fun swapItem(oldPosition: Int, newPosition: Int) {
synchronized(lock) {
@ -234,6 +222,13 @@ abstract class CommonRecyclerAdapter<ITEM>(protected val context: Context) : Rec
}
}
fun clearItems() {
synchronized(lock) {
this.items.clear()
notifyDataSetChanged()
}
}
fun isEmpty(): Boolean {
return items.isEmpty()
}

@ -0,0 +1,50 @@
package io.legado.app.help
import android.text.TextUtils
import java.util.Arrays
class EventMessage {
var what: Int?=null
var tag: String? = null
var obj: Any? = null
fun isFrom(tag: String): Boolean {
return TextUtils.equals(this.tag, tag)
}
fun maybeFrom(vararg tags: String): Boolean {
return listOf(*tags).contains(tag)
}
companion object {
fun obtain(tag: String): EventMessage {
val message = EventMessage()
message.tag = tag
return message
}
fun obtain(what: Int): EventMessage {
val message = EventMessage()
message.what = what
return message
}
fun obtain(what: Int, obj: Any): EventMessage {
val message = EventMessage()
message.what = what
message.obj = obj
return message
}
fun obtain(tag: String, obj: Any): EventMessage {
val message = EventMessage()
message.tag = tag
message.obj = obj
return message
}
}
}

@ -3,48 +3,43 @@ package io.legado.app.ui.sourcedebug
import android.os.Bundle
import android.view.View
import androidx.appcompat.widget.SearchView
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.LinearLayoutManager
import io.legado.app.App
import io.legado.app.R
import io.legado.app.base.BaseActivity
import io.legado.app.data.entities.Book
import io.legado.app.data.entities.BookSource
import io.legado.app.lib.theme.ATH
import io.legado.app.lib.theme.ThemeStore
import io.legado.app.model.WebBook
import io.legado.app.model.webbook.SourceDebug
import io.legado.app.utils.getViewModel
import io.legado.app.utils.isAbsUrl
import kotlinx.android.synthetic.main.activity_source_debug.*
import kotlinx.android.synthetic.main.view_title_bar.*
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.launch
import org.jetbrains.anko.toast
class SourceDebugActivity : BaseActivity<AndroidViewModel>(), SourceDebug.Callback {
class SourceDebugActivity : BaseActivity<SourceDebugModel>() {
override val viewModel: AndroidViewModel
get() = getViewModel(AndroidViewModel::class.java)
override val viewModel: SourceDebugModel
get() = getViewModel(SourceDebugModel::class.java)
override val layoutID: Int
get() = R.layout.activity_source_debug
private lateinit var adapter: SourceDebugAdapter
private var bookSource: BookSource? = null
override fun onActivityCreated(viewModel: AndroidViewModel, savedInstanceState: Bundle?) {
launch(IO) {
intent.getStringExtra("key")?.let {
bookSource = App.db.bookSourceDao().findByKey(it)
}
}
override fun onActivityCreated(viewModel: SourceDebugModel, savedInstanceState: Bundle?) {
viewModel.init(intent.getStringExtra("key"))
initRecyclerView()
initSearchView()
viewModel.logs.observe(this, Observer {
adapter.addItem(it.obj as String)
if (it.what == -1 || it.what == 1000) {
rotate_loading.hide()
}
})
}
private fun initRecyclerView() {
ATH.applyEdgeEffectColor(recycler_view)
adapter = SourceDebugAdapter()
adapter = SourceDebugAdapter(this)
recycler_view.layoutManager = LinearLayoutManager(this)
recycler_view.adapter = adapter
rotate_loading.loadingColor = ThemeStore.accentColor(this)
@ -69,36 +64,12 @@ class SourceDebugActivity : BaseActivity<AndroidViewModel>(), SourceDebug.Callba
}
private fun startSearch(key: String) {
adapter.logList.clear()
adapter.notifyDataSetChanged()
bookSource?.let {
SourceDebug.debugSource = it.bookSourceUrl
adapter.clearItems()
viewModel.startDebug(key, {
rotate_loading.show()
if (key.isAbsUrl()) {
val book = Book()
book.origin = it.bookSourceUrl
book.bookUrl = key
SourceDebug(WebBook(it), this)
.printLog(it.bookSourceUrl, 1, "开始访问$key")
.infoDebug(book)
} else {
SourceDebug(WebBook(it), this)
.printLog(it.bookSourceUrl, 1, "开始搜索关键字$key")
.searchDebug(key)
}
} ?: toast("未获取到书源")
}
override fun printLog(state: Int, msg: String) {
launch {
synchronized(this) {
adapter.logList.add(msg)
adapter.notifyItemInserted(adapter.logList.size - 1)
if (state == -1 || state == 1000) {
rotate_loading.hide()
}
}
}
}, {
toast("未获取到书源")
})
}
override fun onDestroy() {

@ -1,32 +1,15 @@
package io.legado.app.ui.sourcedebug
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import android.content.Context
import io.legado.app.R
import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.base.adapter.SimpleRecyclerAdapter
import kotlinx.android.synthetic.main.item_source_debug.view.*
class SourceDebugAdapter : RecyclerView.Adapter<SourceDebugAdapter.MyViewHolder>() {
val logList = arrayListOf<String>()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
return MyViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.item_source_debug, parent, false))
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
holder.bind(logList[position])
}
override fun getItemCount(): Int {
return logList.size
}
class MyViewHolder(view: View) : RecyclerView.ViewHolder(view) {
fun bind(log: String) = with(itemView) {
text_view.text = log
class SourceDebugAdapter(context: Context) : SimpleRecyclerAdapter<String>(context, R.layout.item_source_debug) {
override fun convert(holder: ItemViewHolder, item: String, payloads: MutableList<Any>) {
holder.itemView.apply {
text_view.text = item
}
}
}

@ -0,0 +1,51 @@
package io.legado.app.ui.sourcedebug
import android.app.Application
import androidx.lifecycle.MutableLiveData
import io.legado.app.App
import io.legado.app.base.BaseViewModel
import io.legado.app.data.entities.Book
import io.legado.app.data.entities.BookSource
import io.legado.app.help.EventMessage
import io.legado.app.model.WebBook
import io.legado.app.model.webbook.SourceDebug
import io.legado.app.utils.isAbsUrl
class SourceDebugModel(application: Application) : BaseViewModel(application), SourceDebug.Callback {
val logs: MutableLiveData<EventMessage> = MutableLiveData()
private var bookSource: BookSource? = null
fun init(sourceUrl: String?) {
sourceUrl?.let {
//优先使用这个,不会抛出异常
execute {
bookSource = App.db.bookSourceDao().findByKey(sourceUrl)
}
}
}
fun startDebug(key: String, start: (() -> Unit)? = null, error: (() -> Unit)? = null) {
bookSource?.let {
start?.let { it() }
SourceDebug.debugSource = it.bookSourceUrl
if (key.isAbsUrl()) {
val book = Book()
book.origin = it.bookSourceUrl
book.bookUrl = key
SourceDebug.printLog(it.bookSourceUrl, 1, "开始访问$key")
SourceDebug(WebBook(it), this)
.infoDebug(book)
} else {
SourceDebug.printLog(it.bookSourceUrl, 1, "开始搜索关键字$key")
SourceDebug(WebBook(it), this)
.searchDebug(key)
}
} ?: error?.let { it() }
}
override fun printLog(state: Int, msg: String) {
logs.postValue(EventMessage.obtain(state, msg))
}
}

@ -81,7 +81,7 @@ class SourceEditActivity : BaseActivity<SourceEditViewModel>(false), KeyboardToo
toast("书源名称和URL不能为空")
} else {
viewModel.save(bookSource) {
startActivity<SourceDebugActivity>(Pair("key", bookSource.bookSourceUrl))
startActivity<SourceDebugActivity>("key" to bookSource.bookSourceUrl)
}
}
}

Loading…
Cancel
Save