Skip to content

Commit

Permalink
add possibility to edit tag membership in user detail
Browse files Browse the repository at this point in the history
  • Loading branch information
AkesiSeli committed Dec 29, 2024
1 parent c393c93 commit 29f7c82
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,6 @@ sealed class OptionId(
data object PurgeCreator : OptionId(29)

data object Restore : OptionId(30)

data object ManageTags : OptionId(31)
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import com.livefast.eattrash.raccoonforlemmy.core.appearance.data.VoteFormat
import com.livefast.eattrash.raccoonforlemmy.core.architecture.MviModel
import com.livefast.eattrash.raccoonforlemmy.core.commonui.lemmyui.UserDetailSection
import com.livefast.eattrash.raccoonforlemmy.core.persistence.data.ActionOnSwipe
import com.livefast.eattrash.raccoonforlemmy.core.persistence.data.UserTagModel
import com.livefast.eattrash.raccoonforlemmy.domain.lemmy.data.CommentModel
import com.livefast.eattrash.raccoonforlemmy.domain.lemmy.data.PostModel
import com.livefast.eattrash.raccoonforlemmy.domain.lemmy.data.SortType
Expand Down Expand Up @@ -66,6 +67,10 @@ interface UserDetailMviModel :
data object BlockInstance : Intent

data object WillOpenDetail : Intent

data class UpdateTags(
val ids: List<Long>,
) : Intent
}

data class UiState(
Expand Down Expand Up @@ -99,6 +104,8 @@ interface UserDetailMviModel :
val actionsOnSwipeToEndPosts: List<ActionOnSwipe> = emptyList(),
val actionsOnSwipeToStartComments: List<ActionOnSwipe> = emptyList(),
val actionsOnSwipeToEndComments: List<ActionOnSwipe> = emptyList(),
val currentUserTagIds: List<Long> = emptyList(),
val availableUserTags: List<UserTagModel> = emptyList(),
)

sealed interface Effect {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ import com.livefast.eattrash.raccoonforlemmy.core.commonui.lemmyui.PostCardPlace
import com.livefast.eattrash.raccoonforlemmy.core.commonui.lemmyui.UserDetailSection
import com.livefast.eattrash.raccoonforlemmy.core.commonui.lemmyui.UserHeader
import com.livefast.eattrash.raccoonforlemmy.core.commonui.lemmyui.di.getFabNestedScrollConnection
import com.livefast.eattrash.raccoonforlemmy.core.commonui.modals.AssignUserTagBottomSheet
import com.livefast.eattrash.raccoonforlemmy.core.commonui.modals.CustomModalBottomSheet
import com.livefast.eattrash.raccoonforlemmy.core.commonui.modals.CustomModalBottomSheetItem
import com.livefast.eattrash.raccoonforlemmy.core.commonui.modals.SortBottomSheet
Expand Down Expand Up @@ -170,6 +171,7 @@ class UserDetailScreen(
var shareBottomSheetUrls by remember { mutableStateOf<List<String>?>(null) }
var sortBottomSheetOpened by remember { mutableStateOf(false) }
var copyPostBottomSheet by remember { mutableStateOf<PostModel?>(null) }
var manageTagsBottomSheetOpened by remember { mutableStateOf(false) }

LaunchedEffect(model) {
model.effects
Expand Down Expand Up @@ -285,6 +287,13 @@ class UserDetailScreen(
LocalStrings.current.adminActionPurge,
)
}
if (uiState.isLogged) {
this +=
Option(
OptionId.ManageTags,
LocalStrings.current.userTagsTitle,
)
}
}
var optionsExpanded by remember { mutableStateOf(false) }
var optionsOffset by remember { mutableStateOf(Offset.Zero) }
Expand Down Expand Up @@ -363,6 +372,10 @@ class UserDetailScreen(
navigationCoordinator.pushScreen(screen)
}

OptionId.ManageTags -> {
manageTagsBottomSheetOpened = true
}

else -> Unit
}
},
Expand Down Expand Up @@ -1277,5 +1290,19 @@ class UserDetailScreen(
},
)
}

