Skip to content

Commit

Permalink
chore: Implement functionality of the network module
Browse files Browse the repository at this point in the history
  • Loading branch information
azrael8576 committed Dec 1, 2023
1 parent e26a734 commit 3f01dd9
Show file tree
Hide file tree
Showing 6 changed files with 194 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.wei.picquest.core.network

import com.wei.picquest.core.network.model.NetworkSearchImages

/**
* Interface representing network calls to the PicQuest backend
*/
interface PqNetworkDataSource {

suspend fun searchImages(query: String): NetworkSearchImages
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.wei.picquest.core.network.di

import com.wei.picquest.core.network.PqNetworkDataSource
import com.wei.picquest.core.network.retrofit.RetrofitPqNetwork
import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent

/**
* TODO Wei 移動至 build variants 下產出資料夾
*/
@Module
@InstallIn(SingletonComponent::class)
interface FlavoredNetworkModule {

@Binds
fun binds(implementation: RetrofitPqNetwork): PqNetworkDataSource
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.wei.picquest.core.network.di

import com.wei.core.network.BuildConfig
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import kotlinx.serialization.json.Json
import okhttp3.Call
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import javax.inject.Singleton

@Module
@InstallIn(SingletonComponent::class)
object NetworkModule {

@Provides
@Singleton
fun providesNetworkJson(): Json = Json {
ignoreUnknownKeys = true
}

@Provides
@Singleton
fun okHttpCallFactory(): Call.Factory = OkHttpClient.Builder()
.addInterceptor(
HttpLoggingInterceptor()
.apply {
if (BuildConfig.DEBUG) {
setLevel(HttpLoggingInterceptor.Level.BODY)
}
},
)
.build()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package com.wei.picquest.core.network.model

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

/**
* Network representation of [SearchImages] when fetched from /
*/
@Serializable
data class NetworkSearchImages(
@SerialName("total")
val total: Int,
@SerialName("totalHits")
val totalHits: Int,
@SerialName("hits")
val hits: List<NetworkImageDetail>
)

@Serializable
data class NetworkImageDetail(
@SerialName("id")
val id: Int,
@SerialName("pageURL")
val pageURL: String,
@SerialName("type")
val type: String,
@SerialName("tags")
val tags: String,
@SerialName("previewURL")
val previewURL: String,
@SerialName("previewWidth")
val previewWidth: Int,
@SerialName("previewHeight")
val previewHeight: Int,
@SerialName("webformatURL")
val webformatURL: String,
@SerialName("webformatWidth")
val webformatWidth: Int,
@SerialName("webformatHeight")
val webformatHeight: Int,
@SerialName("largeImageURL")
val largeImageURL: String,
@SerialName("fullHDURL")
val fullHDURL: String,
@SerialName("imageURL")
val imageURL: String,
@SerialName("imageWidth")
val imageWidth: Int,
@SerialName("imageHeight")
val imageHeight: Int,
@SerialName("imageSize")
val imageSize: Long,
@SerialName("views")
val views: Int,
@SerialName("downloads")
val downloads: Int,
@SerialName("likes")
val likes: Int,
@SerialName("comments")
val comments: Int,
@SerialName("user_id")
val userId: Int,
@SerialName("user")
val user: String,
@SerialName("userImageURL")
val userImageURL: String
// Add vectorURL if your account has full API access
// @SerialName("vectorURL")
// val vectorURL: String? = null
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package com.wei.picquest.core.network.retrofit

import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory
import com.wei.core.network.BuildConfig
import com.wei.picquest.core.network.PqNetworkDataSource
import com.wei.picquest.core.network.model.NetworkSearchImages
import kotlinx.serialization.json.Json
import okhttp3.Call
import okhttp3.MediaType.Companion.toMediaType
import retrofit2.Retrofit
import retrofit2.http.GET
import retrofit2.http.Query
import javax.inject.Inject
import javax.inject.Singleton

private const val PIXABAY_BASE_URL = BuildConfig.BACKEND_URL
private const val API_KEY = BuildConfig.API_KEY

/**
* Retrofit API declaration for Pixabay Network API
*/
interface RetrofitPixabayApi {
/**
* https://pixabay.com/api/?key=${api key}&q=yellow+flowers&image_type=photo
*/
@GET("")
suspend fun searchImages(
@Query("key") apiKey: String = API_KEY,
@Query("q") query: String,
@Query("image_type") imageType: String = "photo",
// Add more parameters as needed
): NetworkSearchImages
}

/**
* [Retrofit] backed [PqNetworkDataSource]
*/
@Singleton
class RetrofitPqNetwork @Inject constructor(
networkJson: Json,
okhttpCallFactory: Call.Factory,
) : PqNetworkDataSource {

private val pixabayApi = Retrofit.Builder()
.baseUrl(PIXABAY_BASE_URL)
.callFactory(okhttpCallFactory)
.addConverterFactory(
networkJson.asConverterFactory("application/json".toMediaType()),
)
.build()
.create(RetrofitPixabayApi::class.java)

override suspend fun searchImages(query: String): NetworkSearchImages {
return pixabayApi.searchImages(query = query)
}
}
3 changes: 2 additions & 1 deletion secrets.defaults.properties
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
## This file provides default values to modules using the secrets-gradle-plugin. It is necessary
# because the secrets properties file is not under source control so CI builds will fail without
# default values.
BACKEND_URL="https://pixabay.com/api/"
BACKEND_URL="https://pixabay.com/api/"
API_KEY="fake_api_key"

0 comments on commit 3f01dd9

Please sign in to comment.