Add rename group and rename feed feature
This commit is contained in:
parent
0db39247e3
commit
263548749c
|
@ -1,21 +1,21 @@
|
||||||
package me.ash.reader.ui.page.home.drawer.feed
|
package me.ash.reader.ui.page.home.drawer.feed
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Column
|
import android.widget.Toast
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
|
||||||
import androidx.compose.foundation.layout.height
|
|
||||||
import androidx.compose.material.ExperimentalMaterialApi
|
import androidx.compose.material.ExperimentalMaterialApi
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.outlined.CreateNewFolder
|
import androidx.compose.material.icons.outlined.CreateNewFolder
|
||||||
|
import androidx.compose.material.icons.outlined.Edit
|
||||||
import androidx.compose.material.icons.rounded.RssFeed
|
import androidx.compose.material.icons.rounded.RssFeed
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.hilt.navigation.compose.hiltViewModel
|
import androidx.hilt.navigation.compose.hiltViewModel
|
||||||
|
@ -33,41 +33,46 @@ fun FeedOptionDrawer(
|
||||||
feedOptionViewModel: FeedOptionViewModel = hiltViewModel(),
|
feedOptionViewModel: FeedOptionViewModel = hiltViewModel(),
|
||||||
content: @Composable () -> Unit = {},
|
content: @Composable () -> Unit = {},
|
||||||
) {
|
) {
|
||||||
|
val context = LocalContext.current
|
||||||
|
val scope = rememberCoroutineScope()
|
||||||
val viewState = feedOptionViewModel.viewState.collectAsStateValue()
|
val viewState = feedOptionViewModel.viewState.collectAsStateValue()
|
||||||
val feed = viewState.feed
|
val feed = viewState.feed
|
||||||
|
val toastString = stringResource(R.string.rename_toast, viewState.newName)
|
||||||
|
|
||||||
BottomDrawer(
|
BottomDrawer(
|
||||||
drawerState = viewState.drawerState,
|
drawerState = viewState.drawerState,
|
||||||
sheetContent = {
|
sheetContent = {
|
||||||
Column {
|
Column {
|
||||||
|
Column(
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
|
verticalArrangement = Arrangement.Center
|
||||||
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
modifier = modifier
|
modifier = Modifier.roundClick { },
|
||||||
.roundClick { }
|
|
||||||
.fillMaxWidth()
|
|
||||||
.align(Alignment.CenterHorizontally),
|
|
||||||
imageVector = Icons.Rounded.RssFeed,
|
imageVector = Icons.Rounded.RssFeed,
|
||||||
contentDescription = feed?.name
|
contentDescription = feed?.name ?: stringResource(R.string.unknown),
|
||||||
?: stringResource(R.string.unknown),
|
tint = MaterialTheme.colorScheme.secondary,
|
||||||
tint = MaterialTheme.colorScheme.onSurface
|
|
||||||
)
|
)
|
||||||
Spacer(modifier = modifier.height(16.dp))
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
Text(
|
Text(
|
||||||
modifier = Modifier
|
modifier = Modifier.roundClick {
|
||||||
.roundClick {}
|
feedOptionViewModel.dispatch(FeedOptionViewAction.ShowRenameDialog)
|
||||||
.fillMaxWidth(),
|
},
|
||||||
text = feed?.name ?: stringResource(R.string.unknown),
|
text = feed?.name ?: stringResource(R.string.unknown),
|
||||||
style = MaterialTheme.typography.headlineSmall,
|
style = MaterialTheme.typography.headlineSmall,
|
||||||
textAlign = TextAlign.Center,
|
|
||||||
color = MaterialTheme.colorScheme.onSurface,
|
color = MaterialTheme.colorScheme.onSurface,
|
||||||
maxLines = 1,
|
maxLines = 1,
|
||||||
overflow = TextOverflow.Ellipsis,
|
overflow = TextOverflow.Ellipsis,
|
||||||
)
|
)
|
||||||
Spacer(modifier = modifier.height(16.dp))
|
}
|
||||||
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
ResultView(
|
ResultView(
|
||||||
link = feed?.url ?: stringResource(R.string.unknown),
|
link = feed?.url ?: stringResource(R.string.unknown),
|
||||||
groups = viewState.groups,
|
groups = viewState.groups,
|
||||||
selectedAllowNotificationPreset = viewState.feed?.isNotification ?: false,
|
selectedAllowNotificationPreset = viewState.feed?.isNotification ?: false,
|
||||||
selectedParseFullContentPreset = viewState.feed?.isFullContent ?: false,
|
selectedParseFullContentPreset = viewState.feed?.isFullContent ?: false,
|
||||||
|
isMoveToGroup = true,
|
||||||
showUnsubscribe = true,
|
showUnsubscribe = true,
|
||||||
selectedGroupId = viewState.feed?.groupId ?: "",
|
selectedGroupId = viewState.feed?.groupId ?: "",
|
||||||
allowNotificationPresetOnClick = {
|
allowNotificationPresetOnClick = {
|
||||||
|
@ -110,4 +115,23 @@ fun FeedOptionDrawer(
|
||||||
feedOptionViewModel.dispatch(FeedOptionViewAction.AddNewGroup)
|
feedOptionViewModel.dispatch(FeedOptionViewAction.AddNewGroup)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
TextFieldDialog(
|
||||||
|
visible = viewState.renameDialogVisible,
|
||||||
|
title = stringResource(R.string.rename),
|
||||||
|
icon = Icons.Outlined.Edit,
|
||||||
|
value = viewState.newName,
|
||||||
|
placeholder = stringResource(R.string.name),
|
||||||
|
onValueChange = {
|
||||||
|
feedOptionViewModel.dispatch(FeedOptionViewAction.InputNewName(it))
|
||||||
|
},
|
||||||
|
onDismissRequest = {
|
||||||
|
feedOptionViewModel.dispatch(FeedOptionViewAction.HideRenameDialog)
|
||||||
|
},
|
||||||
|
onConfirm = {
|
||||||
|
feedOptionViewModel.dispatch(FeedOptionViewAction.Rename)
|
||||||
|
feedOptionViewModel.dispatch(FeedOptionViewAction.Hide(scope))
|
||||||
|
Toast.makeText(context, toastString, Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
|
@ -57,6 +57,10 @@ class FeedOptionViewModel @Inject constructor(
|
||||||
is FeedOptionViewAction.AddNewGroup -> addNewGroup()
|
is FeedOptionViewAction.AddNewGroup -> addNewGroup()
|
||||||
is FeedOptionViewAction.ShowNewGroupDialog -> changeNewGroupDialogVisible(true)
|
is FeedOptionViewAction.ShowNewGroupDialog -> changeNewGroupDialogVisible(true)
|
||||||
is FeedOptionViewAction.HideNewGroupDialog -> changeNewGroupDialogVisible(false)
|
is FeedOptionViewAction.HideNewGroupDialog -> changeNewGroupDialogVisible(false)
|
||||||
|
is FeedOptionViewAction.InputNewName -> inputNewName(action.content)
|
||||||
|
is FeedOptionViewAction.Rename -> rename()
|
||||||
|
is FeedOptionViewAction.ShowRenameDialog -> changeRenameDialogVisible(true)
|
||||||
|
is FeedOptionViewAction.HideRenameDialog -> changeRenameDialogVisible(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,6 +178,40 @@ class FeedOptionViewModel @Inject constructor(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun rename() {
|
||||||
|
_viewState.value.feed?.let {
|
||||||
|
viewModelScope.launch {
|
||||||
|
rssRepository.get().updateFeed(
|
||||||
|
it.copy(
|
||||||
|
name = _viewState.value.newName
|
||||||
|
)
|
||||||
|
)
|
||||||
|
_viewState.update {
|
||||||
|
it.copy(
|
||||||
|
renameDialogVisible = false,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun changeRenameDialogVisible(visible: Boolean) {
|
||||||
|
_viewState.update {
|
||||||
|
it.copy(
|
||||||
|
renameDialogVisible = visible,
|
||||||
|
newName = if (visible) _viewState.value.feed?.name ?: "" else "",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun inputNewName(content: String) {
|
||||||
|
_viewState.update {
|
||||||
|
it.copy(
|
||||||
|
newName = content
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterialApi::class)
|
@OptIn(ExperimentalMaterialApi::class)
|
||||||
|
@ -185,6 +223,8 @@ data class FeedOptionViewState(
|
||||||
val newGroupDialogVisible: Boolean = false,
|
val newGroupDialogVisible: Boolean = false,
|
||||||
val groups: List<Group> = emptyList(),
|
val groups: List<Group> = emptyList(),
|
||||||
val deleteDialogVisible: Boolean = false,
|
val deleteDialogVisible: Boolean = false,
|
||||||
|
val newName: String = "",
|
||||||
|
val renameDialogVisible: Boolean = false,
|
||||||
)
|
)
|
||||||
|
|
||||||
sealed class FeedOptionViewAction {
|
sealed class FeedOptionViewAction {
|
||||||
|
@ -218,4 +258,11 @@ sealed class FeedOptionViewAction {
|
||||||
object ShowNewGroupDialog : FeedOptionViewAction()
|
object ShowNewGroupDialog : FeedOptionViewAction()
|
||||||
object HideNewGroupDialog : FeedOptionViewAction()
|
object HideNewGroupDialog : FeedOptionViewAction()
|
||||||
object AddNewGroup : FeedOptionViewAction()
|
object AddNewGroup : FeedOptionViewAction()
|
||||||
|
|
||||||
|
object ShowRenameDialog : FeedOptionViewAction()
|
||||||
|
object HideRenameDialog : FeedOptionViewAction()
|
||||||
|
object Rename : FeedOptionViewAction()
|
||||||
|
data class InputNewName(
|
||||||
|
val content: String
|
||||||
|
) : FeedOptionViewAction()
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package me.ash.reader.ui.page.home.drawer.group
|
package me.ash.reader.ui.page.home.drawer.group
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.widget.Toast
|
||||||
import androidx.compose.animation.animateContentSize
|
import androidx.compose.animation.animateContentSize
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.foundation.lazy.LazyRow
|
import androidx.compose.foundation.lazy.LazyRow
|
||||||
|
@ -9,12 +11,14 @@ import androidx.compose.foundation.verticalScroll
|
||||||
import androidx.compose.material.ExperimentalMaterialApi
|
import androidx.compose.material.ExperimentalMaterialApi
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.outlined.Article
|
import androidx.compose.material.icons.outlined.Article
|
||||||
|
import androidx.compose.material.icons.outlined.Edit
|
||||||
import androidx.compose.material.icons.outlined.Folder
|
import androidx.compose.material.icons.outlined.Folder
|
||||||
import androidx.compose.material.icons.outlined.Notifications
|
import androidx.compose.material.icons.outlined.Notifications
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
@ -26,9 +30,11 @@ import androidx.hilt.navigation.compose.hiltViewModel
|
||||||
import com.google.accompanist.flowlayout.FlowRow
|
import com.google.accompanist.flowlayout.FlowRow
|
||||||
import com.google.accompanist.flowlayout.MainAxisAlignment
|
import com.google.accompanist.flowlayout.MainAxisAlignment
|
||||||
import me.ash.reader.R
|
import me.ash.reader.R
|
||||||
|
import me.ash.reader.data.entity.Group
|
||||||
import me.ash.reader.ui.component.BottomDrawer
|
import me.ash.reader.ui.component.BottomDrawer
|
||||||
import me.ash.reader.ui.component.SelectionChip
|
import me.ash.reader.ui.component.SelectionChip
|
||||||
import me.ash.reader.ui.component.Subtitle
|
import me.ash.reader.ui.component.Subtitle
|
||||||
|
import me.ash.reader.ui.component.TextFieldDialog
|
||||||
import me.ash.reader.ui.ext.collectAsStateValue
|
import me.ash.reader.ui.ext.collectAsStateValue
|
||||||
import me.ash.reader.ui.ext.currentAccountId
|
import me.ash.reader.ui.ext.currentAccountId
|
||||||
import me.ash.reader.ui.ext.getDefaultGroupId
|
import me.ash.reader.ui.ext.getDefaultGroupId
|
||||||
|
@ -38,40 +44,44 @@ import me.ash.reader.ui.ext.roundClick
|
||||||
@Composable
|
@Composable
|
||||||
fun GroupOptionDrawer(
|
fun GroupOptionDrawer(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
GroupOptionViewModel: GroupOptionViewModel = hiltViewModel(),
|
groupOptionViewModel: GroupOptionViewModel = hiltViewModel(),
|
||||||
content: @Composable () -> Unit = {},
|
content: @Composable () -> Unit = {},
|
||||||
) {
|
) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val viewState = GroupOptionViewModel.viewState.collectAsStateValue()
|
val scope = rememberCoroutineScope()
|
||||||
|
val viewState = groupOptionViewModel.viewState.collectAsStateValue()
|
||||||
val group = viewState.group
|
val group = viewState.group
|
||||||
|
val toastString = stringResource(R.string.rename_toast, viewState.newName)
|
||||||
|
|
||||||
BottomDrawer(
|
BottomDrawer(
|
||||||
drawerState = viewState.drawerState,
|
drawerState = viewState.drawerState,
|
||||||
sheetContent = {
|
sheetContent = {
|
||||||
Column {
|
Column {
|
||||||
|
Column(
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
|
verticalArrangement = Arrangement.Center
|
||||||
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
modifier = modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.align(Alignment.CenterHorizontally),
|
|
||||||
imageVector = Icons.Outlined.Folder,
|
imageVector = Icons.Outlined.Folder,
|
||||||
contentDescription = group?.name ?: stringResource(R.string.unknown),
|
contentDescription = group?.name ?: stringResource(R.string.unknown),
|
||||||
tint = MaterialTheme.colorScheme.onSurface
|
tint = MaterialTheme.colorScheme.secondary,
|
||||||
)
|
)
|
||||||
Spacer(modifier = modifier.height(16.dp))
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
Text(
|
Text(
|
||||||
modifier = Modifier
|
modifier = Modifier.roundClick {
|
||||||
.roundClick {}
|
groupOptionViewModel.dispatch(GroupOptionViewAction.ShowRenameDialog)
|
||||||
.fillMaxWidth(),
|
},
|
||||||
text = group?.name ?: stringResource(R.string.unknown),
|
text = group?.name ?: stringResource(R.string.unknown),
|
||||||
style = MaterialTheme.typography.headlineSmall,
|
style = MaterialTheme.typography.headlineSmall,
|
||||||
textAlign = TextAlign.Center,
|
|
||||||
color = MaterialTheme.colorScheme.onSurface,
|
color = MaterialTheme.colorScheme.onSurface,
|
||||||
maxLines = 1,
|
maxLines = 1,
|
||||||
overflow = TextOverflow.Ellipsis,
|
overflow = TextOverflow.Ellipsis,
|
||||||
)
|
)
|
||||||
Spacer(modifier = modifier.height(16.dp))
|
}
|
||||||
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
Column(
|
Column(
|
||||||
modifier = modifier.verticalScroll(rememberScrollState())
|
modifier = Modifier.verticalScroll(rememberScrollState())
|
||||||
) {
|
) {
|
||||||
Row(
|
Row(
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
@ -84,10 +94,63 @@ fun GroupOptionDrawer(
|
||||||
textAlign = TextAlign.Center,
|
textAlign = TextAlign.Center,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Spacer(modifier = Modifier.height(26.dp))
|
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.height(26.dp))
|
||||||
Subtitle(text = stringResource(R.string.preset))
|
Subtitle(text = stringResource(R.string.preset))
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(10.dp))
|
Spacer(modifier = Modifier.height(10.dp))
|
||||||
|
Preset(groupOptionViewModel, group, context)
|
||||||
|
|
||||||
|
if (viewState.groups.size != 1) {
|
||||||
|
Spacer(modifier = Modifier.height(26.dp))
|
||||||
|
Subtitle(text = stringResource(R.string.move_to_group))
|
||||||
|
Spacer(modifier = Modifier.height(10.dp))
|
||||||
|
|
||||||
|
if (viewState.groups.size > 6) {
|
||||||
|
LazyRowGroups(viewState, group, groupOptionViewModel)
|
||||||
|
} else {
|
||||||
|
FlowRowGroups(viewState, group, groupOptionViewModel)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.height(6.dp))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
content()
|
||||||
|
}
|
||||||
|
|
||||||
|
DeleteGroupDialog(groupName = group?.name ?: "")
|
||||||
|
AllAllowNotificationDialog(groupName = group?.name ?: "")
|
||||||
|
AllParseFullContentDialog(groupName = group?.name ?: "")
|
||||||
|
AllMoveToGroupDialog(groupName = group?.name ?: "")
|
||||||
|
TextFieldDialog(
|
||||||
|
visible = viewState.renameDialogVisible,
|
||||||
|
title = stringResource(R.string.rename),
|
||||||
|
icon = Icons.Outlined.Edit,
|
||||||
|
value = viewState.newName,
|
||||||
|
placeholder = stringResource(R.string.name),
|
||||||
|
onValueChange = {
|
||||||
|
groupOptionViewModel.dispatch(GroupOptionViewAction.InputNewName(it))
|
||||||
|
},
|
||||||
|
onDismissRequest = {
|
||||||
|
groupOptionViewModel.dispatch(GroupOptionViewAction.HideRenameDialog)
|
||||||
|
},
|
||||||
|
onConfirm = {
|
||||||
|
groupOptionViewModel.dispatch(GroupOptionViewAction.Rename)
|
||||||
|
groupOptionViewModel.dispatch(GroupOptionViewAction.Hide(scope))
|
||||||
|
Toast.makeText(context, toastString, Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun Preset(
|
||||||
|
groupOptionViewModel: GroupOptionViewModel,
|
||||||
|
group: Group?,
|
||||||
|
context: Context
|
||||||
|
) {
|
||||||
FlowRow(
|
FlowRow(
|
||||||
mainAxisAlignment = MainAxisAlignment.Start,
|
mainAxisAlignment = MainAxisAlignment.Start,
|
||||||
crossAxisSpacing = 10.dp,
|
crossAxisSpacing = 10.dp,
|
||||||
|
@ -107,7 +170,7 @@ fun GroupOptionDrawer(
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
GroupOptionViewModel.dispatch(GroupOptionViewAction.ShowAllAllowNotificationDialog)
|
groupOptionViewModel.dispatch(GroupOptionViewAction.ShowAllAllowNotificationDialog)
|
||||||
}
|
}
|
||||||
SelectionChip(
|
SelectionChip(
|
||||||
modifier = Modifier.animateContentSize(),
|
modifier = Modifier.animateContentSize(),
|
||||||
|
@ -123,7 +186,7 @@ fun GroupOptionDrawer(
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
GroupOptionViewModel.dispatch(GroupOptionViewAction.ShowAllParseFullContentDialog)
|
groupOptionViewModel.dispatch(GroupOptionViewAction.ShowAllParseFullContentDialog)
|
||||||
}
|
}
|
||||||
if (group?.id != context.currentAccountId.getDefaultGroupId()) {
|
if (group?.id != context.currentAccountId.getDefaultGroupId()) {
|
||||||
SelectionChip(
|
SelectionChip(
|
||||||
|
@ -131,33 +194,18 @@ fun GroupOptionDrawer(
|
||||||
content = stringResource(R.string.delete_group),
|
content = stringResource(R.string.delete_group),
|
||||||
selected = false,
|
selected = false,
|
||||||
) {
|
) {
|
||||||
GroupOptionViewModel.dispatch(GroupOptionViewAction.ShowDeleteDialog)
|
groupOptionViewModel.dispatch(GroupOptionViewAction.ShowDeleteDialog)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Spacer(modifier = Modifier.height(26.dp))
|
}
|
||||||
|
|
||||||
Subtitle(text = stringResource(R.string.move_to_group))
|
@Composable
|
||||||
Spacer(modifier = Modifier.height(10.dp))
|
private fun FlowRowGroups(
|
||||||
|
viewState: GroupOptionViewState,
|
||||||
if (viewState.groups.size > 6) {
|
group: Group?,
|
||||||
LazyRow {
|
groupOptionViewModel: GroupOptionViewModel
|
||||||
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(
|
FlowRow(
|
||||||
mainAxisAlignment = MainAxisAlignment.Start,
|
mainAxisAlignment = MainAxisAlignment.Start,
|
||||||
crossAxisSpacing = 10.dp,
|
crossAxisSpacing = 10.dp,
|
||||||
|
@ -170,25 +218,35 @@ fun GroupOptionDrawer(
|
||||||
content = it.name,
|
content = it.name,
|
||||||
selected = false,
|
selected = false,
|
||||||
) {
|
) {
|
||||||
GroupOptionViewModel.dispatch(
|
groupOptionViewModel.dispatch(
|
||||||
GroupOptionViewAction.ShowAllMoveToGroupDialog(it)
|
GroupOptionViewAction.ShowAllMoveToGroupDialog(it)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(6.dp))
|
@Composable
|
||||||
}
|
private fun LazyRowGroups(
|
||||||
}
|
viewState: GroupOptionViewState,
|
||||||
}
|
group: Group?,
|
||||||
) {
|
groupOptionViewModel: GroupOptionViewModel
|
||||||
content()
|
) {
|
||||||
}
|
LazyRow {
|
||||||
|
items(viewState.groups) {
|
||||||
DeleteGroupDialog(groupName = group?.name ?: "")
|
if (it.id != group?.id) {
|
||||||
AllAllowNotificationDialog(groupName = group?.name ?: "")
|
SelectionChip(
|
||||||
AllParseFullContentDialog(groupName = group?.name ?: "")
|
modifier = Modifier.animateContentSize(),
|
||||||
AllMoveToGroupDialog(groupName = group?.name ?: "")
|
content = it.name,
|
||||||
|
selected = false,
|
||||||
|
) {
|
||||||
|
groupOptionViewModel.dispatch(
|
||||||
|
GroupOptionViewAction.ShowAllMoveToGroupDialog(it)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Spacer(modifier = Modifier.width(10.dp))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,6 +70,11 @@ class GroupOptionViewModel @Inject constructor(
|
||||||
changeAllMoveToGroupDialogVisible(visible = false)
|
changeAllMoveToGroupDialogVisible(visible = false)
|
||||||
is GroupOptionViewAction.AllMoveToGroup ->
|
is GroupOptionViewAction.AllMoveToGroup ->
|
||||||
allMoveToGroup(action.callback)
|
allMoveToGroup(action.callback)
|
||||||
|
|
||||||
|
is GroupOptionViewAction.InputNewName -> inputNewName(action.content)
|
||||||
|
is GroupOptionViewAction.Rename -> rename()
|
||||||
|
is GroupOptionViewAction.ShowRenameDialog -> changeRenameDialogVisible(true)
|
||||||
|
is GroupOptionViewAction.HideRenameDialog -> changeRenameDialogVisible(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,6 +178,40 @@ class GroupOptionViewModel @Inject constructor(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun rename() {
|
||||||
|
_viewState.value.group?.let {
|
||||||
|
viewModelScope.launch {
|
||||||
|
rssRepository.get().updateGroup(
|
||||||
|
it.copy(
|
||||||
|
name = _viewState.value.newName
|
||||||
|
)
|
||||||
|
)
|
||||||
|
_viewState.update {
|
||||||
|
it.copy(
|
||||||
|
renameDialogVisible = false,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun changeRenameDialogVisible(visible: Boolean) {
|
||||||
|
_viewState.update {
|
||||||
|
it.copy(
|
||||||
|
renameDialogVisible = visible,
|
||||||
|
newName = if (visible) _viewState.value.group?.name ?: "" else "",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun inputNewName(content: String) {
|
||||||
|
_viewState.update {
|
||||||
|
it.copy(
|
||||||
|
newName = content
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterialApi::class)
|
@OptIn(ExperimentalMaterialApi::class)
|
||||||
|
@ -185,6 +224,8 @@ data class GroupOptionViewState(
|
||||||
val allParseFullContentDialogVisible: Boolean = false,
|
val allParseFullContentDialogVisible: Boolean = false,
|
||||||
val allMoveToGroupDialogVisible: Boolean = false,
|
val allMoveToGroupDialogVisible: Boolean = false,
|
||||||
val deleteDialogVisible: Boolean = false,
|
val deleteDialogVisible: Boolean = false,
|
||||||
|
val newName: String = "",
|
||||||
|
val renameDialogVisible: Boolean = false,
|
||||||
)
|
)
|
||||||
|
|
||||||
sealed class GroupOptionViewAction {
|
sealed class GroupOptionViewAction {
|
||||||
|
@ -229,4 +270,11 @@ sealed class GroupOptionViewAction {
|
||||||
) : GroupOptionViewAction()
|
) : GroupOptionViewAction()
|
||||||
|
|
||||||
object HideAllMoveToGroupDialog : GroupOptionViewAction()
|
object HideAllMoveToGroupDialog : GroupOptionViewAction()
|
||||||
|
|
||||||
|
object ShowRenameDialog : GroupOptionViewAction()
|
||||||
|
object HideRenameDialog : GroupOptionViewAction()
|
||||||
|
object Rename : GroupOptionViewAction()
|
||||||
|
data class InputNewName(
|
||||||
|
val content: String
|
||||||
|
) : GroupOptionViewAction()
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,6 +43,7 @@ fun ResultView(
|
||||||
groups: List<Group> = emptyList(),
|
groups: List<Group> = emptyList(),
|
||||||
selectedAllowNotificationPreset: Boolean = false,
|
selectedAllowNotificationPreset: Boolean = false,
|
||||||
selectedParseFullContentPreset: Boolean = false,
|
selectedParseFullContentPreset: Boolean = false,
|
||||||
|
isMoveToGroup: Boolean = false,
|
||||||
showUnsubscribe: Boolean = false,
|
showUnsubscribe: Boolean = false,
|
||||||
selectedGroupId: String = "",
|
selectedGroupId: String = "",
|
||||||
allowNotificationPresetOnClick: () -> Unit = {},
|
allowNotificationPresetOnClick: () -> Unit = {},
|
||||||
|
@ -72,6 +73,7 @@ fun ResultView(
|
||||||
Spacer(modifier = Modifier.height(26.dp))
|
Spacer(modifier = Modifier.height(26.dp))
|
||||||
|
|
||||||
AddToGroup(
|
AddToGroup(
|
||||||
|
isMoveToGroup = isMoveToGroup,
|
||||||
groups = groups,
|
groups = groups,
|
||||||
selectedGroupId = selectedGroupId,
|
selectedGroupId = selectedGroupId,
|
||||||
onGroupClick = onGroupClick,
|
onGroupClick = onGroupClick,
|
||||||
|
@ -169,12 +171,13 @@ private fun Preset(
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun AddToGroup(
|
private fun AddToGroup(
|
||||||
|
isMoveToGroup: Boolean = false,
|
||||||
groups: List<Group>,
|
groups: List<Group>,
|
||||||
selectedGroupId: String,
|
selectedGroupId: String,
|
||||||
onGroupClick: (groupId: String) -> Unit = {},
|
onGroupClick: (groupId: String) -> Unit = {},
|
||||||
onAddNewGroup: () -> Unit = {},
|
onAddNewGroup: () -> Unit = {},
|
||||||
) {
|
) {
|
||||||
Subtitle(text = stringResource(R.string.add_to_group))
|
Subtitle(text = stringResource(if (isMoveToGroup) R.string.move_to_group else R.string.add_to_group))
|
||||||
Spacer(modifier = Modifier.height(10.dp))
|
Spacer(modifier = Modifier.height(10.dp))
|
||||||
|
|
||||||
if (groups.size > 6) {
|
if (groups.size > 6) {
|
||||||
|
|
|
@ -72,7 +72,6 @@ fun SettingsPage(
|
||||||
}
|
}
|
||||||
item {
|
item {
|
||||||
SelectableSettingGroupItem(
|
SelectableSettingGroupItem(
|
||||||
selected = true,
|
|
||||||
title = stringResource(R.string.color_and_style),
|
title = stringResource(R.string.color_and_style),
|
||||||
desc = stringResource(R.string.color_and_style_desc),
|
desc = stringResource(R.string.color_and_style_desc),
|
||||||
icon = Icons.Outlined.Palette,
|
icon = Icons.Outlined.Palette,
|
||||||
|
|
|
@ -42,6 +42,8 @@
|
||||||
<string name="move_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_tip">将 \"%1$s\" 分组中的所有订阅源移动至 \"%2$s\" 分组。</string>
|
||||||
<string name="all_move_to_group_toast">已全部移动至 \"%1$s\" 分组</string>
|
<string name="all_move_to_group_toast">已全部移动至 \"%1$s\" 分组</string>
|
||||||
|
<string name="rename">重命名</string>
|
||||||
|
<string name="rename_toast">已重命名为 \"%1$s\"</string>
|
||||||
<string name="create_new_group">新建分组</string>
|
<string name="create_new_group">新建分组</string>
|
||||||
<string name="name">名称</string>
|
<string name="name">名称</string>
|
||||||
<string name="open_with">打开 %1$s</string>
|
<string name="open_with">打开 %1$s</string>
|
||||||
|
|
|
@ -42,6 +42,8 @@
|
||||||
<string name="move_to_group">Move 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_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="all_move_to_group_toast">Moved all to \"%1$s\" group</string>
|
||||||
|
<string name="rename">Rename</string>
|
||||||
|
<string name="rename_toast">Renamed to \"%1$s\"</string>
|
||||||
<string name="create_new_group">Create New Group</string>
|
<string name="create_new_group">Create New Group</string>
|
||||||
<string name="name">Name</string>
|
<string name="name">Name</string>
|
||||||
<string name="open_with">Open %1$s</string>
|
<string name="open_with">Open %1$s</string>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user