Commit 2bcdb6fa authored by Vladislav Bogdashkin's avatar Vladislav Bogdashkin 🎣

Merge branch 'feature/mvi' into develop

parents da5c313b 3ba27c4e
*.iml
.gradle
/local.properties
/.idea
/.idea/caches
/.idea/libraries
/.idea/modules.xml
......
......@@ -2,6 +2,7 @@
<dictionary name="bogdashkin">
<words>
<w>Biganto</w>
<w>snackbar</w>
</words>
</dictionary>
</component>
\ No newline at end of file
......@@ -40,6 +40,7 @@ android {
androidExtensions {
experimental = true
}
configurations.all {
resolutionStrategy.force "com.bluelinelabs:conductor:$conductorVersion"
}
......@@ -64,14 +65,7 @@ dependencies {
implementation fileTree(include: ['*.jar', '*.aar'], dir: 'libs')
implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
implementation 'androidx.core:core-ktx:1.0.2'
//Koin
implementation "org.koin:koin-core:$koinVersion"
implementation "org.koin:koin-core-ext:$koinVersion"
implementation "org.koin:koin-android:$koinVersion"
implementation "org.koin:koin-android-scope:$koinVersion"
implementation 'androidx.core:core-ktx:1.1.0'
//Material
implementation "com.google.android.material:material:$materialVersion"
......@@ -96,6 +90,28 @@ dependencies {
//RxJava
implementation "io.reactivex.rxjava3:rxjava:$rxJavaVersion"
//Mosby MVI
implementation "com.hannesdorfmann.mosby3:mvi-conductor:$mosbyMviConductorVersion"
//conductor support
implementation "com.bluelinelabs:conductor-support:$conductorVersion"
//Butterknife
implementation "com.jakewharton:butterknife:$butterKnifeVersion"
kapt "com.jakewharton:butterknife-compiler:$butterKnifeVersion"
//Dagger2
implementation "com.google.dagger:dagger:$daggerVersion"
kapt "com.google.dagger:dagger-compiler:$daggerVersion"
implementation "com.google.dagger:dagger-android:$daggerVersion"
implementation "com.google.dagger:dagger-android-support:$daggerVersion"
kapt "com.google.dagger:dagger-android-processor:$daggerVersion"
//Rx Relay
implementation "com.jakewharton.rxrelay2:rxrelay:$rxRelayVersion"
//Tests
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.2.0'
......
package com.biganto.visual.roompark.base
import android.os.Bundle
import android.os.PersistableBundle
import dagger.android.support.DaggerAppCompatActivity
import io.reactivex.disposables.CompositeDisposable
/**
* Created by Vladislav Bogdashkin on 30.09.2019.
*/
abstract class BaseRoomParkActivity : DaggerAppCompatActivity(){
protected val disposable = CompositeDisposable()
override fun onCreate(savedInstanceState: Bundle?, persistentState: PersistableBundle?) {
super.onCreate(savedInstanceState, persistentState)
}
override fun onDestroy() {
super.onDestroy()
disposable.clear()
}
override fun onAttachedToWindow() {
super.onAttachedToWindow()
}
}
\ No newline at end of file
package com.biganto.visual.roompark.base
import android.app.Application
import android.util.Log
import com.biganto.visual.roompark.BuildConfig
import com.biganto.visual.roompark.di.koin.initDI
import com.biganto.visual.roompark.di.dagger.DaggerAppComponent
import com.crashlytics.android.Crashlytics
import com.squareup.picasso.Picasso
import dagger.android.AndroidInjector
import dagger.android.DaggerApplication
import timber.log.Timber
/**
* Created by Vladislav Bogdashkin on 03.09.2019.
*/
class RoomParkApplication : Application() {
class RoomParkApplication : DaggerApplication() {
override fun applicationInjector(): AndroidInjector<out DaggerApplication> {
return DaggerAppComponent.builder()
.context(this)
.build()
}
override fun onCreate() {
super.onCreate()
initDI()
if (BuildConfig.DEBUG) Timber.plant(Timber.DebugTree())
else Timber.plant(CrashlyticsTree())
......
package com.biganto.visual.roompark.base
import android.os.Bundle
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.widget.Toolbar
import androidx.coordinatorlayout.widget.CoordinatorLayout
import butterknife.BindView
import butterknife.ButterKnife
import com.biganto.visual.roompark.BuildConfig
import com.biganto.visual.roompark.R
import com.biganto.visual.roompark.di.koin.StartUpData
import org.koin.android.scope.currentScope
import com.biganto.visual.roompark.view_utils.app_bar.DragControlAppBarLayoutBehaviour
import com.biganto.visual.roompark.view_utils.snackbar.ISnackBarProvider
import com.bluelinelabs.conductor.Conductor
import com.bluelinelabs.conductor.Router
import com.crashlytics.android.Crashlytics
import com.google.android.material.appbar.AppBarLayout
import com.google.android.material.appbar.CollapsingToolbarLayout
import com.google.android.material.bottomnavigation.BottomNavigationView
import io.fabric.sdk.android.Fabric
import javax.inject.Inject
class RoomParkMainActivity : AppCompatActivity() {
class RoomParkMainActivity(
) : BaseRoomParkActivity()
,ICollapsingToolBar
,IConductorActivity
,IBottomNavigation{
lateinit var entryText:TextView
private val entryDate : StartUpData by currentScope.inject()
@Inject
lateinit var snackbarProvider: ISnackBarProvider
private lateinit var router: Router
@BindView(R.id.top_toolbar) override lateinit var topAppBar: Toolbar
@BindView(R.id.app_bar) override lateinit var appBar: AppBarLayout
@BindView(R.id.topToolbarHolder) override lateinit var coordinatorLayout: CoordinatorLayout
@BindView(R.id.collapsingToolbarLayout) override lateinit var collapsingToolbarLayout: CollapsingToolbarLayout
@BindView(R.id.conductor_container) override lateinit var conductorContainer: ViewGroup
@BindView(R.id.bottom_navigation_view) override lateinit var bottomNavigation: BottomNavigationView
override fun onCreate(savedInstanceState: Bundle?) {
setTheme(R.style.AppTheme)
super.onCreate(savedInstanceState)
if (!BuildConfig.DEBUG) Fabric.with(this, Crashlytics())
setContentView(R.layout.activity_main)
ButterKnife.bind(this)
setSupportActionBar(topAppBar)
router = Conductor.attachRouter(this, conductorContainer, savedInstanceState)
snackbarProvider.bindRootView(rootView = coordinatorLayout)
}
override fun displayBackButton(show: Boolean) {
supportActionBar?.setDisplayHomeAsUpEnabled(show)
}
override fun hideAll() {
appBar.visibility=Toolbar.INVISIBLE
bottomNavigation.visibility = Toolbar.GONE
val params = coordinatorLayout.layoutParams as CoordinatorLayout.LayoutParams
params.behavior = null
coordinatorLayout.requestLayout()
}
override fun showAll() {
appBar.setExpanded(false,false)
collapsingToolbarLayout.visibility= View.VISIBLE
bottomNavigation.visibility = Toolbar.VISIBLE
appBar.visibility= View.VISIBLE
topAppBar.visibility = View.VISIBLE
val params = coordinatorLayout.layoutParams as CoordinatorLayout.LayoutParams
params.behavior = AppBarLayout.ScrollingViewBehavior()
coordinatorLayout.requestLayout()
}
override fun appBarScrollable(allow: Boolean) {
val params = appBar.layoutParams as CoordinatorLayout.LayoutParams
val behavior = params.behavior as DragControlAppBarLayoutBehaviour
behavior.allowDrag=allow
}
}
package com.biganto.visual.roompark.base
import android.view.ViewGroup
import androidx.appcompat.widget.Toolbar
import androidx.coordinatorlayout.widget.CoordinatorLayout
import com.google.android.material.appbar.AppBarLayout
import com.google.android.material.appbar.CollapsingToolbarLayout
import com.google.android.material.bottomnavigation.BottomNavigationView
/**
* Created by Vladislav Bogdashkin on 26.09.2019.
*/
interface ISupportActionBar{
val topAppBar : Toolbar
fun displayBackButton(show:Boolean)
fun hideAll()
fun showAll()
}
interface ICollapsingToolBar : ISupportActionBar{
val appBar : AppBarLayout
val coordinatorLayout: CoordinatorLayout
val collapsingToolbarLayout : CollapsingToolbarLayout
fun appBarScrollable(allow:Boolean)
}
interface IConductorActivity{
val conductorContainer: ViewGroup
}
interface IBottomNavigation{
val bottomNavigation : BottomNavigationView
}
package com.biganto.visual.roompark.conductor
import com.hannesdorfmann.mosby3.mvp.MvpView
/**
* Created by Vladislav Bogdashkin on 28.05.2018.
*/
interface BigantoBaseContract<in VS : BigantoBaseViewState> : MvpView {
fun render(viewState: VS)
}
abstract class BigantoBaseViewState
\ No newline at end of file
package com.biganto.visual.roompark.conductor
import android.content.Context
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.inputmethod.InputMethodManager
import android.widget.Toast
import androidx.annotation.LayoutRes
import androidx.annotation.StringRes
import butterknife.ButterKnife
import com.biganto.visual.roompark.R
import com.biganto.visual.roompark.base.ICollapsingToolBar
import com.biganto.visual.roompark.base.RoomParkMainActivity
import com.biganto.visual.roompark.conductor.mosby.mvi.BigantoMviController
import com.biganto.visual.roompark.di.dagger.PerScreen
import com.biganto.visual.roompark.view_utils.snackbar.ISnackBarProvider
import com.hannesdorfmann.mosby3.mvi.MviBasePresenter
import io.reactivex.disposables.CompositeDisposable
import javax.inject.Inject
/**
* Created by Vladislav Bogdashkin on 28.05.2018.
*/
@PerScreen
abstract class BigantoBaseController<VS : BigantoBaseViewState,V: BigantoBaseContract<VS>,P : MviBasePresenter<V,VS>>
: BigantoMviController<V, P> {
constructor():super()
constructor(args: Bundle):super(args)
protected val detachDisposable = CompositeDisposable()
abstract override fun createPresenter(): P
@LayoutRes
protected abstract fun getLayoutId(): Int
@StringRes
protected abstract fun getToolbarTitleId(): Int
@Inject
private lateinit var roomParkActivity:RoomParkMainActivity
protected val toolBar: ICollapsingToolBar = roomParkActivity
protected val snackbar: ISnackBarProvider = roomParkActivity.snackbarProvider
override fun onDetach(view: View) {
detachDisposable.clear()
super.onDetach(view)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup): View {
val view = inflater.inflate(getLayoutId(), container, false)
// instantiate the view
ButterKnife.bind(this, view)
return view
}
protected fun View.hideKeyboard() {
val inputMethodManager = applicationContext
?.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
inputMethodManager.hideSoftInputFromWindow(this.windowToken, 0)
}
protected fun View.showKeyboard() {
val inputMethodManager = applicationContext?.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
inputMethodManager.showSoftInput(this, 0)
}
protected fun showMessage(@StringRes msgResId: Int) {
Toast.makeText(this.applicationContext, msgResId, Toast.LENGTH_SHORT).show()
}
override fun handleBack(): Boolean {
return super.handleBack()
}
protected val isTablet
get() = resources?.getBoolean(R.bool.isTablet)?:false
protected val catalogSpansCount
get() = resources?.getInteger(R.integer.catalogSpans)?:1
protected val toursSpansCount
get() = resources?.getInteger(R.integer.catalogSpans)?:1
}
\ No newline at end of file
package com.biganto.visual.roompark.conductor
import com.hannesdorfmann.mosby3.mvi.MviBasePresenter
import com.hannesdorfmann.mosby3.mvp.MvpView
import com.jakewharton.rxrelay2.PublishRelay
/**
* Created by Vladislav Bogdashkin on 30.09.2019.
*/
abstract class BigantoBasePresenter<V : MvpView, VS>
: MviBasePresenter<V, VS>(){
protected val restoreStateObservable =
PublishRelay.create<VS>()
}
\ No newline at end of file
package com.biganto.visual.androidplayer.conductor.dialogs
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.LinearLayout
import android.widget.TextView
import androidx.annotation.LayoutRes
import com.biganto.visual.roompark.R
import com.bluelinelabs.conductor.Controller
/**
* Created by Vladislav Bogdashkin on 09.04.2019.
*/
const val ALERT_DIALOG_MESSAGE_KEY = "BIGANTO_ALERT_MESSAGE"
const val ALERT_DIALOG_BUTTON_TEXT_KEY = "BIGANTO_ALERT_OK_BUTTON_TEXT"
const val ALERT_DIALOG_BUTTON_CANCEL_TEXT_KEY = "BIGANTO_ALERT_CANCEL_BUTTON_TEXT"
fun formBundle(message:String): Bundle {
val b = Bundle()
b.putString(ALERT_DIALOG_MESSAGE_KEY,message)
return b
}
fun formBundle(message:String,buttonText:String): Bundle {
val b = Bundle()
b.putString(ALERT_DIALOG_MESSAGE_KEY,message)
b.putString(ALERT_DIALOG_BUTTON_TEXT_KEY,buttonText)
return b
}
fun formBundle(message:String,buttonText:String,cancelButtonText:String): Bundle {
val b = Bundle()
b.putString(ALERT_DIALOG_MESSAGE_KEY,message)
b.putString(ALERT_DIALOG_BUTTON_TEXT_KEY,buttonText)
b.putString(ALERT_DIALOG_BUTTON_CANCEL_TEXT_KEY,cancelButtonText)
return b
}
open class AlertDialogController : Controller {
constructor():super()
constructor(args: Bundle):super(args)
public constructor(alertMessage:String):super(formBundle(alertMessage))
public constructor(alertMessage:String,buttonText: String):super(formBundle(alertMessage, buttonText))
public constructor(alertMessage:String,buttonText: String,cancelText: String)
:super(formBundle(alertMessage, buttonText,cancelText))
public open var dismissActionDelegate = {router.popController(this);Unit}
@LayoutRes
fun getLayoutId() = R.layout.alert_dialog_screen_view
private lateinit var messageTextView : TextView
private lateinit var okButton : Button
private lateinit var dismissButton : Button
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup): View {
val view = inflater.inflate(getLayoutId(), container, false)
messageTextView=view.findViewById(R.id.alert_message_text_view)
val alertMessage = args.getString(ALERT_DIALOG_MESSAGE_KEY)
messageTextView.text=alertMessage
okButton=view.findViewById(R.id.alert_ok_button)
if (args.containsKey(ALERT_DIALOG_BUTTON_TEXT_KEY))
okButton.text=args.getString(ALERT_DIALOG_BUTTON_TEXT_KEY)
dismissButton=view.findViewById(R.id.alert_dismiss_button)
val bContainer=view.findViewById<LinearLayout>(R.id.buttons_container)
if (args.containsKey(ALERT_DIALOG_BUTTON_CANCEL_TEXT_KEY)){
bContainer.weightSum=2f
dismissButton.visibility=View.VISIBLE
dismissButton.text=args.getString(ALERT_DIALOG_BUTTON_CANCEL_TEXT_KEY)
dismissButton.setOnClickListener { router.popController(this) }
}else{
bContainer.weightSum=1f
dismissButton.visibility=View.GONE
}
okButton.setOnClickListener {
router.popController(this)
dismissActionDelegate.invoke()
}
return view
}
}
\ No newline at end of file
package com.biganto.visual.roompark.conductor.dialogs
import android.os.Bundle
import com.biganto.visual.androidplayer.conductor.dialogs.AlertDialogController
/**
* Created by Vladislav Bogdashkin on 09.04.2019.
*/
class ExceptionAlertDialogController: AlertDialogController {
constructor(args: Bundle) :super(args)
constructor(message: String, buttonText: String):super(message, buttonText)
override var dismissActionDelegate = {activity?.finish();Unit}
}
\ No newline at end of file
package com.biganto.visual.roompark.conductor.dialogs
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import com.biganto.visual.androidplayer.conductor.dialogs.AlertDialogController
import timber.log.Timber
/**
* Created by Vladislav Bogdashkin on 09.04.2019.
*/
class UpdateAppAlertDialogController: AlertDialogController {
constructor(args: Bundle) : super(args)
constructor(message: String, buttonText: String) : super(message, buttonText)
override var dismissActionDelegate = {
val appPackageName = activity?.packageName
var uri = Uri.parse("https://cdn.fishki.net/upload/post/201502/17/1432283/659d2f29de589d5d41252f18e9beb292.jpg")
// uri = Uri.parse("market://details?id=$appPackageName");
try {
startActivity(Intent(Intent.ACTION_VIEW, uri))
} catch (e: Exception) {
when (e) {
is android.content.ActivityNotFoundException -> {
uri = Uri.parse("https://play.google.com/store/apps/details?id=$appPackageName")
startActivity(Intent(Intent.ACTION_VIEW, uri))
}
else -> {
Timber.e("Fatal exception occured, while try to update app version!: $e")
activity?.finish()
}
}
}
Unit
}
}
\ No newline at end of file
package com.biganto.visual.roompark.conductor.dialogs.change_handler;
import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.bluelinelabs.conductor.changehandler.AnimatorChangeHandler;
/**
* Created by Vladislav Bogdashkin on 09.04.2019.
*/
public class DialogChangeHandler extends AnimatorChangeHandler {
private static final int FadeInDuration = 240;
public DialogChangeHandler() {
super(false);
}
@NonNull
@Override
protected Animator getAnimator(@NonNull ViewGroup container, @Nullable View from, @Nullable View to, boolean isPush, boolean toAddedToContainer) {
AnimatorSet animator = new AnimatorSet();
if (to != null && toAddedToContainer) {
ObjectAnimator anim = ObjectAnimator.ofFloat(to, View.ALPHA, 0, 1f);
anim.setDuration(FadeInDuration);
animator.play(anim);
}
return animator;
}
@Override
protected void resetFromView(@NonNull View from) {
// empty - Nothing to do with parent view
}
}
package com.biganto.visual.roompark.conductor.mosby.mvi;
import android.os.Bundle;
import com.hannesdorfmann.mosby3.MviConductorDelegateCallback;
import com.hannesdorfmann.mosby3.MviController;
import com.hannesdorfmann.mosby3.mvi.MviPresenter;
import com.hannesdorfmann.mosby3.mvp.MvpView;
public abstract class BigantoMviController<V extends MvpView, P extends MviPresenter<V, ?>>
extends MviController<V,P> implements MvpView, MviConductorDelegateCallback<V, P> {
public BigantoMviController() {super();}
public BigantoMviController(Bundle args) {
super(args);
}
/**
* Переопределяем метод, чтобы подставить кастомную реализацию LifeCycleListener'a, с учетом проверки связанного
* презентера на null - значение
*/
protected LifecycleListener getMosbyLifecycleListener() {
return new BigantoMviConductorLifecycleListener<>(this);
}
}
package com.biganto.visual.roompark.conductor.mosby.mvi
import android.util.Log
import android.view.View
import androidx.annotation.NonNull
import com.bluelinelabs.conductor.Controller
import com.hannesdorfmann.mosby3.MviConductorDelegateCallback
import com.hannesdorfmann.mosby3.mvi.MviPresenter
import com.hannesdorfmann.mosby3.mvp.MvpView
/**
* В связи с тем, что в исходной реализации MviConductorLifeCycleListener презентер приватное поле,
* есть необходимость рконструировать дефолтный класс библиотеки с внесением изменений - проверкой поля presenter на
* null значение при вызове методов attachView и destroy.
*
* Суть проблемы кроется в том, что при реализации некоторых кейсов (например, когда мы желаем сохранять стек
* навигации среди нескольких роутеров одновроеменно), мы сохраняем ссылку на контроллер, даже в тех случаях когда
* презентер уничтожен (вьюха в mosbyMVI у нас и так отвязана от жизненного цикла контроллера) и при каскадном
* удалении бэкстека, у нас может получиться таким образом, что презентер уже был уничтожен ранее. Т.о. необходима
* проверка на наличие инстанса привязанного к контроллеру презентера.
*
* * **Детально по ссылке:** [mosby issue](https://github.com/sockeqwe/mosby-conductor/issues/38)
*/
class BigantoMviConductorLifecycleListener<V : MvpView, P : MviPresenter<V, *>>
/**
* Instantiate a new Mosby MVP Listener
*
* @param callback [MviConductorDelegateCallback] to set presenter. Typically the
* controller
* himself.
*/
@JvmOverloads constructor(private var callback: MviConductorDelegateCallback<V, P>?,
private val keepPresenterInstance: Boolean = true) : Controller.LifecycleListener() {
private var presenter: P? = null
override fun postCreateView(@NonNull controller: Controller, @NonNull view: View) {
var viewStateWillBeRestored = false
if (presenter == null) {
// Process death,
// hence no presenter with the given viewState id stored, although we have a viewState id
presenter = callback!!.createPresenter()
if (DEBUG) {
Log.d(
DEBUG_TAG,
"New Presenter instance created for $controller. Presenter: $presenter")
}
} else {
viewStateWillBeRestored = true
if (DEBUG) {
Log.d(
DEBUG_TAG, "Reusing Presenter instance for controller "
+ controller
+ ". Presenter: "
+ presenter)
}
}
val viewMpv = callback?.mvpView ?: throw NullPointerException(
"MvpView returned from getMvpView() is null. Returned by " + controller.activity!!)
if (viewStateWillBeRestored) {
callback!!.setRestoringViewState(true)
}
presenter?.attachView(viewMpv)
if (viewStateWillBeRestored) {
callback!!.setRestoringViewState(false)
}
if (DEBUG) {
Log.d(
DEBUG_TAG,
"MvpView attached to Presenter. MvpView: $view Presenter: $presenter")
}
}
override fun preDestroyView(@NonNull controller: Controller, @NonNull view: View) {
presenter?.detachView()
if (DEBUG) {
Log.d(
DEBUG_TAG, "detached MvpView from Presenter. MvpView "
+ callback!!.mvpView
+ " Presenter: "
+ presenter)
}
}
override fun postDestroy(@NonNull controller: Controller) {
if (DEBUG) {
Log.d(
DEBUG_TAG, "Presenter destroyed because View destroyed. MvpView "
+ callback!!.mvpView
+ " Presenter: "
+ presenter)
}
presenter?.destroy()
presenter = null
callback = null
}
companion object {
private var DEBUG = false
private const val DEBUG_TAG = "MviLifecycleListener"
/**
* Determines whether or not a Presenter Instance should be kept
*
* @param keepPresenterInstance true, if the delegate has enabled keep
*/
internal fun retainPresenterInstance(keepPresenterInstance: Boolean, controller: Controller): Boolean {
return keepPresenterInstance && (controller.activity!!.isChangingConfigurations
|| !controller.activity!!.isFinishing) && !controller.isBeingDestroyed
}
}
}
\ No newline at end of file
package com.biganto.visual.roompark.di.dagger
import android.app.Activity
import android.content.Context
import android.content.res.Resources
import com.biganto.visual.roompark.base.BaseRoomParkActivity
import com.biganto.visual.roompark.base.RoomParkMainActivity
import com.biganto.visual.roompark.view_utils.snackbar.ISnackBarProvider
import com.biganto.visual.roompark.view_utils.snackbar.SnackBarProvider
import dagger.Binds
import dagger.Module
import dagger.Provides
import dagger.android.ContributesAndroidInjector
/**
* Created by Vladislav Bogdashkin on 31.07.2019.
*/
@Module
abstract class ActivityModule {
@Binds
abstract fun providesContext(activity: Activity):Context
@Module
companion object{
@JvmStatic
@Provides
fun provideResources(activity: Activity) : Resources = activity.resources
@JvmStatic
@Provides
fun provideSnackBar(activity: Activity): ISnackBarProvider{
return SnackBarProvider(activity)
}
}
}
@Module
abstract class AppActivityModule {
@Module
internal interface MainActivityModule {
@Binds
fun bindMainActivity(activity: RoomParkMainActivity): Activity
}
@Module
internal interface BaseActivityModule {
@Binds
fun bindBaseActivity(activity: BaseRoomParkActivity): Activity
}
@ContributesAndroidInjector(
modules = [ActivityModule::class, MainActivityModule::class])
abstract fun contributeMainActivityInjector(): RoomParkMainActivity
@ContributesAndroidInjector(
modules = [ActivityModule::class, BaseActivityModule::class])
abstract fun contributeBaseActivityInjector(): BaseRoomParkActivity
}
package com.biganto.visual.roompark.di.dagger
import android.app.Application
import com.biganto.visual.roompark.base.RoomParkApplication
import dagger.BindsInstance
import dagger.Component
import dagger.android.AndroidInjectionModule
import dagger.android.AndroidInjector
import dagger.android.support.AndroidSupportInjectionModule
import javax.inject.Singleton
/**
* Created by Vladislav Bogdashkin on 13.06.2018.
*/
@Singleton
@Component(modules =
[ AppModule::class,
DataModule::class,
// RetrofitModule::class,
// AppVersionModule::class,
AndroidInjectionModule::class,
AndroidSupportInjectionModule::class,
// MappingProvider::class,
ActivityModule::class,
AppActivityModule ::class])
interface AppComponent : AndroidInjector<RoomParkApplication>{
@Component.Builder
interface Builder{
@BindsInstance
fun context(application: Application): Builder
// @BindsInstance
// fun retrofitModule(retrofit: RetrofitModule):Builder
// @BindsInstance
// @Named("retrofit")
// fun retrofit(
// retorfitModule: RetrofitModule):Builder
fun build(): AppComponent
}
// fun cache(): ICachedStore
// fun context(): Context
// fun db(): IDb
// fun api(): IApi
// fun roomApi(): IRoomParkApi
// fun fileModule(): FilesModule
//// fun appLifeCycle(): AppLifecycleListener
// fun networkMonitor(): INetworkMonitor
// fun versionMonitor(): IAppVersionControl
// fun versionNotifier(): IAppVersionNotifier
//
// fun estateRepo() : IEstateRepository
// fun tourRepo() : ITourRepository
// fun userRepo() : IUserRepository
}
\ No newline at end of file
package com.biganto.visual.roompark.di.dagger
import dagger.Module
import dagger.Provides
/**
* Created by Vladislav Bogdashkin on 13.06.2018.
*/
const val USER_CACHE_LIMIT_SIZE = 3
const val USER_CACHE_LIMIT_SECONDS_INACTIVE = 30L
const val TOURS_CACHE_LIMIT_SIZE = 500
const val TOURS_CACHE_LIMIT_SECONDS_INACTIVE = 200L
const val ESTATES_CACHE_LIMIT_SIZE = 100
const val ESTATES_CACHE_LIMIT_SECONDS_INACTIVE = 200L
const val FILES_CACHE_LIMIT_SIZE = 10000
const val FILES_CACHE_LIMIT_SECONDS_INACTIVE = 60L
const val DATABASE_VERSION = 6
@Module
class AppModule() {
}
@Module()
class DataModule() {
/*
@Provides
@Singleton
fun provieApi(@Named("bigantoApi") retorfit:Retrofit): IApi {
return RetrofitRepository(retorfit)
}
@Provides
@Singleton
fun provieRoomParkApi(@Named("roomParkApi") retorfit:Retrofit): IRoomParkApi {
return RoomParkRetrofitRepository(retorfit)
}
@Provides
@Singleton
fun provideDb(context:Application): IDb {
return RequeryRepository(getRequeryDataStore(context))
}
@Provides
@Singleton
fun provideFileModule(context:Application): FilesModule {
return FilesModule(context)
}
@Provides
@Singleton
fun providesNetworkListener(context:Application): INetworkMonitor {
return LiveNetworkMonitor(context)
}
@Provides
@Singleton
fun getRequeryDataStore(context:Application): KotlinReactiveEntityStore<Persistable> {
Timber.d("Kotlin store creating..")
val source = DatabaseSource(context, Models.DEFAULT, "BigantoPerfect", DATABASE_VERSION)
source.setLoggingEnabled(false)
// if ( BuildConfig.DEBUG) {
// // use this in development mode to drop and recreate the tables on every upgrade
// source.setTableCreationMode(TableCreationMode.DROP_CREATE)
// }
val store = KotlinEntityDataStore<Persistable>(source.configuration)
Timber.d("Kotlin store %s",source)
return KotlinReactiveEntityStore(store)
// // override onUpgrade to handle migrating to a new version
// val configuration = source.configuration
// return ReactiveSupport.toReactiveStore(
// EntityDataStore<Persistable>(configuration))
}
*/
}
//
//@Singleton // <-- YES
//class MyServiceImpl @Inject // <-- YES
//constructor(private val apiService: ApiService)// <-- YES
// : MyService
\ No newline at end of file
package com.biganto.visual.roompark.di.dagger
import javax.inject.Scope
/**
* Created by Vladislav Bogdashkin on 14.06.2018.
*/
/**
* Custom Scope for each Screen
*/
@Scope
@Retention(AnnotationRetention.RUNTIME)
annotation class PerScreen
\ No newline at end of file
package com.biganto.visual.roompark.di.koin
import com.biganto.visual.roompark.base.RoomParkApplication
import com.biganto.visual.roompark.base.RoomParkMainActivity
import org.koin.android.ext.koin.androidContext
import org.koin.android.ext.koin.androidLogger
import org.koin.core.context.startKoin
import org.koin.core.qualifier.named
import org.koin.dsl.module
/**
* Created by Vladislav Bogdashkin on 03.09.2019.
*/
fun RoomParkApplication.initDI(){
startKoin {
androidLogger()
androidContext(this@initDI)
modules(listOf(
appModule
,scopesModule
))
}
}
val appModule = module{
}
val scopesModule = module {
scope(named<RoomParkMainActivity>()){
scoped { StartUpData("ja pesik!") }
}
}
val presenterScope = module {
scope(named<RoomParkMainActivity>()){ //<- Presenter?
scoped { StartUpData("ja pesik!") }
}
}
data class StartUpData(val helloText:String)
package com.biganto.visual.roompark.domain.use_case
import com.biganto.visual.roompark.di.dagger.PerScreen
import com.biganto.visual.roompark.domain.contract.AuthContract
/**
* Created by Vladislav Bogdashkin on 24.09.2019.
*/
class AuthUseCase{
// val auth: AuthContract by currentScope.inject()
@PerScreen
class AuthUseCase(
val authContract: AuthContract
){
}
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/alert_holder"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorOpacityBackground"
android:clickable="true"
android:focusable="auto"
android:focusableInTouchMode="true"
android:orientation="vertical">
<androidx.cardview.widget.CardView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="64dp"
android:layout_marginTop="64dp"
android:layout_marginEnd="64dp"
android:layout_marginBottom="64dp"
app:cardCornerRadius="6dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias=".4">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/alert_message_text_view"
style="@style/Default_TextView.Error_Text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:padding="16dp" />
<LinearLayout
android:id="@+id/buttons_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="2">
<Button
android:id="@+id/alert_ok_button"
style="@style/DefaultButton.DismissButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="asdasdasd" />
<Button
android:id="@+id/alert_dismiss_button"
style="@style/DefaultButton.DismissButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:visibility="visible" />
</LinearLayout>
</LinearLayout>
</androidx.cardview.widget.CardView>
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="isTablet">true</bool>
<integer name="catalogSpans">3</integer>
<integer name="toursCeilSpans">4</integer>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="isTablet">true</bool>
<integer name="catalogSpans">2</integer>
<integer name="toursCeilSpans">2</integer>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="isTablet">true</bool>
<integer name="catalogSpans">6</integer>
<integer name="toursCeilSpans">5</integer>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="isTablet">true</bool>
<integer name="catalogSpans">3</integer>
<integer name="toursCeilSpans">4</integer>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="isTablet">false</bool>
<integer name="catalogSpans">1</integer>
<integer name="toursCeilSpans">2</integer>
</resources>
\ No newline at end of file
......@@ -100,6 +100,22 @@
</style>
<style name="DefaultButton" parent="Widget.MaterialComponents.Button.OutlinedButton">
<item name="strokeColor">@color/colorAccent</item>
<item name="strokeWidth">0dp</item>
<item name="cornerRadius">0dp</item>
<item name="rippleColor">@color/colorAccentSecondary</item>
<item name="boxBackgroundColor">@color/colorCommonBackground</item>
<item name="android:textSize">@dimen/common_text</item>
<item name="android:textColor">@color/colorAccent</item>
<item name="errorTextAppearance">@style/Auth.EditText</item>
<item name="hintTextColor">@color/colorNoticeText</item>
</style>
<style name="DefaultButton.DismissButton">
<item name="android:text">"СКРЫТЬ"</item>
</style>
<style name="AuthButton" parent="Widget.MaterialComponents.Button.OutlinedButton">
<item name="strokeColor">@color/colorAccent</item>
<item name="strokeWidth">4dp</item>
......@@ -246,6 +262,10 @@
<item name="android:textColor">@color/colorHeaderText</item>
</style>
<style name="Default_TextView.Error_Text">
<item name="android:textColor">@color/colorError</item>
</style>
<style name="Default_TextView.Inverted_Text">
<item name="android:textColor">@color/colorInvertedText</item>
</style>
......
......@@ -13,10 +13,14 @@ ext {
// requeryVersion = '1.5.1'
// rxBindingVersion = '2.1.1'
conductorVersion = '3.0.0-rc1'
materialVersion = '1.1.0-alpha09'
materialVersion = '1.1.0-alpha10'
gradleVersion = '3.5.0'
koinVersion = '2.0.1'
timberVersion = '4.7.1'
picassoVersion = '2.71828'
rxJavaVersion = '3.0.0-RC3'
mosbyMviConductorVersion = '3.1.0'
butterKnifeVersion = '10.2.0'
daggerVersion = '2.24'
rxRelayVersion = '2.1.1'
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment