Skip to content

Commit

Permalink
Replace callback for opening links with link handler composition local
Browse files Browse the repository at this point in the history
  • Loading branch information
msasikanth committed Oct 18, 2023
1 parent cfdfdad commit 914e540
Show file tree
Hide file tree
Showing 10 changed files with 62 additions and 169 deletions.
1 change: 0 additions & 1 deletion androidApp/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -92,5 +92,4 @@ dependencies {
implementation(libs.androidx.work)
implementation(libs.sentry)
coreLibraryDesugaring(libs.desugarJdk)
implementation(libs.androidx.browser)
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,24 +16,17 @@
package dev.sasikanth.rss.reader

import android.app.Activity
import android.content.Intent
import android.graphics.Color
import android.net.Uri
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.appcompat.app.AppCompatActivity
import androidx.browser.customtabs.CustomTabsIntent
import androidx.core.net.toUri
import androidx.core.view.WindowCompat
import com.arkivanov.decompose.ComponentContext
import com.arkivanov.decompose.defaultComponentContext
import dev.sasikanth.rss.reader.app.App
import dev.sasikanth.rss.reader.di.ApplicationComponent
import dev.sasikanth.rss.reader.di.scopes.ActivityScope
import dev.sasikanth.rss.reader.repository.BrowserType
import dev.sasikanth.rss.reader.repository.BrowserType.Default
import dev.sasikanth.rss.reader.repository.BrowserType.InApp
import me.tatarka.inject.annotations.Component
import me.tatarka.inject.annotations.Provides

Expand All @@ -47,31 +40,7 @@ class MainActivity : AppCompatActivity() {

val activityComponent = ActivityComponent::class.create(activity = this)

setContent {
activityComponent.app(::openLink) { reportIssueLink -> openLink(reportIssueLink, Default) }
}
}

private fun openLink(url: String, browserType: BrowserType) {
when (browserType) {
Default -> {
val intent =
Intent(Intent.ACTION_VIEW, Uri.parse(url)).apply { flags = Intent.FLAG_ACTIVITY_NEW_TASK }
if (intent.resolveActivity(packageManager) != null) {
startActivity(intent)
} else {
openCustomTab(url)
}
}
InApp -> {
openCustomTab(url)
}
}
}

private fun openCustomTab(url: String) {
val intent = CustomTabsIntent.Builder().build()
intent.launchUrl(this, url.toUri())
setContent { activityComponent.app() }
}
}

Expand Down
55 changes: 19 additions & 36 deletions shared/src/commonMain/kotlin/dev/sasikanth/rss/reader/app/App.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import androidx.compose.material3.windowsizeclass.ExperimentalMaterial3WindowSiz
import androidx.compose.material3.windowsizeclass.calculateWindowSizeClass
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import com.arkivanov.decompose.extensions.compose.jetbrains.stack.Children
Expand All @@ -33,20 +32,17 @@ import dev.sasikanth.rss.reader.components.image.ImageLoader
import dev.sasikanth.rss.reader.components.image.LocalImageLoader
import dev.sasikanth.rss.reader.components.rememberDynamicColorState
import dev.sasikanth.rss.reader.home.ui.HomeScreen
import dev.sasikanth.rss.reader.repository.BrowserType
import dev.sasikanth.rss.reader.platform.LinkHandler
import dev.sasikanth.rss.reader.platform.LocalLinkHandler
import dev.sasikanth.rss.reader.resources.strings.ProvideStrings
import dev.sasikanth.rss.reader.search.ui.SearchScreen
import dev.sasikanth.rss.reader.settings.ui.SettingsScreen
import dev.sasikanth.rss.reader.share.LocalShareHandler
import dev.sasikanth.rss.reader.share.ShareHandler
import dev.sasikanth.rss.reader.utils.Constants
import dev.sasikanth.rss.reader.utils.LocalWindowSizeClass
import me.tatarka.inject.annotations.Assisted
import me.tatarka.inject.annotations.Inject

typealias App =
@Composable
(openLink: (String, BrowserType) -> Unit, openReportIssuePage: (String) -> Unit) -> Unit
typealias App = @Composable () -> Unit

