Commit 0d5e108e authored by Konstantin Tskhovrebov's avatar Konstantin Tskhovrebov 🤖

Merge branch 'feature/single_activity' into develop

parents 94851cfc 776c2af0
Pipeline #29507968 passed with stage
in 8 minutes and 8 seconds
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="ru.terrakok.gitlabclient">
xmlns:tools="http://schemas.android.com/tools"
package="ru.terrakok.gitlabclient">
<uses-permission android:name="android.permission.INTERNET"/>
......@@ -10,22 +11,17 @@
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="false"
android:theme="@style/AppTheme">
android:theme="@style/AppTheme"
tools:ignore="GoogleAppIndexingWarning">
<activity
android:name=".ui.launch.MainActivity"
android:name=".ui.AppActivity"
android:theme="@style/AppTheme.Splash">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity android:name=".ui.auth.AuthActivity"/>
<activity android:name=".ui.user.UserActivity"/>
<activity android:name=".ui.project.ProjectActivity"/>
<activity android:name=".ui.mergerequest.MergeRequestActivity"/>
<activity android:name=".ui.issue.IssueActivity"/>
</application>
</manifest>
\ No newline at end of file
package ru.terrakok.gitlabclient
import android.content.Context
import android.content.Intent
import ru.terrakok.gitlabclient.ui.auth.AuthActivity
import ru.terrakok.gitlabclient.ui.issue.IssueActivity
import ru.terrakok.gitlabclient.ui.launch.MainActivity
import ru.terrakok.gitlabclient.ui.mergerequest.MergeRequestActivity
import ru.terrakok.gitlabclient.ui.project.ProjectActivity
import ru.terrakok.gitlabclient.ui.user.UserActivity
import android.net.Uri
import ru.terrakok.gitlabclient.toothpick.DI
import ru.terrakok.gitlabclient.ui.about.AboutFragment
import ru.terrakok.gitlabclient.ui.auth.AuthFlowFragment
import ru.terrakok.gitlabclient.ui.auth.AuthFragment
import ru.terrakok.gitlabclient.ui.drawer.DrawerFlowFragment
import ru.terrakok.gitlabclient.ui.global.BaseFragment
import ru.terrakok.gitlabclient.ui.global.StubFragment
import ru.terrakok.gitlabclient.ui.issue.IssueFlowFragment
import ru.terrakok.gitlabclient.ui.issue.IssueFragment
import ru.terrakok.gitlabclient.ui.issue.IssueInfoFragment
import ru.terrakok.gitlabclient.ui.issue.IssueNotesFragment
import ru.terrakok.gitlabclient.ui.libraries.LibrariesFragment
import ru.terrakok.gitlabclient.ui.main.MainFlowFragment
import ru.terrakok.gitlabclient.ui.mergerequest.MergeRequestFlowFragment
import ru.terrakok.gitlabclient.ui.mergerequest.MergeRequestFragment
import ru.terrakok.gitlabclient.ui.mergerequest.MergeRequestInfoFragment
import ru.terrakok.gitlabclient.ui.mergerequest.MergeRequestNotesFragment
import ru.terrakok.gitlabclient.ui.my.activity.MyEventsFragment
import ru.terrakok.gitlabclient.ui.my.issues.MyIssuesContainerFragment
import ru.terrakok.gitlabclient.ui.my.issues.MyIssuesFragment
import ru.terrakok.gitlabclient.ui.my.mergerequests.MyMergeRequestsContainerFragment
import ru.terrakok.gitlabclient.ui.my.mergerequests.MyMergeRequestsFragment
import ru.terrakok.gitlabclient.ui.my.todos.MyTodosContainerFragment
import ru.terrakok.gitlabclient.ui.my.todos.MyTodosFragment
import ru.terrakok.gitlabclient.ui.project.ProjectFlowFragment
import ru.terrakok.gitlabclient.ui.project.ProjectMainFlowFragment
import ru.terrakok.gitlabclient.ui.project.info.ProjectInfoFragment
import ru.terrakok.gitlabclient.ui.projects.ProjectsContainerFragment
import ru.terrakok.gitlabclient.ui.projects.ProjectsListFragment
import ru.terrakok.gitlabclient.ui.user.UserFlowFragment
import ru.terrakok.gitlabclient.ui.user.info.UserInfoFragment
/**
* @author Konstantin Tskhovrebov (aka terrakok) on 26.03.17.
*/
object Screens {
const val AUTH_FLOW = "auth flow"
const val AUTH_SCREEN = "auth screen"
const val DRAWER_FLOW = "drawer flow"
const val MAIN_FLOW = "main flow"
const val MAIN_SCREEN = "main screen"
const val MY_EVENTS_SCREEN = "my events screen"
const val MY_ISSUES_CONTAINER_SCREEN = "my issues container screen"
const val MY_ISSUES_SCREEN = "my issues screen"
const val MY_MR_CONTAINER_SCREEN = "my mr container screen"
const val MY_MR_SCREEN = "my mr screen"
const val MY_TODOS_CONTAINER_SCREEN = "my todo container screen"
const val MY_TODOS_SCREEN = "my todo screen"
const val PROJECTS_CONTAINER_SCREEN = "projects container screen"
const val PROJECTS_SCREEN = "projects screen"
const val ABOUT_SCREEN = "about screen"
const val APP_LIBRARIES_SCREEN = "app libraries screen"
const val APP_LIBRARIES_FLOW = "app libraries flow"
const val AUTH_FLOW = "auth flow"
const val AUTH_SCREEN = "auth screen"
const val PROJECT_FLOW = "project flow"
const val PROJECT_SCREEN = "project screen"
const val PROJECT_MAIN_FLOW = "project main flow"
const val PROJECT_INFO_SCREEN = "project info screen"
const val PROJECT_ISSUES_SCREEN = "project issues screen"
const val PROJECT_MR_SCREEN = "project mr screen"
const val USER_FLOW = "user flow"
const val USER_INFO_SCREEN = "user info screen"
const val MR_FLOW = "mr flow"
const val MR_SCREEN = "mr screen"
const val MR_INFO_SCREEN = "mr info screen"
const val MR_NOTES_SCREEN = "mr notes screen"
const val ISSUE_FLOW = "issue flow"
const val ISSUE_SCREEN = "issue screen"
const val ISSUE_INFO_SCREEN = "issue info screen"
const val ISSUE_NOTES_SCREEN = "issue notes screen"
fun getFlowIntent(context: Context, flowKey: String, data: Any?): Intent? = when (flowKey) {
Screens.AUTH_FLOW -> AuthActivity.getStartIntent(context)
Screens.MAIN_FLOW -> MainActivity.getStartIntent(context)
Screens.PROJECT_FLOW -> ProjectActivity.getStartIntent(data as Long, context)
Screens.USER_FLOW -> UserActivity.getStartIntent(data as Long, context)
Screens.MR_FLOW -> {
val (projectId, mrId) = data as Pair<Long, Long>
MergeRequestActivity.getStartIntent(projectId, mrId, context)
}
Screens.ISSUE_FLOW -> {
val (projectId, issueId) = data as Pair<Long, Long>
IssueActivity.getStartIntent(projectId, issueId, context)
}
const val EXTERNAL_BROWSER_FLOW = "external browser flow"
const val SHARE_FLOW = "share flow"
const val CALL_FLOW = "call flow"
fun createIntent(flowKey: String, data: Any?) = when (flowKey) {
Screens.EXTERNAL_BROWSER_FLOW -> Intent(Intent.ACTION_VIEW, Uri.parse(data as String))
Screens.SHARE_FLOW -> Intent.createChooser(
Intent(Intent.ACTION_SEND).apply {
putExtra(Intent.EXTRA_TEXT, data as String)
type = "text/plain"
},
data as String
)
Screens.CALL_FLOW -> Intent(Intent.ACTION_DIAL, Uri.parse("tel:$data"))
else -> null
}
fun createFragment(screenKey: String, data: Any? = null): BaseFragment? =
when (screenKey) {
Screens.DRAWER_FLOW -> DrawerFlowFragment()
Screens.MAIN_FLOW -> MainFlowFragment()
Screens.MY_EVENTS_SCREEN -> MyEventsFragment()
Screens.MY_ISSUES_CONTAINER_SCREEN -> MyIssuesContainerFragment()
Screens.MY_ISSUES_SCREEN -> {
val (createdByMe, onlyOpened) = data as Pair<Boolean, Boolean>
MyIssuesFragment.create(createdByMe, onlyOpened)
}
Screens.MY_MR_CONTAINER_SCREEN -> MyMergeRequestsContainerFragment()
Screens.MY_MR_SCREEN -> {
val (createdByMe, onlyOpened) = data as Pair<Boolean, Boolean>
MyMergeRequestsFragment.create(createdByMe, onlyOpened)
}
Screens.MY_TODOS_CONTAINER_SCREEN -> MyTodosContainerFragment()
Screens.MY_TODOS_SCREEN -> MyTodosFragment.create(data as Boolean)
Screens.PROJECTS_CONTAINER_SCREEN -> ProjectsContainerFragment()
Screens.PROJECTS_SCREEN -> ProjectsListFragment.create(data as Int)
Screens.ABOUT_SCREEN -> AboutFragment()
Screens.APP_LIBRARIES_FLOW -> LibrariesFragment()
Screens.AUTH_FLOW -> AuthFlowFragment()
Screens.AUTH_SCREEN -> AuthFragment()
Screens.USER_FLOW -> UserFlowFragment.create(data as Long)
Screens.USER_INFO_SCREEN -> UserInfoFragment()
Screens.PROJECT_FLOW -> ProjectFlowFragment.create(data as Long)
Screens.PROJECT_MAIN_FLOW -> ProjectMainFlowFragment()
Screens.PROJECT_INFO_SCREEN -> ProjectInfoFragment()
Screens.PROJECT_ISSUES_SCREEN -> StubFragment.create(DI.PROJECT_FLOW_SCOPE)
Screens.PROJECT_MR_SCREEN -> StubFragment.create(DI.PROJECT_FLOW_SCOPE)
Screens.MR_FLOW -> {
val (projectId, mrId) = data as Pair<Long, Long>
MergeRequestFlowFragment.create(projectId, mrId)
}
Screens.MR_SCREEN -> MergeRequestFragment()
Screens.MR_INFO_SCREEN -> MergeRequestInfoFragment()
Screens.MR_NOTES_SCREEN -> MergeRequestNotesFragment()
Screens.ISSUE_FLOW -> {
val (projectId, issueId) = data as Pair<Long, Long>
IssueFlowFragment.create(projectId, issueId)
}
Screens.ISSUE_SCREEN -> IssueFragment()
Screens.ISSUE_INFO_SCREEN -> IssueInfoFragment()
Screens.ISSUE_NOTES_SCREEN -> IssueNotesFragment()
else -> null
}
}
\ No newline at end of file
package ru.terrakok.gitlabclient.extension
import android.app.Activity
import android.os.Bundle
import android.support.v4.app.Fragment
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty
inline fun <reified T> extra(
key: String,
defaultValue: T? = null
): ReadWriteProperty<Activity, T> =
BundleExtractorDelegate { thisRef ->
extractFromBundle(
bundle = thisRef.intent?.extras,
key = key,
defaultValue = defaultValue
)
}
inline fun <reified T> argument(
key: String,
defaultValue: T? = null
): ReadWriteProperty<Fragment, T> =
BundleExtractorDelegate { thisRef ->
extractFromBundle(
bundle = thisRef.arguments,
key = key,
defaultValue = defaultValue
)
}
inline fun <reified T> extractFromBundle(
bundle: Bundle?,
key: String,
defaultValue: T? = null
): T {
val result = bundle?.get(key) ?: defaultValue
if (result != null && result !is T) {
throw ClassCastException("Property $key has different class type")
}
return result as T
}
class BundleExtractorDelegate<R, T>(private val initializer: (R) -> T) : ReadWriteProperty<R, T> {
private object EMPTY
private var value: Any? = EMPTY
override fun setValue(thisRef: R, property: KProperty<*>, value: T) {
this.value = value
}
override fun getValue(thisRef: R, property: KProperty<*>): T {
if (value == EMPTY) {
value = initializer(thisRef)
}
@Suppress("UNCHECKED_CAST")
return value as T
}
}
\ No newline at end of file
......@@ -2,8 +2,10 @@ package ru.terrakok.gitlabclient.extension
import android.content.Context
import android.content.Intent
import android.graphics.Color
import android.net.Uri
import android.support.annotation.LayoutRes
import android.support.design.widget.Snackbar
import android.support.v4.app.Fragment
import android.support.v4.content.ContextCompat
import android.view.LayoutInflater
......@@ -14,6 +16,9 @@ import android.widget.ImageView
import android.widget.TextView
import com.bumptech.glide.Glide
import com.bumptech.glide.request.RequestOptions
import ru.terrakok.cicerone.Navigator
import ru.terrakok.cicerone.commands.BackTo
import ru.terrakok.cicerone.commands.Replace
import ru.terrakok.gitlabclient.R
import ru.terrakok.gitlabclient.Screens
import ru.terrakok.gitlabclient.entity.app.target.AppTarget
......@@ -24,6 +29,15 @@ import timber.log.Timber
/**
* @author Konstantin Tskhovrebov (aka terrakok). Date: 03.03.17
*/
fun Navigator.setLaunchScreen(screenKey: String, data: Any? = null) {
applyCommands(
arrayOf(
BackTo(null),
Replace(screenKey, data)
)
)
}
fun Context.color(colorRes: Int) = ContextCompat.getColor(this, colorRes)
fun ImageView.tint(colorRes: Int) = this.setColorFilter(this.context.color(colorRes))
......@@ -136,4 +150,13 @@ fun TargetHeader.openInfo(router: FlowRouter) {
}
}
}
}
fun Fragment.showSnackMessage(message: String) {
view?.let {
val snackbar = Snackbar.make(it, message, Snackbar.LENGTH_LONG)
val messageTextView = snackbar.view.findViewById<TextView>(android.support.design.R.id.snackbar_text)
messageTextView.setTextColor(Color.WHITE)
snackbar.show()
}
}
\ No newline at end of file
package ru.terrakok.gitlabclient.model.system.flow
import ru.terrakok.cicerone.commands.Command
/**
* Created by Konstantin Tskhovrebov (aka @terrakok) on 10.01.18.
*/
class FinishFlow(
val transitionData: Any?
) : Command
\ No newline at end of file
package ru.terrakok.gitlabclient.model.system.flow
import android.app.Activity
import android.content.Intent
import android.support.v4.app.FragmentActivity
import android.widget.Toast
import ru.terrakok.cicerone.android.SupportFragmentNavigator
import ru.terrakok.cicerone.commands.BackTo
import ru.terrakok.cicerone.commands.Command
import ru.terrakok.cicerone.commands.Replace
/**
* Created by Konstantin Tskhovrebov (aka @terrakok) on 10.01.18.
*/
abstract class FlowNavigator(
val activity: FragmentActivity,
containerId: Int
) : SupportFragmentNavigator(activity.supportFragmentManager, containerId) {
fun setLaunchScreen(screenKey: String, data: Any? = null) {
applyCommands(
arrayOf(
BackTo(null),
Replace(screenKey, data)
)
)
}
override fun applyCommand(command: Command?) {
when (command) {
is StartFlow -> startFlow(command.screenKey, command.transitionData)
is FinishFlow -> finishFlow(command.transitionData)
else -> super.applyCommand(command)
}
}
protected open fun startFlow(flowKey: String, data: Any?) {
createFlowIntent(flowKey, data)?.let { intent ->
activity.startActivityForResult(intent, getRequestCodeForFlow(flowKey))
}
}
protected open fun finishFlow(data: Any?) {
activity.setResult(Activity.RESULT_OK, createFlowResult(data))
activity.finish()
}
open fun createFlowIntent(flowKey: String, data: Any?): Intent? = null
open fun getRequestCodeForFlow(flowKey: String): Int = -1
open fun createFlowResult(data: Any?): Intent? = null
override fun exit() {
activity.setResult(Activity.RESULT_CANCELED)
activity.finish()
}
override fun showSystemMessage(message: String?) {
Toast.makeText(activity, message, Toast.LENGTH_SHORT).show()
}
}
\ No newline at end of file
......@@ -5,17 +5,17 @@ import ru.terrakok.cicerone.Router
/**
* Created by Konstantin Tskhovrebov (aka @terrakok) on 19.12.17.
*/
class FlowRouter : Router() {
class FlowRouter(private val appRouter: Router) : Router() {
fun startFlow(flowKey: String, data: Any? = null) {
executeCommands(StartFlow(flowKey, data))
fun startFlow(screenKey: String, data: Any? = null) {
appRouter.navigateTo(screenKey, data)
}
fun finishFlow(data: Any? = null) {
executeCommands(FinishFlow(data))
fun newRootFlow(screenKey: String, data: Any? = null) {
appRouter.newRootScreen(screenKey, data)
}
fun cancelFlow() {
finishChain()
fun finishFlow() {
appRouter.exit()
}
}
\ No newline at end of file
package ru.terrakok.gitlabclient.model.system.flow
import ru.terrakok.cicerone.commands.Command
/**
* Created by Konstantin Tskhovrebov (aka @terrakok) on 10.01.18.
*/
class StartFlow(
val screenKey: String,
val transitionData: Any?
) : Command
\ No newline at end of file
package ru.terrakok.gitlabclient.model.system.message
/**
* Created by Konstantin Tskhovrebov (aka @terrakok) on 03.09.18.
*/
data class SystemMessage(
val text: String,
val type: SystemMessageType = SystemMessageType.ALERT
)
\ No newline at end of file
package ru.terrakok.gitlabclient.model.system.message
import com.jakewharton.rxrelay2.PublishRelay
import io.reactivex.Observable
/**
* Created by Konstantin Tskhovrebov (aka @terrakok) on 03.09.18.
*/
class SystemMessageNotifier {
private val notifierRelay = PublishRelay.create<SystemMessage>()
val notifier: Observable<SystemMessage> = notifierRelay.hide()
fun send(message: SystemMessage) = notifierRelay.accept(message)
fun send(message: String) = notifierRelay.accept(SystemMessage(message))
}
\ No newline at end of file
package ru.terrakok.gitlabclient.model.system.message
/**
* Created by Konstantin Tskhovrebov (aka @terrakok) on 03.09.18.
*/
enum class SystemMessageType {
ALERT,
TOAST
}
\ No newline at end of file
package ru.terrakok.gitlabclient.presentation.launch
package ru.terrakok.gitlabclient.presentation
import com.arellomobile.mvp.InjectViewState
import com.arellomobile.mvp.MvpPresenter
import com.arellomobile.mvp.MvpView
import ru.terrakok.cicerone.Router
import ru.terrakok.gitlabclient.Screens
import ru.terrakok.gitlabclient.model.interactor.auth.AuthInteractor
import ru.terrakok.gitlabclient.model.system.flow.FlowRouter
import ru.terrakok.gitlabclient.presentation.global.BasePresenter
import javax.inject.Inject
/**
* @author Konstantin Tskhovrebov (aka terrakok) on 26.03.17.
* Created by Konstantin Tskhovrebov (aka @terrakok) on 03.09.18.
*/
@InjectViewState
class LaunchPresenter @Inject constructor(
private val router: FlowRouter,
class AppPresenter @Inject constructor(
private val router: Router,
private val authInteractor: AuthInteractor
) : BasePresenter<LaunchView>() {
) : MvpPresenter<MvpView>() {
override fun onFirstViewAttach() {
super.onFirstViewAttach()
if (authInteractor.isSignedIn()) viewState.initMainScreen()
else router.startFlow(Screens.AUTH_FLOW)
if (authInteractor.isSignedIn()) router.newRootScreen(Screens.DRAWER_FLOW)
else router.newRootScreen(Screens.AUTH_FLOW)
}
fun onBackPressed() = router.finishChain()
}
\ No newline at end of file
......@@ -38,7 +38,7 @@ class AboutPresenter @Inject constructor(
.connect()
}
fun onShowLibrariesClicked() = router.navigateTo(Screens.APP_LIBRARIES_SCREEN)
fun onShowLibrariesClicked() = router.startFlow(Screens.APP_LIBRARIES_FLOW)
fun onDeveloperClicked(id: Long) = router.startFlow(Screens.USER_FLOW, id)
......
package ru.terrakok.gitlabclient.presentation.auth
import com.arellomobile.mvp.MvpView
import ru.terrakok.cicerone.Router
import ru.terrakok.gitlabclient.presentation.global.BasePresenter
import ru.terrakok.gitlabclient.toothpick.DI
import toothpick.Toothpick
import javax.inject.Inject
/**
* Created by Konstantin Tskhovrebov (aka @terrakok) on 03.09.18.
*/
class AuthFlowPresenter @Inject constructor(
private val router: Router
) : BasePresenter<MvpView>() {
override fun onDestroy() {
Toothpick.closeScope(DI.AUTH_FLOW_SCOPE)
super.onDestroy()
}
fun onExit() {
router.exit()
}
}
\ No newline at end of file
......@@ -33,7 +33,7 @@ class AuthPresenter @Inject constructor(
.doOnSubscribe { viewState.showProgress(true) }
.doAfterTerminate { viewState.showProgress(false) }
.subscribe(
{ router.startFlow(Screens.MAIN_FLOW) },
{ router.newRootFlow(Screens.DRAWER_FLOW) },
{ errorHandler.proceed(it, { viewState.showMessage(it) }) }
).connect()
}
......@@ -55,7 +55,7 @@ class AuthPresenter @Inject constructor(
fun loginOnCustomServer(url: String, token: String) {
authInteractor.login(url, token)
.subscribe(
{ router.startFlow(Screens.MAIN_FLOW) },
{ router.newRootFlow(Screens.DRAWER_FLOW) },
{ errorHandler.proceed(it, { viewState.showMessage(it) }) }
).connect()
}
......
......@@ -47,8 +47,8 @@ class NavigationDrawerPresenter @Inject constructor(
menuController.close()
if (item != currentSelectedItem) {
when (item) {
ACTIVITY -> router.newRootScreen(Screens.MAIN_SCREEN)
PROJECTS -> router.newRootScreen(Screens.PROJECTS_SCREEN)
ACTIVITY -> router.newRootScreen(Screens.MAIN_FLOW)
PROJECTS -> router.newRootScreen(Screens.PROJECTS_CONTAINER_SCREEN)
ABOUT -> router.newRootScreen(Screens.ABOUT_SCREEN)
}
}
......@@ -57,8 +57,11 @@ class NavigationDrawerPresenter @Inject constructor(
fun onLogoutClick() {
menuController.close()
authInteractor.logout()
router.startFlow(Screens.AUTH_FLOW)
router.newRootFlow(Screens.AUTH_FLOW)
}
fun onUserClick(id: Long) = router.startFlow(Screens.USER_FLOW, id)
fun onUserClick(id: Long) {
menuController.close()
router.startFlow(Screens.USER_FLOW, id)
}
}
\ No newline at end of file
package ru.terrakok.gitlabclient.presentation.global
import com.jakewharton.rxrelay2.PublishRelay
import ru.terrakok.cicerone.Router
import ru.terrakok.gitlabclient.Screens
import ru.terrakok.gitlabclient.extension.userMessage
import ru.terrakok.gitlabclient.model.data.server.ServerError
import ru.terrakok.gitlabclient.model.interactor.auth.AuthInteractor
import ru.terrakok.gitlabclient.model.system.ResourceManager
import ru.terrakok.gitlabclient.model.system.SchedulersProvider
import ru.terrakok.gitlabclient.model.system.flow.FlowRouter
import timber.log.Timber
import java.util.concurrent.TimeUnit
import javax.inject.Inject
......@@ -16,7 +16,7 @@ import javax.inject.Inject
* Created by Konstantin Tskhovrebov (aka @terrakok) on 03.11.17.
*/
class ErrorHandler @Inject constructor(
private val router: FlowRouter,
private val router: Router,
private val authInteractor: AuthInteractor,
private val resourceManager: ResourceManager,
private val schedulers: SchedulersProvider
......@@ -49,6 +49,6 @@ class ErrorHandler @Inject constructor(
private fun logout() {
authInteractor.logout()
router.startFlow(Screens.AUTH_FLOW)
router.newRootScreen(Screens.AUTH_FLOW)
}
}
package ru.terrakok.gitlabclient.presentation.issue
import com.arellomobile.mvp.MvpView
import ru.terrakok.cicerone.Router
import ru.terrakok.gitlabclient.presentation.global.BasePresenter
import ru.terrakok.gitlabclient.toothpick.DI
import toothpick.Toothpick
import javax.inject.Inject
/**
* Created by Konstantin Tskhovrebov (aka @terrakok) on 03.09.18.
*/
class IssueFlowPresenter @Inject constructor(
private val router: Router
) : BasePresenter<MvpView>() {
override fun onDestroy() {
Toothpick.closeScope(DI.ISSUE_FLOW_SCOPE)