if (manageTagsBottomSheetOpened) {
AssignUserTagBottomSheet(
tags = uiState.availableUserTags,
initiallyCheckedIds = uiState.currentUserTagIds,
onDismiss = {
manageTagsBottomSheetOpened = false
},
onSelect = { ids ->
manageTagsBottomSheetOpened = false
model.reduce(UserDetailMviModel.Intent.UpdateTags(ids))
},
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ import com.livefast.eattrash.raccoonforlemmy.core.architecture.DefaultMviModel
import com.livefast.eattrash.raccoonforlemmy.core.commonui.lemmyui.UserDetailSection
import com.livefast.eattrash.raccoonforlemmy.core.notifications.NotificationCenter
import com.livefast.eattrash.raccoonforlemmy.core.notifications.NotificationCenterEvent
import com.livefast.eattrash.raccoonforlemmy.core.persistence.repository.AccountRepository
import com.livefast.eattrash.raccoonforlemmy.core.persistence.repository.SettingsRepository
import com.livefast.eattrash.raccoonforlemmy.core.persistence.repository.UserTagRepository
import com.livefast.eattrash.raccoonforlemmy.core.utils.imageload.ImagePreloadManager
import com.livefast.eattrash.raccoonforlemmy.core.utils.share.ShareHelper
import com.livefast.eattrash.raccoonforlemmy.core.utils.vibrate.HapticFeedback
Expand Down Expand Up @@ -56,6 +58,8 @@ class UserDetailViewModel(
private val shareHelper: ShareHelper,
private val hapticFeedback: HapticFeedback,
private val settingsRepository: SettingsRepository,
private val userTagRepository: UserTagRepository,
private val accountRepository: AccountRepository,
private val notificationCenter: NotificationCenter,
private val imagePreloadManager: ImagePreloadManager,
private val getSortTypesUseCase: GetSortTypesUseCase,
Expand All @@ -81,6 +85,15 @@ class UserDetailViewModel(
updateState {
it.copy(user = user)
}

val accountId = accountRepository.getActive()?.id
if (accountId != null) {
val allTags = userTagRepository.getAll(accountId)
updateState {
it.copy(availableUserTags = allTags)
}
}
refreshCurrentUserTags()
}
themeRepository.postLayout
.onEach { layout ->
Expand Down Expand Up @@ -258,6 +271,8 @@ class UserDetailViewModel(
val state = postPaginationManager.extractState()
postNavigationManager.push(state)
}

is UserDetailMviModel.Intent.UpdateTags -> updateTags(intent.ids)
}
}

Expand Down Expand Up @@ -596,4 +611,49 @@ class UserDetailViewModel(
}
}
}

private suspend fun refreshCurrentUserTags() {
val accountId = accountRepository.getActive()?.id ?: return
val user = uiState.value.user
val currentTags =
userTagRepository.getBelonging(
accountId = accountId,
username = user.readableHandle,
)
updateState {
it.copy(
currentUserTagIds = currentTags.mapNotNull { tag -> tag.id },
)
}
}

private fun updateTags(ids: List<Long>) {
screenModelScope.launch {
val accountId = accountRepository.getActive()?.id ?: return@launch
val username = uiState.value.user.readableHandle
val currentTagIds =
userTagRepository
.getTags(
username = username,
accountId = accountId,
).mapNotNull { it.id }

val idsToRemove = currentTagIds.filter { it !in ids }
for (id in idsToRemove) {
userTagRepository.removeMember(
username = username,
userTagId = id,
)
}

val idsToAdd = ids.filter { it !in currentTagIds }
for (id in idsToAdd) {
userTagRepository.addMember(
username = username,
userTagId = id,
)
}
refreshCurrentUserTags()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ val userDetailModule =
shareHelper = instance(),
hapticFeedback = instance(),
settingsRepository = instance(),
userTagRepository = instance(),
accountRepository = instance(),
notificationCenter = instance(),
imagePreloadManager = instance(),
getSortTypesUseCase = instance(),
Expand Down

0 comments on commit 29f7c82

Please # to comment.