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.core.components 18 19 import com.android.photopicker.data.model.Group.Album 20 import com.android.photopicker.data.model.Group.Category 21 import com.android.photopicker.data.model.Group.MediaSet 22 import com.android.photopicker.data.model.Media 23 24 /** 25 * A wrapper around items in the [MediaGrid] to allow the grid to distinguish between separators and 26 * individual [Media]. 27 */ 28 sealed class MediaGridItem { 29 30 /** 31 * Represents a single [Media] (photo or video) in the [MediaGrid]. 32 * 33 * @property media The media that this item represents. 34 */ 35 data class MediaItem(val media: Media) : MediaGridItem() 36 37 /** 38 * Represents an [Album] in the [MediaGrid]. 39 * 40 * @property album The album that this item represents. 41 */ 42 data class AlbumItem(val album: Album) : MediaGridItem() 43 44 /** 45 * Represents a [CategoryItem] in the [MediaGrid]. 46 * 47 * @property mediaCategory The media category that this item represents. 48 */ 49 data class CategoryItem(val category: Category) : MediaGridItem() 50 51 /** 52 * Represents a [MediaSet] for People and Pets media category in the [MediaGrid]. 53 * 54 * @property mediaSet The media set that this item represents. 55 */ 56 data class PersonMediaSetItem(val mediaSet: MediaSet) : MediaGridItem() 57 58 /** 59 * Represents a [MediaSet] for all categories other than People and Pets in the [MediaGrid]. 60 * 61 * @property mediaSet The media set that this item represents. 62 */ 63 data class MediaSetItem(val mediaSet: MediaSet) : MediaGridItem() 64 65 /** 66 * Represents a separator in the [MediaGrid]. (Such as a month separator.) 67 * 68 * @property label A label that can be used to represent this separator in the UI. 69 */ 70 data class SeparatorItem(val label: String) : MediaGridItem() 71 72 /** Handles operations that requires customized output based on the type of [MediaGridItem]. */ 73 companion object { 74 /** 75 * Assembles a key for a [MediaGridItem]. This key must be always be stable and unique in 76 * the grid. 77 * 78 * @return a Unique, stable key that represents one item in the grid. 79 */ keyFactorynull80 fun keyFactory(item: MediaGridItem?, index: Int): String { 81 return when (item) { 82 is MediaItem -> "${item.media.pickerId}" 83 is SeparatorItem -> "${item.label}_$index" 84 is AlbumItem -> "${item.album.pickerId}" // check if this should be id or pickerId 85 is CategoryItem -> "${item.category.pickerId}" 86 is PersonMediaSetItem -> "${item.mediaSet.pickerId}" 87 is MediaSetItem -> "${item.mediaSet.pickerId}" 88 null -> "$index" 89 } 90 } 91 92 /** 93 * Default builder for generating a contentType signature for a grid item. 94 * 95 * ContentType is used to signify re-use of containers to increase the efficiency of the 96 * Grid loading. Each subtype of MediaGridItem should return a distinct value to ensure 97 * optimal re-use. 98 * 99 * @return The contentType signature of the provided item. 100 */ defaultBuildContentTypenull101 fun defaultBuildContentType(item: MediaGridItem?): Int { 102 return when (item) { 103 is MediaItem -> 1 104 is SeparatorItem -> 2 105 is AlbumItem -> 3 106 is CategoryItem -> 4 107 is PersonMediaSetItem -> 5 108 is MediaSetItem -> 6 109 null -> 0 110 } 111 } 112 } 113 } 114