Commit 6dec10ee authored by Eugene Shapovalov's avatar Eugene Shapovalov 💬

Refactor project file enter navigation.

parent efb33417
......@@ -11,9 +11,8 @@ 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.StubFragment
import ru.terrakok.gitlabclient.ui.file.ProjectFileFlowFragment
import ru.terrakok.gitlabclient.ui.file.ProjectFileFragment
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
......@@ -241,17 +240,12 @@ object Screens {
override fun getFragment() = PrivacyPolicyFragment()
}
data class ProjectFileFlow(
data class ProjectFile(
val projectId: Long,
val fileName: String,
val filePath: String,
val branchName: String
) : SupportAppScreen() {
override fun getFragment() = ProjectFileFlowFragment.create(projectId, fileName, filePath, branchName)
}
object ProjectFile : SupportAppScreen() {
override fun getFragment() = ProjectFileFragment()
override fun getFragment() = ProjectFileFragment.create(projectId, filePath, branchName)
}
data class ExternalBrowserFlow(
......
......@@ -11,8 +11,8 @@ data class MergeRequest(
@SerializedName("iid") val iid: Long,
@SerializedName("created_at") val createdAt: LocalDateTime,
@SerializedName("updated_at") val updatedAt: LocalDateTime?,
@SerializedName("target_branch") val targetBranch: String?,
@SerializedName("source_branch") val sourceBranch: String?,
@SerializedName("target_branch") val targetBranch: String,
@SerializedName("source_branch") val sourceBranch: String,
@SerializedName("project_id") val projectId: Long,
@SerializedName("title") val title: String?,
@SerializedName("state") val state: MergeRequestState,
......
package ru.terrakok.gitlabclient.presentation.file
import com.arellomobile.mvp.InjectViewState
import ru.terrakok.cicerone.Router
import ru.terrakok.gitlabclient.model.interactor.project.ProjectInteractor
import ru.terrakok.gitlabclient.model.system.flow.FlowRouter
import ru.terrakok.gitlabclient.presentation.global.BasePresenter
import ru.terrakok.gitlabclient.presentation.global.ErrorHandler
import ru.terrakok.gitlabclient.toothpick.PrimitiveWrapper
import ru.terrakok.gitlabclient.toothpick.qualifier.BranchName
import ru.terrakok.gitlabclient.toothpick.qualifier.FileName
import ru.terrakok.gitlabclient.toothpick.qualifier.FilePath
import ru.terrakok.gitlabclient.toothpick.qualifier.ProjectId
import javax.inject.Inject
......@@ -18,15 +17,14 @@ import javax.inject.Inject
@InjectViewState
class ProjectFilePresenter @Inject constructor(
@ProjectId projectIdWrapper: PrimitiveWrapper<Long>,
@FileName fileName: String,
@FilePath filePath: String,
@BranchName branchName: String,
private val projectInteractor: ProjectInteractor,
private val errorHandler: ErrorHandler,
private val flowRouter: FlowRouter
private val router: Router
) : BasePresenter<ProjectFileView>() {
private val projectId = projectIdWrapper.value
fun onBackPressed() = flowRouter.exit()
fun onBackPressed() = router.exit()
}
\ No newline at end of file
package ru.terrakok.gitlabclient.presentation.mergerequest.changes
import com.arellomobile.mvp.InjectViewState
import ru.terrakok.gitlabclient.Screens
import ru.terrakok.gitlabclient.entity.mergerequest.MergeRequestChange
import ru.terrakok.gitlabclient.model.interactor.mergerequest.MergeRequestInteractor
import ru.terrakok.gitlabclient.model.system.flow.FlowRouter
import ru.terrakok.gitlabclient.presentation.global.BasePresenter
import ru.terrakok.gitlabclient.presentation.global.ErrorHandler
import ru.terrakok.gitlabclient.toothpick.PrimitiveWrapper
......@@ -18,7 +20,8 @@ class MergeRequestChangesPresenter @Inject constructor(
@ProjectId projectIdWrapper: PrimitiveWrapper<Long>,
@MergeRequestId mrIdWrapper: PrimitiveWrapper<Long>,
private val mrInteractor: MergeRequestInteractor,
private val errorHandler: ErrorHandler
private val errorHandler: ErrorHandler,
private val flowRouter: FlowRouter
) : BasePresenter<MergeRequestChangesView>() {
private val projectId = projectIdWrapper.value
......@@ -106,4 +109,15 @@ class MergeRequestChangesPresenter @Inject constructor(
)
.connect()
}
fun onMergeRequestChangeClick(item: MergeRequestChange) {
mrInteractor.getMergeRequest(projectId, mrId)
.doOnSubscribe { viewState.showFullscreenProgress(true) }
.doAfterTerminate { viewState.showFullscreenProgress(false) }
.subscribe(
{ flowRouter.startFlow(Screens.ProjectFile(projectId, item.newPath, it.sourceBranch)) },
{ errorHandler.proceed(it, { viewState.showMessage(it) }) }
)
.connect()
}
}
\ No newline at end of file
......@@ -20,4 +20,6 @@ interface MergeRequestChangesView : MvpView {
@StateStrategyType(OneExecutionStateStrategy::class)
fun showMessage(message: String)
fun showFullscreenProgress(show: Boolean)
}
\ No newline at end of file
......@@ -4,6 +4,7 @@ import com.arellomobile.mvp.InjectViewState
import io.reactivex.Single
import io.reactivex.functions.BiFunction
import ru.terrakok.gitlabclient.R
import ru.terrakok.gitlabclient.Screens
import ru.terrakok.gitlabclient.entity.Branch
import ru.terrakok.gitlabclient.entity.Project
import ru.terrakok.gitlabclient.entity.RepositoryTreeNodeType
......@@ -208,7 +209,13 @@ class ProjectFilesPresenter @Inject constructor(
if (item.nodeType == RepositoryTreeNodeType.TREE) {
projectFileDestination.moveForward(item.name)
} else {
// TODO: file details (Navigate to file details flow).
router.startFlow(
Screens.ProjectFile(
projectId,
getFilePath(projectFileDestination.isInRoot(), projectFileDestination.paths, item.name),
projectFileDestination.branchName
)
)
}
}
......@@ -235,5 +242,12 @@ class ProjectFilesPresenter @Inject constructor(
} else {
paths.subList(1, paths.size).joinToString(separator = REMOTE_SEPARATOR)
}
private fun getFilePath(inRoot: Boolean, paths: List<String>, fileName: String) =
if (inRoot) {
fileName
} else {
"${paths.subList(1, paths.size).joinToString(separator = REMOTE_SEPARATOR)}$REMOTE_SEPARATOR$fileName"
}
}
}
\ No newline at end of file
......@@ -42,9 +42,6 @@ annotation class CacheLifetime
@Qualifier
annotation class WithErrorHandler
@Qualifier
annotation class FileName
@Qualifier
annotation class FilePath
......
package ru.terrakok.gitlabclient.ui.file
import android.os.Bundle
import com.arellomobile.mvp.MvpView
import ru.terrakok.cicerone.Router
import ru.terrakok.gitlabclient.Screens
import ru.terrakok.gitlabclient.extension.argument
import ru.terrakok.gitlabclient.extension.setLaunchScreen
import ru.terrakok.gitlabclient.toothpick.DI
import ru.terrakok.gitlabclient.toothpick.PrimitiveWrapper
import ru.terrakok.gitlabclient.toothpick.module.FlowNavigationModule
import ru.terrakok.gitlabclient.toothpick.qualifier.BranchName
import ru.terrakok.gitlabclient.toothpick.qualifier.FileName
import ru.terrakok.gitlabclient.toothpick.qualifier.FilePath
import ru.terrakok.gitlabclient.toothpick.qualifier.ProjectId
import ru.terrakok.gitlabclient.ui.global.FlowFragment
import toothpick.Scope
import toothpick.Toothpick
import toothpick.config.Module
import javax.inject.Inject
/**
* Created by Eugene Shapovalov (@CraggyHaggy) on 22.11.18.
*/
class ProjectFileFlowFragment : FlowFragment(), MvpView {
private val projectId by argument(ARG_PROJECT_ID, 0L)
private val fileName by argument<String>(ARG_FILE_NAME, null)
private val filePath by argument<String>(ARG_FILE_PATH, null)
private val branchName by argument<String>(ARG_BRANCH_NAME, null)
override val parentScopeName = DI.SERVER_SCOPE
override val scopeModuleInstaller = { scope: Scope ->
scope.installModules(
FlowNavigationModule(scope.getInstance(Router::class.java)),
object : Module() {
init {
bind(PrimitiveWrapper::class.java)
.withName(ProjectId::class.java)
.toInstance(PrimitiveWrapper(projectId))
bind(String::class.java)
.withName(FileName::class.java)
.toInstance(fileName)
bind(String::class.java)
.withName(FilePath::class.java)
.toInstance(filePath)
bind(String::class.java)
.withName(BranchName::class.java)
.toInstance(branchName)
}
}
)
}
@Inject
lateinit var router: Router
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Toothpick.inject(this, scope)
if (childFragmentManager.fragments.isEmpty()) {
navigator.setLaunchScreen(Screens.Auth)
}
}
override fun onExit() {
router.exit()
}
companion object {
private const val ARG_PROJECT_ID = "arg_project_id"
private const val ARG_FILE_NAME = "arg_file_name"
private const val ARG_FILE_PATH = "arg_file_path"
private const val ARG_BRANCH_NAME = "arg_branch_name"
fun create(projectId: Long, fileName: String, filePath: String, branchName: String) =
ProjectFileFlowFragment().apply {
arguments = Bundle().apply {
putLong(ARG_PROJECT_ID, projectId)
putString(ARG_FILE_NAME, fileName)
putString(ARG_FILE_PATH, filePath)
putString(ARG_BRANCH_NAME, branchName)
}
}
}
}
\ No newline at end of file
......@@ -5,23 +5,54 @@ import com.arellomobile.mvp.presenter.InjectPresenter
import com.arellomobile.mvp.presenter.ProvidePresenter
import kotlinx.android.synthetic.main.fragment_mr.*
import ru.terrakok.gitlabclient.R
import ru.terrakok.gitlabclient.extension.argument
import ru.terrakok.gitlabclient.presentation.file.ProjectFilePresenter
import ru.terrakok.gitlabclient.presentation.file.ProjectFileView
import ru.terrakok.gitlabclient.toothpick.DI
import ru.terrakok.gitlabclient.toothpick.PrimitiveWrapper
import ru.terrakok.gitlabclient.toothpick.qualifier.BranchName
import ru.terrakok.gitlabclient.toothpick.qualifier.FilePath
import ru.terrakok.gitlabclient.toothpick.qualifier.ProjectId
import ru.terrakok.gitlabclient.ui.global.BaseFragment
import toothpick.Scope
import toothpick.config.Module
/**
* Created by Eugene Shapovalov (@CraggyHaggy) on 22.11.18.
*/
class ProjectFileFragment : BaseFragment(), ProjectFileView {
private val projectId by argument(ARG_PROJECT_ID, 0L)
private val filePath by argument<String>(ARG_FILE_PATH, null)
private val branchName by argument<String>(ARG_BRANCH_NAME, null)
override val layoutRes = R.layout.fragment_project_file
override val parentScopeName = DI.SERVER_SCOPE
override val scopeModuleInstaller = { scope: Scope ->
scope.installModules(
object : Module() {
init {
bind(PrimitiveWrapper::class.java)
.withName(ProjectId::class.java)
.toInstance(PrimitiveWrapper(projectId))
bind(String::class.java)
.withName(FilePath::class.java)
.toInstance(filePath)
bind(String::class.java)
.withName(BranchName::class.java)
.toInstance(branchName)
}
}
)
}
@InjectPresenter
lateinit var presenter: ProjectFilePresenter
@ProvidePresenter
fun providePresenter() =
scope.getInstance(ProjectFilePresenter::class.java)
fun providePresenter() = scope.getInstance(ProjectFilePresenter::class.java)
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
......@@ -32,4 +63,19 @@ class ProjectFileFragment : BaseFragment(), ProjectFileView {
super.onBackPressed()
presenter.onBackPressed()
}
companion object {
private const val ARG_PROJECT_ID = "arg_project_id"
private const val ARG_FILE_PATH = "arg_file_path"
private const val ARG_BRANCH_NAME = "arg_branch_name"
fun create(projectId: Long, filePath: String, branchName: String) =
ProjectFileFragment().apply {
arguments = Bundle().apply {
putLong(ARG_PROJECT_ID, projectId)
putString(ARG_FILE_PATH, filePath)
putString(ARG_BRANCH_NAME, branchName)
}
}
}
}
\ No newline at end of file
......@@ -13,7 +13,9 @@ import ru.terrakok.gitlabclient.ui.global.GitDiffViewController
/**
* Created by Eugene Shapovalov (@CraggyHaggy) on 26.10.18.
*/
class MergeRequestChangeAdapterDelegate : AdapterDelegate<MutableList<MergeRequestChange>>() {
class MergeRequestChangeAdapterDelegate(
private val clickListener: (MergeRequestChange) -> Unit
) : AdapterDelegate<MutableList<MergeRequestChange>>() {
override fun isForViewType(items: MutableList<MergeRequestChange>, position: Int) = true
......@@ -33,26 +35,30 @@ class MergeRequestChangeAdapterDelegate : AdapterDelegate<MutableList<MergeReque
}
private inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
private lateinit var mergeRequestChange: MergeRequestChange
private lateinit var item: MergeRequestChange
init {
view.setOnClickListener { clickListener(item) }
}
private val gitDiffViewController: GitDiffViewController = GitDiffViewController(itemView.changeFile)
fun bind(mergeRequestChange: MergeRequestChange) {
this.mergeRequestChange = mergeRequestChange
fun bind(item: MergeRequestChange) {
this.item = item
with(itemView) {
changePath.text = mergeRequestChange.newPath
changePath.text = item.newPath
changeIcon.setImageResource(
when {
mergeRequestChange.newFile -> R.drawable.ic_file_added
mergeRequestChange.deletedFile -> R.drawable.ic_file_deleted
item.newFile -> R.drawable.ic_file_added
item.deletedFile -> R.drawable.ic_file_deleted
else -> R.drawable.ic_file_changed
}
)
changeFileName.text = mergeRequestChange.newPath.let {
changeFileName.text = item.newPath.let {
val index = it.lastIndexOf("/")
it.substring(if (index != -1) index + 1 else 0)
}
gitDiffViewController.setText(mergeRequestChange.diff)
gitDiffViewController.setText(item.diff)
changeAddedCount.text = context.getString(
R.string.merge_request_changes_added_count,
gitDiffViewController.getAddedLineCount()
......
......@@ -8,11 +8,13 @@ import ru.terrakok.gitlabclient.ui.global.list.MergeRequestChangeAdapterDelegate
/**
* Created by Eugene Shapovalov (@CraggyHaggy) on 26.10.18.
*/
class MergeRequestChangeAdapter : ListDelegationAdapter<MutableList<MergeRequestChange>>() {
class MergeRequestChangeAdapter(
clickListener: (MergeRequestChange) -> Unit
) : ListDelegationAdapter<MutableList<MergeRequestChange>>() {
init {
items = mutableListOf()
delegatesManager.addDelegate(MergeRequestChangeAdapterDelegate())
delegatesManager.addDelegate(MergeRequestChangeAdapterDelegate(clickListener))
}
fun setData(data: List<MergeRequestChange>) {
......
......@@ -23,7 +23,7 @@ class MergeRequestChangesFragment : BaseFragment(), MergeRequestChangesView {
override val layoutRes = R.layout.fragment_mr_changes
private val adapter by lazy { MergeRequestChangeAdapter() }
private val adapter by lazy { MergeRequestChangeAdapter({ presenter.onMergeRequestChangeClick(it) }) }
private var zeroViewHolder: ZeroViewHolder? = null
@InjectPresenter
......@@ -77,4 +77,8 @@ class MergeRequestChangesFragment : BaseFragment(), MergeRequestChangesView {
override fun showMessage(message: String) {
showSnackMessage(message)
}
override fun showFullscreenProgress(show: Boolean) {
showProgressDialog(show)
}
}
\ 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