Commit 20937292 authored by Maxim Myalkin's avatar Maxim Myalkin

Implement issue comment smart routing.

parent 5a208ed6
......@@ -72,9 +72,10 @@ object Screens {
data class IssueFlow(
val projectId: Long,
val issueId: Long
val issueId: Long,
val targetAction: TargetAction
) : SupportAppScreen() {
override fun getFragment() = IssueFlowFragment.create(projectId, issueId)
override fun getFragment() = IssueFlowFragment.create(projectId, issueId, targetAction)
}
data class MergeRequestFlow(
......
......@@ -172,7 +172,13 @@ fun TargetHeader.Public.openInfo(router: FlowRouter) {
}
AppTarget.ISSUE -> {
internal?.let { targetInternal ->
router.startFlow(Screens.IssueFlow(targetInternal.projectId, targetInternal.targetIid))
router.startFlow(
Screens.IssueFlow(
targetInternal.projectId,
targetInternal.targetIid,
action
)
)
}
}
else -> {
......
......@@ -8,6 +8,7 @@ import ru.terrakok.gitlabclient.di.IssueId
import ru.terrakok.gitlabclient.di.PrimitiveWrapper
import ru.terrakok.gitlabclient.di.ProjectId
import ru.terrakok.gitlabclient.entity.Project
import ru.terrakok.gitlabclient.entity.app.target.TargetAction
import ru.terrakok.gitlabclient.entity.issue.Issue
import ru.terrakok.gitlabclient.model.interactor.issue.IssueInteractor
import ru.terrakok.gitlabclient.model.interactor.project.ProjectInteractor
......@@ -24,6 +25,7 @@ import javax.inject.Inject
class IssuePresenter @Inject constructor(
@ProjectId projectIdWrapper: PrimitiveWrapper<Long>,
@IssueId issueIdWrapper: PrimitiveWrapper<Long>,
private val targetAction: TargetAction,
private val issueInteractor: IssueInteractor,
private val projectInteractor: ProjectInteractor,
private val resourceManager: ResourceManager,
......@@ -36,7 +38,12 @@ class IssuePresenter @Inject constructor(
override fun onFirstViewAttach() {
super.onFirstViewAttach()
updateToolbarTitle()
selectActionTab()
}
private fun updateToolbarTitle() {
Single
.zip(
issueInteractor.getIssue(projectId, issueId),
......@@ -56,5 +63,9 @@ class IssuePresenter @Inject constructor(
.connect()
}
private fun selectActionTab() {
viewState.selectActionTab(targetAction)
}
fun onBackPressed() = flowRouter.exit()
}
\ No newline at end of file
......@@ -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.app.target.TargetAction
/**
* Created by Eugene Shapovalov (@CraggyHaggy) on 01.11.18.
......@@ -15,4 +16,7 @@ interface IssueView : MvpView {
@StateStrategyType(OneExecutionStateStrategy::class)
fun showMessage(message: String)
@StateStrategyType(OneExecutionStateStrategy::class)
fun selectActionTab(targetAction: TargetAction)
}
\ No newline at end of file
......@@ -4,6 +4,7 @@ import com.arellomobile.mvp.InjectViewState
import ru.terrakok.gitlabclient.di.IssueId
import ru.terrakok.gitlabclient.di.PrimitiveWrapper
import ru.terrakok.gitlabclient.di.ProjectId
import ru.terrakok.gitlabclient.entity.app.target.TargetAction
import ru.terrakok.gitlabclient.model.interactor.issue.IssueInteractor
import ru.terrakok.gitlabclient.presentation.global.BasePresenter
import ru.terrakok.gitlabclient.presentation.global.ErrorHandler
......@@ -18,6 +19,7 @@ import javax.inject.Inject
class IssueNotesPresenter @Inject constructor(
@ProjectId projectIdWrapper: PrimitiveWrapper<Long>,
@IssueId issueIdWrapper: PrimitiveWrapper<Long>,
private val targetAction: TargetAction,
private val issueInteractor: IssueInteractor,
private val mdConverter: MarkDownConverter,
private val errorHandler: ErrorHandler
......@@ -41,7 +43,12 @@ class IssueNotesPresenter @Inject constructor(
}
.toList()
.subscribe(
{ viewState.showNotes(it, false) },
{ notes ->
val selectedNotePosition = targetAction.let { it as? TargetAction.CommentedOn }
?.noteId
?.let { noteIdToSelect -> notes.indexOfFirst { it.note.id == noteIdToSelect } }
viewState.showNotes(notes, selectedNotePosition)
},
{ errorHandler.proceed(it, { viewState.showMessage(it) }) }
)
.connect()
......@@ -62,7 +69,10 @@ class IssueNotesPresenter @Inject constructor(
.doOnSubscribe { viewState.showBlockingProgress(true) }
.doAfterTerminate { viewState.showBlockingProgress(false) }
.subscribe(
{ viewState.showNotes(it, true) },
{
viewState.showNotes(it, it.size - 1)
viewState.clearInput()
},
{ errorHandler.proceed(it, { viewState.showMessage(it) }) }
)
.connect()
......
......@@ -13,9 +13,12 @@ import ru.terrakok.gitlabclient.presentation.global.NoteWithFormattedBody
interface IssueNotesView : MvpView {
fun showEmptyProgress(show: Boolean)
fun showNotes(notes: List<NoteWithFormattedBody>, scrollToEnd: Boolean)
fun showNotes(notes: List<NoteWithFormattedBody>, scrollToPosition: Int?)
fun showBlockingProgress(show: Boolean)
@StateStrategyType(OneExecutionStateStrategy::class)
fun showMessage(message: String)
@StateStrategyType(OneExecutionStateStrategy::class)
fun clearInput()
}
\ No newline at end of file
......@@ -5,8 +5,10 @@ import ru.terrakok.gitlabclient.Screens
import ru.terrakok.gitlabclient.di.IssueId
import ru.terrakok.gitlabclient.di.PrimitiveWrapper
import ru.terrakok.gitlabclient.di.ProjectId
import ru.terrakok.gitlabclient.entity.app.target.TargetAction
import ru.terrakok.gitlabclient.extension.argument
import ru.terrakok.gitlabclient.ui.global.FlowFragment
import ru.terrakok.gitlabclient.ui.mergerequest.MergeRequestFlowFragment
import toothpick.Scope
import toothpick.config.Module
......@@ -14,6 +16,7 @@ class IssueFlowFragment : FlowFragment() {
private val issueId by argument(ARG_ISSUE_ID, 0L)
private val projectId by argument(ARG_PROJECT_ID, 0L)
private val targetAction by argument<TargetAction>(ARG_TARGET_ACTION)
override fun installModules(scope: Scope) {
super.installModules(scope)
......@@ -26,6 +29,8 @@ class IssueFlowFragment : FlowFragment() {
bind(PrimitiveWrapper::class.java)
.withName(IssueId::class.java)
.toInstance(PrimitiveWrapper(issueId))
bind(TargetAction::class.java)
.toInstance(targetAction)
}
}
)
......@@ -36,11 +41,14 @@ class IssueFlowFragment : FlowFragment() {
companion object {
private const val ARG_PROJECT_ID = "arg_project_id"
private const val ARG_ISSUE_ID = "arg_issue_id"
fun create(projectId: Long, issueId: Long) =
private const val ARG_TARGET_ACTION = "arg_target_action"
fun create(projectId: Long, issueId: Long, targetAction: TargetAction) =
IssueFlowFragment().apply {
arguments = Bundle().apply {
putLong(ARG_PROJECT_ID, projectId)
putLong(ARG_ISSUE_ID, issueId)
putSerializable(ARG_TARGET_ACTION, targetAction)
}
}
}
......
......@@ -60,7 +60,7 @@ class IssueNotesFragment : BaseFragment(), IssueNotesView {
recyclerView.scrollToPosition(adapter.itemCount - 1)
setFabScrollVisible(false)
}
newNoteView.init { presenter.onSendClicked(it) }
newNoteView.init { presenter.onSendClicked(it) }
}
private fun setFabScrollVisible(visible: Boolean) {
......@@ -77,15 +77,16 @@ class IssueNotesFragment : BaseFragment(), IssueNotesView {
showProgressDialog(show)
}
override fun showNotes(notes: List<NoteWithFormattedBody>, scrollToEnd: Boolean) {
override fun showNotes(notes: List<NoteWithFormattedBody>, scrollToPosition: Int?) {
adapter.setData(notes)
if (scrollToEnd) {
recyclerView.scrollToPosition(adapter.itemCount - 1)
newNoteView.clearInput()
}
scrollToPosition?.let { recyclerView.scrollToPosition(it) }
}
override fun showMessage(message: String) {
showSnackMessage(message)
}
override fun clearInput() {
newNoteView.clearInput()
}
}
\ No newline at end of file
......@@ -7,6 +7,7 @@ import com.arellomobile.mvp.presenter.ProvidePresenter
import kotlinx.android.synthetic.main.fragment_main_mr.*
import ru.terrakok.gitlabclient.R
import ru.terrakok.gitlabclient.Screens
import ru.terrakok.gitlabclient.entity.app.target.TargetAction
import ru.terrakok.gitlabclient.extension.showSnackMessage
import ru.terrakok.gitlabclient.presentation.issue.IssuePresenter
import ru.terrakok.gitlabclient.presentation.issue.IssueView
......@@ -52,18 +53,31 @@ class MainIssueFragment : BaseFragment(), IssueView {
showSnackMessage(message)
}
override fun selectActionTab(targetAction: TargetAction) {
when(targetAction) {
is TargetAction.CommentedOn -> {
viewPager.currentItem = TAB_NOTES
}
}
}
private inner class IssuePagesAdapter : FragmentPagerAdapter(childFragmentManager) {
override fun getItem(position: Int): BaseFragment = when (position) {
0 -> Screens.IssueInfo.fragment
TAB_DETAILS -> Screens.IssueInfo.fragment
else -> Screens.IssueNotes.fragment
}
override fun getCount() = 2
override fun getPageTitle(position: Int) = when (position) {
0 -> getString(R.string.merge_request_info_tab)
1 -> getString(R.string.merge_request_discussion_tab)
TAB_DETAILS -> getString(R.string.merge_request_info_tab)
TAB_NOTES -> getString(R.string.merge_request_discussion_tab)
else -> null
}
}
companion object {
private const val TAB_DETAILS = 0
private const val TAB_NOTES = 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