@Inject
@Composable
Expand All @@ -55,21 +51,19 @@ fun App(
appPresenter: AppPresenter,
imageLoader: ImageLoader,
shareHandler: ShareHandler,
@Assisted openLink: (String, BrowserType) -> Unit,
@Assisted openReportIssuePage: (String) -> Unit
linkHandler: LinkHandler,
) {
val dynamicColorState = rememberDynamicColorState(imageLoader = imageLoader)

CompositionLocalProvider(
LocalImageLoader provides imageLoader,
LocalWindowSizeClass provides calculateWindowSizeClass(),
LocalDynamicColorState provides dynamicColorState,
LocalShareHandler provides shareHandler
LocalShareHandler provides shareHandler,
LocalLinkHandler provides linkHandler
) {
DynamicContentTheme(dynamicColorState) {
ProvideStrings {
val state by appPresenter.state.collectAsState()

Children(
modifier = Modifier.fillMaxSize(),
stack = appPresenter.screenStack,
Expand All @@ -79,31 +73,20 @@ fun App(
onBack = appPresenter::onBackClicked
)
) { child ->
val fillMaxSizeModifier = Modifier.fillMaxSize()
when (val screen = child.instance) {
is Screen.Home ->
HomeScreen(
homePresenter = screen.presenter,
openLink = { openLink(it, state.browserType) },
modifier = Modifier.fillMaxSize()
)
is Screen.Search ->
SearchScreen(
searchPresenter = screen.presenter,
openLink = { openLink(it, state.browserType) },
modifier = Modifier.fillMaxSize()
)
is Screen.Bookmarks ->
BookmarksScreen(
bookmarksPresenter = screen.presenter,
openLink = { openLink(it, state.browserType) },
modifier = Modifier.fillMaxSize()
)
is Screen.Settings ->
SettingsScreen(
settingsPresenter = screen.presenter,
modifier = Modifier.fillMaxSize(),
openReportIssuePage = { openReportIssuePage(Constants.REPORT_ISSUE_LINK) }
)
is Screen.Home -> {
HomeScreen(homePresenter = screen.presenter, modifier = fillMaxSizeModifier)
}
is Screen.Search -> {
SearchScreen(searchPresenter = screen.presenter, modifier = fillMaxSizeModifier)
}
is Screen.Bookmarks -> {
BookmarksScreen(bookmarksPresenter = screen.presenter, modifier = fillMaxSizeModifier)
}
is Screen.Settings -> {
SettingsScreen(settingsPresenter = screen.presenter, modifier = fillMaxSizeModifier)
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,20 +32,12 @@ import dev.sasikanth.rss.reader.di.scopes.ActivityScope
import dev.sasikanth.rss.reader.home.HomePresenter
import dev.sasikanth.rss.reader.refresh.LastUpdatedAt
import dev.sasikanth.rss.reader.repository.RssRepository
import dev.sasikanth.rss.reader.repository.SettingsRepository
import dev.sasikanth.rss.reader.search.SearchPresenter
import dev.sasikanth.rss.reader.settings.SettingsPresenter
import dev.sasikanth.rss.reader.utils.DispatchersProvider
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.cancel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import me.tatarka.inject.annotations.Inject

Expand Down Expand Up @@ -77,7 +69,6 @@ private typealias SettingsPresenterFactory =
class AppPresenter(
componentContext: ComponentContext,
dispatchersProvider: DispatchersProvider,
settingsRepository: SettingsRepository,
private val homePresenter: HomePresenterFactory,
private val searchPresenter: SearchPresentFactory,
private val bookmarksPresenter: BookmarkPresenterFactory,
Expand All @@ -90,15 +81,13 @@ class AppPresenter(
instanceKeeper.getOrCreate {
PresenterInstance(
dispatchersProvider = dispatchersProvider,
settingsRepository = settingsRepository,
lastUpdatedAt = lastUpdatedAt,
rssRepository = rssRepository
)
}

private val navigation = StackNavigation<Config>()

internal val state = presenterInstance.state
internal val screenStack: Value<ChildStack<*, Screen>> =
childStack(
source = navigation,
Expand Down Expand Up @@ -141,27 +130,12 @@ class AppPresenter(

private class PresenterInstance(
dispatchersProvider: DispatchersProvider,
settingsRepository: SettingsRepository,
private val lastUpdatedAt: LastUpdatedAt,
private val rssRepository: RssRepository
) : InstanceKeeper.Instance {

private val coroutineScope = CoroutineScope(SupervisorJob() + dispatchersProvider.main)

private val _state = MutableStateFlow(AppState.DEFAULT)
val state: StateFlow<AppState> =
_state.stateIn(
scope = coroutineScope,
started = SharingStarted.WhileSubscribed(5000),
initialValue = AppState.DEFAULT
)

init {
settingsRepository.browserType
.onEach { browserType -> _state.update { it.copy(browserType = browserType) } }
.launchIn(coroutineScope)
}

fun refreshFeedsIfExpired() {
coroutineScope.launch {
if (lastUpdatedAt.hasExpired()) {
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
Expand All @@ -47,20 +48,23 @@ import dev.sasikanth.rss.reader.bookmarks.BookmarksEvent
import dev.sasikanth.rss.reader.bookmarks.BookmarksPresenter
import dev.sasikanth.rss.reader.components.ScrollToTopButton
import dev.sasikanth.rss.reader.home.ui.PostListItem
import dev.sasikanth.rss.reader.platform.LocalLinkHandler
import dev.sasikanth.rss.reader.resources.strings.LocalStrings
import dev.sasikanth.rss.reader.ui.AppTheme
import kotlinx.coroutines.launch

@Composable
internal fun BookmarksScreen(
bookmarksPresenter: BookmarksPresenter,
openLink: (String) -> Unit,
modifier: Modifier = Modifier
) {
val state by bookmarksPresenter.state.collectAsState()
val bookmarks = state.bookmarks.collectAsLazyPagingItems()
val listState = rememberLazyListState()
val coroutineScope = rememberCoroutineScope()
val showScrollToTop by remember { derivedStateOf { listState.firstVisibleItemIndex > 0 } }
val layoutDirection = LocalLayoutDirection.current
val linkHandler = LocalLinkHandler.current

Scaffold(
modifier = modifier,
Expand Down Expand Up @@ -104,11 +108,13 @@ internal fun BookmarksScreen(
PostListItem(
item = post,
enablePostSource = false,
onClick = { openLink(post.link) },
onClick = { coroutineScope.launch { linkHandler.openLink(post.link) } },
onPostBookmarkClick = {
bookmarksPresenter.dispatch(BookmarksEvent.OnPostBookmarkClick(post))
},
onPostCommentsClick = { openLink(post.commentsLink!!) },
onPostCommentsClick = {
post.commentsLink?.let { coroutineScope.launch { linkHandler.openLink(it) } }
},
onPostSourceClick = {
// no-op
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ import dev.sasikanth.rss.reader.home.HomeEvent
import dev.sasikanth.rss.reader.home.HomePresenter
import dev.sasikanth.rss.reader.home.HomeState
import dev.sasikanth.rss.reader.models.local.PostWithMetadata
import dev.sasikanth.rss.reader.platform.LocalLinkHandler
import dev.sasikanth.rss.reader.resources.strings.LocalStrings
import dev.sasikanth.rss.reader.resources.strings.TwineStrings
import dev.sasikanth.rss.reader.ui.AppTheme
Expand All @@ -99,11 +100,7 @@ private val BOTTOM_SHEET_CORNER_SIZE = 32.dp

@OptIn(ExperimentalFoundationApi::class)
@Composable
internal fun HomeScreen(
homePresenter: HomePresenter,
openLink: (String) -> Unit,
modifier: Modifier = Modifier
) {
internal fun HomeScreen(homePresenter: HomePresenter, modifier: Modifier = Modifier) {
val coroutineScope = rememberCoroutineScope()
val state by homePresenter.state.collectAsState()

Expand All @@ -130,12 +127,13 @@ internal fun HomeScreen(
bottomSheetSwipeTransition.animateDp { BOTTOM_SHEET_CORNER_SIZE * it.inverseProgress() }

val strings = LocalStrings.current
val linkHandler = LocalLinkHandler.current

LaunchedEffect(Unit) {
homePresenter.effects.collect { effect ->
when (effect) {
is HomeEffect.OpenPost -> {
openLink(effect.post.link)
linkHandler.openLink(effect.post.link)
}
HomeEffect.MinimizeSheet -> {
bottomSheetState.collapse()
Expand Down Expand Up @@ -177,7 +175,9 @@ internal fun HomeScreen(
onSwipeToRefresh = { homePresenter.dispatch(HomeEvent.OnSwipeToRefresh) },
onPostClicked = { homePresenter.dispatch(HomeEvent.OnPostClicked(it)) },
onPostBookmarkClick = { homePresenter.dispatch(HomeEvent.OnPostBookmarkClick(it)) },
onPostCommentsClick = { commentsLink -> openLink(commentsLink) },
onPostCommentsClick = { commentsLink ->
coroutineScope.launch { linkHandler.openLink(commentsLink) }
},
onPostSourceClick = { feedLink ->
homePresenter.dispatch(HomeEvent.OnPostSourceClicked(feedLink))
},
Expand Down
Loading

0 comments on commit 914e540

Please sign in to comment.