Improve SubscribeDialog
This commit is contained in:
parent
31a8445df2
commit
54506e5019
|
@ -21,7 +21,7 @@ import me.ash.reader.ui.component.BottomDrawer
|
|||
import me.ash.reader.ui.component.Subtitle
|
||||
import me.ash.reader.ui.ext.collectAsStateValue
|
||||
import me.ash.reader.ui.ext.roundClick
|
||||
import me.ash.reader.ui.page.home.feeds.subscribe.ResultViewPage
|
||||
import me.ash.reader.ui.page.home.feeds.subscribe.ResultView
|
||||
|
||||
@OptIn(ExperimentalMaterialApi::class)
|
||||
@Composable
|
||||
|
@ -60,7 +60,7 @@ fun FeedOptionDrawer(
|
|||
overflow = TextOverflow.Ellipsis,
|
||||
)
|
||||
Spacer(modifier = modifier.height(16.dp))
|
||||
ResultViewPage(
|
||||
ResultView(
|
||||
link = feed?.url ?: stringResource(R.string.unknown),
|
||||
groups = viewState.groups,
|
||||
selectedAllowNotificationPreset = viewState.feed?.isNotification ?: false,
|
||||
|
|
|
@ -29,7 +29,7 @@ import me.ash.reader.ui.component.Subtitle
|
|||
import me.ash.reader.ui.ext.roundClick
|
||||
|
||||
@Composable
|
||||
fun ResultViewPage(
|
||||
fun ResultView(
|
||||
modifier: Modifier = Modifier,
|
||||
link: String = "",
|
||||
groups: List<Group> = emptyList(),
|
|
@ -30,16 +30,12 @@ import androidx.compose.ui.platform.LocalFocusManager
|
|||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.input.ImeAction
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.google.accompanist.pager.ExperimentalPagerApi
|
||||
import com.google.accompanist.pager.PagerState
|
||||
import kotlinx.coroutines.delay
|
||||
import me.ash.reader.R
|
||||
|
||||
@OptIn(ExperimentalPagerApi::class)
|
||||
@Composable
|
||||
fun SearchViewPage(
|
||||
fun SearchView(
|
||||
modifier: Modifier = Modifier,
|
||||
pagerState: PagerState,
|
||||
readOnly: Boolean = false,
|
||||
inputLink: String = "",
|
||||
errorMessage: String = "",
|
|
@ -2,7 +2,7 @@ package me.ash.reader.ui.page.home.feeds.subscribe
|
|||
|
||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.animation.*
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.rounded.RssFeed
|
||||
|
@ -10,22 +10,25 @@ import androidx.compose.material3.Icon
|
|||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalFocusManager
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.window.DialogProperties
|
||||
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.*
|
||||
|
||||
@OptIn(ExperimentalPagerApi::class, androidx.compose.ui.ExperimentalComposeUiApi::class)
|
||||
@OptIn(
|
||||
androidx.compose.ui.ExperimentalComposeUiApi::class,
|
||||
ExperimentalAnimationApi::class
|
||||
)
|
||||
@Composable
|
||||
fun SubscribeDialog(
|
||||
modifier: Modifier = Modifier,
|
||||
|
@ -33,10 +36,8 @@ fun SubscribeDialog(
|
|||
) {
|
||||
val context = LocalContext.current
|
||||
val focusManager = LocalFocusManager.current
|
||||
val scope = rememberCoroutineScope()
|
||||
val viewState = subscribeViewModel.viewState.collectAsStateValue()
|
||||
val groupsState = viewState.groups.collectAsState(initial = emptyList())
|
||||
var dialogHeight by remember { mutableStateOf(300.dp) }
|
||||
val launcher = rememberLauncherForActivityResult(ActivityResultContracts.GetContent()) {
|
||||
it?.let { uri ->
|
||||
context.contentResolver.openInputStream(uri)?.let { inputStream ->
|
||||
|
@ -56,22 +57,12 @@ fun SubscribeDialog(
|
|||
subscribeViewModel.dispatch(SubscribeViewAction.Init)
|
||||
} else {
|
||||
subscribeViewModel.dispatch(SubscribeViewAction.Reset)
|
||||
viewState.pagerState.scrollToPage(0)
|
||||
}
|
||||
}
|
||||
|
||||
LaunchedEffect(viewState.pagerState.currentPage) {
|
||||
focusManager.clearFocus()
|
||||
when (viewState.pagerState.currentPage) {
|
||||
0 -> dialogHeight = 300.dp
|
||||
1 -> dialogHeight = Dp.Unspecified
|
||||
subscribeViewModel.dispatch(SubscribeViewAction.SwitchPage(true))
|
||||
}
|
||||
}
|
||||
|
||||
Dialog(
|
||||
modifier = Modifier
|
||||
.padding(horizontal = 44.dp)
|
||||
.height(dialogHeight),
|
||||
modifier = Modifier.padding(horizontal = 44.dp),
|
||||
visible = viewState.visible,
|
||||
properties = DialogProperties(usePlatformDefaultWidth = false),
|
||||
onDismissRequest = {
|
||||
|
@ -86,25 +77,45 @@ fun SubscribeDialog(
|
|||
},
|
||||
title = {
|
||||
Text(
|
||||
when (viewState.pagerState.currentPage) {
|
||||
0 -> viewState.title
|
||||
else -> viewState.feed?.name ?: stringResource(R.string.unknown)
|
||||
if (viewState.isSearchPage) {
|
||||
viewState.title
|
||||
} else {
|
||||
viewState.feed?.name ?: stringResource(R.string.unknown)
|
||||
}
|
||||
)
|
||||
},
|
||||
text = {
|
||||
SubscribeViewPager(
|
||||
viewState = viewState,
|
||||
AnimatedContent(
|
||||
targetState = viewState.isSearchPage,
|
||||
transitionSpec = {
|
||||
slideInHorizontally { width -> width } + fadeIn() with
|
||||
slideOutHorizontally { width -> -width } + fadeOut()
|
||||
}
|
||||
) { targetExpanded ->
|
||||
if (targetExpanded) {
|
||||
SearchView(
|
||||
readOnly = viewState.lockLinkInput,
|
||||
inputLink = viewState.linkContent,
|
||||
errorMessage = viewState.errorMessage,
|
||||
onLinkValueChange = {
|
||||
subscribeViewModel.dispatch(SubscribeViewAction.InputLink(it))
|
||||
},
|
||||
onSearchKeyboardAction = {
|
||||
subscribeViewModel.dispatch(SubscribeViewAction.Search(scope))
|
||||
onKeyboardAction = {
|
||||
subscribeViewModel.dispatch(SubscribeViewAction.Search)
|
||||
},
|
||||
)
|
||||
} else {
|
||||
ResultView(
|
||||
link = viewState.linkContent,
|
||||
groups = groupsState.value,
|
||||
selectedAllowNotificationPreset = viewState.allowNotificationPreset,
|
||||
selectedParseFullContentPreset = viewState.parseFullContentPreset,
|
||||
selectedGroupId = viewState.selectedGroupId,
|
||||
newGroupContent = viewState.newGroupContent,
|
||||
onNewGroupValueChange = {
|
||||
subscribeViewModel.dispatch(SubscribeViewAction.InputNewGroup(it))
|
||||
},
|
||||
newGroupSelected = viewState.newGroupSelected,
|
||||
changeNewGroupSelected = {
|
||||
subscribeViewModel.dispatch(SubscribeViewAction.SelectedNewGroup(it))
|
||||
},
|
||||
|
@ -117,20 +128,21 @@ fun SubscribeDialog(
|
|||
onGroupClick = {
|
||||
subscribeViewModel.dispatch(SubscribeViewAction.SelectedGroup(it))
|
||||
},
|
||||
onResultKeyboardAction = {
|
||||
onKeyboardAction = {
|
||||
subscribeViewModel.dispatch(SubscribeViewAction.Subscribe)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
confirmButton = {
|
||||
when (viewState.pagerState.currentPage) {
|
||||
0 -> {
|
||||
if (viewState.isSearchPage) {
|
||||
TextButton(
|
||||
enabled = viewState.linkContent.isNotEmpty()
|
||||
&& viewState.title != stringResource(R.string.searching),
|
||||
onClick = {
|
||||
focusManager.clearFocus()
|
||||
subscribeViewModel.dispatch(SubscribeViewAction.Search(scope))
|
||||
subscribeViewModel.dispatch(SubscribeViewAction.Search)
|
||||
}
|
||||
) {
|
||||
Text(
|
||||
|
@ -142,8 +154,7 @@ fun SubscribeDialog(
|
|||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
1 -> {
|
||||
} else {
|
||||
TextButton(
|
||||
onClick = {
|
||||
focusManager.clearFocus()
|
||||
|
@ -153,11 +164,9 @@ fun SubscribeDialog(
|
|||
Text(stringResource(R.string.subscribe))
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
dismissButton = {
|
||||
when (viewState.pagerState.currentPage) {
|
||||
0 -> {
|
||||
if (viewState.isSearchPage) {
|
||||
TextButton(
|
||||
onClick = {
|
||||
focusManager.clearFocus()
|
||||
|
@ -167,8 +176,7 @@ fun SubscribeDialog(
|
|||
) {
|
||||
Text(text = stringResource(R.string.import_from_opml))
|
||||
}
|
||||
}
|
||||
1 -> {
|
||||
} else {
|
||||
TextButton(
|
||||
onClick = {
|
||||
focusManager.clearFocus()
|
||||
|
@ -178,7 +186,6 @@ fun SubscribeDialog(
|
|||
Text(text = stringResource(R.string.cancel))
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
|
@ -4,10 +4,12 @@ import android.util.Log
|
|||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.google.accompanist.pager.ExperimentalPagerApi
|
||||
import com.google.accompanist.pager.PagerState
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.launch
|
||||
import me.ash.reader.R
|
||||
import me.ash.reader.data.entity.Article
|
||||
import me.ash.reader.data.entity.Feed
|
||||
|
@ -16,7 +18,6 @@ import me.ash.reader.data.repository.OpmlRepository
|
|||
import me.ash.reader.data.repository.RssHelper
|
||||
import me.ash.reader.data.repository.RssRepository
|
||||
import me.ash.reader.data.repository.StringsRepository
|
||||
import me.ash.reader.ui.ext.animateScrollToPage
|
||||
import me.ash.reader.ui.ext.formatUrl
|
||||
import java.io.InputStream
|
||||
import javax.inject.Inject
|
||||
|
@ -39,9 +40,10 @@ class SubscribeViewModel @Inject constructor(
|
|||
is SubscribeViewAction.Reset -> reset()
|
||||
is SubscribeViewAction.Show -> changeVisible(true)
|
||||
is SubscribeViewAction.Hide -> changeVisible(false)
|
||||
is SubscribeViewAction.SwitchPage -> switchPage(action.isSearchPage)
|
||||
is SubscribeViewAction.ImportFromInputStream -> importFromInputStream(action.inputStream)
|
||||
is SubscribeViewAction.InputLink -> inputLink(action.content)
|
||||
is SubscribeViewAction.Search -> search(action.scope)
|
||||
is SubscribeViewAction.Search -> search()
|
||||
is SubscribeViewAction.ChangeAllowNotificationPreset ->
|
||||
changeAllowNotificationPreset()
|
||||
is SubscribeViewAction.ChangeParseFullContentPreset ->
|
||||
|
@ -140,7 +142,7 @@ class SubscribeViewModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private fun search(scope: CoroutineScope) {
|
||||
private fun search() {
|
||||
searchJob?.cancel()
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
try {
|
||||
|
@ -181,7 +183,7 @@ class SubscribeViewModel @Inject constructor(
|
|||
articles = feedWithArticle.articles,
|
||||
)
|
||||
}
|
||||
_viewState.value.pagerState.animateScrollToPage(scope, 1)
|
||||
switchPage(false)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
_viewState.update {
|
||||
|
@ -221,6 +223,14 @@ class SubscribeViewModel @Inject constructor(
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun switchPage(isSearchPage: Boolean) {
|
||||
_viewState.update {
|
||||
it.copy(
|
||||
isSearchPage = isSearchPage
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalPagerApi::class)
|
||||
|
@ -238,7 +248,7 @@ data class SubscribeViewState(
|
|||
val newGroupContent: String = "",
|
||||
val newGroupSelected: Boolean = false,
|
||||
val groups: Flow<List<Group>> = emptyFlow(),
|
||||
val pagerState: PagerState = PagerState(),
|
||||
val isSearchPage: Boolean = true,
|
||||
)
|
||||
|
||||
sealed class SubscribeViewAction {
|
||||
|
@ -248,6 +258,10 @@ sealed class SubscribeViewAction {
|
|||
object Show : SubscribeViewAction()
|
||||
object Hide : SubscribeViewAction()
|
||||
|
||||
data class SwitchPage(
|
||||
val isSearchPage: Boolean
|
||||
) : SubscribeViewAction()
|
||||
|
||||
data class ImportFromInputStream(
|
||||
val inputStream: InputStream
|
||||
) : SubscribeViewAction()
|
||||
|
@ -256,9 +270,7 @@ sealed class SubscribeViewAction {
|
|||
val content: String
|
||||
) : SubscribeViewAction()
|
||||
|
||||
data class Search(
|
||||
val scope: CoroutineScope,
|
||||
) : SubscribeViewAction()
|
||||
object Search: SubscribeViewAction()
|
||||
|
||||
object ChangeAllowNotificationPreset : SubscribeViewAction()
|
||||
object ChangeParseFullContentPreset : SubscribeViewAction()
|
||||
|
|
|
@ -1,69 +0,0 @@
|
|||
package me.ash.reader.ui.page.home.feeds.subscribe
|
||||
|
||||
import androidx.compose.foundation.gestures.detectTapGestures
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.input.pointer.pointerInput
|
||||
import androidx.compose.ui.platform.LocalFocusManager
|
||||
import com.google.accompanist.pager.ExperimentalPagerApi
|
||||
import me.ash.reader.data.entity.Group
|
||||
import me.ash.reader.ui.component.ViewPager
|
||||
|
||||
@OptIn(ExperimentalPagerApi::class)
|
||||
@Composable
|
||||
fun SubscribeViewPager(
|
||||
viewState: SubscribeViewState,
|
||||
modifier: Modifier = Modifier,
|
||||
onLinkValueChange: (String) -> Unit = {},
|
||||
onSearchKeyboardAction: () -> Unit = {},
|
||||
groups: List<Group> = emptyList(),
|
||||
onNewGroupValueChange: (String) -> Unit = {},
|
||||
changeNewGroupSelected: (Boolean) -> Unit = {},
|
||||
allowNotificationPresetOnClick: () -> Unit = {},
|
||||
parseFullContentPresetOnClick: () -> Unit = {},
|
||||
onGroupClick: (groupId: String) -> Unit = {},
|
||||
onResultKeyboardAction: () -> Unit = {},
|
||||
) {
|
||||
val focusManager = LocalFocusManager.current
|
||||
|
||||
ViewPager(
|
||||
modifier = modifier.pointerInput(Unit) {
|
||||
detectTapGestures(
|
||||
onTap = {
|
||||
focusManager.clearFocus()
|
||||
}
|
||||
)
|
||||
},
|
||||
state = viewState.pagerState,
|
||||
userScrollEnabled = false,
|
||||
composableList = listOf(
|
||||
{
|
||||
SearchViewPage(
|
||||
pagerState = viewState.pagerState,
|
||||
readOnly = viewState.lockLinkInput,
|
||||
inputLink = viewState.linkContent,
|
||||
errorMessage = viewState.errorMessage,
|
||||
onLinkValueChange = onLinkValueChange,
|
||||
onKeyboardAction = onSearchKeyboardAction,
|
||||
)
|
||||
},
|
||||
{
|
||||
ResultViewPage(
|
||||
link = viewState.linkContent,
|
||||
groups = groups,
|
||||
selectedAllowNotificationPreset = viewState.allowNotificationPreset,
|
||||
selectedParseFullContentPreset = viewState.parseFullContentPreset,
|
||||
selectedGroupId = viewState.selectedGroupId,
|
||||
newGroupContent = viewState.newGroupContent,
|
||||
onNewGroupValueChange = onNewGroupValueChange,
|
||||
newGroupSelected = viewState.newGroupSelected,
|
||||
changeNewGroupSelected = changeNewGroupSelected,
|
||||
allowNotificationPresetOnClick = allowNotificationPresetOnClick,
|
||||
parseFullContentPresetOnClick = parseFullContentPresetOnClick,
|
||||
onGroupClick = onGroupClick,
|
||||
onKeyboardAction = onResultKeyboardAction,
|
||||
)
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
Loading…
Reference in New Issue
Block a user