From 4c7bea918d3c0799c4105b8d00cd9f3fbc008fc1 Mon Sep 17 00:00:00 2001 From: junkfood <69683722+JunkFood02@users.noreply.github.com> Date: Wed, 14 Feb 2024 21:27:51 +0800 Subject: [PATCH] feat(ui): add feed via system share sheet (#618) --- app/src/main/AndroidManifest.xml | 35 +++++++++++++++++ .../infrastructure/android/MainActivity.kt | 38 +++++++++++++++++-- .../me/ash/reader/ui/page/common/HomeEntry.kt | 27 ++++++++++++- .../reader/ui/page/home/feeds/FeedsPage.kt | 2 +- .../feeds/subscribe/SubscribeViewModel.kt | 29 ++++++++++++-- 5 files changed, 122 insertions(+), 9 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 5d6ebf6d1..ee54fd859 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -27,17 +27,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { intent -> + intent.getTextOrNull()?.let { + subscribeViewModel.handleSharedUrlFromIntent(it) + } + } + addOnNewIntentListener(listener) + onDispose { + removeOnNewIntentListener(listener) + } + } + HomeEntry(subscribeViewModel = subscribeViewModel) } } } } } } + +private fun Intent.getTextOrNull(): String? { + + return when (action) { + Intent.ACTION_VIEW -> { + dataString + } + + Intent.ACTION_SEND -> { + getStringExtra(Intent.EXTRA_TEXT) + ?.also { removeExtra(Intent.EXTRA_TEXT) } + } + + else -> null + } + +} diff --git a/app/src/main/java/me/ash/reader/ui/page/common/HomeEntry.kt b/app/src/main/java/me/ash/reader/ui/page/common/HomeEntry.kt index 08b533a7d..43afe6666 100644 --- a/app/src/main/java/me/ash/reader/ui/page/common/HomeEntry.kt +++ b/app/src/main/java/me/ash/reader/ui/page/common/HomeEntry.kt @@ -21,6 +21,7 @@ import me.ash.reader.infrastructure.preference.LocalReadingDarkTheme import me.ash.reader.ui.ext.* import me.ash.reader.ui.page.home.HomeViewModel import me.ash.reader.ui.page.home.feeds.FeedsPage +import me.ash.reader.ui.page.home.feeds.subscribe.SubscribeViewModel import me.ash.reader.ui.page.home.flow.FlowPage import me.ash.reader.ui.page.home.reading.ReadingPage import me.ash.reader.ui.page.settings.SettingsPage @@ -42,10 +43,12 @@ import me.ash.reader.ui.theme.AppTheme @Composable fun HomeEntry( homeViewModel: HomeViewModel = hiltViewModel(), + subscribeViewModel: SubscribeViewModel = hiltViewModel(), ) { val context = LocalContext.current var isReadingPage by rememberSaveable { mutableStateOf(false) } val filterUiState = homeViewModel.filterUiState.collectAsStateValue() + val subscribeUiState = subscribeViewModel.subscribeUiState.collectAsStateValue() val navController = rememberAnimatedNavController() val intent by rememberSaveable { mutableStateOf(context.findActivity()?.intent) } @@ -81,7 +84,23 @@ fun HomeEntry( Log.i("RLog", "currentBackStackEntry: ${navController.currentDestination?.route}") // Animation duration takes 310 ms delay(310L) - isReadingPage = navController.currentDestination?.route == "${RouteName.READING}/{articleId}" + isReadingPage = + navController.currentDestination?.route == "${RouteName.READING}/{articleId}" + } + } + + DisposableEffect(subscribeUiState.shouldNavigateToFeedPage) { + if (subscribeUiState.shouldNavigateToFeedPage) { + if (navController.currentDestination?.route != RouteName.FEEDS) { + navController.popBackStack( + route = RouteName.FEEDS, + inclusive = false, + saveState = true + ) + } + } + onDispose { + subscribeViewModel.onIntentConsumed() } } @@ -126,7 +145,11 @@ fun HomeEntry( // Home forwardAndBackwardComposable(route = RouteName.FEEDS) { - FeedsPage(navController = navController, homeViewModel = homeViewModel) + FeedsPage( + navController = navController, + homeViewModel = homeViewModel, + subscribeViewModel = subscribeViewModel + ) } forwardAndBackwardComposable(route = RouteName.FLOW) { FlowPage( diff --git a/app/src/main/java/me/ash/reader/ui/page/home/feeds/FeedsPage.kt b/app/src/main/java/me/ash/reader/ui/page/home/feeds/FeedsPage.kt index b4f15f663..5a556f7e3 100644 --- a/app/src/main/java/me/ash/reader/ui/page/home/feeds/FeedsPage.kt +++ b/app/src/main/java/me/ash/reader/ui/page/home/feeds/FeedsPage.kt @@ -322,7 +322,7 @@ fun FeedsPage( } ) - SubscribeDialog() + SubscribeDialog(subscribeViewModel = subscribeViewModel) GroupOptionDrawer() FeedOptionDrawer() diff --git a/app/src/main/java/me/ash/reader/ui/page/home/feeds/subscribe/SubscribeViewModel.kt b/app/src/main/java/me/ash/reader/ui/page/home/feeds/subscribe/SubscribeViewModel.kt index 5d27a838b..9a9af7559 100644 --- a/app/src/main/java/me/ash/reader/ui/page/home/feeds/subscribe/SubscribeViewModel.kt +++ b/app/src/main/java/me/ash/reader/ui/page/home/feeds/subscribe/SubscribeViewModel.kt @@ -7,6 +7,7 @@ import com.rometools.rome.feed.synd.SyndFeed import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Job +import kotlinx.coroutines.delay import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow @@ -52,7 +53,7 @@ class SubscribeViewModel @Inject constructor( searchJob?.cancel() searchJob = null _subscribeUiState.update { - SubscribeUiState().copy(title = androidStringsHelper.getString(R.string.subscribe)) + SubscribeUiState(title = androidStringsHelper.getString(R.string.subscribe)) } } @@ -75,7 +76,9 @@ class SubscribeViewModel @Inject constructor( if (_subscribeUiState.value.newGroupContent.isNotBlank()) { applicationScope.launch { // TODO: How to add a single group without no feeds via Google Reader API? - selectedGroup(rssService.get().addGroup(null, _subscribeUiState.value.newGroupContent)) + selectedGroup( + rssService.get().addGroup(null, _subscribeUiState.value.newGroupContent) + ) hideNewGroupDialog() _subscribeUiState.update { it.copy(newGroupContent = "") } } @@ -139,7 +142,8 @@ class SubscribeViewModel @Inject constructor( _subscribeUiState.update { it.copy( title = androidStringsHelper.getString(R.string.subscribe), - errorMessage = e.message ?: androidStringsHelper.getString(R.string.unknown), + errorMessage = e.message + ?: androidStringsHelper.getString(R.string.unknown), lockLinkInput = false, ) } @@ -175,6 +179,24 @@ class SubscribeViewModel @Inject constructor( _subscribeUiState.update { it.copy(newGroupContent = content) } } + fun handleSharedUrlFromIntent(url: String) { + viewModelScope.launch { + _subscribeUiState.update { + it.copy( + visible = true, + shouldNavigateToFeedPage = true, + linkContent = url, + errorMessage = "", + ) + } + delay(50) + }.invokeOnCompletion { search() } + } + + fun onIntentConsumed() { + _subscribeUiState.update { it.copy(shouldNavigateToFeedPage = false) } + } + fun showDrawer() { _subscribeUiState.update { it.copy(visible = true) } } @@ -238,4 +260,5 @@ data class SubscribeUiState( val isSearchPage: Boolean = true, val newName: String = "", val renameDialogVisible: Boolean = false, + val shouldNavigateToFeedPage: Boolean = false, )