Skip to content

Commit

Permalink
Add photos searching
Browse files Browse the repository at this point in the history
  • Loading branch information
stslex committed Oct 6, 2021
1 parent c5d90c5 commit 12c9451
Show file tree
Hide file tree
Showing 20 changed files with 403 additions and 87 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package st.slex.csplashscreen.data.model.remote.image

import com.google.gson.annotations.SerializedName

data class RemoteImageSearchModel(
val total: Int?,
val total_pages: Int?,
@SerializedName("results")
val results: List<RemoteImageModel>
)
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import st.slex.csplashscreen.utiles.API_KEY

class PhotosPagingSource @AssistedInject constructor(
private val service: PhotosService,
@Assisted("query") private val query: List<String>
@Assisted val query: QueryPhotos
) : PagingSource<Int, ImageModel>() {

override fun getRefreshKey(state: PagingState<Int, ImageModel>): Int? {
Expand All @@ -22,30 +22,24 @@ class PhotosPagingSource @AssistedInject constructor(
}

override suspend fun load(params: LoadParams<Int>): LoadResult<Int, ImageModel> {
if (query.isEmpty()) {
return LoadResult.Page(emptyList(), prevKey = null, nextKey = null)
}
try {
val pageNumber = params.key ?: INITIAL_PAGE_NUMBER
val pageSize = params.loadSize

val response = if (query.size > 1) {
service.getPhotos(
query[0],
query[1],
query[2],
pageNumber,
pageSize,
API_KEY
)
} else {
service.getPhotos(query[0], pageNumber, pageSize, API_KEY)
val response = when (query) {
is QueryPhotos.AllPhotos ->
service.getPhotos(pageNumber, pageSize, API_KEY)
is QueryPhotos.CollectionPhotos ->
service.getPhotos(query.query, pageNumber, pageSize, API_KEY)
is QueryPhotos.EmptyQuery -> null
}

return if (response.isSuccessful) {
return if (response?.body() != null && response.isSuccessful) {

val photos = response.body()!!.map {
it.toImageModel()
}

val nextPageNumber = if (photos.isEmpty()) null else pageNumber + 1
val prevPageNumber = if (pageNumber > 1) pageNumber - 1 else null
LoadResult.Page(photos, prevPageNumber, nextPageNumber)
Expand All @@ -61,10 +55,10 @@ class PhotosPagingSource @AssistedInject constructor(

@AssistedFactory
interface Factory {
fun create(@Assisted("query") query: List<String>): PhotosPagingSource
fun create(@Assisted query: QueryPhotos): PhotosPagingSource
}

companion object {
const val INITIAL_PAGE_NUMBER = 0
const val INITIAL_PAGE_NUMBER = 1
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ import javax.inject.Inject

interface PhotosRepository {

fun queryAll(query: List<String>): PagingSource<Int, ImageModel>
fun queryAll(query: QueryPhotos): PagingSource<Int, ImageModel>

class Base @Inject constructor(
private val photosPagingSourceFactory: PhotosPagingSource.Factory
) : PhotosRepository {

override fun queryAll(query: List<String>): PagingSource<Int, ImageModel> =
override fun queryAll(query: QueryPhotos): PagingSource<Int, ImageModel> =
photosPagingSourceFactory.create(query)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,20 @@ import retrofit2.http.GET
import retrofit2.http.Path
import retrofit2.http.Query
import st.slex.csplashscreen.data.model.remote.image.RemoteImageModel
import st.slex.csplashscreen.utiles.QUERY_API_KEY
import st.slex.csplashscreen.utiles.QUERY_PAGE
import st.slex.csplashscreen.utiles.QUERY_PAGE_SIZE
import st.slex.csplashscreen.utiles.*

interface PhotosService {

@GET("{query1}/{query2}/{query3}")
@GET("$GET_COLLECTIONS/{query}/$GET_PHOTOS")
suspend fun getPhotos(
@Path("query1") query1: String,
@Path("query2") query2: String,
@Path("query3") query3: String,
@Path("query") query: String,
@Query(QUERY_PAGE) page: Int,
@Query(QUERY_PAGE_SIZE) page_size: Int,
@Query(QUERY_API_KEY) api_key: String
): Response<List<RemoteImageModel>>

@GET("{q}")
@GET(GET_PHOTOS)
suspend fun getPhotos(
@Path("q") query: String,
@Query(QUERY_PAGE) page: Int,
@Query(QUERY_PAGE_SIZE) page_size: Int,
@Query(QUERY_API_KEY) api_key: String
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package st.slex.csplashscreen.data.photos

sealed class QueryPhotos {
class CollectionPhotos(val query: String) : QueryPhotos()
object AllPhotos : QueryPhotos()
object EmptyQuery : QueryPhotos()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package st.slex.csplashscreen.data.search

sealed class QuerySearch {
class SearchPhotos(val text: String) : QuerySearch()
object EmptyQuery : QuerySearch()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package st.slex.csplashscreen.data.search

import androidx.paging.PagingSource
import androidx.paging.PagingState
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import retrofit2.HttpException
import st.slex.csplashscreen.data.core.toImageModel
import st.slex.csplashscreen.data.model.ui.image.ImageModel
import st.slex.csplashscreen.utiles.API_KEY

class SearchPagingSource @AssistedInject constructor(
private val service: SearchService,
@Assisted val query: QuerySearch
) : PagingSource<Int, ImageModel>() {

override fun getRefreshKey(state: PagingState<Int, ImageModel>): Int? {
val anchorPosition = state.anchorPosition ?: return null
val anchorPage = state.closestPageToPosition(anchorPosition) ?: return null
return anchorPage.prevKey?.plus(1) ?: anchorPage.nextKey?.minus(1)
}

override suspend fun load(params: LoadParams<Int>): LoadResult<Int, ImageModel> {
try {
val pageNumber = params.key ?: INITIAL_PAGE_NUMBER
val pageSize = params.loadSize

val response = when (query) {
is QuerySearch.SearchPhotos ->
service.searchPhoto(query.text, pageNumber, pageSize, API_KEY)
is QuerySearch.EmptyQuery -> null
}

return if (response?.body() != null && response.isSuccessful) {

val photos = response.body()!!.results.map {
it.toImageModel()
}

val nextPageNumber = if (photos.isEmpty()) null else pageNumber + 1
val prevPageNumber = if (pageNumber > 1) pageNumber - 1 else null
LoadResult.Page(photos, prevPageNumber, nextPageNumber)
} else {
LoadResult.Error(HttpException(response))
}
} catch (e: HttpException) {
return LoadResult.Error(e)
} catch (e: Exception) {
return LoadResult.Error(e)
}
}

@AssistedFactory
interface Factory {
fun create(@Assisted query: QuerySearch): SearchPagingSource
}

companion object {
const val INITIAL_PAGE_NUMBER = 1
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package st.slex.csplashscreen.data.search

import androidx.paging.PagingSource
import st.slex.csplashscreen.data.model.ui.image.ImageModel
import javax.inject.Inject

interface SearchRepository {

fun queryAll(query: QuerySearch): PagingSource<Int, ImageModel>

class Base @Inject constructor(
private val searchPagingSource: SearchPagingSource.Factory
) : SearchRepository {

override fun queryAll(query: QuerySearch): PagingSource<Int, ImageModel> =
searchPagingSource.create(query)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package st.slex.csplashscreen.data.search

import retrofit2.Response
import retrofit2.http.GET
import retrofit2.http.Query
import st.slex.csplashscreen.data.model.remote.image.RemoteImageSearchModel
import st.slex.csplashscreen.utiles.*


interface SearchService {

@GET("/$GET_SEARCH/$GET_PHOTOS")
suspend fun searchPhoto(
@Query(QUERY) query: String,
@Query(QUERY_PAGE) page: Int,
@Query(QUERY_PAGE_SIZE) page_size: Int,
@Query(QUERY_API_KEY) api_key: String
): Response<RemoteImageSearchModel>
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import retrofit2.Retrofit
import st.slex.csplashscreen.data.collections.CollectionService
import st.slex.csplashscreen.data.photo.PhotoService
import st.slex.csplashscreen.data.photos.PhotosService
import st.slex.csplashscreen.data.search.SearchService

@Module(includes = [RetrofitModule::class])
class NetworkServiceModule {
Expand All @@ -21,4 +22,8 @@ class NetworkServiceModule {
@Provides
fun providesPhotoService(retrofit: Retrofit): PhotoService =
retrofit.create(PhotoService::class.java)

@Provides
fun providesPhotoSearchService(retrofit: Retrofit): SearchService =
retrofit.create(SearchService::class.java)
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi
import st.slex.csplashscreen.data.collections.CollectionsRepository
import st.slex.csplashscreen.data.photo.PhotoRepository
import st.slex.csplashscreen.data.photos.PhotosRepository
import st.slex.csplashscreen.data.search.SearchRepository

@Module
interface RepositoryModule {
Expand All @@ -19,4 +20,8 @@ interface RepositoryModule {
@ExperimentalCoroutinesApi
@Binds
fun bindsPhotoRepository(repository: PhotoRepository.Base): PhotoRepository

@ExperimentalCoroutinesApi
@Binds
fun bindsPhotoSearchRepository(repository: SearchRepository.Base): SearchRepository
}
14 changes: 14 additions & 0 deletions app/src/main/java/st/slex/csplashscreen/ui/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import st.slex.csplashscreen.ui.collection.Collection
import st.slex.csplashscreen.ui.detail.ImageDetailScreen
import st.slex.csplashscreen.ui.main.MainScreen
import st.slex.csplashscreen.ui.raw_image.RawImageScreen
import st.slex.csplashscreen.ui.search_photos.SearchPhotosScreen
import st.slex.csplashscreen.ui.theme.CSplashScreenTheme
import javax.inject.Inject

Expand Down Expand Up @@ -101,5 +102,18 @@ fun NavigationComponent(navController: NavHostController, viewModel: MainViewMod
) {
RawImageScreen(url = it.arguments?.getString("url").toString(), navController)
}

composable(
route = "search_photos/{query}",
arguments = listOf(navArgument("query") { type = NavType.StringType })
) {
var query = it.arguments?.getString("query").toString()
if (query == " ") query = ""
SearchPhotosScreen(
viewModel = viewModel,
navController = navController,
querySearch = query
)
}
}
}
Loading

0 comments on commit 12c9451

Please sign in to comment.