Optimize SubscribeDialog

This commit is contained in:
Ash 2022-04-02 22:28:16 +08:00
parent 4c95f89b07
commit c42d92fcc8
7 changed files with 47 additions and 72 deletions

View File

@ -1,6 +1,5 @@
package me.ash.reader.ui.page.home.drawer.feed package me.ash.reader.ui.page.home.drawer.feed
import android.util.Log
import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
import androidx.compose.material.ExperimentalMaterialApi import androidx.compose.material.ExperimentalMaterialApi
@ -9,7 +8,6 @@ import androidx.compose.material.icons.rounded.DeleteOutline
import androidx.compose.material.icons.rounded.RssFeed import androidx.compose.material.icons.rounded.RssFeed
import androidx.compose.material3.* import androidx.compose.material3.*
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
@ -82,7 +80,7 @@ fun FeedOptionDrawer(
parseFullContentPresetOnClick = { parseFullContentPresetOnClick = {
viewModel.dispatch(FeedOptionViewAction.ChangeParseFullContentPreset) viewModel.dispatch(FeedOptionViewAction.ChangeParseFullContentPreset)
}, },
groupOnClick = { onGroupClick = {
viewModel.dispatch(FeedOptionViewAction.SelectedGroup(it)) viewModel.dispatch(FeedOptionViewAction.SelectedGroup(it))
}, },
onKeyboardAction = { }, onKeyboardAction = { },

View File

@ -133,11 +133,7 @@ fun FeedsPage(
) )
}, },
content = { content = {
SubscribeDialog( SubscribeDialog()
openInputStreamCallback = {
feedsViewModel.dispatch(FeedsViewAction.ImportFromInputStream(it))
},
)
LazyColumn { LazyColumn {
item { item {
Text( Text(

View File

@ -15,7 +15,6 @@ import me.ash.reader.data.repository.AccountRepository
import me.ash.reader.data.repository.OpmlRepository import me.ash.reader.data.repository.OpmlRepository
import me.ash.reader.data.repository.RssRepository import me.ash.reader.data.repository.RssRepository
import me.ash.reader.ui.page.home.FilterState import me.ash.reader.ui.page.home.FilterState
import java.io.InputStream
import javax.inject.Inject import javax.inject.Inject
@HiltViewModel @HiltViewModel
@ -31,7 +30,6 @@ class FeedsViewModel @Inject constructor(
when (action) { when (action) {
is FeedsViewAction.FetchAccount -> fetchAccount() is FeedsViewAction.FetchAccount -> fetchAccount()
is FeedsViewAction.FetchData -> fetchData(action.filterState) is FeedsViewAction.FetchData -> fetchData(action.filterState)
is FeedsViewAction.ImportFromInputStream -> importFromInputStream(action.inputStream)
is FeedsViewAction.ExportAsString -> exportAsOpml(action.callback) is FeedsViewAction.ExportAsString -> exportAsOpml(action.callback)
is FeedsViewAction.ScrollToItem -> scrollToItem(action.index) is FeedsViewAction.ScrollToItem -> scrollToItem(action.index)
} }
@ -47,17 +45,6 @@ class FeedsViewModel @Inject constructor(
} }
} }
private fun importFromInputStream(inputStream: InputStream) {
viewModelScope.launch(Dispatchers.IO) {
try {
opmlRepository.saveToDatabase(inputStream)
rssRepository.get().doSync()
} catch (e: Exception) {
Log.e("FeedsViewModel", "importFromInputStream: ", e)
}
}
}
private fun exportAsOpml(callback: (String) -> Unit = {}) { private fun exportAsOpml(callback: (String) -> Unit = {}) {
viewModelScope.launch(Dispatchers.Default) { viewModelScope.launch(Dispatchers.Default) {
try { try {
@ -157,10 +144,6 @@ sealed class FeedsViewAction {
object FetchAccount : FeedsViewAction() object FetchAccount : FeedsViewAction()
data class ImportFromInputStream(
val inputStream: InputStream
) : FeedsViewAction()
data class ExportAsString( data class ExportAsString(
val callback: (String) -> Unit = {} val callback: (String) -> Unit = {}
) : FeedsViewAction() ) : FeedsViewAction()

View File

@ -42,7 +42,7 @@ fun ResultViewPage(
changeNewGroupSelected: (Boolean) -> Unit = {}, changeNewGroupSelected: (Boolean) -> Unit = {},
allowNotificationPresetOnClick: () -> Unit = {}, allowNotificationPresetOnClick: () -> Unit = {},
parseFullContentPresetOnClick: () -> Unit = {}, parseFullContentPresetOnClick: () -> Unit = {},
groupOnClick: (groupId: String) -> Unit = {}, onGroupClick: (groupId: String) -> Unit = {},
onKeyboardAction: () -> Unit = {}, onKeyboardAction: () -> Unit = {},
) { ) {
Column( Column(
@ -68,7 +68,7 @@ fun ResultViewPage(
newGroupSelected = newGroupSelected, newGroupSelected = newGroupSelected,
onNewGroupValueChange = onNewGroupValueChange, onNewGroupValueChange = onNewGroupValueChange,
changeNewGroupSelected = changeNewGroupSelected, changeNewGroupSelected = changeNewGroupSelected,
groupOnClick = groupOnClick, onGroupClick = onGroupClick,
onKeyboardAction = onKeyboardAction, onKeyboardAction = onKeyboardAction,
) )
Spacer(modifier = Modifier.height(6.dp)) Spacer(modifier = Modifier.height(6.dp))
@ -158,7 +158,7 @@ private fun AddToGroup(
newGroupSelected: Boolean, newGroupSelected: Boolean,
onNewGroupValueChange: (String) -> Unit = {}, onNewGroupValueChange: (String) -> Unit = {},
changeNewGroupSelected: (Boolean) -> Unit = {}, changeNewGroupSelected: (Boolean) -> Unit = {},
groupOnClick: (groupId: String) -> Unit = {}, onGroupClick: (groupId: String) -> Unit = {},
onKeyboardAction: () -> Unit = {}, onKeyboardAction: () -> Unit = {},
) { ) {
Subtitle(text = stringResource(R.string.add_to_group)) Subtitle(text = stringResource(R.string.add_to_group))
@ -175,7 +175,7 @@ private fun AddToGroup(
selected = !newGroupSelected && it.id == selectedGroupId, selected = !newGroupSelected && it.id == selectedGroupId,
) { ) {
changeNewGroupSelected(false) changeNewGroupSelected(false)
groupOnClick(it.id) onGroupClick(it.id)
} }
} }

View File

@ -21,31 +21,27 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.DialogProperties import androidx.compose.ui.window.DialogProperties
import androidx.hilt.navigation.compose.hiltViewModel import androidx.hilt.navigation.compose.hiltViewModel
import com.google.accompanist.pager.ExperimentalPagerApi import com.google.accompanist.pager.ExperimentalPagerApi
import kotlinx.coroutines.Dispatchers
import me.ash.reader.* import me.ash.reader.*
import me.ash.reader.R import me.ash.reader.R
import me.ash.reader.ui.extension.collectAsStateValue import me.ash.reader.ui.extension.collectAsStateValue
import me.ash.reader.ui.widget.Dialog import me.ash.reader.ui.widget.Dialog
import java.io.InputStream
@OptIn(ExperimentalPagerApi::class, androidx.compose.ui.ExperimentalComposeUiApi::class) @OptIn(ExperimentalPagerApi::class, androidx.compose.ui.ExperimentalComposeUiApi::class)
@Composable @Composable
fun SubscribeDialog( fun SubscribeDialog(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
subscribeViewModel: SubscribeViewModel = hiltViewModel(), subscribeViewModel: SubscribeViewModel = hiltViewModel(),
openInputStreamCallback: (InputStream) -> Unit,
) { ) {
val context = LocalContext.current val context = LocalContext.current
val focusManager = LocalFocusManager.current val focusManager = LocalFocusManager.current
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
val viewState = subscribeViewModel.viewState.collectAsStateValue() val viewState = subscribeViewModel.viewState.collectAsStateValue()
val groupsState = val groupsState = viewState.groups.collectAsState(initial = emptyList())
viewState.groups.collectAsState(initial = emptyList(), context = Dispatchers.IO)
var dialogHeight by remember { mutableStateOf(300.dp) } var dialogHeight by remember { mutableStateOf(300.dp) }
val launcher = rememberLauncherForActivityResult(ActivityResultContracts.GetContent()) { val launcher = rememberLauncherForActivityResult(ActivityResultContracts.GetContent()) {
it?.let { uri -> it?.let { uri ->
context.contentResolver.openInputStream(uri)?.let { inputStream -> context.contentResolver.openInputStream(uri)?.let { inputStream ->
openInputStreamCallback(inputStream) subscribeViewModel.dispatch(SubscribeViewAction.ImportFromInputStream(inputStream))
} }
} }
} }
@ -99,48 +95,40 @@ fun SubscribeDialog(
}, },
text = { text = {
SubscribeViewPager( SubscribeViewPager(
readOnly = viewState.lockLinkInput, viewState = viewState,
inputLink = viewState.linkContent,
errorMessage = viewState.errorMessage,
onLinkValueChange = { onLinkValueChange = {
subscribeViewModel.dispatch(SubscribeViewAction.InputLink(it)) subscribeViewModel.dispatch(SubscribeViewAction.InputLink(it))
}, },
onSearchKeyboardAction = { onSearchKeyboardAction = {
subscribeViewModel.dispatch(SubscribeViewAction.Search(scope)) subscribeViewModel.dispatch(SubscribeViewAction.Search(scope))
}, },
link = viewState.linkContent,
groups = groupsState.value, groups = groupsState.value,
selectedAllowNotificationPreset = viewState.allowNotificationPreset,
selectedParseFullContentPreset = viewState.parseFullContentPreset,
selectedGroupId = viewState.selectedGroupId,
newGroupContent = viewState.newGroupContent,
onNewGroupValueChange = { onNewGroupValueChange = {
subscribeViewModel.dispatch(SubscribeViewAction.InputNewGroup(it)) subscribeViewModel.dispatch(SubscribeViewAction.InputNewGroup(it))
}, },
newGroupSelected = viewState.newGroupSelected,
changeNewGroupSelected = { changeNewGroupSelected = {
subscribeViewModel.dispatch(SubscribeViewAction.SelectedNewGroup(it)) subscribeViewModel.dispatch(SubscribeViewAction.SelectedNewGroup(it))
}, },
pagerState = viewState.pagerState,
allowNotificationPresetOnClick = { allowNotificationPresetOnClick = {
subscribeViewModel.dispatch(SubscribeViewAction.ChangeAllowNotificationPreset) subscribeViewModel.dispatch(SubscribeViewAction.ChangeAllowNotificationPreset)
}, },
parseFullContentPresetOnClick = { parseFullContentPresetOnClick = {
subscribeViewModel.dispatch(SubscribeViewAction.ChangeParseFullContentPreset) subscribeViewModel.dispatch(SubscribeViewAction.ChangeParseFullContentPreset)
}, },
groupOnClick = { onGroupClick = {
subscribeViewModel.dispatch(SubscribeViewAction.SelectedGroup(it)) subscribeViewModel.dispatch(SubscribeViewAction.SelectedGroup(it))
}, },
onResultKeyboardAction = { onResultKeyboardAction = {
subscribeViewModel.dispatch(SubscribeViewAction.Subscribe) subscribeViewModel.dispatch(SubscribeViewAction.Subscribe)
} },
) )
}, },
confirmButton = { confirmButton = {
when (viewState.pagerState.currentPage) { when (viewState.pagerState.currentPage) {
0 -> { 0 -> {
TextButton( TextButton(
enabled = viewState.linkContent.isNotEmpty(), enabled = viewState.linkContent.isNotEmpty()
&& viewState.title != stringResource(R.string.searching),
onClick = { onClick = {
focusManager.clearFocus() focusManager.clearFocus()
subscribeViewModel.dispatch(SubscribeViewAction.Search(scope)) subscribeViewModel.dispatch(SubscribeViewAction.Search(scope))

View File

@ -1,5 +1,6 @@
package me.ash.reader.ui.page.home.feeds.subscribe package me.ash.reader.ui.page.home.feeds.subscribe
import android.util.Log
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import com.google.accompanist.pager.ExperimentalPagerApi import com.google.accompanist.pager.ExperimentalPagerApi
@ -11,16 +12,19 @@ import me.ash.reader.R
import me.ash.reader.data.article.Article import me.ash.reader.data.article.Article
import me.ash.reader.data.feed.Feed import me.ash.reader.data.feed.Feed
import me.ash.reader.data.group.Group import me.ash.reader.data.group.Group
import me.ash.reader.data.repository.OpmlRepository
import me.ash.reader.data.repository.RssHelper import me.ash.reader.data.repository.RssHelper
import me.ash.reader.data.repository.RssRepository import me.ash.reader.data.repository.RssRepository
import me.ash.reader.data.repository.StringsRepository import me.ash.reader.data.repository.StringsRepository
import me.ash.reader.formatUrl import me.ash.reader.formatUrl
import me.ash.reader.ui.extension.animateScrollToPage import me.ash.reader.ui.extension.animateScrollToPage
import java.io.InputStream
import javax.inject.Inject import javax.inject.Inject
@OptIn(ExperimentalPagerApi::class) @OptIn(ExperimentalPagerApi::class)
@HiltViewModel @HiltViewModel
class SubscribeViewModel @Inject constructor( class SubscribeViewModel @Inject constructor(
private val opmlRepository: OpmlRepository,
private val rssRepository: RssRepository, private val rssRepository: RssRepository,
private val rssHelper: RssHelper, private val rssHelper: RssHelper,
private val stringsRepository: StringsRepository, private val stringsRepository: StringsRepository,
@ -35,6 +39,7 @@ class SubscribeViewModel @Inject constructor(
is SubscribeViewAction.Reset -> reset() is SubscribeViewAction.Reset -> reset()
is SubscribeViewAction.Show -> changeVisible(true) is SubscribeViewAction.Show -> changeVisible(true)
is SubscribeViewAction.Hide -> changeVisible(false) is SubscribeViewAction.Hide -> changeVisible(false)
is SubscribeViewAction.ImportFromInputStream -> importFromInputStream(action.inputStream)
is SubscribeViewAction.InputLink -> inputLink(action.content) is SubscribeViewAction.InputLink -> inputLink(action.content)
is SubscribeViewAction.Search -> search(action.scope) is SubscribeViewAction.Search -> search(action.scope)
is SubscribeViewAction.ChangeAllowNotificationPreset -> is SubscribeViewAction.ChangeAllowNotificationPreset ->
@ -67,6 +72,17 @@ class SubscribeViewModel @Inject constructor(
} }
} }
private fun importFromInputStream(inputStream: InputStream) {
viewModelScope.launch(Dispatchers.IO) {
try {
opmlRepository.saveToDatabase(inputStream)
rssRepository.get().doSync()
} catch (e: Exception) {
Log.e("FeedsViewModel", "importFromInputStream: ", e)
}
}
}
private fun subscribe() { private fun subscribe() {
val feed = _viewState.value.feed ?: return val feed = _viewState.value.feed ?: return
val articles = _viewState.value.articles val articles = _viewState.value.articles
@ -232,6 +248,10 @@ sealed class SubscribeViewAction {
object Show : SubscribeViewAction() object Show : SubscribeViewAction()
object Hide : SubscribeViewAction() object Hide : SubscribeViewAction()
data class ImportFromInputStream(
val inputStream: InputStream
) : SubscribeViewAction()
data class InputLink( data class InputLink(
val content: String val content: String
) : SubscribeViewAction() ) : SubscribeViewAction()

View File

@ -6,32 +6,22 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.platform.LocalFocusManager
import com.google.accompanist.pager.ExperimentalPagerApi import com.google.accompanist.pager.ExperimentalPagerApi
import com.google.accompanist.pager.PagerState
import me.ash.reader.data.group.Group import me.ash.reader.data.group.Group
import me.ash.reader.ui.widget.ViewPager import me.ash.reader.ui.widget.ViewPager
@OptIn(ExperimentalPagerApi::class) @OptIn(ExperimentalPagerApi::class)
@Composable @Composable
fun SubscribeViewPager( fun SubscribeViewPager(
viewState: SubscribeViewState,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
readOnly: Boolean = false,
inputLink: String = "",
errorMessage: String = "",
onLinkValueChange: (String) -> Unit = {}, onLinkValueChange: (String) -> Unit = {},
onSearchKeyboardAction: () -> Unit = {}, onSearchKeyboardAction: () -> Unit = {},
link: String = "",
groups: List<Group> = emptyList(), groups: List<Group> = emptyList(),
selectedAllowNotificationPreset: Boolean = false,
selectedParseFullContentPreset: Boolean = false,
selectedGroupId: String = "",
newGroupContent: String = "",
onNewGroupValueChange: (String) -> Unit = {}, onNewGroupValueChange: (String) -> Unit = {},
newGroupSelected: Boolean,
changeNewGroupSelected: (Boolean) -> Unit = {}, changeNewGroupSelected: (Boolean) -> Unit = {},
pagerState: PagerState = com.google.accompanist.pager.rememberPagerState(),
allowNotificationPresetOnClick: () -> Unit = {}, allowNotificationPresetOnClick: () -> Unit = {},
parseFullContentPresetOnClick: () -> Unit = {}, parseFullContentPresetOnClick: () -> Unit = {},
groupOnClick: (groupId: String) -> Unit = {}, onGroupClick: (groupId: String) -> Unit = {},
onResultKeyboardAction: () -> Unit = {}, onResultKeyboardAction: () -> Unit = {},
) { ) {
val focusManager = LocalFocusManager.current val focusManager = LocalFocusManager.current
@ -44,33 +34,33 @@ fun SubscribeViewPager(
} }
) )
}, },
state = pagerState, state = viewState.pagerState,
userScrollEnabled = false, userScrollEnabled = false,
composableList = listOf( composableList = listOf(
{ {
SearchViewPage( SearchViewPage(
pagerState = pagerState, pagerState = viewState.pagerState,
readOnly = readOnly, readOnly = viewState.lockLinkInput,
inputLink = inputLink, inputLink = viewState.linkContent,
errorMessage = errorMessage, errorMessage = viewState.errorMessage,
onLinkValueChange = onLinkValueChange, onLinkValueChange = onLinkValueChange,
onKeyboardAction = onSearchKeyboardAction, onKeyboardAction = onSearchKeyboardAction,
) )
}, },
{ {
ResultViewPage( ResultViewPage(
link = link, link = viewState.linkContent,
groups = groups, groups = groups,
selectedAllowNotificationPreset = selectedAllowNotificationPreset, selectedAllowNotificationPreset = viewState.allowNotificationPreset,
selectedParseFullContentPreset = selectedParseFullContentPreset, selectedParseFullContentPreset = viewState.parseFullContentPreset,
selectedGroupId = selectedGroupId, selectedGroupId = viewState.selectedGroupId,
newGroupContent = newGroupContent, newGroupContent = viewState.newGroupContent,
onNewGroupValueChange = onNewGroupValueChange, onNewGroupValueChange = onNewGroupValueChange,
newGroupSelected = newGroupSelected, newGroupSelected = viewState.newGroupSelected,
changeNewGroupSelected = changeNewGroupSelected, changeNewGroupSelected = changeNewGroupSelected,
allowNotificationPresetOnClick = allowNotificationPresetOnClick, allowNotificationPresetOnClick = allowNotificationPresetOnClick,
parseFullContentPresetOnClick = parseFullContentPresetOnClick, parseFullContentPresetOnClick = parseFullContentPresetOnClick,
groupOnClick = groupOnClick, onGroupClick = onGroupClick,
onKeyboardAction = onResultKeyboardAction, onKeyboardAction = onResultKeyboardAction,
) )
} }