Skip to content
Snippets Groups Projects
Commit 418af0b9 authored by Jawnnypoo's avatar Jawnnypoo
Browse files

Reverse the notes on the issue

parent dd71bf11
No related branches found
No related tags found
No related merge requests found
Showing
with 382 additions and 497 deletions
Loading
@@ -98,9 +98,9 @@ android {
Loading
@@ -98,9 +98,9 @@ android {
} }
   
ext { ext {
supportLibVersion = '26.0.1' supportLibVersion = '26.0.2'
retrofitVersion = '2.3.0' retrofitVersion = '2.3.0'
okHttpVersion = '3.8.1' okHttpVersion = '3.9.0'
butterknifeVersion = '8.8.1' butterknifeVersion = '8.8.1'
parcelerVersion = '1.1.9' parcelerVersion = '1.1.9'
reptarVersion = '2.5.1' reptarVersion = '2.5.1'
Loading
@@ -190,7 +190,7 @@ dependencies {
Loading
@@ -190,7 +190,7 @@ dependencies {
   
implementation 'com.github.chrisbanes:PhotoView:2.1.3' implementation 'com.github.chrisbanes:PhotoView:2.1.3'
   
implementation 'me.zhanghai.android.materialprogressbar:library:1.4.1' implementation 'me.zhanghai.android.materialprogressbar:library:1.4.2'
   
implementation 'com.github.Jawnnypoo:PhysicsLayout:2.1.0' implementation 'com.github.Jawnnypoo:PhysicsLayout:2.1.0'
   
Loading
@@ -213,7 +213,7 @@ dependencies {
Loading
@@ -213,7 +213,7 @@ dependencies {
exclude group: 'org.json', module: 'json' exclude group: 'org.json', module: 'json'
} }
   
implementation 'com.github.jkwiecien:EasyImage:2.0.2' implementation 'com.github.jkwiecien:EasyImage:2.0.3'
   
implementation 'com.atlassian.commonmark:commonmark:0.9.0' implementation 'com.atlassian.commonmark:commonmark:0.9.0'
   
Loading
@@ -230,7 +230,7 @@ dependencies {
Loading
@@ -230,7 +230,7 @@ dependencies {
exclude group: 'com.jakewharton.threetenabp', module: 'threetenabp' exclude group: 'com.jakewharton.threetenabp', module: 'threetenabp'
} }
   
androidTestImplementation ('com.android.support.test:runner:1.0.0') { androidTestImplementation ('com.android.support.test:runner:1.0.1') {
exclude group:'com.android.support', module:'support-annotations' exclude group:'com.android.support', module:'support-annotations'
} }
} }
package com.commit451.gitlab.activity package com.commit451.gitlab.activity
   
import android.app.Activity
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.net.Uri
import android.os.Bundle import android.os.Bundle
import android.support.design.widget.Snackbar import android.support.design.widget.Snackbar
import android.support.v4.widget.SwipeRefreshLayout import android.support.design.widget.TabLayout
import android.support.v7.widget.LinearLayoutManager import android.support.v4.view.ViewPager
import android.support.v7.widget.RecyclerView
import android.support.v7.widget.Toolbar import android.support.v7.widget.Toolbar
import android.view.MenuItem import android.view.MenuItem
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.TextView
import android.widget.Toast import android.widget.Toast
import butterknife.BindView import butterknife.BindView
import butterknife.ButterKnife import butterknife.ButterKnife
Loading
@@ -22,28 +18,20 @@ import com.commit451.addendum.parceler.getParcelerParcelableExtra
Loading
@@ -22,28 +18,20 @@ import com.commit451.addendum.parceler.getParcelerParcelableExtra
import com.commit451.addendum.parceler.putParcelerParcelableExtra import com.commit451.addendum.parceler.putParcelerParcelableExtra
import com.commit451.gitlab.App import com.commit451.gitlab.App
import com.commit451.gitlab.R import com.commit451.gitlab.R
import com.commit451.gitlab.adapter.IssueDetailsAdapter import com.commit451.gitlab.adapter.IssuePagerAdapter
import com.commit451.gitlab.api.response.FileUploadResponse
import com.commit451.gitlab.event.IssueChangedEvent import com.commit451.gitlab.event.IssueChangedEvent
import com.commit451.gitlab.event.IssueReloadEvent import com.commit451.gitlab.event.IssueReloadEvent
import com.commit451.gitlab.extension.getUrl import com.commit451.gitlab.extension.getUrl
import com.commit451.gitlab.extension.setup import com.commit451.gitlab.extension.setup
import com.commit451.gitlab.model.api.Issue import com.commit451.gitlab.model.api.Issue
import com.commit451.gitlab.model.api.Note
import com.commit451.gitlab.model.api.Project import com.commit451.gitlab.model.api.Project
import com.commit451.gitlab.navigation.Navigator import com.commit451.gitlab.navigation.Navigator
import com.commit451.gitlab.rx.CustomCompleteObserver import com.commit451.gitlab.rx.CustomCompleteObserver
import com.commit451.gitlab.rx.CustomResponseSingleObserver
import com.commit451.gitlab.rx.CustomSingleObserver import com.commit451.gitlab.rx.CustomSingleObserver
import com.commit451.gitlab.util.IntentUtil import com.commit451.gitlab.util.IntentUtil
import com.commit451.gitlab.util.LinkHeaderParser
import com.commit451.gitlab.view.SendMessageView
import com.commit451.teleprinter.Teleprinter import com.commit451.teleprinter.Teleprinter
import io.reactivex.Single import io.reactivex.Single
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import org.greenrobot.eventbus.Subscribe import org.greenrobot.eventbus.Subscribe
import retrofit2.Response
import timber.log.Timber import timber.log.Timber
   
/** /**
Loading
@@ -55,11 +43,6 @@ class IssueActivity : BaseActivity() {
Loading
@@ -55,11 +43,6 @@ class IssueActivity : BaseActivity() {
   
private val EXTRA_PROJECT = "extra_project" private val EXTRA_PROJECT = "extra_project"
private val EXTRA_SELECTED_ISSUE = "extra_selected_issue" private val EXTRA_SELECTED_ISSUE = "extra_selected_issue"
private val EXTRA_PROJECT_NAMESPACE = "project_namespace"
private val EXTRA_PROJECT_NAME = "project_name"
private val EXTRA_ISSUE_IID = "extra_issue_iid"
private val REQUEST_ATTACH = 1
   
fun newIntent(context: Context, project: Project, issue: Issue): Intent { fun newIntent(context: Context, project: Project, issue: Issue): Intent {
val intent = Intent(context, IssueActivity::class.java) val intent = Intent(context, IssueActivity::class.java)
Loading
@@ -67,53 +50,24 @@ class IssueActivity : BaseActivity() {
Loading
@@ -67,53 +50,24 @@ class IssueActivity : BaseActivity() {
intent.putParcelerParcelableExtra(EXTRA_SELECTED_ISSUE, issue) intent.putParcelerParcelableExtra(EXTRA_SELECTED_ISSUE, issue)
return intent return intent
} }
fun newIntent(context: Context, namespace: String, projectName: String, issueIid: String): Intent {
val intent = Intent(context, IssueActivity::class.java)
intent.putExtra(EXTRA_PROJECT_NAMESPACE, namespace)
intent.putExtra(EXTRA_PROJECT_NAME, projectName)
intent.putExtra(EXTRA_ISSUE_IID, issueIid)
return intent
}
} }
   
@BindView(R.id.root) lateinit var root: ViewGroup @BindView(R.id.root) lateinit var root: ViewGroup
@BindView(R.id.toolbar) lateinit var toolbar: Toolbar @BindView(R.id.toolbar) lateinit var toolbar: Toolbar
@BindView(R.id.issue_title) lateinit var textTitle: TextView @BindView(R.id.tabs) lateinit var tabLayout: TabLayout
@BindView(R.id.swipe_layout) lateinit var swipeRefreshLayout: SwipeRefreshLayout @BindView(R.id.pager) lateinit var viewPager: ViewPager
@BindView(R.id.list) lateinit var listNotes: RecyclerView
@BindView(R.id.send_message_view) lateinit var sendMessageView: SendMessageView
@BindView(R.id.progress) lateinit var progress: View @BindView(R.id.progress) lateinit var progress: View
@BindView(R.id.toolbar_title) lateinit var toolbarTitle: TextView
@BindView(R.id.toolbar_subtitle) lateinit var toolbarSubTitle: TextView
   
lateinit var menuItemOpenClose: MenuItem lateinit var menuItemOpenClose: MenuItem
lateinit var adapterIssueDetails: IssueDetailsAdapter
lateinit var layoutManagerNotes: LinearLayoutManager
lateinit var teleprinter: Teleprinter lateinit var teleprinter: Teleprinter
   
var project: Project? = null lateinit var project: Project
var issue: Issue? = null lateinit var issue: Issue
var issueIid: String? = null
var loading: Boolean = false
var nextPageUrl: Uri? = null
val onScrollListener = object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView?, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
val visibleItemCount = layoutManagerNotes.childCount
val totalItemCount = layoutManagerNotes.itemCount
val firstVisibleItem = layoutManagerNotes.findFirstVisibleItemPosition()
if (firstVisibleItem + visibleItemCount >= totalItemCount && !loading && nextPageUrl != null) {
loadMoreNotes()
}
}
}
   
val onMenuItemClickListener = Toolbar.OnMenuItemClickListener { item -> val onMenuItemClickListener = Toolbar.OnMenuItemClickListener { item ->
when (item.itemId) { when (item.itemId) {
R.id.action_share -> { R.id.action_share -> {
IntentUtil.share(root, issue!!.getUrl(project!!)) IntentUtil.share(root, issue.getUrl(project))
return@OnMenuItemClickListener true return@OnMenuItemClickListener true
} }
R.id.action_close -> { R.id.action_close -> {
Loading
@@ -121,7 +75,7 @@ class IssueActivity : BaseActivity() {
Loading
@@ -121,7 +75,7 @@ class IssueActivity : BaseActivity() {
return@OnMenuItemClickListener true return@OnMenuItemClickListener true
} }
R.id.action_delete -> { R.id.action_delete -> {
App.get().gitLab.deleteIssue(project!!.id, issue!!.iid) App.get().gitLab.deleteIssue(project.id, issue.iid)
.setup(bindToLifecycle()) .setup(bindToLifecycle())
.subscribe(object : CustomCompleteObserver() { .subscribe(object : CustomCompleteObserver() {
   
Loading
@@ -148,9 +102,7 @@ class IssueActivity : BaseActivity() {
Loading
@@ -148,9 +102,7 @@ class IssueActivity : BaseActivity() {
fun onEditIssueClick() { fun onEditIssueClick() {
val project = project val project = project
val issue = issue val issue = issue
if (project != null && issue != null) { Navigator.navigateToEditIssue(this@IssueActivity, project, issue)
Navigator.navigateToEditIssue(this@IssueActivity, project, issue)
}
} }
   
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
Loading
@@ -160,6 +112,9 @@ class IssueActivity : BaseActivity() {
Loading
@@ -160,6 +112,9 @@ class IssueActivity : BaseActivity() {
teleprinter = Teleprinter(this) teleprinter = Teleprinter(this)
App.bus().register(this) App.bus().register(this)
   
project = intent.getParcelerParcelableExtra<Project>(EXTRA_PROJECT)!!
issue = intent.getParcelerParcelableExtra<Issue>(EXTRA_SELECTED_ISSUE)!!
toolbar.setNavigationIcon(R.drawable.ic_back_24dp) toolbar.setNavigationIcon(R.drawable.ic_back_24dp)
toolbar.setNavigationOnClickListener { onBackPressed() } toolbar.setNavigationOnClickListener { onBackPressed() }
toolbar.inflateMenu(R.menu.share) toolbar.inflateMenu(R.menu.share)
Loading
@@ -168,83 +123,15 @@ class IssueActivity : BaseActivity() {
Loading
@@ -168,83 +123,15 @@ class IssueActivity : BaseActivity() {
menuItemOpenClose = toolbar.menu.findItem(R.id.action_close) menuItemOpenClose = toolbar.menu.findItem(R.id.action_close)
toolbar.setOnMenuItemClickListener(onMenuItemClickListener) toolbar.setOnMenuItemClickListener(onMenuItemClickListener)
   
layoutManagerNotes = LinearLayoutManager(this) val sectionsPagerAdapter = IssuePagerAdapter(
listNotes.layoutManager = layoutManagerNotes this,
listNotes.addOnScrollListener(onScrollListener) supportFragmentManager,
project,
sendMessageView.callback = object : SendMessageView.Callback { issue)
override fun onSendClicked(message: String) {
postNote(message)
}
override fun onAttachmentClicked() {
Navigator.navigateToAttach(this@IssueActivity, project!!, REQUEST_ATTACH)
}
}
swipeRefreshLayout.setOnRefreshListener { loadNotes() }
   
if (intent.hasExtra(EXTRA_SELECTED_ISSUE)) { viewPager.adapter = sectionsPagerAdapter
project = intent.getParcelerParcelableExtra<Project>(EXTRA_PROJECT) tabLayout.setupWithViewPager(viewPager)
issue = intent.getParcelerParcelableExtra<Issue>(EXTRA_SELECTED_ISSUE) bindIssue()
adapterIssueDetails = IssueDetailsAdapter(issue, project!!)
listNotes.adapter = adapterIssueDetails
bindIssue()
bindProject()
loadNotes()
} else if (intent.hasExtra(EXTRA_ISSUE_IID)) {
issueIid = intent.getStringExtra(EXTRA_ISSUE_IID)
val projectNamespace = intent.getStringExtra(EXTRA_PROJECT_NAMESPACE)
val projectName = intent.getStringExtra(EXTRA_PROJECT_NAME)
swipeRefreshLayout.isRefreshing = true
App.get().gitLab.getProject(projectNamespace, projectName)
.flatMap { project ->
this@IssueActivity.project = project
App.get().gitLab.getIssuesByIid(project.id)
}
.compose(this.bindToLifecycle<List<Issue>>())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : CustomSingleObserver<List<Issue>>() {
override fun error(t: Throwable) {
Timber.e(t)
swipeRefreshLayout.isRefreshing = false
Snackbar.make(root, getString(R.string.failed_to_load), Snackbar.LENGTH_SHORT)
.show()
}
override fun success(issues: List<Issue>) {
if (issues.isEmpty()) {
swipeRefreshLayout.isRefreshing = false
Snackbar.make(root, getString(R.string.failed_to_load), Snackbar.LENGTH_SHORT)
.show()
} else {
issue = issues[0]
adapterIssueDetails = IssueDetailsAdapter(issue, project!!)
listNotes.adapter = adapterIssueDetails
bindIssue()
bindProject()
loadNotes()
}
}
})
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
when (requestCode) {
REQUEST_ATTACH ->
if (resultCode == Activity.RESULT_OK) {
val response = data?.getParcelerParcelableExtra<FileUploadResponse>(AttachActivity.KEY_FILE_UPLOAD_RESPONSE)!!
progress.visibility = View.GONE
sendMessageView.appendText(response.markdown)
} else {
Snackbar.make(root, R.string.failed_to_upload_file, Snackbar.LENGTH_LONG)
.show()
}
}
} }
   
override fun onDestroy() { override fun onDestroy() {
Loading
@@ -252,108 +139,18 @@ class IssueActivity : BaseActivity() {
Loading
@@ -252,108 +139,18 @@ class IssueActivity : BaseActivity() {
super.onDestroy() super.onDestroy()
} }
   
fun bindProject() {
toolbarSubTitle.text = project?.nameWithNamespace
}
fun bindIssue() { fun bindIssue() {
setOpenCloseMenuStatus() setOpenCloseMenuStatus()
textTitle.text = issue?.title toolbar.title = getString(R.string.issue_number, issue?.iid)
toolbarTitle.text = getString(R.string.issue_number, issue?.iid) toolbar.subtitle = project.nameWithNamespace
if (issue?.isConfidential!!) {
toolbarTitle.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_visibility_off_white_24dp, 0)
}
adapterIssueDetails.updateIssue(issue!!)
}
fun loadNotes() {
swipeRefreshLayout.isRefreshing = true
loading = true
App.get().gitLab.getIssueNotes(project!!.id, issue!!.iid)
.compose(this.bindToLifecycle<Response<List<Note>>>())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : CustomResponseSingleObserver<List<Note>>() {
override fun error(t: Throwable) {
loading = false
Timber.e(t)
swipeRefreshLayout.isRefreshing = false
Snackbar.make(root, getString(R.string.connection_error), Snackbar.LENGTH_SHORT)
.show()
}
override fun responseNonNullSuccess(notes: List<Note>) {
loading = false
swipeRefreshLayout.isRefreshing = false
nextPageUrl = LinkHeaderParser.parse(response()).next
adapterIssueDetails.setNotes(notes)
}
})
}
fun loadMoreNotes() {
loading = true
adapterIssueDetails.setLoading(true)
App.get().gitLab.getIssueNotes(nextPageUrl!!.toString())
.compose(this.bindToLifecycle<Response<List<Note>>>())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : CustomResponseSingleObserver<List<Note>>() {
override fun error(t: Throwable) {
loading = false
Timber.e(t)
adapterIssueDetails.setLoading(false)
}
override fun responseNonNullSuccess(notes: List<Note>) {
loading = false
adapterIssueDetails.setLoading(false)
nextPageUrl = LinkHeaderParser.parse(response()).next
adapterIssueDetails.addNotes(notes)
}
})
}
fun postNote(message: String) {
if (message.isEmpty()) {
return
}
progress.visibility = View.VISIBLE
progress.alpha = 0.0f
progress.animate().alpha(1.0f)
// Clear text & collapse keyboard
teleprinter.hideKeyboard()
sendMessageView.clearText()
App.get().gitLab.addIssueNote(project!!.id, issue!!.iid, message)
.setup(bindToLifecycle())
.subscribe(object : CustomSingleObserver<Note>() {
override fun error(t: Throwable) {
Timber.e(t)
progress.visibility = View.GONE
Snackbar.make(root, getString(R.string.connection_error), Snackbar.LENGTH_SHORT)
.show()
}
override fun success(note: Note) {
progress.visibility = View.GONE
adapterIssueDetails.addNote(note)
listNotes.smoothScrollToPosition(IssueDetailsAdapter.headerCount)
}
})
} }
   
fun closeOrOpenIssue() { fun closeOrOpenIssue() {
progress.visibility = View.VISIBLE progress.visibility = View.VISIBLE
if (issue!!.state == Issue.STATE_CLOSED) { if (issue.state == Issue.STATE_CLOSED) {
updateIssueStatus(App.get().gitLab.updateIssueStatus(project!!.id, issue!!.iid, Issue.STATE_REOPEN)) updateIssueStatus(App.get().gitLab.updateIssueStatus(project.id, issue.iid, Issue.STATE_REOPEN))
} else { } else {
updateIssueStatus(App.get().gitLab.updateIssueStatus(project!!.id, issue!!.iid, Issue.STATE_CLOSE)) updateIssueStatus(App.get().gitLab.updateIssueStatus(project.id, issue.iid, Issue.STATE_CLOSE))
} }
} }
   
Loading
@@ -375,21 +172,19 @@ class IssueActivity : BaseActivity() {
Loading
@@ -375,21 +172,19 @@ class IssueActivity : BaseActivity() {
App.bus().post(IssueChangedEvent(this@IssueActivity.issue!!)) App.bus().post(IssueChangedEvent(this@IssueActivity.issue!!))
App.bus().post(IssueReloadEvent()) App.bus().post(IssueReloadEvent())
setOpenCloseMenuStatus() setOpenCloseMenuStatus()
loadNotes()
} }
}) })
} }
   
fun setOpenCloseMenuStatus() { fun setOpenCloseMenuStatus() {
menuItemOpenClose.setTitle(if (issue!!.state == Issue.STATE_CLOSED) R.string.reopen else R.string.close) menuItemOpenClose.setTitle(if (issue.state == Issue.STATE_CLOSED) R.string.reopen else R.string.close)
} }
   
@Subscribe @Subscribe
fun onEvent(event: IssueChangedEvent) { fun onEvent(event: IssueChangedEvent) {
if (issue!!.id == event.issue.id) { if (issue.id == event.issue.id) {
issue = event.issue issue = event.issue
bindIssue() bindIssue()
loadNotes()
} }
} }
} }
Loading
@@ -31,11 +31,13 @@ class LoadSomeInfoActivity : BaseActivity() {
Loading
@@ -31,11 +31,13 @@ class LoadSomeInfoActivity : BaseActivity() {
private val EXTRA_MERGE_REQUEST = "merge_request" private val EXTRA_MERGE_REQUEST = "merge_request"
private val EXTRA_BUILD_ID = "build_id" private val EXTRA_BUILD_ID = "build_id"
private val EXTRA_MILESTONE_ID = "milestone_id" private val EXTRA_MILESTONE_ID = "milestone_id"
private val EXTRA_ISSUE_ID = "issue_id"
   
private val LOAD_TYPE_DIFF = 0 private val LOAD_TYPE_DIFF = 0
private val LOAD_TYPE_MERGE_REQUEST = 1 private val LOAD_TYPE_MERGE_REQUEST = 1
private val LOAD_TYPE_BUILD = 2 private val LOAD_TYPE_BUILD = 2
private val LOAD_TYPE_MILESTONE = 3 private val LOAD_TYPE_MILESTONE = 3
private val LOAD_TYPE_ISSUE = 4
   
fun newIntent(context: Context, namespace: String, projectName: String, commitSha: String): Intent { fun newIntent(context: Context, namespace: String, projectName: String, commitSha: String): Intent {
val intent = Intent(context, LoadSomeInfoActivity::class.java) val intent = Intent(context, LoadSomeInfoActivity::class.java)
Loading
@@ -46,6 +48,15 @@ class LoadSomeInfoActivity : BaseActivity() {
Loading
@@ -46,6 +48,15 @@ class LoadSomeInfoActivity : BaseActivity() {
return intent return intent
} }
   
fun newIssueIntent(context: Context, namespace: String, projectName: String, issueId: String): Intent {
val intent = Intent(context, LoadSomeInfoActivity::class.java)
intent.putExtra(EXTRA_PROJECT_NAMESPACE, namespace)
intent.putExtra(EXTRA_PROJECT_NAME, projectName)
intent.putExtra(EXTRA_ISSUE_ID, issueId)
intent.putExtra(EXTRA_LOAD_TYPE, LOAD_TYPE_ISSUE)
return intent
}
fun newMergeRequestIntent(context: Context, namespace: String, projectName: String, mergeRequestId: String): Intent { fun newMergeRequestIntent(context: Context, namespace: String, projectName: String, mergeRequestId: String): Intent {
val intent = Intent(context, LoadSomeInfoActivity::class.java) val intent = Intent(context, LoadSomeInfoActivity::class.java)
intent.putExtra(EXTRA_PROJECT_NAMESPACE, namespace) intent.putExtra(EXTRA_PROJECT_NAMESPACE, namespace)
Loading
@@ -94,7 +105,7 @@ class LoadSomeInfoActivity : BaseActivity() {
Loading
@@ -94,7 +105,7 @@ class LoadSomeInfoActivity : BaseActivity() {
Timber.d("Loading some info type: %d", loadType) Timber.d("Loading some info type: %d", loadType)
   
when (loadType) { when (loadType) {
LOAD_TYPE_DIFF, LOAD_TYPE_MERGE_REQUEST, LOAD_TYPE_BUILD, LOAD_TYPE_MILESTONE -> { LOAD_TYPE_DIFF, LOAD_TYPE_MERGE_REQUEST, LOAD_TYPE_BUILD, LOAD_TYPE_MILESTONE, LOAD_TYPE_ISSUE -> {
val namespace = intent.getStringExtra(EXTRA_PROJECT_NAMESPACE) val namespace = intent.getStringExtra(EXTRA_PROJECT_NAMESPACE)
val project = intent.getStringExtra(EXTRA_PROJECT_NAME) val project = intent.getStringExtra(EXTRA_PROJECT_NAME)
App.get().gitLab.getProject(namespace, project) App.get().gitLab.getProject(namespace, project)
Loading
@@ -122,6 +133,24 @@ class LoadSomeInfoActivity : BaseActivity() {
Loading
@@ -122,6 +133,24 @@ class LoadSomeInfoActivity : BaseActivity() {
fun loadNextPart(response: Project) { fun loadNextPart(response: Project) {
project = response project = response
when (loadType) { when (loadType) {
LOAD_TYPE_ISSUE -> {
val issueId = intent.getStringExtra(EXTRA_ISSUE_ID)
App.get().gitLab.getIssue(response.id, issueId)
.setup(bindToLifecycle())
.subscribe(object : CustomSingleObserver<Issue>() {
override fun error(t: Throwable) {
Timber.e(t)
this@LoadSomeInfoActivity.onError()
}
override fun success(issue: Issue) {
Navigator.navigateToIssue(this@LoadSomeInfoActivity, project!!, issue)
finish()
}
})
return
}
LOAD_TYPE_DIFF -> { LOAD_TYPE_DIFF -> {
val sha = intent.getStringExtra(EXTRA_COMMIT_SHA) val sha = intent.getStringExtra(EXTRA_COMMIT_SHA)
App.get().gitLab.getCommit(response.id, sha) App.get().gitLab.getCommit(response.id, sha)
Loading
Loading
Loading
@@ -26,7 +26,8 @@ class RoutingActivity : BaseActivity() {
Loading
@@ -26,7 +26,8 @@ class RoutingActivity : BaseActivity() {
val navigator = object : RoutingNavigator { val navigator = object : RoutingNavigator {
override fun onRouteToIssue(projectNamespace: String, projectName: String, issueIid: String) { override fun onRouteToIssue(projectNamespace: String, projectName: String, issueIid: String) {
Timber.d("Routing to issue") Timber.d("Routing to issue")
Navigator.navigateToIssue(this@RoutingActivity, projectNamespace, projectName, issueIid) startActivity(LoadSomeInfoActivity.newIssueIntent(this@RoutingActivity, projectNamespace, projectName, issueIid))
overridePendingTransition(R.anim.fade_in, R.anim.do_nothing)
} }
   
override fun onRouteToCommit(projectNamespace: String, projectName: String, commitSha: String) { override fun onRouteToCommit(projectNamespace: String, projectName: String, commitSha: String) {
Loading
Loading
Loading
@@ -32,7 +32,7 @@ class IssueLabelsAdapter(private val listener: IssueLabelsAdapter.Listener) : Re
Loading
@@ -32,7 +32,7 @@ class IssueLabelsAdapter(private val listener: IssueLabelsAdapter.Listener) : Re
return values.size return values.size
} }
   
fun setLabels(labels: Collection<String>) { fun setLabels(labels: Collection<String>?) {
values.clear() values.clear()
addLabels(labels) addLabels(labels)
} }
Loading
Loading
Loading
@@ -2,11 +2,8 @@ package com.commit451.gitlab.adapter
Loading
@@ -2,11 +2,8 @@ package com.commit451.gitlab.adapter
   
import android.support.v7.widget.RecyclerView import android.support.v7.widget.RecyclerView
import android.view.ViewGroup import android.view.ViewGroup
import com.commit451.gitlab.model.api.Issue
import com.commit451.gitlab.model.api.Note import com.commit451.gitlab.model.api.Note
import com.commit451.gitlab.model.api.Project import com.commit451.gitlab.model.api.Project
import com.commit451.gitlab.viewHolder.IssueHeaderViewHolder
import com.commit451.gitlab.viewHolder.IssueLabelsViewHolder
import com.commit451.gitlab.viewHolder.LoadingFooterViewHolder import com.commit451.gitlab.viewHolder.LoadingFooterViewHolder
import com.commit451.gitlab.viewHolder.NoteViewHolder import com.commit451.gitlab.viewHolder.NoteViewHolder
import java.util.* import java.util.*
Loading
@@ -14,16 +11,13 @@ import java.util.*
Loading
@@ -14,16 +11,13 @@ import java.util.*
/** /**
* Nice notes * Nice notes
*/ */
class IssueDetailsAdapter(private var issue: Issue?, private val project: Project) : RecyclerView.Adapter<RecyclerView.ViewHolder>() { class IssueNotesAdapter(private val project: Project) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
   
companion object { companion object {
   
private val TYPE_HEADER = 0
private val TYPE_HEADER_LABEL = 1
private val TYPE_COMMENT = 2 private val TYPE_COMMENT = 2
private val TYPE_FOOTER = 3 private val TYPE_FOOTER = 3
   
val headerCount = 2
private val FOOTER_COUNT = 1 private val FOOTER_COUNT = 1
} }
   
Loading
@@ -31,11 +25,7 @@ class IssueDetailsAdapter(private var issue: Issue?, private val project: Projec
Loading
@@ -31,11 +25,7 @@ class IssueDetailsAdapter(private var issue: Issue?, private val project: Projec
private var loading = false private var loading = false
   
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
if (viewType == TYPE_HEADER) { if (viewType == TYPE_COMMENT) {
return IssueHeaderViewHolder.inflate(parent)
} else if (viewType == TYPE_HEADER_LABEL) {
return IssueLabelsViewHolder.inflate(parent)
} else if (viewType == TYPE_COMMENT) {
return NoteViewHolder.inflate(parent) return NoteViewHolder.inflate(parent)
} else if (viewType == TYPE_FOOTER) { } else if (viewType == TYPE_FOOTER) {
return LoadingFooterViewHolder.inflate(parent) return LoadingFooterViewHolder.inflate(parent)
Loading
@@ -44,11 +34,7 @@ class IssueDetailsAdapter(private var issue: Issue?, private val project: Projec
Loading
@@ -44,11 +34,7 @@ class IssueDetailsAdapter(private var issue: Issue?, private val project: Projec
} }
   
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
if (holder is IssueHeaderViewHolder) { if (holder is NoteViewHolder) {
holder.bind(issue!!, project)
} else if (holder is IssueLabelsViewHolder) {
holder.bind(issue!!.labels!!)
} else if (holder is NoteViewHolder) {
val note = getNoteAt(position) val note = getNoteAt(position)
holder.bind(note, project) holder.bind(note, project)
} else if (holder is LoadingFooterViewHolder) { } else if (holder is LoadingFooterViewHolder) {
Loading
@@ -57,15 +43,11 @@ class IssueDetailsAdapter(private var issue: Issue?, private val project: Projec
Loading
@@ -57,15 +43,11 @@ class IssueDetailsAdapter(private var issue: Issue?, private val project: Projec
} }
   
override fun getItemCount(): Int { override fun getItemCount(): Int {
return notes.size + headerCount + FOOTER_COUNT return notes.size + FOOTER_COUNT
} }
   
override fun getItemViewType(position: Int): Int { override fun getItemViewType(position: Int): Int {
if (position == 0) { if (position == notes.size) {
return TYPE_HEADER
} else if (position == 1) {
return TYPE_HEADER_LABEL
} else if (position == headerCount + notes.size) {
return TYPE_FOOTER return TYPE_FOOTER
} else { } else {
return TYPE_COMMENT return TYPE_COMMENT
Loading
@@ -73,7 +55,7 @@ class IssueDetailsAdapter(private var issue: Issue?, private val project: Projec
Loading
@@ -73,7 +55,7 @@ class IssueDetailsAdapter(private var issue: Issue?, private val project: Projec
} }
   
fun getNoteAt(position: Int): Note { fun getNoteAt(position: Int): Note {
return notes[position - headerCount] return notes[position]
} }
   
fun setNotes(notes: List<Note>) { fun setNotes(notes: List<Note>) {
Loading
@@ -84,26 +66,17 @@ class IssueDetailsAdapter(private var issue: Issue?, private val project: Projec
Loading
@@ -84,26 +66,17 @@ class IssueDetailsAdapter(private var issue: Issue?, private val project: Projec
fun addNotes(notes: List<Note>) { fun addNotes(notes: List<Note>) {
if (!notes.isEmpty()) { if (!notes.isEmpty()) {
this.notes.addAll(notes) this.notes.addAll(notes)
notifyItemRangeChanged(headerCount, headerCount + this.notes.size) notifyItemRangeChanged(0, this.notes.size)
} }
} }
   
fun addNote(note: Note) { fun addNote(note: Note) {
notes.addFirst(note) notes.addFirst(note)
notifyItemInserted(headerCount) notifyItemInserted(0)
}
fun updateIssue(issue: Issue) {
val oldLabels = this.issue!!.labels
this.issue = issue
notifyItemChanged(0)
if (oldLabels!!.size != this.issue!!.labels!!.size) {
notifyItemChanged(1)
}
} }
   
fun setLoading(loading: Boolean) { fun setLoading(loading: Boolean) {
this.loading = loading this.loading = loading
notifyItemChanged(notes.size + headerCount) notifyItemChanged(notes.size)
} }
} }
package com.commit451.gitlab.adapter
import android.content.Context
import android.support.v4.app.Fragment
import android.support.v4.app.FragmentManager
import android.support.v4.app.FragmentPagerAdapter
import com.commit451.gitlab.R
import com.commit451.gitlab.fragment.IssueDetailsFragment
import com.commit451.gitlab.fragment.IssueDiscussionFragment
import com.commit451.gitlab.model.api.Issue
import com.commit451.gitlab.model.api.Project
/**
* Issue Pager Adapter
*/
class IssuePagerAdapter(context: Context, fm: FragmentManager, private val project: Project, private val issue: Issue) : FragmentPagerAdapter(fm) {
private val titles: Array<String> = context.resources.getStringArray(R.array.issue_tabs)
override fun getItem(position: Int): Fragment {
when (position) {
0 -> return IssueDetailsFragment.newInstance(project, issue)
1 -> return IssueDiscussionFragment.newInstance(project, issue)
}
throw IllegalStateException("Position exceeded on view pager")
}
override fun getCount(): Int {
return titles.size
}
override fun getPageTitle(position: Int): CharSequence {
return titles[position]
}
}
\ No newline at end of file
package com.commit451.gitlab.viewHolder package com.commit451.gitlab.fragment
   
import android.support.v7.widget.RecyclerView import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.ImageView import android.widget.ImageView
import android.widget.TextView import android.widget.TextView
import butterknife.BindView import butterknife.BindView
import butterknife.ButterKnife import com.commit451.adapterflowlayout.AdapterFlowLayout
import com.commit451.addendum.parceler.getParcelerParcelable
import com.commit451.addendum.parceler.putParcelerParcelable
import com.commit451.gitlab.App import com.commit451.gitlab.App
import com.commit451.gitlab.R import com.commit451.gitlab.R
import com.commit451.gitlab.adapter.IssueLabelsAdapter
import com.commit451.gitlab.event.IssueChangedEvent
import com.commit451.gitlab.extension.setMarkdownText import com.commit451.gitlab.extension.setMarkdownText
import com.commit451.gitlab.model.api.Issue import com.commit451.gitlab.model.api.Issue
import com.commit451.gitlab.model.api.Project import com.commit451.gitlab.model.api.Project
Loading
@@ -17,29 +21,69 @@ import com.commit451.gitlab.transformation.CircleTransformation
Loading
@@ -17,29 +21,69 @@ import com.commit451.gitlab.transformation.CircleTransformation
import com.commit451.gitlab.util.DateUtil import com.commit451.gitlab.util.DateUtil
import com.commit451.gitlab.util.ImageUtil import com.commit451.gitlab.util.ImageUtil
import com.commit451.gitlab.util.InternalLinkMovementMethod import com.commit451.gitlab.util.InternalLinkMovementMethod
import com.commit451.gitlab.viewHolder.IssueLabelViewHolder
import org.greenrobot.eventbus.Subscribe
   
/** /**
* Header for an issue * Shows the discussion of an issue
*/ */
class IssueHeaderViewHolder(view: View) : RecyclerView.ViewHolder(view) { class IssueDetailsFragment : ButterKnifeFragment() {
   
companion object { companion object {
   
fun inflate(parent: ViewGroup): IssueHeaderViewHolder { private val KEY_PROJECT = "project"
val view = LayoutInflater.from(parent.context) private val KEY_ISSUE = "issue"
.inflate(R.layout.header_issue, parent, false)
return IssueHeaderViewHolder(view) fun newInstance(project: Project, issue: Issue): IssueDetailsFragment {
val fragment = IssueDetailsFragment()
val args = Bundle()
args.putParcelerParcelable(KEY_PROJECT, project)
args.putParcelerParcelable(KEY_ISSUE, issue)
fragment.arguments = args
return fragment
} }
} }
   
@BindView(R.id.description) lateinit var textDescription: TextView @BindView(R.id.root) lateinit var root: ViewGroup
@BindView(R.id.text_description) lateinit var textDescription: TextView
@BindView(R.id.author_image) lateinit var imageAuthor: ImageView @BindView(R.id.author_image) lateinit var imageAuthor: ImageView
@BindView(R.id.author) lateinit var textAuthor: TextView @BindView(R.id.author) lateinit var textAuthor: TextView
@BindView(R.id.milestone_root) lateinit var rootMilestone: ViewGroup @BindView(R.id.milestone_root) lateinit var rootMilestone: ViewGroup
@BindView(R.id.milestone_text) lateinit var textMilestone: TextView @BindView(R.id.milestone_text) lateinit var textMilestone: TextView
@BindView(R.id.list_labels) lateinit var listLabels: AdapterFlowLayout
lateinit var adapterLabels: IssueLabelsAdapter
lateinit var project: Project
lateinit var issue: Issue
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
project = arguments.getParcelerParcelable<Project>(KEY_PROJECT)!!
issue = arguments.getParcelerParcelable<Issue>(KEY_ISSUE)!!
}
override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater?.inflate(R.layout.fragment_issue_details, container, false)
}
override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
   
init { adapterLabels = IssueLabelsAdapter(object : IssueLabelsAdapter.Listener {
ButterKnife.bind(this, view) override fun onLabelClicked(label: String, viewHolder: IssueLabelViewHolder) {
}
})
bind(issue, project)
App.bus().register(this)
}
override fun onDestroyView() {
App.bus().unregister(this)
super.onDestroyView()
} }
   
fun bind(issue: Issue, project: Project) { fun bind(issue: Issue, project: Project) {
Loading
@@ -53,7 +97,7 @@ class IssueHeaderViewHolder(view: View) : RecyclerView.ViewHolder(view) {
Loading
@@ -53,7 +97,7 @@ class IssueHeaderViewHolder(view: View) : RecyclerView.ViewHolder(view) {
} }
   
App.get().picasso App.get().picasso
.load(ImageUtil.getAvatarUrl(issue.author, itemView.resources.getDimensionPixelSize(R.dimen.image_size))) .load(ImageUtil.getAvatarUrl(issue.author, resources.getDimensionPixelSize(R.dimen.image_size)))
.transform(CircleTransformation()) .transform(CircleTransformation())
.into(imageAuthor) .into(imageAuthor)
   
Loading
@@ -61,9 +105,9 @@ class IssueHeaderViewHolder(view: View) : RecyclerView.ViewHolder(view) {
Loading
@@ -61,9 +105,9 @@ class IssueHeaderViewHolder(view: View) : RecyclerView.ViewHolder(view) {
if (issue.author != null) { if (issue.author != null) {
author = issue.author!!.name + " " author = issue.author!!.name + " "
} }
author += itemView.resources.getString(R.string.created_issue) author += resources.getString(R.string.created_issue)
if (issue.createdAt != null) { if (issue.createdAt != null) {
author = author + " " + DateUtil.getRelativeTimeSpanString(itemView.context, issue.createdAt) author = author + " " + DateUtil.getRelativeTimeSpanString(context, issue.createdAt)
} }
textAuthor.text = author textAuthor.text = author
if (issue.milestone != null) { if (issue.milestone != null) {
Loading
@@ -72,5 +116,14 @@ class IssueHeaderViewHolder(view: View) : RecyclerView.ViewHolder(view) {
Loading
@@ -72,5 +116,14 @@ class IssueHeaderViewHolder(view: View) : RecyclerView.ViewHolder(view) {
} else { } else {
rootMilestone.visibility = View.GONE rootMilestone.visibility = View.GONE
} }
adapterLabels.setLabels(issue.labels)
}
@Subscribe
fun onEvent(event: IssueChangedEvent) {
if (issue.iid == event.issue.iid) {
issue = event.issue
bind(issue, project)
}
} }
} }
\ No newline at end of file
Loading
@@ -18,11 +18,14 @@ import com.commit451.addendum.parceler.putParcelerParcelable
Loading
@@ -18,11 +18,14 @@ import com.commit451.addendum.parceler.putParcelerParcelable
import com.commit451.gitlab.App import com.commit451.gitlab.App
import com.commit451.gitlab.R import com.commit451.gitlab.R
import com.commit451.gitlab.activity.AttachActivity import com.commit451.gitlab.activity.AttachActivity
import com.commit451.gitlab.adapter.IssueNotesAdapter
import com.commit451.gitlab.adapter.MergeRequestDetailAdapter import com.commit451.gitlab.adapter.MergeRequestDetailAdapter
import com.commit451.gitlab.api.response.FileUploadResponse import com.commit451.gitlab.api.response.FileUploadResponse
import com.commit451.gitlab.event.MergeRequestChangedEvent import com.commit451.gitlab.event.IssueChangedEvent
import com.commit451.gitlab.extension.setup import com.commit451.gitlab.extension.setup
import com.commit451.gitlab.model.api.* import com.commit451.gitlab.model.api.Issue
import com.commit451.gitlab.model.api.Note
import com.commit451.gitlab.model.api.Project
import com.commit451.gitlab.navigation.TransitionFactory import com.commit451.gitlab.navigation.TransitionFactory
import com.commit451.gitlab.rx.CustomResponseSingleObserver import com.commit451.gitlab.rx.CustomResponseSingleObserver
import com.commit451.gitlab.rx.CustomSingleObserver import com.commit451.gitlab.rx.CustomSingleObserver
Loading
@@ -41,15 +44,15 @@ class IssueDiscussionFragment : ButterKnifeFragment() {
Loading
@@ -41,15 +44,15 @@ class IssueDiscussionFragment : ButterKnifeFragment() {
companion object { companion object {
   
private val KEY_PROJECT = "project" private val KEY_PROJECT = "project"
private val KEY_MERGE_REQUEST = "merge_request" private val KEY_ISSUE = "issue"
   
private val REQUEST_ATTACH = 1 private val REQUEST_ATTACH = 1
   
fun newInstance(project: Project, issue: Issue): IssueDiscussionFragment{ fun newInstance(project: Project, issue: Issue): IssueDiscussionFragment {
val fragment = IssueDiscussionFragment() val fragment = IssueDiscussionFragment()
val args = Bundle() val args = Bundle()
args.putParcelerParcelable(KEY_PROJECT, project) args.putParcelerParcelable(KEY_PROJECT, project)
args.putParcelerParcelable(KEY_MERGE_REQUEST, issue) args.putParcelerParcelable(KEY_ISSUE, issue)
fragment.arguments = args fragment.arguments = args
return fragment return fragment
} }
Loading
@@ -61,12 +64,12 @@ class IssueDiscussionFragment : ButterKnifeFragment() {
Loading
@@ -61,12 +64,12 @@ class IssueDiscussionFragment : ButterKnifeFragment() {
@BindView(R.id.send_message_view) lateinit var sendMessageView: SendMessageView @BindView(R.id.send_message_view) lateinit var sendMessageView: SendMessageView
@BindView(R.id.progress) lateinit var progress: View @BindView(R.id.progress) lateinit var progress: View
   
lateinit var adapterMergeRequestDetail: MergeRequestDetailAdapter lateinit var adapter: IssueNotesAdapter
lateinit var layoutManagerNotes: LinearLayoutManager lateinit var layoutManagerNotes: LinearLayoutManager
lateinit var teleprinter: Teleprinter lateinit var teleprinter: Teleprinter
   
lateinit var project: Project lateinit var project: Project
lateinit var mergeRequest: MergeRequest lateinit var issue: Issue
var nextPageUrl: Uri? = null var nextPageUrl: Uri? = null
var loading: Boolean = false var loading: Boolean = false
   
Loading
@@ -85,21 +88,21 @@ class IssueDiscussionFragment : ButterKnifeFragment() {
Loading
@@ -85,21 +88,21 @@ class IssueDiscussionFragment : ButterKnifeFragment() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
project = arguments.getParcelerParcelable<Project>(KEY_PROJECT)!! project = arguments.getParcelerParcelable<Project>(KEY_PROJECT)!!
mergeRequest = arguments.getParcelerParcelable<MergeRequest>(KEY_MERGE_REQUEST)!! issue = arguments.getParcelerParcelable<Issue>(KEY_ISSUE)!!
} }
   
override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? { override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater!!.inflate(R.layout.fragment_merge_request_discussion, container, false) return inflater?.inflate(R.layout.fragment_merge_request_discussion, container, false)
} }
   
override fun onViewCreated(view: View?, savedInstanceState: Bundle?) { override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
teleprinter = Teleprinter(activity) teleprinter = Teleprinter(activity)
   
adapterMergeRequestDetail = MergeRequestDetailAdapter(activity, mergeRequest, project) adapter = IssueNotesAdapter(project)
layoutManagerNotes = LinearLayoutManager(activity) layoutManagerNotes = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, true)
listNotes.layoutManager = layoutManagerNotes listNotes.layoutManager = layoutManagerNotes
listNotes.adapter = adapterMergeRequestDetail listNotes.adapter = adapter
listNotes.addOnScrollListener(onScrollListener) listNotes.addOnScrollListener(onScrollListener)
   
sendMessageView.callback = object : SendMessageView.Callback { sendMessageView.callback = object : SendMessageView.Callback {
Loading
@@ -123,7 +126,7 @@ class IssueDiscussionFragment : ButterKnifeFragment() {
Loading
@@ -123,7 +126,7 @@ class IssueDiscussionFragment : ButterKnifeFragment() {
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data) super.onActivityResult(requestCode, resultCode, data)
when (requestCode) { when (requestCode) {
REQUEST_ATTACH -> { REQUEST_ATTACH -> {
if (resultCode == RESULT_OK) { if (resultCode == RESULT_OK) {
val response = data!!.getParcelerParcelableExtra<FileUploadResponse>(AttachActivity.KEY_FILE_UPLOAD_RESPONSE)!! val response = data!!.getParcelerParcelableExtra<FileUploadResponse>(AttachActivity.KEY_FILE_UPLOAD_RESPONSE)!!
progress.visibility = View.GONE progress.visibility = View.GONE
Loading
@@ -143,7 +146,7 @@ class IssueDiscussionFragment : ButterKnifeFragment() {
Loading
@@ -143,7 +146,7 @@ class IssueDiscussionFragment : ButterKnifeFragment() {
   
fun loadNotes() { fun loadNotes() {
swipeRefreshLayout.isRefreshing = true swipeRefreshLayout.isRefreshing = true
App.get().gitLab.getMergeRequestNotes(project.id, mergeRequest.iid) App.get().gitLab.getIssueNotes(project.id, issue.iid)
.setup(bindUntilEvent(FragmentEvent.DESTROY_VIEW)) .setup(bindUntilEvent(FragmentEvent.DESTROY_VIEW))
.subscribe(object : CustomResponseSingleObserver<List<Note>>() { .subscribe(object : CustomResponseSingleObserver<List<Note>>() {
   
Loading
@@ -159,13 +162,13 @@ class IssueDiscussionFragment : ButterKnifeFragment() {
Loading
@@ -159,13 +162,13 @@ class IssueDiscussionFragment : ButterKnifeFragment() {
swipeRefreshLayout.isRefreshing = false swipeRefreshLayout.isRefreshing = false
loading = false loading = false
nextPageUrl = LinkHeaderParser.parse(response()).next nextPageUrl = LinkHeaderParser.parse(response()).next
adapterMergeRequestDetail.setNotes(notes) adapter.setNotes(notes)
} }
}) })
} }
   
fun loadMoreNotes() { fun loadMoreNotes() {
adapterMergeRequestDetail.setLoading(true) adapter.setLoading(true)
App.get().gitLab.getMergeRequestNotes(nextPageUrl!!.toString()) App.get().gitLab.getMergeRequestNotes(nextPageUrl!!.toString())
.setup(bindUntilEvent(FragmentEvent.DESTROY_VIEW)) .setup(bindUntilEvent(FragmentEvent.DESTROY_VIEW))
.subscribe(object : CustomResponseSingleObserver<List<Note>>() { .subscribe(object : CustomResponseSingleObserver<List<Note>>() {
Loading
@@ -173,16 +176,16 @@ class IssueDiscussionFragment : ButterKnifeFragment() {
Loading
@@ -173,16 +176,16 @@ class IssueDiscussionFragment : ButterKnifeFragment() {
override fun error(e: Throwable) { override fun error(e: Throwable) {
loading = false loading = false
Timber.e(e) Timber.e(e)
adapterMergeRequestDetail.setLoading(false) adapter.setLoading(false)
Snackbar.make(root, getString(R.string.connection_error), Snackbar.LENGTH_SHORT) Snackbar.make(root, getString(R.string.connection_error), Snackbar.LENGTH_SHORT)
.show() .show()
} }
   
override fun responseNonNullSuccess(notes: List<Note>) { override fun responseNonNullSuccess(notes: List<Note>) {
adapterMergeRequestDetail.setLoading(false) adapter.setLoading(false)
loading = false loading = false
nextPageUrl = LinkHeaderParser.parse(response()).next nextPageUrl = LinkHeaderParser.parse(response()).next
adapterMergeRequestDetail.addNotes(notes) adapter.addNotes(notes)
} }
}) })
} }
Loading
@@ -200,7 +203,7 @@ class IssueDiscussionFragment : ButterKnifeFragment() {
Loading
@@ -200,7 +203,7 @@ class IssueDiscussionFragment : ButterKnifeFragment() {
teleprinter.hideKeyboard() teleprinter.hideKeyboard()
sendMessageView.clearText() sendMessageView.clearText()
   
App.get().gitLab.addMergeRequestNote(project.id, mergeRequest.id, message) App.get().gitLab.addIssueNote(project.id, issue.iid, message)
.setup(bindUntilEvent(FragmentEvent.DESTROY_VIEW)) .setup(bindUntilEvent(FragmentEvent.DESTROY_VIEW))
.subscribe(object : CustomSingleObserver<Note>() { .subscribe(object : CustomSingleObserver<Note>() {
   
Loading
@@ -213,16 +216,16 @@ class IssueDiscussionFragment : ButterKnifeFragment() {
Loading
@@ -213,16 +216,16 @@ class IssueDiscussionFragment : ButterKnifeFragment() {
   
override fun success(note: Note) { override fun success(note: Note) {
progress.visibility = View.GONE progress.visibility = View.GONE
adapterMergeRequestDetail.addNote(note) adapter.addNote(note)
listNotes.smoothScrollToPosition(MergeRequestDetailAdapter.headerCount) listNotes.smoothScrollToPosition(MergeRequestDetailAdapter.headerCount)
} }
}) })
} }
   
@Subscribe @Subscribe
fun onMergeRequestChangedEvent(event: MergeRequestChangedEvent) { fun onEvent(event: IssueChangedEvent) {
if (mergeRequest.id == event.mergeRequest.id) { if (issue.iid == event.issue.iid) {
mergeRequest = event.mergeRequest issue = event.issue
loadNotes() loadNotes()
} }
} }
Loading
Loading
Loading
@@ -132,10 +132,6 @@ object Navigator {
Loading
@@ -132,10 +132,6 @@ object Navigator {
activity.startActivity(IssueActivity.newIntent(activity, project, issue)) activity.startActivity(IssueActivity.newIntent(activity, project, issue))
} }
   
fun navigateToIssue(activity: Activity, namespace: String, projectName: String, issueIid: String) {
activity.startActivity(IssueActivity.newIntent(activity, namespace, projectName, issueIid))
}
fun navigateToMergeRequest(activity: Activity, project: Project, mergeRequest: MergeRequest) { fun navigateToMergeRequest(activity: Activity, project: Project, mergeRequest: MergeRequest) {
val intent = MergeRequestActivity.newIntent(activity, project, mergeRequest) val intent = MergeRequestActivity.newIntent(activity, project, mergeRequest)
activity.startActivity(intent) activity.startActivity(intent)
Loading
Loading
package com.commit451.gitlab.viewHolder
import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import butterknife.BindView
import butterknife.ButterKnife
import com.commit451.adapterflowlayout.AdapterFlowLayout
import com.commit451.gitlab.R
import com.commit451.gitlab.adapter.IssueLabelsAdapter
/**
* Shows the labels for an issue
*/
class IssueLabelsViewHolder(view: View) : RecyclerView.ViewHolder(view) {
companion object {
fun inflate(parent: ViewGroup): IssueLabelsViewHolder {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.header_issue_labels, parent, false)
return IssueLabelsViewHolder(view)
}
}
@BindView(R.id.adapter_layout) lateinit var flowLayout: AdapterFlowLayout
var adapterIssueLabels: IssueLabelsAdapter
private val mListener = object : IssueLabelsAdapter.Listener {
override fun onLabelClicked(label: String, viewHolder: IssueLabelViewHolder) {
//TODO anything?
}
}
init {
ButterKnife.bind(this, view)
adapterIssueLabels = IssueLabelsAdapter(mListener)
flowLayout.adapter = adapterIssueLabels
}
fun bind(labels: Collection<String>) {
adapterIssueLabels.setLabels(labels)
}
}
\ No newline at end of file
Loading
@@ -2,90 +2,50 @@
Loading
@@ -2,90 +2,50 @@
<android.support.design.widget.CoordinatorLayout <android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/root" android:id="@+id/root"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
   
<LinearLayout <android.support.design.widget.AppBarLayout
android:id="@+id/app_bar_container" android:id="@+id/appbar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content">
android:layout_marginBottom="?attr/actionBarSize"
android:orientation="vertical">
   
<android.support.design.widget.AppBarLayout <android.support.v7.widget.Toolbar
android:id="@+id/appbar" android:id="@+id/toolbar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="?attr/actionBarSize"/>
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize" >
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
   
<TextView <android.support.design.widget.TabLayout
android:id="@+id/toolbar_title" android:id="@+id/tabs"
style="@style/TextAppearance.AppCompat.Widget.ActionBar.Title" android:layout_width="match_parent"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_height="wrap_content" app:tabMode="fixed"/>
android:drawablePadding="8dp"
tools:text="Issue title" />
<TextView
android:id="@+id/toolbar_subtitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="subtitle" />
   
</LinearLayout> </android.support.design.widget.AppBarLayout>
</android.support.v7.widget.Toolbar>
<TextView
android:id="@+id/issue_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp"
android:drawablePadding="8dp"
android:layout_marginRight="56dp"
tools:text="This is an issue"/>
   
</android.support.design.widget.AppBarLayout> <FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
   
<com.commit451.gitlab.view.LabCoatSwipeRefreshLayout <android.support.v4.view.ViewPager
android:id="@+id/swipe_layout" android:id="@+id/pager"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="match_parent"/>
   
<android.support.v7.widget.RecyclerView <include layout="@layout/progress_fullscreen"/>
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
   
</com.commit451.gitlab.view.LabCoatSwipeRefreshLayout> </FrameLayout>
</LinearLayout>
<com.commit451.gitlab.view.SendMessageView
android:id="@+id/send_message_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"/>
   
<android.support.design.widget.FloatingActionButton <android.support.design.widget.FloatingActionButton
android:id="@+id/fab_edit_issue" android:id="@+id/fab_edit_issue"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_margin="16dp" android:layout_margin="16dp"
app:srcCompat="@drawable/ic_edit_24dp"
app:fabSize="mini" app:fabSize="mini"
app:layout_anchor="@id/appbar" app:layout_anchor="@id/appbar"
app:layout_anchorGravity="bottom|right|end"/> app:layout_anchorGravity="bottom|right|end"
app:srcCompat="@drawable/ic_edit_24dp"/>
<include layout="@layout/progress_fullscreen"/>
   
</android.support.design.widget.CoordinatorLayout> </android.support.design.widget.CoordinatorLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.NestedScrollView
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/root"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginLeft="@dimen/activity_horizontal_margin"
android:layout_marginRight="@dimen/activity_horizontal_margin"
android:layout_marginTop="8dp"
android:orientation="vertical">
<TextView
android:id="@+id/text_description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="Description"
android:textAppearance="?android:attr/textAppearanceMedium" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="8dp">
<ImageView
android:id="@+id/author_image"
android:layout_width="@dimen/image_size"
android:layout_height="@dimen/image_size"
android:contentDescription="@null"/>
<TextView
android:id="@+id/author"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/padding_normal"
android:layout_marginRight="@dimen/padding_normal"
android:layout_gravity="center_vertical"
tools:text="Jawnnypoo created issue 8 hours ago"
android:textAppearance="?android:attr/textAppearanceMedium" />
</LinearLayout>
<LinearLayout
android:id="@+id/milestone_root"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:orientation="horizontal">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:srcCompat="@drawable/ic_milestone_24dp"
android:contentDescription="@null"/>
<TextView
android:id="@+id/milestone_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/padding_normal"
android:layout_marginRight="@dimen/padding_normal"
android:layout_gravity="center_vertical"
tools:text="2.0.0"/>
</LinearLayout>
<com.commit451.adapterflowlayout.AdapterFlowLayout
android:id="@+id/list_labels"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"/>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
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:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginTop="16dp"
tools:text="Description"
android:textAppearance="?android:attr/textAppearanceMedium" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_margin="16dp">
<ImageView
android:id="@+id/author_image"
android:layout_width="@dimen/image_size"
android:layout_height="@dimen/image_size"
android:contentDescription="@null"/>
<TextView
android:id="@+id/author"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/padding_normal"
android:layout_marginRight="@dimen/padding_normal"
android:layout_gravity="center_vertical"
tools:text="Jawnnypoo created issue 8 hours ago"
android:textAppearance="?android:attr/textAppearanceMedium" />
</LinearLayout>
<LinearLayout
android:id="@+id/milestone_root"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/activity_horizontal_margin"
android:layout_marginRight="@dimen/activity_horizontal_margin"
android:orientation="horizontal">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:srcCompat="@drawable/ic_milestone_24dp"
android:contentDescription="@null"/>
<TextView
android:id="@+id/milestone_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/padding_normal"
android:layout_marginRight="@dimen/padding_normal"
android:layout_gravity="center_vertical"
tools:text="2.0.0"/>
</LinearLayout>
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<com.commit451.adapterflowlayout.AdapterFlowLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/adapter_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/activity_horizontal_margin"
android:layout_marginRight="@dimen/activity_horizontal_margin"/>
\ No newline at end of file
Loading
@@ -190,6 +190,12 @@
Loading
@@ -190,6 +190,12 @@
<string name="root">ROOT</string> <string name="root">ROOT</string>
   
<!-- Issues --> <!-- Issues -->
<string name="issue_tab_discussion">Discussion</string>
<string name="issue_tab_details">Details</string>
<string-array name="issue_tabs">
<item>@string/issue_tab_details</item>
<item>@string/issue_tab_discussion</item>
</string-array>
<string name="new_note_hint">Add comment</string> <string name="new_note_hint">Add comment</string>
<string name="add_issue">Add new issue</string> <string name="add_issue">Add new issue</string>
<string name="add_issue_dialog_title">New issue</string> <string name="add_issue_dialog_title">New issue</string>
Loading
Loading
Loading
@@ -2,14 +2,14 @@
Loading
@@ -2,14 +2,14 @@
apply plugin: 'com.github.ben-manes.versions' apply plugin: 'com.github.ben-manes.versions'
apply plugin: 'com.commit451.updatewrapper' apply plugin: 'com.commit451.updatewrapper'
buildscript { buildscript {
ext.kotlinVersion = '1.1.4-2' ext.kotlinVersion = '1.1.4-3'
repositories { repositories {
jcenter() jcenter()
maven { url "https://jitpack.io" } maven { url "https://jitpack.io" }
google() google()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:3.0.0-beta2' classpath 'com.android.tools.build:gradle:3.0.0-beta4'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
classpath 'com.github.ben-manes:gradle-versions-plugin:0.15.0' classpath 'com.github.ben-manes:gradle-versions-plugin:0.15.0'
classpath 'com.github.Commit451:updatewrapper:1.1.2' classpath 'com.github.Commit451:updatewrapper:1.1.2'
Loading
Loading
Loading
@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
Loading
@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-rc-1-all.zip distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment