Procházet zdrojové kódy

Added pagination support for search photos

Ana Sekuloski před 3 roky
rodič
revize
3122409897

+ 8 - 2
flickersearchlibrary/src/main/java/com/livelike/flickersearchlibrary/Flickr.kt

@@ -19,13 +19,19 @@ object Flickr {
     private const val DEFAULT_NUMBER_OF_PHOTOS_PER_PAGE = 20
 
     /**
-     * Provides search results for given search term.
+     * Provides search results for given search term. [numOfPhotos] will be returned on given [page].
+     * By default 20 photos will be returned on the first page.
      * If no search query is provided, empty results will be returned.
      *
      * @param searchQuery [String] the search term for which photo results should be returned.
+     * @param numOfPhotos [Int] number of photos to return.
+     * @param page [Int] the page where the photos should be contained.
      * @return [List] of [Photo]s matching the given search term, or empty results if no term is provided.
      */
-    suspend fun search(searchQuery: String?) = flickrService.search(searchQuery)
+    suspend fun search(
+        searchQuery: String?, numOfPhotos: Int = DEFAULT_NUMBER_OF_PHOTOS_PER_PAGE,
+        page: Int = 1
+    ) = flickrService.search(searchQuery, numOfPhotos, page)
 
     /**
      * Retrieves [numOfPhotos] recently published photos on Flickr on the given [page].

+ 2 - 0
flickersearchlibrary/src/main/java/com/livelike/flickersearchlibrary/api/FlickrApi.kt

@@ -14,6 +14,8 @@ internal interface FlickrApi {
     @GET(".")
     suspend fun search(
         @Query(QUERY_TEXT) searchQuery: String,
+        @Query(QUERY_PER_PAGE) perPage: Int,
+        @Query(QUERY_PAGE) page: Int,
         @Query(QUERY_METHOD) method: String = SEARCH_METHOD,
         @Query(QUERY_API_KEY) apiKey: String = DEFAULT_API_KEY,
         @Query(QUERY_FORMAT) format: String = JSON_FORMAT,

+ 4 - 2
flickersearchlibrary/src/main/java/com/livelike/flickersearchlibrary/service/FlickrService.kt

@@ -8,13 +8,15 @@ import com.livelike.flickersearchlibrary.ui.model.PhotoItem
 internal interface FlickrService {
 
     /**
-     * Searches for photos and retrieves [List] of [PhotoItem]s.
+     * Searches for photos and retrieves [List] of [PhotoItem]s. [numOfPhotos] will be returned on given [page].
      * If no search query is provided, empty list will be returned.
      *
      * @param searchQuery [String] text query for searching photos.
+     * @param numOfPhotos [Int] number of photos to return.
+     * @param page [Int] the page where the photos should be contained.
      * @return [List] of [PhotoItem]s matching given [searchQuery] or empty list if no query is provided.
      */
-    suspend fun search(searchQuery: String?): List<PhotoItem>
+    suspend fun search(searchQuery: String?, numOfPhotos: Int, page: Int): List<PhotoItem>
 
     /**
      * Retrieves [numOfPhotos] recently published photos on Flickr on the given [page].

+ 11 - 4
flickersearchlibrary/src/main/java/com/livelike/flickersearchlibrary/service/logic/FlickrServiceLogic.kt

@@ -13,10 +13,14 @@ internal class FlickrServiceLogic(private val api: FlickrApi) : FlickrService {
 
     private val cachedPhotos = mutableListOf<PhotoItem>()
 
-    override suspend fun search(searchQuery: String?): List<PhotoItem> =
-        searchQuery?.let {
+    override suspend fun search(
+        searchQuery: String?,
+        numOfPhotos: Int,
+        page: Int
+    ): List<PhotoItem> {
+        return if (!searchQuery.isNullOrBlank()) {
             val response = executeApiCall {
-                api.search(searchQuery)
+                api.search(searchQuery, numOfPhotos, page)
             }
             if (response is ApiResponse.Success) {
                 val photoItems = response.body.map {
@@ -27,7 +31,10 @@ internal class FlickrServiceLogic(private val api: FlickrApi) : FlickrService {
             }
 
             cachedPhotos
-        } ?: emptyList()
+        } else {
+            emptyList()
+        }
+    }
 
     override suspend fun getRecentPhotos(numOfPhotos: Int, page: Int): List<PhotoItem> {
         val response = executeApiCall {

+ 7 - 2
flickersearchlibrary/src/main/java/com/livelike/flickersearchlibrary/ui/FlickrPhotosActivity.kt

@@ -46,12 +46,12 @@ class FlickrPhotosActivity : AppCompatActivity() {
 
     private fun setupListeners() {
         views.searchView.setOnSearchClickListener {
-            viewModel.searchPhotos(views.searchView.query.toString())
+            search(views.searchView.query.toString())
         }
 
         views.searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
             override fun onQueryTextSubmit(query: String?): Boolean {
-                viewModel.searchPhotos(query)
+                search(query)
                 return true
             }
 
@@ -81,4 +81,9 @@ class FlickrPhotosActivity : AppCompatActivity() {
             viewModel.getRecentPhotos()
         }
     }
+
+    private fun search(searchQuery: String?) {
+        photosAdapter.clearItems()
+        viewModel.searchPhotos(searchQuery)
+    }
 }

+ 15 - 5
flickersearchlibrary/src/main/java/com/livelike/flickersearchlibrary/ui/FlickrPhotosViewModel.kt

@@ -17,23 +17,33 @@ internal class FlickrPhotosViewModel : ViewModel() {
 
     fun getRecentPhotos() = viewModelScope.launch {
         _photos.postValue(Flickr.getRecentPhotos())
-        visiblePhotosState = PhotosState(PhotoType.RECENT, 1)
+        visiblePhotosState = PhotosState(PhotoType.RECENT, 1, null)
     }
 
     fun searchPhotos(searchQuery: String?) = viewModelScope.launch {
         _photos.postValue(Flickr.search(searchQuery))
-        visiblePhotosState = PhotosState(PhotoType.SEARCH, 1)
+        visiblePhotosState = PhotosState(PhotoType.SEARCH, 1, searchQuery)
     }
 
     fun loadMorePhotos() = viewModelScope.launch {
         val nextPage = visiblePhotosState.currentPage + 1
-        if (visiblePhotosState.type == PhotoType.RECENT) {
-            _photos.postValue(Flickr.getRecentPhotos(page = nextPage))
+        when (visiblePhotosState.type) {
+            PhotoType.RECENT -> _photos.postValue(Flickr.getRecentPhotos(page = nextPage))
+            PhotoType.SEARCH -> _photos.postValue(
+                Flickr.search(
+                    page = nextPage,
+                    searchQuery = visiblePhotosState.searchQuery
+                )
+            )
         }
         visiblePhotosState = visiblePhotosState.copy(currentPage = nextPage)
     }
 
-    private data class PhotosState(var type: PhotoType, var currentPage: Int)
+    private data class PhotosState(
+        var type: PhotoType,
+        var currentPage: Int,
+        var searchQuery: String?
+    )
 
     private enum class PhotoType {
         RECENT,

+ 4 - 0
flickersearchlibrary/src/main/java/com/livelike/flickersearchlibrary/ui/adapter/FlickrPhotosAdapter.kt

@@ -18,6 +18,10 @@ class FlickrPhotosAdapter : RecyclerView.Adapter<FlickrPhotosAdapter.PhotoViewHo
         itemsListDiffer.submitList(currentList)
     }
 
+    fun clearItems() {
+        itemsListDiffer.submitList(emptyList())
+    }
+
     override fun onCreateViewHolder(
         parent: ViewGroup,
         viewType: Int