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

Implemented project issues tab.

parent 350b5ab2
......@@ -5,6 +5,7 @@ import android.content.Intent
import android.graphics.Bitmap
import android.graphics.drawable.Drawable
import android.net.Uri
import android.os.Bundle
import android.support.annotation.LayoutRes
import android.support.v4.app.Fragment
import android.support.v4.content.ContextCompat
......@@ -145,4 +146,9 @@ fun TargetHeader.openInfo(router: FlowRouter) {
}
}
}
}
\ No newline at end of file
}
inline fun <reified T : Enum<T>> Bundle.getEnum(key: String): T? = if (containsKey(key))
getInt(key).let { return@let enumValues<T>()[it] } else null
fun <T : Enum<T>> Bundle.putEnum(key: String, value: T) = putInt(key, value.ordinal)
\ No newline at end of file
......@@ -2,8 +2,21 @@ package ru.terrakok.gitlabclient.model.data.server
import io.reactivex.Completable
import io.reactivex.Single
import retrofit2.http.*
import ru.terrakok.gitlabclient.entity.*
import retrofit2.http.Field
import retrofit2.http.FormUrlEncoded
import retrofit2.http.GET
import retrofit2.http.POST
import retrofit2.http.Path
import retrofit2.http.Query
import ru.terrakok.gitlabclient.entity.File
import ru.terrakok.gitlabclient.entity.Note
import ru.terrakok.gitlabclient.entity.OrderBy
import ru.terrakok.gitlabclient.entity.Project
import ru.terrakok.gitlabclient.entity.RepositoryTreeNode
import ru.terrakok.gitlabclient.entity.Sort
import ru.terrakok.gitlabclient.entity.TokenData
import ru.terrakok.gitlabclient.entity.User
import ru.terrakok.gitlabclient.entity.Visibility
import ru.terrakok.gitlabclient.entity.event.Event
import ru.terrakok.gitlabclient.entity.event.EventAction
import ru.terrakok.gitlabclient.entity.event.EventTarget
......@@ -18,7 +31,7 @@ import ru.terrakok.gitlabclient.entity.target.TargetType
import ru.terrakok.gitlabclient.entity.todo.Todo
import ru.terrakok.gitlabclient.entity.todo.TodoAction
import ru.terrakok.gitlabclient.entity.todo.TodoState
import java.util.*
import java.util.Date
/**
* @author Konstantin Tskhovrebov (aka terrakok). Date: 28.03.17
......@@ -91,6 +104,21 @@ interface GitlabApi {
@Query("per_page") pageSize: Int
): Single<List<Issue>>
@GET("$API_PATH/projects/{project_id}/issues")
fun getIssues(
@Path("project_id") projectId: Long,
@Query("scope") scope: IssueScope?,
@Query("state") state: IssueState?,
@Query("labels") labels: String?,
@Query("milestone") milestone: String?,
@Query("iids") iids: Array<Long>?,
@Query("order_by") orderBy: OrderBy?,
@Query("sort") sort: Sort?,
@Query("search") search: String?,
@Query("page") page: Int,
@Query("per_page") pageSize: Int
): Single<List<Issue>>
@GET("$API_PATH/projects/{project_id}/issues/{issue_id}")
fun getIssue(
@Path("project_id") projectId: Long,
......@@ -109,7 +137,7 @@ interface GitlabApi {
): Single<List<Event>>
@GET("$API_PATH/merge_requests")
fun getMergeRequests(
fun getMyMergeRequests(
@Query("state") state: MergeRequestState?,
@Query("milestone") milestone: String?,
@Query("view") viewType: MergeRequestViewType?,
......@@ -126,7 +154,8 @@ interface GitlabApi {
@Query("per_page") pageSize: Int
): Single<List<MergeRequest>>
fun getProjectMergeRequests(
@GET("$API_PATH/projects/{project_id}/merge_requests")
fun getMergeRequests(
@Path("project_id") projectId: Long,
@Query("state") state: MergeRequestState?,
@Query("milestone") milestone: String?,
......
......@@ -10,27 +10,41 @@ import javax.inject.Inject
* @author Konstantin Tskhovrebov (aka terrakok) on 15.06.17.
*/
class IssueInteractor @Inject constructor(
private val issueRepository: IssueRepository
private val issueRepository: IssueRepository
) {
fun getMyIssues(
createdByMe: Boolean,
onlyOpened: Boolean,
page: Int
createdByMe: Boolean,
onlyOpened: Boolean,
page: Int
) = issueRepository
.getMyIssues(
scope = if (createdByMe) IssueScope.CREATED_BY_ME else IssueScope.ASSIGNED_BY_ME,
state = if (onlyOpened) IssueState.OPENED else null,
orderBy = OrderBy.UPDATED_AT,
page = page
scope = if (createdByMe) IssueScope.CREATED_BY_ME else IssueScope.ASSIGNED_BY_ME,
state = if (onlyOpened) IssueState.OPENED else null,
orderBy = OrderBy.UPDATED_AT,
page = page
)
fun getIssues(
projectId: Long,
issueState: IssueState?,
page: Int
) = issueRepository
.getIssues(
projectId = projectId,
state = issueState,
scope = IssueScope.ALL,
orderBy = OrderBy.UPDATED_AT,
page = page
)
fun getIssue(
projectId: Long,
issueId: Long
projectId: Long,
issueId: Long
) = issueRepository.getIssue(projectId, issueId)
fun getIssueNotes(
projectId: Long,
issueId: Long
projectId: Long,
issueId: Long
) = issueRepository.getIssueNotes(projectId, issueId)
}
\ No newline at end of file
......@@ -6,7 +6,14 @@ import io.reactivex.functions.BiFunction
import ru.terrakok.gitlabclient.entity.OrderBy
import ru.terrakok.gitlabclient.entity.Project
import ru.terrakok.gitlabclient.entity.Sort
import ru.terrakok.gitlabclient.entity.app.target.*
import ru.terrakok.gitlabclient.entity.app.target.AppTarget
import ru.terrakok.gitlabclient.entity.app.target.TargetBadge
import ru.terrakok.gitlabclient.entity.app.target.TargetBadgeIcon
import ru.terrakok.gitlabclient.entity.app.target.TargetBadgeStatus
import ru.terrakok.gitlabclient.entity.app.target.TargetHeader
import ru.terrakok.gitlabclient.entity.app.target.TargetHeaderIcon
import ru.terrakok.gitlabclient.entity.app.target.TargetHeaderTitle
import ru.terrakok.gitlabclient.entity.app.target.TargetInternal
import ru.terrakok.gitlabclient.entity.event.EventAction
import ru.terrakok.gitlabclient.entity.issue.Issue
import ru.terrakok.gitlabclient.entity.issue.IssueScope
......@@ -52,6 +59,32 @@ class IssueRepository @Inject constructor(
.subscribeOn(schedulers.io())
.observeOn(schedulers.ui())
fun getIssues(
projectId: Long,
scope: IssueScope? = null,
state: IssueState? = null,
labels: String? = null,
milestone: String? = null,
iids: Array<Long>? = null,
orderBy: OrderBy? = null,
sort: Sort? = null,
search: String? = null,
page: Int,
pageSize: Int = defaultPageSize
) = api
.getIssues(projectId, scope, state, labels, milestone, iids, orderBy, sort, search, page, pageSize)
.flatMap { issues ->
Single.zip(
Single.just(issues),
getDistinctProjects(issues),
BiFunction<List<Issue>, Map<Long, Project>, List<TargetHeader>> { sourceIssues, projects ->
sourceIssues.map { getTargetHeader(it, projects[it.projectId]!!) }
}
)
}
.subscribeOn(schedulers.io())
.observeOn(schedulers.ui())
private fun getDistinctProjects(events: List<Issue>): Single<Map<Long, Project>> {
return Observable.fromIterable(events)
.distinct { it.projectId }
......@@ -61,7 +94,7 @@ class IssueRepository @Inject constructor(
private fun getTargetHeader(issue: Issue, project: Project): TargetHeader {
val badges = mutableListOf<TargetBadge>()
badges.add(TargetBadge.Status(when(issue.state) {
badges.add(TargetBadge.Status(when (issue.state) {
IssueState.OPENED -> TargetBadgeStatus.OPENED
IssueState.CLOSED -> TargetBadgeStatus.CLOSED
}))
......
package ru.terrakok.gitlabclient.presentation.project
package ru.terrakok.gitlabclient.presentation.project.info
import com.arellomobile.mvp.InjectViewState
import io.reactivex.Single
......@@ -16,11 +16,11 @@ import javax.inject.Inject
*/
@InjectViewState
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
@ProjectId private val projectIdWrapper: PrimitiveWrapper<Long>,
private val router: Router,
private val projectInteractor: ProjectInteractor,
private val mdConverter: MarkDownConverter,
private val errorHandler: ErrorHandler
) : BasePresenter<ProjectInfoView>() {
private val projectId = projectIdWrapper.value
......@@ -45,8 +45,8 @@ class ProjectInfoPresenter @Inject constructor(
.doOnSubscribe { viewState.showProgress(true) }
.doAfterTerminate { viewState.showProgress(false) }
.subscribe(
{ (project, mdReadme) -> viewState.showProject(project, mdReadme) },
{ errorHandler.proceed(it, { viewState.showMessage(it) }) }
{ (project, mdReadme) -> viewState.showProject(project, mdReadme) },
{ errorHandler.proceed(it, { viewState.showMessage(it) }) }
)
.connect()
}
......
package ru.terrakok.gitlabclient.presentation.project
package ru.terrakok.gitlabclient.presentation.project.info
import com.arellomobile.mvp.MvpView
import com.arellomobile.mvp.viewstate.strategy.AddToEndSingleStrategy
......@@ -11,6 +11,7 @@ import ru.terrakok.gitlabclient.entity.Project
*/
@StateStrategyType(AddToEndSingleStrategy::class)
interface ProjectInfoView : MvpView {
fun showProject(project: Project, mdReadme: CharSequence)
fun showProgress(show: Boolean)
......
package ru.terrakok.gitlabclient.presentation.project.issues
import com.arellomobile.mvp.InjectViewState
import ru.terrakok.gitlabclient.Screens
import ru.terrakok.gitlabclient.entity.app.target.TargetHeader
import ru.terrakok.gitlabclient.entity.issue.IssueState
import ru.terrakok.gitlabclient.extension.openInfo
import ru.terrakok.gitlabclient.model.interactor.issue.IssueInteractor
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.presentation.global.MarkDownConverter
import ru.terrakok.gitlabclient.presentation.global.Paginator
import ru.terrakok.gitlabclient.toothpick.PrimitiveWrapper
import ru.terrakok.gitlabclient.toothpick.qualifier.ProjectId
import javax.inject.Inject
/**
* @author Eugene Shapovalov (CraggyHaggy). Date: 27.08.18
*/
@InjectViewState
class ProjectIssuesPresenter @Inject constructor(
@ProjectId private val projectIdWrapper: PrimitiveWrapper<Long>,
private val issueState: IssueState,
private val issueInteractor: IssueInteractor,
private val mdConverter: MarkDownConverter,
private val errorHandler: ErrorHandler,
private val router: FlowRouter
) : BasePresenter<ProjectIssuesView>() {
private val projectId = projectIdWrapper.value
override fun onFirstViewAttach() {
super.onFirstViewAttach()
refreshIssues()
}
private val paginator = Paginator(
{
issueInteractor.getIssues(projectId, issueState, it)
.toObservable()
.flatMapIterable { it }
.flatMap { item ->
mdConverter.markdownToSpannable(item.body.toString())
.map { md -> item.copy(body = md) }
.toObservable()
}
.toList()
},
object : Paginator.ViewController<TargetHeader> {
override fun showEmptyProgress(show: Boolean) {
viewState.showEmptyProgress(show)
}
override fun showEmptyError(show: Boolean, error: Throwable?) {
if (error != null) {
errorHandler.proceed(error, { viewState.showEmptyError(show, it) })
} else {
viewState.showEmptyError(show, null)
}
}
override fun showErrorMessage(error: Throwable) {
errorHandler.proceed(error, { viewState.showMessage(it) })
}
override fun showEmptyView(show: Boolean) {
viewState.showEmptyView(show)
}
override fun showData(show: Boolean, data: List<TargetHeader>) {
viewState.showIssues(show, data)
}
override fun showRefreshProgress(show: Boolean) {
viewState.showRefreshProgress(show)
}
override fun showPageProgress(show: Boolean) {
viewState.showPageProgress(show)
}
}
)
fun onIssueClick(item: TargetHeader) = item.openInfo(router)
fun onUserClick(userId: Long) = router.startFlow(Screens.USER_FLOW, userId)
fun refreshIssues() = paginator.refresh()
fun loadNextIssuesPage() = paginator.loadNewPage()
override fun onDestroy() {
super.onDestroy()
paginator.release()
}
}
\ No newline at end of file
package ru.terrakok.gitlabclient.presentation.project.issues
import com.arellomobile.mvp.MvpView
import com.arellomobile.mvp.viewstate.strategy.OneExecutionStateStrategy
import com.arellomobile.mvp.viewstate.strategy.StateStrategyType
import ru.terrakok.gitlabclient.entity.app.target.TargetHeader
/**
* @author Eugene Shapovalov (CraggyHaggy). Date: 27.08.18
*/
@StateStrategyType(OneExecutionStateStrategy::class)
interface ProjectIssuesView : MvpView {
fun showRefreshProgress(show: Boolean)
fun showEmptyProgress(show: Boolean)
fun showPageProgress(show: Boolean)
fun showEmptyView(show: Boolean)
fun showEmptyError(show: Boolean, message: String?)
fun showIssues(show: Boolean, issues: List<TargetHeader>)
@StateStrategyType(OneExecutionStateStrategy::class)
fun showMessage(message: String)
}
\ No newline at end of file
package ru.terrakok.gitlabclient.ui.project
import android.os.Bundle
import android.util.TypedValue
import com.aurelhubert.ahbottomnavigation.AHBottomNavigationAdapter
import kotlinx.android.synthetic.main.fragment_project.*
import ru.terrakok.cicerone.Router
......@@ -9,7 +10,7 @@ import ru.terrakok.gitlabclient.extension.color
import ru.terrakok.gitlabclient.extension.shareText
import ru.terrakok.gitlabclient.toothpick.DI
import ru.terrakok.gitlabclient.ui.global.BaseFragment
import ru.terrakok.gitlabclient.ui.project.info.ProjectInfoFragment
import ru.terrakok.gitlabclient.ui.project.issues.ProjectIssuesContainerFragment
import toothpick.Toothpick
import javax.inject.Inject
......@@ -20,15 +21,16 @@ class ProjectFragment : BaseFragment(), ProjectInfoFragment.ToolbarConfigurator
override val layoutRes: Int = R.layout.fragment_project
@Inject lateinit var router: Router
@Inject
lateinit var router: Router
private var shareUrl: String? = null
private lateinit var tabs: HashMap<String, BaseFragment>
private val tabKeys = listOf(
tabIdToFragmentTag(R.id.tab_info),
tabIdToFragmentTag(R.id.tab_issue),
tabIdToFragmentTag(R.id.tab_merge_request)
tabIdToFragmentTag(R.id.tab_info),
tabIdToFragmentTag(R.id.tab_issue),
tabIdToFragmentTag(R.id.tab_merge_request)
)
private fun tabIdToFragmentTag(id: Int) = "tab_$id"
......@@ -57,7 +59,10 @@ class ProjectFragment : BaseFragment(), ProjectInfoFragment.ToolbarConfigurator
inactiveColor = context.color(R.color.silver)
setOnTabSelectedListener { position, wasSelected ->
if (!wasSelected) showTab(position, currentItem)
if (!wasSelected) {
setToolbarElevation(position)
showTab(position, currentItem)
}
true
}
}
......@@ -66,8 +71,11 @@ class ProjectFragment : BaseFragment(), ProjectInfoFragment.ToolbarConfigurator
tabs = createNewFragments()
childFragmentManager.beginTransaction()
.add(R.id.container, tabs[tabKeys[0]], tabKeys[0])
.add(R.id.container, tabs[tabKeys[1]], tabKeys[1])
.hide(tabs[tabKeys[1]])
.commitNow()
bottomBar.setCurrentItem(0, false)
setToolbarElevation(0)
} else {
tabs = findFragments()
}
......@@ -81,13 +89,27 @@ class ProjectFragment : BaseFragment(), ProjectInfoFragment.ToolbarConfigurator
}
private fun createNewFragments(): HashMap<String, BaseFragment> = hashMapOf(
tabKeys[0] to ProjectInfoFragment()
tabKeys[0] to ProjectInfoFragment(),
tabKeys[1] to ProjectIssuesContainerFragment()
)
private fun findFragments(): HashMap<String, BaseFragment> = hashMapOf(
tabKeys[0] to childFragmentManager.findFragmentByTag(tabKeys[0]) as BaseFragment
tabKeys[0] to childFragmentManager.findFragmentByTag(tabKeys[0]) as BaseFragment,
tabKeys[1] to childFragmentManager.findFragmentByTag(tabKeys[1]) as BaseFragment
)
private fun setToolbarElevation(tabItem: Int) {
if (tabItem == 0) {
toolbar.elevation = TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
8f,
resources.displayMetrics
)
} else {
toolbar.elevation = 0f
}
}
override fun setTitle(title: String) {
toolbar.title = title
}
......
package ru.terrakok.gitlabclient.ui.project.info
package ru.terrakok.gitlabclient.ui.project
import com.arellomobile.mvp.presenter.InjectPresenter
import com.arellomobile.mvp.presenter.ProvidePresenter
......@@ -9,8 +9,8 @@ import ru.terrakok.gitlabclient.entity.Project
import ru.terrakok.gitlabclient.entity.Visibility
import ru.terrakok.gitlabclient.extension.loadRoundedImage
import ru.terrakok.gitlabclient.extension.visible
import ru.terrakok.gitlabclient.presentation.project.ProjectInfoPresenter
import ru.terrakok.gitlabclient.presentation.project.ProjectInfoView
import ru.terrakok.gitlabclient.presentation.project.info.ProjectInfoPresenter
import ru.terrakok.gitlabclient.presentation.project.info.ProjectInfoView
import ru.terrakok.gitlabclient.toothpick.DI
import ru.terrakok.gitlabclient.ui.global.BaseFragment
import toothpick.Toothpick
......@@ -22,7 +22,8 @@ class ProjectInfoFragment : BaseFragment(), ProjectInfoView {
override val layoutRes = R.layout.fragment_project_info
@InjectPresenter lateinit var presenter: ProjectInfoPresenter
@InjectPresenter
lateinit var presenter: ProjectInfoPresenter
@ProvidePresenter
fun providePresenter(): ProjectInfoPresenter =
......@@ -31,7 +32,7 @@ class ProjectInfoFragment : BaseFragment(), ProjectInfoView {
.getInstance(ProjectInfoPresenter::class.java)
override fun showProject(project: Project, mdReadme: CharSequence) {
(parentFragment as? ProjectInfoFragment.ToolbarConfigurator)?.apply {
(parentFragment as? ToolbarConfigurator)?.apply {
setTitle(project.name)
setShareUrl(project.webUrl)
}
......@@ -42,11 +43,13 @@ class ProjectInfoFragment : BaseFragment(), ProjectInfoView {
avatarImageView.loadRoundedImage(project.avatarUrl, context)
iconImageView.setBackgroundResource(R.drawable.circle)
iconImageView.setImageResource(when (project.visibility) {
Visibility.PRIVATE -> R.drawable.ic_lock_white_18dp
Visibility.INTERNAL -> R.drawable.ic_security_white_24dp
else -> R.drawable.ic_globe_18dp
})
iconImageView.setImageResource(
when (project.visibility) {
Visibility.PRIVATE -> R.drawable.ic_lock_white_18dp
Visibility.INTERNAL -> R.drawable.ic_security_white_24dp
else -> R.drawable.ic_globe_18dp
}
)
Markwon.setText(readmeTextView, mdReadme)
}
......
package ru.terrakok.gitlabclient.ui.project.issues
import android.os.Bundle
import android.support.v4.app.FragmentPagerAdapter
import kotlinx.android.synthetic.main.fragment_my_issues_container.*
import ru.terrakok.gitlabclient.R
import ru.terrakok.gitlabclient.entity.issue.IssueState
import ru.terrakok.gitlabclient.ui.global.BaseFragment
/**
* @author Eugene Shapovalov (CraggyHaggy). Date: 27.08.18
*/
class ProjectIssuesContainerFragment : BaseFragment() {
override val layoutRes = R.layout.fragment_project_issues_container
private val adapter: ProjectIssuesPagesAdapter by lazy { ProjectIssuesPagesAdapter() }
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
viewPager.adapter = adapter
}
private inner class ProjectIssuesPagesAdapter : FragmentPagerAdapter(childFragmentManager) {
override fun getItem(position: Int) = when (position) {
0 -> ProjectIssuesFragment.newInstance(IssueState.OPENED)
1 -> ProjectIssuesFragment.newInstance(IssueState.CLOSED)
else -> null
}
override fun getCount() = 2
override fun getPageTitle(position: Int) = when (position) {
0 -> getString(R.string.target_status_opened)
1 -> getString(R.string.target_status_closed)
else -> null
}
}
}
\ No newline at end of file
package ru.terrakok.gitlabclient.ui.project.issues
import android.os.Bundle
import android.support.v7.widget.LinearLayoutManager
import com.arellomobile.mvp.presenter.InjectPresenter
import com.arellomobile.mvp.presenter.ProvidePresenter
import kotlinx.android.synthetic.main.layout_base_list.*
import kotlinx.android.synthetic.main.layout_zero.*
import ru.terrakok.gitlabclient.R
import ru.terrakok.gitlabclient.entity.app.target.TargetHeader
import ru.terrakok.gitlabclient.entity.issue.IssueState
import ru.terrakok.gitlabclient.extension.getEnum
import ru.terrakok.gitlabclient.extension.putEnum
import ru.terrakok.gitlabclient.extension.visible
import ru.terrakok.gitlabclient.presentation.project.issues.ProjectIssuesPresenter
import ru.terrakok.gitlabclient.presentation.project.issues.ProjectIssuesView
import ru.terrakok.gitlabclient.toothpick.DI
import ru.terrakok.gitlabclient.ui.global.BaseFragment
import ru.terrakok.gitlabclient.ui.global.ZeroViewHolder
import ru.terrakok.gitlabclient.ui.my.TargetsAdapter
import ru.terrakok.gitlabclient.ui.my.issues.MyIssuesFragment
import toothpick.Toothpick
import toothpick.config.Module
/**
* @author Eugene Shapovalov (CraggyHaggy). Date: 27.08.18
*/
class ProjectIssuesFragment : BaseFragment(), ProjectIssuesView {
override val layoutRes = R.layout.fragment_project_issues
@InjectPresenter
lateinit var presenter: ProjectIssuesPresenter
@ProvidePresenter
fun providePresenter(): ProjectIssuesPresenter {
val scopeName = "ProjectIssuesScope_${hashCode()}"
val scope = Toothpick.openScopes(DI.PROJECT_SCOPE, scopeName)
scope.installModules(object : Module() {
init {
bind(IssueState::class.java)
.toInstance(arguments?.getEnum<IssueState>(ARG_ISSUE_STATE))
}
})
return scope.getInstance(ProjectIssuesPresenter::class.java).also {
Toothpick.closeScope(scopeName)
}
}
private val adapter: TargetsAdapter by lazy {
TargetsAdapter(
{ presenter.onUserClick(it) },
{ presenter.onIssueClick(it) },
{ presenter.loadNextIssuesPage() }
)
}
private var zeroViewHolder: ZeroViewHolder? = null
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
recyclerView.apply {
layoutManager = LinearLayoutManager(context)
setHasFixedSize(true)
adapter = this@ProjectIssuesFragment.adapter
}
swipeToRefresh.setOnRefreshListener { presenter.refreshIssues() }
zeroViewHolder = ZeroViewHolder(zeroLayout, { presenter.refreshIssues() })
}
override fun showRefreshProgress(show: Boolean) {
swipeToRefresh.post { swipeToRefresh.isRefreshing = show }
}
override fun showEmptyProgress(show: Boolean) {
fullscreenProgressView.visible(show)
//trick for disable and hide swipeToRefresh on fullscreen progress
swipeToRefresh.visible(!show)
swipeToRefresh.post { swipeToRefresh.isRefreshing = false }
}
override fun showPageProgress(show: Boolean) {
recyclerView.post { adapter.showProgress(show) }
}
override fun showEmptyView(show: Boolean) {
if (show) zeroViewHolder?.showEmptyData()
else zeroViewHolder?.hide()
}
override fun showEmptyError(show: Boolean, message: String?) {
if (show) zeroViewHolder?.showEmptyError(message)
else zeroViewHolder?.hide()
}
override fun showIssues(show: Boolean, issues: List<TargetHeader>) {
recyclerView.visible(show)
recyclerView.post { adapter.setData(issues) }
}
override fun showMessage(message: String) {
showSnackMessage(message)
}
companion object {