mirror of
https://github.com/LiveFastEatTrashRaccoon/RaccoonForLemmy.git
synced 2025-02-10 07:20:41 +01:00
refactor: use filtered contents to render bookmarks (#840)
This commit is contained in:
parent
236590c0f9
commit
a10189d212
@ -70,7 +70,6 @@ kotlin {
|
|||||||
implementation(projects.unit.modlog)
|
implementation(projects.unit.modlog)
|
||||||
implementation(projects.unit.myaccount)
|
implementation(projects.unit.myaccount)
|
||||||
implementation(projects.unit.reportlist)
|
implementation(projects.unit.reportlist)
|
||||||
implementation(projects.unit.saveditems)
|
|
||||||
implementation(projects.unit.web)
|
implementation(projects.unit.web)
|
||||||
implementation(projects.unit.zoomableimage)
|
implementation(projects.unit.zoomableimage)
|
||||||
}
|
}
|
||||||
|
@ -61,7 +61,6 @@ import com.github.diegoberaldin.raccoonforlemmy.unit.managesubscriptions.ManageS
|
|||||||
import com.github.diegoberaldin.raccoonforlemmy.unit.modlog.ModlogScreen
|
import com.github.diegoberaldin.raccoonforlemmy.unit.modlog.ModlogScreen
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.unit.myaccount.ProfileLoggedScreen
|
import com.github.diegoberaldin.raccoonforlemmy.unit.myaccount.ProfileLoggedScreen
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.unit.reportlist.ReportListScreen
|
import com.github.diegoberaldin.raccoonforlemmy.unit.reportlist.ReportListScreen
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.unit.saveditems.SavedItemsScreen
|
|
||||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||||
import kotlinx.coroutines.flow.launchIn
|
import kotlinx.coroutines.flow.launchIn
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
@ -125,7 +124,8 @@ internal object ProfileMainScreen : Tab {
|
|||||||
}
|
}
|
||||||
|
|
||||||
NotificationCenterEvent.ProfileSideMenuAction.Bookmarks -> {
|
NotificationCenterEvent.ProfileSideMenuAction.Bookmarks -> {
|
||||||
navigationCoordinator.pushScreen(SavedItemsScreen())
|
val screen = FilteredContentsScreen(type = FilteredContentsType.Bookmarks.toInt())
|
||||||
|
navigationCoordinator.pushScreen(screen)
|
||||||
}
|
}
|
||||||
|
|
||||||
NotificationCenterEvent.ProfileSideMenuAction.Drafts -> {
|
NotificationCenterEvent.ProfileSideMenuAction.Drafts -> {
|
||||||
|
@ -85,7 +85,6 @@ include(":unit:rawcontent")
|
|||||||
include(":unit:remove")
|
include(":unit:remove")
|
||||||
include(":unit:replies")
|
include(":unit:replies")
|
||||||
include(":unit:reportlist")
|
include(":unit:reportlist")
|
||||||
include(":unit:saveditems")
|
|
||||||
include(":unit:selectcommunity")
|
include(":unit:selectcommunity")
|
||||||
include(":unit:selectinstance")
|
include(":unit:selectinstance")
|
||||||
include(":unit:userdetail")
|
include(":unit:userdetail")
|
||||||
|
@ -87,7 +87,6 @@ kotlin {
|
|||||||
implementation(projects.unit.postdetail)
|
implementation(projects.unit.postdetail)
|
||||||
implementation(projects.unit.remove)
|
implementation(projects.unit.remove)
|
||||||
implementation(projects.unit.reportlist)
|
implementation(projects.unit.reportlist)
|
||||||
implementation(projects.unit.saveditems)
|
|
||||||
implementation(projects.unit.selectcommunity)
|
implementation(projects.unit.selectcommunity)
|
||||||
implementation(projects.unit.selectinstance)
|
implementation(projects.unit.selectinstance)
|
||||||
implementation(projects.unit.userdetail)
|
implementation(projects.unit.userdetail)
|
||||||
|
@ -50,7 +50,6 @@ import com.github.diegoberaldin.raccoonforlemmy.unit.modlog.di.modlogModule
|
|||||||
import com.github.diegoberaldin.raccoonforlemmy.unit.postdetail.di.postDetailModule
|
import com.github.diegoberaldin.raccoonforlemmy.unit.postdetail.di.postDetailModule
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.unit.remove.di.removeModule
|
import com.github.diegoberaldin.raccoonforlemmy.unit.remove.di.removeModule
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.unit.reportlist.di.reportListModule
|
import com.github.diegoberaldin.raccoonforlemmy.unit.reportlist.di.reportListModule
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.unit.saveditems.di.savedItemsModule
|
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.unit.selectcommunity.di.selectCommunityModule
|
import com.github.diegoberaldin.raccoonforlemmy.unit.selectcommunity.di.selectCommunityModule
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.unit.selectinstance.di.selectInstanceModule
|
import com.github.diegoberaldin.raccoonforlemmy.unit.selectinstance.di.selectInstanceModule
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.unit.userdetail.di.userDetailModule
|
import com.github.diegoberaldin.raccoonforlemmy.unit.userdetail.di.userDetailModule
|
||||||
@ -93,7 +92,6 @@ val sharedHelperModule = module {
|
|||||||
instanceInfoModule,
|
instanceInfoModule,
|
||||||
removeModule,
|
removeModule,
|
||||||
reportListModule,
|
reportListModule,
|
||||||
savedItemsModule,
|
|
||||||
createReportModule,
|
createReportModule,
|
||||||
createPostModule,
|
createPostModule,
|
||||||
createCommentModule,
|
createCommentModule,
|
||||||
|
@ -51,7 +51,6 @@ import com.github.diegoberaldin.raccoonforlemmy.unit.modlog.di.modlogModule
|
|||||||
import com.github.diegoberaldin.raccoonforlemmy.unit.postdetail.di.postDetailModule
|
import com.github.diegoberaldin.raccoonforlemmy.unit.postdetail.di.postDetailModule
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.unit.remove.di.removeModule
|
import com.github.diegoberaldin.raccoonforlemmy.unit.remove.di.removeModule
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.unit.reportlist.di.reportListModule
|
import com.github.diegoberaldin.raccoonforlemmy.unit.reportlist.di.reportListModule
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.unit.saveditems.di.savedItemsModule
|
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.unit.selectcommunity.di.selectCommunityModule
|
import com.github.diegoberaldin.raccoonforlemmy.unit.selectcommunity.di.selectCommunityModule
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.unit.selectinstance.di.selectInstanceModule
|
import com.github.diegoberaldin.raccoonforlemmy.unit.selectinstance.di.selectInstanceModule
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.unit.userdetail.di.userDetailModule
|
import com.github.diegoberaldin.raccoonforlemmy.unit.userdetail.di.userDetailModule
|
||||||
@ -96,7 +95,6 @@ fun initKoin() {
|
|||||||
instanceInfoModule,
|
instanceInfoModule,
|
||||||
removeModule,
|
removeModule,
|
||||||
reportListModule,
|
reportListModule,
|
||||||
savedItemsModule,
|
|
||||||
createReportModule,
|
createReportModule,
|
||||||
createPostModule,
|
createPostModule,
|
||||||
createCommentModule,
|
createCommentModule,
|
||||||
|
@ -11,14 +11,17 @@ import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.PostModel
|
|||||||
sealed interface FilteredContentsType {
|
sealed interface FilteredContentsType {
|
||||||
data object Votes : FilteredContentsType
|
data object Votes : FilteredContentsType
|
||||||
data object Moderated : FilteredContentsType
|
data object Moderated : FilteredContentsType
|
||||||
|
data object Bookmarks : FilteredContentsType
|
||||||
}
|
}
|
||||||
|
|
||||||
fun FilteredContentsType.toInt(): Int = when (this) {
|
fun FilteredContentsType.toInt(): Int = when (this) {
|
||||||
FilteredContentsType.Moderated -> 0
|
FilteredContentsType.Moderated -> 0
|
||||||
FilteredContentsType.Votes -> 1
|
FilteredContentsType.Votes -> 1
|
||||||
|
FilteredContentsType.Bookmarks -> 2
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Int.toFilteredContentsType(): FilteredContentsType = when (this) {
|
fun Int.toFilteredContentsType(): FilteredContentsType = when (this) {
|
||||||
|
2 -> FilteredContentsType.Bookmarks
|
||||||
1 -> FilteredContentsType.Votes
|
1 -> FilteredContentsType.Votes
|
||||||
else -> FilteredContentsType.Moderated
|
else -> FilteredContentsType.Moderated
|
||||||
}
|
}
|
||||||
@ -26,7 +29,6 @@ fun Int.toFilteredContentsType(): FilteredContentsType = when (this) {
|
|||||||
|
|
||||||
sealed interface FilteredContentsSection {
|
sealed interface FilteredContentsSection {
|
||||||
data object Posts : FilteredContentsSection
|
data object Posts : FilteredContentsSection
|
||||||
|
|
||||||
data object Comments : FilteredContentsSection
|
data object Comments : FilteredContentsSection
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,7 +49,7 @@ interface FilteredContentsMviModel :
|
|||||||
data class ModFeaturePost(val id: Long) : Intent
|
data class ModFeaturePost(val id: Long) : Intent
|
||||||
data class ModLockPost(val id: Long) : Intent
|
data class ModLockPost(val id: Long) : Intent
|
||||||
data class ModDistinguishComment(val commentId: Long) : Intent
|
data class ModDistinguishComment(val commentId: Long) : Intent
|
||||||
data object WillOpenDetail: Intent
|
data object WillOpenDetail : Intent
|
||||||
}
|
}
|
||||||
|
|
||||||
data class State(
|
data class State(
|
||||||
|
@ -175,6 +175,7 @@ class FilteredContentsScreen(
|
|||||||
text = when (uiState.contentsType) {
|
text = when (uiState.contentsType) {
|
||||||
FilteredContentsType.Moderated -> LocalXmlStrings.current.moderatorZoneActionContents
|
FilteredContentsType.Moderated -> LocalXmlStrings.current.moderatorZoneActionContents
|
||||||
FilteredContentsType.Votes -> LocalXmlStrings.current.profileUpvotesDownvotes
|
FilteredContentsType.Votes -> LocalXmlStrings.current.profileUpvotesDownvotes
|
||||||
|
FilteredContentsType.Bookmarks -> LocalXmlStrings.current.navigationDrawerTitleBookmarks
|
||||||
},
|
},
|
||||||
style = MaterialTheme.typography.titleMedium,
|
style = MaterialTheme.typography.titleMedium,
|
||||||
)
|
)
|
||||||
|
@ -21,8 +21,6 @@ import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.SortType
|
|||||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.imageUrl
|
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.imageUrl
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.CommentRepository
|
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.CommentRepository
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.PostRepository
|
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.PostRepository
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.IO
|
|
||||||
import kotlinx.coroutines.async
|
import kotlinx.coroutines.async
|
||||||
import kotlinx.coroutines.coroutineScope
|
import kotlinx.coroutines.coroutineScope
|
||||||
import kotlinx.coroutines.flow.launchIn
|
import kotlinx.coroutines.flow.launchIn
|
||||||
@ -185,6 +183,10 @@ class FilteredContentsViewModel(
|
|||||||
liked = currentState.liked,
|
liked = currentState.liked,
|
||||||
sortType = SortType.New,
|
sortType = SortType.New,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
FilteredContentsType.Bookmarks -> PostPaginationSpecification.Saved(
|
||||||
|
sortType = SortType.New,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
postPaginationManager.reset(postSpecification)
|
postPaginationManager.reset(postSpecification)
|
||||||
val commentSpecification = when (currentState.contentsType) {
|
val commentSpecification = when (currentState.contentsType) {
|
||||||
@ -197,6 +199,10 @@ class FilteredContentsViewModel(
|
|||||||
liked = currentState.liked,
|
liked = currentState.liked,
|
||||||
sortType = SortType.New,
|
sortType = SortType.New,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
FilteredContentsType.Bookmarks -> CommentPaginationSpecification.Saved(
|
||||||
|
sortType = SortType.New,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
commentPaginationManager.reset(commentSpecification)
|
commentPaginationManager.reset(commentSpecification)
|
||||||
updateState {
|
updateState {
|
||||||
@ -329,7 +335,7 @@ class FilteredContentsViewModel(
|
|||||||
saved = newValue,
|
saved = newValue,
|
||||||
)
|
)
|
||||||
handlePostUpdate(newPost)
|
handlePostUpdate(newPost)
|
||||||
screenModelScope.launch(Dispatchers.IO) {
|
screenModelScope.launch {
|
||||||
try {
|
try {
|
||||||
val auth = identityRepository.authToken.value.orEmpty()
|
val auth = identityRepository.authToken.value.orEmpty()
|
||||||
postRepository.save(
|
postRepository.save(
|
||||||
@ -348,7 +354,7 @@ class FilteredContentsViewModel(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun feature(post: PostModel) {
|
private fun feature(post: PostModel) {
|
||||||
screenModelScope.launch(Dispatchers.IO) {
|
screenModelScope.launch {
|
||||||
val auth = identityRepository.authToken.value.orEmpty()
|
val auth = identityRepository.authToken.value.orEmpty()
|
||||||
val newPost = postRepository.featureInCommunity(
|
val newPost = postRepository.featureInCommunity(
|
||||||
postId = post.id, auth = auth, featured = !post.featuredCommunity
|
postId = post.id, auth = auth, featured = !post.featuredCommunity
|
||||||
@ -360,7 +366,7 @@ class FilteredContentsViewModel(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun lock(post: PostModel) {
|
private fun lock(post: PostModel) {
|
||||||
screenModelScope.launch(Dispatchers.IO) {
|
screenModelScope.launch {
|
||||||
val auth = identityRepository.authToken.value.orEmpty()
|
val auth = identityRepository.authToken.value.orEmpty()
|
||||||
val newPost = postRepository.lock(
|
val newPost = postRepository.lock(
|
||||||
postId = post.id,
|
postId = post.id,
|
||||||
|
@ -1,81 +0,0 @@
|
|||||||
plugins {
|
|
||||||
alias(libs.plugins.kotlin.multiplatform)
|
|
||||||
alias(libs.plugins.android.library)
|
|
||||||
alias(libs.plugins.compose)
|
|
||||||
alias(libs.plugins.detekt)
|
|
||||||
}
|
|
||||||
|
|
||||||
@OptIn(org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi::class)
|
|
||||||
kotlin {
|
|
||||||
applyDefaultHierarchyTemplate()
|
|
||||||
|
|
||||||
androidTarget {
|
|
||||||
compilations.all {
|
|
||||||
kotlinOptions {
|
|
||||||
jvmTarget = "1.8"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
listOf(
|
|
||||||
iosX64(),
|
|
||||||
iosArm64(),
|
|
||||||
iosSimulatorArm64()
|
|
||||||
).forEach {
|
|
||||||
it.binaries.framework {
|
|
||||||
baseName = "saveditems"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sourceSets {
|
|
||||||
val commonMain by getting {
|
|
||||||
dependencies {
|
|
||||||
implementation(compose.runtime)
|
|
||||||
implementation(compose.foundation)
|
|
||||||
implementation(compose.material)
|
|
||||||
implementation(compose.material3)
|
|
||||||
implementation(compose.materialIconsExtended)
|
|
||||||
|
|
||||||
implementation(libs.koin.core)
|
|
||||||
implementation(libs.voyager.navigator)
|
|
||||||
implementation(libs.voyager.screenmodel)
|
|
||||||
implementation(libs.voyager.koin)
|
|
||||||
|
|
||||||
implementation(projects.core.appearance)
|
|
||||||
implementation(projects.core.architecture)
|
|
||||||
implementation(projects.core.commonui.components)
|
|
||||||
implementation(projects.core.commonui.detailopenerApi)
|
|
||||||
implementation(projects.core.commonui.lemmyui)
|
|
||||||
implementation(projects.core.commonui.modals)
|
|
||||||
implementation(projects.core.l10n)
|
|
||||||
implementation(projects.core.navigation)
|
|
||||||
implementation(projects.core.notifications)
|
|
||||||
implementation(projects.core.persistence)
|
|
||||||
implementation(projects.core.utils)
|
|
||||||
|
|
||||||
implementation(projects.domain.identity)
|
|
||||||
implementation(projects.domain.lemmy.data)
|
|
||||||
implementation(projects.domain.lemmy.pagination)
|
|
||||||
implementation(projects.domain.lemmy.repository)
|
|
||||||
|
|
||||||
implementation(projects.unit.zoomableimage)
|
|
||||||
implementation(projects.unit.web)
|
|
||||||
implementation(projects.unit.createreport)
|
|
||||||
implementation(projects.unit.createcomment)
|
|
||||||
implementation(projects.unit.rawcontent)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
val commonTest by getting {
|
|
||||||
dependencies {
|
|
||||||
implementation(kotlin("test"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
android {
|
|
||||||
namespace = "com.github.diegoberaldin.raccoonforlemmy.unit.saveditems"
|
|
||||||
compileSdk = libs.versions.android.targetSdk.get().toInt()
|
|
||||||
defaultConfig {
|
|
||||||
minSdk = libs.versions.android.minSdk.get().toInt()
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
<?xml version="1.0" ?>
|
|
||||||
<SmellBaseline>
|
|
||||||
<ManuallySuppressedIssues></ManuallySuppressedIssues>
|
|
||||||
<CurrentIssues>
|
|
||||||
<ID>CyclomaticComplexMethod:SavedItemsScreen.kt$SavedItemsScreen$@OptIn(ExperimentalMaterialApi::class, ExperimentalMaterial3Api::class) @Composable override fun Content()</ID>
|
|
||||||
<ID>CyclomaticComplexMethod:SavedItemsViewModel.kt$SavedItemsViewModel$override fun reduce(intent: SavedItemsMviModel.Intent)</ID>
|
|
||||||
<ID>LongMethod:SavedItemsScreen.kt$SavedItemsScreen$@OptIn(ExperimentalMaterialApi::class, ExperimentalMaterial3Api::class) @Composable override fun Content()</ID>
|
|
||||||
<ID>LongMethod:SavedItemsViewModel.kt$SavedItemsViewModel$private fun loadNextPage()</ID>
|
|
||||||
<ID>LongParameterList:SavedItemsViewModel.kt$SavedItemsViewModel$( private val identityRepository: IdentityRepository, private val apiConfigurationRepository: ApiConfigurationRepository, private val siteRepository: SiteRepository, private val userRepository: UserRepository, private val postRepository: PostRepository, private val commentRepository: CommentRepository, private val themeRepository: ThemeRepository, private val settingsRepository: SettingsRepository, private val shareHelper: ShareHelper, private val notificationCenter: NotificationCenter, private val hapticFeedback: HapticFeedback, private val getSortTypesUseCase: GetSortTypesUseCase, )</ID>
|
|
||||||
<ID>TooGenericExceptionCaught:SavedItemsViewModel.kt$SavedItemsViewModel$e: Throwable</ID>
|
|
||||||
<ID>TooManyFunctions:SavedItemsViewModel.kt$SavedItemsViewModel : SavedItemsMviModelDefaultMviModel</ID>
|
|
||||||
</CurrentIssues>
|
|
||||||
</SmellBaseline>
|
|
@ -1,56 +0,0 @@
|
|||||||
package com.github.diegoberaldin.raccoonforlemmy.unit.saveditems
|
|
||||||
|
|
||||||
import androidx.compose.runtime.Stable
|
|
||||||
import cafe.adriel.voyager.core.model.ScreenModel
|
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.PostLayout
|
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.VoteFormat
|
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.MviModel
|
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.CommentModel
|
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.PostModel
|
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.SortType
|
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.UserModel
|
|
||||||
|
|
||||||
@Stable
|
|
||||||
interface SavedItemsMviModel :
|
|
||||||
MviModel<SavedItemsMviModel.Intent, SavedItemsMviModel.UiState, SavedItemsMviModel.Effect>,
|
|
||||||
ScreenModel {
|
|
||||||
|
|
||||||
sealed interface Intent {
|
|
||||||
data object Refresh : Intent
|
|
||||||
data object LoadNextPage : Intent
|
|
||||||
data class ChangeSection(val section: SavedItemsSection) : Intent
|
|
||||||
data class UpVotePost(val id: Long, val feedback: Boolean = false) : Intent
|
|
||||||
data class DownVotePost(val id: Long, val feedback: Boolean = false) : Intent
|
|
||||||
data class SavePost(val id: Long, val feedback: Boolean = false) : Intent
|
|
||||||
data class UpVoteComment(val id: Long, val feedback: Boolean = false) : Intent
|
|
||||||
data class DownVoteComment(val id: Long, val feedback: Boolean = false) : Intent
|
|
||||||
data class SaveComment(val id: Long, val feedback: Boolean = false) : Intent
|
|
||||||
data class Share(val url: String) : Intent
|
|
||||||
data object WillOpenSave : Intent
|
|
||||||
}
|
|
||||||
|
|
||||||
data class UiState(
|
|
||||||
val section: SavedItemsSection = SavedItemsSection.Posts,
|
|
||||||
val user: UserModel? = null,
|
|
||||||
val instance: String = "",
|
|
||||||
val refreshing: Boolean = false,
|
|
||||||
val loading: Boolean = false,
|
|
||||||
val canFetchMore: Boolean = true,
|
|
||||||
val sortType: SortType = SortType.New,
|
|
||||||
val blurNsfw: Boolean = true,
|
|
||||||
val posts: List<PostModel> = emptyList(),
|
|
||||||
val comments: List<CommentModel> = emptyList(),
|
|
||||||
val postLayout: PostLayout = PostLayout.Card,
|
|
||||||
val fullHeightImages: Boolean = true,
|
|
||||||
val fullWidthImages: Boolean = false,
|
|
||||||
val voteFormat: VoteFormat = VoteFormat.Aggregated,
|
|
||||||
val autoLoadImages: Boolean = true,
|
|
||||||
val preferNicknames: Boolean = true,
|
|
||||||
val showScores: Boolean = true,
|
|
||||||
val availableSortTypes: List<SortType> = emptyList(),
|
|
||||||
)
|
|
||||||
|
|
||||||
sealed interface Effect {
|
|
||||||
data object BackToTop : Effect
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,565 +0,0 @@
|
|||||||
package com.github.diegoberaldin.raccoonforlemmy.unit.saveditems
|
|
||||||
|
|
||||||
import androidx.compose.animation.AnimatedVisibility
|
|
||||||
import androidx.compose.animation.slideInVertically
|
|
||||||
import androidx.compose.animation.slideOutVertically
|
|
||||||
import androidx.compose.foundation.Image
|
|
||||||
import androidx.compose.foundation.background
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
|
||||||
import androidx.compose.foundation.layout.Box
|
|
||||||
import androidx.compose.foundation.layout.Column
|
|
||||||
import androidx.compose.foundation.layout.Spacer
|
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
|
||||||
import androidx.compose.foundation.layout.height
|
|
||||||
import androidx.compose.foundation.layout.padding
|
|
||||||
import androidx.compose.foundation.layout.size
|
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
|
||||||
import androidx.compose.foundation.lazy.items
|
|
||||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
|
||||||
import androidx.compose.material.ExperimentalMaterialApi
|
|
||||||
import androidx.compose.material.icons.Icons
|
|
||||||
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
|
||||||
import androidx.compose.material.icons.filled.ExpandLess
|
|
||||||
import androidx.compose.material.pullrefresh.PullRefreshIndicator
|
|
||||||
import androidx.compose.material.pullrefresh.pullRefresh
|
|
||||||
import androidx.compose.material.pullrefresh.rememberPullRefreshState
|
|
||||||
import androidx.compose.material3.CircularProgressIndicator
|
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
|
||||||
import androidx.compose.material3.HorizontalDivider
|
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.material3.Scaffold
|
|
||||||
import androidx.compose.material3.Snackbar
|
|
||||||
import androidx.compose.material3.SnackbarHost
|
|
||||||
import androidx.compose.material3.SnackbarHostState
|
|
||||||
import androidx.compose.material3.Text
|
|
||||||
import androidx.compose.material3.TopAppBar
|
|
||||||
import androidx.compose.material3.TopAppBarDefaults
|
|
||||||
import androidx.compose.material3.rememberTopAppBarState
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
|
||||||
import androidx.compose.runtime.collectAsState
|
|
||||||
import androidx.compose.runtime.getValue
|
|
||||||
import androidx.compose.runtime.mutableStateOf
|
|
||||||
import androidx.compose.runtime.remember
|
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
|
||||||
import androidx.compose.runtime.setValue
|
|
||||||
import androidx.compose.ui.Alignment
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.graphics.ColorFilter
|
|
||||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import cafe.adriel.voyager.core.screen.Screen
|
|
||||||
import cafe.adriel.voyager.koin.getScreenModel
|
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.PostLayout
|
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Spacing
|
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.FloatingActionButtonMenu
|
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.FloatingActionButtonMenuItem
|
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.SectionSelector
|
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.detailopener.api.getDetailOpener
|
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.lemmyui.CommentCard
|
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.lemmyui.Option
|
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.lemmyui.OptionId
|
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.lemmyui.PostCard
|
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.lemmyui.di.getFabNestedScrollConnection
|
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.modals.ShareBottomSheet
|
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.modals.SortBottomSheet
|
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.core.l10n.LocalXmlStrings
|
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.core.navigation.di.getNavigationCoordinator
|
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.core.persistence.di.getSettingsRepository
|
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.compose.onClick
|
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.compose.rememberCallback
|
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.compose.rememberCallbackArgs
|
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.CommentModel
|
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.PostModel
|
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.readableHandle
|
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.toIcon
|
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.toInt
|
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.unit.createreport.CreateReportScreen
|
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.unit.rawcontent.RawContentDialog
|
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.unit.web.WebViewScreen
|
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.unit.zoomableimage.ZoomableImageScreen
|
|
||||||
import kotlinx.coroutines.flow.launchIn
|
|
||||||
import kotlinx.coroutines.flow.onEach
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
|
|
||||||
class SavedItemsScreen : Screen {
|
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterialApi::class, ExperimentalMaterial3Api::class)
|
|
||||||
@Composable
|
|
||||||
override fun Content() {
|
|
||||||
val model = getScreenModel<SavedItemsMviModel>()
|
|
||||||
val uiState by model.uiState.collectAsState()
|
|
||||||
val navigatorCoordinator = remember { getNavigationCoordinator() }
|
|
||||||
val topAppBarState = rememberTopAppBarState()
|
|
||||||
val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior(topAppBarState)
|
|
||||||
val lazyListState = rememberLazyListState()
|
|
||||||
val scope = rememberCoroutineScope()
|
|
||||||
val fabNestedScrollConnection = remember { getFabNestedScrollConnection() }
|
|
||||||
val isFabVisible by fabNestedScrollConnection.isFabVisible.collectAsState()
|
|
||||||
var rawContent by remember { mutableStateOf<Any?>(null) }
|
|
||||||
val settingsRepository = remember { getSettingsRepository() }
|
|
||||||
val settings by settingsRepository.currentSettings.collectAsState()
|
|
||||||
val navigationCoordinator = remember { getNavigationCoordinator() }
|
|
||||||
val detailOpener = remember { getDetailOpener() }
|
|
||||||
val snackbarHostState = remember { SnackbarHostState() }
|
|
||||||
|
|
||||||
LaunchedEffect(navigationCoordinator) {
|
|
||||||
navigationCoordinator.globalMessage.onEach { message ->
|
|
||||||
snackbarHostState.showSnackbar(
|
|
||||||
message = message,
|
|
||||||
)
|
|
||||||
}.launchIn(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
Scaffold(
|
|
||||||
modifier = Modifier.background(MaterialTheme.colorScheme.background),
|
|
||||||
topBar = {
|
|
||||||
TopAppBar(
|
|
||||||
scrollBehavior = scrollBehavior,
|
|
||||||
title = {
|
|
||||||
Text(
|
|
||||||
modifier = Modifier.padding(horizontal = Spacing.s),
|
|
||||||
text = LocalXmlStrings.current.navigationDrawerTitleBookmarks,
|
|
||||||
style = MaterialTheme.typography.titleMedium,
|
|
||||||
)
|
|
||||||
},
|
|
||||||
actions = {
|
|
||||||
Image(
|
|
||||||
modifier = Modifier
|
|
||||||
.padding(horizontal = Spacing.xs)
|
|
||||||
.onClick(
|
|
||||||
onClick = {
|
|
||||||
val sheet = SortBottomSheet(
|
|
||||||
values = uiState.availableSortTypes.map { it.toInt() },
|
|
||||||
screenKey = "savedItems",
|
|
||||||
)
|
|
||||||
navigatorCoordinator.showBottomSheet(sheet)
|
|
||||||
},
|
|
||||||
),
|
|
||||||
imageVector = uiState.sortType.toIcon(),
|
|
||||||
contentDescription = null,
|
|
||||||
colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.onBackground),
|
|
||||||
)
|
|
||||||
},
|
|
||||||
navigationIcon = {
|
|
||||||
Image(
|
|
||||||
modifier = Modifier.onClick(
|
|
||||||
onClick = {
|
|
||||||
navigatorCoordinator.popScreen()
|
|
||||||
},
|
|
||||||
),
|
|
||||||
imageVector = Icons.AutoMirrored.Default.ArrowBack,
|
|
||||||
contentDescription = null,
|
|
||||||
colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.onBackground),
|
|
||||||
)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
},
|
|
||||||
floatingActionButton = {
|
|
||||||
AnimatedVisibility(
|
|
||||||
visible = isFabVisible,
|
|
||||||
enter = slideInVertically(
|
|
||||||
initialOffsetY = { it * 2 },
|
|
||||||
),
|
|
||||||
exit = slideOutVertically(
|
|
||||||
targetOffsetY = { it * 2 },
|
|
||||||
),
|
|
||||||
) {
|
|
||||||
FloatingActionButtonMenu(
|
|
||||||
items = buildList {
|
|
||||||
this += FloatingActionButtonMenuItem(
|
|
||||||
icon = Icons.Default.ExpandLess,
|
|
||||||
text = LocalXmlStrings.current.actionBackToTop,
|
|
||||||
onSelected = rememberCallback {
|
|
||||||
scope.launch {
|
|
||||||
runCatching {
|
|
||||||
lazyListState.scrollToItem(0)
|
|
||||||
topAppBarState.heightOffset = 0f
|
|
||||||
topAppBarState.contentOffset = 0f
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
snackbarHost = {
|
|
||||||
SnackbarHost(snackbarHostState) { data ->
|
|
||||||
Snackbar(
|
|
||||||
containerColor = MaterialTheme.colorScheme.surfaceVariant,
|
|
||||||
contentColor = MaterialTheme.colorScheme.onSurfaceVariant,
|
|
||||||
snackbarData = data,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
) { paddingValues ->
|
|
||||||
Column(
|
|
||||||
modifier = Modifier
|
|
||||||
.padding(paddingValues)
|
|
||||||
.then(
|
|
||||||
if (settings.hideNavigationBarWhileScrolling) {
|
|
||||||
Modifier.nestedScroll(scrollBehavior.nestedScrollConnection)
|
|
||||||
} else {
|
|
||||||
Modifier
|
|
||||||
}
|
|
||||||
).nestedScroll(fabNestedScrollConnection),
|
|
||||||
verticalArrangement = Arrangement.spacedBy(Spacing.s),
|
|
||||||
) {
|
|
||||||
SectionSelector(
|
|
||||||
titles = listOf(
|
|
||||||
LocalXmlStrings.current.profileSectionPosts,
|
|
||||||
LocalXmlStrings.current.profileSectionComments,
|
|
||||||
),
|
|
||||||
currentSection = when (uiState.section) {
|
|
||||||
SavedItemsSection.Comments -> 1
|
|
||||||
else -> 0
|
|
||||||
},
|
|
||||||
onSectionSelected = {
|
|
||||||
val section = when (it) {
|
|
||||||
1 -> SavedItemsSection.Comments
|
|
||||||
else -> SavedItemsSection.Posts
|
|
||||||
}
|
|
||||||
model.reduce(SavedItemsMviModel.Intent.ChangeSection(section))
|
|
||||||
},
|
|
||||||
)
|
|
||||||
val pullRefreshState = rememberPullRefreshState(
|
|
||||||
refreshing = uiState.refreshing,
|
|
||||||
onRefresh = rememberCallback(model) {
|
|
||||||
model.reduce(SavedItemsMviModel.Intent.Refresh)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
Box(
|
|
||||||
modifier = Modifier.fillMaxWidth().pullRefresh(pullRefreshState),
|
|
||||||
) {
|
|
||||||
LazyColumn(
|
|
||||||
modifier = Modifier.fillMaxSize(),
|
|
||||||
state = lazyListState,
|
|
||||||
) {
|
|
||||||
if (uiState.section == SavedItemsSection.Posts) {
|
|
||||||
items(uiState.posts) { post ->
|
|
||||||
PostCard(
|
|
||||||
post = post,
|
|
||||||
postLayout = uiState.postLayout,
|
|
||||||
limitBodyHeight = true,
|
|
||||||
fullHeightImage = uiState.fullHeightImages,
|
|
||||||
fullWidthImage = uiState.fullWidthImages,
|
|
||||||
voteFormat = uiState.voteFormat,
|
|
||||||
autoLoadImages = uiState.autoLoadImages,
|
|
||||||
preferNicknames = uiState.preferNicknames,
|
|
||||||
showScores = uiState.showScores,
|
|
||||||
blurNsfw = uiState.blurNsfw,
|
|
||||||
onClick = {
|
|
||||||
model.reduce(SavedItemsMviModel.Intent.WillOpenSave)
|
|
||||||
detailOpener.openPostDetail(post)
|
|
||||||
},
|
|
||||||
onOpenCommunity = rememberCallbackArgs { community, instance ->
|
|
||||||
detailOpener.openCommunityDetail(community, instance)
|
|
||||||
},
|
|
||||||
onOpenCreator = rememberCallbackArgs { u, instance ->
|
|
||||||
if (u.id != uiState.user?.id) {
|
|
||||||
detailOpener.openUserDetail(u, instance)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onOpenPost = rememberCallbackArgs { p, instance ->
|
|
||||||
detailOpener.openPostDetail(p, instance)
|
|
||||||
},
|
|
||||||
onOpenWeb = rememberCallbackArgs { url ->
|
|
||||||
navigationCoordinator.pushScreen(
|
|
||||||
WebViewScreen(url)
|
|
||||||
)
|
|
||||||
},
|
|
||||||
onUpVote = rememberCallback(model) {
|
|
||||||
model.reduce(
|
|
||||||
SavedItemsMviModel.Intent.UpVotePost(
|
|
||||||
id = post.id,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
},
|
|
||||||
onDownVote = rememberCallback(model) {
|
|
||||||
model.reduce(
|
|
||||||
SavedItemsMviModel.Intent.DownVotePost(
|
|
||||||
id = post.id,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
},
|
|
||||||
onSave = rememberCallback(model) {
|
|
||||||
model.reduce(
|
|
||||||
SavedItemsMviModel.Intent.SavePost(
|
|
||||||
id = post.id,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
},
|
|
||||||
onReply = rememberCallback {
|
|
||||||
model.reduce(SavedItemsMviModel.Intent.WillOpenSave)
|
|
||||||
detailOpener.openPostDetail(post)
|
|
||||||
},
|
|
||||||
onOpenImage = rememberCallbackArgs { url ->
|
|
||||||
navigatorCoordinator.pushScreen(
|
|
||||||
ZoomableImageScreen(
|
|
||||||
url = url,
|
|
||||||
source = post.community?.readableHandle.orEmpty(),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
},
|
|
||||||
options = buildList {
|
|
||||||
add(
|
|
||||||
Option(
|
|
||||||
OptionId.Share,
|
|
||||||
LocalXmlStrings.current.postActionShare
|
|
||||||
)
|
|
||||||
)
|
|
||||||
add(
|
|
||||||
Option(
|
|
||||||
OptionId.SeeRaw,
|
|
||||||
LocalXmlStrings.current.postActionSeeRaw
|
|
||||||
)
|
|
||||||
)
|
|
||||||
add(
|
|
||||||
Option(
|
|
||||||
OptionId.Report,
|
|
||||||
LocalXmlStrings.current.postActionReport
|
|
||||||
)
|
|
||||||
)
|
|
||||||
},
|
|
||||||
onOptionSelected = { optionIndex ->
|
|
||||||
when (optionIndex) {
|
|
||||||
OptionId.Report -> {
|
|
||||||
navigatorCoordinator.pushScreen(
|
|
||||||
CreateReportScreen(postId = post.id),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
OptionId.SeeRaw -> {
|
|
||||||
rawContent = post
|
|
||||||
}
|
|
||||||
|
|
||||||
OptionId.Share -> {
|
|
||||||
val urls = listOfNotNull(
|
|
||||||
post.originalUrl,
|
|
||||||
"https://${uiState.instance}/post/${post.id}"
|
|
||||||
).distinct()
|
|
||||||
if (urls.size == 1) {
|
|
||||||
model.reduce(
|
|
||||||
SavedItemsMviModel.Intent.Share(
|
|
||||||
urls.first()
|
|
||||||
)
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
val screen = ShareBottomSheet(urls = urls)
|
|
||||||
navigationCoordinator.showBottomSheet(screen)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
else -> Unit
|
|
||||||
}
|
|
||||||
},
|
|
||||||
)
|
|
||||||
if (uiState.postLayout != PostLayout.Card) {
|
|
||||||
HorizontalDivider(modifier = Modifier.padding(vertical = Spacing.interItem))
|
|
||||||
} else {
|
|
||||||
Spacer(modifier = Modifier.height(Spacing.interItem))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (uiState.posts.isEmpty() && !uiState.loading) {
|
|
||||||
item {
|
|
||||||
Text(
|
|
||||||
modifier = Modifier.fillMaxWidth().padding(top = Spacing.xs),
|
|
||||||
textAlign = TextAlign.Center,
|
|
||||||
text = LocalXmlStrings.current.messageEmptyList,
|
|
||||||
style = MaterialTheme.typography.bodyLarge,
|
|
||||||
color = MaterialTheme.colorScheme.onBackground,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
items(uiState.comments) { comment ->
|
|
||||||
CommentCard(
|
|
||||||
comment = comment,
|
|
||||||
voteFormat = uiState.voteFormat,
|
|
||||||
autoLoadImages = uiState.autoLoadImages,
|
|
||||||
preferNicknames = uiState.preferNicknames,
|
|
||||||
showScores = uiState.showScores,
|
|
||||||
showBot = true,
|
|
||||||
indentAmount = 0,
|
|
||||||
onClick = {
|
|
||||||
detailOpener.openPostDetail(
|
|
||||||
post = PostModel(id = comment.postId),
|
|
||||||
highlightCommentId = comment.id,
|
|
||||||
)
|
|
||||||
},
|
|
||||||
onImageClick = rememberCallbackArgs { url ->
|
|
||||||
navigationCoordinator.pushScreen(
|
|
||||||
ZoomableImageScreen(
|
|
||||||
url = url,
|
|
||||||
source = comment.community?.readableHandle.orEmpty(),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
},
|
|
||||||
onUpVote = {
|
|
||||||
model.reduce(
|
|
||||||
SavedItemsMviModel.Intent.UpVoteComment(
|
|
||||||
id = comment.id,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
},
|
|
||||||
onDownVote = {
|
|
||||||
model.reduce(
|
|
||||||
SavedItemsMviModel.Intent.DownVoteComment(
|
|
||||||
id = comment.id,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
},
|
|
||||||
onSave = {
|
|
||||||
model.reduce(
|
|
||||||
SavedItemsMviModel.Intent.SaveComment(
|
|
||||||
id = comment.id,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
},
|
|
||||||
onReply = {
|
|
||||||
detailOpener.openReply(
|
|
||||||
originalPost = PostModel(id = comment.postId),
|
|
||||||
originalComment = comment,
|
|
||||||
)
|
|
||||||
|
|
||||||
},
|
|
||||||
options = buildList {
|
|
||||||
add(
|
|
||||||
Option(
|
|
||||||
OptionId.SeeRaw,
|
|
||||||
LocalXmlStrings.current.postActionSeeRaw
|
|
||||||
)
|
|
||||||
)
|
|
||||||
add(
|
|
||||||
Option(
|
|
||||||
OptionId.Report,
|
|
||||||
LocalXmlStrings.current.postActionReport
|
|
||||||
)
|
|
||||||
)
|
|
||||||
},
|
|
||||||
onOptionSelected = { optionIndex ->
|
|
||||||
when (optionIndex) {
|
|
||||||
OptionId.Report -> {
|
|
||||||
navigatorCoordinator.pushScreen(
|
|
||||||
CreateReportScreen(commentId = comment.id),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
OptionId.SeeRaw -> {
|
|
||||||
rawContent = comment
|
|
||||||
}
|
|
||||||
|
|
||||||
else -> Unit
|
|
||||||
}
|
|
||||||
},
|
|
||||||
)
|
|
||||||
HorizontalDivider(
|
|
||||||
modifier = Modifier.padding(vertical = Spacing.xxxs),
|
|
||||||
thickness = 0.25.dp
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (uiState.comments.isEmpty() && !uiState.loading) {
|
|
||||||
item {
|
|
||||||
Text(
|
|
||||||
modifier = Modifier.fillMaxWidth().padding(top = Spacing.xs),
|
|
||||||
textAlign = TextAlign.Center,
|
|
||||||
text = LocalXmlStrings.current.messageEmptyList,
|
|
||||||
style = MaterialTheme.typography.bodyLarge,
|
|
||||||
color = MaterialTheme.colorScheme.onBackground,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
item {
|
|
||||||
if (!uiState.loading && !uiState.refreshing && uiState.canFetchMore) {
|
|
||||||
model.reduce(SavedItemsMviModel.Intent.LoadNextPage)
|
|
||||||
}
|
|
||||||
if (uiState.loading && !uiState.refreshing) {
|
|
||||||
Box(
|
|
||||||
modifier = Modifier.fillMaxWidth().padding(Spacing.xs),
|
|
||||||
contentAlignment = Alignment.Center,
|
|
||||||
) {
|
|
||||||
CircularProgressIndicator(
|
|
||||||
modifier = Modifier.size(25.dp),
|
|
||||||
color = MaterialTheme.colorScheme.primary,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PullRefreshIndicator(
|
|
||||||
refreshing = uiState.refreshing,
|
|
||||||
state = pullRefreshState,
|
|
||||||
modifier = Modifier.align(Alignment.TopCenter),
|
|
||||||
backgroundColor = MaterialTheme.colorScheme.background,
|
|
||||||
contentColor = MaterialTheme.colorScheme.onBackground,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rawContent != null) {
|
|
||||||
when (val content = rawContent) {
|
|
||||||
is PostModel -> {
|
|
||||||
RawContentDialog(
|
|
||||||
title = content.title,
|
|
||||||
publishDate = content.publishDate,
|
|
||||||
updateDate = content.updateDate,
|
|
||||||
url = content.url,
|
|
||||||
text = content.text,
|
|
||||||
upVotes = content.upvotes,
|
|
||||||
downVotes = content.downvotes,
|
|
||||||
onDismiss = rememberCallback {
|
|
||||||
rawContent = null
|
|
||||||
},
|
|
||||||
onQuote = rememberCallbackArgs { quotation ->
|
|
||||||
rawContent = null
|
|
||||||
if (quotation != null) {
|
|
||||||
detailOpener.openReply(
|
|
||||||
originalPost = content,
|
|
||||||
initialText = buildString {
|
|
||||||
append("> ")
|
|
||||||
append(quotation)
|
|
||||||
append("\n\n")
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
is CommentModel -> {
|
|
||||||
RawContentDialog(
|
|
||||||
text = content.text,
|
|
||||||
publishDate = content.publishDate,
|
|
||||||
updateDate = content.updateDate,
|
|
||||||
upVotes = content.upvotes,
|
|
||||||
downVotes = content.downvotes,
|
|
||||||
onDismiss = {
|
|
||||||
rawContent = null
|
|
||||||
},
|
|
||||||
onQuote = rememberCallbackArgs { quotation ->
|
|
||||||
rawContent = null
|
|
||||||
if (quotation != null) {
|
|
||||||
detailOpener.openReply(
|
|
||||||
originalComment = content,
|
|
||||||
initialText = buildString {
|
|
||||||
append("> ")
|
|
||||||
append(quotation)
|
|
||||||
append("\n\n")
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
package com.github.diegoberaldin.raccoonforlemmy.unit.saveditems
|
|
||||||
|
|
||||||
sealed interface SavedItemsSection {
|
|
||||||
data object Posts : SavedItemsSection
|
|
||||||
|
|
||||||
data object Comments : SavedItemsSection
|
|
||||||
}
|
|
@ -1,406 +0,0 @@
|
|||||||
package com.github.diegoberaldin.raccoonforlemmy.unit.saveditems
|
|
||||||
|
|
||||||
import cafe.adriel.voyager.core.model.screenModelScope
|
|
||||||
import com.diegoberaldin.raccoonforlemmy.domain.lemmy.pagination.CommentPaginationManager
|
|
||||||
import com.diegoberaldin.raccoonforlemmy.domain.lemmy.pagination.CommentPaginationSpecification
|
|
||||||
import com.diegoberaldin.raccoonforlemmy.domain.lemmy.pagination.PostNavigationManager
|
|
||||||
import com.diegoberaldin.raccoonforlemmy.domain.lemmy.pagination.PostPaginationManager
|
|
||||||
import com.diegoberaldin.raccoonforlemmy.domain.lemmy.pagination.PostPaginationSpecification
|
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.repository.ThemeRepository
|
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.DefaultMviModel
|
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.NotificationCenter
|
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.NotificationCenterEvent
|
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.core.persistence.repository.SettingsRepository
|
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.share.ShareHelper
|
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.vibrate.HapticFeedback
|
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.domain.identity.repository.ApiConfigurationRepository
|
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.domain.identity.repository.IdentityRepository
|
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.CommentModel
|
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.PostModel
|
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.SortType
|
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.CommentRepository
|
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.GetSortTypesUseCase
|
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.PostRepository
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.IO
|
|
||||||
import kotlinx.coroutines.delay
|
|
||||||
import kotlinx.coroutines.flow.launchIn
|
|
||||||
import kotlinx.coroutines.flow.onEach
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
|
|
||||||
class SavedItemsViewModel(
|
|
||||||
private val identityRepository: IdentityRepository,
|
|
||||||
private val apiConfigurationRepository: ApiConfigurationRepository,
|
|
||||||
private val postPaginationManager: PostPaginationManager,
|
|
||||||
private val commentPaginationManager: CommentPaginationManager,
|
|
||||||
private val postRepository: PostRepository,
|
|
||||||
private val commentRepository: CommentRepository,
|
|
||||||
private val themeRepository: ThemeRepository,
|
|
||||||
private val settingsRepository: SettingsRepository,
|
|
||||||
private val shareHelper: ShareHelper,
|
|
||||||
private val notificationCenter: NotificationCenter,
|
|
||||||
private val hapticFeedback: HapticFeedback,
|
|
||||||
private val getSortTypesUseCase: GetSortTypesUseCase,
|
|
||||||
private val postNavigationManager: PostNavigationManager,
|
|
||||||
) : SavedItemsMviModel,
|
|
||||||
DefaultMviModel<SavedItemsMviModel.Intent, SavedItemsMviModel.UiState, SavedItemsMviModel.Effect>(
|
|
||||||
initialState = SavedItemsMviModel.UiState(),
|
|
||||||
) {
|
|
||||||
|
|
||||||
init {
|
|
||||||
updateState { it.copy(instance = apiConfigurationRepository.instance.value) }
|
|
||||||
screenModelScope.launch {
|
|
||||||
themeRepository.postLayout.onEach { layout ->
|
|
||||||
updateState { it.copy(postLayout = layout) }
|
|
||||||
}.launchIn(this)
|
|
||||||
settingsRepository.currentSettings.onEach { settings ->
|
|
||||||
updateState {
|
|
||||||
it.copy(
|
|
||||||
voteFormat = settings.voteFormat,
|
|
||||||
autoLoadImages = settings.autoLoadImages,
|
|
||||||
preferNicknames = settings.preferUserNicknames,
|
|
||||||
fullHeightImages = settings.fullHeightImages,
|
|
||||||
fullWidthImages = settings.fullWidthImages,
|
|
||||||
showScores = settings.showScores,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}.launchIn(this)
|
|
||||||
notificationCenter.subscribe(NotificationCenterEvent.PostUpdated::class).onEach { evt ->
|
|
||||||
handlePostUpdate(evt.model)
|
|
||||||
}.launchIn(this)
|
|
||||||
notificationCenter.subscribe(NotificationCenterEvent.PostDeleted::class).onEach { evt ->
|
|
||||||
handlePostDelete(evt.model.id)
|
|
||||||
}.launchIn(this)
|
|
||||||
notificationCenter.subscribe(NotificationCenterEvent.ChangeSortType::class)
|
|
||||||
.onEach { evt ->
|
|
||||||
if (evt.screenKey == "savedItems") {
|
|
||||||
applySortType(evt.value)
|
|
||||||
}
|
|
||||||
}.launchIn(this)
|
|
||||||
notificationCenter.subscribe(NotificationCenterEvent.Share::class).onEach { evt ->
|
|
||||||
shareHelper.share(evt.url)
|
|
||||||
}.launchIn(this)
|
|
||||||
|
|
||||||
if (uiState.value.posts.isEmpty()) {
|
|
||||||
val sortTypes = getSortTypesUseCase.getTypesForSavedItems()
|
|
||||||
updateState { it.copy(availableSortTypes = sortTypes) }
|
|
||||||
refresh()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun reduce(intent: SavedItemsMviModel.Intent) {
|
|
||||||
when (intent) {
|
|
||||||
SavedItemsMviModel.Intent.LoadNextPage -> screenModelScope.launch {
|
|
||||||
loadNextPage()
|
|
||||||
}
|
|
||||||
|
|
||||||
SavedItemsMviModel.Intent.Refresh -> screenModelScope.launch {
|
|
||||||
refresh()
|
|
||||||
}
|
|
||||||
|
|
||||||
is SavedItemsMviModel.Intent.ChangeSection -> changeSection(intent.section)
|
|
||||||
is SavedItemsMviModel.Intent.DownVoteComment -> {
|
|
||||||
if (intent.feedback) {
|
|
||||||
hapticFeedback.vibrate()
|
|
||||||
}
|
|
||||||
toggleDownVoteComment(
|
|
||||||
comment = uiState.value.comments.first { it.id == intent.id },
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
is SavedItemsMviModel.Intent.DownVotePost -> {
|
|
||||||
if (intent.feedback) {
|
|
||||||
hapticFeedback.vibrate()
|
|
||||||
}
|
|
||||||
toggleDownVotePost(
|
|
||||||
post = uiState.value.posts.first { it.id == intent.id },
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
is SavedItemsMviModel.Intent.SaveComment -> {
|
|
||||||
if (intent.feedback) {
|
|
||||||
hapticFeedback.vibrate()
|
|
||||||
}
|
|
||||||
toggleSaveComment(
|
|
||||||
comment = uiState.value.comments.first { it.id == intent.id },
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
is SavedItemsMviModel.Intent.SavePost -> {
|
|
||||||
if (intent.feedback) {
|
|
||||||
hapticFeedback.vibrate()
|
|
||||||
}
|
|
||||||
toggleSavePost(
|
|
||||||
post = uiState.value.posts.first { it.id == intent.id },
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
is SavedItemsMviModel.Intent.Share -> {
|
|
||||||
shareHelper.share(intent.url)
|
|
||||||
}
|
|
||||||
|
|
||||||
is SavedItemsMviModel.Intent.UpVoteComment -> {
|
|
||||||
if (intent.feedback) {
|
|
||||||
hapticFeedback.vibrate()
|
|
||||||
}
|
|
||||||
toggleUpVoteComment(
|
|
||||||
comment = uiState.value.comments.first { it.id == intent.id },
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
is SavedItemsMviModel.Intent.UpVotePost -> {
|
|
||||||
if (intent.feedback) {
|
|
||||||
hapticFeedback.vibrate()
|
|
||||||
}
|
|
||||||
toggleUpVotePost(
|
|
||||||
post = uiState.value.posts.first { it.id == intent.id },
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
SavedItemsMviModel.Intent.WillOpenSave -> {
|
|
||||||
val state = postPaginationManager.extractState()
|
|
||||||
postNavigationManager.push(state)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private suspend fun refresh() {
|
|
||||||
postPaginationManager.reset(
|
|
||||||
PostPaginationSpecification.Saved(sortType = uiState.value.sortType)
|
|
||||||
)
|
|
||||||
commentPaginationManager.reset(
|
|
||||||
CommentPaginationSpecification.Saved(sortType = uiState.value.sortType)
|
|
||||||
)
|
|
||||||
updateState {
|
|
||||||
it.copy(
|
|
||||||
canFetchMore = true,
|
|
||||||
refreshing = true,
|
|
||||||
loading = false,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
loadNextPage()
|
|
||||||
}
|
|
||||||
|
|
||||||
private suspend fun loadNextPage() {
|
|
||||||
val currentState = uiState.value
|
|
||||||
if (!currentState.canFetchMore || currentState.loading) {
|
|
||||||
updateState { it.copy(refreshing = false) }
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
updateState { it.copy(loading = true) }
|
|
||||||
val section = currentState.section
|
|
||||||
if (section == SavedItemsSection.Posts) {
|
|
||||||
val posts = postPaginationManager.loadNextPage()
|
|
||||||
updateState {
|
|
||||||
it.copy(
|
|
||||||
posts = posts,
|
|
||||||
loading = false,
|
|
||||||
canFetchMore = postPaginationManager.canFetchMore,
|
|
||||||
refreshing = false,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
val comments = commentPaginationManager.loadNextPage()
|
|
||||||
updateState {
|
|
||||||
it.copy(
|
|
||||||
comments = comments,
|
|
||||||
loading = false,
|
|
||||||
canFetchMore = commentPaginationManager.canFetchMore,
|
|
||||||
refreshing = false,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun applySortType(value: SortType) {
|
|
||||||
if (uiState.value.sortType == value) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
updateState { it.copy(sortType = value) }
|
|
||||||
screenModelScope.launch {
|
|
||||||
emitEffect(SavedItemsMviModel.Effect.BackToTop)
|
|
||||||
delay(50)
|
|
||||||
refresh()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun handlePostUpdate(post: PostModel) {
|
|
||||||
updateState {
|
|
||||||
it.copy(
|
|
||||||
posts = it.posts.map { p ->
|
|
||||||
if (p.id == post.id) {
|
|
||||||
post
|
|
||||||
} else {
|
|
||||||
p
|
|
||||||
}
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun handleCommentUpdate(comment: CommentModel) {
|
|
||||||
updateState {
|
|
||||||
it.copy(
|
|
||||||
comments = it.comments.map { c ->
|
|
||||||
if (c.id == comment.id) {
|
|
||||||
comment
|
|
||||||
} else {
|
|
||||||
c
|
|
||||||
}
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun handlePostDelete(id: Long) {
|
|
||||||
updateState { it.copy(posts = it.posts.filter { post -> post.id != id }) }
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun changeSection(section: SavedItemsSection) {
|
|
||||||
updateState {
|
|
||||||
it.copy(
|
|
||||||
section = section,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun toggleUpVotePost(post: PostModel) {
|
|
||||||
val newValue = post.myVote <= 0
|
|
||||||
val newPost = postRepository.asUpVoted(
|
|
||||||
post = post,
|
|
||||||
voted = newValue,
|
|
||||||
)
|
|
||||||
handlePostUpdate(newPost)
|
|
||||||
screenModelScope.launch {
|
|
||||||
try {
|
|
||||||
val auth = identityRepository.authToken.value.orEmpty()
|
|
||||||
postRepository.upVote(
|
|
||||||
auth = auth,
|
|
||||||
post = post,
|
|
||||||
voted = newValue,
|
|
||||||
)
|
|
||||||
notificationCenter.send(
|
|
||||||
event = NotificationCenterEvent.PostUpdated(newPost),
|
|
||||||
)
|
|
||||||
} catch (e: Throwable) {
|
|
||||||
e.printStackTrace()
|
|
||||||
handlePostUpdate(post)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun toggleDownVotePost(post: PostModel) {
|
|
||||||
val newValue = post.myVote >= 0
|
|
||||||
val newPost = postRepository.asDownVoted(
|
|
||||||
post = post,
|
|
||||||
downVoted = newValue,
|
|
||||||
)
|
|
||||||
handlePostUpdate(newPost)
|
|
||||||
screenModelScope.launch(Dispatchers.IO) {
|
|
||||||
try {
|
|
||||||
val auth = identityRepository.authToken.value.orEmpty()
|
|
||||||
postRepository.downVote(
|
|
||||||
auth = auth,
|
|
||||||
post = post,
|
|
||||||
downVoted = newValue,
|
|
||||||
)
|
|
||||||
notificationCenter.send(
|
|
||||||
event = NotificationCenterEvent.PostUpdated(newPost),
|
|
||||||
)
|
|
||||||
} catch (e: Throwable) {
|
|
||||||
e.printStackTrace()
|
|
||||||
handlePostUpdate(post)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun toggleSavePost(post: PostModel) {
|
|
||||||
val newValue = !post.saved
|
|
||||||
val newPost = postRepository.asSaved(
|
|
||||||
post = post,
|
|
||||||
saved = newValue,
|
|
||||||
)
|
|
||||||
handlePostUpdate(newPost)
|
|
||||||
screenModelScope.launch(Dispatchers.IO) {
|
|
||||||
try {
|
|
||||||
val auth = identityRepository.authToken.value.orEmpty()
|
|
||||||
postRepository.save(
|
|
||||||
auth = auth,
|
|
||||||
post = post,
|
|
||||||
saved = newValue,
|
|
||||||
)
|
|
||||||
notificationCenter.send(
|
|
||||||
event = NotificationCenterEvent.PostUpdated(newPost),
|
|
||||||
)
|
|
||||||
} catch (e: Throwable) {
|
|
||||||
e.printStackTrace()
|
|
||||||
handlePostUpdate(post)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun toggleUpVoteComment(comment: CommentModel) {
|
|
||||||
val newValue = comment.myVote <= 0
|
|
||||||
val newComment = commentRepository.asUpVoted(
|
|
||||||
comment = comment,
|
|
||||||
voted = newValue,
|
|
||||||
)
|
|
||||||
handleCommentUpdate(newComment)
|
|
||||||
screenModelScope.launch(Dispatchers.IO) {
|
|
||||||
try {
|
|
||||||
val auth = identityRepository.authToken.value.orEmpty()
|
|
||||||
commentRepository.upVote(
|
|
||||||
auth = auth,
|
|
||||||
comment = comment,
|
|
||||||
voted = newValue,
|
|
||||||
)
|
|
||||||
} catch (e: Throwable) {
|
|
||||||
e.printStackTrace()
|
|
||||||
handleCommentUpdate(comment)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun toggleDownVoteComment(comment: CommentModel) {
|
|
||||||
val newValue = comment.myVote >= 0
|
|
||||||
val newComment = commentRepository.asDownVoted(comment, newValue)
|
|
||||||
handleCommentUpdate(newComment)
|
|
||||||
screenModelScope.launch(Dispatchers.IO) {
|
|
||||||
try {
|
|
||||||
val auth = identityRepository.authToken.value.orEmpty()
|
|
||||||
commentRepository.downVote(
|
|
||||||
auth = auth,
|
|
||||||
comment = comment,
|
|
||||||
downVoted = newValue,
|
|
||||||
)
|
|
||||||
} catch (e: Throwable) {
|
|
||||||
e.printStackTrace()
|
|
||||||
handleCommentUpdate(comment)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun toggleSaveComment(comment: CommentModel) {
|
|
||||||
val newValue = !comment.saved
|
|
||||||
val newComment = commentRepository.asSaved(
|
|
||||||
comment = comment,
|
|
||||||
saved = newValue,
|
|
||||||
)
|
|
||||||
handleCommentUpdate(newComment)
|
|
||||||
screenModelScope.launch(Dispatchers.IO) {
|
|
||||||
try {
|
|
||||||
val auth = identityRepository.authToken.value.orEmpty()
|
|
||||||
commentRepository.save(
|
|
||||||
auth = auth,
|
|
||||||
comment = comment,
|
|
||||||
saved = newValue,
|
|
||||||
)
|
|
||||||
} catch (e: Throwable) {
|
|
||||||
e.printStackTrace()
|
|
||||||
handleCommentUpdate(comment)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,25 +0,0 @@
|
|||||||
package com.github.diegoberaldin.raccoonforlemmy.unit.saveditems.di
|
|
||||||
|
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.unit.saveditems.SavedItemsMviModel
|
|
||||||
import com.github.diegoberaldin.raccoonforlemmy.unit.saveditems.SavedItemsViewModel
|
|
||||||
import org.koin.dsl.module
|
|
||||||
|
|
||||||
val savedItemsModule = module {
|
|
||||||
factory<SavedItemsMviModel> {
|
|
||||||
SavedItemsViewModel(
|
|
||||||
identityRepository = get(),
|
|
||||||
apiConfigurationRepository = get(),
|
|
||||||
postPaginationManager = get(),
|
|
||||||
commentPaginationManager = get(),
|
|
||||||
postRepository = get(),
|
|
||||||
commentRepository = get(),
|
|
||||||
themeRepository = get(),
|
|
||||||
settingsRepository = get(),
|
|
||||||
shareHelper = get(),
|
|
||||||
hapticFeedback = get(),
|
|
||||||
notificationCenter = get(),
|
|
||||||
getSortTypesUseCase = get(),
|
|
||||||
postNavigationManager = get(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user