Add move all feeds to target Group feature
This commit is contained in:
parent
4f7ebb7958
commit
890ee337a4
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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),
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
|
@ -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 ?: "")
|
||||
AllMoveToGroupDialog(groupName = group?.name ?: "")
|
||||
}
|
|
@ -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<Group> = 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()
|
||||
}
|
||||
|
|
|
@ -39,6 +39,9 @@
|
|||
<string name="all_parse_full_content_toast">全文解析 \"%1$s\" 分组中的文章</string>
|
||||
<string name="all_deny_parse_full_content_toast">不再全文解析 \"%1$s\" 分组中的文章</string>
|
||||
<string name="add_to_group">添加到组</string>
|
||||
<string name="move_to_group">移动到组</string>
|
||||
<string name="all_move_to_group_tip">将 \"%1$s\" 分组中的所有订阅源移动至 \"%2$s\" 分组。</string>
|
||||
<string name="all_move_to_group_toast">已全部移动至 \"%1$s\" 分组</string>
|
||||
<string name="create_new_group">新建分组</string>
|
||||
<string name="name">名称</string>
|
||||
<string name="open_with">打开 %1$s</string>
|
||||
|
|
|
@ -39,6 +39,9 @@
|
|||
<string name="all_parse_full_content_toast">Full content parsing of all articles in the \"%1$s\" group</string>
|
||||
<string name="all_deny_parse_full_content_toast">No more full content parsing of all articles in the \"%1$s\" group</string>
|
||||
<string name="add_to_group">Add to Group</string>
|
||||
<string name="move_to_group">Move to Group</string>
|
||||
<string name="all_move_to_group_tip">Move all feeds in the \"%1$s\" group to the \"%2$s\" group.</string>
|
||||
<string name="all_move_to_group_toast">Moved all to \"%1$s\" group</string>
|
||||
<string name="create_new_group">Create New Group</string>
|
||||
<string name="name">Name</string>
|
||||
<string name="open_with">Open %1$s</string>
|
||||
|
|
Loading…
Reference in New Issue
Block a user