diff options
author | 2024-07-08 18:13:57 +0000 | |
---|---|---|
committer | 2024-07-24 17:59:35 +0000 | |
commit | 8d78a1e3dddee3642336bbf4a8ebc1c2c549f66e (patch) | |
tree | f5f52cfda35807f26ed1308ed79375d8e62de441 /tools | |
parent | dde6ccd62dbdde0d98836058545a13c3a9a322fc (diff) |
[PhotoPickerToolV2] Include custom Mime Type Filter option and Launch tab(Photos/Albums) in PhotoPickerScreen, UI enhancement, resolve the scrolling issue, change the icon of the app.
Added a box for the user to predefine custom mime type filters (along with show images only and show videos only switches). Also included the Launch tab for selecting Photos or Albums as a pre-selected tab when the user launches PhotoPicker. Did some UI enhancement like changing the button colors of Pick Images and ACTION_GET_CONTENT when they are selected, selected Pick Images by default. Resolved the scrolling issue and changed the icon of the app.
Bug: 349514760
Test: m PhotoPickerToolV2 -j64 & adb install -r -d out/target/product/<lunch target name>/system/app/PhotoPickerToolV2/PhotoPickerToolV2.apk
Flag: TEST_ONLY
Change-Id: Id279e028579d6338f15a0e5223a82e56206abebf
Diffstat (limited to 'tools')
33 files changed, 351 insertions, 308 deletions
diff --git a/tools/photopickerV2/AndroidManifest.xml b/tools/photopickerV2/AndroidManifest.xml index 222776c79..f176fa716 100644 --- a/tools/photopickerV2/AndroidManifest.xml +++ b/tools/photopickerV2/AndroidManifest.xml @@ -24,5 +24,4 @@ </intent-filter> </activity> </application> - -</manifest> +</manifest>
\ No newline at end of file diff --git a/tools/photopickerV2/res/drawable/ic_launcher_background.xml b/tools/photopickerV2/res/drawable/ic_launcher_background.xml deleted file mode 100644 index 07d5da9cb..000000000 --- a/tools/photopickerV2/res/drawable/ic_launcher_background.xml +++ /dev/null @@ -1,170 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="108dp" - android:height="108dp" - android:viewportWidth="108" - android:viewportHeight="108"> - <path - android:fillColor="#3DDC84" - android:pathData="M0,0h108v108h-108z" /> - <path - android:fillColor="#00000000" - android:pathData="M9,0L9,108" - android:strokeWidth="0.8" - android:strokeColor="#33FFFFFF" /> - <path - android:fillColor="#00000000" - android:pathData="M19,0L19,108" - android:strokeWidth="0.8" - android:strokeColor="#33FFFFFF" /> - <path - android:fillColor="#00000000" - android:pathData="M29,0L29,108" - android:strokeWidth="0.8" - android:strokeColor="#33FFFFFF" /> - <path - android:fillColor="#00000000" - android:pathData="M39,0L39,108" - android:strokeWidth="0.8" - android:strokeColor="#33FFFFFF" /> - <path - android:fillColor="#00000000" - android:pathData="M49,0L49,108" - android:strokeWidth="0.8" - android:strokeColor="#33FFFFFF" /> - <path - android:fillColor="#00000000" - android:pathData="M59,0L59,108" - android:strokeWidth="0.8" - android:strokeColor="#33FFFFFF" /> - <path - android:fillColor="#00000000" - android:pathData="M69,0L69,108" - android:strokeWidth="0.8" - android:strokeColor="#33FFFFFF" /> - <path - android:fillColor="#00000000" - android:pathData="M79,0L79,108" - android:strokeWidth="0.8" - android:strokeColor="#33FFFFFF" /> - <path - android:fillColor="#00000000" - android:pathData="M89,0L89,108" - android:strokeWidth="0.8" - android:strokeColor="#33FFFFFF" /> - <path - android:fillColor="#00000000" - android:pathData="M99,0L99,108" - android:strokeWidth="0.8" - android:strokeColor="#33FFFFFF" /> - <path - android:fillColor="#00000000" - android:pathData="M0,9L108,9" - android:strokeWidth="0.8" - android:strokeColor="#33FFFFFF" /> - <path - android:fillColor="#00000000" - android:pathData="M0,19L108,19" - android:strokeWidth="0.8" - android:strokeColor="#33FFFFFF" /> - <path - android:fillColor="#00000000" - android:pathData="M0,29L108,29" - android:strokeWidth="0.8" - android:strokeColor="#33FFFFFF" /> - <path - android:fillColor="#00000000" - android:pathData="M0,39L108,39" - android:strokeWidth="0.8" - android:strokeColor="#33FFFFFF" /> - <path - android:fillColor="#00000000" - android:pathData="M0,49L108,49" - android:strokeWidth="0.8" - android:strokeColor="#33FFFFFF" /> - <path - android:fillColor="#00000000" - android:pathData="M0,59L108,59" - android:strokeWidth="0.8" - android:strokeColor="#33FFFFFF" /> - <path - android:fillColor="#00000000" - android:pathData="M0,69L108,69" - android:strokeWidth="0.8" - android:strokeColor="#33FFFFFF" /> - <path - android:fillColor="#00000000" - android:pathData="M0,79L108,79" - android:strokeWidth="0.8" - android:strokeColor="#33FFFFFF" /> - <path - android:fillColor="#00000000" - android:pathData="M0,89L108,89" - android:strokeWidth="0.8" - android:strokeColor="#33FFFFFF" /> - <path - android:fillColor="#00000000" - android:pathData="M0,99L108,99" - android:strokeWidth="0.8" - android:strokeColor="#33FFFFFF" /> - <path - android:fillColor="#00000000" - android:pathData="M19,29L89,29" - android:strokeWidth="0.8" - android:strokeColor="#33FFFFFF" /> - <path - android:fillColor="#00000000" - android:pathData="M19,39L89,39" - android:strokeWidth="0.8" - android:strokeColor="#33FFFFFF" /> - <path - android:fillColor="#00000000" - android:pathData="M19,49L89,49" - android:strokeWidth="0.8" - android:strokeColor="#33FFFFFF" /> - <path - android:fillColor="#00000000" - android:pathData="M19,59L89,59" - android:strokeWidth="0.8" - android:strokeColor="#33FFFFFF" /> - <path - android:fillColor="#00000000" - android:pathData="M19,69L89,69" - android:strokeWidth="0.8" - android:strokeColor="#33FFFFFF" /> - <path - android:fillColor="#00000000" - android:pathData="M19,79L89,79" - android:strokeWidth="0.8" - android:strokeColor="#33FFFFFF" /> - <path - android:fillColor="#00000000" - android:pathData="M29,19L29,89" - android:strokeWidth="0.8" - android:strokeColor="#33FFFFFF" /> - <path - android:fillColor="#00000000" - android:pathData="M39,19L39,89" - android:strokeWidth="0.8" - android:strokeColor="#33FFFFFF" /> - <path - android:fillColor="#00000000" - android:pathData="M49,19L49,89" - android:strokeWidth="0.8" - android:strokeColor="#33FFFFFF" /> - <path - android:fillColor="#00000000" - android:pathData="M59,19L59,89" - android:strokeWidth="0.8" - android:strokeColor="#33FFFFFF" /> - <path - android:fillColor="#00000000" - android:pathData="M69,19L69,89" - android:strokeWidth="0.8" - android:strokeColor="#33FFFFFF" /> - <path - android:fillColor="#00000000" - android:pathData="M79,19L79,89" - android:strokeWidth="0.8" - android:strokeColor="#33FFFFFF" /> -</vector> diff --git a/tools/photopickerV2/res/drawable/ic_launcher_foreground.xml b/tools/photopickerV2/res/drawable/ic_launcher_foreground.xml deleted file mode 100644 index 2b068d114..000000000 --- a/tools/photopickerV2/res/drawable/ic_launcher_foreground.xml +++ /dev/null @@ -1,30 +0,0 @@ -<vector xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:aapt="http://schemas.android.com/aapt" - android:width="108dp" - android:height="108dp" - android:viewportWidth="108" - android:viewportHeight="108"> - <path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z"> - <aapt:attr name="android:fillColor"> - <gradient - android:endX="85.84757" - android:endY="92.4963" - android:startX="42.9492" - android:startY="49.59793" - android:type="linear"> - <item - android:color="#44000000" - android:offset="0.0" /> - <item - android:color="#00000000" - android:offset="1.0" /> - </gradient> - </aapt:attr> - </path> - <path - android:fillColor="#FFFFFF" - android:fillType="nonZero" - android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z" - android:strokeWidth="1" - android:strokeColor="#00000000" /> -</vector>
\ No newline at end of file diff --git a/tools/photopickerV2/res/mipmap-anydpi-v26/ic_launcher.xml b/tools/photopickerV2/res/mipmap-anydpi-v26/ic_launcher.xml index 6f3b755bf..4ae7d1237 100644 --- a/tools/photopickerV2/res/mipmap-anydpi-v26/ic_launcher.xml +++ b/tools/photopickerV2/res/mipmap-anydpi-v26/ic_launcher.xml @@ -1,6 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> - <background android:drawable="@drawable/ic_launcher_background" /> - <foreground android:drawable="@drawable/ic_launcher_foreground" /> - <monochrome android:drawable="@drawable/ic_launcher_foreground" /> + <background android:drawable="@mipmap/ic_launcher_background"/> + <foreground android:drawable="@mipmap/ic_launcher_foreground"/> </adaptive-icon>
\ No newline at end of file diff --git a/tools/photopickerV2/res/mipmap-anydpi-v26/ic_launcher_round.xml b/tools/photopickerV2/res/mipmap-anydpi-v26/ic_launcher_round.xml index 6f3b755bf..4ae7d1237 100644 --- a/tools/photopickerV2/res/mipmap-anydpi-v26/ic_launcher_round.xml +++ b/tools/photopickerV2/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -1,6 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> - <background android:drawable="@drawable/ic_launcher_background" /> - <foreground android:drawable="@drawable/ic_launcher_foreground" /> - <monochrome android:drawable="@drawable/ic_launcher_foreground" /> + <background android:drawable="@mipmap/ic_launcher_background"/> + <foreground android:drawable="@mipmap/ic_launcher_foreground"/> </adaptive-icon>
\ No newline at end of file diff --git a/tools/photopickerV2/res/mipmap-hdpi/ic_launcher.webp b/tools/photopickerV2/res/mipmap-hdpi/ic_launcher.webp Binary files differindex c209e78ec..99169c72f 100644 --- a/tools/photopickerV2/res/mipmap-hdpi/ic_launcher.webp +++ b/tools/photopickerV2/res/mipmap-hdpi/ic_launcher.webp diff --git a/tools/photopickerV2/res/mipmap-hdpi/ic_launcher_background.webp b/tools/photopickerV2/res/mipmap-hdpi/ic_launcher_background.webp Binary files differnew file mode 100644 index 000000000..edcf7f225 --- /dev/null +++ b/tools/photopickerV2/res/mipmap-hdpi/ic_launcher_background.webp diff --git a/tools/photopickerV2/res/mipmap-hdpi/ic_launcher_foreground.webp b/tools/photopickerV2/res/mipmap-hdpi/ic_launcher_foreground.webp Binary files differnew file mode 100644 index 000000000..edcf7f225 --- /dev/null +++ b/tools/photopickerV2/res/mipmap-hdpi/ic_launcher_foreground.webp diff --git a/tools/photopickerV2/res/mipmap-hdpi/ic_launcher_round.webp b/tools/photopickerV2/res/mipmap-hdpi/ic_launcher_round.webp Binary files differindex b2dfe3d1b..909bff6df 100644 --- a/tools/photopickerV2/res/mipmap-hdpi/ic_launcher_round.webp +++ b/tools/photopickerV2/res/mipmap-hdpi/ic_launcher_round.webp diff --git a/tools/photopickerV2/res/mipmap-mdpi/ic_launcher.webp b/tools/photopickerV2/res/mipmap-mdpi/ic_launcher.webp Binary files differindex 4f0f1d64e..6935bd2fd 100644 --- a/tools/photopickerV2/res/mipmap-mdpi/ic_launcher.webp +++ b/tools/photopickerV2/res/mipmap-mdpi/ic_launcher.webp diff --git a/tools/photopickerV2/res/mipmap-mdpi/ic_launcher_background.webp b/tools/photopickerV2/res/mipmap-mdpi/ic_launcher_background.webp Binary files differnew file mode 100644 index 000000000..3873089d9 --- /dev/null +++ b/tools/photopickerV2/res/mipmap-mdpi/ic_launcher_background.webp diff --git a/tools/photopickerV2/res/mipmap-mdpi/ic_launcher_foreground.webp b/tools/photopickerV2/res/mipmap-mdpi/ic_launcher_foreground.webp Binary files differnew file mode 100644 index 000000000..3873089d9 --- /dev/null +++ b/tools/photopickerV2/res/mipmap-mdpi/ic_launcher_foreground.webp diff --git a/tools/photopickerV2/res/mipmap-mdpi/ic_launcher_round.webp b/tools/photopickerV2/res/mipmap-mdpi/ic_launcher_round.webp Binary files differindex 62b611da0..3f0a5209a 100644 --- a/tools/photopickerV2/res/mipmap-mdpi/ic_launcher_round.webp +++ b/tools/photopickerV2/res/mipmap-mdpi/ic_launcher_round.webp diff --git a/tools/photopickerV2/res/mipmap-xhdpi/ic_launcher.webp b/tools/photopickerV2/res/mipmap-xhdpi/ic_launcher.webp Binary files differindex 948a3070f..84bad22ef 100644 --- a/tools/photopickerV2/res/mipmap-xhdpi/ic_launcher.webp +++ b/tools/photopickerV2/res/mipmap-xhdpi/ic_launcher.webp diff --git a/tools/photopickerV2/res/mipmap-xhdpi/ic_launcher_background.webp b/tools/photopickerV2/res/mipmap-xhdpi/ic_launcher_background.webp Binary files differnew file mode 100644 index 000000000..1257b0afe --- /dev/null +++ b/tools/photopickerV2/res/mipmap-xhdpi/ic_launcher_background.webp diff --git a/tools/photopickerV2/res/mipmap-xhdpi/ic_launcher_foreground.webp b/tools/photopickerV2/res/mipmap-xhdpi/ic_launcher_foreground.webp Binary files differnew file mode 100644 index 000000000..1257b0afe --- /dev/null +++ b/tools/photopickerV2/res/mipmap-xhdpi/ic_launcher_foreground.webp diff --git a/tools/photopickerV2/res/mipmap-xhdpi/ic_launcher_round.webp b/tools/photopickerV2/res/mipmap-xhdpi/ic_launcher_round.webp Binary files differindex 1b9a6956b..25a6dd43c 100644 --- a/tools/photopickerV2/res/mipmap-xhdpi/ic_launcher_round.webp +++ b/tools/photopickerV2/res/mipmap-xhdpi/ic_launcher_round.webp diff --git a/tools/photopickerV2/res/mipmap-xxhdpi/ic_launcher.webp b/tools/photopickerV2/res/mipmap-xxhdpi/ic_launcher.webp Binary files differindex 28d4b77f9..f89cfccc4 100644 --- a/tools/photopickerV2/res/mipmap-xxhdpi/ic_launcher.webp +++ b/tools/photopickerV2/res/mipmap-xxhdpi/ic_launcher.webp diff --git a/tools/photopickerV2/res/mipmap-xxhdpi/ic_launcher_background.webp b/tools/photopickerV2/res/mipmap-xxhdpi/ic_launcher_background.webp Binary files differnew file mode 100644 index 000000000..052eeb3f0 --- /dev/null +++ b/tools/photopickerV2/res/mipmap-xxhdpi/ic_launcher_background.webp diff --git a/tools/photopickerV2/res/mipmap-xxhdpi/ic_launcher_foreground.webp b/tools/photopickerV2/res/mipmap-xxhdpi/ic_launcher_foreground.webp Binary files differnew file mode 100644 index 000000000..052eeb3f0 --- /dev/null +++ b/tools/photopickerV2/res/mipmap-xxhdpi/ic_launcher_foreground.webp diff --git a/tools/photopickerV2/res/mipmap-xxhdpi/ic_launcher_round.webp b/tools/photopickerV2/res/mipmap-xxhdpi/ic_launcher_round.webp Binary files differindex 9287f5083..8d0d8bc3e 100644 --- a/tools/photopickerV2/res/mipmap-xxhdpi/ic_launcher_round.webp +++ b/tools/photopickerV2/res/mipmap-xxhdpi/ic_launcher_round.webp diff --git a/tools/photopickerV2/res/mipmap-xxxhdpi/ic_launcher.webp b/tools/photopickerV2/res/mipmap-xxxhdpi/ic_launcher.webp Binary files differindex aa7d6427e..951355b65 100644 --- a/tools/photopickerV2/res/mipmap-xxxhdpi/ic_launcher.webp +++ b/tools/photopickerV2/res/mipmap-xxxhdpi/ic_launcher.webp diff --git a/tools/photopickerV2/res/mipmap-xxxhdpi/ic_launcher_background.webp b/tools/photopickerV2/res/mipmap-xxxhdpi/ic_launcher_background.webp Binary files differnew file mode 100644 index 000000000..c981aa65c --- /dev/null +++ b/tools/photopickerV2/res/mipmap-xxxhdpi/ic_launcher_background.webp diff --git a/tools/photopickerV2/res/mipmap-xxxhdpi/ic_launcher_foreground.webp b/tools/photopickerV2/res/mipmap-xxxhdpi/ic_launcher_foreground.webp Binary files differnew file mode 100644 index 000000000..c981aa65c --- /dev/null +++ b/tools/photopickerV2/res/mipmap-xxxhdpi/ic_launcher_foreground.webp diff --git a/tools/photopickerV2/res/mipmap-xxxhdpi/ic_launcher_round.webp b/tools/photopickerV2/res/mipmap-xxxhdpi/ic_launcher_round.webp Binary files differindex 9126ae37c..632a00bf3 100644 --- a/tools/photopickerV2/res/mipmap-xxxhdpi/ic_launcher_round.webp +++ b/tools/photopickerV2/res/mipmap-xxxhdpi/ic_launcher_round.webp diff --git a/tools/photopickerV2/res/values/colors.xml b/tools/photopickerV2/res/values/colors.xml deleted file mode 100644 index f8c6127d3..000000000 --- a/tools/photopickerV2/res/values/colors.xml +++ /dev/null @@ -1,10 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <color name="purple_200">#FFBB86FC</color> - <color name="purple_500">#FF6200EE</color> - <color name="purple_700">#FF3700B3</color> - <color name="teal_200">#FF03DAC5</color> - <color name="teal_700">#FF018786</color> - <color name="black">#FF000000</color> - <color name="white">#FFFFFFFF</color> -</resources>
\ No newline at end of file diff --git a/tools/photopickerV2/res/values/strings.xml b/tools/photopickerV2/res/values/strings.xml index 28dc35735..87cf043d7 100644 --- a/tools/photopickerV2/res/values/strings.xml +++ b/tools/photopickerV2/res/values/strings.xml @@ -7,11 +7,17 @@ <string name="title_photopicker">PhotoPicker V2</string> <string name="pick_images">Pick Images</string> <string name="action_get_content">Action Get Content</string> + <string name="open_document">Open Document</string> + <string name="open_document_tree">Open Document Tree</string> <string name="display_images_in_order">Display Images in Order</string> + <string name="show_images_only"> Show Images Only</string> + <string name="show_videos_only"> Show Videos Only</string> + <string name="select_mime_type">Select Mime Type</string> + <string name="select_launch_tab">Select Launch Tab</string> <string name="allow_multiple_selection">Allow Multiple Selection</string> + <string name="allow_custom_mime_type">Allow Custom Mime Type</string> <string name="max_number_of_media_items">Max number of media items</string> - <string name="enter_valid_number">Enter a valid count greater than one</string> + <string name="enter_valid_number">Enter a valid number greater than one</string> <string name="pick_media">Pick Media</string> <string name="working_on_it">Working on it</string> - </resources>
\ No newline at end of file diff --git a/tools/photopickerV2/src/com/android/providers/media/tools/photopickerv2/MainActivity.kt b/tools/photopickerV2/src/com/android/providers/media/tools/photopickerv2/MainActivity.kt index de82e8bc9..4b051e62b 100644 --- a/tools/photopickerV2/src/com/android/providers/media/tools/photopickerv2/MainActivity.kt +++ b/tools/photopickerV2/src/com/android/providers/media/tools/photopickerv2/MainActivity.kt @@ -18,7 +18,9 @@ package com.android.providers.media.tools.photopickerv2 import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent -import com.android.providers.media.tools.photopickerv2.navigation.NavGraph +import androidx.compose.material3.MaterialTheme +import com.android.providers.media.tools.photopickerv2.navigation.MainScreen + /** * Base Activity for this application. **/ @@ -26,8 +28,11 @@ class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { - // UI is triggered by the starting view set in the navigation graph. - NavGraph() + MaterialTheme(){ + // UI is triggered by the starting view set in the navigation graph. + MainScreen() + } } } } + diff --git a/tools/photopickerV2/src/com/android/providers/media/tools/photopickerv2/navigation/NavGraph.kt b/tools/photopickerV2/src/com/android/providers/media/tools/photopickerv2/navigation/NavGraph.kt index 7fcc8dda2..d8a87138a 100644 --- a/tools/photopickerV2/src/com/android/providers/media/tools/photopickerv2/navigation/NavGraph.kt +++ b/tools/photopickerV2/src/com/android/providers/media/tools/photopickerv2/navigation/NavGraph.kt @@ -20,7 +20,6 @@ import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.vector.ImageVector -import androidx.navigation.NavController import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.compose.rememberNavController @@ -35,32 +34,25 @@ import androidx.annotation.StringRes import androidx.compose.material.icons.Icons import androidx.compose.material3.Scaffold import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.saveable.rememberSaveable import androidx.navigation.NavHostController import androidx.navigation.compose.currentBackStackEntryAsState import com.android.providers.media.tools.photopickerv2.utils.NavigationComponent - /** - * NavGraph is the main navigation graph of the app. - * It contains the three tabs of the app : - * PhotoPicker - * DocsUI - * PickerChoice + * MainScreen sets up the Scaffold with a bottom navigation bar + * and hosts the NavGraph for navigation between the tabs. */ @SuppressLint @Composable -fun NavGraph() { +fun MainScreen() { val navController = rememberNavController() val pickerRoutes = listOf( NavigationItem.PhotoPicker, NavigationItem.DocsUI, NavigationItem.PickerChoice ) - val selectedRoute = rememberSaveable { mutableStateOf(NavigationItem.PhotoPicker.route) } val navBackStackEntry by navController.currentBackStackEntryAsState() - val currentRoute = navBackStackEntry?.destination?.route ?: selectedRoute.value + val currentRoute = navBackStackEntry?.destination?.route ?: NavigationItem.PhotoPicker.route Scaffold( /** @@ -77,22 +69,22 @@ fun NavGraph() { ) } ) { innerPadding -> - NavigationHost(navController = navController, modifier = Modifier.padding(innerPadding)) + NavGraph(navController = navController, modifier = Modifier.padding(innerPadding)) } } /** - * NavigationHost is the navigation host for the app. - * It is responsible for navigating between the three tabs of the app : + * NavGraph is the main navigation graph of the app. + * It contains the three tabs of the app : * PhotoPicker * DocsUI * PickerChoice */ @SuppressLint @Composable -fun NavigationHost(navController: NavController, modifier: Modifier = Modifier) { +fun NavGraph(navController: NavHostController, modifier: Modifier = Modifier) { NavHost( - navController = navController as NavHostController, + navController = navController, startDestination = NavigationItem.PhotoPicker.route, modifier = modifier ) { diff --git a/tools/photopickerV2/src/com/android/providers/media/tools/photopickerv2/photopicker/PhotoPickerScreen.kt b/tools/photopickerV2/src/com/android/providers/media/tools/photopickerv2/photopicker/PhotoPickerScreen.kt index 846430c63..678edf60b 100644 --- a/tools/photopickerV2/src/com/android/providers/media/tools/photopickerv2/photopicker/PhotoPickerScreen.kt +++ b/tools/photopickerV2/src/com/android/providers/media/tools/photopickerv2/photopicker/PhotoPickerScreen.kt @@ -31,9 +31,11 @@ import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.foundation.verticalScroll +import androidx.compose.material3.ButtonDefaults import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue @@ -42,6 +44,7 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.unit.dp @@ -52,11 +55,13 @@ import com.bumptech.glide.integration.compose.GlideImage import com.android.providers.media.tools.photopickerv2.utils.isImage import com.android.providers.media.tools.photopickerv2.R import com.android.providers.media.tools.photopickerv2.utils.ButtonComponent +import com.android.providers.media.tools.photopickerv2.utils.DropdownList import com.android.providers.media.tools.photopickerv2.utils.ErrorMessage +import com.android.providers.media.tools.photopickerv2.utils.LaunchLocation import com.android.providers.media.tools.photopickerv2.utils.PhotoPickerTitle import com.android.providers.media.tools.photopickerv2.utils.SwitchComponent import com.android.providers.media.tools.photopickerv2.utils.TextFieldComponent -import com.android.providers.media.tools.photopickerv2.utils.resetApp +import com.android.providers.media.tools.photopickerv2.utils.resetMedia /** * This is the screen for the PhotoPicker tab. @@ -68,11 +73,17 @@ fun PhotoPickerScreen(photoPickerViewModel: PhotoPickerViewModel = viewModel()) val context = LocalContext.current // initializing intent extras - var isOrderSelectionEnabled by remember { mutableStateOf(true) } + var isOrderSelectionEnabled by remember { mutableStateOf(false) } var allowMultiple by remember { mutableStateOf(false) } var isActionGetContentSelected by remember { mutableStateOf(false) } - val mimeTypeOptions = listOf("*/*", "image/*", "video/*") - var selectedMimeType by remember { mutableStateOf(mimeTypeOptions[0]) } + + var allowCustomMimeType by remember { mutableStateOf(false) } + var selectedMimeType by remember { mutableStateOf("") } + var customMimeTypeInput by remember { mutableStateOf("") } + + var showImagesOnly by remember { mutableStateOf(false) } + var showVideosOnly by remember { mutableStateOf(false) } + var selectedLaunchTab by remember { mutableStateOf(LaunchLocation.PHOTOS_TAB.name) } // We can only take string as an input, not an int using OutlinedTextField var maxSelectionInput by remember { mutableStateOf("10") } @@ -81,9 +92,18 @@ fun PhotoPickerScreen(photoPickerViewModel: PhotoPickerViewModel = viewModel()) var selectionErrorMessage by remember { mutableStateOf("") } var maxSelectionLimitError by remember { mutableStateOf("") } - // Initially, all the pick options are disabled. They get enabled on either selecting - // action_get_content or pick images button - var isAnyPickOptionEnabled by remember { mutableStateOf(false) } + // The Pick Images intent is selected by default + var selectedButton by remember { mutableStateOf<Int?>(R.string.pick_images) } + + // Color of PickImages and ACTION_GET_CONTENT button + val getContentColor = if (isActionGetContentSelected){ + ButtonDefaults.buttonColors() + } else ButtonDefaults.buttonColors(Color.Gray) + + val pickImagesColor = if (!isActionGetContentSelected) { + ButtonDefaults.buttonColors() + } else ButtonDefaults.buttonColors(Color.Gray) + // For handling the result of the photo picking activity val launcher = rememberLauncherForActivityResult( @@ -113,10 +133,30 @@ fun PhotoPickerScreen(photoPickerViewModel: PhotoPickerViewModel = viewModel()) val resultMedia by photoPickerViewModel.selectedMedia.collectAsState() + fun resetFeatureComponents( + isGetContentSelected: Boolean, + selectedButtonType: Int + ) { + isActionGetContentSelected = isGetContentSelected + selectedButton = selectedButtonType + allowMultiple = false + showImagesOnly = false + showVideosOnly = false + selectedMimeType = "" + resetMedia(photoPickerViewModel) + isOrderSelectionEnabled = false + maxSelectionInput = "10" // resetting the max Selection limit to default + maxMediaItemsDisplayed = 10 + allowCustomMimeType = false + customMimeTypeInput = "" + selectedLaunchTab = LaunchLocation.PHOTOS_TAB.toString() + } + Column( modifier = Modifier .padding(16.dp) - .fillMaxSize() + .verticalScroll(rememberScrollState()) + .fillMaxWidth() ) { // Title : PhotoPicker V2 PhotoPickerTitle() @@ -132,14 +172,13 @@ fun PhotoPickerScreen(photoPickerViewModel: PhotoPickerViewModel = viewModel()) ButtonComponent( label = stringResource(id = R.string.pick_images), onClick = { - isAnyPickOptionEnabled = true - isActionGetContentSelected = false - maxSelectionInput = "10" // resetting the max Selection limit to default - maxMediaItemsDisplayed = 10 - allowMultiple = false // setting it to false (default) - resetApp(photoPickerViewModel) + resetFeatureComponents( + isGetContentSelected = false, + selectedButtonType = R.string.pick_images + ) }, - modifier = Modifier.weight(1f) + modifier = Modifier.weight(1f), + colors = pickImagesColor ) // ACTION_GET_CONTENT will only support "images/*" and "videos/*" @@ -147,24 +186,109 @@ fun PhotoPickerScreen(photoPickerViewModel: PhotoPickerViewModel = viewModel()) ButtonComponent( label = stringResource(id = R.string.action_get_content), onClick = { - isAnyPickOptionEnabled = true - isActionGetContentSelected = true - allowMultiple = false // setting it to false (default) - resetApp(photoPickerViewModel) + resetFeatureComponents( + isGetContentSelected = true, + selectedButtonType = R.string.action_get_content + ) }, - modifier = Modifier.weight(1f) + modifier = Modifier.weight(1f), + colors = getContentColor ) } - // Display Images in Order - SwitchComponent( - label = stringResource(id = R.string.display_images_in_order), - checked = isOrderSelectionEnabled, - onCheckedChange = { isOrderSelectionEnabled = it }, - enabled = isAnyPickOptionEnabled && !isActionGetContentSelected - ) + if (!isActionGetContentSelected) { + // Display Images in Order + SwitchComponent( + label = stringResource(id = R.string.display_images_in_order), + checked = isOrderSelectionEnabled, + onCheckedChange = { isOrderSelectionEnabled = it } + ) + Spacer(modifier = Modifier.height(8.dp)) + } - Spacer(modifier = Modifier.height(8.dp)) + if (!allowCustomMimeType || isActionGetContentSelected){ + // SHOW ONLY IMAGES OR VIDEOS + Row( + modifier = Modifier + .fillMaxWidth() + .padding(vertical = 5.dp), + verticalAlignment = Alignment.CenterVertically + ) { + Column (modifier = Modifier.weight(1f)){ + SwitchComponent( + label = stringResource(R.string.show_images_only), + checked = showImagesOnly, + onCheckedChange = { + showImagesOnly = it + if (it) { + showVideosOnly = false + selectedMimeType = "image/*" + } else if (!showImagesOnly && !showVideosOnly) { + selectedMimeType = "*/*" + } + } + ) + } + + Spacer(modifier = Modifier.width(6.dp)) + + Column (modifier = Modifier.weight(1f)){ + SwitchComponent( + label = stringResource(R.string.show_videos_only), + checked = showVideosOnly, + onCheckedChange = { + showVideosOnly = it + if (it) { + showImagesOnly = false + selectedMimeType = "video/*" + } else if (!showImagesOnly && !showVideosOnly) { + selectedMimeType = "*/*" + } + } + ) + } + } + } + + if (!isActionGetContentSelected){ + // Allow Custom Mime Type + SwitchComponent( + label = stringResource(id = R.string.allow_custom_mime_type), + checked = allowCustomMimeType, + onCheckedChange = { + allowCustomMimeType = it + } + ) + + if (allowCustomMimeType){ + TextFieldComponent( + // Custom Mime Type Input + value = customMimeTypeInput, + onValueChange = { customMimeType -> + customMimeTypeInput = customMimeType + }, + label = stringResource(id = R.string.select_mime_type) + ) + } + + // To toggle show images only and show videos only switches + if (showImagesOnly) { + showVideosOnly = false + } else if (showVideosOnly) { + showImagesOnly = false + } + + Spacer(modifier = Modifier.height(16.dp)) + + // Launch Tab + DropdownList( + label = stringResource(id = R.string.select_launch_tab), + options = LaunchLocation.values().map { it.name }, + selectedOption = selectedLaunchTab, + onOptionSelected = { selectedLaunchTab = it }, + enabled = true + ) + } // Multiple Selection SwitchComponent( @@ -172,8 +296,7 @@ fun PhotoPickerScreen(photoPickerViewModel: PhotoPickerViewModel = viewModel()) checked = allowMultiple, onCheckedChange = { allowMultiple = it - }, - enabled = isAnyPickOptionEnabled + } ) // Max Number of Media Items @@ -188,8 +311,7 @@ fun PhotoPickerScreen(photoPickerViewModel: PhotoPickerViewModel = viewModel()) maxMediaItemsDisplayed = it.toIntOrNull() ?: 1 }, label = stringResource(id = R.string.max_number_of_media_items), - keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number), - enabled = isAnyPickOptionEnabled + keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number) ) } @@ -200,13 +322,13 @@ fun PhotoPickerScreen(photoPickerViewModel: PhotoPickerViewModel = viewModel()) ) } - Spacer(modifier = Modifier.height(16.dp)) + Spacer(modifier = Modifier.height(8.dp)) // Pick Media Button ButtonComponent( label = stringResource(R.string.pick_media), onClick = { - // Resetting the maxSelection input box when multiple selection is turned off + // Resetting the maxSelection input box when allowMultiple is deselected if (!allowMultiple) { maxSelectionLimitError = "" selectionErrorMessage = "" @@ -214,12 +336,20 @@ fun PhotoPickerScreen(photoPickerViewModel: PhotoPickerViewModel = viewModel()) maxMediaItemsDisplayed = 10 } + // Resetting the custom Mime Type Box when allowCustomMimeType is deselected + if (!allowCustomMimeType) { + customMimeTypeInput = "" + } + val errorMessage = photoPickerViewModel.validateAndLaunchPicker( isActionGetContentSelected = isActionGetContentSelected, allowMultiple = allowMultiple, maxMediaItemsDisplayed = maxMediaItemsDisplayed, selectedMimeType = selectedMimeType, + allowCustomMimeType = allowCustomMimeType, + customMimeTypeInput = customMimeTypeInput, isOrderSelectionEnabled = isOrderSelectionEnabled, + selectedLaunchTab = LaunchLocation.valueOf(selectedLaunchTab), launcher = launcher::launch ) if (errorMessage != null) { @@ -228,8 +358,7 @@ fun PhotoPickerScreen(photoPickerViewModel: PhotoPickerViewModel = viewModel()) } else { maxSelectionLimitError = "" } - }, - enabled = isAnyPickOptionEnabled + } ) // Error Message if there is a wrong input in the max Selection text field @@ -239,12 +368,8 @@ fun PhotoPickerScreen(photoPickerViewModel: PhotoPickerViewModel = viewModel()) Spacer(modifier = Modifier.height(16.dp)) - LazyColumn ( - modifier = Modifier - .padding(16.dp) - .fillMaxSize() - ){ - items(resultMedia) { uri -> + Column{ + resultMedia.forEach { uri -> if (isImage(context, uri)) { // To display image GlideImage( diff --git a/tools/photopickerV2/src/com/android/providers/media/tools/photopickerv2/photopicker/PhotoPickerViewModel.kt b/tools/photopickerV2/src/com/android/providers/media/tools/photopickerv2/photopicker/PhotoPickerViewModel.kt index b8175c62c..e72acb01b 100644 --- a/tools/photopickerV2/src/com/android/providers/media/tools/photopickerv2/photopicker/PhotoPickerViewModel.kt +++ b/tools/photopickerV2/src/com/android/providers/media/tools/photopickerv2/photopicker/PhotoPickerViewModel.kt @@ -17,11 +17,14 @@ package com.android.providers.media.tools.photopickerv2.photopicker import android.annotation.SuppressLint import android.app.Application +import android.content.ActivityNotFoundException import android.content.Intent import android.net.Uri import android.provider.MediaStore +import android.widget.Toast import androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia.Companion.isPhotoPickerAvailable import androidx.lifecycle.AndroidViewModel +import com.android.providers.media.tools.photopickerv2.utils.LaunchLocation import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow @@ -34,13 +37,14 @@ class PhotoPickerViewModel( application: Application, ) : AndroidViewModel(application) { + private val _selectedMedia = MutableStateFlow<List<Uri>>(emptyList()) val selectedMedia: StateFlow<List<Uri>> = _selectedMedia private val _pickImagesMaxSelectionLimit: Int init{ - // If the photo picker is available on the device, getPickImagesMaxLimit is there but not + // If the PhotoPicker is available on the device, getPickImagesMaxLimit is there but not // always visible on the SDK (only from Android 13+) _pickImagesMaxSelectionLimit = if (isPhotoPickerAvailable(application)){ val maxLimit = MediaStore.getPickImagesMaxLimit() @@ -59,7 +63,10 @@ class PhotoPickerViewModel( allowMultiple: Boolean, maxMediaItemsDisplayed: Int, selectedMimeType: String, + allowCustomMimeType: Boolean, + customMimeTypeInput: String, isOrderSelectionEnabled: Boolean, + selectedLaunchTab: LaunchLocation, launcher: (Intent) -> Unit ): String? { if (!isActionGetContentSelected && allowMultiple){ @@ -73,24 +80,40 @@ class PhotoPickerViewModel( } val intent = if (isActionGetContentSelected) { - // Action_get_content supports only images and videos in the Photo picker tab + // ACTION_GET_CONTENT supports only images and videos in the PhotoPicker tab Intent(Intent.ACTION_GET_CONTENT).apply { - type = "image/*,video/*" + if (selectedMimeType == "image/*") type = "image/*" + else if (selectedMimeType == "video/*") type = "video/*" + else { + type = "image/*,video/*" + putExtra(Intent.EXTRA_MIME_TYPES, arrayOf("image/*", "video/*")) + } putExtra(Intent.EXTRA_ALLOW_MULTIPLE, allowMultiple) addCategory(Intent.CATEGORY_OPENABLE) - putExtra(Intent.EXTRA_MIME_TYPES, arrayOf("image/*", "video/*")) } } else { Intent(MediaStore.ACTION_PICK_IMAGES).apply { - type = selectedMimeType + if (allowCustomMimeType) type = customMimeTypeInput + else if (selectedMimeType != "") type = selectedMimeType + putExtra(Intent.EXTRA_ALLOW_MULTIPLE, allowMultiple) if (allowMultiple) { putExtra(MediaStore.EXTRA_PICK_IMAGES_MAX, maxMediaItemsDisplayed) } - putExtra("android.provider.extra.PICK_IMAGES_IN_ORDER", isOrderSelectionEnabled) + putExtra( + MediaStore.EXTRA_PICK_IMAGES_LAUNCH_TAB, + if (selectedLaunchTab == LaunchLocation.ALBUMS_TAB) 0 else 1 + ) + putExtra(MediaStore.EXTRA_PICK_IMAGES_IN_ORDER, isOrderSelectionEnabled) } } - launcher(intent) + try { + launcher(intent) + } catch (e: ActivityNotFoundException) { + val errorMessage = + "No Activity found to handle Intent with type \"" + intent.getType() + "\"" + Toast.makeText(getApplication(), errorMessage, Toast.LENGTH_SHORT).show() + } return null } } diff --git a/tools/photopickerV2/src/com/android/providers/media/tools/photopickerv2/utils/UIComponents.kt b/tools/photopickerV2/src/com/android/providers/media/tools/photopickerv2/utils/UIComponents.kt index 064b62470..480210fe3 100644 --- a/tools/photopickerV2/src/com/android/providers/media/tools/photopickerv2/utils/UIComponents.kt +++ b/tools/photopickerV2/src/com/android/providers/media/tools/photopickerv2/utils/UIComponents.kt @@ -17,12 +17,21 @@ package com.android.providers.media.tools.photopickerv2.utils import android.widget.Toast import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.heightIn import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.foundation.verticalScroll import androidx.compose.material3.Button +import androidx.compose.material3.ButtonColors import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.NavigationBar @@ -32,6 +41,10 @@ import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Switch import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color @@ -40,6 +53,8 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp +import androidx.compose.ui.window.Popup +import androidx.compose.ui.window.PopupProperties import androidx.navigation.NavController import com.android.providers.media.tools.photopickerv2.R import com.android.providers.media.tools.photopickerv2.navigation.NavigationItem @@ -65,14 +80,12 @@ fun PhotoPickerTitle(label: String = stringResource(id = R.string.title_photopic * @param label the label to be displayed next to the switch component. * @param checked the state of the switch component. * @param onCheckedChange the callback function to be called when the switch component is changed. - * @param enabled the enabled state of the switch component. */ @Composable fun SwitchComponent( label: String, checked: Boolean, - onCheckedChange: (Boolean) -> Unit, - enabled: Boolean = true + onCheckedChange: (Boolean) -> Unit ) { Row( modifier = Modifier @@ -83,14 +96,13 @@ fun SwitchComponent( Text( text = label, modifier = Modifier.weight(1f), - color = if (enabled) Color.Black else Color.Gray, + color = Color.Black, fontWeight = FontWeight.Medium, fontSize = 16.sp, ) Switch( checked = checked, - onCheckedChange = onCheckedChange, - enabled = enabled + onCheckedChange = onCheckedChange ) } } @@ -102,7 +114,6 @@ fun SwitchComponent( * @param onValueChange the callback function to be called when the text field component is changed. * @param label the label to be displayed next to the text field component. * @param keyboardOptions the keyboard options to be used for the text field component. - * @param enabled the enabled state of the text field component. * @param modifier the modifier to be applied to the text field component. */ @Composable @@ -111,7 +122,6 @@ fun TextFieldComponent( onValueChange: (String) -> Unit, label: String, keyboardOptions: KeyboardOptions = KeyboardOptions.Default, - enabled: Boolean = true, modifier: Modifier = Modifier ) { OutlinedTextField( @@ -121,8 +131,7 @@ fun TextFieldComponent( keyboardOptions = keyboardOptions, modifier = modifier .fillMaxWidth() - .background(if (enabled) Color.Transparent else Color.Gray), - enabled = enabled + .background(Color.Transparent) ) } @@ -147,21 +156,20 @@ fun ErrorMessage( * * @param label the label to be displayed on the button component. * @param onClick the callback function to be called when the button component is clicked. - * @param enabled the enabled state of the button component. * @param modifier the modifier to be applied to the button component. + * @param colors the color of the button. */ @Composable fun ButtonComponent( label: String, onClick: () -> Unit, - enabled: Boolean = true, - modifier: Modifier = Modifier + modifier: Modifier = Modifier, + colors: ButtonColors = ButtonDefaults.buttonColors(), ) { Button( onClick = onClick, - colors = ButtonDefaults.buttonColors(), - modifier = modifier.fillMaxWidth(), - enabled = enabled + colors = colors, + modifier = modifier.fillMaxWidth() ) { Text(label) } @@ -204,4 +212,101 @@ fun NavigationComponent( } } +/** + * DropdownList is a composable function that creates a dropdown list component. + * + * @param label The label to be displayed above the dropdown list. + * @param options A list of options to be displayed in the dropdown list. + * @param selectedOption The currently selected option. + * @param onOptionSelected A callback function that gets called when an option is selected. + * @param enabled A boolean flag to enable or disable the dropdown list. + */ +@Composable +fun DropdownList( + label: String, + options: List<String>, + selectedOption: String, + onOptionSelected: (String) -> Unit, + enabled: Boolean +) { + var isExpanded by rememberSaveable { mutableStateOf(false) } + val scrollState = rememberScrollState() + Column { + Text( + text = label, + fontWeight = FontWeight.Bold, + modifier = Modifier.padding(bottom = 8.dp), + color = if (enabled) Color.Black else Color.Gray + ) + + Box( + modifier = Modifier + .fillMaxWidth() + .background(if (enabled) Color.Transparent else Color.Gray) + .clickable { if (enabled) isExpanded = true }, + contentAlignment = Alignment.Center + ) { + Text( + text = selectedOption, + color = if (enabled) Color.Black else Color.Gray, + modifier = Modifier.padding(8.dp) + ) + } + + if (isExpanded) { + Popup( + alignment = Alignment.TopCenter, + properties = PopupProperties( + excludeFromSystemGesture = true, + ), + onDismissRequest = { isExpanded = false } + ) { + Column( + modifier = Modifier + .fillMaxWidth() + .heightIn(max = 200.dp) + .verticalScroll(scrollState) + .border(1.dp, Color.Gray) + .background(Color.White), + horizontalAlignment = Alignment.CenterHorizontally, + ) { + options.forEachIndexed { index, option -> + if (index != 0) { + HorizontalDivider(thickness = 1.dp, color = Color.LightGray) + } + Box( + modifier = Modifier + .fillMaxWidth() + .clickable { + if (enabled) { + onOptionSelected(option) + isExpanded = false + } + } + .background(if (enabled) Color.Transparent else Color.LightGray), + contentAlignment = Alignment.Center + ) { + Text( + text = option, + color = if (enabled) Color.Black else Color.Gray, + modifier = Modifier.padding(8.dp) + ) + } + } + } + } + } + } +} + +enum class LaunchLocation { + PHOTOS_TAB, + ALBUMS_TAB; + + companion object { + fun getListOfAvailableLocations(): List<String> { + return values().toList().map { it -> it.name } + } + } +} diff --git a/tools/photopickerV2/src/com/android/providers/media/tools/photopickerv2/utils/Utils.kt b/tools/photopickerV2/src/com/android/providers/media/tools/photopickerv2/utils/Utils.kt index c3955f00b..a86198224 100644 --- a/tools/photopickerV2/src/com/android/providers/media/tools/photopickerv2/utils/Utils.kt +++ b/tools/photopickerV2/src/com/android/providers/media/tools/photopickerv2/utils/Utils.kt @@ -38,7 +38,7 @@ fun isImage(context: Context, uri: Uri): Boolean { * * @param photoPickerViewModel The PhotoPickerViewModel instance to reset. */ -fun resetApp(photoPickerViewModel: PhotoPickerViewModel) { +fun resetMedia(photoPickerViewModel: PhotoPickerViewModel) { photoPickerViewModel.updateSelectedMediaList(emptyList()) } |