Update library fragment
parent
81df005655
commit
300d365d8b
@ -1,40 +1,30 @@
|
|||||||
package org.koitharu.kotatsu.library.domain
|
package org.koitharu.kotatsu.library.domain
|
||||||
|
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import kotlinx.coroutines.flow.combine
|
||||||
|
import kotlinx.coroutines.flow.flatMapLatest
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
import org.koitharu.kotatsu.core.db.MangaDatabase
|
import org.koitharu.kotatsu.core.db.MangaDatabase
|
||||||
import org.koitharu.kotatsu.core.db.entity.toManga
|
import org.koitharu.kotatsu.core.db.entity.toManga
|
||||||
import org.koitharu.kotatsu.core.db.entity.toMangaTags
|
import org.koitharu.kotatsu.core.db.entity.toMangaTags
|
||||||
import org.koitharu.kotatsu.core.model.FavouriteCategory
|
import org.koitharu.kotatsu.core.model.FavouriteCategory
|
||||||
import org.koitharu.kotatsu.favourites.data.FavouriteManga
|
|
||||||
import org.koitharu.kotatsu.favourites.data.toFavouriteCategory
|
import org.koitharu.kotatsu.favourites.data.toFavouriteCategory
|
||||||
import org.koitharu.kotatsu.favourites.domain.FavouritesRepository
|
|
||||||
import org.koitharu.kotatsu.history.domain.HistoryRepository
|
|
||||||
import org.koitharu.kotatsu.parsers.model.Manga
|
import org.koitharu.kotatsu.parsers.model.Manga
|
||||||
import org.koitharu.kotatsu.parsers.model.SortOrder
|
|
||||||
|
|
||||||
class LibraryRepository(
|
class LibraryRepository(
|
||||||
private val db: MangaDatabase,
|
private val db: MangaDatabase,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
fun observeFavourites(): Flow<Map<FavouriteCategory, List<Manga>>> {
|
||||||
fun observeFavourites(order: SortOrder): Flow<Map<FavouriteCategory, List<Manga>>> {
|
return db.favouriteCategoriesDao.observeAll()
|
||||||
return db.favouritesDao.observeAll(order)
|
.flatMapLatest { categories ->
|
||||||
.map { list -> groupByCategory(list) }
|
combine(
|
||||||
}
|
categories.map { cat ->
|
||||||
|
val category = cat.toFavouriteCategory()
|
||||||
private fun groupByCategory(list: List<FavouriteManga>): Map<FavouriteCategory, List<Manga>> {
|
db.favouritesDao.observeAll(category.id, category.order)
|
||||||
val map = HashMap<FavouriteCategory, MutableList<Manga>>()
|
.map { category to it.map { x -> x.manga.toManga(x.tags.toMangaTags()) } }
|
||||||
for (item in list) {
|
},
|
||||||
val manga = item.manga.toManga(item.tags.toMangaTags())
|
) { array -> array.toMap() }
|
||||||
for (category in item.categories) {
|
|
||||||
if (!category.isVisibleInLibrary) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
map.getOrPut(category.toFavouriteCategory()) { ArrayList() }
|
|
||||||
.add(manga)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return map
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,46 +1,22 @@
|
|||||||
package org.koitharu.kotatsu.list.ui.adapter
|
package org.koitharu.kotatsu.list.ui.adapter
|
||||||
|
|
||||||
import android.widget.TextView
|
|
||||||
import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegate
|
|
||||||
import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateViewBinding
|
import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateViewBinding
|
||||||
import org.koitharu.kotatsu.R
|
import org.koitharu.kotatsu.databinding.ItemHeaderButtonBinding
|
||||||
import org.koitharu.kotatsu.core.ui.titleRes
|
|
||||||
import org.koitharu.kotatsu.databinding.ItemHeaderWithFilterBinding
|
|
||||||
import org.koitharu.kotatsu.list.ui.model.ListHeader
|
import org.koitharu.kotatsu.list.ui.model.ListHeader
|
||||||
import org.koitharu.kotatsu.list.ui.model.ListModel
|
import org.koitharu.kotatsu.list.ui.model.ListModel
|
||||||
|
import org.koitharu.kotatsu.utils.ext.setTextAndVisible
|
||||||
|
|
||||||
fun listHeaderAD() = adapterDelegate<ListHeader, ListModel>(
|
fun listHeaderAD(
|
||||||
layout = R.layout.item_header,
|
listener: ListHeaderClickListener,
|
||||||
on = { item, _, _ -> item is ListHeader && item.sortOrder == null },
|
) = adapterDelegateViewBinding<ListHeader, ListModel, ItemHeaderButtonBinding>(
|
||||||
|
{ inflater, parent -> ItemHeaderButtonBinding.inflate(inflater, parent, false) },
|
||||||
) {
|
) {
|
||||||
|
binding.buttonMore.setOnClickListener {
|
||||||
bind {
|
listener.onListHeaderClick(item, it)
|
||||||
val textView = (itemView as TextView)
|
|
||||||
if (item.text != null) {
|
|
||||||
textView.text = item.text
|
|
||||||
} else {
|
|
||||||
textView.setText(item.textRes)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun listHeaderWithFilterAD(
|
|
||||||
listener: MangaListListener,
|
|
||||||
) = adapterDelegateViewBinding<ListHeader, ListModel, ItemHeaderWithFilterBinding>(
|
|
||||||
viewBinding = { inflater, parent -> ItemHeaderWithFilterBinding.inflate(inflater, parent, false) },
|
|
||||||
on = { item, _, _ -> item is ListHeader && item.sortOrder != null },
|
|
||||||
) {
|
|
||||||
|
|
||||||
binding.textViewFilter.setOnClickListener {
|
|
||||||
listener.onFilterClick(it)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bind {
|
bind {
|
||||||
if (item.text != null) {
|
binding.textViewTitle.text = item.getText(context)
|
||||||
binding.textViewTitle.text = item.text
|
binding.buttonMore.setTextAndVisible(item.buttonTextRes)
|
||||||
} else {
|
|
||||||
binding.textViewTitle.setText(item.textRes)
|
|
||||||
}
|
|
||||||
binding.textViewFilter.setText(requireNotNull(item.sortOrder).titleRes)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
package org.koitharu.kotatsu.list.ui.adapter
|
||||||
|
|
||||||
|
import android.view.View
|
||||||
|
import org.koitharu.kotatsu.list.ui.model.ListHeader
|
||||||
|
|
||||||
|
interface ListHeaderClickListener {
|
||||||
|
|
||||||
|
fun onListHeaderClick(item: ListHeader, view: View)
|
||||||
|
}
|
||||||
@ -1,11 +1,62 @@
|
|||||||
package org.koitharu.kotatsu.list.ui.model
|
package org.koitharu.kotatsu.list.ui.model
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
import org.koitharu.kotatsu.parsers.model.SortOrder
|
import org.koitharu.kotatsu.core.ui.DateTimeAgo
|
||||||
|
|
||||||
@Deprecated("")
|
class ListHeader private constructor(
|
||||||
data class ListHeader(
|
|
||||||
val text: CharSequence?,
|
val text: CharSequence?,
|
||||||
@StringRes val textRes: Int,
|
@StringRes val textRes: Int,
|
||||||
val sortOrder: SortOrder?,
|
val dateTimeAgo: DateTimeAgo?,
|
||||||
) : ListModel
|
@StringRes val buttonTextRes: Int,
|
||||||
|
val payload: Any?,
|
||||||
|
) : ListModel {
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
text: CharSequence,
|
||||||
|
@StringRes buttonTextRes: Int,
|
||||||
|
payload: Any?,
|
||||||
|
) : this(text, 0, null, buttonTextRes, payload)
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
@StringRes textRes: Int,
|
||||||
|
@StringRes buttonTextRes: Int,
|
||||||
|
payload: Any?,
|
||||||
|
) : this(null, textRes, null, buttonTextRes, payload)
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
dateTimeAgo: DateTimeAgo,
|
||||||
|
@StringRes buttonTextRes: Int,
|
||||||
|
payload: Any?,
|
||||||
|
) : this(null, 0, dateTimeAgo, buttonTextRes, payload)
|
||||||
|
|
||||||
|
fun getText(context: Context): CharSequence? = when {
|
||||||
|
text != null -> text
|
||||||
|
textRes != 0 -> context.getString(textRes)
|
||||||
|
else -> dateTimeAgo?.format(context.resources)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun equals(other: Any?): Boolean {
|
||||||
|
if (this === other) return true
|
||||||
|
if (javaClass != other?.javaClass) return false
|
||||||
|
|
||||||
|
other as ListHeader
|
||||||
|
|
||||||
|
if (text != other.text) return false
|
||||||
|
if (textRes != other.textRes) return false
|
||||||
|
if (dateTimeAgo != other.dateTimeAgo) return false
|
||||||
|
if (buttonTextRes != other.buttonTextRes) return false
|
||||||
|
if (payload != other.payload) return false
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hashCode(): Int {
|
||||||
|
var result = text?.hashCode() ?: 0
|
||||||
|
result = 31 * result + textRes
|
||||||
|
result = 31 * result + (dateTimeAgo?.hashCode() ?: 0)
|
||||||
|
result = 31 * result + buttonTextRes
|
||||||
|
result = 31 * result + (payload?.hashCode() ?: 0)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -1,36 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<RelativeLayout
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/textView_title"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_alignParentStart="true"
|
|
||||||
android:layout_centerVertical="true"
|
|
||||||
android:layout_toStartOf="@id/textView_filter"
|
|
||||||
android:singleLine="true"
|
|
||||||
android:textAppearance="@style/TextAppearance.Kotatsu.SectionHeader"
|
|
||||||
tools:text="@tools:sample/lorem[21]" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/textView_filter"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_alignParentEnd="true"
|
|
||||||
android:layout_centerVertical="true"
|
|
||||||
android:background="@drawable/list_selector"
|
|
||||||
android:gravity="center_vertical"
|
|
||||||
android:paddingStart="6dp"
|
|
||||||
android:singleLine="true"
|
|
||||||
android:textAppearance="@style/TextAppearance.Kotatsu.SectionHeader"
|
|
||||||
app:drawableEndCompat="@drawable/ic_expand_more"
|
|
||||||
app:drawableTint="?android:attr/textColorSecondary"
|
|
||||||
tools:ignore="RtlSymmetry"
|
|
||||||
tools:text="@string/popular" />
|
|
||||||
|
|
||||||
</RelativeLayout>
|
|
||||||
@ -0,0 +1,30 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<menu
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/action_share"
|
||||||
|
android:icon="?actionModeShareDrawable"
|
||||||
|
android:title="@string/share"
|
||||||
|
app:showAsAction="ifRoom|withText" />
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/action_remove"
|
||||||
|
android:icon="@drawable/ic_delete"
|
||||||
|
android:title="@string/remove"
|
||||||
|
app:showAsAction="ifRoom|withText" />
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/action_favourite"
|
||||||
|
android:icon="@drawable/ic_heart_outline"
|
||||||
|
android:title="@string/add_to_favourites"
|
||||||
|
app:showAsAction="ifRoom|withText" />
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/action_save"
|
||||||
|
android:icon="@drawable/ic_save"
|
||||||
|
android:title="@string/save"
|
||||||
|
app:showAsAction="ifRoom|withText" />
|
||||||
|
|
||||||
|
</menu>
|
||||||
Loading…
Reference in New Issue