Skip to content
This repository has been archived by the owner on Nov 12, 2024. It is now read-only.

Migrate to Circuit #1288

Merged
merged 37 commits into from
May 30, 2023
Merged

Migrate to Circuit #1288

merged 37 commits into from
May 30, 2023

Conversation

chrisbanes
Copy link
Owner

@chrisbanes chrisbanes commented May 26, 2023

  • Fix navigation to settings

@chrisbanes chrisbanes marked this pull request as ready for review May 26, 2023 13:11
Copy link
Contributor

@ZacSweers ZacSweers left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is really cool! Bunch of questions for ya about things that we could maybe do better on the Circuit side

val configuration = LocalConfiguration.current
val useBottomNavigation = configuration.smallestScreenWidthDp < 600

val rootScreen by remember {
derivedStateOf { backstack.last().screen }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clever 👍

Comment on lines +108 to 116
// Launch an effect to track changes to the current back stack entry, and push them
// as a screen views to analytics
LaunchedEffect(backstack.topRecord) {
val topScreen = backstack.topRecord?.screen as? TiviScreen
analytics.trackScreenView(
name = topScreen?.name ?: "unknown screen",
arguments = topScreen?.arguments,
)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We do this with a delegating navigator inside of slack. This works too though! The delegating navigator made it easy for us to actually set this up with tracing, so we get spans as screens are pushed and popped off too

import kotlinx.coroutines.launch

@OptIn(ExperimentalMaterial3Api::class)
class BottomSheetOverlay<Model : Any, Result : Any>(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think we should offer a batteries-included component like this? Definitely know there's like 4 different implementations of this same idea floating around different repos at the moment heh

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I was thinking the same thing. Probably worth keeping as a separate artifact. It also gets tricky with Jetpack Compose vs Compose Multiplatform.

}
}

suspend fun OverlayHost.showInBottomSheet(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice

object UpNextScreen : TiviScreen(name = "UpNext()")

abstract class TiviScreen(val name: String) : Screen {
open val arguments: Map<String, *>? = null
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd be curious to learn more about this!

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are solely there for analytics. These gets pushed up to Crashlytics along with screen views.

Comment on lines +26 to +34
@IntoSet
@Provides
@ApplicationScope
fun bindAccountPresenterFactory(factory: AccountUiPresenterFactory): Presenter.Factory = factory

@IntoSet
@Provides
@ApplicationScope
fun bindAccountUiFactory(factory: AccountUiFactory): Ui.Factory = factory
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think there's anything we could do to make these kind of stuff easier to use in other DI systems like kotlin-inject? We built anvil support mostly because that's just what we use, but open to supporting other stuff if there's stuff you think is reusable

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another option is you could group these together into one composite factory, and possibly even cover multiple screens within it

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personally I didn't have a problem with writing these.

kotlin-inject makes creating the assisted injection factory super simple, which helped a lot.

I'm not sure how much of this stuff could be transferable across DI systems tbh.

Comment on lines +42 to +51
class AccountUiPresenterFactory(
private val presenterFactory: (Navigator) -> AccountPresenter,
) : Presenter.Factory {
override fun create(screen: Screen, navigator: Navigator, context: CircuitContext): Presenter<*>? {
return when (screen) {
is AccountScreen -> presenterFactory(navigator)
else -> null
}
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For cases not using a code gen tool, anything we could do to make these simpler? Maybe a ScreenPresenterFactory(Screen,Function) API that dries some of this up?

Copy link
Owner Author

@chrisbanes chrisbanes May 27, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about writing exactly that, but the only thing you're really saving is the when.

You still need a class somewhere to inject the assisted factory. I guess you could move that to the component/module instead, and just call a ScreenPresenterFactory(). I prefer the explicitness here though.

Comment on lines +57 to +61
override fun create(
screen: Screen,
navigator: Navigator,
context: CircuitContext,
): Presenter<*>? = when (screen) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Side not - these are fun interface so could it be simpler to use the function syntax?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ehh nevermind I guess it's not possible to use class delegation with a function input. Tried it locally without success

# Conflicts:
#	android-app/app/src/main/java/app/tivi/AppNavigation.kt
#	android-app/app/src/main/java/app/tivi/ComposeScreens.kt
#	android-app/app/src/main/java/app/tivi/NavigationUtils.kt
#	android-app/app/src/main/java/app/tivi/inject/ApiComponent.kt
#	common/ui/compose/src/main/java/app/tivi/common/compose/ViewModel.kt
#	common/ui/screens/src/androidMain/kotlin/app/tivi/screens/Platform.kt
#	common/ui/screens/src/jvmMain/kotlin/app/tivi/screens/Platform.kt
#	ui/account/src/main/java/app/tivi/account/AccountUi.kt
#	ui/discover/src/main/java/app/tivi/home/discover/Discover.kt
#	ui/library/src/main/java/app/tivi/home/library/Library.kt
#	ui/library/src/main/java/app/tivi/home/library/LibraryUiState.kt
#	ui/popular/src/main/java/app/tivi/home/popular/Popular.kt
#	ui/recommended/src/main/java/app/tivi/home/recommended/Recommended.kt
#	ui/search/src/main/java/app/tivi/home/search/Search.kt
#	ui/search/src/main/java/app/tivi/home/search/SearchUiState.kt
#	ui/show/details/src/main/java/app/tivi/showdetails/details/ShowDetails.kt
#	ui/show/seasons/src/main/java/app/tivi/showdetails/seasons/ShowSeasons.kt
#	ui/trending/src/main/java/app/tivi/home/trending/Trending.kt
@chrisbanes chrisbanes enabled auto-merge (rebase) May 29, 2023 15:19
auto-merge was automatically disabled May 29, 2023 15:43

Rebase failed

@chrisbanes chrisbanes merged commit 6d81143 into main May 30, 2023
@chrisbanes chrisbanes deleted the cb/circuit branch May 30, 2023 07:23
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants