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
Loading
@@ -98,9 +98,9 @@ android {
}
 
ext {
supportLibVersion = '26.0.1'
supportLibVersion = '26.0.2'
retrofitVersion = '2.3.0'
okHttpVersion = '3.8.1'
okHttpVersion = '3.9.0'
butterknifeVersion = '8.8.1'
parcelerVersion = '1.1.9'
reptarVersion = '2.5.1'
Loading
Loading
@@ -190,7 +190,7 @@ dependencies {
 
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'
 
Loading
Loading
@@ -213,7 +213,7 @@ dependencies {
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'
 
Loading
Loading
@@ -230,7 +230,7 @@ dependencies {
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'
}
}
package com.commit451.gitlab.activity
 
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.support.design.widget.Snackbar
import android.support.v4.widget.SwipeRefreshLayout
import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.RecyclerView
import android.support.design.widget.TabLayout
import android.support.v4.view.ViewPager
import android.support.v7.widget.Toolbar
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import android.widget.Toast
import butterknife.BindView
import butterknife.ButterKnife
Loading
Loading
@@ -22,28 +18,20 @@ import com.commit451.addendum.parceler.getParcelerParcelableExtra
import com.commit451.addendum.parceler.putParcelerParcelableExtra
import com.commit451.gitlab.App
import com.commit451.gitlab.R
import com.commit451.gitlab.adapter.IssueDetailsAdapter
import com.commit451.gitlab.api.response.FileUploadResponse
import com.commit451.gitlab.adapter.IssuePagerAdapter
import com.commit451.gitlab.event.IssueChangedEvent
import com.commit451.gitlab.event.IssueReloadEvent
import com.commit451.gitlab.extension.getUrl
import com.commit451.gitlab.extension.setup
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.Navigator
import com.commit451.gitlab.rx.CustomCompleteObserver
import com.commit451.gitlab.rx.CustomResponseSingleObserver
import com.commit451.gitlab.rx.CustomSingleObserver
import com.commit451.gitlab.util.IntentUtil
import com.commit451.gitlab.util.LinkHeaderParser
import com.commit451.gitlab.view.SendMessageView
import com.commit451.teleprinter.Teleprinter
import io.reactivex.Single
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import org.greenrobot.eventbus.Subscribe
import retrofit2.Response
import timber.log.Timber
 
/**
Loading
Loading
@@ -55,11 +43,6 @@ class IssueActivity : BaseActivity() {
 
private val EXTRA_PROJECT = "extra_project"
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 {
val intent = Intent(context, IssueActivity::class.java)
Loading
Loading
@@ -67,53 +50,24 @@ class IssueActivity : BaseActivity() {
intent.putParcelerParcelableExtra(EXTRA_SELECTED_ISSUE, issue)
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.toolbar) lateinit var toolbar: Toolbar
@BindView(R.id.issue_title) lateinit var textTitle: TextView
@BindView(R.id.swipe_layout) lateinit var swipeRefreshLayout: SwipeRefreshLayout
@BindView(R.id.list) lateinit var listNotes: RecyclerView
@BindView(R.id.send_message_view) lateinit var sendMessageView: SendMessageView
@BindView(R.id.tabs) lateinit var tabLayout: TabLayout
@BindView(R.id.pager) lateinit var viewPager: ViewPager
@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 adapterIssueDetails: IssueDetailsAdapter
lateinit var layoutManagerNotes: LinearLayoutManager
lateinit var teleprinter: Teleprinter
 
var project: Project? = null
var issue: Issue? = null
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()
}
}
}
lateinit var project: Project
lateinit var issue: Issue
 
val onMenuItemClickListener = Toolbar.OnMenuItemClickListener { item ->
when (item.itemId) {
R.id.action_share -> {
IntentUtil.share(root, issue!!.getUrl(project!!))
IntentUtil.share(root, issue.getUrl(project))
return@OnMenuItemClickListener true
}
R.id.action_close -> {
Loading
Loading
@@ -121,7 +75,7 @@ class IssueActivity : BaseActivity() {
return@OnMenuItemClickListener true
}
R.id.action_delete -> {
App.get().gitLab.deleteIssue(project!!.id, issue!!.iid)
App.get().gitLab.deleteIssue(project.id, issue.iid)
.setup(bindToLifecycle())
.subscribe(object : CustomCompleteObserver() {
 
Loading
Loading
@@ -148,9 +102,7 @@ class IssueActivity : BaseActivity() {
fun onEditIssueClick() {
val project = project
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?) {
Loading
Loading
@@ -160,6 +112,9 @@ class IssueActivity : BaseActivity() {
teleprinter = Teleprinter(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.setNavigationOnClickListener { onBackPressed() }
toolbar.inflateMenu(R.menu.share)
Loading
Loading
@@ -168,83 +123,15 @@ class IssueActivity : BaseActivity() {
menuItemOpenClose = toolbar.menu.findItem(R.id.action_close)
toolbar.setOnMenuItemClickListener(onMenuItemClickListener)
 
layoutManagerNotes = LinearLayoutManager(this)
listNotes.layoutManager = layoutManagerNotes
listNotes.addOnScrollListener(onScrollListener)
sendMessageView.callback = object : SendMessageView.Callback {
override fun onSendClicked(message: String) {
postNote(message)
}
override fun onAttachmentClicked() {
Navigator.navigateToAttach(this@IssueActivity, project!!, REQUEST_ATTACH)
}
}
swipeRefreshLayout.setOnRefreshListener { loadNotes() }
val sectionsPagerAdapter = IssuePagerAdapter(
this,
supportFragmentManager,
project,
issue)
 
if (intent.hasExtra(EXTRA_SELECTED_ISSUE)) {
project = intent.getParcelerParcelableExtra<Project>(EXTRA_PROJECT)
issue = intent.getParcelerParcelableExtra<Issue>(EXTRA_SELECTED_ISSUE)
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()
}
}
viewPager.adapter = sectionsPagerAdapter
tabLayout.setupWithViewPager(viewPager)
bindIssue()
}
 
override fun onDestroy() {
Loading
Loading
@@ -252,108 +139,18 @@ class IssueActivity : BaseActivity() {
super.onDestroy()
}
 
fun bindProject() {
toolbarSubTitle.text = project?.nameWithNamespace
}
fun bindIssue() {
setOpenCloseMenuStatus()
textTitle.text = issue?.title
toolbarTitle.text = getString(R.string.issue_number, issue?.iid)
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)
}
})
toolbar.title = getString(R.string.issue_number, issue?.iid)
toolbar.subtitle = project.nameWithNamespace
}
 
fun closeOrOpenIssue() {
progress.visibility = View.VISIBLE
if (issue!!.state == Issue.STATE_CLOSED) {
updateIssueStatus(App.get().gitLab.updateIssueStatus(project!!.id, issue!!.iid, Issue.STATE_REOPEN))
if (issue.state == Issue.STATE_CLOSED) {
updateIssueStatus(App.get().gitLab.updateIssueStatus(project.id, issue.iid, Issue.STATE_REOPEN))
} 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
Loading
@@ -375,21 +172,19 @@ class IssueActivity : BaseActivity() {
App.bus().post(IssueChangedEvent(this@IssueActivity.issue!!))
App.bus().post(IssueReloadEvent())
setOpenCloseMenuStatus()
loadNotes()
}
})
}
 
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
fun onEvent(event: IssueChangedEvent) {
if (issue!!.id == event.issue.id) {
if (issue.id == event.issue.id) {
issue = event.issue
bindIssue()
loadNotes()
}
}
}
Loading
Loading
@@ -31,11 +31,13 @@ class LoadSomeInfoActivity : BaseActivity() {
private val EXTRA_MERGE_REQUEST = "merge_request"
private val EXTRA_BUILD_ID = "build_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_MERGE_REQUEST = 1
private val LOAD_TYPE_BUILD = 2
private val LOAD_TYPE_MILESTONE = 3
private val LOAD_TYPE_ISSUE = 4
 
fun newIntent(context: Context, namespace: String, projectName: String, commitSha: String): Intent {
val intent = Intent(context, LoadSomeInfoActivity::class.java)
Loading
Loading
@@ -46,6 +48,15 @@ class LoadSomeInfoActivity : BaseActivity() {
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 {
val intent = Intent(context, LoadSomeInfoActivity::class.java)
intent.putExtra(EXTRA_PROJECT_NAMESPACE, namespace)
Loading
Loading
@@ -94,7 +105,7 @@ class LoadSomeInfoActivity : BaseActivity() {
Timber.d("Loading some info type: %d", 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 project = intent.getStringExtra(EXTRA_PROJECT_NAME)
App.get().gitLab.getProject(namespace, project)
Loading
Loading
@@ -122,6 +133,24 @@ class LoadSomeInfoActivity : BaseActivity() {
fun loadNextPart(response: Project) {
project = response
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 -> {
val sha = intent.getStringExtra(EXTRA_COMMIT_SHA)
App.get().gitLab.getCommit(response.id, sha)
Loading
Loading
Loading
Loading
@@ -26,7 +26,8 @@ class RoutingActivity : BaseActivity() {
val navigator = object : RoutingNavigator {
override fun onRouteToIssue(projectNamespace: String, projectName: String, issueIid: String) {
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) {
Loading
Loading
Loading
Loading
@@ -32,7 +32,7 @@ class IssueLabelsAdapter(private val listener: IssueLabelsAdapter.Listener) : Re
return values.size
}
 
fun setLabels(labels: Collection<String>) {
fun setLabels(labels: Collection<String>?) {
values.clear()
addLabels(labels)
}
Loading
Loading
Loading
Loading
@@ -2,11 +2,8 @@ package com.commit451.gitlab.adapter
 
import android.support.v7.widget.RecyclerView
import android.view.ViewGroup
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.viewHolder.IssueHeaderViewHolder
import com.commit451.gitlab.viewHolder.IssueLabelsViewHolder
import com.commit451.gitlab.viewHolder.LoadingFooterViewHolder
import com.commit451.gitlab.viewHolder.NoteViewHolder
import java.util.*
Loading
Loading
@@ -14,16 +11,13 @@ import java.util.*
/**
* 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 {
 
private val TYPE_HEADER = 0
private val TYPE_HEADER_LABEL = 1
private val TYPE_COMMENT = 2
private val TYPE_FOOTER = 3
 
val headerCount = 2
private val FOOTER_COUNT = 1
}
 
Loading
Loading
@@ -31,11 +25,7 @@ class IssueDetailsAdapter(private var issue: Issue?, private val project: Projec
private var loading = false
 
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
if (viewType == TYPE_HEADER) {
return IssueHeaderViewHolder.inflate(parent)
} else if (viewType == TYPE_HEADER_LABEL) {
return IssueLabelsViewHolder.inflate(parent)
} else if (viewType == TYPE_COMMENT) {
if (viewType == TYPE_COMMENT) {
return NoteViewHolder.inflate(parent)
} else if (viewType == TYPE_FOOTER) {
return LoadingFooterViewHolder.inflate(parent)
Loading
Loading
@@ -44,11 +34,7 @@ class IssueDetailsAdapter(private var issue: Issue?, private val project: Projec
}
 
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
if (holder is IssueHeaderViewHolder) {
holder.bind(issue!!, project)
} else if (holder is IssueLabelsViewHolder) {
holder.bind(issue!!.labels!!)
} else if (holder is NoteViewHolder) {
if (holder is NoteViewHolder) {
val note = getNoteAt(position)
holder.bind(note, project)
} else if (holder is LoadingFooterViewHolder) {
Loading
Loading
@@ -57,15 +43,11 @@ class IssueDetailsAdapter(private var issue: Issue?, private val project: Projec
}
 
override fun getItemCount(): Int {
return notes.size + headerCount + FOOTER_COUNT
return notes.size + FOOTER_COUNT
}
 
override fun getItemViewType(position: Int): Int {
if (position == 0) {
return TYPE_HEADER
} else if (position == 1) {
return TYPE_HEADER_LABEL
} else if (position == headerCount + notes.size) {
if (position == notes.size) {
return TYPE_FOOTER
} else {
return TYPE_COMMENT
Loading
Loading
@@ -73,7 +55,7 @@ class IssueDetailsAdapter(private var issue: Issue?, private val project: Projec
}
 
fun getNoteAt(position: Int): Note {
return notes[position - headerCount]
return notes[position]
}
 
fun setNotes(notes: List<Note>) {
Loading
Loading
@@ -84,26 +66,17 @@ class IssueDetailsAdapter(private var issue: Issue?, private val project: Projec
fun addNotes(notes: List<Note>) {
if (!notes.isEmpty()) {
this.notes.addAll(notes)
notifyItemRangeChanged(headerCount, headerCount + this.notes.size)
notifyItemRangeChanged(0, this.notes.size)
}
}
 
fun addNote(note: Note) {
notes.addFirst(note)
notifyItemInserted(headerCount)
}
fun updateIssue(issue: Issue) {
val oldLabels = this.issue!!.labels
this.issue = issue
notifyItemChanged(0)
if (oldLabels!!.size != this.issue!!.labels!!.size) {
notifyItemChanged(1)
}
notifyItemInserted(0)
}
 
fun setLoading(loading: Boolean) {
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.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
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.R
import com.commit451.gitlab.adapter.IssueLabelsAdapter
import com.commit451.gitlab.event.IssueChangedEvent
import com.commit451.gitlab.extension.setMarkdownText
import com.commit451.gitlab.model.api.Issue
import com.commit451.gitlab.model.api.Project
Loading
Loading
@@ -17,29 +21,69 @@ import com.commit451.gitlab.transformation.CircleTransformation
import com.commit451.gitlab.util.DateUtil
import com.commit451.gitlab.util.ImageUtil
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 {
 
fun inflate(parent: ViewGroup): IssueHeaderViewHolder {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.header_issue, parent, false)
return IssueHeaderViewHolder(view)
private val KEY_PROJECT = "project"
private val KEY_ISSUE = "issue"
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) lateinit var textAuthor: TextView
@BindView(R.id.milestone_root) lateinit var rootMilestone: ViewGroup
@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 {
ButterKnife.bind(this, view)
adapterLabels = IssueLabelsAdapter(object : IssueLabelsAdapter.Listener {
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) {
Loading
Loading
@@ -53,7 +97,7 @@ class IssueHeaderViewHolder(view: View) : RecyclerView.ViewHolder(view) {
}
 
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())
.into(imageAuthor)
 
Loading
Loading
@@ -61,9 +105,9 @@ class IssueHeaderViewHolder(view: View) : RecyclerView.ViewHolder(view) {
if (issue.author != null) {
author = issue.author!!.name + " "
}
author += itemView.resources.getString(R.string.created_issue)
author += resources.getString(R.string.created_issue)
if (issue.createdAt != null) {
author = author + " " + DateUtil.getRelativeTimeSpanString(itemView.context, issue.createdAt)
author = author + " " + DateUtil.getRelativeTimeSpanString(context, issue.createdAt)
}
textAuthor.text = author
if (issue.milestone != null) {
Loading
Loading
@@ -72,5 +116,14 @@ class IssueHeaderViewHolder(view: View) : RecyclerView.ViewHolder(view) {
} else {
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
Loading
@@ -18,11 +18,14 @@ import com.commit451.addendum.parceler.putParcelerParcelable
import com.commit451.gitlab.App
import com.commit451.gitlab.R
import com.commit451.gitlab.activity.AttachActivity
import com.commit451.gitlab.adapter.IssueNotesAdapter
import com.commit451.gitlab.adapter.MergeRequestDetailAdapter
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.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.rx.CustomResponseSingleObserver
import com.commit451.gitlab.rx.CustomSingleObserver
Loading
Loading
@@ -41,15 +44,15 @@ class IssueDiscussionFragment : ButterKnifeFragment() {
companion object {
 
private val KEY_PROJECT = "project"
private val KEY_MERGE_REQUEST = "merge_request"
private val KEY_ISSUE = "issue"
 
private val REQUEST_ATTACH = 1
 
fun newInstance(project: Project, issue: Issue): IssueDiscussionFragment{
fun newInstance(project: Project, issue: Issue): IssueDiscussionFragment {
val fragment = IssueDiscussionFragment()
val args = Bundle()
args.putParcelerParcelable(KEY_PROJECT, project)
args.putParcelerParcelable(KEY_MERGE_REQUEST, issue)
args.putParcelerParcelable(KEY_ISSUE, issue)
fragment.arguments = args
return fragment
}
Loading
Loading
@@ -61,12 +64,12 @@ class IssueDiscussionFragment : ButterKnifeFragment() {
@BindView(R.id.send_message_view) lateinit var sendMessageView: SendMessageView
@BindView(R.id.progress) lateinit var progress: View
 
lateinit var adapterMergeRequestDetail: MergeRequestDetailAdapter
lateinit var adapter: IssueNotesAdapter
lateinit var layoutManagerNotes: LinearLayoutManager
lateinit var teleprinter: Teleprinter
 
lateinit var project: Project
lateinit var mergeRequest: MergeRequest
lateinit var issue: Issue
var nextPageUrl: Uri? = null
var loading: Boolean = false
 
Loading
Loading
@@ -85,21 +88,21 @@ class IssueDiscussionFragment : ButterKnifeFragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
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? {
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?) {
super.onViewCreated(view, savedInstanceState)
teleprinter = Teleprinter(activity)
 
adapterMergeRequestDetail = MergeRequestDetailAdapter(activity, mergeRequest, project)
layoutManagerNotes = LinearLayoutManager(activity)
adapter = IssueNotesAdapter(project)
layoutManagerNotes = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, true)
listNotes.layoutManager = layoutManagerNotes
listNotes.adapter = adapterMergeRequestDetail
listNotes.adapter = adapter
listNotes.addOnScrollListener(onScrollListener)
 
sendMessageView.callback = object : SendMessageView.Callback {
Loading
Loading
@@ -123,7 +126,7 @@ class IssueDiscussionFragment : ButterKnifeFragment() {
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
when (requestCode) {
REQUEST_ATTACH -> {
REQUEST_ATTACH -> {
if (resultCode == RESULT_OK) {
val response = data!!.getParcelerParcelableExtra<FileUploadResponse>(AttachActivity.KEY_FILE_UPLOAD_RESPONSE)!!
progress.visibility = View.GONE
Loading
Loading
@@ -143,7 +146,7 @@ class IssueDiscussionFragment : ButterKnifeFragment() {
 
fun loadNotes() {
swipeRefreshLayout.isRefreshing = true
App.get().gitLab.getMergeRequestNotes(project.id, mergeRequest.iid)
App.get().gitLab.getIssueNotes(project.id, issue.iid)
.setup(bindUntilEvent(FragmentEvent.DESTROY_VIEW))
.subscribe(object : CustomResponseSingleObserver<List<Note>>() {
 
Loading
Loading
@@ -159,13 +162,13 @@ class IssueDiscussionFragment : ButterKnifeFragment() {
swipeRefreshLayout.isRefreshing = false
loading = false
nextPageUrl = LinkHeaderParser.parse(response()).next
adapterMergeRequestDetail.setNotes(notes)
adapter.setNotes(notes)
}
})
}
 
fun loadMoreNotes() {
adapterMergeRequestDetail.setLoading(true)
adapter.setLoading(true)
App.get().gitLab.getMergeRequestNotes(nextPageUrl!!.toString())
.setup(bindUntilEvent(FragmentEvent.DESTROY_VIEW))
.subscribe(object : CustomResponseSingleObserver<List<Note>>() {
Loading
Loading
@@ -173,16 +176,16 @@ class IssueDiscussionFragment : ButterKnifeFragment() {
override fun error(e: Throwable) {
loading = false
Timber.e(e)
adapterMergeRequestDetail.setLoading(false)
adapter.setLoading(false)
Snackbar.make(root, getString(R.string.connection_error), Snackbar.LENGTH_SHORT)
.show()
}
 
override fun responseNonNullSuccess(notes: List<Note>) {
adapterMergeRequestDetail.setLoading(false)
adapter.setLoading(false)
loading = false
nextPageUrl = LinkHeaderParser.parse(response()).next
adapterMergeRequestDetail.addNotes(notes)
adapter.addNotes(notes)
}
})
}
Loading
Loading
@@ -200,7 +203,7 @@ class IssueDiscussionFragment : ButterKnifeFragment() {
teleprinter.hideKeyboard()
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))
.subscribe(object : CustomSingleObserver<Note>() {
 
Loading
Loading
@@ -213,16 +216,16 @@ class IssueDiscussionFragment : ButterKnifeFragment() {
 
override fun success(note: Note) {
progress.visibility = View.GONE
adapterMergeRequestDetail.addNote(note)
adapter.addNote(note)
listNotes.smoothScrollToPosition(MergeRequestDetailAdapter.headerCount)
}
})
}
 
@Subscribe
fun onMergeRequestChangedEvent(event: MergeRequestChangedEvent) {
if (mergeRequest.id == event.mergeRequest.id) {
mergeRequest = event.mergeRequest
fun onEvent(event: IssueChangedEvent) {
if (issue.iid == event.issue.iid) {
issue = event.issue
loadNotes()
}
}
Loading
Loading
Loading
Loading
@@ -132,10 +132,6 @@ object Navigator {
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) {
val intent = MergeRequestActivity.newIntent(activity, project, mergeRequest)
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
Loading
@@ -2,90 +2,50 @@
<android.support.design.widget.CoordinatorLayout
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:id="@+id/app_bar_container"
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="?attr/actionBarSize"
android:orientation="vertical">
android:layout_height="wrap_content">
 
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<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">
android:layout_height="?attr/actionBarSize"/>
 
<TextView
android:id="@+id/toolbar_title"
style="@style/TextAppearance.AppCompat.Widget.ActionBar.Title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
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" />
<android.support.design.widget.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMode="fixed"/>
 
</LinearLayout>
</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>
 
</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:id="@+id/swipe_layout"
<android.support.v4.view.ViewPager
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="wrap_content">
android:layout_height="match_parent"/>
 
<android.support.v7.widget.RecyclerView
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<include layout="@layout/progress_fullscreen"/>
 
</com.commit451.gitlab.view.LabCoatSwipeRefreshLayout>
</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"/>
</FrameLayout>
 
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab_edit_issue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="16dp"
app:srcCompat="@drawable/ic_edit_24dp"
app:fabSize="mini"
app:layout_anchor="@id/appbar"
app:layout_anchorGravity="bottom|right|end"/>
<include layout="@layout/progress_fullscreen"/>
app:layout_anchorGravity="bottom|right|end"
app:srcCompat="@drawable/ic_edit_24dp"/>
 
</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
Loading
@@ -190,6 +190,12 @@
<string name="root">ROOT</string>
 
<!-- 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="add_issue">Add new issue</string>
<string name="add_issue_dialog_title">New issue</string>
Loading
Loading
Loading
Loading
@@ -2,14 +2,14 @@
apply plugin: 'com.github.ben-manes.versions'
apply plugin: 'com.commit451.updatewrapper'
buildscript {
ext.kotlinVersion = '1.1.4-2'
ext.kotlinVersion = '1.1.4-3'
repositories {
jcenter()
maven { url "https://jitpack.io" }
google()
}
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 'com.github.ben-manes:gradle-versions-plugin:0.15.0'
classpath 'com.github.Commit451:updatewrapper:1.1.2'
Loading
Loading
Loading
Loading
@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
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