From 890ee337a47adcf1b88fd514ad5075d5837c272b Mon Sep 17 00:00:00 2001 From: Ash Date: Thu, 7 Apr 2022 03:12:18 +0800 Subject: [PATCH] Add move all feeds to target Group feature --- .../java/me/ash/reader/data/dao/FeedDao.kt | 13 +++ .../data/repository/AbstractRssRepository.kt | 4 + .../home/drawer/group/AllMoveToGroupDialog.kt | 83 +++++++++++++++++++ .../home/drawer/group/GroupOptionDrawer.kt | 53 ++++++++++-- .../home/drawer/group/GroupOptionViewModel.kt | 43 ++++++++++ app/src/main/res/values-zh-rCN/strings.xml | 3 + app/src/main/res/values/strings.xml | 3 + 7 files changed, 195 insertions(+), 7 deletions(-) create mode 100644 app/src/main/java/me/ash/reader/ui/page/home/drawer/group/AllMoveToGroupDialog.kt diff --git a/app/src/main/java/me/ash/reader/data/dao/FeedDao.kt b/app/src/main/java/me/ash/reader/data/dao/FeedDao.kt index 80396a3..14b35fa 100644 --- a/app/src/main/java/me/ash/reader/data/dao/FeedDao.kt +++ b/app/src/main/java/me/ash/reader/data/dao/FeedDao.kt @@ -5,6 +5,19 @@ import me.ash.reader.data.entity.Feed @Dao interface FeedDao { + @Query( + """ + UPDATE feed SET groupId = :targetGroupId + WHERE groupId = :groupId + AND accountId = :accountId + """ + ) + suspend fun updateTargetGroupIdByGroupId( + accountId: Int, + groupId: String, + targetGroupId: String + ) + @Query( """ UPDATE feed SET isFullContent = :isFullContent diff --git a/app/src/main/java/me/ash/reader/data/repository/AbstractRssRepository.kt b/app/src/main/java/me/ash/reader/data/repository/AbstractRssRepository.kt index d568c54..6052dd8 100644 --- a/app/src/main/java/me/ash/reader/data/repository/AbstractRssRepository.kt +++ b/app/src/main/java/me/ash/reader/data/repository/AbstractRssRepository.kt @@ -154,6 +154,10 @@ abstract class AbstractRssRepository constructor( suspend fun groupAllowNotification(group: Group, isNotification: Boolean) { feedDao.updateIsNotificationByGroupId(context.currentAccountId, group.id, isNotification) } + + suspend fun groupMoveToTargetGroup(group: Group, targetGroup: Group) { + feedDao.updateTargetGroupIdByGroupId(context.currentAccountId, group.id, targetGroup.id) + } } @HiltWorker diff --git a/app/src/main/java/me/ash/reader/ui/page/home/drawer/group/AllMoveToGroupDialog.kt b/app/src/main/java/me/ash/reader/ui/page/home/drawer/group/AllMoveToGroupDialog.kt new file mode 100644 index 0000000..4465184 --- /dev/null +++ b/app/src/main/java/me/ash/reader/ui/page/home/drawer/group/AllMoveToGroupDialog.kt @@ -0,0 +1,83 @@ +package me.ash.reader.ui.page.home.drawer.group + +import android.widget.Toast +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.outlined.DriveFileMove +import androidx.compose.material3.Icon +import androidx.compose.material3.Text +import androidx.compose.material3.TextButton +import androidx.compose.runtime.Composable +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.stringResource +import androidx.hilt.navigation.compose.hiltViewModel +import com.google.accompanist.pager.ExperimentalPagerApi +import me.ash.reader.R +import me.ash.reader.ui.component.Dialog +import me.ash.reader.ui.ext.collectAsStateValue + +@OptIn(ExperimentalPagerApi::class) +@Composable +fun AllMoveToGroupDialog( + modifier: Modifier = Modifier, + groupName: String, + viewModel: GroupOptionViewModel = hiltViewModel(), +) { + val context = LocalContext.current + val viewState = viewModel.viewState.collectAsStateValue() + val scope = rememberCoroutineScope() + val toastString = + stringResource(R.string.all_move_to_group_toast, viewState.targetGroup?.name ?: "") + + Dialog( + visible = viewState.allMoveToGroupDialogVisible, + onDismissRequest = { + viewModel.dispatch(GroupOptionViewAction.HideAllMoveToGroupDialog) + }, + icon = { + Icon( + imageVector = Icons.Outlined.DriveFileMove, + contentDescription = stringResource(R.string.move_to_group), + ) + }, + title = { + Text(text = stringResource(R.string.move_to_group)) + }, + text = { + Text( + text = stringResource( + R.string.all_move_to_group_tip, + groupName, + viewState.targetGroup?.name ?: "", + ) + ) + }, + confirmButton = { + TextButton( + onClick = { + viewModel.dispatch(GroupOptionViewAction.AllMoveToGroup { + viewModel.dispatch(GroupOptionViewAction.HideAllMoveToGroupDialog) + viewModel.dispatch(GroupOptionViewAction.Hide(scope)) + Toast.makeText(context, toastString, Toast.LENGTH_SHORT).show() + }) + } + ) { + Text( + text = stringResource(R.string.confirm), + ) + } + }, + dismissButton = { + TextButton( + onClick = { + viewModel.dispatch(GroupOptionViewAction.HideAllMoveToGroupDialog) + } + ) { + Text( + text = stringResource(R.string.cancel), + ) + } + }, + ) +} \ No newline at end of file diff --git a/app/src/main/java/me/ash/reader/ui/page/home/drawer/group/GroupOptionDrawer.kt b/app/src/main/java/me/ash/reader/ui/page/home/drawer/group/GroupOptionDrawer.kt index 2db3335..e644141 100644 --- a/app/src/main/java/me/ash/reader/ui/page/home/drawer/group/GroupOptionDrawer.kt +++ b/app/src/main/java/me/ash/reader/ui/page/home/drawer/group/GroupOptionDrawer.kt @@ -2,6 +2,8 @@ package me.ash.reader.ui.page.home.drawer.group import androidx.compose.animation.animateContentSize import androidx.compose.foundation.layout.* +import androidx.compose.foundation.lazy.LazyRow +import androidx.compose.foundation.lazy.items import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.material.ExperimentalMaterialApi @@ -135,12 +137,48 @@ fun GroupOptionDrawer( } Spacer(modifier = Modifier.height(26.dp)) -// AddToGroup( -// groups = groups, -// selectedGroupId = selectedGroupId, -// onGroupClick = onGroupClick, -// onAddNewGroup = onAddNewGroup, -// ) + Subtitle(text = stringResource(R.string.move_to_group)) + Spacer(modifier = Modifier.height(10.dp)) + + if (viewState.groups.size > 6) { + LazyRow { + items(viewState.groups) { + if (it.id != group?.id) { + SelectionChip( + modifier = Modifier.animateContentSize(), + content = it.name, + selected = false, + ) { + GroupOptionViewModel.dispatch( + GroupOptionViewAction.ShowAllMoveToGroupDialog(it) + ) + } + } + Spacer(modifier = Modifier.width(10.dp)) + } + } + } else { + FlowRow( + mainAxisAlignment = MainAxisAlignment.Start, + crossAxisSpacing = 10.dp, + mainAxisSpacing = 10.dp, + ) { + viewState.groups.forEach { + if (it.id != group?.id) { + SelectionChip( + modifier = Modifier.animateContentSize(), + content = it.name, + selected = false, + ) { + GroupOptionViewModel.dispatch( + GroupOptionViewAction.ShowAllMoveToGroupDialog(it) + ) + } + } + } + } + } + Spacer(modifier = Modifier.height(6.dp)) } } @@ -152,4 +190,5 @@ fun GroupOptionDrawer( DeleteGroupDialog(groupName = group?.name ?: "") AllAllowNotificationDialog(groupName = group?.name ?: "") AllParseFullContentDialog(groupName = group?.name ?: "") -} \ No newline at end of file + AllMoveToGroupDialog(groupName = group?.name ?: "") +} diff --git a/app/src/main/java/me/ash/reader/ui/page/home/drawer/group/GroupOptionViewModel.kt b/app/src/main/java/me/ash/reader/ui/page/home/drawer/group/GroupOptionViewModel.kt index 84a815b..e625ee7 100644 --- a/app/src/main/java/me/ash/reader/ui/page/home/drawer/group/GroupOptionViewModel.kt +++ b/app/src/main/java/me/ash/reader/ui/page/home/drawer/group/GroupOptionViewModel.kt @@ -49,18 +49,27 @@ class GroupOptionViewModel @Inject constructor( is GroupOptionViewAction.ShowDeleteDialog -> changeDeleteDialogVisible(true) is GroupOptionViewAction.HideDeleteDialog -> changeDeleteDialogVisible(false) is GroupOptionViewAction.Delete -> delete(action.callback) + is GroupOptionViewAction.ShowAllAllowNotificationDialog -> changeAllAllowNotificationDialogVisible(true) is GroupOptionViewAction.HideAllAllowNotificationDialog -> changeAllAllowNotificationDialogVisible(false) is GroupOptionViewAction.AllAllowNotification -> allAllowNotification(action.isNotification, action.callback) + is GroupOptionViewAction.ShowAllParseFullContentDialog -> changeAllParseFullContentDialogVisible(true) is GroupOptionViewAction.HideAllParseFullContentDialog -> changeAllParseFullContentDialogVisible(false) is GroupOptionViewAction.AllParseFullContent -> allParseFullContent(action.isFullContent, action.callback) + + is GroupOptionViewAction.ShowAllMoveToGroupDialog -> + changeAllMoveToGroupDialogVisible(action.targetGroup, true) + is GroupOptionViewAction.HideAllMoveToGroupDialog -> + changeAllMoveToGroupDialogVisible(visible = false) + is GroupOptionViewAction.AllMoveToGroup -> + allMoveToGroup(action.callback) } } @@ -142,15 +151,39 @@ class GroupOptionViewModel @Inject constructor( ) } } + + private fun allMoveToGroup(callback: () -> Unit) { + _viewState.value.group?.let { group -> + _viewState.value.targetGroup?.let { targetGroup -> + viewModelScope.launch(Dispatchers.IO) { + rssRepository.get().groupMoveToTargetGroup(group, targetGroup) + withContext(Dispatchers.Main) { + callback() + } + } + } + } + } + + private fun changeAllMoveToGroupDialogVisible(targetGroup: Group? = null, visible: Boolean) { + _viewState.update { + it.copy( + targetGroup = if (visible) targetGroup else null, + allMoveToGroupDialogVisible = visible, + ) + } + } } @OptIn(ExperimentalMaterialApi::class) data class GroupOptionViewState( var drawerState: ModalBottomSheetState = ModalBottomSheetState(ModalBottomSheetValue.Hidden), val group: Group? = null, + val targetGroup: Group? = null, val groups: List = emptyList(), val allAllowNotificationDialogVisible: Boolean = false, val allParseFullContentDialogVisible: Boolean = false, + val allMoveToGroupDialogVisible: Boolean = false, val deleteDialogVisible: Boolean = false, ) @@ -186,4 +219,14 @@ sealed class GroupOptionViewAction { object ShowAllAllowNotificationDialog : GroupOptionViewAction() object HideAllAllowNotificationDialog : GroupOptionViewAction() + + data class AllMoveToGroup( + val callback: () -> Unit = {} + ) : GroupOptionViewAction() + + data class ShowAllMoveToGroupDialog( + val targetGroup: Group + ) : GroupOptionViewAction() + + object HideAllMoveToGroupDialog : GroupOptionViewAction() } diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index b011f0a..69625d9 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -39,6 +39,9 @@ 全文解析 \"%1$s\" 分组中的文章 不再全文解析 \"%1$s\" 分组中的文章 添加到组 + 移动到组 + 将 \"%1$s\" 分组中的所有订阅源移动至 \"%2$s\" 分组。 + 已全部移动至 \"%1$s\" 分组 新建分组 名称 打开 %1$s diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index d861067..4977564 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -39,6 +39,9 @@ Full content parsing of all articles in the \"%1$s\" group No more full content parsing of all articles in the \"%1$s\" group Add to Group + Move to Group + Move all feeds in the \"%1$s\" group to the \"%2$s\" group. + Moved all to \"%1$s\" group Create New Group Name Open %1$s