Commit f216f7aa authored by Eugene Shapovalov's avatar Eugene Shapovalov 💬

Merge remote-tracking branch 'remotes/origin/develop' into feature/user_activity_badges

# Conflicts:
#	app/src/main/java/ru/terrakok/gitlabclient/extension/Extensions.kt
parents 0bbdb2e9 63d42715
......@@ -16,8 +16,8 @@ android {
minSdkVersion(19)
targetSdkVersion(28)
versionName = "1.4.2"
versionCode = 14
versionName = "1.5.1"
versionCode = 16
buildToolsVersion = "28.0.3"
......@@ -146,9 +146,9 @@ dependencies {
//JUnit
testImplementation("junit:junit:4.12")
//Mockito
testImplementation("org.mockito:mockito-core:2.8.9")
testImplementation("org.mockito:mockito-core:2.27.0")
//Mockito Kotlin
testImplementation("com.nhaarman:mockito-kotlin-kt1.1:1.5.0")
testImplementation("com.nhaarman.mockitokotlin2:mockito-kotlin:2.1.0")
}
configurations.all {
......
package ru.terrakok.gitlabclient
import android.app.Application
import android.content.Context
import android.graphics.Color
import android.os.Build
import androidx.multidex.MultiDex
import com.crashlytics.android.Crashlytics
import com.jakewharton.threetenabp.AndroidThreeTen
import io.fabric.sdk.android.Fabric
......@@ -18,6 +21,14 @@ import toothpick.configuration.Configuration
*/
class App : Application() {
override fun attachBaseContext(base: Context?) {
super.attachBaseContext(base)
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
MultiDex.install(this)
}
}
override fun onCreate() {
super.onCreate()
......
......@@ -4,15 +4,14 @@ import android.content.Context
import android.content.Intent
import android.net.Uri
import ru.terrakok.cicerone.android.support.SupportAppScreen
import ru.terrakok.gitlabclient.entity.app.target.TargetAction
import ru.terrakok.gitlabclient.entity.issue.IssueState
import ru.terrakok.gitlabclient.entity.mergerequest.MergeRequestState
import ru.terrakok.gitlabclient.entity.milestone.MilestoneState
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.file.ProjectFileFragment
import ru.terrakok.gitlabclient.ui.global.StubFragment
import ru.terrakok.gitlabclient.ui.issue.IssueFlowFragment
import ru.terrakok.gitlabclient.ui.issue.IssueInfoFragment
import ru.terrakok.gitlabclient.ui.issue.IssueNotesFragment
......@@ -39,7 +38,6 @@ import ru.terrakok.gitlabclient.ui.project.issues.ProjectIssuesFragment
import ru.terrakok.gitlabclient.ui.project.labels.ProjectLabelsFragment
import ru.terrakok.gitlabclient.ui.project.mergerequest.ProjectMergeRequestsContainerFragment
import ru.terrakok.gitlabclient.ui.project.mergerequest.ProjectMergeRequestsFragment
import ru.terrakok.gitlabclient.ui.project.milestones.ProjectMilestonesContainerFragment
import ru.terrakok.gitlabclient.ui.project.milestones.ProjectMilestonesFragment
import ru.terrakok.gitlabclient.ui.projects.ProjectsContainerFragment
import ru.terrakok.gitlabclient.ui.projects.ProjectsListFragment
......@@ -74,16 +72,18 @@ 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(
val projectId: Long,
val mrId: Long
val mrId: Long,
val targetAction: TargetAction
) : SupportAppScreen() {
override fun getFragment() = MergeRequestFlowFragment.create(projectId, mrId)
override fun getFragment() = MergeRequestFlowFragment.create(projectId, mrId, targetAction)
}
//screens
......@@ -189,14 +189,8 @@ object Screens {
override fun getFragment() = ProjectLabelsFragment()
}
object ProjectMilestonesContainer : SupportAppScreen() {
override fun getFragment() = ProjectMilestonesContainerFragment()
}
data class ProjectMilestones(
val milestoneState: MilestoneState
) : SupportAppScreen() {
override fun getFragment() = ProjectMilestonesFragment.create(milestoneState)
object ProjectMilestones : SupportAppScreen() {
override fun getFragment() = ProjectMilestonesFragment()
}
object ProjectFiles : SupportAppScreen() {
......
......@@ -2,11 +2,13 @@ package ru.terrakok.gitlabclient.di.provider
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import org.threeten.bp.LocalDate
import org.threeten.bp.LocalDateTime
import ru.terrakok.gitlabclient.entity.Color
import ru.terrakok.gitlabclient.entity.todo.Todo
import ru.terrakok.gitlabclient.model.data.server.deserializer.ColorDeserializer
import ru.terrakok.gitlabclient.model.data.server.deserializer.DateDeserializer
import ru.terrakok.gitlabclient.model.data.server.deserializer.LocalDateTimeDeserializer
import ru.terrakok.gitlabclient.model.data.server.deserializer.LocalDateDeserializer
import ru.terrakok.gitlabclient.model.data.server.deserializer.TodoDeserializer
import javax.inject.Inject
import javax.inject.Provider
......@@ -18,8 +20,9 @@ class GsonProvider @Inject constructor() : Provider<Gson> {
override fun get(): Gson =
GsonBuilder()
.registerTypeAdapter(LocalDateTime::class.java, DateDeserializer())
.registerTypeAdapter(LocalDateTime::class.java, LocalDateTimeDeserializer())
.registerTypeAdapter(Todo::class.java, TodoDeserializer())
.registerTypeAdapter(Color::class.java, ColorDeserializer())
.registerTypeAdapter(LocalDate::class.java, LocalDateDeserializer())
.create()
}
\ No newline at end of file
package ru.terrakok.gitlabclient.entity.app.target
import java.io.Serializable
/**
* @author Maxim Myalkin (MaxMyalkin) on 19.05.2019.
*/
sealed class TargetAction : Serializable {
data class CommentedOn(val noteId: Long) : TargetAction()
object Undefined: TargetAction()
}
\ No newline at end of file
......@@ -16,7 +16,8 @@ sealed class TargetHeader {
val target: AppTarget,
val targetId: Long,
val internal: TargetInternal?,
val badges: List<TargetBadge>
val badges: List<TargetBadge>,
val action: TargetAction
) : TargetHeader()
object Confidential : TargetHeader()
......
package ru.terrakok.gitlabclient.entity.milestone
import com.google.gson.annotations.SerializedName
import org.threeten.bp.LocalDate
import org.threeten.bp.LocalDateTime
data class Milestone(
......@@ -9,9 +10,10 @@ data class Milestone(
@SerializedName("project_id") val projectId: Long,
@SerializedName("description") val description: String?,
@SerializedName("state") val state: MilestoneState,
@SerializedName("due_date") val dueDate: String?,
@SerializedName("start_date") val startDate: String?,
@SerializedName("due_date") val dueDate: LocalDate?,
@SerializedName("start_date") val startDate: LocalDate?,
@SerializedName("created_at") val createdAt: LocalDateTime?,
@SerializedName("title") val title: String?,
@SerializedName("updated_at") val updatedAt: LocalDateTime?
@SerializedName("updated_at") val updatedAt: LocalDateTime?,
@SerializedName("web_url") val webUrl: String?
)
......@@ -9,6 +9,7 @@ import android.graphics.drawable.Drawable
import android.net.Uri
import android.text.SpannableStringBuilder
import android.text.Spanned
import android.text.TextUtils
import android.text.style.ForegroundColorSpan
import android.view.LayoutInflater
import android.view.View
......@@ -19,6 +20,7 @@ import android.widget.ImageView
import android.widget.TextView
import androidx.annotation.ColorInt
import androidx.annotation.LayoutRes
import androidx.appcompat.widget.Toolbar
import androidx.core.content.ContextCompat
import androidx.core.graphics.drawable.DrawableCompat
import androidx.fragment.app.Fragment
......@@ -162,12 +164,24 @@ fun TargetHeader.Public.openInfo(router: FlowRouter) {
}
AppTarget.MERGE_REQUEST -> {
internal?.let { targetInternal ->
router.startFlow(Screens.MergeRequestFlow(targetInternal.projectId, targetInternal.targetIid))
router.startFlow(
Screens.MergeRequestFlow(
targetInternal.projectId,
targetInternal.targetIid,
action
)
)
}
}
AppTarget.ISSUE -> {
internal?.let { targetInternal ->
router.startFlow(Screens.IssueFlow(targetInternal.projectId, targetInternal.targetIid))
router.startFlow(
Screens.IssueFlow(
targetInternal.projectId,
targetInternal.targetIid,
action
)
)
}
}
else -> {
......@@ -209,6 +223,19 @@ fun View.setBackgroundTintByColor(@ColorInt color: Int) {
DrawableCompat.setTint(wrappedDrawable.mutate(), color)
}
fun Toolbar.setTitleEllipsize(ellipsize: TextUtils.TruncateAt) {
val fakeTitle = "fakeTitle"
title = fakeTitle
for(i in 0..childCount) {
val child = getChildAt(i)
if (child is TextView && child.text == fakeTitle) {
child.ellipsize = TextUtils.TruncateAt.START
break
}
}
title = ""
}
fun Result<*>.getXTotalHeader(): Int {
return if (!isError) response().headers().get("X-Total")?.toInt() ?: 0 else 0
}
\ No newline at end of file
......@@ -4,6 +4,7 @@ import android.content.Context
import android.content.res.Resources
import androidx.annotation.DrawableRes
import org.threeten.bp.Duration
import org.threeten.bp.LocalDate
import org.threeten.bp.LocalDateTime
import org.threeten.bp.format.DateTimeFormatter
import retrofit2.HttpException
......@@ -13,6 +14,7 @@ import ru.terrakok.gitlabclient.entity.app.target.TargetBadgeStatus
import ru.terrakok.gitlabclient.entity.app.target.TargetHeaderIcon
import ru.terrakok.gitlabclient.entity.app.target.TargetHeaderTitle
import ru.terrakok.gitlabclient.entity.event.EventAction
import ru.terrakok.gitlabclient.entity.milestone.MilestoneState
import ru.terrakok.gitlabclient.entity.todo.TodoAction
import ru.terrakok.gitlabclient.model.system.ResourceManager
import java.io.IOException
......@@ -40,7 +42,10 @@ fun Throwable.userMessage(resourceManager: ResourceManager) = when (this) {
private val DATE_FORMAT = DateTimeFormatter.ofPattern("dd MMM yyyy")
fun LocalDateTime.humanTime(resources: Resources): String {
val delta = Duration.between(this, LocalDateTime.now()).seconds
val delta = Duration.between(this, LocalDateTime.now())
.seconds
.let { maxOf(0, it) }
val timeStr =
when {
delta < 60 -> resources.getString(R.string.time_sec, delta)
......@@ -53,6 +58,8 @@ fun LocalDateTime.humanTime(resources: Resources): String {
return resources.getString(R.string.time_ago, timeStr)
}
fun LocalDate.humanDate() = format(DATE_FORMAT)
fun EventAction.getHumanName(resources: Resources) = when (this) {
EventAction.UPDATED -> resources.getString(R.string.event_action_updated)
EventAction.REOPENED -> resources.getString(R.string.event_action_reopened)
......@@ -172,4 +179,14 @@ fun TargetBadgeStatus.getBadgeColors(context: Context) = when (this) {
fun String.extractFileNameFromPath(): String {
val index = lastIndexOf("/")
return substring(if (index != -1) index + 1 else 0)
}
fun MilestoneState.getHumanName(resources: Resources) = when (this) {
MilestoneState.ACTIVE -> resources.getString(R.string.milestone_active)
MilestoneState.CLOSED -> resources.getString(R.string.milestone_closed)
}
fun MilestoneState.getStateColors(context: Context) = when (this) {
MilestoneState.ACTIVE -> Pair(context.color(R.color.green), context.color(R.color.lightGreen))
MilestoneState.CLOSED -> Pair(context.color(R.color.red), context.color(R.color.lightRed))
}
\ No newline at end of file
package ru.terrakok.gitlabclient.model.data.server.deserializer
import com.google.gson.JsonDeserializationContext
import com.google.gson.JsonDeserializer
import com.google.gson.JsonElement
import org.threeten.bp.LocalDate
import org.threeten.bp.format.DateTimeFormatter
import java.lang.reflect.Type
/**
* Created by Eugene Shapovalov (@CraggyHaggy) on 16.05.19.
*/
class LocalDateDeserializer : JsonDeserializer<LocalDate> {
override fun deserialize(
json: JsonElement,
type: Type,
jsonDeserializationContext: JsonDeserializationContext
): LocalDate {
return LocalDate.parse(json.asJsonPrimitive.asString, DateTimeFormatter.ofPattern("yyyy-MM-dd"))
}
}
\ No newline at end of file
......@@ -11,7 +11,7 @@ import java.util.*
/**
* Created by Konstantin Tskhovrebov (aka @terrakok) on 27.02.18.
*/
class DateDeserializer : JsonDeserializer<LocalDateTime> {
class LocalDateTimeDeserializer : JsonDeserializer<LocalDateTime> {
private val offset = TimeZone.getDefault().rawOffset / 1000L
override fun deserialize(
......
......@@ -14,7 +14,7 @@ class MilestoneInteractor @Inject constructor(
fun getMilestones(
projectId: Long,
milestoneState: MilestoneState,
milestoneState: MilestoneState?,
page: Int
) = milestoneRepository
.getMilestones(projectId, milestoneState, page)
......
......@@ -143,7 +143,8 @@ class EventRepository @Inject constructor(
targetData.target,
targetData.id,
getTargetInternal(event),
badges
badges,
getTargetAction(event)
)
} else {
TargetHeader.Confidential
......@@ -267,6 +268,17 @@ class EventRepository @Inject constructor(
}
}
private fun getTargetAction(event: Event): TargetAction =
when (event.actionName) {
EventAction.COMMENTED_ON -> {
event.note
?.id
?.let { TargetAction.CommentedOn(it) }
?: TargetAction.Undefined
}
else -> TargetAction.Undefined
}
private fun getBody(event: Event, project: Project?) = when (event.targetType) {
EventTargetType.NOTE,
EventTargetType.DIFF_NOTE -> {
......
......@@ -121,7 +121,8 @@ class IssueRepository @Inject constructor(
AppTarget.ISSUE,
issue.id,
TargetInternal(issue.projectId, issue.iid),
badges
badges,
TargetAction.Undefined
)
}
......
......@@ -132,7 +132,8 @@ class MergeRequestRepository @Inject constructor(
AppTarget.MERGE_REQUEST,
mr.id,
TargetInternal(mr.projectId, mr.iid),
badges
badges,
TargetAction.Undefined
)
}
......
......@@ -88,7 +88,8 @@ class TodoRepository @Inject constructor(
appTarget,
target.id,
TargetInternal(target.projectId, target.iid),
badges
badges,
TargetAction.Undefined
)
}
......
......@@ -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
......@@ -8,6 +8,7 @@ import ru.terrakok.gitlabclient.di.MergeRequestId
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.mergerequest.MergeRequest
import ru.terrakok.gitlabclient.model.interactor.mergerequest.MergeRequestInteractor
import ru.terrakok.gitlabclient.model.interactor.project.ProjectInteractor
......@@ -24,6 +25,7 @@ import javax.inject.Inject
class MergeRequestPresenter @Inject constructor(
@ProjectId projectIdWrapper: PrimitiveWrapper<Long>,
@MergeRequestId mrIdWrapper: PrimitiveWrapper<Long>,
private val targetAction: TargetAction,
private val mrInteractor: MergeRequestInteractor,
private val projectInteractor: ProjectInteractor,
private val resourceManager: ResourceManager,
......@@ -36,7 +38,11 @@ class MergeRequestPresenter @Inject constructor(
override fun onFirstViewAttach() {
super.onFirstViewAttach()
updateToolbarTitle()
selectActionTab()
}
private fun updateToolbarTitle() {
Single
.zip(
mrInteractor.getMergeRequest(projectId, mrId),
......@@ -56,5 +62,9 @@ class MergeRequestPresenter @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 27.10.18.
......@@ -15,4 +16,7 @@ interface MergeRequestView : 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.MergeRequestId
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.mergerequest.MergeRequestInteractor
import ru.terrakok.gitlabclient.presentation.global.BasePresenter
import ru.terrakok.gitlabclient.presentation.global.ErrorHandler
......@@ -18,6 +19,7 @@ import javax.inject.Inject
class MergeRequestNotesPresenter @Inject constructor(
@ProjectId projectIdWrapper: PrimitiveWrapper<Long>,
@MergeRequestId mrIdWrapper: PrimitiveWrapper<Long>,
private val targetAction: TargetAction,
private val mrInteractor: MergeRequestInteractor,
private val mdConverter: MarkDownConverter,
private val errorHandler: ErrorHandler
......@@ -41,7 +43,12 @@ class MergeRequestNotesPresenter @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 MergeRequestNotesPresenter @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,13 @@ import ru.terrakok.gitlabclient.presentation.global.NoteWithFormattedBody
interface MergeRequestNotesView : 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
......@@ -39,9 +39,5 @@ class ProjectPresenter @Inject constructor(
fun onBackPressed() = flowRouter.exit()
fun onLabelPressed() = flowRouter.navigateTo(Screens.ProjectLabels)
fun onMilestonesClicked() = flowRouter.navigateTo(Screens.ProjectMilestonesContainer)
fun onFilesPressed() = flowRouter.navigateTo(Screens.ProjectFiles)
}
\ No newline at end of file
......@@ -42,11 +42,10 @@ class ProjectFileDestination {
fun isInitiated() = defaultPath.isNotEmpty() && branchName.isNotEmpty() && paths.isNotEmpty()
fun moveToRoot() {
val fromRoot = isInitiated() && !isInRoot()
if (!isInitiated()) {
paths.add(ROOT_PATH)
}
callback?.onMoveForward(fromRoot)
callback?.onMoveForward(true)
}
fun moveForward(path: String) {
......@@ -65,12 +64,12 @@ class ProjectFileDestination {
fun isInRoot() = paths.size <= 1
fun changeBranch(branchName: String) {
if (this.branchName != branchName) {
this.branchName = branchName
this.paths.clear()
this.paths.add(ROOT_PATH)
callback?.onBranchChange(