add create/edit issue

This commit is contained in:
k0shk0sh 2019-08-01 21:13:04 +02:00
parent 7ee56dbe87
commit fdd8bc81e8
13 changed files with 203 additions and 406 deletions

View File

@ -1,225 +0,0 @@
package com.fastaccess.github.di.modules
import com.apollographql.apollo.ApolloClient
import com.fastaccess.data.repository.*
import com.fastaccess.domain.repository.services.IssuePrService
import com.fastaccess.domain.repository.services.NotificationService
import com.fastaccess.domain.repository.services.RepoService
import com.fastaccess.github.di.scopes.PerFragment
import com.fastaccess.github.usecase.auth.GetAccessTokenUseCase
import com.fastaccess.github.usecase.auth.LoginUseCase
import com.fastaccess.github.usecase.auth.LoginWithAccessTokenUseCase
import com.fastaccess.github.usecase.feed.FeedsUseCase
import com.fastaccess.github.usecase.issuesprs.*
import com.fastaccess.github.usecase.main.IssuesMainScreenUseCase
import com.fastaccess.github.usecase.main.PullRequestsMainScreenUseCase
import com.fastaccess.github.usecase.notification.NotificationUseCase
import com.fastaccess.github.usecase.search.FilterSearchReposUseCase
import com.fastaccess.github.usecase.search.FilterSearchUsersUseCase
import com.fastaccess.github.usecase.user.BlockUnblockUserUseCase
import com.fastaccess.github.usecase.user.IsUserBlockedUseCase
import com.fastaccess.github.usecase.user.UserUseCase
import com.google.gson.Gson
import dagger.Module
import dagger.Provides
/**
* Created by Kosh on 12.05.18.
*/
@Module(includes = [FastHubDatabaseModule::class, NetworkModule::class])
class UseCaseModule {
@PerFragment @Provides fun provideLoginUseCase(
loginRemoteRepository: LoginRepositoryProvider,
schedulerProvider: SchedulerProvider
): LoginUseCase = LoginUseCase(loginRemoteRepository, schedulerProvider)
@PerFragment @Provides fun provideLoginWithAccessTokenUseCase(
loginRemoteRepository: LoginRepositoryProvider,
gson: Gson,
schedulerProvider: SchedulerProvider
): LoginWithAccessTokenUseCase {
return LoginWithAccessTokenUseCase(loginRemoteRepository, gson, schedulerProvider)
}
@PerFragment @Provides fun provideGetAccessTokenUseCase(
loginRemoteRepository: LoginRepositoryProvider,
schedulerProvider: SchedulerProvider
): GetAccessTokenUseCase {
return GetAccessTokenUseCase(loginRemoteRepository, schedulerProvider)
}
@PerFragment @Provides fun provideUserUseCase(
userRepository: UserRepositoryProvider,
schedulerProvider: SchedulerProvider
): UserUseCase = UserUseCase(userRepository, schedulerProvider)
@PerFragment @Provides fun provideIssuesMainScreenUseCase(
loginRepository: LoginRepositoryProvider,
myIssuesPullsRepository: MyIssuesPullsRepositoryProvider,
apolloClient: ApolloClient,
schedulerProvider: SchedulerProvider
): IssuesMainScreenUseCase {
return IssuesMainScreenUseCase(loginRepository, myIssuesPullsRepository, apolloClient, schedulerProvider)
}
@PerFragment @Provides fun providePullRequestsMainScreenUseCase(
loginRepository: LoginRepositoryProvider,
myIssues: MyIssuesPullsRepositoryProvider,
apolloClient: ApolloClient,
schedulerProvider: SchedulerProvider
): PullRequestsMainScreenUseCase {
return PullRequestsMainScreenUseCase(loginRepository, myIssues, apolloClient, schedulerProvider)
}
@PerFragment @Provides fun provideNotificationUseCase(
notificationRepositoryProvider: NotificationRepositoryProvider,
notificationService: NotificationService,
gson: Gson,
schedulerProvider: SchedulerProvider
): NotificationUseCase {
return NotificationUseCase(notificationRepositoryProvider, notificationService, gson, schedulerProvider)
}
@PerFragment @Provides fun provideFeedsUseCase(
provider: FeedsRepositoryProvider,
schedulerProvider: SchedulerProvider
): FeedsUseCase = FeedsUseCase(provider, schedulerProvider)
@PerFragment @Provides fun provideBlockUnblockUserUseCase(
userRepository: UserRepositoryProvider,
schedulerProvider: SchedulerProvider
): BlockUnblockUserUseCase {
return BlockUnblockUserUseCase(userRepository, schedulerProvider)
}
@PerFragment @Provides fun provideIsUserBlockedUseCase(
userRepository: UserRepositoryProvider,
schedulerProvider: SchedulerProvider
): IsUserBlockedUseCase {
return IsUserBlockedUseCase(userRepository, schedulerProvider)
}
@PerFragment @Provides fun provideFilterIssuesUseCase(
loginRepository: LoginRepositoryProvider,
apolloClient: ApolloClient,
schedulerProvider: SchedulerProvider
): FilterIssuesUseCase {
return FilterIssuesUseCase(loginRepository, apolloClient, schedulerProvider)
}
@PerFragment @Provides fun provideFilterPullRequestsUseCase(
loginRepository: LoginRepositoryProvider,
apolloClient: ApolloClient,
schedulerProvider: SchedulerProvider
): FilterPullRequestsUseCase {
return FilterPullRequestsUseCase(loginRepository, apolloClient, schedulerProvider)
}
@PerFragment @Provides fun provideFilterSearchReposUseCase(
apolloClient: ApolloClient,
schedulerProvider: SchedulerProvider
): FilterSearchReposUseCase {
return FilterSearchReposUseCase(apolloClient, schedulerProvider)
}
@PerFragment @Provides fun provideFilterSearchUsersUseCase(
apolloClient: ApolloClient,
schedulerProvider: SchedulerProvider
): FilterSearchUsersUseCase {
return FilterSearchUsersUseCase(apolloClient, schedulerProvider)
}
@PerFragment @Provides fun provideGetIssueUseCase(
issueRepositoryProvider: IssueRepositoryProvider,
apolloClient: ApolloClient,
schedulerProvider: SchedulerProvider
): GetIssueUseCase {
return GetIssueUseCase(issueRepositoryProvider, apolloClient, schedulerProvider)
}
@PerFragment @Provides fun provideGetIssueTimelineUseCase(
issueRepositoryProvider: IssueRepositoryProvider,
apolloClient: ApolloClient,
schedulerProvider: SchedulerProvider
): GetIssueTimelineUseCase {
return GetIssueTimelineUseCase(issueRepositoryProvider, apolloClient, schedulerProvider)
}
@PerFragment @Provides fun provideEditIssuePrUseCase(
issueRepositoryProvider: IssueRepositoryProvider,
issuePrService: IssuePrService,
loginRepositoryProvider: LoginRepositoryProvider,
schedulerProvider: SchedulerProvider
): CloseOpenIssuePrUseCase {
return CloseOpenIssuePrUseCase(issueRepositoryProvider, issuePrService, loginRepositoryProvider, schedulerProvider)
}
@PerFragment @Provides fun provideLockUnlockIssuePrUseCase(
issueRepositoryProvider: IssueRepositoryProvider,
apolloClient: ApolloClient,
loginRepositoryProvider: LoginRepositoryProvider,
schedulerProvider: SchedulerProvider
): LockUnlockIssuePrUseCase {
return LockUnlockIssuePrUseCase(issueRepositoryProvider, apolloClient, loginRepositoryProvider, schedulerProvider)
}
@PerFragment @Provides fun provideGetLabelsUseCase(
apolloClient: ApolloClient,
schedulerProvider: SchedulerProvider
): GetLabelsUseCase {
return GetLabelsUseCase(apolloClient, schedulerProvider)
}
@PerFragment @Provides fun provideCreateLabelUseCase(
repoService: RepoService,
schedulerProvider: SchedulerProvider
): CreateLabelUseCase {
return CreateLabelUseCase(repoService, schedulerProvider)
}
@PerFragment @Provides fun providePutLabelsUseCase(
repoService: RepoService,
schedulerProvider: SchedulerProvider
): PutLabelsUseCase {
return PutLabelsUseCase(repoService, schedulerProvider)
}
@PerFragment @Provides fun provideGetAssigneesUseCase(
apolloClient: ApolloClient,
schedulerProvider: SchedulerProvider
): GetAssigneesUseCase {
return GetAssigneesUseCase(apolloClient, schedulerProvider)
}
@PerFragment @Provides fun provideAddAssigneesUseCase(
repoService: RepoService,
schedulerProvider: SchedulerProvider
): AddAssigneesUseCase {
return AddAssigneesUseCase(repoService, schedulerProvider)
}
@PerFragment @Provides fun provideGetMilestonesUseCase(
apolloClient: ApolloClient,
schedulerProvider: SchedulerProvider
): GetMilestonesUseCase {
return GetMilestonesUseCase(apolloClient, schedulerProvider)
}
@PerFragment @Provides fun provideCreateMilestoneUseCase(
repoService: RepoService,
schedulerProvider: SchedulerProvider
): CreateMilestoneUseCase {
return CreateMilestoneUseCase(repoService, schedulerProvider)
}
@PerFragment @Provides fun provideMilestoneIssuePrUseCase(
issueRepositoryProvider: IssueRepositoryProvider,
issuePrService: IssuePrService,
loginRepositoryProvider: LoginRepositoryProvider,
schedulerProvider: SchedulerProvider
): MilestoneIssuePrUseCase {
return MilestoneIssuePrUseCase(issueRepositoryProvider, issuePrService, loginRepositoryProvider, schedulerProvider)
}
}

