Commit 13bc0f53 authored by Konstantin Tskhovrebov's avatar Konstantin Tskhovrebov 🤖

Merge branch 'develop'

parents 0a3a846f c47a5851
......@@ -39,5 +39,6 @@ data class Project(
@SerializedName("shared_with_groups") val sharedWithGroups: List<SharedWithGroup>?,
@SerializedName("only_allow_merge_if_pipeline_succeeds") val onlyAllowMergeIfPipelineSucceeds: Boolean,
@SerializedName("only_allow_merge_if_all_discussions_are_resolved") val onlyAllowMergeIfAllDiscussionsAreResolved: Boolean,
@SerializedName("request_access_enabled") val requestAccessEnabled: Boolean
@SerializedName("request_access_enabled") val requestAccessEnabled: Boolean,
@SerializedName("readme_url") val readmeUrl: String?
)
......@@ -15,7 +15,6 @@ import ru.terrakok.gitlabclient.entity.app.target.TargetHeaderTitle
import ru.terrakok.gitlabclient.entity.event.EventAction
import ru.terrakok.gitlabclient.entity.todo.TodoAction
import ru.terrakok.gitlabclient.model.system.ResourceManager
import timber.log.Timber
import java.io.IOException
/**
......@@ -123,9 +122,7 @@ fun TargetHeaderTitle.getHumanName(resources: Resources) = when (this) {
when (action) {
TodoAction.ASSIGNED -> {
"$author $actionName $targetName ${resources.getString(R.string.at)} $projectName ${resources.getString(
R.string.to
)} $assignee"
"$author $actionName $targetName ${resources.getString(R.string.at)} $projectName ${resources.getString(R.string.to)} $assignee"
}
TodoAction.DIRECTLY_ADDRESSED,
TodoAction.MENTIONED -> {
......@@ -135,11 +132,13 @@ fun TargetHeaderTitle.getHumanName(resources: Resources) = when (this) {
"$author $actionName ${resources.getString(R.string.for_str)} $targetName ${resources.getString(R.string.at)} $projectName"
}
TodoAction.UNMERGEABLE -> {
"$actionName $targetName $projectName"
"$actionName $targetName ${resources.getString(R.string.at)} $projectName"
}
else -> {
Timber.e("Unsupported template for todo action=$actionName.")
"$author $actionName $targetName $assignee ${resources.getString(R.string.at)} $projectName"
TodoAction.BUILD_FAILED -> {
"$actionName ${resources.getString(R.string.for_str)} $targetName ${resources.getString(R.string.at)} $projectName"
}
TodoAction.APPROVAL_REQUIRED -> {
"$author $actionName ${resources.getString(R.string.for_str)} $targetName ${resources.getString(R.string.at)} $projectName"
}
}
}
......
......@@ -2,6 +2,7 @@ package ru.terrakok.gitlabclient.model.interactor.project
import io.reactivex.Single
import ru.terrakok.gitlabclient.entity.OrderBy
import ru.terrakok.gitlabclient.entity.Project
import ru.terrakok.gitlabclient.model.repository.project.ProjectRepository
import ru.terrakok.gitlabclient.model.repository.tools.Base64Tools
import ru.terrakok.gitlabclient.model.system.SchedulersProvider
......@@ -42,28 +43,22 @@ class ProjectInteractor @Inject constructor(
fun getProject(id: Long) = projectRepository.getProject(id)
/**
* Returns [Single] with the project readme file decoded as [String]
* at the specified project and branch. The project readme is searched ignoring case.
*
* @param id project id.
* @param branchName project branch name to search readme.
* @return [Single] with readme decoded as [String].
* @throws NoSuchElementException if project readme with name [README_FILE_NAME] not found.
*/
fun getProjectReadme(id: Long, branchName: String) =
projectRepository.getRepositoryTree(projectId = id, branchName = branchName)
.map { treeNodes ->
treeNodes.first { it.name.contains(README_FILE_NAME, true) }
}
.flatMap { treeNode ->
projectRepository.getFile(id, treeNode.name, branchName)
.observeOn(schedulers.computation())
.map { file -> base64Tools.decode(file.content) }
.observeOn(schedulers.ui())
fun getProjectReadme(project: Project) =
Single
.defer {
if (project.readmeUrl != null) {
val readmePath = project.readmeUrl.substringAfter(
"${project.webUrl}/blob/${project.defaultBranch}/"
)
projectRepository.getFile(project.id, readmePath, project.defaultBranch)
} else {
Single.error(ReadmeNotFound())
}
}
.observeOn(schedulers.computation())
.map { file -> base64Tools.decode(file.content) }
.observeOn(schedulers.ui())
companion object {
private const val README_FILE_NAME = "readme.md"
}
class ReadmeNotFound : Exception()
}
\ No newline at end of file
......@@ -30,10 +30,10 @@ class ProjectInfoPresenter @Inject constructor(
.getProject(projectId)
.flatMap { project ->
projectInteractor
.getProjectReadme(project.id, project.defaultBranch)
.getProjectReadme(project)
.onErrorResumeNext { throwable ->
when (throwable) {
is NoSuchElementException -> Single.just("")
is ProjectInteractor.ReadmeNotFound -> Single.just("")
else -> Single.error(throwable)
}
}
......
......@@ -13,11 +13,23 @@ private const val PROGRESS_TAG = "bf_progress"
abstract class BaseFragment : MvpAppCompatFragment() {
abstract val layoutRes: Int
private var instanceStateSaved: Boolean = false
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?) =
inflater.inflate(layoutRes, container, false)
override fun onResume() {
super.onResume()
instanceStateSaved = false
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
instanceStateSaved = true
}
protected fun showProgressDialog(progress: Boolean) {
if (!isAdded) return
if (!isAdded || instanceStateSaved) return
val fragment = childFragmentManager.findFragmentByTag(PROGRESS_TAG)
if (fragment != null && !progress) {
......
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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:id="@+id/zeroLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/zeroImageView"
android:layout_width="100dp"
android:layout_height="100dp"
android:src="@drawable/default_img"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@id/titleTextView"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/titleTextView"
style="@style/TextHeadline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="40dp"
app:layout_constraintLeft_toRightOf="@id/zeroImageView"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="@id/zeroImageView"
tools:text="@string/empty_error" />
<TextView
android:id="@+id/descriptionTextView"
style="@style/TextBody"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:layout_marginEnd="24dp"
app:layout_constraintLeft_toLeftOf="@id/titleTextView"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/titleTextView"
tools:text="@string/empty_error_description" />
<Button
android:id="@+id/refreshButton"
style="@style/Base.Widget.AppCompat.Button.Borderless.Colored"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/refresh"
android:layout_marginStart="25dp"
app:layout_constraintLeft_toRightOf="@id/zeroImageView"
app:layout_constraintTop_toBottomOf="@id/descriptionTextView" />
</android.support.constraint.ConstraintLayout>
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
<android.support.constraint.ConstraintLayout 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:id="@+id/zeroLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Space
android:id="@+id/spaceTop"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@id/zeroImageView"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed"
app:layout_constraintVertical_weight="1" />
<ImageView
android:id="@+id/zeroImageView"
android:layout_width="100dp"
android:layout_height="100dp"
android:src="@drawable/default_img"
app:layout_constraintBottom_toTopOf="@+id/titleTextView"
app:layout_constraintBottom_toTopOf="@id/spaceMiddle"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed"/>
app:layout_constraintTop_toBottomOf="@id/spaceTop" />
<Space
android:id="@+id/spaceMiddle"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@id/titleTextView"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/zeroImageView"
app:layout_constraintVertical_weight="1" />
<TextView
android:id="@+id/titleTextView"
style="@style/TextHeadline"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="24dp"
android:layout_marginStart="24dp"
android:layout_marginTop="64dp"
android:layout_marginEnd="24dp"
android:gravity="center"
app:layout_constraintBottom_toTopOf="@+id/descriptionTextView"
app:layout_constraintBottom_toTopOf="@id/descriptionTextView"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/zeroImageView"
tools:text="@string/empty_error"/>
app:layout_constraintTop_toBottomOf="@id/spaceMiddle"
tools:text="@string/empty_error" />
<TextView
android:id="@+id/descriptionTextView"
style="@style/TextBody"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="24dp"
android:layout_marginStart="24dp"
android:layout_marginTop="24dp"
android:layout_marginEnd="24dp"
android:gravity="center"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintBottom_toTopOf="@id/spaceBottom"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/titleTextView"
tools:text="@string/empty_error_description"/>
tools:text="@string/empty_error_description" />
<Space
android:id="@+id/spaceBottom"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@id/refreshButton"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/descriptionTextView"
app:layout_constraintVertical_weight="1" />
<Button
android:id="@+id/refreshButton"
style="@style/Base.Widget.AppCompat.Button.Borderless.Colored"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="24dp"
android:text="@string/refresh"
android:layout_marginBottom="24dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"/>
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/spaceBottom" />
</android.support.constraint.ConstraintLayout>
......@@ -135,9 +135,9 @@
<string name="my_todos_done">Done</string>
<string name="todo_action_assigned">assigned</string>
<string name="todo_action_mentioned">mentioned</string>
<string name="todo_action_build_failed">build failed</string>
<string name="todo_action_build_failed">The build failed</string>
<string name="todo_action_marked">added a todo</string>
<string name="todo_action_approval_required">approval required</string>
<string name="todo_action_approval_required">set you as an approver</string>
<string name="todo_action_directly_addressed">directly addressed</string>
<string name="todo_action_unmergeable">Could not merge</string>
......
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