diff --git a/app-wear/src/main/java/movie/metropolis/app/di/FacadeModule.kt b/app-wear/src/main/java/movie/metropolis/app/di/FacadeModule.kt index 49684498..94e44902 100644 --- a/app-wear/src/main/java/movie/metropolis/app/di/FacadeModule.kt +++ b/app-wear/src/main/java/movie/metropolis/app/di/FacadeModule.kt @@ -2,6 +2,7 @@ package movie.metropolis.app.di import dagger.Module import dagger.Provides +import dagger.Reusable import dagger.hilt.InstallIn import dagger.hilt.android.components.ActivityRetainedComponent import movie.metropolis.app.presentation.booking.BookingsFacade @@ -14,6 +15,7 @@ import movie.wear.WearService class FacadeModule { @Provides + @Reusable fun booking( service: WearService ): BookingsFacade { diff --git a/app/src/main/java/movie/metropolis/app/di/FacadeModule.kt b/app/src/main/java/movie/metropolis/app/di/FacadeModule.kt index d34f2cef..93688230 100644 --- a/app/src/main/java/movie/metropolis/app/di/FacadeModule.kt +++ b/app/src/main/java/movie/metropolis/app/di/FacadeModule.kt @@ -2,6 +2,7 @@ package movie.metropolis.app.di import dagger.Module import dagger.Provides +import dagger.Reusable import dagger.hilt.InstallIn import dagger.hilt.android.components.ActivityRetainedComponent import movie.calendar.CalendarList @@ -75,6 +76,7 @@ import movie.rating.MetadataProvider class FacadeModule { @Provides + @Reusable fun booking( booking: UserBookingFeature, share: TicketShareRegistry, @@ -90,6 +92,7 @@ class FacadeModule { } @Provides + @Reusable fun cinemas(event: EventCinemaFeature): CinemasFacade { var facade: CinemasFacade facade = CinemasFacadeFromFeature(event) @@ -98,10 +101,11 @@ class FacadeModule { } @Provides + @Reusable fun cinema( cinemas: EventCinemaFeature, showings: EventShowingsFeature.Factory - ) = CinemaFacade.Factory { + ): CinemaFacade.Factory = CinemaFacade.Factory { var facade: CinemaFacade facade = CinemaFacadeFromFeature(it, cinemas, showings) facade = CinemaFacadeRecover(facade) @@ -110,13 +114,14 @@ class FacadeModule { } @Provides + @Reusable fun movie( showings: EventShowingsFeature.Factory, detail: EventDetailFeature, favorite: FavoriteFeature, analyzer: ImageAnalyzer, rating: MetadataProvider - ) = MovieFacade.Factory { + ): MovieFacade.Factory = MovieFacade.Factory { var facade: MovieFacade facade = MovieFacadeFromFeature(it, showings, detail, favorite) facade = MovieFacadePoster(facade, analyzer) @@ -128,6 +133,7 @@ class FacadeModule { } @Provides + @Reusable fun listing( preview: EventPreviewFeature.Factory, favorite: FavoriteFeature, @@ -152,6 +158,7 @@ class FacadeModule { } @Provides + @Reusable fun profile( cinema: EventCinemaFeature, user: UserDataFeature, @@ -165,6 +172,7 @@ class FacadeModule { } @Provides + @Reusable fun login( user: UserCredentialFeature, setup: SetupFeature, @@ -176,6 +184,7 @@ class FacadeModule { } @Provides + @Reusable fun order( user: UserCredentialFeature, booking: BookingFacade @@ -188,6 +197,7 @@ class FacadeModule { } @Provides + @Reusable fun settings( prefs: EventPreference, calendars: CalendarList @@ -200,11 +210,13 @@ class FacadeModule { } @Provides + @Reusable fun home(user: UserCredentialFeature): HomeFacade { return HomeFacadeFromFeature(user) } @Provides + @Reusable fun share( share: TicketShareRegistry, user: UserBookingFeature @@ -218,6 +230,7 @@ class FacadeModule { } @Provides + @Reusable fun setup( feature: SetupFeature ): SetupFacade { @@ -227,6 +240,7 @@ class FacadeModule { } @Provides + @Reusable fun orderComplete( facade: BillingFacade ): OrderCompleteFacade { diff --git a/app/src/main/java/movie/metropolis/app/di/NotificationModule.kt b/app/src/main/java/movie/metropolis/app/di/NotificationModule.kt index 499848c7..88940641 100644 --- a/app/src/main/java/movie/metropolis/app/di/NotificationModule.kt +++ b/app/src/main/java/movie/metropolis/app/di/NotificationModule.kt @@ -4,6 +4,7 @@ import android.content.Context import dagger.Binds import dagger.Module import dagger.Provides +import dagger.Reusable import dagger.hilt.InstallIn import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.components.SingletonComponent @@ -20,6 +21,7 @@ interface NotificationModule { companion object { @Provides + @Reusable fun provider( @ApplicationContext context: Context diff --git a/app/src/main/java/movie/metropolis/app/di/PlatformModule.kt b/app/src/main/java/movie/metropolis/app/di/PlatformModule.kt index e7cb35fc..a8660e91 100644 --- a/app/src/main/java/movie/metropolis/app/di/PlatformModule.kt +++ b/app/src/main/java/movie/metropolis/app/di/PlatformModule.kt @@ -3,6 +3,7 @@ package movie.metropolis.app.di import android.content.Context import dagger.Module import dagger.Provides +import dagger.Reusable import dagger.hilt.InstallIn import dagger.hilt.android.components.ActivityRetainedComponent import dagger.hilt.android.qualifiers.ApplicationContext @@ -14,6 +15,7 @@ import movie.metropolis.app.feature.billing.BillingFacadeImpl class PlatformModule { @Provides + @Reusable fun billing( @ApplicationContext context: Context ): BillingFacade { diff --git a/app/src/main/java/movie/metropolis/app/screen/booking/BookingScreen.kt b/app/src/main/java/movie/metropolis/app/screen/booking/BookingScreen.kt index 1bf48aa7..cda5c87d 100644 --- a/app/src/main/java/movie/metropolis/app/screen/booking/BookingScreen.kt +++ b/app/src/main/java/movie/metropolis/app/screen/booking/BookingScreen.kt @@ -25,6 +25,7 @@ import movie.metropolis.app.screen.booking.component.TicketItemEmpty import movie.metropolis.app.screen.booking.component.TicketItemError import movie.metropolis.app.screen.booking.component.TicketItemExpired import movie.metropolis.app.screen.booking.component.TicketItemLoading +import movie.metropolis.app.screen.home.component.HomeScreenToolbar import movie.style.AppButton import movie.style.state.ImmutableList import movie.style.theme.Theme @@ -32,9 +33,9 @@ import movie.style.theme.Theme @OptIn(ExperimentalMaterial3Api::class) @Composable fun BookingScreen( - padding: PaddingValues, behavior: TopAppBarScrollBehavior, onMovieClick: (String) -> Unit, + profileIcon: @Composable () -> Unit, viewModel: BookingViewModel = hiltViewModel(), actions: ActivityActions = LocalActivityActions.current ) { @@ -43,19 +44,18 @@ fun BookingScreen( val scope = rememberCoroutineScope() var isReaderActive by rememberSaveable { mutableStateOf(false) } BookingScreenContent( - padding = padding, behavior = behavior, active = active, expired = expired, + profileIcon = profileIcon, onRefreshClick = viewModel::refresh, onMovieClick = onMovieClick, onShareClick = { scope.launch { actions.actionShare(viewModel.saveAsFile(it)) } - }, - onCameraClick = { isReaderActive = true } - ) + } + ) { isReaderActive = true } ReaderDialog( isVisible = isReaderActive, onVisibilityChanged = { isReaderActive = it }, @@ -66,15 +66,23 @@ fun BookingScreen( @OptIn(ExperimentalMaterial3Api::class, ExperimentalFoundationApi::class) @Composable private fun BookingScreenContent( - padding: PaddingValues, active: Loadable>, expired: Loadable>, behavior: TopAppBarScrollBehavior, + profileIcon: @Composable () -> Unit, onRefreshClick: () -> Unit = {}, onMovieClick: (String) -> Unit = {}, onShareClick: (BookingView.Active) -> Unit = {}, onCameraClick: () -> Unit = {} -) { +) = Scaffold( + topBar = { + HomeScreenToolbar( + profileIcon = profileIcon, + behavior = behavior, + title = { Text(stringResource(id = R.string.tickets)) } + ) + } +) { padding -> Column( modifier = Modifier .nestedScroll(behavior.nestedScrollConnection) @@ -159,10 +167,10 @@ private fun BookingScreenContent( private fun Preview() { Theme { BookingScreenContent( - padding = PaddingValues(), active = Loadable.loading(), expired = Loadable.loading(), - behavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior() + behavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior(), + profileIcon = {} ) } } \ No newline at end of file diff --git a/app/src/main/java/movie/metropolis/app/screen/cinema/CinemasScreen.kt b/app/src/main/java/movie/metropolis/app/screen/cinema/CinemasScreen.kt index 771eaf27..b2597a78 100644 --- a/app/src/main/java/movie/metropolis/app/screen/cinema/CinemasScreen.kt +++ b/app/src/main/java/movie/metropolis/app/screen/cinema/CinemasScreen.kt @@ -8,10 +8,12 @@ import androidx.compose.material3.* import androidx.compose.runtime.* import androidx.compose.ui.* import androidx.compose.ui.input.nestedscroll.* +import androidx.compose.ui.res.* import androidx.compose.ui.tooling.preview.* import androidx.compose.ui.tooling.preview.datasource.* import androidx.compose.ui.unit.* import androidx.hilt.navigation.compose.hiltViewModel +import movie.metropolis.app.R import movie.metropolis.app.feature.location.rememberLocation import movie.metropolis.app.model.CinemaView import movie.metropolis.app.presentation.Loadable @@ -25,14 +27,15 @@ import movie.metropolis.app.screen.cinema.component.CinemaItemError import movie.metropolis.app.screen.cinema.component.CinemaItemLoading import movie.metropolis.app.screen.cinema.component.CinemaViewParameter import movie.metropolis.app.screen.detail.plus +import movie.metropolis.app.screen.home.component.HomeScreenToolbar import movie.style.layout.PreviewLayout @OptIn(ExperimentalMaterial3Api::class) @Composable fun CinemasScreen( - padding: PaddingValues, onClickCinema: (String) -> Unit, state: LazyListState, + profileIcon: @Composable () -> Unit, behavior: TopAppBarScrollBehavior, viewModel: CinemasViewModel = hiltViewModel() ) { @@ -44,7 +47,7 @@ fun CinemasScreen( CinemasScreen( items = items, behavior = behavior, - padding = padding, + profileIcon = profileIcon, onClickCinema = onClickCinema, state = state ) @@ -54,11 +57,19 @@ fun CinemasScreen( @Composable private fun CinemasScreen( items: Loadable>, - padding: PaddingValues, behavior: TopAppBarScrollBehavior, + profileIcon: @Composable () -> Unit, onClickCinema: (String) -> Unit, state: LazyListState = rememberLazyListState() -) { +) = Scaffold( + topBar = { + HomeScreenToolbar( + profileIcon = profileIcon, + behavior = behavior, + title = { Text(stringResource(id = R.string.cinemas)) } + ) + } +) { padding -> LazyColumn( modifier = Modifier .nestedScroll(behavior.nestedScrollConnection) @@ -100,7 +111,7 @@ private fun CinemaItemPreview( ) = PreviewLayout(padding = PaddingValues()) { CinemasScreen( items = items, - padding = PaddingValues(), + profileIcon = {}, behavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior(), onClickCinema = {} ) diff --git a/app/src/main/java/movie/metropolis/app/screen/home/HomeScreen.kt b/app/src/main/java/movie/metropolis/app/screen/home/HomeScreen.kt index 683a0daf..b4bdebfe 100644 --- a/app/src/main/java/movie/metropolis/app/screen/home/HomeScreen.kt +++ b/app/src/main/java/movie/metropolis/app/screen/home/HomeScreen.kt @@ -1,8 +1,6 @@ package movie.metropolis.app.screen.home -import androidx.compose.animation.* import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.* import androidx.compose.material3.* import androidx.compose.runtime.* import androidx.compose.ui.* @@ -21,8 +19,8 @@ import movie.metropolis.app.screen.cinema.CinemasScreen import movie.metropolis.app.screen.cinema.CinemasViewModel import movie.metropolis.app.screen.currentDestinationAsState import movie.metropolis.app.screen.home.component.HomeScreenContent -import movie.metropolis.app.screen.home.component.HomeScreenToolbar import movie.metropolis.app.screen.home.component.ProfileIcon +import movie.metropolis.app.screen.home.component.rememberScreenState import movie.metropolis.app.screen.listing.ListingScreen import movie.metropolis.app.screen.listing.ListingViewModel import movie.metropolis.app.screen.settings.SettingsScreen @@ -35,7 +33,7 @@ import movie.style.haptic.ClickOnChange import movie.style.theme.Theme @OptIn( - ExperimentalAnimationApi::class, ExperimentalMaterial3Api::class, + ExperimentalMaterial3Api::class, ExperimentalComposeUiApi::class ) @Composable @@ -50,14 +48,9 @@ fun HomeScreen( ) { val email = viewModel.email val destination by controller.currentDestinationAsState() - val behavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior() - LaunchedEffect(destination) { - behavior.state.contentOffset = 0f - } HomeScreen( isLoggedIn = email != null, route = destination?.route ?: startWith, - behavior = behavior, onRouteChanged = listener@{ if (destination?.route == it) return@listener while (controller.popBackStack()) { @@ -65,30 +58,18 @@ fun HomeScreen( } controller.navigate(it) }, - title = { - val text = when (destination?.route) { - Route.Cinemas() -> stringResource(id = R.string.cinemas) - Route.Movies() -> stringResource(id = R.string.movies) - Route.Tickets() -> stringResource(id = R.string.tickets) - Route.Settings() -> stringResource(id = R.string.settings) - else -> "" - } - Text(text) - }, - profileIcon = { + onNavigateToLogin = onClickLogin + ) { + val listing = rememberScreenState() + val cinemas = rememberScreenState() + val booking = rememberScreenState() + val settings = rememberScreenState() + val profileIcon = @Composable { if (email != null) ProfileIcon( email = email, onClick = onClickUser ) - }, - onNavigateToLogin = onClickLogin - ) { - val moviesState = rememberLazyListState() - val cinemasState = rememberLazyListState() - val listing: ListingViewModel = hiltViewModel() - val cinemas: CinemasViewModel = hiltViewModel() - val booking: BookingViewModel = hiltViewModel() - val settings: SettingsViewModel = hiltViewModel() + } HomeScreenContent( modifier = Modifier.semantics { testTagsAsResourceId = true @@ -97,64 +78,53 @@ fun HomeScreen( controller = controller, listing = { ListingScreen( - padding = PaddingValues(), - behavior = behavior, - onClickMovie = onClickMovie, - state = moviesState, - viewModel = listing + behavior = listing.behavior, + state = listing.list, + viewModel = listing.viewModel, + profileIcon = profileIcon, + onClickMovie = onClickMovie ) }, cinemas = { CinemasScreen( - padding = PaddingValues(), - onClickCinema = onClickCinema, - state = cinemasState, - behavior = behavior, - viewModel = cinemas + behavior = cinemas.behavior, + state = cinemas.list, + viewModel = cinemas.viewModel, + profileIcon = profileIcon, + onClickCinema = onClickCinema ) }, booking = { BookingScreen( - padding = PaddingValues(), - behavior = behavior, - onMovieClick = { onClickMovie(it, true) }, - viewModel = booking + behavior = booking.behavior, + viewModel = booking.viewModel, + profileIcon = profileIcon, + onMovieClick = { onClickMovie(it, true) } ) }, settings = { SettingsScreen( - padding = PaddingValues(), - behavior = behavior, - viewModel = settings + behavior = settings.behavior, + viewModel = settings.viewModel, + profileIcon = profileIcon, ) } ) } } -@OptIn(ExperimentalMaterial3Api::class) @Composable private fun HomeScreen( isLoggedIn: Boolean, route: String, onNavigateToLogin: () -> Unit, - title: @Composable () -> Unit, - profileIcon: @Composable () -> Unit, onRouteChanged: (String) -> Unit, - behavior: TopAppBarScrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior(), content: @Composable () -> Unit ) { ClickOnChange(route) AppScaffold( contentWindowInsets = ScaffoldDefaults.contentWindowInsets .only(WindowInsetsSides.Bottom + WindowInsetsSides.Horizontal), - topBar = { - HomeScreenToolbar( - profileIcon = profileIcon, - behavior = behavior, - title = title - ) - }, floatingActionButton = { if (!isLoggedIn) AppButton( onClick = onNavigateToLogin, diff --git a/app/src/main/java/movie/metropolis/app/screen/home/component/ScreenState.kt b/app/src/main/java/movie/metropolis/app/screen/home/component/ScreenState.kt new file mode 100644 index 00000000..ad7a8016 --- /dev/null +++ b/app/src/main/java/movie/metropolis/app/screen/home/component/ScreenState.kt @@ -0,0 +1,24 @@ +package movie.metropolis.app.screen.home.component + +import androidx.compose.foundation.lazy.* +import androidx.compose.material3.* +import androidx.compose.runtime.* +import androidx.hilt.navigation.compose.hiltViewModel +import androidx.lifecycle.ViewModel + +@OptIn(ExperimentalMaterial3Api::class) +data class ScreenState( + val behavior: TopAppBarScrollBehavior, + val list: LazyListState, + val viewModel: T +) + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +inline fun rememberScreenState(): ScreenState { + return ScreenState( + behavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior(), + list = rememberLazyListState(), + viewModel = hiltViewModel() + ) +} \ No newline at end of file diff --git a/app/src/main/java/movie/metropolis/app/screen/listing/ListingScreen.kt b/app/src/main/java/movie/metropolis/app/screen/listing/ListingScreen.kt index ede63e51..1baf22cd 100644 --- a/app/src/main/java/movie/metropolis/app/screen/listing/ListingScreen.kt +++ b/app/src/main/java/movie/metropolis/app/screen/listing/ListingScreen.kt @@ -23,6 +23,7 @@ import movie.metropolis.app.presentation.Loadable import movie.metropolis.app.presentation.onFailure import movie.metropolis.app.presentation.onLoading import movie.metropolis.app.presentation.onSuccess +import movie.metropolis.app.screen.home.component.HomeScreenToolbar import movie.metropolis.app.screen.listing.component.MoviePromo import movie.metropolis.app.screen.listing.component.MovieRow import movie.style.state.ImmutableList.Companion.immutable @@ -32,9 +33,9 @@ import movie.style.theme.Theme @OptIn(ExperimentalMaterial3Api::class) @Composable fun ListingScreen( - padding: PaddingValues, behavior: TopAppBarScrollBehavior, onClickMovie: (String, upcoming: Boolean) -> Unit, + profileIcon: @Composable () -> Unit, state: LazyListState, viewModel: ListingViewModel = hiltViewModel(), actions: ActivityActions = LocalActivityActions.current @@ -49,9 +50,9 @@ fun ListingScreen( upcomingPromotions = upcomingPromotions, currentGroups = currentGroups, upcomingGroups = upcomingGroups, - contentPadding = padding, behavior = behavior, state = state, + profileIcon = profileIcon, onClickFavorite = { scope.launch { val granted = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { @@ -77,19 +78,27 @@ private fun ListingScreenContent( upcomingPromotions: Loadable>, currentGroups: Loadable>>, upcomingGroups: Loadable>>, - contentPadding: PaddingValues, behavior: TopAppBarScrollBehavior, state: LazyListState, + profileIcon: @Composable () -> Unit, onClickFavorite: (MovieView) -> Unit, onClick: (String, upcoming: Boolean) -> Unit -) { +) = Scaffold( + topBar = { + HomeScreenToolbar( + profileIcon = profileIcon, + behavior = behavior, + title = { Text(stringResource(id = R.string.movies)) } + ) + } +) { padding -> val context = LocalContext.current LazyColumn( modifier = Modifier .fillMaxSize() .nestedScroll(behavior.nestedScrollConnection) .testTag("listingColumn"), - contentPadding = contentPadding, + contentPadding = padding, state = state, ) { item { MoviePromo(items = currentPromotions, onClick = { onClick(it, false) }) } diff --git a/app/src/main/java/movie/metropolis/app/screen/settings/SettingsScreen.kt b/app/src/main/java/movie/metropolis/app/screen/settings/SettingsScreen.kt index 4217a368..fd198570 100644 --- a/app/src/main/java/movie/metropolis/app/screen/settings/SettingsScreen.kt +++ b/app/src/main/java/movie/metropolis/app/screen/settings/SettingsScreen.kt @@ -26,6 +26,7 @@ import movie.metropolis.app.ActivityActions import movie.metropolis.app.LocalActivityActions import movie.metropolis.app.R import movie.metropolis.app.screen.detail.plus +import movie.metropolis.app.screen.home.component.HomeScreenToolbar import movie.style.AppDialog import movie.style.AppSettings import movie.style.InputField @@ -36,8 +37,8 @@ import movie.style.theme.Theme @OptIn(ExperimentalMaterial3Api::class) @Composable fun SettingsScreen( - padding: PaddingValues, behavior: TopAppBarScrollBehavior, + profileIcon: @Composable () -> Unit, viewModel: SettingsViewModel ) { val filterSeen by viewModel.filterSeen.collectAsState() @@ -46,8 +47,8 @@ fun SettingsScreen( val clipRadius by viewModel.clipRadius.collectAsState() val onlyMovies by viewModel.onlyMovies.collectAsState() SettingsScreen( - padding = padding, behavior = behavior, + profileIcon = profileIcon, filterSeen = filterSeen, onFilterSeenChanged = viewModel::updateFilterSeen, addToCalendar = addToCalendar, @@ -63,8 +64,8 @@ fun SettingsScreen( @OptIn(ExperimentalMaterial3Api::class) @Composable private fun SettingsScreen( - padding: PaddingValues = PaddingValues(), behavior: TopAppBarScrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(), + profileIcon: @Composable () -> Unit, filterSeen: Boolean = false, onFilterSeenChanged: (Boolean) -> Unit = {}, addToCalendar: Boolean = false, @@ -74,7 +75,15 @@ private fun SettingsScreen( onlyMovies: Boolean = false, onOnlyMoviesChanged: (Boolean) -> Unit = {}, calendars: ImmutableMap = immutableMapOf() -) { +) = Scaffold( + topBar = { + HomeScreenToolbar( + profileIcon = profileIcon, + behavior = behavior, + title = { Text(stringResource(id = R.string.settings)) } + ) + } +) { padding -> LazyColumn( modifier = Modifier .fillMaxSize() @@ -223,7 +232,7 @@ fun LazyItemScope.Calendar( stringResource(R.string.select_calendar_description), style = Theme.textStyle.caption ) - Divider() + HorizontalDivider() } } items(calendars.toList(), key = { (id) -> id }) { (id, name) -> @@ -249,6 +258,6 @@ fun LazyItemScope.Calendar( @Composable private fun Preview() { Theme { - SettingsScreen() + SettingsScreen(profileIcon = {}) } } \ No newline at end of file diff --git a/feature-calendar/src/main/java/movie/calendar/di/CalendarModule.kt b/feature-calendar/src/main/java/movie/calendar/di/CalendarModule.kt index 261b8dc8..72899f84 100644 --- a/feature-calendar/src/main/java/movie/calendar/di/CalendarModule.kt +++ b/feature-calendar/src/main/java/movie/calendar/di/CalendarModule.kt @@ -4,6 +4,7 @@ import android.content.ContentResolver import android.content.Context import dagger.Module import dagger.Provides +import dagger.Reusable import dagger.hilt.InstallIn import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.components.SingletonComponent @@ -19,6 +20,7 @@ import movie.calendar.CalendarWriterPreventIfExists internal class CalendarModule { @Provides + @Reusable fun list( resolver: ContentResolver ): CalendarList { @@ -29,6 +31,7 @@ internal class CalendarModule { } @Provides + @Reusable fun writer( resolver: ContentResolver ): CalendarWriter.Factory = CalendarWriter.Factory { id -> @@ -39,6 +42,7 @@ internal class CalendarModule { } @Provides + @Reusable fun resolver( @ApplicationContext context: Context diff --git a/feature-core-auth/src/main/java/movie/core/auth/di/AuthModule.kt b/feature-core-auth/src/main/java/movie/core/auth/di/AuthModule.kt index a03f8540..1827f3dc 100644 --- a/feature-core-auth/src/main/java/movie/core/auth/di/AuthModule.kt +++ b/feature-core-auth/src/main/java/movie/core/auth/di/AuthModule.kt @@ -4,6 +4,7 @@ import android.accounts.AccountManager import android.content.Context import dagger.Module import dagger.Provides +import dagger.Reusable import dagger.hilt.InstallIn import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.components.SingletonComponent @@ -23,6 +24,7 @@ import movie.core.auth.UserAccountLogout class AuthModule { @Provides + @Reusable fun account( @ApplicationContext context: Context, @@ -35,6 +37,7 @@ class AuthModule { } @Provides + @Reusable fun encryption( @ApplicationContext context: Context @@ -49,6 +52,7 @@ class AuthModule { } @Provides + @Reusable fun authMeta(): AuthMetadata = AuthMetadata( user = BuildConfig.BasicUser, password = BuildConfig.BasicPass, diff --git a/feature-core-network/src/main/java/movie/core/nwk/di/NetworkModule.kt b/feature-core-network/src/main/java/movie/core/nwk/di/NetworkModule.kt index 7f0c8698..54e6b233 100644 --- a/feature-core-network/src/main/java/movie/core/nwk/di/NetworkModule.kt +++ b/feature-core-network/src/main/java/movie/core/nwk/di/NetworkModule.kt @@ -2,6 +2,7 @@ package movie.core.nwk.di import dagger.Module import dagger.Provides +import dagger.Reusable import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent import io.ktor.client.HttpClient @@ -43,6 +44,7 @@ import javax.inject.Singleton class NetworkModule { @Provides + @Reusable fun serializer(): Json = Json { ignoreUnknownKeys = true explicitNulls = false @@ -50,6 +52,7 @@ class NetworkModule { @ClientRoot @Provides + @Singleton fun clientRoot( engine: HttpClientEngine, provider: EndpointProvider, @@ -81,6 +84,7 @@ class NetworkModule { @ClientData @Provides + @Singleton fun clientData( @ClientRoot client: LazyHttpClient, @@ -95,6 +99,7 @@ class NetworkModule { @ClientQuickbook @Provides + @Singleton fun clientQuickbook( @ClientRoot client: LazyHttpClient, @@ -109,6 +114,7 @@ class NetworkModule { @ClientCustomer @Provides + @Singleton fun clientCustomer( @ClientRoot client: LazyHttpClient, @@ -126,6 +132,7 @@ class NetworkModule { fun engine(): HttpClientEngine = LazyHttpClientEngine { CIO.create() } @Provides + @Reusable fun event( @ClientData client: LazyHttpClient, @@ -139,6 +146,7 @@ class NetworkModule { } @Provides + @Reusable fun cinema( @ClientRoot client: LazyHttpClient @@ -150,6 +158,7 @@ class NetworkModule { } @Provides + @Reusable fun user( @ClientCustomer client: LazyHttpClient, diff --git a/feature-core/src/main/java/movie/core/di/FavoriteFeatureModule.kt b/feature-core/src/main/java/movie/core/di/FavoriteFeatureModule.kt index 92c35c98..a529204c 100644 --- a/feature-core/src/main/java/movie/core/di/FavoriteFeatureModule.kt +++ b/feature-core/src/main/java/movie/core/di/FavoriteFeatureModule.kt @@ -2,6 +2,7 @@ package movie.core.di import dagger.Module import dagger.Provides +import dagger.Reusable import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent import movie.core.FavoriteFeature @@ -16,6 +17,7 @@ import movie.pulse.ExactPulseScheduler class FavoriteFeatureModule { @Provides + @Reusable fun feature( favorite: MovieFavoriteDao, media: MovieMediaDao, diff --git a/feature-core/src/main/java/movie/core/di/KotlinModule.kt b/feature-core/src/main/java/movie/core/di/KotlinModule.kt index d4efa642..caeeb727 100644 --- a/feature-core/src/main/java/movie/core/di/KotlinModule.kt +++ b/feature-core/src/main/java/movie/core/di/KotlinModule.kt @@ -4,6 +4,7 @@ import androidx.lifecycle.ProcessLifecycleOwner import androidx.lifecycle.lifecycleScope import dagger.Module import dagger.Provides +import dagger.Reusable import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent import kotlinx.coroutines.CoroutineScope @@ -13,6 +14,7 @@ import kotlinx.coroutines.CoroutineScope class KotlinModule { @Provides + @Reusable fun scope(): CoroutineScope = ProcessLifecycleOwner.get().lifecycleScope } \ No newline at end of file diff --git a/feature-core/src/main/java/movie/core/di/PreferenceModule.kt b/feature-core/src/main/java/movie/core/di/PreferenceModule.kt index a9b27bfa..585401ca 100644 --- a/feature-core/src/main/java/movie/core/di/PreferenceModule.kt +++ b/feature-core/src/main/java/movie/core/di/PreferenceModule.kt @@ -2,6 +2,7 @@ package movie.core.di import dagger.Module import dagger.Provides +import dagger.Reusable import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent import movie.core.preference.EventPreference @@ -21,6 +22,7 @@ import movie.settings.di.User class PreferenceModule { @Provides + @Reusable fun event( @Functionality store: PreferenceStore @@ -29,6 +31,7 @@ class PreferenceModule { } @Provides + @Reusable fun region( @User store: PreferenceStore @@ -37,6 +40,7 @@ class PreferenceModule { } @Provides + @Reusable fun sync( @User store: PreferenceStore @@ -45,6 +49,7 @@ class PreferenceModule { } @Provides + @Reusable fun user( @User store: PreferenceStore diff --git a/feature-core/src/main/java/movie/core/di/PulseModule.kt b/feature-core/src/main/java/movie/core/di/PulseModule.kt index 637f4133..6febccf6 100644 --- a/feature-core/src/main/java/movie/core/di/PulseModule.kt +++ b/feature-core/src/main/java/movie/core/di/PulseModule.kt @@ -3,6 +3,7 @@ package movie.core.di import android.content.Context import dagger.Module import dagger.Provides +import dagger.Reusable import dagger.hilt.InstallIn import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.components.SingletonComponent @@ -14,7 +15,12 @@ import movie.core.EventShowingsFeature import movie.core.FavoriteFeature import movie.core.UserBookingFeature import movie.core.notification.NotificationInfoProvider -import movie.core.pulse.* +import movie.core.pulse.ExactPulseNotificationMovie +import movie.core.pulse.PulseSavingBookings +import movie.core.pulse.PulseSavingCurrent +import movie.core.pulse.PulseSavingShowings +import movie.core.pulse.PulseSavingUpcoming +import movie.core.pulse.PulseScheduling import movie.image.ImageAnalyzer import movie.pulse.ExactPulse import movie.pulse.Pulse @@ -27,6 +33,7 @@ class PulseModule { @Daily @Provides + @Reusable fun pulse( preview: EventPreviewFeature.Factory, cinema: EventCinemaFeature, diff --git a/feature-core/src/main/java/movie/core/di/SetupFeatureModule.kt b/feature-core/src/main/java/movie/core/di/SetupFeatureModule.kt index 3cacd6b3..13b9e346 100644 --- a/feature-core/src/main/java/movie/core/di/SetupFeatureModule.kt +++ b/feature-core/src/main/java/movie/core/di/SetupFeatureModule.kt @@ -2,6 +2,7 @@ package movie.core.di import dagger.Module import dagger.Provides +import dagger.Reusable import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent import movie.core.SetupFeature @@ -14,6 +15,7 @@ import movie.core.preference.RegionPreference class SetupFeatureModule { @Provides + @Reusable fun feature( preference: RegionPreference ): SetupFeature { @@ -21,6 +23,7 @@ class SetupFeatureModule { } @Provides + @Reusable fun endpoint( feature: SetupFeature ): EndpointProvider = object : EndpointProvider { diff --git a/feature-core/src/main/java/movie/core/di/TicketShareRegistryModule.kt b/feature-core/src/main/java/movie/core/di/TicketShareRegistryModule.kt index 4d4d946a..4e11bba3 100644 --- a/feature-core/src/main/java/movie/core/di/TicketShareRegistryModule.kt +++ b/feature-core/src/main/java/movie/core/di/TicketShareRegistryModule.kt @@ -2,6 +2,7 @@ package movie.core.di import dagger.Module import dagger.Provides +import dagger.Reusable import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent import kotlinx.serialization.json.Json @@ -17,6 +18,7 @@ import javax.inject.Singleton class TicketShareRegistryModule { @Provides + @Reusable fun registry( store: TicketStore = store(), json: Json = Json diff --git a/feature-core/src/main/java/movie/core/di/TracingModule.kt b/feature-core/src/main/java/movie/core/di/TracingModule.kt index 73526a99..3ae85be9 100644 --- a/feature-core/src/main/java/movie/core/di/TracingModule.kt +++ b/feature-core/src/main/java/movie/core/di/TracingModule.kt @@ -2,6 +2,7 @@ package movie.core.di import dagger.Module import dagger.Provides +import dagger.Reusable import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent import movie.core.nwk.PerformanceTracer @@ -13,6 +14,7 @@ import movie.core.nwk.PerformanceTracer as NetworkTracer class TracingModule { @Provides + @Reusable fun database(): DbTracer = object : DbTracer { override fun trace(tag: String): DbTracer.Trace { return DbTracer.Trace {} @@ -20,6 +22,7 @@ class TracingModule { } @Provides + @Reusable fun network(): NetworkTracer = object : NetworkTracer { override fun trace(url: String, method: String): PerformanceTracer.Trace { return object : NetworkTracer.Trace { diff --git a/feature-core/src/main/java/movie/core/di/UserFeatureModule.kt b/feature-core/src/main/java/movie/core/di/UserFeatureModule.kt index b92a4f07..489134d2 100644 --- a/feature-core/src/main/java/movie/core/di/UserFeatureModule.kt +++ b/feature-core/src/main/java/movie/core/di/UserFeatureModule.kt @@ -2,6 +2,7 @@ package movie.core.di import dagger.Module import dagger.Provides +import dagger.Reusable import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent import kotlinx.coroutines.CoroutineScope @@ -47,6 +48,7 @@ import kotlin.time.Duration.Companion.days internal class UserFeatureModule { @Provides + @Reusable fun credential( service: UserService, account: UserAccount @@ -55,6 +57,7 @@ internal class UserFeatureModule { } @Provides + @Reusable fun data( service: UserService, cinema: EventCinemaFeature, @@ -74,6 +77,7 @@ internal class UserFeatureModule { } @Provides + @Reusable fun booking( booking: BookingDao, seats: BookingSeatsDao, diff --git a/feature-image-analysis/src/main/java/movie/image/di/ImageDatabaseModule.kt b/feature-image-analysis/src/main/java/movie/image/di/ImageDatabaseModule.kt index 7d6ec27e..24aef523 100644 --- a/feature-image-analysis/src/main/java/movie/image/di/ImageDatabaseModule.kt +++ b/feature-image-analysis/src/main/java/movie/image/di/ImageDatabaseModule.kt @@ -6,6 +6,7 @@ import androidx.room.ExperimentalRoomApi import androidx.room.Room import dagger.Module import dagger.Provides +import dagger.Reusable import dagger.hilt.InstallIn import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.components.SingletonComponent @@ -20,6 +21,7 @@ internal class ImageDatabaseModule { @OptIn(ExperimentalRoomApi::class) @Provides + @Reusable fun database( @ApplicationContext context: Context @@ -31,6 +33,7 @@ internal class ImageDatabaseModule { } @Provides + @Reusable fun analysis( database: ImageDatabase ): AnalysisDao { @@ -38,6 +41,7 @@ internal class ImageDatabaseModule { } @Provides + @Reusable fun image( database: ImageDatabase ): ImageDao { @@ -45,6 +49,7 @@ internal class ImageDatabaseModule { } @Provides + @Reusable fun color( database: ImageDatabase ): ColorDao { diff --git a/feature-image-analysis/src/main/java/movie/image/di/ImageModule.kt b/feature-image-analysis/src/main/java/movie/image/di/ImageModule.kt index 34ead16b..d79c468b 100644 --- a/feature-image-analysis/src/main/java/movie/image/di/ImageModule.kt +++ b/feature-image-analysis/src/main/java/movie/image/di/ImageModule.kt @@ -2,6 +2,7 @@ package movie.image.di import dagger.Module import dagger.Provides +import dagger.Reusable import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent import movie.image.ImageAnalyzer @@ -20,6 +21,7 @@ import movie.image.database.ImageDao internal class ImageModule { @Provides + @Reusable fun analyzer( imageDao: ImageDao, colorDao: ColorDao, diff --git a/feature-metadata/src/main/java/movie/rating/di/DatabaseModule.kt b/feature-metadata/src/main/java/movie/rating/di/DatabaseModule.kt index 25b7abd4..eceaaa11 100644 --- a/feature-metadata/src/main/java/movie/rating/di/DatabaseModule.kt +++ b/feature-metadata/src/main/java/movie/rating/di/DatabaseModule.kt @@ -4,6 +4,7 @@ import android.content.Context import androidx.room.Room import dagger.Module import dagger.Provides +import dagger.Reusable import dagger.hilt.InstallIn import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.components.SingletonComponent @@ -15,6 +16,7 @@ import movie.rating.database.RatingDatabase internal class DatabaseModule { @Provides + @Reusable fun database( @ApplicationContext context: Context @@ -26,6 +28,7 @@ internal class DatabaseModule { } @Provides + @Reusable fun dao(database: RatingDatabase): RatingDao = database.rating() } \ No newline at end of file diff --git a/feature-metadata/src/main/java/movie/rating/di/RatingProviderModule.kt b/feature-metadata/src/main/java/movie/rating/di/RatingProviderModule.kt index 827e0472..42f9683f 100644 --- a/feature-metadata/src/main/java/movie/rating/di/RatingProviderModule.kt +++ b/feature-metadata/src/main/java/movie/rating/di/RatingProviderModule.kt @@ -2,6 +2,7 @@ package movie.rating.di import dagger.Module import dagger.Provides +import dagger.Reusable import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent import io.ktor.client.HttpClient @@ -28,6 +29,7 @@ import javax.inject.Singleton internal class RatingProviderModule { @Provides + @Reusable fun rating( @Rating client: LazyHttpClient, dao: RatingDao diff --git a/feature-pulse/src/main/java/movie/pulse/di/PulseModule.kt b/feature-pulse/src/main/java/movie/pulse/di/PulseModule.kt index 98ff4731..18ecc143 100644 --- a/feature-pulse/src/main/java/movie/pulse/di/PulseModule.kt +++ b/feature-pulse/src/main/java/movie/pulse/di/PulseModule.kt @@ -3,6 +3,7 @@ package movie.pulse.di import android.content.Context import dagger.Module import dagger.Provides +import dagger.Reusable import dagger.hilt.InstallIn import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.components.SingletonComponent @@ -14,6 +15,7 @@ import movie.pulse.ExactPulseSchedulerPlatform class PulseModule { @Provides + @Reusable fun scheduler( @ApplicationContext context: Context diff --git a/feature-wear/src/main/java/movie/wear/di/WearModule.kt b/feature-wear/src/main/java/movie/wear/di/WearModule.kt index a6bb5b14..fc8a2125 100644 --- a/feature-wear/src/main/java/movie/wear/di/WearModule.kt +++ b/feature-wear/src/main/java/movie/wear/di/WearModule.kt @@ -5,6 +5,7 @@ import com.google.android.gms.wearable.DataClient import com.google.android.gms.wearable.Wearable import dagger.Module import dagger.Provides +import dagger.Reusable import dagger.hilt.InstallIn import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.components.SingletonComponent @@ -18,6 +19,7 @@ import movie.wear.WearServiceUriSpec class WearModule { @Provides + @Reusable fun service( client: DataClient ): WearService { @@ -29,6 +31,7 @@ class WearModule { } @Provides + @Reusable internal fun client( @ApplicationContext context: Context