Commit 7cf3ab1d authored by Konstantin Tskhovrebov's avatar Konstantin Tskhovrebov 🤖

added empty mr and issue info fragments

parent fa39ce4b
......@@ -281,7 +281,7 @@ fun TargetHeader.openInfo(router: FlowRouter) {
AppTarget.ISSUE -> {
internal?.let { targetInternal ->
router.startFlow(
Screens.MR_FLOW,
Screens.ISSUE_FLOW,
Pair(targetInternal.projectId, targetInternal.targetIid)
)
}
......
package ru.terrakok.gitlabclient.model.interactor.issue
import io.reactivex.Single
import ru.terrakok.gitlabclient.entity.OrderBy
import ru.terrakok.gitlabclient.entity.issue.Issue
import ru.terrakok.gitlabclient.entity.issue.IssueScope
import ru.terrakok.gitlabclient.entity.issue.IssueState
import ru.terrakok.gitlabclient.model.repository.issue.IssueRepository
......@@ -23,4 +25,9 @@ class IssueInteractor @Inject constructor(
orderBy = OrderBy.UPDATED_AT,
page = page
)
fun getIssue(
projectId: Long,
mergeRequestId: Long
) = Single.never<Issue>()
}
\ No newline at end of file
......@@ -3,17 +3,17 @@ package ru.terrakok.gitlabclient.model.interactor.project
import ru.terrakok.gitlabclient.entity.OrderBy
import ru.terrakok.gitlabclient.model.repository.project.ProjectRepository
import ru.terrakok.gitlabclient.model.repository.tools.Base64Tools
import ru.terrakok.gitlabclient.model.repository.tools.MarkDownConverter
import ru.terrakok.gitlabclient.model.system.SchedulersProvider
import javax.inject.Inject
/**
* @author Konstantin Tskhovrebov (aka terrakok) on 26.04.17.
*/
class ProjectInteractor @Inject constructor(private val projectRepository: ProjectRepository,
private val mdConverter: MarkDownConverter,
private val schedulers: SchedulersProvider,
private val base64Tools: Base64Tools) {
class ProjectInteractor @Inject constructor(
private val projectRepository: ProjectRepository,
private val schedulers: SchedulersProvider,
private val base64Tools: Base64Tools
) {
fun getMainProjects(page: Int) = projectRepository
.getProjectsList(
......@@ -41,13 +41,9 @@ class ProjectInteractor @Inject constructor(private val projectRepository: Proje
fun getProject(id: Long) = projectRepository.getProject(id)
fun getProjectReadmeHtml(id: Long, branchName: String) =
fun getProjectReadme(id: Long, branchName: String) =
projectRepository.getFile(id, "README.md", branchName)
.observeOn(schedulers.computation())
.map { file ->
val md = base64Tools.decode(file.content)
val html = mdConverter.markdownToHtml(md)
html
}
.map { file -> base64Tools.decode(file.content) }
.observeOn(schedulers.ui())
}
\ No newline at end of file
......@@ -89,7 +89,7 @@ class EventRepository @Inject constructor(
event.createdAt,
targetData.target,
targetData.id,
if (event.targetIid != null) TargetInternal(event.projectId, event.targetIid) else null,
getTargetInternal(event),
badges
)
}
......@@ -143,6 +143,25 @@ class EventRepository @Inject constructor(
}
}
private fun getTargetInternal(event: Event): TargetInternal? =
when (event.targetType) {
EventTargetType.DIFF_NOTE,
EventTargetType.NOTE -> {
if (event.note?.noteableIid != null) {
TargetInternal(event.projectId, event.note.noteableIid)
} else {
null
}
}
else -> {
if (event.targetIid != null) {
TargetInternal(event.projectId, event.targetIid)
} else {
null
}
}
}
private fun getBody(event: Event) = when (event.targetType) {
EventTargetType.NOTE,
EventTargetType.DIFF_NOTE -> event.note?.body
......
package ru.terrakok.gitlabclient.model.repository.tools
import org.commonmark.parser.Parser
import org.commonmark.renderer.html.HtmlRenderer
/**
* @author Konstantin Tskhovrebov (aka terrakok). Date: 28.05.17
*/
class MarkDownConverter {
companion object {
private val parser = Parser.builder().build()
private val renderer = HtmlRenderer.builder().build()
}
fun markdownToHtml(raw: String) = renderer.render(parser.parse(raw))
}
\ No newline at end of file
package ru.terrakok.gitlabclient.model.interactor.utils
package ru.terrakok.gitlabclient.presentation.global
import io.reactivex.Single
import ru.terrakok.gitlabclient.model.repository.tools.MarkDownConverter
import org.commonmark.parser.Parser
import org.commonmark.renderer.html.HtmlRenderer
import ru.terrakok.gitlabclient.model.system.SchedulersProvider
import javax.inject.Inject
/**
* Created by Konstantin Tskhovrebov (aka @terrakok) on 05.01.18.
* @author Konstantin Tskhovrebov (aka terrakok). Date: 28.05.17
*/
class UtilsInteractor @Inject constructor(
private val mdConverter: MarkDownConverter,
class MarkDownConverter @Inject constructor(
private val schedulers: SchedulersProvider
) {
private val parser: Parser = Parser.builder().build()
private val renderer: HtmlRenderer = HtmlRenderer.builder().build()
fun md2html(md: String) = Single
.fromCallable { mdConverter.markdownToHtml(md) }
fun markdownToHtml(raw: String) = Single
.fromCallable {
renderer.render(parser.parse(raw))
}
.subscribeOn(schedulers.computation())
.observeOn(schedulers.ui())
}
\ No newline at end of file
package ru.terrakok.gitlabclient.presentation.issue
import com.arellomobile.mvp.InjectViewState
import io.reactivex.Single
import io.reactivex.functions.BiFunction
import ru.terrakok.cicerone.Router
import ru.terrakok.gitlabclient.entity.Project
import ru.terrakok.gitlabclient.entity.issue.Issue
import ru.terrakok.gitlabclient.model.interactor.issue.IssueInteractor
import ru.terrakok.gitlabclient.model.interactor.project.ProjectInteractor
import ru.terrakok.gitlabclient.presentation.global.BasePresenter
import ru.terrakok.gitlabclient.presentation.global.ErrorHandler
import ru.terrakok.gitlabclient.presentation.global.MarkDownConverter
import ru.terrakok.gitlabclient.toothpick.PrimitiveWrapper
import ru.terrakok.gitlabclient.toothpick.qualifier.IssueId
import ru.terrakok.gitlabclient.toothpick.qualifier.ProjectId
import javax.inject.Inject
private typealias IssueLinker = BiFunction<Pair<Issue, String>, Project, IssueInfoView.IssueInfo>
/**
* Created by Konstantin Tskhovrebov (aka @terrakok) on 05.01.18.
*/
@InjectViewState
class IssueInfoPresenter @Inject constructor(
@ProjectId private val projectIdWrapper: PrimitiveWrapper<Long>,
@IssueId private val issueIdWrapper: PrimitiveWrapper<Long>,
private val router: Router,
private val issueInteractor: IssueInteractor,
private val projectInteractor: ProjectInteractor,
private val mdConverter: MarkDownConverter,
private val errorHandler: ErrorHandler
) : BasePresenter<IssueInfoView>() {
private val projectId = projectIdWrapper.value
private val issueId = issueIdWrapper.value
override fun onFirstViewAttach() {
super.onFirstViewAttach()
Single
.zip(
issueInteractor
.getIssue(projectId, issueId)
.flatMap { issue ->
mdConverter
.markdownToHtml(issue.description ?: "")
.map { Pair(issue, it) }
},
projectInteractor.getProject(projectId),
IssueLinker { (issue, html), project -> IssueInfoView.IssueInfo(issue, project, html) }
)
.doOnSubscribe { viewState.showProgress(true) }
.doAfterTerminate { viewState.showProgress(false) }
.subscribe(
{ viewState.showIssue(it) },
{ errorHandler.proceed(it, { viewState.showMessage(it) }) }
)
.connect()
}
fun onBackPressed() = router.exit()
}
\ No newline at end of file
package ru.terrakok.gitlabclient.presentation.issue
import com.arellomobile.mvp.MvpView
import com.arellomobile.mvp.viewstate.strategy.AddToEndSingleStrategy
import com.arellomobile.mvp.viewstate.strategy.OneExecutionStateStrategy
import com.arellomobile.mvp.viewstate.strategy.StateStrategyType
import ru.terrakok.gitlabclient.entity.Project
import ru.terrakok.gitlabclient.entity.issue.Issue
/**
* @author Konstantin Tskhovrebov (aka terrakok) on 27.04.17.
*/
@StateStrategyType(AddToEndSingleStrategy::class)
interface IssueInfoView : MvpView {
data class IssueInfo(val issue: Issue, val project: Project, val htmlDescription: String)
fun showIssue(issueInfo: IssueInfo)
fun showProgress(show: Boolean)
@StateStrategyType(OneExecutionStateStrategy::class)
fun showMessage(message: String)
}
\ No newline at end of file
package ru.terrakok.gitlabclient.presentation.mergerequest
import com.arellomobile.mvp.InjectViewState
import io.reactivex.Single
import io.reactivex.functions.BiFunction
import ru.terrakok.cicerone.Router
import ru.terrakok.gitlabclient.entity.Project
import ru.terrakok.gitlabclient.entity.mergerequest.MergeRequest
import ru.terrakok.gitlabclient.model.interactor.mergerequest.MergeRequestInteractor
import ru.terrakok.gitlabclient.model.interactor.utils.UtilsInteractor
import ru.terrakok.gitlabclient.model.interactor.project.ProjectInteractor
import ru.terrakok.gitlabclient.presentation.global.BasePresenter
import ru.terrakok.gitlabclient.presentation.global.ErrorHandler
import ru.terrakok.gitlabclient.presentation.global.MarkDownConverter
import ru.terrakok.gitlabclient.toothpick.PrimitiveWrapper
import ru.terrakok.gitlabclient.toothpick.qualifier.MergeRequestId
import ru.terrakok.gitlabclient.toothpick.qualifier.ProjectId
import javax.inject.Inject
private typealias MergeRequestLinker = BiFunction<Pair<MergeRequest, String>, Project, MergeRequestInfoView.MergeRequestInfo>
/**
* Created by Konstantin Tskhovrebov (aka @terrakok) on 05.01.18.
*/
@InjectViewState
class MergeRequestInfoPresenter @Inject constructor(
@ProjectId private val projectIdWrapper: PrimitiveWrapper<Long>,
@MergeRequestId private val mrIdWrapper: PrimitiveWrapper<Long>,
private val router: Router,
private val interactor: MergeRequestInteractor,
private val utils: UtilsInteractor,
private val mrInteractor: MergeRequestInteractor,
private val projectInteractor: ProjectInteractor,
private val mdConverter: MarkDownConverter,
private val errorHandler: ErrorHandler
) : BasePresenter<MergeRequestInfoView>() {
......@@ -28,16 +38,22 @@ class MergeRequestInfoPresenter @Inject constructor(
override fun onFirstViewAttach() {
super.onFirstViewAttach()
interactor.getMergeRequest(projectId, mrId)
.flatMap { mr ->
utils
.md2html(mr.description ?: "")
.map { Pair(mr, it) }
}
Single
.zip(
mrInteractor
.getMergeRequest(projectId, mrId)
.flatMap { mr ->
mdConverter
.markdownToHtml(mr.description ?: "")
.map { Pair(mr, it) }
},
projectInteractor.getProject(projectId),
MergeRequestLinker { (mr, html), project -> MergeRequestInfoView.MergeRequestInfo(mr, project, html) }
)
.doOnSubscribe { viewState.showProgress(true) }
.doAfterTerminate { viewState.showProgress(false) }
.subscribe(
{ (mr, description) -> viewState.showMergeRequest(mr, description) },
{ viewState.showMergeRequest(it) },
{ errorHandler.proceed(it, { viewState.showMessage(it) }) }
)
.connect()
......
......@@ -4,6 +4,7 @@ import com.arellomobile.mvp.MvpView
import com.arellomobile.mvp.viewstate.strategy.AddToEndSingleStrategy
import com.arellomobile.mvp.viewstate.strategy.OneExecutionStateStrategy
import com.arellomobile.mvp.viewstate.strategy.StateStrategyType
import ru.terrakok.gitlabclient.entity.Project
import ru.terrakok.gitlabclient.entity.mergerequest.MergeRequest
/**
......@@ -11,7 +12,9 @@ import ru.terrakok.gitlabclient.entity.mergerequest.MergeRequest
*/
@StateStrategyType(AddToEndSingleStrategy::class)
interface MergeRequestInfoView : MvpView {
fun showMergeRequest(mr: MergeRequest, htmlDescription: String)
data class MergeRequestInfo(val mr: MergeRequest, val project: Project, val htmlDescription: String)
fun showMergeRequest(mrInfo: MergeRequestInfo)
fun showProgress(show: Boolean)
@StateStrategyType(OneExecutionStateStrategy::class)
......
......@@ -5,6 +5,7 @@ import ru.terrakok.cicerone.Router
import ru.terrakok.gitlabclient.model.interactor.project.ProjectInteractor
import ru.terrakok.gitlabclient.presentation.global.BasePresenter
import ru.terrakok.gitlabclient.presentation.global.ErrorHandler
import ru.terrakok.gitlabclient.presentation.global.MarkDownConverter
import ru.terrakok.gitlabclient.toothpick.PrimitiveWrapper
import ru.terrakok.gitlabclient.toothpick.qualifier.ProjectId
import javax.inject.Inject
......@@ -17,6 +18,7 @@ class ProjectInfoPresenter @Inject constructor(
@ProjectId private val projectIdWrapper: PrimitiveWrapper<Long>,
private val router: Router,
private val projectInteractor: ProjectInteractor,
private val mdConverter: MarkDownConverter,
private val errorHandler: ErrorHandler
) : BasePresenter<ProjectInfoView>() {
......@@ -28,7 +30,9 @@ class ProjectInfoPresenter @Inject constructor(
projectInteractor.getProject(projectId)
.doOnSuccess { project -> viewState.showProjectInfo(project) }
.flatMap { project ->
projectInteractor.getProjectReadmeHtml(project.id, project.defaultBranch)
projectInteractor
.getProjectReadme(project.id, project.defaultBranch)
.flatMap { mdConverter.markdownToHtml(it) }
}
.doOnSubscribe { viewState.showProgress(true) }
.doAfterTerminate { viewState.showProgress(false) }
......
......@@ -13,11 +13,11 @@ import ru.terrakok.gitlabclient.model.data.storage.RawAppData
import ru.terrakok.gitlabclient.model.interactor.app.AppInfoInteractor
import ru.terrakok.gitlabclient.model.repository.app.AppInfoRepository
import ru.terrakok.gitlabclient.model.repository.tools.Base64Tools
import ru.terrakok.gitlabclient.model.repository.tools.MarkDownConverter
import ru.terrakok.gitlabclient.model.system.AppSchedulers
import ru.terrakok.gitlabclient.model.system.ResourceManager
import ru.terrakok.gitlabclient.model.system.SchedulersProvider
import ru.terrakok.gitlabclient.model.system.flow.FlowRouter
import ru.terrakok.gitlabclient.presentation.global.MarkDownConverter
import ru.terrakok.gitlabclient.toothpick.PrimitiveWrapper
import ru.terrakok.gitlabclient.toothpick.qualifier.DefaultPageSize
import ru.terrakok.gitlabclient.toothpick.qualifier.DefaultServerPath
......@@ -34,7 +34,7 @@ class AppModule(context: Context) : Module() {
bind(PrimitiveWrapper::class.java).withName(DefaultPageSize::class.java).toInstance(PrimitiveWrapper(20))
bind(SchedulersProvider::class.java).toInstance(AppSchedulers())
bind(ResourceManager::class.java).singletonInScope()
bind(MarkDownConverter::class.java).toInstance(MarkDownConverter())
bind(MarkDownConverter::class.java).singletonInScope()
bind(Base64Tools::class.java).toInstance(Base64Tools())
bind(AssetManager::class.java).toInstance(context.assets)
bind(RawAppData::class.java)
......
package ru.terrakok.gitlabclient.toothpick.qualifier
import javax.inject.Qualifier
/**
* @author Konstantin Tskhovrebov (aka terrakok) on 09.07.17.
*/
@Qualifier
annotation class DefaultPageSize
\ No newline at end of file
package ru.terrakok.gitlabclient.toothpick.qualifier
import javax.inject.Qualifier
/**
* @author Konstantin Tskhovrebov (aka terrakok) on 14.09.17.
*/
@Qualifier
annotation class DefaultServerPath
\ No newline at end of file
package ru.terrakok.gitlabclient.toothpick.qualifier
import javax.inject.Qualifier
/**
* @author Konstantin Tskhovrebov (aka terrakok) on 09.07.17.
*/
@Qualifier
annotation class IssueId
\ No newline at end of file
package ru.terrakok.gitlabclient.toothpick.qualifier
import javax.inject.Qualifier
/**
* @author Konstantin Tskhovrebov (aka terrakok) on 09.07.17.
*/
@Qualifier
annotation class MergeRequestId
\ No newline at end of file
package ru.terrakok.gitlabclient.toothpick.qualifier
import javax.inject.Qualifier
/**
* @author Konstantin Tskhovrebov (aka terrakok) on 09.07.17.
*/
@Qualifier
annotation class ProjectId
\ No newline at end of file
package ru.terrakok.gitlabclient.toothpick.qualifier
import javax.inject.Qualifier
/**
* @author Konstantin Tskhovrebov (aka terrakok) on 09.07.17.
*/
@Qualifier
annotation class ProjectListMode
\ No newline at end of file
package ru.terrakok.gitlabclient.toothpick.qualifier
import javax.inject.Qualifier
/**
* @author Konstantin Tskhovrebov (aka terrakok) on 14.09.17.
*/
@Qualifier
annotation class ServerPath
\ No newline at end of file
package ru.terrakok.gitlabclient.toothpick.qualifier
import javax.inject.Qualifier
/**
* @author Eugene Shapovalov (CraggyHaggy). Date: 29.09.17
*/
@Qualifier
annotation class TodoListPendingState
\ No newline at end of file
package ru.terrakok.gitlabclient.toothpick.qualifier
import javax.inject.Qualifier
/**
* @author Konstantin Tskhovrebov (aka terrakok) on 09.07.17.
*/
@Qualifier
annotation class UserId
\ No newline at end of file
package ru.terrakok.gitlabclient.toothpick.qualifier
import javax.inject.Qualifier
/**
* Created by Konstantin Tskhovrebov (aka @terrakok) on 03.02.18.
*/
@Qualifier annotation class DefaultPageSize
@Qualifier annotation class DefaultServerPath
@Qualifier annotation class ServerPath
@Qualifier annotation class IssueId
@Qualifier annotation class MergeRequestId
@Qualifier annotation class ProjectId
@Qualifier annotation class ProjectListMode
@Qualifier annotation class TodoListPendingState
@Qualifier annotation class UserId
\ No newline at end of file
......@@ -67,6 +67,7 @@ class TargetHeaderAdapterDelegate(
val res = view.resources
view.titleTextView.text = item.title.getHumanName(res)
Markwon.setMarkdown(view.descriptionTextView, mdConfig, item.body ?: "")
view.descriptionTextView.movementMethod = null //disable internal link click
view.avatarImageView.loadRoundedImage(item.author.avatarUrl)
view.iconImageView.setImageResource(item.icon.getIcon())
view.dateTextView.text = item.date.humanTime(res)
......
......@@ -5,6 +5,7 @@ import android.content.Intent
import android.os.Bundle
import ru.terrakok.cicerone.NavigatorHolder
import ru.terrakok.gitlabclient.R
import ru.terrakok.gitlabclient.Screens
import ru.terrakok.gitlabclient.model.system.flow.FlowNavigator
import ru.terrakok.gitlabclient.toothpick.DI
import ru.terrakok.gitlabclient.toothpick.PrimitiveWrapper
......@@ -43,7 +44,7 @@ class IssueActivity : BaseActivity() {
}
if (savedInstanceState == null) {
//navigator.setLaunchScreen(Screens.ISSUE_INFO_SCREEN, null)
navigator.setLaunchScreen(Screens.ISSUE_INFO_SCREEN, null)
}
}
......@@ -65,7 +66,10 @@ class IssueActivity : BaseActivity() {
private val navigator = object : FlowNavigator(this, R.id.container) {
override fun createFragment(screenKey: String?, data: Any?) = null
override fun createFragment(screenKey: String?, data: Any?) = when(screenKey) {
Screens.ISSUE_INFO_SCREEN -> IssueInfoFragment()
else -> null
}
}
companion object {
......
package ru.terrakok.gitlabclient.ui.issue
import android.os.Bundle
import com.arellomobile.mvp.presenter.InjectPresenter
import com.arellomobile.mvp.presenter.ProvidePresenter
import kotlinx.android.synthetic.main.fragment_issue_info.*
import ru.terrakok.gitlabclient.R
import ru.terrakok.gitlabclient.presentation.issue.IssueInfoPresenter
import ru.terrakok.gitlabclient.presentation.issue.IssueInfoView
import ru.terrakok.gitlabclient.toothpick.DI
import ru.terrakok.gitlabclient.ui.global.BaseFragment
import toothpick.Toothpick
/**
* Created by Konstantin Tskhovrebov (aka @terrakok) on 03.02.18.
*/
class IssueInfoFragment : BaseFragment(), IssueInfoView {
override val layoutRes = R.layout.fragment_issue_info
@InjectPresenter lateinit var presenter: IssueInfoPresenter
@ProvidePresenter
fun providePresenter() =
Toothpick.openScope(DI.ISSUE_SCOPE)
.getInstance(IssueInfoPresenter::class.java)
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
toolbar.setNavigationOnClickListener { presenter.onBackPressed() }
}
override fun showIssue(issueInfo: IssueInfoView.IssueInfo) {
toolbar.title = issueInfo.issue.id.toString()
}
override fun showProgress(show: Boolean) {
showProgressDialog(show)
}
override fun showMessage(message: String) {
showSnackMessage(message)
}
override fun onBackPressed() {
presenter.onBackPressed()
}
}
\ No newline at end of file
......@@ -5,6 +5,7 @@ import android.content.Intent
import android.os.Bundle
import ru.terrakok.cicerone.NavigatorHolder
import ru.terrakok.gitlabclient.R
import ru.terrakok.gitlabclient.Screens
import ru.terrakok.gitlabclient.model.system.flow.FlowNavigator
import ru.terrakok.gitlabclient.toothpick.DI
import ru.terrakok.gitlabclient.toothpick.PrimitiveWrapper
......@@ -43,7 +44,7 @@ class MergeRequestActivity : BaseActivity() {
}
if (savedInstanceState == null) {
//navigator.setLaunchScreen(Screens.MR_INFO_SCREEN, null)
navigator.setLaunchScreen(Screens.MR_INFO_SCREEN, null)
}
}
......@@ -65,7 +66,10 @@ class MergeRequestActivity : BaseActivity() {
private val navigator = object : FlowNavigator(this, R.id.container) {
override fun createFragment(screenKey: String?, data: Any?) = null
override fun createFragment(screenKey: String?, data: Any?) = when(screenKey) {
Screens.MR_INFO_SCREEN -> MergeRequestInfoFragment()
else -> null
}
}
companion object {
......
package ru.terrakok.gitlabclient.ui.mergerequest
import android.os.Bundle
import com.arellomobile.mvp.presenter.InjectPresenter
import com.arellomobile.mvp.presenter.ProvidePresenter
import kotlinx.android.synthetic.main.fragment_mr_info.*
import ru.terrakok.gitlabclient.R
import ru.terrakok.gitlabclient.presentation.mergerequest.MergeRequestInfoPresenter
import ru.terrakok.gitlabclient.presentation.mergerequest.MergeRequestInfoView
import ru.terrakok.gitlabclient.toothpick.DI
import ru.terrakok.gitlabclient.ui.global.BaseFragment
import toothpick.Toothpick
/**
* Created by Konstantin Tskhovrebov (aka @terrakok) on 03.02.18.
*/
class MergeRequestInfoFragment : BaseFragment(), MergeRequestInfoView {
override val layoutRes = R.layout.fragment_mr_info
@InjectPresenter
lateinit var presenter: MergeRequestInfoPresenter
@ProvidePresenter
fun providePresenter() =
Toothpick.openScope(DI.MERGE_REQUEST_SCOPE)
.getInstance(MergeRequestInfoPresenter::class.java)
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
toolbar.setNavigationOnClickListener { presenter.onBackPressed() }
}
override fun showMergeRequest(mrInfo: MergeRequestInfoView.MergeRequestInfo) {
toolbar.title = mrInfo.mr.id.toString()
}
override fun showProgress(show: Boolean) {
showProgressDialog(show)
}
override fun showMessage(message: String) {
showSnackMessage(message)
}
override fun onBackPressed() {
presenter.onBackPressed()
}
}
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"