1 /* 2 * Copyright 2024 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.photopicker.features.photogrid 18 19 import androidx.compose.animation.AnimatedContentTransitionScope 20 import androidx.compose.animation.EnterTransition 21 import androidx.compose.animation.ExitTransition 22 import androidx.compose.animation.slideInHorizontally 23 import androidx.compose.animation.slideOutHorizontally 24 import androidx.compose.runtime.Composable 25 import androidx.compose.ui.Modifier 26 import androidx.navigation.NamedNavArgument 27 import androidx.navigation.NavBackStackEntry 28 import androidx.navigation.NavDeepLink 29 import com.android.photopicker.core.configuration.PhotopickerConfiguration 30 import com.android.photopicker.core.events.Event 31 import com.android.photopicker.core.events.RegisteredEventClass 32 import com.android.photopicker.core.features.FeatureManager 33 import com.android.photopicker.core.features.FeatureRegistration 34 import com.android.photopicker.core.features.FeatureToken 35 import com.android.photopicker.core.features.Location 36 import com.android.photopicker.core.features.LocationParams 37 import com.android.photopicker.core.features.PhotopickerUiFeature 38 import com.android.photopicker.core.features.Priority 39 import com.android.photopicker.core.navigation.PhotopickerDestinations 40 import com.android.photopicker.core.navigation.Route 41 42 /** 43 * Feature class for the Photopicker's primary photo grid. 44 * 45 * This feature adds the [PHOTO_GRID] route to the application as a high priority initial route. 46 */ 47 class PhotoGridFeature : PhotopickerUiFeature { 48 companion object Registration : FeatureRegistration { 49 override val TAG: String = "PhotopickerPhotoGridFeature" 50 isEnablednull51 override fun isEnabled(config: PhotopickerConfiguration) = true 52 53 override fun build(featureManager: FeatureManager) = PhotoGridFeature() 54 } 55 56 override val token = FeatureToken.PHOTO_GRID.token 57 58 /** Events consumed by the Photo grid */ 59 override val eventsConsumed = emptySet<RegisteredEventClass>() 60 61 /** Events produced by the Photo grid */ 62 override val eventsProduced = setOf(Event.ShowSnackbarMessage::class.java) 63 64 override fun registerLocations(): List<Pair<Location, Int>> { 65 return listOf( 66 Pair(Location.NAVIGATION_BAR_NAV_BUTTON, Priority.HIGH.priority), 67 ) 68 } 69 registerNavigationRoutesnull70 override fun registerNavigationRoutes(): Set<Route> { 71 return setOf( 72 // The main grid of the user's photos. 73 object : Route { 74 override val route = PhotopickerDestinations.PHOTO_GRID.route 75 override val initialRoutePriority = Priority.HIGH.priority 76 override val arguments = emptyList<NamedNavArgument>() 77 override val deepLinks = emptyList<NavDeepLink>() 78 override val isDialog = false 79 override val dialogProperties = null 80 81 /* 82 Animations for PHOTO_GRID 83 - When navigating directly, content will slide IN from the left edge. 84 - When navigating away, content will slide OUT towards the left edge. 85 - When returning from the backstack, content will slide IN from the right edge. 86 - When popping to another route on the backstack, content will slide OUT towards 87 the left edge. 88 */ 89 override val enterTransition: 90 (AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition)? = 91 { 92 // Positive value to slide left-to-right 93 slideInHorizontally { -it } 94 } 95 override val exitTransition: 96 (AnimatedContentTransitionScope<NavBackStackEntry>.() -> ExitTransition)? = 97 { 98 // Negative value to slide right-to-left 99 slideOutHorizontally { -it } 100 } 101 override val popEnterTransition: 102 (AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition)? = 103 { 104 // When returning from the backstack slide right-to-left 105 slideInHorizontally { -it } 106 } 107 override val popExitTransition: 108 (AnimatedContentTransitionScope<NavBackStackEntry>.() -> ExitTransition)? = 109 { 110 // When navigating to the backstack slide left-to-right 111 slideOutHorizontally { -it } 112 } 113 114 @Composable 115 override fun composable(navBackStackEntry: NavBackStackEntry?) { 116 PhotoGrid() 117 } 118 }, 119 ) 120 } 121 122 @Composable composenull123 override fun compose( 124 location: Location, 125 modifier: Modifier, 126 params: LocationParams, 127 ) { 128 when (location) { 129 Location.NAVIGATION_BAR_NAV_BUTTON -> PhotoGridNavButton(modifier) 130 else -> {} 131 } 132 } 133 } 134