Skip to content

Commit

Permalink
feat(ui): add feed via system share sheet (#618)
Browse files Browse the repository at this point in the history
  • Loading branch information
JunkFood02 authored Feb 14, 2024
1 parent 8f4d241 commit 4c7bea9
Show file tree
Hide file tree
Showing 5 changed files with 122 additions and 9 deletions.
35 changes: 35 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,52 @@
<activity
android:name=".infrastructure.android.MainActivity"
android:exported="true"
android:launchMode="singleInstance"
android:theme="@style/Theme.Reader">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />

<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />

<data android:scheme="http" />
<data android:scheme="https" />

<data android:host="*" />

<data android:mimeType="text/xml" />
<data android:mimeType="application/rss+xml" />
<data android:mimeType="application/atom+xml" />
<data android:mimeType="application/xml" />
<data android:mimeType="application/json" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND" />

<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />

<data android:scheme="http" />
<data android:scheme="https" />
<data android:host="*" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />

<data android:mimeType="text/plain" />
</intent-filter>
</activity>
<activity
android:name=".infrastructure.android.CrashReportActivity"
android:exported="false"
android:theme="@style/Theme.Reader">

</activity>

<provider
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package me.ash.reader.infrastructure.android

import android.content.Intent
import android.database.CursorWindow
import android.os.Build
import android.os.Bundle
Expand All @@ -9,7 +10,10 @@ import android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
import androidx.activity.compose.setContent
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.DisposableEffect
import androidx.core.util.Consumer
import androidx.core.view.WindowCompat
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.profileinstaller.ProfileInstallerInitializer
import coil.ImageLoader
import coil.compose.LocalImageLoader
Expand All @@ -20,8 +24,8 @@ import me.ash.reader.infrastructure.preference.LanguagesPreference
import me.ash.reader.infrastructure.preference.SettingsProvider
import me.ash.reader.ui.ext.languages
import me.ash.reader.ui.page.common.HomeEntry
import me.ash.reader.ui.page.home.feeds.subscribe.SubscribeViewModel
import java.lang.reflect.Field
import java.util.Locale
import javax.inject.Inject


Expand All @@ -30,7 +34,6 @@ import javax.inject.Inject
*/
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {

@Inject
lateinit var imageLoader: ImageLoader

Expand Down Expand Up @@ -67,10 +70,39 @@ class MainActivity : AppCompatActivity() {
) {
AccountSettingsProvider(accountDao) {
SettingsProvider {
HomeEntry()
val subscribeViewModel: SubscribeViewModel = hiltViewModel()
DisposableEffect(this) {
val listener = Consumer<Intent> { 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
}

}
27 changes: 25 additions & 2 deletions app/src/main/java/me/ash/reader/ui/page/common/HomeEntry.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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) }
Expand Down Expand Up @@ -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()
}
}

Expand Down Expand Up @@ -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(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ fun FeedsPage(
}
)

SubscribeDialog()
SubscribeDialog(subscribeViewModel = subscribeViewModel)
GroupOptionDrawer()
FeedOptionDrawer()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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))
}
}

Expand All @@ -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 = "") }
}
Expand Down Expand Up @@ -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,
)
}
Expand Down Expand Up @@ -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) }
}
Expand Down Expand Up @@ -238,4 +260,5 @@ data class SubscribeUiState(
val isSearchPage: Boolean = true,
val newName: String = "",
val renameDialogVisible: Boolean = false,
val shouldNavigateToFeedPage: Boolean = false,
)

0 comments on commit 4c7bea9

Please sign in to comment.