-
Notifications
You must be signed in to change notification settings - Fork 239
Coroutines-Homework #161
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: development
Are you sure you want to change the base?
Coroutines-Homework #161
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package otus.homework.coroutines.data | ||
|
||
import retrofit2.http.GET | ||
|
||
interface CatsService { | ||
|
||
@GET("fact") | ||
suspend fun getCatFact(): FactDto | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package otus.homework.coroutines.data | ||
|
||
import com.google.gson.annotations.SerializedName | ||
|
||
data class FactDto( | ||
@SerializedName("fact") | ||
val fact: String, | ||
@SerializedName("length") | ||
val length: String | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package otus.homework.coroutines.data | ||
|
||
import com.google.gson.annotations.SerializedName | ||
|
||
data class ImageDto( | ||
@SerializedName("id") | ||
val id: String, | ||
@SerializedName("url") | ||
val url: String, | ||
@SerializedName("width") | ||
val width: Int, | ||
@SerializedName("height") | ||
val height: Int | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package otus.homework.coroutines.data | ||
|
||
import retrofit2.http.GET | ||
|
||
interface ImageService { | ||
|
||
@GET("images/search") | ||
suspend fun getImage(): ArrayList<ImageDto> | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package otus.homework.coroutines.data | ||
|
||
import otus.homework.coroutines.domain.Repository | ||
|
||
class RepositoryImpl( | ||
private val catsService: CatsService, | ||
private val imageService: ImageService | ||
) : Repository { | ||
|
||
override suspend fun getFact(): String = catsService.getCatFact().fact | ||
|
||
override suspend fun getImageUrl(): String = imageService.getImage()[0].url | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package otus.homework.coroutines.di | ||
|
||
import otus.homework.coroutines.data.CatsService | ||
import otus.homework.coroutines.data.ImageService | ||
import otus.homework.coroutines.data.RepositoryImpl | ||
import otus.homework.coroutines.domain.GetCatModelUseCase | ||
import otus.homework.coroutines.presentation.mvvm.MainViewModel | ||
import retrofit2.Retrofit | ||
import retrofit2.converter.gson.GsonConverterFactory | ||
|
||
class DiContainer { | ||
|
||
private val factRetrofit by lazy { | ||
Retrofit.Builder() | ||
.baseUrl("https://catfact.ninja/") | ||
.addConverterFactory(GsonConverterFactory.create()) | ||
.build() | ||
} | ||
|
||
private val factService by lazy { factRetrofit.create(CatsService::class.java) } | ||
|
||
private val imageRetrofit by lazy { | ||
Retrofit.Builder() | ||
.baseUrl("https://api.thecatapi.com/v1/") | ||
.addConverterFactory(GsonConverterFactory.create()) | ||
.build() | ||
} | ||
|
||
private val imageService by lazy { imageRetrofit.create(ImageService::class.java) } | ||
|
||
private val repository by lazy { RepositoryImpl(factService, imageService) } | ||
|
||
val useCase by lazy { GetCatModelUseCase(repository) } | ||
|
||
val mainViewModel by lazy { MainViewModel(useCase) } | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
package otus.homework.coroutines.domain | ||
|
||
data class CatModel( | ||
val fact: String, | ||
val imageUrl: String | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package otus.homework.coroutines.domain | ||
|
||
import kotlinx.coroutines.Dispatchers | ||
import kotlinx.coroutines.async | ||
import kotlinx.coroutines.withContext | ||
|
||
class GetCatModelUseCase(private val repository: Repository) { | ||
|
||
suspend operator fun invoke(): CatModel = withContext(Dispatchers.IO) { | ||
val fact = async { repository.getFact() } | ||
val url = async { repository.getImageUrl() } | ||
CatModel(fact.await(), url.await()) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package otus.homework.coroutines.domain | ||
|
||
interface Repository { | ||
|
||
suspend fun getFact(): String | ||
|
||
suspend fun getImageUrl(): String | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package otus.homework.coroutines.presentation.mvp | ||
|
||
import kotlinx.coroutines.* | ||
import otus.homework.coroutines.domain.GetCatModelUseCase | ||
import otus.homework.coroutines.presentation.CrashMonitor | ||
import java.net.SocketTimeoutException | ||
|
||
class CatsPresenter( | ||
private val catUseCase: GetCatModelUseCase | ||
) { | ||
private var _catsView: ICatsView? = null | ||
private var scope: CoroutineScope? = null | ||
|
||
init { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. А почему это не сделать при декларации переменной? Тогда не придется с сейфколлами работать |
||
scope = CoroutineScope(Dispatchers.Main + CoroutineName("CatsCoroutine")) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Инстанс job не нужен? |
||
} | ||
|
||
fun onInitComplete() { | ||
scope?.launch { | ||
try { | ||
val cat = catUseCase.invoke() | ||
_catsView?.populate(cat) | ||
} catch (e: CancellationException) { | ||
throw e | ||
} catch (_: SocketTimeoutException) { | ||
_catsView?.showError() | ||
} catch (t: Throwable) { | ||
CrashMonitor.trackWarning() | ||
} | ||
} | ||
} | ||
|
||
fun attachView(catsView: ICatsView) { | ||
_catsView = catsView | ||
} | ||
|
||
fun detachView() { | ||
_catsView = null | ||
scope?.cancel() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Тут не будет исключения тк нет инстанса Job? |
||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package otus.homework.coroutines.presentation.mvp | ||
|
||
import android.content.Context | ||
import android.util.AttributeSet | ||
import android.widget.Button | ||
import android.widget.ImageView | ||
import android.widget.TextView | ||
import android.widget.Toast | ||
import androidx.constraintlayout.widget.ConstraintLayout | ||
import com.squareup.picasso.Picasso | ||
import otus.homework.coroutines.R | ||
import otus.homework.coroutines.domain.CatModel | ||
|
||
class CatsView @JvmOverloads constructor( | ||
context: Context, | ||
attrs: AttributeSet? = null, | ||
defStyleAttr: Int = 0 | ||
) : ConstraintLayout(context, attrs, defStyleAttr), ICatsView { | ||
|
||
var presenter: CatsPresenter? = null | ||
|
||
override fun onFinishInflate() { | ||
super.onFinishInflate() | ||
findViewById<Button>(R.id.button).setOnClickListener { | ||
presenter?.onInitComplete() | ||
} | ||
} | ||
|
||
override fun populate(cat: CatModel) { | ||
findViewById<TextView>(R.id.fact_textView).text = cat.fact | ||
Picasso.get().load(cat.imageUrl).into(findViewById<ImageView>(R.id.imageView)) | ||
} | ||
|
||
override fun showError() { | ||
Toast.makeText(this.context, R.string.error, Toast.LENGTH_SHORT).show() | ||
} | ||
} | ||
|
||
interface ICatsView { | ||
|
||
fun populate(cat: CatModel) | ||
|
||
fun showError() | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Лучше указывать просто List