View File

@ -133,6 +133,10 @@ class IssueFragment : BaseFragment(), LockUnlockFragment.OnLockReasonSelected,
commentText.setText(data?.getStringExtra(EXTRA))
sendComment.callOnClick()
}
EDIT_ISSUE_REQUEST_CODE -> {
val model = data?.getParcelableExtra<EditIssuePrBundleModel>(EXTRA) ?: return
viewModel.editIssue(login, repo, number, model.title, model.description)
}
else -> Timber.e("nothing yet for requestCode($requestCode)")
}
}

View File

@ -21,10 +21,11 @@ class IssueTimelineViewModel @Inject constructor(
private val issueUseCase: GetIssueUseCase,
private val timelineUseCase: GetIssueTimelineUseCase,
private val issueRepositoryProvider: IssueRepositoryProvider,
private val editIssuePrUseCase: CloseOpenIssuePrUseCase,
private val closeOpenIssuePrUseCase: CloseOpenIssuePrUseCase,
private val lockUnlockIssuePrUseCase: LockUnlockIssuePrUseCase,
private val loginRepositoryProvider: LoginRepositoryProvider,
private val createIssueCommentUseCase: CreateIssueCommentUseCase
private val createIssueCommentUseCase: CreateIssueCommentUseCase,
private val editIssuePrUseCase: EditIssuePrUseCase
) : BaseViewModel() {
private var pageInfo: PageInfoModel? = null
@ -36,10 +37,11 @@ class IssueTimelineViewModel @Inject constructor(
override fun onCleared() {
super.onCleared()
timelineUseCase.dispose()
editIssuePrUseCase.dispose()
closeOpenIssuePrUseCase.dispose()
issueUseCase.dispose()
lockUnlockIssuePrUseCase.dispose()
createIssueCommentUseCase.dispose()
editIssuePrUseCase.dispose()
}
fun getIssue(
@ -99,10 +101,10 @@ class IssueTimelineViewModel @Inject constructor(
repo: String,
number: Int
) {
editIssuePrUseCase.repo = repo
editIssuePrUseCase.login = login
editIssuePrUseCase.number = number
justSubscribe(editIssuePrUseCase.buildObservable()
closeOpenIssuePrUseCase.repo = repo
closeOpenIssuePrUseCase.login = login
closeOpenIssuePrUseCase.number = number
justSubscribe(closeOpenIssuePrUseCase.buildObservable()
.doOnNext {
addTimeline(it)
})
@ -160,4 +162,19 @@ class IssueTimelineViewModel @Inject constructor(
_list.addAll(list.map { it.comment?.author?.login ?: it.comment?.author?.name ?: "" })
userNamesLiveData.postValue(_list)
}
fun editIssue(
login: String,
repo: String,
number: Int,
title: String?,
description: String?
) {
editIssuePrUseCase.login = login
editIssuePrUseCase.repo = repo
editIssuePrUseCase.number = number
editIssuePrUseCase.title = title
editIssuePrUseCase.description = description
justSubscribe(editIssuePrUseCase.buildObservable())
}
}

View File

@ -6,7 +6,6 @@ import android.os.Bundle
import android.view.MotionEvent
import android.view.View
import androidx.core.os.bundleOf
import androidx.core.view.isVisible
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.ViewModelProviders
import com.fastaccess.data.model.parcelable.EditIssuePrBundleModel
@ -14,9 +13,11 @@ import com.fastaccess.github.R
import com.fastaccess.github.base.BaseFragment
import com.fastaccess.github.base.BaseViewModel
import com.fastaccess.github.extensions.observeNotNull
import com.fastaccess.github.extensions.route
import com.fastaccess.github.extensions.routeForResult
import com.fastaccess.github.utils.EDITOR_DEEPLINK
import com.fastaccess.github.utils.EXTRA
import com.fastaccess.github.utils.extensions.asString
import io.noties.markwon.Markwon
import kotlinx.android.synthetic.main.appbar_center_title_layout.*
import kotlinx.android.synthetic.main.edit_issue_pr_fragment_layout.*
@ -44,23 +45,36 @@ class EditIssuePrFragment : BaseFragment() {
savedInstanceState: Bundle?
) {
assigneesLayout.isVisible = model.isOwner
labelsLayout.isVisible = model.isOwner
milestoneLayout.isVisible = model.isOwner
toolbar.title = if (model.isCreate) getString(R.string.create_issue) else getString(R.string.edit)
toolbar.subtitle = "${model.login}/${model.repo}/${getString(R.string.issue)}${if (model.isCreate) "" else "#${model.number}"}"
setToolbarNavigationIcon(R.drawable.ic_clear)
toolbar.inflateMenu(R.menu.submit_menu)
toolbar.setNavigationOnClickListener { activity?.onBackPressed() }
viewModel.templateLiveData.observeNotNull(this) {
if (model.description.isNullOrEmpty()) {
model.description = it
descriptionEditText.post { markwon.setMarkdown(descriptionEditText, it) }
toolbar.setOnMenuItemClickListener {
val title = titleEditText.asString()
val description = model.description
if (title.isEmpty() || model.login.isEmpty() || model.repo.isEmpty()) {
titleInput.error = getString(R.string.required_field)
} else {
titleInput.error = null
if (model.isCreate) {
viewModel.createIssue(model.login, model.repo, title, description)
} else {
model.title = title
val intent = Intent().apply {
putExtra(EXTRA, model)
}
requireActivity().let {
it.setResult(Activity.RESULT_OK, intent)
it.finish()
}
}
}
return@setOnMenuItemClickListener true
}
observeChanges()
if (savedInstanceState == null) {
titleEditText.setText(model.title)
val description = model.description
@ -96,6 +110,20 @@ class EditIssuePrFragment : BaseFragment() {
}
}
private fun observeChanges() {
viewModel.templateLiveData.observeNotNull(this) {
if (model.description.isNullOrEmpty()) {
model.description = it
descriptionEditText.post { markwon.setMarkdown(descriptionEditText, it) }
}
}
viewModel.issueUrlLiveData.observeNotNull(this) {
route(it)
activity?.finish()
}
}
companion object {
private const val COMMENT_REQUEST_CODE = 1001
fun newInstance(bundle: Bundle) = EditIssuePrFragment().apply {

View File

@ -3,17 +3,19 @@ package com.fastaccess.github.ui.modules.issuesprs.edit
import androidx.lifecycle.MutableLiveData
import com.fastaccess.github.base.BaseViewModel
import com.fastaccess.github.usecase.files.GetFileContentUseCase
import timber.log.Timber
import com.fastaccess.github.usecase.issuesprs.CreateIssueUseCase
import javax.inject.Inject
/**
* Created by Kosh on 2019-07-30.
*/
class EditIssuePrViewModel @Inject constructor(
private val getFileContentUseCase: GetFileContentUseCase
private val getFileContentUseCase: GetFileContentUseCase,
private val createIssueUseCase: CreateIssueUseCase
) : BaseViewModel() {
val templateLiveData = MutableLiveData<String>()
val issueUrlLiveData = MutableLiveData<String>()
fun loadTemplate(
login: String,
@ -26,9 +28,22 @@ class EditIssuePrViewModel @Inject constructor(
.map {
it.text?.replace(Regex("(?s)<!--.*?-->"), "")?.replace("<>", "") ?: "" // replace all comments! keep the text small!
}
.doOnNext {
Timber.e(it)
templateLiveData.postValue(it)
})
.doOnNext { templateLiveData.postValue(it) })
}
fun createIssue(
login: String,
repo: String,
title: String,
description: String?
) {
createIssueUseCase.login = login
createIssueUseCase.repo = repo
createIssueUseCase.title = title
createIssueUseCase.description = description
justSubscribe(
createIssueUseCase.buildObservable()
.doOnNext { issueUrlLiveData.postValue(it) }
)
}
}

View File

@ -1,7 +1,7 @@
package com.fastaccess.github.usecase.issuesprs
import com.fastaccess.data.repository.SchedulerProvider
import com.fastaccess.domain.repository.services.RepoService
import com.fastaccess.domain.repository.services.IssuePrService
import com.fastaccess.domain.response.body.AssigneesBodyModel
import com.fastaccess.domain.usecase.base.BaseObservableUseCase
import io.reactivex.Observable
@ -11,7 +11,7 @@ import javax.inject.Inject
* Created by Kosh on 16.02.19.
*/
class AddAssigneesUseCase @Inject constructor(
private val repoService: RepoService,
private val service: IssuePrService,
private val schedulerProvider: SchedulerProvider
) : BaseObservableUseCase() {
@ -22,14 +22,14 @@ class AddAssigneesUseCase @Inject constructor(
var toRemove: List<String>? = null
override fun buildObservable(): Observable<Boolean> = when (toRemove.isNullOrEmpty()) {
true -> repoService.addAssignees(login, repo, number, AssigneesBodyModel(assignees))
true -> service.addAssignees(login, repo, number, AssigneesBodyModel(assignees))
.subscribeOn(schedulerProvider.ioThread())
.observeOn(schedulerProvider.uiThread())
.map { true }
else -> repoService.removeAssignees(login, repo, number, AssigneesBodyModel(toRemove))
else -> service.removeAssignees(login, repo, number, AssigneesBodyModel(toRemove))
.subscribeOn(schedulerProvider.ioThread())
.observeOn(schedulerProvider.uiThread())
.flatMap { repoService.addAssignees(login, repo, number, AssigneesBodyModel(assignees)) }
.flatMap { service.addAssignees(login, repo, number, AssigneesBodyModel(assignees)) }
.map { true }
}
}

View File

@ -0,0 +1,27 @@
package com.fastaccess.github.usecase.issuesprs
import com.fastaccess.data.repository.SchedulerProvider
import com.fastaccess.domain.repository.services.IssuePrService
import com.fastaccess.domain.response.IssueRequestModel
import com.fastaccess.domain.usecase.base.BaseObservableUseCase
import io.reactivex.Observable
import javax.inject.Inject
/**
* Created by Kosh on 16.02.19.
*/
class CreateIssueUseCase @Inject constructor(
private val issuePrService: IssuePrService,
private val schedulerProvider: SchedulerProvider
) : BaseObservableUseCase() {
var repo: String = ""
var login: String = ""
var title: String = ""
var description: String? = null
override fun buildObservable(): Observable<String> = issuePrService.createIssue(login, repo, IssueRequestModel(title, description))
.subscribeOn(schedulerProvider.ioThread())
.observeOn(schedulerProvider.uiThread())
.map { it.htmlUrl }
}

View File

@ -0,0 +1,40 @@
package com.fastaccess.github.usecase.issuesprs
import com.fastaccess.data.repository.IssueRepositoryProvider
import com.fastaccess.data.repository.SchedulerProvider
import com.fastaccess.domain.repository.services.IssuePrService
import com.fastaccess.domain.response.IssueRequestModel
import com.fastaccess.domain.usecase.base.BaseObservableUseCase
import io.reactivex.Observable
import javax.inject.Inject
/**
* Created by Kosh on 16.02.19.
*/
class EditIssuePrUseCase @Inject constructor(
private val issueRepositoryProvider: IssueRepositoryProvider,
private val issuePrService: IssuePrService,
private val schedulerProvider: SchedulerProvider
) : BaseObservableUseCase() {
var repo: String = ""
var login: String = ""
var number: Int = -1
var title: String? = null
var description: String? = null
override fun buildObservable(): Observable<Boolean> = issueRepositoryProvider.getIssueByNumberMaybe("$login/$repo", number)
.subscribeOn(schedulerProvider.ioThread())
.observeOn(schedulerProvider.uiThread())
.flatMapObservable { issue ->
issuePrService.editIssue(login, repo, number, IssueRequestModel(title = title, body = description))
.subscribeOn(schedulerProvider.ioThread())
.observeOn(schedulerProvider.uiThread())
.map {
issue.title = it.title
issue.body = it.body
issueRepositoryProvider.upsert(issue)
return@map true
}
}
}

View File

@ -1,7 +1,7 @@
package com.fastaccess.github.usecase.issuesprs
import com.fastaccess.data.repository.SchedulerProvider
import com.fastaccess.domain.repository.services.RepoService
import com.fastaccess.domain.repository.services.IssuePrService
import com.fastaccess.domain.response.body.LabelsBodyModel
import com.fastaccess.domain.usecase.base.BaseObservableUseCase
import io.reactivex.Observable
@ -11,7 +11,7 @@ import javax.inject.Inject
* Created by Kosh on 16.02.19.
*/
class PutLabelsUseCase @Inject constructor(
private val repoService: RepoService,
private val issueService: IssuePrService,
private val schedulerProvider: SchedulerProvider
) : BaseObservableUseCase() {
@ -22,15 +22,15 @@ class PutLabelsUseCase @Inject constructor(
var toRemove: List<String>? = null
override fun buildObservable(): Observable<Boolean> = when (toRemove.isNullOrEmpty()) {
true -> repoService.addLabelsToIssue(login, repo, number, LabelsBodyModel(toAdd))
true -> issueService.addLabelsToIssue(login, repo, number, LabelsBodyModel(toAdd))
.subscribeOn(schedulerProvider.ioThread())
.observeOn(schedulerProvider.uiThread())
.map { true }
else -> repoService.addLabelsToIssue(login, repo, number, LabelsBodyModel(toAdd))
else -> issueService.addLabelsToIssue(login, repo, number, LabelsBodyModel(toAdd))
.subscribeOn(schedulerProvider.ioThread())
.observeOn(schedulerProvider.uiThread())
.flatMap { Observable.fromIterable(toRemove) }
.flatMap { repoService.removeLabelsToIssue(login, repo, number, it) }
.flatMap { issueService.removeLabelsToIssue(login, repo, number, it) }
.map { true }
}
}

View File

@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.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:layout_width="match_parent"
android:layout_height="match_parent">
@ -73,131 +72,9 @@
android:gravity="top|start"
android:inputType="none"
android:maxLines="20"
android:minLines="5" />
android:minLines="10" />
</com.google.android.material.textfield.TextInputLayout>
<LinearLayout
android:id="@+id/assigneesLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/spacing_xs_large"
android:layout_marginBottom="@dimen/spacing_normal"
android:orientation="vertical">
<androidx.appcompat.widget.AppCompatTextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/spacing_xs_large"
android:drawableEnd="@drawable/ic_add"
android:fontFamily="@font/rubik_bold"
android:gravity="center|start"
android:paddingTop="@dimen/spacing_xs_large"
android:paddingBottom="@dimen/spacing_xs_large"
android:text="@string/assignees"
android:textAllCaps="true"
android:textAppearance="@style/TextAppearance.AppCompat.Subhead"
android:textStyle="bold" />
<com.google.android.material.card.MaterialCardView
style="@style/CardViewStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardCornerRadius="10dp">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/assigneesList"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="@dimen/spacing_normal"
android:paddingBottom="@dimen/spacing_normal"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
tools:text="All children like flattened walnuts in peanut sauce and wasabi." />
</com.google.android.material.card.MaterialCardView>
</LinearLayout>
<LinearLayout
android:id="@+id/labelsLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/spacing_xs_large"
android:layout_marginBottom="@dimen/spacing_normal"
android:orientation="vertical">
<androidx.appcompat.widget.AppCompatTextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/spacing_xs_large"
android:drawableEnd="@drawable/ic_add"
android:fontFamily="@font/rubik_bold"
android:gravity="center|start"
android:paddingTop="@dimen/spacing_xs_large"
android:paddingBottom="@dimen/spacing_xs_large"
android:text="@string/labels"
android:textAllCaps="true"
android:textAppearance="@style/TextAppearance.AppCompat.Subhead"
android:textStyle="bold" />
<com.google.android.material.card.MaterialCardView
style="@style/CardViewStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardCornerRadius="10dp">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/labelsList"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="@dimen/spacing_normal"
android:paddingBottom="@dimen/spacing_normal"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
tools:text="All children like flattened walnuts in peanut sauce and wasabi." />
</com.google.android.material.card.MaterialCardView>
</LinearLayout>
<LinearLayout
android:id="@+id/milestoneLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/spacing_xs_large"
android:layout_marginBottom="@dimen/spacing_normal"
android:orientation="vertical">
<androidx.appcompat.widget.AppCompatTextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/spacing_xs_large"
android:drawableEnd="@drawable/ic_add"
android:fontFamily="@font/rubik_bold"
android:gravity="center|start"
android:paddingTop="@dimen/spacing_xs_large"
android:paddingBottom="@dimen/spacing_xs_large"
android:text="@string/milestone"
android:textAllCaps="true"
android:textAppearance="@style/TextAppearance.AppCompat.Subhead"
android:textStyle="bold" />
<com.google.android.material.card.MaterialCardView
style="@style/CardViewStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardCornerRadius="10dp">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/assignees"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="@dimen/spacing_normal"
android:paddingBottom="@dimen/spacing_normal"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
tools:text="All children like flattened walnuts in peanut sauce and wasabi." />
</com.google.android.material.card.MaterialCardView>
</LinearLayout>
</LinearLayout>
</androidx.core.widget.NestedScrollView>

View File

@ -2,7 +2,10 @@ package com.fastaccess.domain.repository.services
import com.fastaccess.domain.response.IssueRequestModel
import com.fastaccess.domain.response.IssueResponse
import com.fastaccess.domain.response.LabelResponse
import com.fastaccess.domain.response.body.AssigneesBodyModel
import com.fastaccess.domain.response.body.CommentRequestModel
import com.fastaccess.domain.response.body.LabelsBodyModel
import io.reactivex.Observable
import retrofit2.Response
import retrofit2.http.*
@ -21,13 +24,20 @@ interface IssuePrService {
@Body issue: IssueRequestModel
): Observable<IssueResponse>
@PATCH("repos/{owner}/{repo}/issues")
fun createIssue(
@Path("owner") owner: String,
@Path("repo") repo: String,
@Body issue: IssueRequestModel
): Observable<IssueResponse>
@POST("repos/{owner}/{repo}/issues/{number}/comments")
fun createIssueComment(
@Path("owner") owner: String,
@Path("repo") repo: String,
@Path("number") number: Int,
@Body body: CommentRequestModel
): Observable<Response<Void>>
): Observable<Response<Void>>
@PATCH("repos/{owner}/{repo}/issues/comments/{id}")
fun editIssueComment(
@ -43,4 +53,29 @@ interface IssuePrService {
@Path("repo") repo: String,
@Path("id") id: Long
): Observable<Response<Void>>
@POST("repos/{owner}/{repo}/issues/{number}/labels")
fun addLabelsToIssue(
@Path("owner") owner: String, @Path("repo") repo: String, @Path("number") number: Int,
@Body body: LabelsBodyModel
): Observable<LabelResponse>
@HTTP(method = "DELETE", path = "repos/{owner}/{repo}/issues/{number}/labels/{name}", hasBody = false)
fun removeLabelsToIssue(
@Path("owner") owner: String, @Path("repo") repo: String, @Path("number") number: Int,
@Path("name") name: String
): Observable<LabelResponse>
@POST("repos/{owner}/{repo}/issues/{number}/assignees")
fun addAssignees(
@Path("owner") owner: String, @Path("repo") repo: String, @Path("number") number: Int,
@Body body: AssigneesBodyModel
): Observable<IssueResponse>
@HTTP(method = "DELETE", path = "repos/{owner}/{repo}/issues/{number}/assignees", hasBody = true)
fun removeAssignees(
@Path("owner") owner: String, @Path("repo") repo: String, @Path("number") number: Int,
@Body body: AssigneesBodyModel
): Observable<IssueResponse>
}

View File

@ -1,14 +1,10 @@
package com.fastaccess.domain.repository.services
import com.fastaccess.domain.response.IssueResponse
import com.fastaccess.domain.response.LabelResponse
import com.fastaccess.domain.response.body.AssigneesBodyModel
import com.fastaccess.domain.response.body.LabelsBodyModel
import com.fastaccess.domain.response.body.MilestoneBodyModel
import io.reactivex.Observable
import okhttp3.ResponseBody
import retrofit2.http.Body
import retrofit2.http.HTTP
import retrofit2.http.POST
import retrofit2.http.Path
@ -19,23 +15,6 @@ interface RepoService {
@POST("repos/{owner}/{repo}/labels")
fun addLabel(@Path("owner") owner: String, @Path("repo") repo: String, @Body body: LabelResponse): Observable<LabelResponse>
@POST("repos/{owner}/{repo}/issues/{number}/labels")
fun addLabelsToIssue(@Path("owner") owner: String, @Path("repo") repo: String, @Path("number") number: Int,
@Body body: LabelsBodyModel): Observable<LabelResponse>
@HTTP(method = "DELETE", path = "repos/{owner}/{repo}/issues/{number}/labels/{name}", hasBody = false)
fun removeLabelsToIssue(@Path("owner") owner: String, @Path("repo") repo: String, @Path("number") number: Int,
@Path("name") name: String): Observable<LabelResponse>
@POST("repos/{owner}/{repo}/issues/{number}/assignees")
fun addAssignees(@Path("owner") owner: String, @Path("repo") repo: String, @Path("number") number: Int,
@Body body: AssigneesBodyModel): Observable<IssueResponse>
@HTTP(method = "DELETE", path = "repos/{owner}/{repo}/issues/{number}/assignees", hasBody = true)
fun removeAssignees(@Path("owner") owner: String, @Path("repo") repo: String, @Path("number") number: Int,
@Body body: AssigneesBodyModel): Observable<IssueResponse>
@POST("repos/{owner}/{repo}/milestones")
fun createMilestone(@Path("owner") owner: String, @Path("repo") repo: String,
@Body create: MilestoneBodyModel): Observable<ResponseBody>

View File

@ -5,8 +5,8 @@
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#000"
android:fillColor="?icon_color"
android:fillType="nonZero"
android:pathData="M20,2H4c-1.1,0 -1.99,0.9 -1.99,2L2,22l4,-4h14c1.1,0 2,-0.9 2,-2V4c0,-1.1 -0.9,-2 -2,-2z"
tools:fillColor="?icon_color" />
tools:fillColor="#000" />
</vector>