Skip to content
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

add moxy #1

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 17 additions & 5 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ dependencies {
//SwipeRefreshLayout
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0"

//Coil
implementation "io.coil-kt:coil:1.1.1"

def navigation = "2.4.2"
implementation "androidx.navigation:navigation-fragment-ktx:$navigation"
implementation "androidx.navigation:navigation-ui-ktx:$navigation"
Expand All @@ -70,20 +73,29 @@ dependencies {
def retrofit = "2.9.0"
implementation "com.squareup.retrofit2:retrofit:$retrofit"
implementation "com.squareup.retrofit2:converter-gson:$retrofit"
implementation "com.squareup.retrofit2:adapter-rxjava3:${retrofit}"
implementation "com.squareup.retrofit2:adapter-rxjava3:$retrofit"

def okhttp = "5.0.0-alpha.3"
def okhttp = "5.0.0-alpha.6"
implementation "com.squareup.okhttp3:okhttp:$okhttp"
debugImplementation "com.squareup.okhttp3:logging-interceptor:$okhttp"
// endregion

// region Hilt
def hilt_version = "2.40.5"
implementation "com.google.dagger:hilt-android:$hilt_version"
kapt "com.google.dagger:hilt-compiler:$hilt_version"

def hiltExt = "1.3.0-RC1"
implementation "it.czerwinski.android.hilt:hilt-extensions:${hiltExt}"
kapt "it.czerwinski.android.hilt:hilt-processor:${hiltExt}"
def hiltExt = "1.3.0"
implementation "it.czerwinski.android.hilt:hilt-extensions:$hiltExt"
kapt "it.czerwinski.android.hilt:hilt-processor:$hiltExt"
// endregion

def moxy = "2.2.2"
implementation "com.github.moxy-community:moxy:$moxy"
implementation "com.github.moxy-community:moxy-androidx:$moxy"
implementation "com.github.moxy-community:moxy-material:$moxy"
implementation "com.github.moxy-community:moxy-ktx:$moxy"
kapt "com.github.moxy-community:moxy-compiler:$moxy"


testImplementation 'junit:junit:4.13.2'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import retrofit2.adapter.rxjava3.RxJava3CallAdapterFactory
import retrofit2.converter.gson.GsonConverterFactory
import ru.itis.karakurik.spacexapp.data.network.SpaceXApi
import ru.itis.karakurik.spacexapp.di.qualifier.BaseUrl
import ru.itis.karakurik.spacexapp.di.qualifier.CacheMaxSize
import ru.itis.karakurik.spacexapp.di.qualifier.LoggingInterceptor
import java.io.File
import javax.inject.Qualifier
Expand Down Expand Up @@ -61,25 +62,22 @@ class NetModule {

@Provides
fun provideCallAdapterFactory(): CallAdapter.Factory = RxJava3CallAdapterFactory.create()

@Provides
@BaseUrl
fun provideBaseUrl(): String = BASE_URL

@Provides
@LoggingInterceptor
fun provideLoggingInterceptor(): Interceptor {
return HttpLoggingInterceptor()
fun provideLoggingInterceptor(): Interceptor =
HttpLoggingInterceptor()
.setLevel(HttpLoggingInterceptor.Level.BODY)
}

@Provides
fun provideCacheDirectory(): File {
return File("cache");
}

@Qualifier
annotation class CacheMaxSize

@CacheMaxSize
@Provides
fun provideCacheMaxSize(): Long {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package ru.itis.karakurik.spacexapp.di.qualifier

import javax.inject.Qualifier

@Qualifier
@Retention(AnnotationRetention.RUNTIME)
annotation class CacheMaxSize
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
package ru.itis.karakurik.androidLab2.extentions
package ru.itis.karakurik.spacexapp.presentation.common.extentions

import androidx.appcompat.app.AppCompatActivity
import androidx.navigation.NavController
import androidx.navigation.fragment.NavHostFragment
import androidx.recyclerview.widget.LinearSmoothScroller

import androidx.recyclerview.widget.RecyclerView

fun AppCompatActivity.findController (id: Int) : NavController {
internal fun AppCompatActivity.findController (id: Int) : NavController {
return (supportFragmentManager.findFragmentById(id) as NavHostFragment).navController
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package ru.itis.karakurik.spacexapp.presentation.common.extentions

import android.content.Context
import android.widget.Toast

internal fun Context.toastLong(message: String?) =
message?.let {
Toast.makeText(
this,
message,
Toast.LENGTH_LONG
).show()
}

internal fun Context.toastShort(message: String?) =
message?.let {
Toast.makeText(
this,
message,
Toast.LENGTH_SHORT
).show()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package ru.itis.karakurik.spacexapp.presentation.common.extentions

import android.view.View

internal fun View.toGone() {
this.visibility = View.GONE
}

internal fun View.toVisible() {
this.visibility = View.VISIBLE
}

internal fun View.toInvisible() {
this.visibility = View.INVISIBLE
}
Original file line number Diff line number Diff line change
@@ -1,27 +1,48 @@
package ru.itis.karakurik.spacexapp.presentation.launchDetails

import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
import coil.load
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.Dispatchers
import moxy.MvpAppCompatFragment
import moxy.MvpPresenter
import moxy.ktx.moxyPresenter
import moxy.presenter.InjectPresenter
import moxy.presenter.ProvidePresenter
import ru.itis.karakurik.spacexapp.R
import ru.itis.karakurik.spacexapp.databinding.FragmentLaunchDetailsBinding
import ru.itis.karakurik.spacexapp.domain.entity.Launch
import ru.itis.karakurik.spacexapp.domain.utils.DateHelper
import ru.itis.karakurik.spacexapp.presentation.common.extentions.toGone
import ru.itis.karakurik.spacexapp.presentation.common.extentions.toVisible
import ru.itis.karakurik.spacexapp.presentation.common.extentions.toastLong
import javax.inject.Inject
import javax.inject.Provider

@AndroidEntryPoint
class LaunchDetailsFragment : Fragment() {
class LaunchDetailsFragment : MvpAppCompatFragment(), LaunchDetailsView {

private var _binding: FragmentLaunchDetailsBinding? = null
private val binding get() = _binding!!

private val args: LaunchDetailsFragmentArgs by navArgs()
private val viewModel: LaunchDetailsViewModel by viewModels()

@Inject
lateinit var presenterProvider: Provider<LaunchDetailsPresenter>

private val presenter by moxyPresenter {
presenterProvider.get()
}

override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
Expand All @@ -34,37 +55,42 @@ class LaunchDetailsFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

initObservers()
presenter.onGetLaunch(args.launchId)
}

viewModel.onGetLaunch(args.launchId)
override fun onDestroy() {
super.onDestroy()
_binding = null
}

private fun initObservers() {
with(viewModel) {
launch.observe(viewLifecycleOwner) { result ->
result.fold(
onSuccess = {
setLaunchData(it)
}, onFailure = {
Toast.makeText(
requireContext(),
"Не удалось получить информацию о полете",
Toast.LENGTH_LONG
).show()
}
)
}
}
override fun showLoading() {
binding.progress.toVisible()
}

private fun setLaunchData(launch: Launch) {
with(binding) {
tvHello.text = DateHelper.convertTimeStampToString(launch.dateUnix)
}
override fun hideLoading() {
binding.progress.toGone()
}

override fun onDestroy() {
super.onDestroy()
_binding = null
override fun consumerError(throwable: Throwable) {
requireContext().toastLong("Не удалось получить информацию о полете")
}

override fun showLaunchData(launch: Launch) {
with(binding) {
tvLaunchName.text = launch.name
ivLaunchIcon.load(launch.largeImageUrl) {
placeholder(R.drawable.launch_icon_large)
crossfade(true)
}
tvLaunchDescription.text = launch.details
ivLaunchIcon.setOnClickListener {
startActivity(
Intent(
Intent.ACTION_VIEW,
Uri.parse(launch.webCastUrl)
)
)
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,44 +1,37 @@
package ru.itis.karakurik.spacexapp.presentation.launchDetails

import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import dagger.hilt.android.lifecycle.HiltViewModel
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.disposables.CompositeDisposable
import io.reactivex.rxjava3.kotlin.addTo
import io.reactivex.rxjava3.kotlin.subscribeBy
import ru.itis.karakurik.spacexapp.domain.entity.Launch
import moxy.MvpPresenter
import ru.itis.karakurik.spacexapp.domain.usecases.GetLaunchUseCase
import javax.inject.Inject

@HiltViewModel
class LaunchDetailsViewModel @Inject constructor(
class LaunchDetailsPresenter @Inject constructor(
private val getLaunchUseCase: GetLaunchUseCase
) : ViewModel() {
) : MvpPresenter<LaunchDetailsView>() {

private val disposables = CompositeDisposable()

private var _launch: MutableLiveData<Result<Launch>> = MutableLiveData()
val launch get() = _launch

fun onGetLaunch(launchId: String) {
getLaunchUseCase(launchId)
.observeOn(AndroidSchedulers.mainThread())
.doOnSubscribe {
// showLoading()
viewState.showLoading()
}
.doAfterSuccess {
// hideLoading
.doFinally {
viewState.hideLoading()
}
.subscribeBy(onSuccess = {
_launch.value = Result.success(it)
}, onError = { error ->
_launch.value = Result.failure(error)
viewState.showLaunchData(it)
}, onError = {
viewState.consumerError(it)
}).addTo(disposables)
}

override fun onCleared() {
super.onCleared()
disposables.clear()
override fun onDestroy() {
super.onDestroy()
disposables.dispose()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package ru.itis.karakurik.spacexapp.presentation.launchDetails

import moxy.MvpView
import moxy.viewstate.strategy.alias.AddToEnd
import moxy.viewstate.strategy.alias.AddToEndSingle
import moxy.viewstate.strategy.alias.SingleState
import moxy.viewstate.strategy.alias.Skip
import ru.itis.karakurik.spacexapp.domain.entity.Launch

@AddToEnd
interface LaunchDetailsView : MvpView {
fun showLoading()

fun hideLoading()

@Skip
fun consumerError(throwable: Throwable)

fun showLaunchData(launch: Launch)
}

This file was deleted.

Loading