Add Stable interface for Category state (#7539)

(cherry picked from commit a21aa8125e63b9e0d4377aa9c97d6614ee4acf7f)
This commit is contained in:
Andreas 2022-07-15 23:35:19 +02:00 committed by Jobobby04
parent 8a3c9255e5
commit 41855c34de
20 changed files with 288 additions and 118 deletions

View File

@ -7,7 +7,6 @@ import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.rememberTopAppBarScrollState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.nestedscroll.nestedScroll
@ -20,6 +19,7 @@ import eu.kanade.presentation.category.components.CategoryFloatingActionButton
import eu.kanade.presentation.category.components.CategoryRenameDialog
import eu.kanade.presentation.category.components.CategoryTopAppBar
import eu.kanade.presentation.components.EmptyScreen
import eu.kanade.presentation.components.LoadingScreen
import eu.kanade.presentation.components.Scaffold
import eu.kanade.presentation.util.horizontalPadding
import eu.kanade.presentation.util.plus
@ -52,25 +52,25 @@ fun CategoryScreen(
floatingActionButton = {
CategoryFloatingActionButton(
lazyListState = lazyListState,
onCreate = { presenter.dialog = CategoryPresenter.Dialog.Create },
onCreate = { presenter.dialog = Dialog.Create },
)
},
) { paddingValues ->
val context = LocalContext.current
val categories by presenter.categories.collectAsState(initial = emptyList())
if (categories.isEmpty()) {
EmptyScreen(textResource = R.string.information_empty_category)
} else {
when {
presenter.isLoading -> LoadingScreen()
presenter.isEmpty -> EmptyScreen(textResource = R.string.information_empty_category)
else -> {
CategoryContent(
categories = categories,
state = presenter,
lazyListState = lazyListState,
paddingValues = paddingValues + topPaddingValues + PaddingValues(horizontal = horizontalPadding),
onMoveUp = { presenter.moveUp(it) },
onMoveDown = { presenter.moveDown(it) },
onRename = { presenter.dialog = Dialog.Rename(it) },
onDelete = { presenter.dialog = Dialog.Delete(it) },
)
}
}
val onDismissRequest = { presenter.dialog = null }
when (val dialog = presenter.dialog) {
Dialog.Create -> {

View File

@ -0,0 +1,28 @@
package eu.kanade.presentation.category
import androidx.compose.runtime.Stable
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import eu.kanade.domain.category.model.Category
import eu.kanade.tachiyomi.ui.category.CategoryPresenter
@Stable
interface CategoryState {
val isLoading: Boolean
var dialog: CategoryPresenter.Dialog?
val categories: List<Category>
val isEmpty: Boolean
}
fun CategoryState(): CategoryState {
return CategoryStateImpl()
}
class CategoryStateImpl : CategoryState {
override var isLoading: Boolean by mutableStateOf(true)
override var dialog: CategoryPresenter.Dialog? by mutableStateOf(null)
override var categories: List<Category> by mutableStateOf(emptyList())
override val isEmpty: Boolean by derivedStateOf { categories.isEmpty() }
}

View File

@ -7,8 +7,6 @@ import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.rememberTopAppBarScrollState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.LocalContext
@ -19,6 +17,7 @@ import eu.kanade.presentation.category.components.CategoryFloatingActionButton
import eu.kanade.presentation.category.components.CategoryTopAppBar
import eu.kanade.presentation.category.components.genre.SortTagContent
import eu.kanade.presentation.components.EmptyScreen
import eu.kanade.presentation.components.LoadingScreen
import eu.kanade.presentation.components.Scaffold
import eu.kanade.presentation.util.horizontalPadding
import eu.kanade.presentation.util.plus
@ -56,19 +55,20 @@ fun SortTagScreen(
},
) { paddingValues ->
val context = LocalContext.current
val tags by presenter.tags.collectAsState(initial = emptyList())
if (tags.isEmpty()) {
EmptyScreen(textResource = R.string.information_empty_tags)
} else {
when {
presenter.isLoading -> LoadingScreen()
presenter.isEmpty -> EmptyScreen(textResource = R.string.information_empty_category)
else -> {
SortTagContent(
categories = tags,
state = presenter,
lazyListState = lazyListState,
paddingValues = paddingValues + topPaddingValues + PaddingValues(horizontal = horizontalPadding),
onMoveUp = { tag, index -> presenter.moveUp(tag, index) },
onMoveDown = { tag, index -> presenter.moveDown(tag, index) },
onDelete = { presenter.dialog = Dialog.Delete(it) },
)
}
}
val onDismissRequest = { presenter.dialog = null }
when (val dialog = presenter.dialog) {
Dialog.Create -> {

View File

@ -0,0 +1,27 @@
package eu.kanade.presentation.category
import androidx.compose.runtime.Stable
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import eu.kanade.tachiyomi.ui.category.genre.SortTagPresenter
@Stable
interface SortTagState {
val isLoading: Boolean
var dialog: SortTagPresenter.Dialog?
val tags: List<String>
val isEmpty: Boolean
}
fun SortTagState(): SortTagState {
return SortTagStateImpl()
}
class SortTagStateImpl : SortTagState {
override var isLoading: Boolean by mutableStateOf(true)
override var dialog: SortTagPresenter.Dialog? by mutableStateOf(null)
override var tags: List<String> by mutableStateOf(emptyList())
override val isEmpty: Boolean by derivedStateOf { tags.isEmpty() }
}

View File

@ -7,8 +7,6 @@ import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.rememberTopAppBarScrollState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.LocalContext
@ -20,6 +18,7 @@ import eu.kanade.presentation.category.components.CategoryRenameDialog
import eu.kanade.presentation.category.components.CategoryTopAppBar
import eu.kanade.presentation.category.components.sources.SourceCategoryContent
import eu.kanade.presentation.components.EmptyScreen
import eu.kanade.presentation.components.LoadingScreen
import eu.kanade.presentation.components.Scaffold
import eu.kanade.presentation.util.horizontalPadding
import eu.kanade.presentation.util.plus
@ -57,18 +56,18 @@ fun SourceCategoryScreen(
},
) { paddingValues ->
val context = LocalContext.current
val categories by presenter.categories.collectAsState(initial = emptyList())
if (categories.isEmpty()) {
EmptyScreen(textResource = R.string.information_empty_category)
} else {
when {
presenter.isLoading -> LoadingScreen()
presenter.isEmpty -> EmptyScreen(textResource = R.string.information_empty_category)
else -> {
SourceCategoryContent(
categories = categories,
state = presenter,
lazyListState = lazyListState,
paddingValues = paddingValues + topPaddingValues + PaddingValues(horizontal = horizontalPadding),
onRename = { presenter.dialog = Dialog.Rename(it) },
onDelete = { presenter.dialog = Dialog.Delete(it) },
)
}
}
val onDismissRequest = { presenter.dialog = null }
when (val dialog = presenter.dialog) {
Dialog.Create -> {

View File

@ -0,0 +1,27 @@
package eu.kanade.presentation.category
import androidx.compose.runtime.Stable
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import eu.kanade.tachiyomi.ui.category.sources.SourceCategoryPresenter
@Stable
interface SourceCategoryState {
val isLoading: Boolean
var dialog: SourceCategoryPresenter.Dialog?
val categories: List<String>
val isEmpty: Boolean
}
fun SourceCategoryState(): SourceCategoryState {
return SourceCategoryStateImpl()
}
class SourceCategoryStateImpl : SourceCategoryState {
override var isLoading: Boolean by mutableStateOf(true)
override var dialog: SourceCategoryPresenter.Dialog? by mutableStateOf(null)
override var categories: List<String> by mutableStateOf(emptyList())
override val isEmpty: Boolean by derivedStateOf { categories.isEmpty() }
}

View File

@ -7,8 +7,6 @@ import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.rememberTopAppBarScrollState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.LocalContext
@ -19,6 +17,7 @@ import eu.kanade.presentation.category.components.CategoryFloatingActionButton
import eu.kanade.presentation.category.components.CategoryTopAppBar
import eu.kanade.presentation.category.components.repo.SourceRepoContent
import eu.kanade.presentation.components.EmptyScreen
import eu.kanade.presentation.components.LoadingScreen
import eu.kanade.presentation.components.Scaffold
import eu.kanade.presentation.util.horizontalPadding
import eu.kanade.presentation.util.plus
@ -56,17 +55,18 @@ fun SourceRepoScreen(
},
) { paddingValues ->
val context = LocalContext.current
val repos by presenter.repos.collectAsState(initial = emptyList())
if (repos.isEmpty()) {
EmptyScreen(textResource = R.string.information_empty_repos)
} else {
when {
presenter.isLoading -> LoadingScreen()
presenter.isEmpty -> EmptyScreen(textResource = R.string.information_empty_category)
else -> {
SourceRepoContent(
repos = repos,
state = presenter,
lazyListState = lazyListState,
paddingValues = paddingValues + topPaddingValues + PaddingValues(horizontal = horizontalPadding),
onDelete = { presenter.dialog = Dialog.Delete(it) },
)
}
}
val onDismissRequest = { presenter.dialog = null }
when (val dialog = presenter.dialog) {
Dialog.Create -> {

View File

@ -0,0 +1,27 @@
package eu.kanade.presentation.category
import androidx.compose.runtime.Stable
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import eu.kanade.tachiyomi.ui.category.repos.RepoPresenter
@Stable
interface SourceRepoState {
val isLoading: Boolean
var dialog: RepoPresenter.Dialog?
val repos: List<String>
val isEmpty: Boolean
}
fun SourceRepoState(): SourceRepoState {
return SourceRepoStateImpl()
}
class SourceRepoStateImpl : SourceRepoState {
override var isLoading: Boolean by mutableStateOf(true)
override var dialog: RepoPresenter.Dialog? by mutableStateOf(null)
override var repos: List<String> by mutableStateOf(emptyList())
override val isEmpty: Boolean by derivedStateOf { repos.isEmpty() }
}

View File

@ -5,34 +5,40 @@ import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import eu.kanade.domain.category.model.Category
import eu.kanade.presentation.category.CategoryState
import eu.kanade.presentation.components.LazyColumn
import eu.kanade.tachiyomi.ui.category.CategoryPresenter.Dialog
@Composable
fun CategoryContent(
categories: List<Category>,
state: CategoryState,
lazyListState: LazyListState,
paddingValues: PaddingValues,
onMoveUp: (Category) -> Unit,
onMoveDown: (Category) -> Unit,
onRename: (Category) -> Unit,
onDelete: (Category) -> Unit,
) {
val categories = state.categories
LazyColumn(
state = lazyListState,
contentPadding = paddingValues,
verticalArrangement = Arrangement.spacedBy(8.dp),
) {
itemsIndexed(categories) { index, category ->
itemsIndexed(
items = categories,
key = { _, category -> category.id },
) { index, category ->
CategoryListItem(
modifier = Modifier.animateItemPlacement(),
category = category,
canMoveUp = index != 0,
canMoveDown = index != categories.lastIndex,
onMoveUp = onMoveUp,
onMoveDown = onMoveDown,
onRename = onRename,
onDelete = onDelete,
onRename = { state.dialog = Dialog.Rename(category) },
onDelete = { state.dialog = Dialog.Delete(category) },
)
}
}

View File

@ -21,15 +21,18 @@ import eu.kanade.presentation.util.horizontalPadding
@Composable
fun CategoryListItem(
modifier: Modifier = Modifier,
category: Category,
canMoveUp: Boolean,
canMoveDown: Boolean,
onMoveUp: (Category) -> Unit,
onMoveDown: (Category) -> Unit,
onRename: (Category) -> Unit,
onDelete: (Category) -> Unit,
onRename: () -> Unit,
onDelete: () -> Unit,
) {
ElevatedCard(
modifier = modifier,
) {
ElevatedCard {
Row(
modifier = Modifier
.padding(start = horizontalPadding, top = horizontalPadding, end = horizontalPadding),
@ -52,10 +55,10 @@ fun CategoryListItem(
Icon(imageVector = Icons.Outlined.ArrowDropDown, contentDescription = "")
}
Spacer(modifier = Modifier.weight(1f))
IconButton(onClick = { onRename(category) }) {
IconButton(onClick = onRename) {
Icon(imageVector = Icons.Outlined.Edit, contentDescription = "")
}
IconButton(onClick = { onDelete(category) }) {
IconButton(onClick = onDelete) {
Icon(imageVector = Icons.Outlined.Delete, contentDescription = "")
}
}

View File

@ -5,32 +5,36 @@ import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import eu.kanade.presentation.category.SortTagState
import eu.kanade.presentation.components.LazyColumn
import eu.kanade.tachiyomi.ui.category.genre.SortTagPresenter
@Composable
fun SortTagContent(
categories: List<String>,
state: SortTagState,
lazyListState: LazyListState,
paddingValues: PaddingValues,
onMoveUp: (String, Int) -> Unit,
onMoveDown: (String, Int) -> Unit,
onDelete: (String) -> Unit,
) {
val tags = state.tags
LazyColumn(
state = lazyListState,
contentPadding = paddingValues,
verticalArrangement = Arrangement.spacedBy(8.dp),
) {
itemsIndexed(categories) { index, tag ->
itemsIndexed(tags) { index, tag ->
SortTagListItem(
modifier = Modifier.animateItemPlacement(),
tag = tag,
index = index,
canMoveUp = index != 0,
canMoveDown = index != categories.lastIndex,
canMoveDown = index != tags.lastIndex,
onMoveUp = onMoveUp,
onMoveDown = onMoveDown,
onDelete = onDelete,
onDelete = { state.dialog = SortTagPresenter.Dialog.Delete(it) },
)
}
}

View File

@ -19,6 +19,7 @@ import eu.kanade.presentation.util.horizontalPadding
@Composable
fun SortTagListItem(
modifier: Modifier,
tag: String,
index: Int,
canMoveUp: Boolean,
@ -27,7 +28,9 @@ fun SortTagListItem(
onMoveDown: (String, Int) -> Unit,
onDelete: (String) -> Unit,
) {
ElevatedCard {
ElevatedCard(
modifier = modifier,
) {
Row(
modifier = Modifier
.padding(start = horizontalPadding, top = horizontalPadding, end = horizontalPadding),

View File

@ -5,16 +5,19 @@ import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.items
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import eu.kanade.presentation.category.SourceRepoState
import eu.kanade.presentation.components.LazyColumn
import eu.kanade.tachiyomi.ui.category.repos.RepoPresenter
@Composable
fun SourceRepoContent(
repos: List<String>,
state: SourceRepoState,
lazyListState: LazyListState,
paddingValues: PaddingValues,
onDelete: (String) -> Unit,
) {
val repos = state.repos
LazyColumn(
state = lazyListState,
contentPadding = paddingValues,
@ -22,8 +25,9 @@ fun SourceRepoContent(
) {
items(repos) { repo ->
SourceRepoListItem(
modifier = Modifier.animateItemPlacement(),
repo = repo,
onDelete = onDelete,
onDelete = { state.dialog = RepoPresenter.Dialog.Delete(it) },
)
}
}

View File

@ -17,10 +17,13 @@ import eu.kanade.presentation.util.horizontalPadding
@Composable
fun SourceRepoListItem(
modifier: Modifier,
repo: String,
onDelete: (String) -> Unit,
) {
ElevatedCard {
ElevatedCard(
modifier = modifier,
) {
Row(
modifier = Modifier
.padding(start = horizontalPadding, top = horizontalPadding, end = horizontalPadding),

View File

@ -3,29 +3,32 @@ package eu.kanade.presentation.category.components.sources
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.lazy.items
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import eu.kanade.presentation.category.SourceCategoryState
import eu.kanade.presentation.components.LazyColumn
import eu.kanade.tachiyomi.ui.category.sources.SourceCategoryPresenter
@Composable
fun SourceCategoryContent(
categories: List<String>,
state: SourceCategoryState,
lazyListState: LazyListState,
paddingValues: PaddingValues,
onRename: (String) -> Unit,
onDelete: (String) -> Unit,
) {
val categories = state.categories
LazyColumn(
state = lazyListState,
contentPadding = paddingValues,
verticalArrangement = Arrangement.spacedBy(8.dp),
) {
itemsIndexed(categories) { index, category ->
items(categories) { category ->
SourceCategoryListItem(
modifier = Modifier.animateItemPlacement(),
category = category,
onRename = onRename,
onDelete = onDelete,
onRename = { state.dialog = SourceCategoryPresenter.Dialog.Rename(category) },
onDelete = { state.dialog = SourceCategoryPresenter.Dialog.Delete(category) },
)
}
}

View File

@ -18,11 +18,14 @@ import eu.kanade.presentation.util.horizontalPadding
@Composable
fun SourceCategoryListItem(
modifier: Modifier,
category: String,
onRename: (String) -> Unit,
onDelete: (String) -> Unit,
) {
ElevatedCard {
ElevatedCard(
modifier = modifier,
) {
Row(
modifier = Modifier
.padding(start = horizontalPadding, top = horizontalPadding, end = horizontalPadding),

View File

@ -1,36 +1,45 @@
package eu.kanade.tachiyomi.ui.category
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import android.os.Bundle
import eu.kanade.domain.category.interactor.CreateCategoryWithName
import eu.kanade.domain.category.interactor.DeleteCategory
import eu.kanade.domain.category.interactor.GetCategories
import eu.kanade.domain.category.interactor.RenameCategory
import eu.kanade.domain.category.interactor.ReorderCategory
import eu.kanade.domain.category.model.Category
import eu.kanade.presentation.category.CategoryState
import eu.kanade.presentation.category.CategoryStateImpl
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
import eu.kanade.tachiyomi.util.lang.launchIO
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.consumeAsFlow
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
class CategoryPresenter(
private val state: CategoryStateImpl = CategoryState() as CategoryStateImpl,
private val getCategories: GetCategories = Injekt.get(),
private val createCategoryWithName: CreateCategoryWithName = Injekt.get(),
private val renameCategory: RenameCategory = Injekt.get(),
private val reorderCategory: ReorderCategory = Injekt.get(),
private val deleteCategory: DeleteCategory = Injekt.get(),
) : BasePresenter<CategoryController>() {
var dialog: Dialog? by mutableStateOf(null)
val categories = getCategories.subscribe()
) : BasePresenter<CategoryController>(), CategoryState by state {
private val _events: Channel<Event> = Channel(Int.MAX_VALUE)
val events = _events.consumeAsFlow()
override fun onCreate(savedState: Bundle?) {
super.onCreate(savedState)
presenterScope.launchIO {
getCategories.subscribe()
.collectLatest {
state.isLoading = false
state.categories = it
}
}
}
fun createCategory(name: String) {
presenterScope.launchIO {
when (createCategoryWithName.await(name)) {

View File

@ -1,15 +1,16 @@
package eu.kanade.tachiyomi.ui.category.genre
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import android.os.Bundle
import eu.kanade.domain.manga.interactor.CreateSortTag
import eu.kanade.domain.manga.interactor.DeleteSortTag
import eu.kanade.domain.manga.interactor.GetSortTag
import eu.kanade.domain.manga.interactor.ReorderSortTag
import eu.kanade.presentation.category.SortTagState
import eu.kanade.presentation.category.SortTagStateImpl
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
import eu.kanade.tachiyomi.util.lang.launchIO
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.consumeAsFlow
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
@ -18,22 +19,27 @@ import uy.kohesive.injekt.api.get
* Presenter of [SortTagController]. Used to manage the categories of the library.
*/
class SortTagPresenter(
private val state: SortTagStateImpl = SortTagState() as SortTagStateImpl,
private val getSortTag: GetSortTag = Injekt.get(),
private val createSortTag: CreateSortTag = Injekt.get(),
private val deleteSortTag: DeleteSortTag = Injekt.get(),
private val reorderSortTag: ReorderSortTag = Injekt.get(),
) : BasePresenter<SortTagController>() {
var dialog: Dialog? by mutableStateOf(null)
/**
* List containing categories.
*/
val tags = getSortTag.subscribe()
) : BasePresenter<SortTagController>(), SortTagState by state {
private val _events: Channel<Event> = Channel(Int.MAX_VALUE)
val events = _events.consumeAsFlow()
override fun onCreate(savedState: Bundle?) {
super.onCreate(savedState)
presenterScope.launchIO {
getSortTag.subscribe()
.collectLatest {
state.isLoading = false
state.tags = it
}
}
}
fun createTag(name: String) {
presenterScope.launchIO {
when (createSortTag.await(name)) {

View File

@ -1,14 +1,15 @@
package eu.kanade.tachiyomi.ui.category.repos
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import android.os.Bundle
import eu.kanade.domain.source.interactor.CreateSourceRepo
import eu.kanade.domain.source.interactor.DeleteSourceRepos
import eu.kanade.domain.source.interactor.GetSourceRepos
import eu.kanade.presentation.category.SourceRepoState
import eu.kanade.presentation.category.SourceRepoStateImpl
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
import eu.kanade.tachiyomi.util.lang.launchIO
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.consumeAsFlow
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
@ -17,18 +18,26 @@ import uy.kohesive.injekt.api.get
* Presenter of [RepoController]. Used to manage the repos for the extensions.
*/
class RepoPresenter(
private val state: SourceRepoStateImpl = SourceRepoState() as SourceRepoStateImpl,
private val getSourceRepos: GetSourceRepos = Injekt.get(),
private val createSourceRepo: CreateSourceRepo = Injekt.get(),
private val deleteSourceRepos: DeleteSourceRepos = Injekt.get(),
) : BasePresenter<RepoController>() {
var dialog: Dialog? by mutableStateOf(null)
val repos = getSourceRepos.subscribe()
) : BasePresenter<RepoController>(), SourceRepoState by state {
private val _events: Channel<Event> = Channel(Int.MAX_VALUE)
val events = _events.consumeAsFlow()
override fun onCreate(savedState: Bundle?) {
super.onCreate(savedState)
presenterScope.launchIO {
getSourceRepos.subscribe()
.collectLatest {
state.isLoading = false
state.repos = it
}
}
}
/**
* Creates and adds a new repo to the database.
*

View File

@ -1,15 +1,16 @@
package eu.kanade.tachiyomi.ui.category.sources
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import android.os.Bundle
import eu.kanade.domain.source.interactor.CreateSourceCategory
import eu.kanade.domain.source.interactor.DeleteSourceCategory
import eu.kanade.domain.source.interactor.GetSourceCategories
import eu.kanade.domain.source.interactor.RenameSourceCategory
import eu.kanade.presentation.category.SourceCategoryState
import eu.kanade.presentation.category.SourceCategoryStateImpl
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
import eu.kanade.tachiyomi.util.lang.launchIO
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.consumeAsFlow
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
@ -18,19 +19,27 @@ import uy.kohesive.injekt.api.get
* Presenter of [SourceCategoryController]. Used to manage the categories of the library.
*/
class SourceCategoryPresenter(
private val state: SourceCategoryStateImpl = SourceCategoryState() as SourceCategoryStateImpl,
private val getSourceCategories: GetSourceCategories = Injekt.get(),
private val createSourceCategory: CreateSourceCategory = Injekt.get(),
private val renameSourceCategory: RenameSourceCategory = Injekt.get(),
private val deleteSourceCategory: DeleteSourceCategory = Injekt.get(),
) : BasePresenter<SourceCategoryController>() {
var dialog: Dialog? by mutableStateOf(null)
val categories = getSourceCategories.subscribe()
) : BasePresenter<SourceCategoryController>(), SourceCategoryState by state {
private val _events: Channel<Event> = Channel(Int.MAX_VALUE)
val events = _events.consumeAsFlow()
override fun onCreate(savedState: Bundle?) {
super.onCreate(savedState)
presenterScope.launchIO {
getSourceCategories.subscribe()
.collectLatest {
state.isLoading = false
state.categories = it
}
}
}
/**
* Creates and adds a new category to the database.
*