• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.animations.springDefaultEffectOffset
30 import com.android.photopicker.core.configuration.PhotopickerConfiguration
31 import com.android.photopicker.core.events.Event
32 import com.android.photopicker.core.events.RegisteredEventClass
33 import com.android.photopicker.core.features.FeatureManager
34 import com.android.photopicker.core.features.FeatureRegistration
35 import com.android.photopicker.core.features.FeatureToken
36 import com.android.photopicker.core.features.Location
37 import com.android.photopicker.core.features.LocationParams
38 import com.android.photopicker.core.features.PhotopickerUiFeature
39 import com.android.photopicker.core.features.PrefetchResultKey
40 import com.android.photopicker.core.features.Priority
41 import com.android.photopicker.core.navigation.PhotopickerDestinations
42 import com.android.photopicker.core.navigation.Route
43 import kotlinx.coroutines.Deferred
44 
45 /**
46  * Feature class for the Photopicker's primary photo grid.
47  *
48  * This feature adds the [PHOTO_GRID] route to the application as a high priority initial route.
49  */
50 class PhotoGridFeature : PhotopickerUiFeature {
51     companion object Registration : FeatureRegistration {
52         override val TAG: String = "PhotopickerPhotoGridFeature"
53 
isEnablednull54         override fun isEnabled(
55             config: PhotopickerConfiguration,
56             deferredPrefetchResultsMap: Map<PrefetchResultKey, Deferred<Any?>>,
57         ) = true
58 
59         override fun build(featureManager: FeatureManager) = PhotoGridFeature()
60     }
61 
62     override val token = FeatureToken.PHOTO_GRID.token
63 
64     /** Events consumed by the Photo grid */
65     override val eventsConsumed = emptySet<RegisteredEventClass>()
66 
67     /** Events produced by the Photo grid */
68     override val eventsProduced =
69         setOf(Event.ShowSnackbarMessage::class.java, Event.LogPhotopickerUIEvent::class.java)
70 
71     override fun registerLocations(): List<Pair<Location, Int>> {
72         return listOf(Pair(Location.NAVIGATION_BAR_NAV_BUTTON, Priority.HIGHEST.priority))
73     }
74 
registerNavigationRoutesnull75     override fun registerNavigationRoutes(): Set<Route> {
76         return setOf(
77             // The main grid of the user's photos.
78             object : Route {
79                 override val route = PhotopickerDestinations.PHOTO_GRID.route
80                 override val initialRoutePriority = Priority.HIGH.priority
81                 override val arguments = emptyList<NamedNavArgument>()
82                 override val deepLinks = emptyList<NavDeepLink>()
83                 override val isDialog = false
84                 override val dialogProperties = null
85 
86                 /*
87                 Animations for PHOTO_GRID
88                 - When navigating directly, content will slide IN from the left edge.
89                 - When navigating away, content will slide OUT towards the left edge.
90                 - When returning from the backstack, content will slide IN from the right edge.
91                 - When popping to another route on the backstack, content will slide OUT towards
92                   the left edge.
93                  */
94                 override val enterTransition:
95                     (AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition)? =
96                     {
97                         // Positive value to slide left-to-right
98                         slideInHorizontally(animationSpec = springDefaultEffectOffset) { it }
99                     }
100                 override val exitTransition:
101                     (AnimatedContentTransitionScope<NavBackStackEntry>.() -> ExitTransition)? =
102                     {
103                         // Negative value to slide right-to-left
104                         slideOutHorizontally(animationSpec = springDefaultEffectOffset) { -it }
105                     }
106                 override val popEnterTransition:
107                     (AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition)? =
108                     {
109                         // When returning from the backstack slide right-to-left
110                         slideInHorizontally(animationSpec = springDefaultEffectOffset) { -it }
111                     }
112                 override val popExitTransition:
113                     (AnimatedContentTransitionScope<NavBackStackEntry>.() -> ExitTransition)? =
114                     {
115                         // When navigating to the backstack slide left-to-right
116                         slideOutHorizontally(animationSpec = springDefaultEffectOffset) { -it }
117                     }
118 
119                 @Composable
120                 override fun composable(navBackStackEntry: NavBackStackEntry?) {
121                     PhotoGrid()
122                 }
123             }
124         )
125     }
126 
127     @Composable
composenull128     override fun compose(location: Location, modifier: Modifier, params: LocationParams) {
129         when (location) {
130             Location.NAVIGATION_BAR_NAV_BUTTON -> PhotoGridNavButton(modifier)
131             else -> {}
132         }
133     }
134 }
135