diff --git a/app/src/main/java/com/fastaccess/github/base/BaseViewModel.kt b/app/src/main/java/com/fastaccess/github/base/BaseViewModel.kt index 15252175..38198b6e 100644 --- a/app/src/main/java/com/fastaccess/github/base/BaseViewModel.kt +++ b/app/src/main/java/com/fastaccess/github/base/BaseViewModel.kt @@ -3,7 +3,6 @@ package com.fastaccess.github.base import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import com.fastaccess.data.model.FastHubErrors -import com.fastaccess.extension.uiThread import com.fastaccess.github.R import com.google.gson.Gson import io.reactivex.Completable @@ -66,14 +65,12 @@ abstract class BaseViewModel : ViewModel() { } protected fun callApi(observable: Observable): Observable = observable - .uiThread() .doOnSubscribe { showProgress() } .doOnNext { hideProgress() } .doOnError { handleError(it) } .doOnComplete { hideProgress() } protected fun callApi(completable: Completable): Completable = completable - .uiThread() .doOnSubscribe { showProgress() } .doOnComplete { hideProgress() } .doOnError { handleError(it) } diff --git a/app/src/main/java/com/fastaccess/github/di/modules/FragmentModule.kt b/app/src/main/java/com/fastaccess/github/di/modules/FragmentModule.kt index 1d8204c0..64934cf2 100644 --- a/app/src/main/java/com/fastaccess/github/di/modules/FragmentModule.kt +++ b/app/src/main/java/com/fastaccess/github/di/modules/FragmentModule.kt @@ -4,6 +4,9 @@ import android.content.Context import com.fastaccess.github.di.annotations.ForApplication import com.fastaccess.github.di.scopes.PerFragment import com.fastaccess.github.extensions.getDrawableCompat +import com.fastaccess.github.platform.mentions.MentionsPresenter +import com.fastaccess.github.ui.modules.issue.fragment.IssueFragment +import com.fastaccess.github.usecase.search.FilterSearchUsersUseCase import com.fastaccess.markdown.R import com.fastaccess.markdown.spans.* import dagger.Module @@ -18,6 +21,8 @@ import net.nightwhistler.htmlspanner.style.Style @Module class FragmentModule { + @PerFragment @Provides fun provideContext(fragment: IssueFragment) = fragment.requireContext() + @PerFragment @Provides fun provideHtmlSpanner(@ForApplication context: Context): HtmlSpanner { val mySpanner = HtmlSpanner() mySpanner.isStripExtraWhiteSpace = true @@ -48,4 +53,9 @@ class FragmentModule { mySpanner.registerHandler("h6", HeaderHandler(1.0f)) return mySpanner } + + @PerFragment @Provides fun provideMentionsPresenter( + context: Context, + searchUsersUseCase: FilterSearchUsersUseCase + ) = MentionsPresenter(context, searchUsersUseCase) } \ No newline at end of file diff --git a/app/src/main/java/com/fastaccess/github/di/modules/NetworkModule.kt b/app/src/main/java/com/fastaccess/github/di/modules/NetworkModule.kt index 4daca5e9..1e5e2149 100644 --- a/app/src/main/java/com/fastaccess/github/di/modules/NetworkModule.kt +++ b/app/src/main/java/com/fastaccess/github/di/modules/NetworkModule.kt @@ -25,6 +25,7 @@ import java.lang.reflect.Type import java.net.URI import java.text.SimpleDateFormat import java.util.* +import javax.inject.Named import javax.inject.Singleton /** @@ -52,6 +53,14 @@ class NetworkModule { .addInterceptor(HttpLoggingInterceptor()) .build() + @Named("apolloClient") @Singleton @Provides fun provideHttpClientForApollo(auth: AuthenticationInterceptor): OkHttpClient = OkHttpClient + .Builder() + .addInterceptor(auth) + .addInterceptor(Pandora.get().interceptor) + .addInterceptor(HttpLoggingInterceptor()) + .build() + + @Singleton @Provides fun provideRetrofit( gson: Gson, okHttpClient: OkHttpClient @@ -70,12 +79,13 @@ class NetworkModule { .addConverterFactory(GithubResponseConverter(gson)) .client(okHttpClient) - @Singleton @Provides fun provideApollo(okHttpClient: OkHttpClient): ApolloClient = ApolloClient.builder() + @Singleton @Provides fun provideApollo(@Named("apolloClient") okHttpClient: OkHttpClient): ApolloClient = ApolloClient.builder() .serverUrl(BuildConfig.GRAPHQL_REST_URL) .okHttpClient(okHttpClient) .addCustomTypeAdapter(CustomType.URI, UriApolloAdapter()) .addCustomTypeAdapter(CustomType.DATETIME, DateApolloAdapter()) .addCustomTypeAdapter(CustomType.HTML, ObjectApolloAdapter()) + .addCustomTypeAdapter(CustomType.ID, ObjectApolloAdapter()) .build() @Singleton @Provides fun provideLoginService(retrofit: Retrofit): LoginService = retrofit.create(LoginService::class.java) diff --git a/app/src/main/java/com/fastaccess/github/di/modules/RepositoryModule.kt b/app/src/main/java/com/fastaccess/github/di/modules/RepositoryModule.kt index b6a2ed43..8f145d9d 100644 --- a/app/src/main/java/com/fastaccess/github/di/modules/RepositoryModule.kt +++ b/app/src/main/java/com/fastaccess/github/di/modules/RepositoryModule.kt @@ -35,8 +35,11 @@ class RepositoryModule { return MyIssuesPullsRepositoryProvider(fastHubDatabase.getMainIssuesPullsDao()) } - @Singleton @Provides fun provideNotificationRepositoryProvider(fastHubDatabase: FastHubDatabase): NotificationRepositoryProvider { - return NotificationRepositoryProvider(fastHubDatabase.getNotifications()) + @Singleton @Provides fun provideNotificationRepositoryProvider( + fastHubDatabase: FastHubDatabase, + schedulerProvider: SchedulerProvider + ): NotificationRepositoryProvider { + return NotificationRepositoryProvider(fastHubDatabase.getNotifications(), schedulerProvider) } @Singleton @Provides fun provideFeedsRepositoryProvider( @@ -91,4 +94,6 @@ class RepositoryModule { @Singleton @Provides fun provideSuggestionRepositoryProvider(fastHubDatabase: FastHubDatabase): SuggestionRepositoryProvider { return SuggestionRepositoryProvider(fastHubDatabase.getSuggestionDao()) } + + @Singleton @Provides fun provideAndroidSchedulerProvider(): SchedulerProvider = AndroidSchedulerProvider() } \ No newline at end of file diff --git a/app/src/main/java/com/fastaccess/github/di/modules/UseCaseModule.kt b/app/src/main/java/com/fastaccess/github/di/modules/UseCaseModule.kt index 15e85645..b681377d 100644 --- a/app/src/main/java/com/fastaccess/github/di/modules/UseCaseModule.kt +++ b/app/src/main/java/com/fastaccess/github/di/modules/UseCaseModule.kt @@ -33,155 +33,190 @@ class UseCaseModule { @PerFragment @Provides fun provideLoginWithAccessTokenUseCase( loginRemoteRepository: LoginRepositoryProvider, - gson: Gson + gson: Gson, + schedulerProvider: SchedulerProvider ): LoginWithAccessTokenUseCase { - return LoginWithAccessTokenUseCase(loginRemoteRepository, gson) + return LoginWithAccessTokenUseCase(loginRemoteRepository, gson, schedulerProvider) } - @PerFragment @Provides fun provideGetAccessTokenUseCase(loginRemoteRepository: LoginRepositoryProvider): GetAccessTokenUseCase { - return GetAccessTokenUseCase(loginRemoteRepository) + @PerFragment @Provides fun provideGetAccessTokenUseCase( + loginRemoteRepository: LoginRepositoryProvider, + schedulerProvider: SchedulerProvider + ): GetAccessTokenUseCase { + return GetAccessTokenUseCase(loginRemoteRepository, schedulerProvider) } - @PerFragment @Provides fun provideUserUseCase(userRepository: UserRepositoryProvider): UserUseCase = UserUseCase(userRepository) + @PerFragment @Provides fun provideUserUseCase( + userRepository: UserRepositoryProvider, + schedulerProvider: SchedulerProvider + ): UserUseCase = UserUseCase(userRepository, schedulerProvider) @PerFragment @Provides fun provideIssuesMainScreenUseCase( loginRepository: LoginRepositoryProvider, myIssuesPullsRepository: MyIssuesPullsRepositoryProvider, - apolloClient: ApolloClient + apolloClient: ApolloClient, + schedulerProvider: SchedulerProvider ): IssuesMainScreenUseCase { - return IssuesMainScreenUseCase(loginRepository, myIssuesPullsRepository, apolloClient) + return IssuesMainScreenUseCase(loginRepository, myIssuesPullsRepository, apolloClient, schedulerProvider) } @PerFragment @Provides fun providePullRequestsMainScreenUseCase( loginRepository: LoginRepositoryProvider, myIssues: MyIssuesPullsRepositoryProvider, - apolloClient: ApolloClient + apolloClient: ApolloClient, + schedulerProvider: SchedulerProvider ): PullRequestsMainScreenUseCase { - return PullRequestsMainScreenUseCase(loginRepository, myIssues, apolloClient) + return PullRequestsMainScreenUseCase(loginRepository, myIssues, apolloClient, schedulerProvider) } @PerFragment @Provides fun provideNotificationUseCase( notificationRepositoryProvider: NotificationRepositoryProvider, notificationService: NotificationService, - gson: Gson + gson: Gson, + schedulerProvider: SchedulerProvider ): NotificationUseCase { - return NotificationUseCase(notificationRepositoryProvider, notificationService, gson) + return NotificationUseCase(notificationRepositoryProvider, notificationService, gson, schedulerProvider) } - @PerFragment @Provides fun provideFeedsUseCase(provider: FeedsRepositoryProvider): FeedsUseCase = FeedsUseCase(provider) + @PerFragment @Provides fun provideFeedsUseCase( + provider: FeedsRepositoryProvider, + schedulerProvider: SchedulerProvider + ): FeedsUseCase = FeedsUseCase(provider, schedulerProvider) - @PerFragment @Provides fun provideBlockUnblockUserUseCase(userRepository: UserRepositoryProvider): BlockUnblockUserUseCase { - return BlockUnblockUserUseCase(userRepository) + @PerFragment @Provides fun provideBlockUnblockUserUseCase( + userRepository: UserRepositoryProvider, + schedulerProvider: SchedulerProvider + ): BlockUnblockUserUseCase { + return BlockUnblockUserUseCase(userRepository, schedulerProvider) } - @PerFragment @Provides fun provideIsUserBlockedUseCase(userRepository: UserRepositoryProvider): IsUserBlockedUseCase { - return IsUserBlockedUseCase(userRepository) + @PerFragment @Provides fun provideIsUserBlockedUseCase( + userRepository: UserRepositoryProvider, + schedulerProvider: SchedulerProvider + ): IsUserBlockedUseCase { + return IsUserBlockedUseCase(userRepository, schedulerProvider) } @PerFragment @Provides fun provideFilterIssuesUseCase( loginRepository: LoginRepositoryProvider, - apolloClient: ApolloClient + apolloClient: ApolloClient, + schedulerProvider: SchedulerProvider ): FilterIssuesUseCase { - return FilterIssuesUseCase(loginRepository, apolloClient) + return FilterIssuesUseCase(loginRepository, apolloClient, schedulerProvider) } @PerFragment @Provides fun provideFilterPullRequestsUseCase( loginRepository: LoginRepositoryProvider, - apolloClient: ApolloClient + apolloClient: ApolloClient, + schedulerProvider: SchedulerProvider ): FilterPullRequestsUseCase { - return FilterPullRequestsUseCase(loginRepository, apolloClient) + return FilterPullRequestsUseCase(loginRepository, apolloClient, schedulerProvider) } @PerFragment @Provides fun provideFilterSearchReposUseCase( - apolloClient: ApolloClient + apolloClient: ApolloClient, + schedulerProvider: SchedulerProvider ): FilterSearchReposUseCase { - return FilterSearchReposUseCase(apolloClient) + return FilterSearchReposUseCase(apolloClient, schedulerProvider) } @PerFragment @Provides fun provideFilterSearchUsersUseCase( - apolloClient: ApolloClient + apolloClient: ApolloClient, + schedulerProvider: SchedulerProvider ): FilterSearchUsersUseCase { - return FilterSearchUsersUseCase(apolloClient) + return FilterSearchUsersUseCase(apolloClient, schedulerProvider) } @PerFragment @Provides fun provideGetIssueUseCase( issueRepositoryProvider: IssueRepositoryProvider, - apolloClient: ApolloClient + apolloClient: ApolloClient, + schedulerProvider: SchedulerProvider ): GetIssueUseCase { - return GetIssueUseCase(issueRepositoryProvider, apolloClient) + return GetIssueUseCase(issueRepositoryProvider, apolloClient, schedulerProvider) } @PerFragment @Provides fun provideGetIssueTimelineUseCase( issueRepositoryProvider: IssueRepositoryProvider, - apolloClient: ApolloClient + apolloClient: ApolloClient, + schedulerProvider: SchedulerProvider ): GetIssueTimelineUseCase { - return GetIssueTimelineUseCase(issueRepositoryProvider, apolloClient) + return GetIssueTimelineUseCase(issueRepositoryProvider, apolloClient, schedulerProvider) } @PerFragment @Provides fun provideEditIssuePrUseCase( issueRepositoryProvider: IssueRepositoryProvider, issuePrService: IssuePrService, - loginRepositoryProvider: LoginRepositoryProvider + loginRepositoryProvider: LoginRepositoryProvider, + schedulerProvider: SchedulerProvider ): CloseOpenIssuePrUseCase { - return CloseOpenIssuePrUseCase(issueRepositoryProvider, issuePrService, loginRepositoryProvider) + return CloseOpenIssuePrUseCase(issueRepositoryProvider, issuePrService, loginRepositoryProvider, schedulerProvider) } @PerFragment @Provides fun provideLockUnlockIssuePrUseCase( issueRepositoryProvider: IssueRepositoryProvider, apolloClient: ApolloClient, - loginRepositoryProvider: LoginRepositoryProvider + loginRepositoryProvider: LoginRepositoryProvider, + schedulerProvider: SchedulerProvider ): LockUnlockIssuePrUseCase { - return LockUnlockIssuePrUseCase(issueRepositoryProvider, apolloClient, loginRepositoryProvider) + return LockUnlockIssuePrUseCase(issueRepositoryProvider, apolloClient, loginRepositoryProvider, schedulerProvider) } @PerFragment @Provides fun provideGetLabelsUseCase( - apolloClient: ApolloClient + apolloClient: ApolloClient, + schedulerProvider: SchedulerProvider ): GetLabelsUseCase { - return GetLabelsUseCase(apolloClient) + return GetLabelsUseCase(apolloClient, schedulerProvider) } @PerFragment @Provides fun provideCreateLabelUseCase( - repoService: RepoService + repoService: RepoService, + schedulerProvider: SchedulerProvider ): CreateLabelUseCase { - return CreateLabelUseCase(repoService) + return CreateLabelUseCase(repoService, schedulerProvider) } @PerFragment @Provides fun providePutLabelsUseCase( - repoService: RepoService + repoService: RepoService, + schedulerProvider: SchedulerProvider ): PutLabelsUseCase { - return PutLabelsUseCase(repoService) + return PutLabelsUseCase(repoService, schedulerProvider) } @PerFragment @Provides fun provideGetAssigneesUseCase( - apolloClient: ApolloClient + apolloClient: ApolloClient, + schedulerProvider: SchedulerProvider ): GetAssigneesUseCase { - return GetAssigneesUseCase(apolloClient) + return GetAssigneesUseCase(apolloClient, schedulerProvider) } @PerFragment @Provides fun provideAddAssigneesUseCase( - repoService: RepoService + repoService: RepoService, + schedulerProvider: SchedulerProvider ): AddAssigneesUseCase { - return AddAssigneesUseCase(repoService) + return AddAssigneesUseCase(repoService, schedulerProvider) } @PerFragment @Provides fun provideGetMilestonesUseCase( - apolloClient: ApolloClient + apolloClient: ApolloClient, + schedulerProvider: SchedulerProvider ): GetMilestonesUseCase { - return GetMilestonesUseCase(apolloClient) + return GetMilestonesUseCase(apolloClient, schedulerProvider) } @PerFragment @Provides fun provideCreateMilestoneUseCase( - repoService: RepoService + repoService: RepoService, + schedulerProvider: SchedulerProvider ): CreateMilestoneUseCase { - return CreateMilestoneUseCase(repoService) + return CreateMilestoneUseCase(repoService, schedulerProvider) } @PerFragment @Provides fun provideMilestoneIssuePrUseCase( issueRepositoryProvider: IssueRepositoryProvider, issuePrService: IssuePrService, - loginRepositoryProvider: LoginRepositoryProvider + loginRepositoryProvider: LoginRepositoryProvider, + schedulerProvider: SchedulerProvider ): MilestoneIssuePrUseCase { - return MilestoneIssuePrUseCase(issueRepositoryProvider, issuePrService, loginRepositoryProvider) + return MilestoneIssuePrUseCase(issueRepositoryProvider, issuePrService, loginRepositoryProvider, schedulerProvider) } } \ No newline at end of file diff --git a/app/src/main/java/com/fastaccess/github/platform/mentions/MentionsPresenter.kt b/app/src/main/java/com/fastaccess/github/platform/mentions/MentionsPresenter.kt new file mode 100644 index 00000000..050853d5 --- /dev/null +++ b/app/src/main/java/com/fastaccess/github/platform/mentions/MentionsPresenter.kt @@ -0,0 +1,93 @@ +package com.fastaccess.github.platform.mentions + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.fastaccess.github.ui.adapter.base.BaseViewHolder +import com.fastaccess.github.usecase.search.FilterSearchUsersUseCase +import com.otaliastudios.autocomplete.RecyclerViewPresenter +import timber.log.Timber +import javax.inject.Inject + +/** + * Created by Kosh on 2019-07-18. + */ +class MentionsPresenter @Inject constructor( + c: Context, + private val searchUsersUseCase: FilterSearchUsersUseCase +) : RecyclerViewPresenter(c) { + + private val localList = ArrayList() + + private val adapter by lazy { MentionsAdapter(this, arrayListOf()) } + + override fun instantiateAdapter(): RecyclerView.Adapter<*> = adapter + + override fun onQuery(query: CharSequence?) { + Timber.e("$query") + if (!query.isNullOrEmpty()) { + if (localList.firstOrNull { it.contains(query) } != null) { + Timber.e("current list has the query($query)") +// searchUsersUseCase.dispose() + return + } + searchUsersUseCase.keyword = query.toString() + searchUsersUseCase.executeSafely(searchUsersUseCase.buildObservable() + .map { result -> result.second.map { it.login ?: it.name ?: "" } } + .doOnNext { + Timber.e("result($it)") + localList.clear() + setUsers(it) + }) + } + } + + fun setUsers(newList: List) { + localList.addAll(newList) + adapter.newList(localList.distinct()) + } + + fun onClick(item: String) = dispatchClick(item) + + fun onDispose() = searchUsersUseCase.dispose() +} + +class MentionsAdapter( + private val presenter: MentionsPresenter, + private val list: ArrayList +) : RecyclerView.Adapter() { + + override fun onCreateViewHolder( + parent: ViewGroup, + viewType: Int + ): MentionsViewHolder = MentionsViewHolder( + LayoutInflater.from(parent.context).inflate( + android.R.layout.simple_list_item_1, + parent, false + ) + ).apply { + itemView.setOnClickListener { presenter.onClick(list.getOrNull(adapterPosition) ?: "") } + } + + override fun getItemCount(): Int = list.size + + override fun onBindViewHolder( + holder: MentionsViewHolder, + position: Int + ) = holder.bind(list.getOrNull(position) ?: "") + + fun newList(newList: List) { + list.clear() + list.addAll(newList) + notifyDataSetChanged() + } + + class MentionsViewHolder(view: View) : BaseViewHolder(view) { + override fun bind(item: String) { + itemView.findViewById(android.R.id.text1).text = item + } + } +} diff --git a/app/src/main/java/com/fastaccess/github/ui/modules/auth/chooser/LoginChooserFragment.kt b/app/src/main/java/com/fastaccess/github/ui/modules/auth/chooser/LoginChooserFragment.kt index 5da49a68..372f0ceb 100644 --- a/app/src/main/java/com/fastaccess/github/ui/modules/auth/chooser/LoginChooserFragment.kt +++ b/app/src/main/java/com/fastaccess/github/ui/modules/auth/chooser/LoginChooserFragment.kt @@ -6,7 +6,7 @@ import android.view.View import androidx.core.view.isVisible import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProviders -import com.fastaccess.extension.uiThread +import com.fastaccess.data.repository.SchedulerProvider import com.fastaccess.github.R import com.fastaccess.github.base.BaseFragment import com.fastaccess.github.base.BaseViewModel @@ -23,15 +23,19 @@ import javax.inject.Inject */ class LoginChooserFragment : BaseFragment() { @Inject lateinit var viewModelFactory: ViewModelProvider.Factory + @Inject lateinit var schedulerProvider: SchedulerProvider private val viewModel by lazy { ViewModelProviders.of(requireActivity(), viewModelFactory).get(LoginChooserViewModel::class.java) } private var callback: LoginChooserCallback? = null private val adapter by lazy { LoggedInUsersAdapter { user -> - addDisposal(viewModel.reLogin(user) - .uiThread() - .subscribe({ (requireActivity() as? LoginChooserCallback)?.onUserLoggedIn(user) }, - { throwable -> view?.let { showSnackBar(it, message = throwable.message) } })) + addDisposal( + viewModel.reLogin(user) + .subscribeOn(schedulerProvider.ioThread()) + .observeOn(schedulerProvider.uiThread()) + .subscribe({ (requireActivity() as? LoginChooserCallback)?.onUserLoggedIn(user) }, + { throwable -> view?.let { showSnackBar(it, message = throwable.message) } }) + ) } } @@ -47,8 +51,16 @@ class LoginChooserFragment : BaseFragment() { override fun viewModel(): BaseViewModel? = null override fun layoutRes() = R.layout.login_chooser_fragment_layout - override fun onFragmentCreatedWithUser(view: View, savedInstanceState: Bundle?) {} - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + override fun onFragmentCreatedWithUser( + view: View, + savedInstanceState: Bundle? + ) { + } + + override fun onViewCreated( + view: View, + savedInstanceState: Bundle? + ) { super.onViewCreated(view, savedInstanceState) basicAuth.setOnClickListener { callback?.navToBasicAuth(loginCard) } accessToken.setOnClickListener { callback?.navToAccessToken(loginCard) } diff --git a/app/src/main/java/com/fastaccess/github/ui/modules/auth/login/LoginViewModel.kt b/app/src/main/java/com/fastaccess/github/ui/modules/auth/login/LoginViewModel.kt index 05f9b08d..5dec0e60 100644 --- a/app/src/main/java/com/fastaccess/github/ui/modules/auth/login/LoginViewModel.kt +++ b/app/src/main/java/com/fastaccess/github/ui/modules/auth/login/LoginViewModel.kt @@ -2,11 +2,11 @@ package com.fastaccess.github.ui.modules.auth.login import androidx.lifecycle.MutableLiveData import com.crashlytics.android.Crashlytics -import com.fastaccess.data.persistence.db.FastHubDatabase import com.fastaccess.data.model.FastHubErrors -import com.fastaccess.data.persistence.models.LoginModel import com.fastaccess.data.model.ValidationError -import com.fastaccess.extension.uiThread +import com.fastaccess.data.persistence.db.FastHubDatabase +import com.fastaccess.data.persistence.models.LoginModel +import com.fastaccess.data.repository.SchedulerProvider import com.fastaccess.github.R import com.fastaccess.github.base.BaseViewModel import com.fastaccess.github.di.modules.AuthenticationInterceptor @@ -25,17 +25,20 @@ class LoginViewModel @Inject constructor( private val accessTokenUseCase: GetAccessTokenUseCase, private val loginWithAccessTokenUseCase: LoginWithAccessTokenUseCase, private val interceptor: AuthenticationInterceptor, - private val fasthubDatabase: FastHubDatabase + private val fasthubDatabase: FastHubDatabase, + private val schedulerProvider: SchedulerProvider ) : BaseViewModel() { val validationLiveData = MutableLiveData() val loggedInUser = MutableLiveData() - fun login(userName: String? = null, - password: String? = null, - twoFactorCode: String? = null, - endPoint: String? = null, - isAccessToken: Boolean = true) { + fun login( + userName: String? = null, + password: String? = null, + twoFactorCode: String? = null, + endPoint: String? = null, + isAccessToken: Boolean = true + ) { validationLiveData.value = ValidationError(ValidationError.FieldType.TWO_FACTOR, !twoFactorCode.isNullOrBlank()) validationLiveData.value = ValidationError(ValidationError.FieldType.URL, !endPoint.isNullOrBlank()) validationLiveData.value = ValidationError(ValidationError.FieldType.PASSWORD, !password.isNullOrBlank()) @@ -59,10 +62,12 @@ class LoginViewModel @Inject constructor( } } - private fun loginWithAccessToken(password: String, - twoFactorCode: String? = null, - isEnterprise: Boolean? = false, - enterpriseUrl: String? = null) { + private fun loginWithAccessToken( + password: String, + twoFactorCode: String? = null, + isEnterprise: Boolean? = false, + enterpriseUrl: String? = null + ) { interceptor.token = password loginWithAccessTokenUseCase.executeSafely(callApi(loginWithAccessTokenUseCase.buildObservable() .flatMap { user -> @@ -77,9 +82,11 @@ class LoginViewModel @Inject constructor( )) } - private fun loginBasic(twoFactorCode: String? = null, - isEnterprise: Boolean? = false, - enterpriseUrl: String? = null) { + private fun loginBasic( + twoFactorCode: String? = null, + isEnterprise: Boolean? = false, + enterpriseUrl: String? = null + ) { loginUserCase.setAuthBody(twoFactorCode) loginUserCase.executeSafely(callApi(loginUserCase.buildObservable() .flatMap({ @@ -104,5 +111,7 @@ class LoginViewModel @Inject constructor( super.onCleared() } - fun clearDb() = Completable.fromCallable { fasthubDatabase.clearAll() }.uiThread() + fun clearDb() = Completable.fromCallable { fasthubDatabase.clearAll() } + .subscribeOn(schedulerProvider.ioThread()) + .observeOn(schedulerProvider.uiThread()) } \ No newline at end of file diff --git a/app/src/main/java/com/fastaccess/github/ui/modules/issue/fragment/IssueFragment.kt b/app/src/main/java/com/fastaccess/github/ui/modules/issue/fragment/IssueFragment.kt index b90605fa..9418bde9 100644 --- a/app/src/main/java/com/fastaccess/github/ui/modules/issue/fragment/IssueFragment.kt +++ b/app/src/main/java/com/fastaccess/github/ui/modules/issue/fragment/IssueFragment.kt @@ -2,6 +2,7 @@ package com.fastaccess.github.ui.modules.issue.fragment import android.graphics.Color import android.os.Bundle +import android.text.Editable import android.view.View import androidx.core.os.bundleOf import androidx.core.view.isVisible @@ -21,10 +22,8 @@ import com.fastaccess.github.R import com.fastaccess.github.base.BaseFragment import com.fastaccess.github.base.BaseViewModel import com.fastaccess.github.base.engine.ThemeEngine -import com.fastaccess.github.extensions.isTrue -import com.fastaccess.github.extensions.observeNotNull -import com.fastaccess.github.extensions.shareUrl -import com.fastaccess.github.extensions.timeAgo +import com.fastaccess.github.extensions.* +import com.fastaccess.github.platform.mentions.MentionsPresenter import com.fastaccess.github.ui.adapter.IssueTimelineAdapter import com.fastaccess.github.ui.modules.issue.fragment.viewmodel.IssueTimelineViewModel import com.fastaccess.github.ui.modules.issuesprs.edit.LockUnlockFragment @@ -43,6 +42,9 @@ import com.fastaccess.markdown.MarkdownProvider import com.fastaccess.markdown.spans.LabelSpan import com.fastaccess.markdown.widget.SpannableBuilder import com.google.android.material.appbar.AppBarLayout +import com.otaliastudios.autocomplete.Autocomplete +import com.otaliastudios.autocomplete.AutocompleteCallback +import com.otaliastudios.autocomplete.CharPolicy import github.type.LockReason import kotlinx.android.synthetic.main.empty_state_layout.* import kotlinx.android.synthetic.main.issue_header_row_item.* @@ -61,6 +63,7 @@ class IssueFragment : BaseFragment(), LockUnlockFragment.OnLockReasonSelected, @Inject lateinit var viewModelFactory: ViewModelProvider.Factory @Inject lateinit var htmlSpanner: HtmlSpanner @Inject lateinit var preference: FastHubSharedPreference + @Inject lateinit var mentionsPresenter: MentionsPresenter private val viewModel by lazy { ViewModelProviders.of(this, viewModelFactory).get(IssueTimelineViewModel::class.java) } private val login by lazy { arguments?.getString(EXTRA) ?: "" } @@ -97,9 +100,15 @@ class IssueFragment : BaseFragment(), LockUnlockFragment.OnLockReasonSelected, swipeRefresh.isRefreshing = false } } + setupEditText() observeChanges() } + override fun onDestroyView() { + mentionsPresenter.onDispose() + super.onDestroyView() + } + override fun onLockReasonSelected(lockReason: LockReason?) { viewModel.lockUnlockIssue(login, repo, number, lockReason, true) } @@ -120,6 +129,29 @@ class IssueFragment : BaseFragment(), LockUnlockFragment.OnLockReasonSelected, initMilestone(milestone) } + private fun setupEditText() { + Autocomplete.on(commentText) + .with(CharPolicy('@')) + .with(mentionsPresenter) + .with(requireContext().getDrawableCompat(R.drawable.popup_window_background)) + .with(object : AutocompleteCallback { + override fun onPopupItemClicked( + editable: Editable?, + item: String? + ): Boolean { + val range = CharPolicy.getQueryRange(editable) ?: return false + val start = range[0] + val end = range[1] + Timber.e("$start $end $item") + editable?.replace(start, end, "$item ") + return true + } + + override fun onPopupVisibilityChanged(shown: Boolean) {} + }) + .build() + } + private fun menuClick(model: IssueModel) { toolbar.setOnMenuItemClickListener { item -> when (item.itemId) { @@ -160,8 +192,11 @@ class IssueFragment : BaseFragment(), LockUnlockFragment.OnLockReasonSelected, viewModel.getIssue(login, repo, number).observeNotNull(this) { initIssue(it.first, it.second) } - viewModel.timeline.observeNotNull(this) { - adapter.submitList(it) + viewModel.timeline.observeNotNull(this) { timeline -> + adapter.submitList(timeline) + } + viewModel.userNamesLiveData.observeNotNull(this) { + mentionsPresenter.setUsers(it) } } diff --git a/app/src/main/java/com/fastaccess/github/ui/modules/issue/fragment/viewmodel/IssueTimelineViewModel.kt b/app/src/main/java/com/fastaccess/github/ui/modules/issue/fragment/viewmodel/IssueTimelineViewModel.kt index 21041fdb..f35a1002 100644 --- a/app/src/main/java/com/fastaccess/github/ui/modules/issue/fragment/viewmodel/IssueTimelineViewModel.kt +++ b/app/src/main/java/com/fastaccess/github/ui/modules/issue/fragment/viewmodel/IssueTimelineViewModel.kt @@ -32,6 +32,7 @@ class IssueTimelineViewModel @Inject constructor( private var pageInfo: PageInfoModel? = null val timeline = MutableLiveData>() private val list = arrayListOf() + val userNamesLiveData = MutableLiveData>() override fun onCleared() { super.onCleared() @@ -41,11 +42,20 @@ class IssueTimelineViewModel @Inject constructor( lockUnlockIssuePrUseCase.dispose() } - fun getIssue(login: String, repo: String, number: Int) = issueRepositoryProvider.getIssueByNumber("$login/$repo", number) + fun getIssue( + login: String, + repo: String, + number: Int + ) = issueRepositoryProvider.getIssueByNumber("$login/$repo", number) .filterNull() .map { Pair(it, loginRepositoryProvider.getLoginBlocking()) } - fun loadData(login: String, repo: String, number: Int, reload: Boolean = false) { + fun loadData( + login: String, + repo: String, + number: Int, + reload: Boolean = false + ) { if (reload) { pageInfo = null list.clear() @@ -58,13 +68,20 @@ class IssueTimelineViewModel @Inject constructor( issueUseCase.repo = repo issueUseCase.number = number justSubscribe(issueUseCase.buildObservable() - .flatMap { loadTimeline(login, repo, number, cursor) }) + .flatMap { loadTimeline(login, repo, number, cursor) } + .map { mapToUserNames(it.second) }) } else { - justSubscribe(loadTimeline(login, repo, number, cursor)) + justSubscribe(loadTimeline(login, repo, number, cursor) + .map { mapToUserNames(it.second) }) } } - private fun loadTimeline(login: String, repo: String, number: Int, cursor: String?): Observable>> { + private fun loadTimeline( + login: String, + repo: String, + number: Int, + cursor: String? + ): Observable>> { timelineUseCase.login = login timelineUseCase.repo = repo timelineUseCase.number = number @@ -77,7 +94,11 @@ class IssueTimelineViewModel @Inject constructor( } } - fun closeOpenIssue(login: String, repo: String, number: Int) { + fun closeOpenIssue( + login: String, + repo: String, + number: Int + ) { editIssuePrUseCase.repo = repo editIssuePrUseCase.login = login editIssuePrUseCase.number = number @@ -87,7 +108,13 @@ class IssueTimelineViewModel @Inject constructor( }) } - fun lockUnlockIssue(login: String, repo: String, number: Int, lockReason: LockReason? = null, lock: Boolean = false) { + fun lockUnlockIssue( + login: String, + repo: String, + number: Int, + lockReason: LockReason? = null, + lock: Boolean = false + ) { lockUnlockIssuePrUseCase.repo = repo lockUnlockIssuePrUseCase.login = login lockUnlockIssuePrUseCase.number = number @@ -105,4 +132,10 @@ class IssueTimelineViewModel @Inject constructor( } fun hasNext() = pageInfo?.hasNextPage ?: false + + private fun mapToUserNames(list: List) { + val _list = userNamesLiveData.value ?: arrayListOf() + _list.addAll(list.map { it.comment?.author?.login ?: it.comment?.author?.name ?: "" }) + userNamesLiveData.postValue(_list) + } } \ No newline at end of file diff --git a/app/src/main/java/com/fastaccess/github/ui/modules/main/fragment/MainFragment.kt b/app/src/main/java/com/fastaccess/github/ui/modules/main/fragment/MainFragment.kt index 234d840f..0e57e9e7 100644 --- a/app/src/main/java/com/fastaccess/github/ui/modules/main/fragment/MainFragment.kt +++ b/app/src/main/java/com/fastaccess/github/ui/modules/main/fragment/MainFragment.kt @@ -145,7 +145,7 @@ class MainFragment : BaseFragment(), IconDialogFragment.IconDialogClickListener swipeRefresh.isRefreshing = it == true } viewModel.list.observeNotNull(this) { - adapter.submitList(it.distinct()) + adapter.submitList(it) } viewModel.logoutProcess.observeNotNull(this) { if (it) { diff --git a/app/src/main/java/com/fastaccess/github/ui/modules/main/fragment/viewmodel/MainFragmentViewModel.kt b/app/src/main/java/com/fastaccess/github/ui/modules/main/fragment/viewmodel/MainFragmentViewModel.kt index 37bdea9f..29598e19 100644 --- a/app/src/main/java/com/fastaccess/github/ui/modules/main/fragment/viewmodel/MainFragmentViewModel.kt +++ b/app/src/main/java/com/fastaccess/github/ui/modules/main/fragment/viewmodel/MainFragmentViewModel.kt @@ -6,11 +6,7 @@ import com.fastaccess.data.model.MainScreenModel import com.fastaccess.data.model.MainScreenModelRowType import com.fastaccess.data.persistence.db.FastHubDatabase import com.fastaccess.data.persistence.models.FeedModel -import com.fastaccess.data.repository.FeedsRepositoryProvider -import com.fastaccess.data.repository.LoginRepositoryProvider -import com.fastaccess.data.repository.MyIssuesPullsRepositoryProvider -import com.fastaccess.data.repository.NotificationRepositoryProvider -import com.fastaccess.extension.uiThread +import com.fastaccess.data.repository.* import com.fastaccess.github.base.BaseViewModel import com.fastaccess.github.extensions.map import com.fastaccess.github.extensions.switchMap @@ -34,7 +30,8 @@ class MainFragmentViewModel @Inject constructor( private val myIssuesPullsRepo: MyIssuesPullsRepositoryProvider, private val notificationRepositoryProvider: NotificationRepositoryProvider, private val fasthubDatabase: FastHubDatabase, - private val loginProvider: LoginRepositoryProvider + private val loginProvider: LoginRepositoryProvider, + private val schedulerProvider: SchedulerProvider ) : BaseViewModel() { val login = loginProvider.getLogin() @@ -55,7 +52,7 @@ class MainFragmentViewModel @Inject constructor( .flatMap { notificationUseCase.buildObservable() } .flatMap { issuesMainScreenUseCase.buildObservable() } .flatMap { pullRequestsMainScreenUseCase.buildObservable() } - )) + ).subscribeOn(schedulerProvider.ioThread()).observeOn(schedulerProvider.uiThread())) } fun logout() { @@ -63,7 +60,8 @@ class MainFragmentViewModel @Inject constructor( fasthubDatabase.clearAll() loginProvider.logoutAll() } - .uiThread() + .subscribeOn(schedulerProvider.ioThread()) + .observeOn(schedulerProvider.uiThread()) .subscribe({ logoutProcess.postValue(true) }, { error.postValue(FastHubErrors(FastHubErrors.ErrorType.OTHER, it.message)) }) ) diff --git a/app/src/main/java/com/fastaccess/github/ui/modules/profile/fragment/viewmodel/ProfileViewModel.kt b/app/src/main/java/com/fastaccess/github/ui/modules/profile/fragment/viewmodel/ProfileViewModel.kt index 097e354b..0687f57c 100644 --- a/app/src/main/java/com/fastaccess/github/ui/modules/profile/fragment/viewmodel/ProfileViewModel.kt +++ b/app/src/main/java/com/fastaccess/github/ui/modules/profile/fragment/viewmodel/ProfileViewModel.kt @@ -1,7 +1,6 @@ package com.fastaccess.github.ui.modules.profile.fragment.viewmodel import androidx.lifecycle.MutableLiveData -import com.fastaccess.extension.uiThread import com.fastaccess.github.base.BaseViewModel import com.fastaccess.github.usecase.user.BlockUnblockUserUseCase import com.fastaccess.github.usecase.user.FollowUnfollowUserUseCase @@ -26,30 +25,38 @@ class ProfileViewModel @Inject constructor( fun getUserFromRemote(login: String) { userUseCase.login = login - add(callApi(userUseCase.buildObservable()) - .subscribe({}, { it.printStackTrace() })) + add( + callApi(userUseCase.buildObservable()) + .subscribe({}, { it.printStackTrace() }) + ) } fun checkBlockingState(login: String) { blockedUseCase.login = login - add(blockedUseCase.buildObservable() - .uiThread() - .subscribe({ - isBlocked.postValue(it) - }, { - isBlocked.postValue(false) - it.printStackTrace() - })) + add( + blockedUseCase.buildObservable() + .subscribe({ + isBlocked.postValue(it) + }, { + isBlocked.postValue(false) + it.printStackTrace() + }) + ) } fun blockUnblockUser(login: String) { unblockUserUseCase.login = login unblockUserUseCase.block = isBlocked.value == false - add(callApi(unblockUserUseCase.buildObservable()) - .subscribe({ isBlocked.postValue(it) }, { it.printStackTrace() })) + add( + callApi(unblockUserUseCase.buildObservable()) + .subscribe({ isBlocked.postValue(it) }, { it.printStackTrace() }) + ) } - fun followUnfollowUser(login: String, viewerIsFollowing: Boolean?) { + fun followUnfollowUser( + login: String, + viewerIsFollowing: Boolean? + ) { followUnfollowUserUseCase.login = login followUnfollowUserUseCase.follow = viewerIsFollowing == false justSubscribe(followUnfollowUserUseCase.buildObservable()) diff --git a/app/src/main/java/com/fastaccess/github/ui/modules/trending/filter/FilterTrendingBottomSheet.kt b/app/src/main/java/com/fastaccess/github/ui/modules/trending/filter/FilterTrendingBottomSheet.kt index e44d34b2..37ce111f 100644 --- a/app/src/main/java/com/fastaccess/github/ui/modules/trending/filter/FilterTrendingBottomSheet.kt +++ b/app/src/main/java/com/fastaccess/github/ui/modules/trending/filter/FilterTrendingBottomSheet.kt @@ -6,7 +6,7 @@ import android.view.View import androidx.core.os.bundleOf import com.fastaccess.data.model.LanguageColorsModel import com.fastaccess.data.model.parcelable.FilterTrendingModel -import com.fastaccess.extension.uiThread +import com.fastaccess.data.repository.SchedulerProvider import com.fastaccess.github.R import com.fastaccess.github.base.BaseFragment import com.fastaccess.github.base.BaseViewModel @@ -24,6 +24,7 @@ import javax.inject.Inject class FilterTrendingBottomSheet : BaseFragment() { @Inject lateinit var gson: Gson + @Inject lateinit var schedulerProvider: SchedulerProvider private var callback: FilterTrendingCallback? = null private val adapter by lazy { LanguagesAdapter() } @@ -48,19 +49,26 @@ class FilterTrendingBottomSheet : BaseFragment() { super.onDetach() } - override fun onFragmentCreatedWithUser(view: View, savedInstanceState: Bundle?) { + override fun onFragmentCreatedWithUser( + view: View, + savedInstanceState: Bundle? + ) { setupToolbar(R.string.filter) adapter.checkedLanguage = model.lang languageRecyclerView.adapter = adapter languageRecyclerView.addDivider() - sinceGroup.check(when (model.since) { - FilterTrendingModel.TrendingSince.DAILY -> R.id.daily - FilterTrendingModel.TrendingSince.WEEKLY -> R.id.weekly - FilterTrendingModel.TrendingSince.MONTHLY -> R.id.monthly - }) + sinceGroup.check( + when (model.since) { + FilterTrendingModel.TrendingSince.DAILY -> R.id.daily + FilterTrendingModel.TrendingSince.WEEKLY -> R.id.weekly + FilterTrendingModel.TrendingSince.MONTHLY -> R.id.monthly + } + ) addDisposal(LanguageColorsModel.newInstance(gson, requireContext()) - .uiThread() - .subscribe({ adapter.submitList(it) }, { showSnackBar(view, message = it.message) })) + .subscribeOn(schedulerProvider.ioThread()) + .observeOn(schedulerProvider.uiThread()) + .subscribe({ adapter.submitList(it) }, { showSnackBar(view, message = it.message) }) + ) submit.setOnClickListener { model.lang = adapter.checkedLanguage diff --git a/app/src/main/java/com/fastaccess/github/usecase/auth/GetAccessTokenUseCase.kt b/app/src/main/java/com/fastaccess/github/usecase/auth/GetAccessTokenUseCase.kt index 9ea6ca46..9cf2b846 100644 --- a/app/src/main/java/com/fastaccess/github/usecase/auth/GetAccessTokenUseCase.kt +++ b/app/src/main/java/com/fastaccess/github/usecase/auth/GetAccessTokenUseCase.kt @@ -1,6 +1,7 @@ package com.fastaccess.github.usecase.auth import com.fastaccess.data.repository.LoginRepositoryProvider +import com.fastaccess.data.repository.SchedulerProvider import com.fastaccess.domain.response.AccessTokenResponse import com.fastaccess.domain.usecase.base.BaseObservableUseCase import com.fastaccess.github.BuildConfig @@ -11,14 +12,25 @@ import javax.inject.Inject /** * Created by Kosh on 12.05.18. */ -class GetAccessTokenUseCase @Inject constructor(private val loginRemoteRepository: LoginRepositoryProvider) : - BaseObservableUseCase() { +class GetAccessTokenUseCase @Inject constructor( + private val loginRemoteRepository: LoginRepositoryProvider, + private val schedulerProvider: SchedulerProvider +) : + BaseObservableUseCase() { var code: String? = null - override fun buildObservable(): Observable = code?.let { - loginRemoteRepository.getAccessToken(it, BuildConfig.GITHUB_CLIENT_ID, BuildConfig.GITHUB_SECRET, - BuildConfig.APPLICATION_ID, REDIRECT_URL) - } ?: Observable.empty() + override fun buildObservable(): Observable { + val observable = code?.let { + loginRemoteRepository.getAccessToken( + it, BuildConfig.GITHUB_CLIENT_ID, BuildConfig.GITHUB_SECRET, + BuildConfig.APPLICATION_ID, REDIRECT_URL + ) + } ?: Observable.empty() + + return observable + .subscribeOn(schedulerProvider.ioThread()) + .observeOn(schedulerProvider.uiThread()) + } } \ No newline at end of file diff --git a/app/src/main/java/com/fastaccess/github/usecase/auth/LoginWithAccessTokenUseCase.kt b/app/src/main/java/com/fastaccess/github/usecase/auth/LoginWithAccessTokenUseCase.kt index 80656fbb..7684cfa7 100644 --- a/app/src/main/java/com/fastaccess/github/usecase/auth/LoginWithAccessTokenUseCase.kt +++ b/app/src/main/java/com/fastaccess/github/usecase/auth/LoginWithAccessTokenUseCase.kt @@ -2,6 +2,7 @@ package com.fastaccess.github.usecase.auth import com.fastaccess.data.persistence.models.LoginModel import com.fastaccess.data.repository.LoginRepositoryProvider +import com.fastaccess.data.repository.SchedulerProvider import com.fastaccess.domain.usecase.base.BaseObservableUseCase import com.google.gson.Gson import io.reactivex.Observable @@ -10,10 +11,14 @@ import javax.inject.Inject /** * Created by Kosh on 12.05.18. */ -class LoginWithAccessTokenUseCase @Inject constructor(private val loginRemoteRepository: LoginRepositoryProvider, - private val gson: Gson) : BaseObservableUseCase() { +class LoginWithAccessTokenUseCase @Inject constructor( + private val loginRemoteRepository: LoginRepositoryProvider, + private val gson: Gson, + private val schedulerProvider: SchedulerProvider +) : BaseObservableUseCase() { override fun buildObservable(): Observable = loginRemoteRepository.loginAccessToken() - .map { gson.fromJson(gson.toJson(it), LoginModel::class.java) } + + .map { gson.fromJson(gson.toJson(it), LoginModel::class.java) } fun insertUser(loginModel: LoginModel): Observable = Observable.fromCallable { loginRemoteRepository.logoutAll() @@ -24,5 +29,6 @@ class LoginWithAccessTokenUseCase @Inject constructor(private val loginRemoteRep } else { null } - } + }.subscribeOn(schedulerProvider.ioThread()) + .observeOn(schedulerProvider.uiThread()) } \ No newline at end of file diff --git a/app/src/main/java/com/fastaccess/github/usecase/feed/FeedsUseCase.kt b/app/src/main/java/com/fastaccess/github/usecase/feed/FeedsUseCase.kt index 74c7c93f..ea6d3763 100644 --- a/app/src/main/java/com/fastaccess/github/usecase/feed/FeedsUseCase.kt +++ b/app/src/main/java/com/fastaccess/github/usecase/feed/FeedsUseCase.kt @@ -1,6 +1,7 @@ package com.fastaccess.github.usecase.feed import com.fastaccess.data.repository.FeedsRepositoryProvider +import com.fastaccess.data.repository.SchedulerProvider import com.fastaccess.domain.response.FeedResponse import com.fastaccess.domain.response.PageableResponse import com.fastaccess.domain.usecase.base.BaseObservableUseCase @@ -10,7 +11,12 @@ import javax.inject.Inject /** * Created by Kosh on 26.06.18. */ -class FeedsUseCase @Inject constructor(private val feedsRepositoryProvider: FeedsRepositoryProvider) : BaseObservableUseCase() { +class FeedsUseCase @Inject constructor( + private val feedsRepositoryProvider: FeedsRepositoryProvider, + private val schedulerProvider: SchedulerProvider +) : BaseObservableUseCase() { var page: Int = 0 override fun buildObservable(): Observable> = feedsRepositoryProvider.getReceivedEvents(page) + .subscribeOn(schedulerProvider.ioThread()) + .observeOn(schedulerProvider.uiThread()) } \ No newline at end of file diff --git a/app/src/main/java/com/fastaccess/github/usecase/issuesprs/AddAssigneesUseCase.kt b/app/src/main/java/com/fastaccess/github/usecase/issuesprs/AddAssigneesUseCase.kt index 3598d2ad..f9b9bf56 100644 --- a/app/src/main/java/com/fastaccess/github/usecase/issuesprs/AddAssigneesUseCase.kt +++ b/app/src/main/java/com/fastaccess/github/usecase/issuesprs/AddAssigneesUseCase.kt @@ -1,5 +1,6 @@ package com.fastaccess.github.usecase.issuesprs +import com.fastaccess.data.repository.SchedulerProvider import com.fastaccess.domain.repository.services.RepoService import com.fastaccess.domain.response.body.AssigneesBodyModel import com.fastaccess.domain.usecase.base.BaseObservableUseCase @@ -10,7 +11,8 @@ import javax.inject.Inject * Created by Kosh on 16.02.19. */ class AddAssigneesUseCase @Inject constructor( - private val repoService: RepoService + private val repoService: RepoService, + private val schedulerProvider: SchedulerProvider ) : BaseObservableUseCase() { var repo: String = "" @@ -20,8 +22,13 @@ class AddAssigneesUseCase @Inject constructor( var toRemove: List? = null override fun buildObservable(): Observable = when (toRemove.isNullOrEmpty()) { - true -> repoService.addAssignees(login, repo, number, AssigneesBodyModel(assignees)).map { true } + true -> repoService.addAssignees(login, repo, number, AssigneesBodyModel(assignees)) + .subscribeOn(schedulerProvider.ioThread()) + .observeOn(schedulerProvider.uiThread()) + .map { true } else -> repoService.removeAssignees(login, repo, number, AssigneesBodyModel(toRemove)) + .subscribeOn(schedulerProvider.ioThread()) + .observeOn(schedulerProvider.uiThread()) .flatMap { repoService.addAssignees(login, repo, number, AssigneesBodyModel(assignees)) } .map { true } } diff --git a/app/src/main/java/com/fastaccess/github/usecase/issuesprs/CloseOpenIssuePrUseCase.kt b/app/src/main/java/com/fastaccess/github/usecase/issuesprs/CloseOpenIssuePrUseCase.kt index b340df12..782cbb9c 100644 --- a/app/src/main/java/com/fastaccess/github/usecase/issuesprs/CloseOpenIssuePrUseCase.kt +++ b/app/src/main/java/com/fastaccess/github/usecase/issuesprs/CloseOpenIssuePrUseCase.kt @@ -5,6 +5,7 @@ import com.fastaccess.data.model.TimelineModel import com.fastaccess.data.persistence.models.MyIssuesPullsModel import com.fastaccess.data.repository.IssueRepositoryProvider import com.fastaccess.data.repository.LoginRepositoryProvider +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 @@ -19,7 +20,8 @@ import javax.inject.Inject class CloseOpenIssuePrUseCase @Inject constructor( private val issueRepositoryProvider: IssueRepositoryProvider, private val issuePrService: IssuePrService, - private val loginRepositoryProvider: LoginRepositoryProvider + private val loginRepositoryProvider: LoginRepositoryProvider, + private val schedulerProvider: SchedulerProvider ) : BaseObservableUseCase() { var repo: String = "" @@ -27,14 +29,22 @@ class CloseOpenIssuePrUseCase @Inject constructor( var number: Int = -1 override fun buildObservable(): Observable = issueRepositoryProvider.getIssueByNumberMaybe("$login/$repo", number) + .subscribeOn(schedulerProvider.ioThread()) + .observeOn(schedulerProvider.uiThread()) .flatMapObservable { issue -> issuePrService.editIssue(login, repo, number, IssueRequestModel(state = if ("closed".equals(issue.state, true)) "open" else "closed")) .map { issue.state = it.issueState issueRepositoryProvider.upsert(issue) val me = loginRepositoryProvider.getLoginBlocking()?.me() - return@map TimelineModel(closeOpenEventModel = CloseOpenEventModel(Date(), me, null, - MyIssuesPullsModel(issue.id, issue.databaseId, issue.number, issue.title, issue.repo?.nameWithOwner, 0, it.issueState, issue.url))) + return@map TimelineModel( + closeOpenEventModel = CloseOpenEventModel( + Date(), me, null, + MyIssuesPullsModel( + issue.id, issue.databaseId, issue.number, issue.title, issue.repo?.nameWithOwner, 0, it.issueState, issue.url + ) + ) + ) } } } \ No newline at end of file diff --git a/app/src/main/java/com/fastaccess/github/usecase/issuesprs/CreateLabelUseCase.kt b/app/src/main/java/com/fastaccess/github/usecase/issuesprs/CreateLabelUseCase.kt index d01b63fe..4ab74ed6 100644 --- a/app/src/main/java/com/fastaccess/github/usecase/issuesprs/CreateLabelUseCase.kt +++ b/app/src/main/java/com/fastaccess/github/usecase/issuesprs/CreateLabelUseCase.kt @@ -1,6 +1,7 @@ package com.fastaccess.github.usecase.issuesprs import com.fastaccess.data.model.parcelable.LabelModel +import com.fastaccess.data.repository.SchedulerProvider import com.fastaccess.domain.repository.services.RepoService import com.fastaccess.domain.response.LabelResponse import com.fastaccess.domain.usecase.base.BaseObservableUseCase @@ -11,7 +12,8 @@ import javax.inject.Inject * Created by Kosh on 16.02.19. */ class CreateLabelUseCase @Inject constructor( - private val repoService: RepoService + private val repoService: RepoService, + private val schedulerProvider: SchedulerProvider ) : BaseObservableUseCase() { var repo: String = "" @@ -20,6 +22,8 @@ class CreateLabelUseCase @Inject constructor( var color: String = "" override fun buildObservable(): Observable = repoService.addLabel(login, repo, LabelResponse(color = color, name = name)) + .subscribeOn(schedulerProvider.ioThread()) + .observeOn(schedulerProvider.uiThread()) .map { LabelModel(it.name, it.color, it.url) } diff --git a/app/src/main/java/com/fastaccess/github/usecase/issuesprs/CreateMilestoneUseCase.kt b/app/src/main/java/com/fastaccess/github/usecase/issuesprs/CreateMilestoneUseCase.kt index 0b8a56f9..50827514 100644 --- a/app/src/main/java/com/fastaccess/github/usecase/issuesprs/CreateMilestoneUseCase.kt +++ b/app/src/main/java/com/fastaccess/github/usecase/issuesprs/CreateMilestoneUseCase.kt @@ -1,5 +1,6 @@ package com.fastaccess.github.usecase.issuesprs +import com.fastaccess.data.repository.SchedulerProvider import com.fastaccess.domain.repository.services.RepoService import com.fastaccess.domain.response.body.MilestoneBodyModel import com.fastaccess.domain.usecase.base.BaseObservableUseCase @@ -10,7 +11,8 @@ import javax.inject.Inject * Created by Kosh on 16.02.19. */ class CreateMilestoneUseCase @Inject constructor( - private val repoService: RepoService + private val repoService: RepoService, + private val schedulerProvider: SchedulerProvider ) : BaseObservableUseCase() { var repo: String = "" @@ -20,5 +22,7 @@ class CreateMilestoneUseCase @Inject constructor( var dueOn: String = "" override fun buildObservable(): Observable = repoService.createMilestone(login, repo, MilestoneBodyModel(title, description, dueOn)) + .subscribeOn(schedulerProvider.ioThread()) + .observeOn(schedulerProvider.uiThread()) .map { true } } \ No newline at end of file diff --git a/app/src/main/java/com/fastaccess/github/usecase/issuesprs/FilterIssuesUseCase.kt b/app/src/main/java/com/fastaccess/github/usecase/issuesprs/FilterIssuesUseCase.kt index 59cdf57c..08322248 100644 --- a/app/src/main/java/com/fastaccess/github/usecase/issuesprs/FilterIssuesUseCase.kt +++ b/app/src/main/java/com/fastaccess/github/usecase/issuesprs/FilterIssuesUseCase.kt @@ -7,6 +7,7 @@ import com.fastaccess.data.model.PageInfoModel import com.fastaccess.data.model.parcelable.FilterIssuesPrsModel import com.fastaccess.data.persistence.models.MyIssuesPullsModel import com.fastaccess.data.repository.LoginRepositoryProvider +import com.fastaccess.data.repository.SchedulerProvider import com.fastaccess.domain.usecase.base.BaseObservableUseCase import github.SearchIssuesQuery import io.reactivex.Observable @@ -17,7 +18,8 @@ import javax.inject.Inject */ class FilterIssuesUseCase @Inject constructor( private val loginRepository: LoginRepositoryProvider, - private val apolloClient: ApolloClient + private val apolloClient: ApolloClient, + private val schedulerProvider: SchedulerProvider ) : BaseObservableUseCase() { var cursor: Input = Input.absent() @@ -28,6 +30,8 @@ class FilterIssuesUseCase @Inject constructor( val query = keyword return if (query.isNullOrEmpty()) { loginRepository.getLogin() + .subscribeOn(schedulerProvider.ioThread()) + .observeOn(schedulerProvider.uiThread()) .flatMapObservable { user -> return@flatMapObservable user.login?.let { login -> searchObservable(login = login) @@ -43,6 +47,8 @@ class FilterIssuesUseCase @Inject constructor( query: String? = null ): Observable>> { return Rx2Apollo.from(apolloClient.query(SearchIssuesQuery(constructQuery(filterModel, login, query), cursor))) + .subscribeOn(schedulerProvider.ioThread()) + .observeOn(schedulerProvider.uiThread()) .map { it.data()?.search } .map { search -> val list = search.nodes?.asSequence()?.mapNotNull { it.fragments.shortIssueRowItem } diff --git a/app/src/main/java/com/fastaccess/github/usecase/issuesprs/FilterPullRequestsUseCase.kt b/app/src/main/java/com/fastaccess/github/usecase/issuesprs/FilterPullRequestsUseCase.kt index 15b1d5f5..5b1460d7 100644 --- a/app/src/main/java/com/fastaccess/github/usecase/issuesprs/FilterPullRequestsUseCase.kt +++ b/app/src/main/java/com/fastaccess/github/usecase/issuesprs/FilterPullRequestsUseCase.kt @@ -7,6 +7,7 @@ import com.fastaccess.data.model.PageInfoModel import com.fastaccess.data.model.parcelable.FilterIssuesPrsModel import com.fastaccess.data.persistence.models.MyIssuesPullsModel import com.fastaccess.data.repository.LoginRepositoryProvider +import com.fastaccess.data.repository.SchedulerProvider import com.fastaccess.domain.usecase.base.BaseObservableUseCase import github.SearchPullRequestsQuery import io.reactivex.Observable @@ -17,7 +18,8 @@ import javax.inject.Inject */ class FilterPullRequestsUseCase @Inject constructor( private val loginRepository: LoginRepositoryProvider, - private val apolloClient: ApolloClient + private val apolloClient: ApolloClient, + private val schedulerProvider: SchedulerProvider ) : BaseObservableUseCase() { var cursor: Input = Input.absent() @@ -28,6 +30,8 @@ class FilterPullRequestsUseCase @Inject constructor( val query = keyword return if (query.isNullOrEmpty()) { loginRepository.getLogin() + .subscribeOn(schedulerProvider.ioThread()) + .observeOn(schedulerProvider.uiThread()) .flatMapObservable { user -> return@flatMapObservable user.login?.let { login -> searchObservable(login = login) @@ -38,18 +42,27 @@ class FilterPullRequestsUseCase @Inject constructor( } } - private fun searchObservable(login: String? = null, query: String? = null): Observable>> { + private fun searchObservable( + login: String? = null, + query: String? = null + ): Observable>> { return Rx2Apollo.from(apolloClient.query(SearchPullRequestsQuery(constructQuery(filterModel, login, query), cursor))) + .subscribeOn(schedulerProvider.ioThread()) + .observeOn(schedulerProvider.uiThread()) .map { it.data()?.search } .map { search -> val list = search.nodes?.asSequence()?.mapNotNull { it.fragments.shortPullRequestRowItem } ?.map { - MyIssuesPullsModel(it.id, it.databaseId, it.number, it.title, - it.repository.nameWithOwner, it.comments.totalCount, it.state.name, it.url.toString(), true) + MyIssuesPullsModel( + it.id, it.databaseId, it.number, it.title, + it.repository.nameWithOwner, it.comments.totalCount, it.state.name, it.url.toString(), true + ) } ?.toList() ?: arrayListOf() - val pageInfo = PageInfoModel(search.pageInfo.startCursor, search.pageInfo.endCursor, - search.pageInfo.isHasNextPage, search.pageInfo.isHasPreviousPage) + val pageInfo = PageInfoModel( + search.pageInfo.startCursor, search.pageInfo.endCursor, + search.pageInfo.isHasNextPage, search.pageInfo.isHasPreviousPage + ) return@map Pair(pageInfo, list) } } @@ -57,42 +70,54 @@ class FilterPullRequestsUseCase @Inject constructor( /** * Example: is:open is:pr author:k0shk0sh archived:false sort:created-desc */ - private fun constructQuery(model: FilterIssuesPrsModel, login: String? = null, query: String? = null): String { + private fun constructQuery( + model: FilterIssuesPrsModel, + login: String? = null, + query: String? = null + ): String { return StringBuilder() .append(if (query.isNullOrEmpty()) "" else "$query ") - .append("is:${when (model.searchType) { - FilterIssuesPrsModel.SearchType.OPEN -> "open" - FilterIssuesPrsModel.SearchType.CLOSED -> "closed" - }}") + .append( + "is:${when (model.searchType) { + FilterIssuesPrsModel.SearchType.OPEN -> "open" + FilterIssuesPrsModel.SearchType.CLOSED -> "closed" + }}" + ) .append(" ") .append("is:pr") .append(" ") .append("archived:false") .append(" ") - .append("sort:${when (model.searchSortBy) { - FilterIssuesPrsModel.SearchSortBy.NEWEST -> "created-desc" - FilterIssuesPrsModel.SearchSortBy.OLDEST -> "created-asc" - FilterIssuesPrsModel.SearchSortBy.MOST_COMMENTED -> "comments-desc" - FilterIssuesPrsModel.SearchSortBy.LEAST_COMMENTED -> "comments-asc" - FilterIssuesPrsModel.SearchSortBy.RECENTLY_UPDATED -> "updated-desc" - FilterIssuesPrsModel.SearchSortBy.LEAST_RECENTLY_UPDATED -> "updated-asc" - }}") + .append( + "sort:${when (model.searchSortBy) { + FilterIssuesPrsModel.SearchSortBy.NEWEST -> "created-desc" + FilterIssuesPrsModel.SearchSortBy.OLDEST -> "created-asc" + FilterIssuesPrsModel.SearchSortBy.MOST_COMMENTED -> "comments-desc" + FilterIssuesPrsModel.SearchSortBy.LEAST_COMMENTED -> "comments-asc" + FilterIssuesPrsModel.SearchSortBy.RECENTLY_UPDATED -> "updated-desc" + FilterIssuesPrsModel.SearchSortBy.LEAST_RECENTLY_UPDATED -> "updated-asc" + }}" + ) .append(" ") .apply { if (!login.isNullOrEmpty()) { - append("${when (model.searchBy) { - FilterIssuesPrsModel.SearchBy.ASSIGNED -> "assignee" - FilterIssuesPrsModel.SearchBy.MENTIONED -> "mentions" - FilterIssuesPrsModel.SearchBy.REVIEW_REQUESTS -> "review-requested" - else -> "author" - }}:$login").append(" ") + append( + "${when (model.searchBy) { + FilterIssuesPrsModel.SearchBy.ASSIGNED -> "assignee" + FilterIssuesPrsModel.SearchBy.MENTIONED -> "mentions" + FilterIssuesPrsModel.SearchBy.REVIEW_REQUESTS -> "review-requested" + else -> "author" + }}:$login" + ).append(" ") } if (model.searchVisibility != FilterIssuesPrsModel.SearchVisibility.BOTH) { - append("is:${when (model.searchVisibility) { - FilterIssuesPrsModel.SearchVisibility.PUBLIC -> "public" - FilterIssuesPrsModel.SearchVisibility.PRIVATE -> "private" - else -> "" - }}") + append( + "is:${when (model.searchVisibility) { + FilterIssuesPrsModel.SearchVisibility.PUBLIC -> "public" + FilterIssuesPrsModel.SearchVisibility.PRIVATE -> "private" + else -> "" + }}" + ) } } .toString() diff --git a/app/src/main/java/com/fastaccess/github/usecase/issuesprs/GetAssigneesUseCase.kt b/app/src/main/java/com/fastaccess/github/usecase/issuesprs/GetAssigneesUseCase.kt index ea24dd5e..955d6882 100644 --- a/app/src/main/java/com/fastaccess/github/usecase/issuesprs/GetAssigneesUseCase.kt +++ b/app/src/main/java/com/fastaccess/github/usecase/issuesprs/GetAssigneesUseCase.kt @@ -5,6 +5,7 @@ import com.apollographql.apollo.api.Input import com.apollographql.apollo.rx2.Rx2Apollo import com.fastaccess.data.model.PageInfoModel import com.fastaccess.data.model.ShortUserModel +import com.fastaccess.data.repository.SchedulerProvider import com.fastaccess.domain.usecase.base.BaseObservableUseCase import com.fastaccess.extension.toUser import github.GetAssigneesQuery @@ -15,7 +16,8 @@ import javax.inject.Inject * Created by Kosh on 27.01.19. */ class GetAssigneesUseCase @Inject constructor( - private val apolloClient: ApolloClient + private val apolloClient: ApolloClient, + private val schedulerProvider: SchedulerProvider ) : BaseObservableUseCase() { var login: String? = null @@ -30,10 +32,14 @@ class GetAssigneesUseCase @Inject constructor( return Observable.error(Throwable("this should never happen ;)")) } return Rx2Apollo.from(apolloClient.query(GetAssigneesQuery(login, repo, page))) + .subscribeOn(schedulerProvider.ioThread()) + .observeOn(schedulerProvider.uiThread()) .map { it.data()?.repositoryOwner?.repository?.assignableUsers } .map { data -> - val pageInfo = PageInfoModel(data.pageInfo.startCursor, data.pageInfo.endCursor, - data.pageInfo.isHasNextPage, data.pageInfo.isHasPreviousPage) + val pageInfo = PageInfoModel( + data.pageInfo.startCursor, data.pageInfo.endCursor, + data.pageInfo.isHasNextPage, data.pageInfo.isHasPreviousPage + ) return@map Pair(pageInfo, data.nodes?.map { it.fragments.shortUserRowItem.toUser() } ?: listOf()) } } diff --git a/app/src/main/java/com/fastaccess/github/usecase/issuesprs/GetIssueTimelineUseCase.kt b/app/src/main/java/com/fastaccess/github/usecase/issuesprs/GetIssueTimelineUseCase.kt index f5cba6ec..5d99c340 100644 --- a/app/src/main/java/com/fastaccess/github/usecase/issuesprs/GetIssueTimelineUseCase.kt +++ b/app/src/main/java/com/fastaccess/github/usecase/issuesprs/GetIssueTimelineUseCase.kt @@ -6,6 +6,7 @@ import com.apollographql.apollo.rx2.Rx2Apollo import com.fastaccess.data.model.* import com.fastaccess.data.model.parcelable.LabelModel import com.fastaccess.data.repository.IssueRepositoryProvider +import com.fastaccess.data.repository.SchedulerProvider import com.fastaccess.domain.usecase.base.BaseObservableUseCase import com.fastaccess.extension.* import com.fastaccess.github.extensions.addIfNotNull @@ -19,7 +20,8 @@ import javax.inject.Inject */ class GetIssueTimelineUseCase @Inject constructor( private val issueRepositoryProvider: IssueRepositoryProvider, - private val apolloClient: ApolloClient + private val apolloClient: ApolloClient, + private val schedulerProvider: SchedulerProvider ) : BaseObservableUseCase() { var login: String? = null @@ -37,12 +39,16 @@ class GetIssueTimelineUseCase @Inject constructor( } return Rx2Apollo.from(apolloClient.query(GetIssueTimelineQuery(login, repo, number, page))) + .subscribeOn(schedulerProvider.ioThread()) + .observeOn(schedulerProvider.uiThread()) .map { it.data()?.repositoryOwner?.repository?.issue } .map { val list = arrayListOf() val timeline = it.timeline - val pageInfo = PageInfoModel(timeline.pageInfo.startCursor, timeline.pageInfo.endCursor, - timeline.pageInfo.isHasNextPage, timeline.pageInfo.isHasPreviousPage) + val pageInfo = PageInfoModel( + timeline.pageInfo.startCursor, timeline.pageInfo.endCursor, + timeline.pageInfo.isHasNextPage, timeline.pageInfo.isHasPreviousPage + ) timeline.nodes?.forEach { node -> when (node) { is AsCommit -> list.add(getCommit(node)) @@ -69,21 +75,29 @@ class GetIssueTimelineUseCase @Inject constructor( } } - private fun getTransferred(node: AsTransferredEvent): TimelineModel = TimelineModel(transferredEventModel = TransferredEventModel( - node.createdAt, node.actor?.fragments?.shortActor?.toUser(), node.fromRepository?.nameWithOwner - )) + private fun getTransferred(node: AsTransferredEvent): TimelineModel = TimelineModel( + transferredEventModel = TransferredEventModel( + node.createdAt, node.actor?.fragments?.shortActor?.toUser(), node.fromRepository?.nameWithOwner + ) + ) - private fun getRenamed(node: AsRenamedTitleEvent): TimelineModel = TimelineModel(renamedEventModel = RenamedEventModel( - node.createdAt, node.actor?.fragments?.shortActor?.toUser(), node.currentTitle, node.previousTitle - )) + private fun getRenamed(node: AsRenamedTitleEvent): TimelineModel = TimelineModel( + renamedEventModel = RenamedEventModel( + node.createdAt, node.actor?.fragments?.shortActor?.toUser(), node.currentTitle, node.previousTitle + ) + ) - private fun getDemilestoned(node: AsDemilestonedEvent): TimelineModel = TimelineModel(milestoneEventModel = MilestoneDemilestonedEventModel( - node.createdAt, node.actor?.fragments?.shortActor?.toUser(), node.milestoneTitle, false - )) + private fun getDemilestoned(node: AsDemilestonedEvent): TimelineModel = TimelineModel( + milestoneEventModel = MilestoneDemilestonedEventModel( + node.createdAt, node.actor?.fragments?.shortActor?.toUser(), node.milestoneTitle, false + ) + ) - private fun getMilestone(node: AsMilestonedEvent): TimelineModel = TimelineModel(milestoneEventModel = MilestoneDemilestonedEventModel( - node.createdAt, node.actor?.fragments?.shortActor?.toUser(), node.milestoneTitle, true - )) + private fun getMilestone(node: AsMilestonedEvent): TimelineModel = TimelineModel( + milestoneEventModel = MilestoneDemilestonedEventModel( + node.createdAt, node.actor?.fragments?.shortActor?.toUser(), node.milestoneTitle, true + ) + ) private fun getUnassigned( node: AsUnassignedEvent, @@ -97,10 +111,12 @@ class GetIssueTimelineUseCase @Inject constructor( } } if (shouldAdd) { - return TimelineModel(assignedEventModel = AssignedUnAssignedEventModel( - node.createdAt, node.actor?.fragments?.shortActor?.toUser(), false, - arrayListOf(ShortUserModel(node.user?.login, node.user?.login, avatarUrl = node.user?.avatarUrl?.toString())) - )) + return TimelineModel( + assignedEventModel = AssignedUnAssignedEventModel( + node.createdAt, node.actor?.fragments?.shortActor?.toUser(), false, + arrayListOf(ShortUserModel(node.user?.login, node.user?.login, avatarUrl = node.user?.avatarUrl?.toString())) + ) + ) } return null } @@ -117,23 +133,29 @@ class GetIssueTimelineUseCase @Inject constructor( } } if (shouldAdd) { - return TimelineModel(assignedEventModel = AssignedUnAssignedEventModel( - node.createdAt, node.actor?.fragments?.shortActor?.toUser(), true, - arrayListOf(ShortUserModel(node.user?.login, node.user?.login, avatarUrl = node.user?.avatarUrl?.toString())) - )) + return TimelineModel( + assignedEventModel = AssignedUnAssignedEventModel( + node.createdAt, node.actor?.fragments?.shortActor?.toUser(), true, + arrayListOf(ShortUserModel(node.user?.login, node.user?.login, avatarUrl = node.user?.avatarUrl?.toString())) + ) + ) } return null } private fun getUnsubscribed( node: AsUnsubscribedEvent - ): TimelineModel = TimelineModel(subscribedUnsubscribedEvent = SubscribedUnsubscribedEventModel( - node.createdAt, node.actor?.fragments?.shortActor?.toUser(), false - )) + ): TimelineModel = TimelineModel( + subscribedUnsubscribedEvent = SubscribedUnsubscribedEventModel( + node.createdAt, node.actor?.fragments?.shortActor?.toUser(), false + ) + ) - private fun getSubscribed(node: AsSubscribedEvent): TimelineModel = TimelineModel(subscribedUnsubscribedEvent = SubscribedUnsubscribedEventModel( - node.createdAt, node.actor?.fragments?.shortActor?.toUser(), false - )) + private fun getSubscribed(node: AsSubscribedEvent): TimelineModel = TimelineModel( + subscribedUnsubscribedEvent = SubscribedUnsubscribedEventModel( + node.createdAt, node.actor?.fragments?.shortActor?.toUser(), false + ) + ) private fun getUnlabeled( node: AsUnlabeledEvent, @@ -147,9 +169,11 @@ class GetIssueTimelineUseCase @Inject constructor( } } if (shouldAdd) { - return TimelineModel(labelUnlabeledEvent = LabelUnlabeledEventModel( - node.createdAt, node.actor?.fragments?.shortActor?.toUser(), false, arrayListOf(constructLabel(node.label)) - )) + return TimelineModel( + labelUnlabeledEvent = LabelUnlabeledEventModel( + node.createdAt, node.actor?.fragments?.shortActor?.toUser(), false, arrayListOf(constructLabel(node.label)) + ) + ) } return null } @@ -166,9 +190,11 @@ class GetIssueTimelineUseCase @Inject constructor( } } if (shouldAdd) { - return TimelineModel(labelUnlabeledEvent = LabelUnlabeledEventModel( - node.createdAt, node.actor?.fragments?.shortActor?.toUser(), true, arrayListOf(constructLabel(node.label)) - )) + return TimelineModel( + labelUnlabeledEvent = LabelUnlabeledEventModel( + node.createdAt, node.actor?.fragments?.shortActor?.toUser(), true, arrayListOf(constructLabel(node.label)) + ) + ) } return null } @@ -182,53 +208,73 @@ class GetIssueTimelineUseCase @Inject constructor( } - private fun getUnlocked(node: AsUnlockedEvent): TimelineModel = TimelineModel(lockUnlockEventModel = LockUnlockEventModel( - node.createdAt, node.actor?.fragments?.shortActor?.toUser(), null, node.lockable.activeLockReason?.rawValue() - )) + private fun getUnlocked(node: AsUnlockedEvent): TimelineModel = TimelineModel( + lockUnlockEventModel = LockUnlockEventModel( + node.createdAt, node.actor?.fragments?.shortActor?.toUser(), null, node.lockable.activeLockReason?.rawValue() + ) + ) - private fun getLock(node: AsLockedEvent): TimelineModel = TimelineModel(lockUnlockEventModel = LockUnlockEventModel( - node.createdAt, node.actor?.fragments?.shortActor?.toUser(), node.lockReason?.rawValue(), node.lockable.activeLockReason?.rawValue(), true - )) + private fun getLock(node: AsLockedEvent): TimelineModel = TimelineModel( + lockUnlockEventModel = LockUnlockEventModel( + node.createdAt, node.actor?.fragments?.shortActor?.toUser(), node.lockReason?.rawValue(), node.lockable.activeLockReason?.rawValue(), true + ) + ) private fun getReopened(node: AsReopenedEvent): TimelineModel { - return TimelineModel(closeOpenEventModel = CloseOpenEventModel( - node.createdAt, node.actor?.fragments?.shortActor?.toUser()) + return TimelineModel( + closeOpenEventModel = CloseOpenEventModel( + node.createdAt, node.actor?.fragments?.shortActor?.toUser() + ) ) } private fun getClosed(node: AsClosedEvent): TimelineModel { val commit = node.closer?.fragments?.commitFragment?.toCommit() val pr = node.closer?.fragments?.shortPullRequestRowItem?.toPullRequest() - return TimelineModel(closeOpenEventModel = CloseOpenEventModel( - node.createdAt, node.actor?.fragments?.shortActor?.toUser(), commit, pr, true) + return TimelineModel( + closeOpenEventModel = CloseOpenEventModel( + node.createdAt, node.actor?.fragments?.shortActor?.toUser(), commit, pr, true + ) ) } private fun getReference(node: AsReferencedEvent): TimelineModel { val issueModel = node.subject.fragments.shortIssueRowItem?.toIssue() val pullRequest = node.subject.fragments.shortPullRequestRowItem?.toPullRequest() - return TimelineModel(referencedEventModel = ReferencedEventModel( - node.commitRepository.nameWithOwner, node.createdAt, ShortUserModel( - node.actor?.fragments?.shortActor?.login, node.actor?.fragments?.shortActor?.login, node.actor?.fragments?.shortActor?.url?.toString(), - avatarUrl = node.actor?.fragments?.shortActor?.avatarUrl?.toString()), node.isCrossRepository, node.isDirectReference, - node.commit?.fragments?.commitFragment?.toCommit(), issueModel, pullRequest)) + return TimelineModel( + referencedEventModel = ReferencedEventModel( + node.commitRepository.nameWithOwner, node.createdAt, ShortUserModel( + node.actor?.fragments?.shortActor?.login, node.actor?.fragments?.shortActor?.login, + node.actor?.fragments?.shortActor?.url?.toString(), + avatarUrl = node.actor?.fragments?.shortActor?.avatarUrl?.toString() + ), node.isCrossRepository, node.isDirectReference, + node.commit?.fragments?.commitFragment?.toCommit(), issueModel, pullRequest + ) + ) } private fun getCrossReference(node: AsCrossReferencedEvent): TimelineModel { val actor = node.actor?.fragments?.shortActor?.toUser() val issueModel = node.source.fragments.shortIssueRowItem?.toIssue() val pullRequest = node.source.fragments.shortPullRequestRowItem?.toPullRequest() - return TimelineModel(crossReferencedEventModel = CrossReferencedEventModel(node.createdAt, node.referencedAt, - node.isCrossRepository, node.isWillCloseTarget, actor, issueModel, pullRequest)) + return TimelineModel( + crossReferencedEventModel = CrossReferencedEventModel( + node.createdAt, node.referencedAt, + node.isCrossRepository, node.isWillCloseTarget, actor, issueModel, pullRequest + ) + ) } - private fun getComment(node: AsIssueComment) = TimelineModel(comment = CommentModel(node.id, - ShortUserModel(node.author?.login, node.author?.login, avatarUrl = node.author?.avatarUrl.toString()), - node.bodyHTML.toString(), node.body, CommentAuthorAssociation.fromName(node.authorAssociation.rawValue()), - node.viewerCannotUpdateReasons.map { reason -> CommentCannotUpdateReason.fromName(reason.rawValue()) }.toList(), - node.reactionGroups?.map { it.fragments.reactions.toReactionGroup() }, node.createdAt, node.updatedAt, - node.isViewerCanReact, node.isViewerCanDelete, node.isViewerCanUpdate, node.isViewerDidAuthor, node.isViewerCanMinimize - )) + private fun getComment(node: AsIssueComment) = TimelineModel( + comment = CommentModel( + node.id, + ShortUserModel(node.author?.login, node.author?.login, avatarUrl = node.author?.avatarUrl.toString()), + node.bodyHTML.toString(), node.body, CommentAuthorAssociation.fromName(node.authorAssociation.rawValue()), + node.viewerCannotUpdateReasons.map { reason -> CommentCannotUpdateReason.fromName(reason.rawValue()) }.toList(), + node.reactionGroups?.map { it.fragments.reactions.toReactionGroup() }, node.createdAt, node.updatedAt, + node.isViewerCanReact, node.isViewerCanDelete, node.isViewerCanUpdate, node.isViewerDidAuthor, node.isViewerCanMinimize + ) + ) private fun getCommit(node: AsCommit) = TimelineModel(commit = node.fragments.commitFragment?.toCommit()) } \ No newline at end of file diff --git a/app/src/main/java/com/fastaccess/github/usecase/issuesprs/GetIssueUseCase.kt b/app/src/main/java/com/fastaccess/github/usecase/issuesprs/GetIssueUseCase.kt index d9b8f463..da4f86fa 100644 --- a/app/src/main/java/com/fastaccess/github/usecase/issuesprs/GetIssueUseCase.kt +++ b/app/src/main/java/com/fastaccess/github/usecase/issuesprs/GetIssueUseCase.kt @@ -7,6 +7,7 @@ import com.fastaccess.data.model.EmbeddedRepoModel import com.fastaccess.data.model.ShortUserModel import com.fastaccess.data.persistence.models.IssueModel import com.fastaccess.data.repository.IssueRepositoryProvider +import com.fastaccess.data.repository.SchedulerProvider import com.fastaccess.domain.usecase.base.BaseObservableUseCase import com.fastaccess.extension.toLabels import com.fastaccess.extension.toMilestone @@ -21,7 +22,8 @@ import javax.inject.Inject */ class GetIssueUseCase @Inject constructor( private val issueRepositoryProvider: IssueRepositoryProvider, - private val apolloClient: ApolloClient + private val apolloClient: ApolloClient, + private val schedulerProvider: SchedulerProvider ) : BaseObservableUseCase() { var login: String? = null @@ -38,18 +40,23 @@ class GetIssueUseCase @Inject constructor( } return Rx2Apollo.from(apolloClient.query(GetIssueQuery(login, repo, number))) + .subscribeOn(schedulerProvider.ioThread()) + .observeOn(schedulerProvider.uiThread()) .map { it.data()?.repositoryOwner?.repository?.issue?.fragments?.fullIssue } .map { issue -> issueRepositoryProvider.upsert(IssueModel(issue.id, issue.databaseId, issue.number, issue.activeLockReason?.rawValue(), issue.body, issue.bodyHTML.toString(), issue.closedAt, issue.createdAt, issue.updatedAt, issue.state.rawValue(), - issue.title, issue.viewerSubscription?.rawValue(), ShortUserModel(issue.author?.login, issue.author?.login, - issue.author?.url?.toString(), avatarUrl = issue.author?.avatarUrl?.toString()), + issue.title, issue.viewerSubscription?.rawValue(), ShortUserModel( + issue.author?.login, issue.author?.login, + issue.author?.url?.toString(), avatarUrl = issue.author?.avatarUrl?.toString() + ), EmbeddedRepoModel(issue.repository.nameWithOwner), CountModel(issue.userContentEdits?.totalCount), issue.reactionGroups?.map { it.fragments.reactions.toReactionGroup() }, issue.viewerCannotUpdateReasons.map { it.rawValue() }, issue.isClosed, issue.isCreatedViaEmail, issue.isLocked, issue.isViewerCanReact, issue.isViewerCanSubscribe, issue.isViewerCanUpdate, issue.isViewerDidAuthor, issue.authorAssociation.rawValue(), issue.url.toString(), issue.labels?.nodes?.map { it.fragments.labels.toLabels() }, - issue.milestone?.toMilestone(), issue.assignees.nodes?.map { it.fragments }?.map { it.shortUserRowItem.toUser() })) + issue.milestone?.toMilestone(), issue.assignees.nodes?.map { it.fragments }?.map { it.shortUserRowItem.toUser() }) + ) } } } \ No newline at end of file diff --git a/app/src/main/java/com/fastaccess/github/usecase/issuesprs/GetLabelsUseCase.kt b/app/src/main/java/com/fastaccess/github/usecase/issuesprs/GetLabelsUseCase.kt index f1fbffae..7c252042 100644 --- a/app/src/main/java/com/fastaccess/github/usecase/issuesprs/GetLabelsUseCase.kt +++ b/app/src/main/java/com/fastaccess/github/usecase/issuesprs/GetLabelsUseCase.kt @@ -5,6 +5,7 @@ import com.apollographql.apollo.api.Input import com.apollographql.apollo.rx2.Rx2Apollo import com.fastaccess.data.model.PageInfoModel import com.fastaccess.data.model.parcelable.LabelModel +import com.fastaccess.data.repository.SchedulerProvider import com.fastaccess.domain.usecase.base.BaseObservableUseCase import com.fastaccess.extension.toLabels import github.GetLabelsQuery @@ -15,7 +16,8 @@ import javax.inject.Inject * Created by Kosh on 27.01.19. */ class GetLabelsUseCase @Inject constructor( - private val apolloClient: ApolloClient + private val apolloClient: ApolloClient, + private val schedulerProvider: SchedulerProvider ) : BaseObservableUseCase() { var login: String? = null @@ -27,13 +29,19 @@ class GetLabelsUseCase @Inject constructor( val repo = repo if (login.isNullOrEmpty() || repo.isNullOrEmpty()) { - return Observable.error(Throwable("this should never happen ;)")) + return Observable.error>>(Throwable("this should never happen ;)")) + .subscribeOn(schedulerProvider.ioThread()) + .observeOn(schedulerProvider.uiThread()) } return Rx2Apollo.from(apolloClient.query(GetLabelsQuery(login, repo, page))) + .subscribeOn(schedulerProvider.ioThread()) + .observeOn(schedulerProvider.uiThread()) .map { it.data()?.repositoryOwner?.repository?.labels } .map { data -> - val pageInfo = PageInfoModel(data.pageInfo.startCursor, data.pageInfo.endCursor, - data.pageInfo.isHasNextPage, data.pageInfo.isHasPreviousPage) + val pageInfo = PageInfoModel( + data.pageInfo.startCursor, data.pageInfo.endCursor, + data.pageInfo.isHasNextPage, data.pageInfo.isHasPreviousPage + ) return@map Pair(pageInfo, data.nodes?.map { it.fragments.labels.toLabels() } ?: listOf()) } } diff --git a/app/src/main/java/com/fastaccess/github/usecase/issuesprs/GetMilestonesUseCase.kt b/app/src/main/java/com/fastaccess/github/usecase/issuesprs/GetMilestonesUseCase.kt index 76b24d6a..7bc0dd61 100644 --- a/app/src/main/java/com/fastaccess/github/usecase/issuesprs/GetMilestonesUseCase.kt +++ b/app/src/main/java/com/fastaccess/github/usecase/issuesprs/GetMilestonesUseCase.kt @@ -5,6 +5,7 @@ import com.apollographql.apollo.api.Input import com.apollographql.apollo.rx2.Rx2Apollo import com.fastaccess.data.model.PageInfoModel import com.fastaccess.data.model.parcelable.MilestoneModel +import com.fastaccess.data.repository.SchedulerProvider import com.fastaccess.domain.usecase.base.BaseObservableUseCase import github.GetMilestonesQuery import io.reactivex.Observable @@ -14,7 +15,8 @@ import javax.inject.Inject * Created by Kosh on 27.01.19. */ class GetMilestonesUseCase @Inject constructor( - private val apolloClient: ApolloClient + private val apolloClient: ApolloClient, + private val schedulerProvider: SchedulerProvider ) : BaseObservableUseCase() { var login: String? = null @@ -29,14 +31,20 @@ class GetMilestonesUseCase @Inject constructor( return Observable.error(Throwable("this should never happen ;)")) } return Rx2Apollo.from(apolloClient.query(GetMilestonesQuery(login, repo, page))) + .subscribeOn(schedulerProvider.ioThread()) + .observeOn(schedulerProvider.uiThread()) .map { it.data()?.repositoryOwner?.repository?.milestones } .map { data -> - val pageInfo = PageInfoModel(data.pageInfo.startCursor, data.pageInfo.endCursor, - data.pageInfo.isHasNextPage, data.pageInfo.isHasPreviousPage) + val pageInfo = PageInfoModel( + data.pageInfo.startCursor, data.pageInfo.endCursor, + data.pageInfo.isHasNextPage, data.pageInfo.isHasPreviousPage + ) return@map Pair(pageInfo, data.nodes?.map { it.fragments.milestoneFragment } ?.map { - MilestoneModel(it.id, it.title, it.description, it.state.toString(), - it.url.toString(), it.number, it.isClosed, it.dueOn) + MilestoneModel( + it.id, it.title, it.description, it.state.toString(), + it.url.toString(), it.number, it.isClosed, it.dueOn + ) } ?: listOf()) } } diff --git a/app/src/main/java/com/fastaccess/github/usecase/issuesprs/LockUnlockIssuePrUseCase.kt b/app/src/main/java/com/fastaccess/github/usecase/issuesprs/LockUnlockIssuePrUseCase.kt index 29b2621a..ee65fc0a 100644 --- a/app/src/main/java/com/fastaccess/github/usecase/issuesprs/LockUnlockIssuePrUseCase.kt +++ b/app/src/main/java/com/fastaccess/github/usecase/issuesprs/LockUnlockIssuePrUseCase.kt @@ -7,6 +7,7 @@ import com.fastaccess.data.model.LockUnlockEventModel import com.fastaccess.data.model.TimelineModel import com.fastaccess.data.repository.IssueRepositoryProvider import com.fastaccess.data.repository.LoginRepositoryProvider +import com.fastaccess.data.repository.SchedulerProvider import com.fastaccess.domain.usecase.base.BaseObservableUseCase import com.fastaccess.extension.me import github.LockMutation @@ -22,7 +23,8 @@ import javax.inject.Inject class LockUnlockIssuePrUseCase @Inject constructor( private val issueRepositoryProvider: IssueRepositoryProvider, private val apolloClient: ApolloClient, - private val loginRepositoryProvider: LoginRepositoryProvider + private val loginRepositoryProvider: LoginRepositoryProvider, + private val schedulerProvider: SchedulerProvider ) : BaseObservableUseCase() { var repo: String = "" @@ -32,12 +34,16 @@ class LockUnlockIssuePrUseCase @Inject constructor( var lock: Boolean = false override fun buildObservable(): Observable = issueRepositoryProvider.getIssueByNumberMaybe("$login/$repo", number) + .subscribeOn(schedulerProvider.ioThread()) + .observeOn(schedulerProvider.uiThread()) .flatMapObservable { issue -> if (lockReason == null) { Rx2Apollo.from(apolloClient.mutate(LockMutation(issue.id, Input.optional(lockReason)))) } else { Rx2Apollo.from(apolloClient.mutate(UnlockMutation(issue.id))) } + .subscribeOn(schedulerProvider.ioThread()) + .observeOn(schedulerProvider.uiThread()) .map { issue.locked = lock == true issue.activeLockReason = lockReason?.rawValue() diff --git a/app/src/main/java/com/fastaccess/github/usecase/issuesprs/MilestoneIssuePrUseCase.kt b/app/src/main/java/com/fastaccess/github/usecase/issuesprs/MilestoneIssuePrUseCase.kt index 66a0d1b3..40d4aa78 100644 --- a/app/src/main/java/com/fastaccess/github/usecase/issuesprs/MilestoneIssuePrUseCase.kt +++ b/app/src/main/java/com/fastaccess/github/usecase/issuesprs/MilestoneIssuePrUseCase.kt @@ -5,6 +5,7 @@ import com.fastaccess.data.model.TimelineModel import com.fastaccess.data.model.parcelable.MilestoneModel import com.fastaccess.data.repository.IssueRepositoryProvider import com.fastaccess.data.repository.LoginRepositoryProvider +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 @@ -19,7 +20,8 @@ import javax.inject.Inject class MilestoneIssuePrUseCase @Inject constructor( private val issueRepositoryProvider: IssueRepositoryProvider, private val issuePrService: IssuePrService, - private val loginRepositoryProvider: LoginRepositoryProvider + private val loginRepositoryProvider: LoginRepositoryProvider, + private val schedulerProvider: SchedulerProvider ) : BaseObservableUseCase() { var repo: String = "" @@ -29,17 +31,27 @@ class MilestoneIssuePrUseCase @Inject constructor( override fun buildObservable(): Observable> = issueRepositoryProvider.getIssueByNumberMaybe("$login/$repo", number) + .subscribeOn(schedulerProvider.ioThread()) + .observeOn(schedulerProvider.uiThread()) .flatMapObservable { issue -> issuePrService.editIssue(login, repo, number, IssueRequestModel(milestone = milestone)) .map { - val milestone = MilestoneModel(it.milestone?.id?.toString(), + val milestone = MilestoneModel( + it.milestone?.id?.toString(), it.milestone?.title, it.milestone?.description, - it.milestone?.state, it.milestone?.url, it.milestone?.number, it.milestone?.closedAt != null, it.milestone?.dueOn) + it.milestone?.state, it.milestone?.url, it.milestone?.number, it.milestone?.closedAt != null, it.milestone?.dueOn + ) issue.milestone = milestone issueRepositoryProvider.upsert(issue) val me = loginRepositoryProvider.getLoginBlocking()?.me() - return@map Pair(TimelineModel(milestoneEventModel = MilestoneDemilestonedEventModel(Date(), me, - it.milestone?.title ?: it.milestone?.number?.toString(), true)), milestone) + return@map Pair( + TimelineModel( + milestoneEventModel = MilestoneDemilestonedEventModel( + Date(), me, + it.milestone?.title ?: it.milestone?.number?.toString(), true + ) + ), milestone + ) } } } \ No newline at end of file diff --git a/app/src/main/java/com/fastaccess/github/usecase/issuesprs/PutLabelsUseCase.kt b/app/src/main/java/com/fastaccess/github/usecase/issuesprs/PutLabelsUseCase.kt index d14ba13b..5fc436fe 100644 --- a/app/src/main/java/com/fastaccess/github/usecase/issuesprs/PutLabelsUseCase.kt +++ b/app/src/main/java/com/fastaccess/github/usecase/issuesprs/PutLabelsUseCase.kt @@ -1,5 +1,6 @@ package com.fastaccess.github.usecase.issuesprs +import com.fastaccess.data.repository.SchedulerProvider import com.fastaccess.domain.repository.services.RepoService import com.fastaccess.domain.response.body.LabelsBodyModel import com.fastaccess.domain.usecase.base.BaseObservableUseCase @@ -10,7 +11,8 @@ import javax.inject.Inject * Created by Kosh on 16.02.19. */ class PutLabelsUseCase @Inject constructor( - private val repoService: RepoService + private val repoService: RepoService, + private val schedulerProvider: SchedulerProvider ) : BaseObservableUseCase() { var repo: String = "" @@ -21,8 +23,12 @@ class PutLabelsUseCase @Inject constructor( override fun buildObservable(): Observable = when (toRemove.isNullOrEmpty()) { true -> repoService.addLabelsToIssue(login, repo, number, LabelsBodyModel(toAdd)) + .subscribeOn(schedulerProvider.ioThread()) + .observeOn(schedulerProvider.uiThread()) .map { true } else -> repoService.addLabelsToIssue(login, repo, number, LabelsBodyModel(toAdd)) + .subscribeOn(schedulerProvider.ioThread()) + .observeOn(schedulerProvider.uiThread()) .flatMap { Observable.fromIterable(toRemove) } .flatMap { repoService.removeLabelsToIssue(login, repo, number, it) } .map { true } diff --git a/app/src/main/java/com/fastaccess/github/usecase/main/IssuesMainScreenUseCase.kt b/app/src/main/java/com/fastaccess/github/usecase/main/IssuesMainScreenUseCase.kt index 7ac1c57b..c629dad0 100644 --- a/app/src/main/java/com/fastaccess/github/usecase/main/IssuesMainScreenUseCase.kt +++ b/app/src/main/java/com/fastaccess/github/usecase/main/IssuesMainScreenUseCase.kt @@ -5,6 +5,7 @@ import com.apollographql.apollo.rx2.Rx2Apollo import com.fastaccess.data.persistence.models.MyIssuesPullsModel import com.fastaccess.data.repository.LoginRepositoryProvider import com.fastaccess.data.repository.MyIssuesPullsRepositoryProvider +import com.fastaccess.data.repository.SchedulerProvider import com.fastaccess.domain.usecase.base.BaseObservableUseCase import github.GetIssuesWithoutStateQuery import github.type.IssueState @@ -17,7 +18,8 @@ import javax.inject.Inject class IssuesMainScreenUseCase @Inject constructor( private val loginRepository: LoginRepositoryProvider, private val myIssues: MyIssuesPullsRepositoryProvider, - private val apolloClient: ApolloClient + private val apolloClient: ApolloClient, + private val schedulerProvider: SchedulerProvider ) : BaseObservableUseCase() { var state: IssueState = IssueState.OPEN @@ -33,6 +35,8 @@ class IssuesMainScreenUseCase @Inject constructor( .build() ) ) + .subscribeOn(schedulerProvider.ioThread()) + .observeOn(schedulerProvider.uiThread()) .map { it.data()?.user?.issues?.nodes } .map { value -> myIssues.deleteAllIssues() diff --git a/app/src/main/java/com/fastaccess/github/usecase/main/PullRequestsMainScreenUseCase.kt b/app/src/main/java/com/fastaccess/github/usecase/main/PullRequestsMainScreenUseCase.kt index b14dff4f..2075bcc5 100644 --- a/app/src/main/java/com/fastaccess/github/usecase/main/PullRequestsMainScreenUseCase.kt +++ b/app/src/main/java/com/fastaccess/github/usecase/main/PullRequestsMainScreenUseCase.kt @@ -5,6 +5,7 @@ import com.apollographql.apollo.rx2.Rx2Apollo import com.fastaccess.data.persistence.models.MyIssuesPullsModel import com.fastaccess.data.repository.LoginRepositoryProvider import com.fastaccess.data.repository.MyIssuesPullsRepositoryProvider +import com.fastaccess.data.repository.SchedulerProvider import com.fastaccess.domain.usecase.base.BaseObservableUseCase import github.GetPullRequestsQuery import github.type.IssueState @@ -17,7 +18,8 @@ import javax.inject.Inject class PullRequestsMainScreenUseCase @Inject constructor( private val loginRepository: LoginRepositoryProvider, private val myIssues: MyIssuesPullsRepositoryProvider, - private val apolloClient: ApolloClient + private val apolloClient: ApolloClient, + private val schedulerProvider: SchedulerProvider ) : BaseObservableUseCase() { var state: IssueState = IssueState.OPEN @@ -32,6 +34,8 @@ class PullRequestsMainScreenUseCase @Inject constructor( .build() ) ) + .subscribeOn(schedulerProvider.ioThread()) + .observeOn(schedulerProvider.uiThread()) .map { it.data()?.user?.pullRequests?.nodes } .map { value -> myIssues.deleteAllPrs() diff --git a/app/src/main/java/com/fastaccess/github/usecase/notification/NotificationUseCase.kt b/app/src/main/java/com/fastaccess/github/usecase/notification/NotificationUseCase.kt index ce4ac4f9..480d1597 100644 --- a/app/src/main/java/com/fastaccess/github/usecase/notification/NotificationUseCase.kt +++ b/app/src/main/java/com/fastaccess/github/usecase/notification/NotificationUseCase.kt @@ -2,6 +2,7 @@ package com.fastaccess.github.usecase.notification import com.fastaccess.data.persistence.models.NotificationModel import com.fastaccess.data.repository.NotificationRepositoryProvider +import com.fastaccess.data.repository.SchedulerProvider import com.fastaccess.domain.repository.services.NotificationService import com.fastaccess.domain.response.NotificationResponse import com.fastaccess.domain.response.PageableResponse @@ -18,7 +19,8 @@ import javax.inject.Inject class NotificationUseCase @Inject constructor( private val notificationRepositoryProvider: NotificationRepositoryProvider, private val notificationService: NotificationService, - private val gson: Gson + private val gson: Gson, + private val schedulerProvider: SchedulerProvider ) : BaseObservableUseCase() { var page: Int? = null @@ -36,18 +38,21 @@ class NotificationUseCase @Inject constructor( notificationService.getNotifications(getLastWeekDate(), page) } } - return observable.map { it -> - it.items?.let { items -> - if (all == true) { - notificationRepositoryProvider.deleteAll(false) - val list = items.asSequence().filter { it.unread == false }.toList() - notificationRepositoryProvider.insert(NotificationModel.convert(gson, list)) - return@map it + return observable + .subscribeOn(schedulerProvider.ioThread()) + .observeOn(schedulerProvider.uiThread()) + .map { it -> + it.items?.let { items -> + if (all == true) { + notificationRepositoryProvider.deleteAll(false) + val list = items.asSequence().filter { it.unread == false }.toList() + notificationRepositoryProvider.insert(NotificationModel.convert(gson, list)) + return@map it + } + if (page ?: 0 <= 1) notificationRepositoryProvider.deleteAll(true) + notificationRepositoryProvider.insert(NotificationModel.convert(gson, items)) } - if (page ?: 0 <= 1) notificationRepositoryProvider.deleteAll(true) - notificationRepositoryProvider.insert(NotificationModel.convert(gson, items)) + return@map it } - return@map it - } } } \ No newline at end of file diff --git a/app/src/main/java/com/fastaccess/github/usecase/search/FilterSearchReposUseCase.kt b/app/src/main/java/com/fastaccess/github/usecase/search/FilterSearchReposUseCase.kt index d35f63d3..f456bb52 100644 --- a/app/src/main/java/com/fastaccess/github/usecase/search/FilterSearchReposUseCase.kt +++ b/app/src/main/java/com/fastaccess/github/usecase/search/FilterSearchReposUseCase.kt @@ -7,6 +7,7 @@ import com.fastaccess.data.model.CountModel import com.fastaccess.data.model.PageInfoModel import com.fastaccess.data.model.ShortRepoModel import com.fastaccess.data.model.parcelable.FilterByRepo +import com.fastaccess.data.repository.SchedulerProvider import com.fastaccess.domain.usecase.base.BaseObservableUseCase import github.SearchReposQuery import io.reactivex.Observable @@ -16,7 +17,8 @@ import javax.inject.Inject * Created by Kosh on 20.01.19. */ class FilterSearchReposUseCase @Inject constructor( - private val apolloClient: ApolloClient + private val apolloClient: ApolloClient, + private val schedulerProvider: SchedulerProvider ) : BaseObservableUseCase() { var cursor: Input = Input.absent() @@ -25,17 +27,25 @@ class FilterSearchReposUseCase @Inject constructor( override fun buildObservable(): Observable>> = Rx2Apollo .from(apolloClient.query(SearchReposQuery(constructQuery(keyword), cursor))) + .subscribeOn(schedulerProvider.ioThread()) + .observeOn(schedulerProvider.uiThread()) .map { it.data()?.search } .map { search -> val list = search.nodes ?.mapNotNull { it.fragments.shortRepoRowItem } ?.map { repo -> - ShortRepoModel(repo.id, repo.databaseId, repo.name, + ShortRepoModel( + repo.id, repo.databaseId, repo.name, CountModel(repo.stargazers.totalCount), CountModel(repo.issues.totalCount), - CountModel(repo.pullRequests.totalCount), repo.forkCount, repo.isFork, repo.isPrivate) + CountModel(repo.pullRequests.totalCount), repo.forkCount, repo.isFork, repo.isPrivate + ) } ?: arrayListOf() - return@map Pair(PageInfoModel(search.pageInfo.startCursor, search.pageInfo.endCursor, - search.pageInfo.isHasNextPage, search.pageInfo.isHasPreviousPage), list) + return@map Pair( + PageInfoModel( + search.pageInfo.startCursor, search.pageInfo.endCursor, + search.pageInfo.isHasNextPage, search.pageInfo.isHasPreviousPage + ), list + ) } diff --git a/app/src/main/java/com/fastaccess/github/usecase/search/FilterSearchUsersUseCase.kt b/app/src/main/java/com/fastaccess/github/usecase/search/FilterSearchUsersUseCase.kt index cc60ad69..f2dacd43 100644 --- a/app/src/main/java/com/fastaccess/github/usecase/search/FilterSearchUsersUseCase.kt +++ b/app/src/main/java/com/fastaccess/github/usecase/search/FilterSearchUsersUseCase.kt @@ -5,6 +5,7 @@ import com.apollographql.apollo.api.Input import com.apollographql.apollo.rx2.Rx2Apollo import com.fastaccess.data.model.PageInfoModel import com.fastaccess.data.model.ShortUserModel +import com.fastaccess.data.repository.SchedulerProvider import com.fastaccess.domain.usecase.base.BaseObservableUseCase import github.SearchUserQuery import io.reactivex.Observable @@ -14,7 +15,8 @@ import javax.inject.Inject * Created by Kosh on 20.01.19. */ class FilterSearchUsersUseCase @Inject constructor( - private val apolloClient: ApolloClient + private val apolloClient: ApolloClient, + private val schedulerProvider: SchedulerProvider ) : BaseObservableUseCase() { var cursor: Input = Input.absent() @@ -22,16 +24,24 @@ class FilterSearchUsersUseCase @Inject constructor( override fun buildObservable(): Observable>> = Rx2Apollo .from(apolloClient.query(SearchUserQuery(keyword, cursor))) + .subscribeOn(schedulerProvider.ioThread()) + .observeOn(schedulerProvider.uiThread()) .map { it.data()?.search } .map { search -> val list = search.nodes ?.mapNotNull { it.fragments.shortUserRowItem } ?.map { user -> - ShortUserModel(user.id, user.login, user.url.toString(), user.name, user.location, - user.bio, user.avatarUrl.toString(), user.isViewerCanFollow, user.isViewerIsFollowing) + ShortUserModel( + user.id, user.login, user.url.toString(), user.name, user.location, + user.bio, user.avatarUrl.toString(), user.isViewerCanFollow, user.isViewerIsFollowing + ) } ?: arrayListOf() - return@map Pair(PageInfoModel(search.pageInfo.startCursor, search.pageInfo.endCursor, - search.pageInfo.isHasNextPage, search.pageInfo.isHasPreviousPage), list) + return@map Pair( + PageInfoModel( + search.pageInfo.startCursor, search.pageInfo.endCursor, + search.pageInfo.isHasNextPage, search.pageInfo.isHasPreviousPage + ), list + ) } diff --git a/app/src/main/java/com/fastaccess/github/usecase/user/BlockUnblockUserUseCase.kt b/app/src/main/java/com/fastaccess/github/usecase/user/BlockUnblockUserUseCase.kt index 7e3827a6..32e598b8 100644 --- a/app/src/main/java/com/fastaccess/github/usecase/user/BlockUnblockUserUseCase.kt +++ b/app/src/main/java/com/fastaccess/github/usecase/user/BlockUnblockUserUseCase.kt @@ -1,5 +1,6 @@ package com.fastaccess.github.usecase.user +import com.fastaccess.data.repository.SchedulerProvider import com.fastaccess.data.repository.UserRepositoryProvider import com.fastaccess.domain.usecase.base.BaseObservableUseCase import io.reactivex.Observable @@ -8,12 +9,17 @@ import javax.inject.Inject /** * Created by Kosh on 10.06.18. */ -class BlockUnblockUserUseCase @Inject constructor(private val userRepository: UserRepositoryProvider) : BaseObservableUseCase() { +class BlockUnblockUserUseCase @Inject constructor( + private val userRepository: UserRepositoryProvider, + private val schedulerProvider: SchedulerProvider +) : BaseObservableUseCase() { var login: String? = null var block: Boolean = false override fun buildObservable(): Observable = login?.let { login -> userRepository.blockUnblockUser(login, block) + .subscribeOn(schedulerProvider.ioThread()) + .observeOn(schedulerProvider.uiThread()) .map { val isSuccess = it.isSuccessful && it.code() == 204 if (isSuccess) { diff --git a/app/src/main/java/com/fastaccess/github/usecase/user/IsUserBlockedUseCase.kt b/app/src/main/java/com/fastaccess/github/usecase/user/IsUserBlockedUseCase.kt index 1c795029..f9a5acc7 100644 --- a/app/src/main/java/com/fastaccess/github/usecase/user/IsUserBlockedUseCase.kt +++ b/app/src/main/java/com/fastaccess/github/usecase/user/IsUserBlockedUseCase.kt @@ -1,5 +1,6 @@ package com.fastaccess.github.usecase.user +import com.fastaccess.data.repository.SchedulerProvider import com.fastaccess.data.repository.UserRepositoryProvider import com.fastaccess.domain.usecase.base.BaseObservableUseCase import io.reactivex.Observable @@ -8,11 +9,16 @@ import javax.inject.Inject /** * Created by Kosh on 10.06.18. */ -class IsUserBlockedUseCase @Inject constructor(private val userRepository: UserRepositoryProvider) : BaseObservableUseCase() { +class IsUserBlockedUseCase @Inject constructor( + private val userRepository: UserRepositoryProvider, + private val schedulerProvider: SchedulerProvider +) : BaseObservableUseCase() { var login: String? = null override fun buildObservable(): Observable = login?.let { login -> - userRepository.isUserBlock(login) + userRepository.isUserBlocked(login) + .subscribeOn(schedulerProvider.ioThread()) + .observeOn(schedulerProvider.uiThread()) .map { it.isSuccessful && it.code() == 204 } } ?: Observable.empty() } \ No newline at end of file diff --git a/app/src/main/java/com/fastaccess/github/usecase/user/UserFeedsUseCase.kt b/app/src/main/java/com/fastaccess/github/usecase/user/UserFeedsUseCase.kt index 44d89420..36458ec3 100644 --- a/app/src/main/java/com/fastaccess/github/usecase/user/UserFeedsUseCase.kt +++ b/app/src/main/java/com/fastaccess/github/usecase/user/UserFeedsUseCase.kt @@ -1,6 +1,7 @@ package com.fastaccess.github.usecase.user import com.fastaccess.data.repository.FeedsRepositoryProvider +import com.fastaccess.data.repository.SchedulerProvider import com.fastaccess.domain.response.FeedResponse import com.fastaccess.domain.response.PageableResponse import com.fastaccess.domain.usecase.base.BaseObservableUseCase @@ -10,12 +11,17 @@ import javax.inject.Inject /** * Created by Kosh on 20.10.18. */ -class UserFeedsUseCase @Inject constructor(private val feedsRepositoryProvider: FeedsRepositoryProvider) : BaseObservableUseCase() { +class UserFeedsUseCase @Inject constructor( + private val feedsRepositoryProvider: FeedsRepositoryProvider, + private val schedulerProvider: SchedulerProvider +) : BaseObservableUseCase() { var page: Int = 0 var login: String? = null override fun buildObservable(): Observable> = when { login.isNullOrEmpty() -> Observable.empty() else -> feedsRepositoryProvider.getFeeds(login ?: "", page) + .subscribeOn(schedulerProvider.ioThread()) + .observeOn(schedulerProvider.ioThread()) } } \ No newline at end of file diff --git a/app/src/main/java/com/fastaccess/github/usecase/user/UserUseCase.kt b/app/src/main/java/com/fastaccess/github/usecase/user/UserUseCase.kt index 07586ed8..8f23e2c2 100644 --- a/app/src/main/java/com/fastaccess/github/usecase/user/UserUseCase.kt +++ b/app/src/main/java/com/fastaccess/github/usecase/user/UserUseCase.kt @@ -1,6 +1,7 @@ package com.fastaccess.github.usecase.user import com.fastaccess.data.persistence.models.UserModel +import com.fastaccess.data.repository.SchedulerProvider import com.fastaccess.data.repository.UserRepositoryProvider import com.fastaccess.domain.usecase.base.BaseObservableUseCase import io.reactivex.Observable @@ -9,10 +10,18 @@ import javax.inject.Inject /** * Created by Kosh on 10.06.18. */ -class UserUseCase @Inject constructor(private val userRepository: UserRepositoryProvider) : BaseObservableUseCase() { +class UserUseCase @Inject constructor( + private val userRepository: UserRepositoryProvider, + val schedulerProvider: SchedulerProvider +) : BaseObservableUseCase() { var login: String? = null - override fun buildObservable(): Observable = login?.let { userRepository.getUserFromRemote(it) } ?: Observable.empty() + override fun buildObservable(): Observable { + val observable = login?.let { userRepository.getUserFromRemote(it) } ?: Observable.empty() + return observable + .subscribeOn(schedulerProvider.ioThread()) + .observeOn(schedulerProvider.uiThread()) + } fun getUser(login: String) = userRepository.getUser(login) } \ No newline at end of file diff --git a/app/src/main/res/layouts/main_layouts/layout/issue_pr_fragment_layout.xml b/app/src/main/res/layouts/main_layouts/layout/issue_pr_fragment_layout.xml index e1503e12..2f6efe41 100644 --- a/app/src/main/res/layouts/main_layouts/layout/issue_pr_fragment_layout.xml +++ b/app/src/main/res/layouts/main_layouts/layout/issue_pr_fragment_layout.xml @@ -119,7 +119,7 @@ android:layout_height="?actionBarSize" android:orientation="horizontal"> - - + android:layout_gravity="center" + android:layout_marginEnd="@dimen/spacing_xs_large"> diff --git a/build-dependecies/fasthub-dependencies.gradle b/build-dependecies/fasthub-dependencies.gradle index da923d72..6cea7ca2 100644 --- a/build-dependecies/fasthub-dependencies.gradle +++ b/build-dependecies/fasthub-dependencies.gradle @@ -64,7 +64,8 @@ ext { 'com.github.zagum:Android-ExpandIcon:1.2.1', "com.evernote:android-state:$androidState", 'org.jsoup:jsoup:1.12.1', - 'com.github.k0shk0sh:RetainedDateTimePickers:1.0.2' + 'com.github.k0shk0sh:RetainedDateTimePickers:1.0.2', + 'com.otaliastudios:autocomplete:1.1.0' ] networking = [ diff --git a/data/src/main/java/com/fastaccess/data/repository/AndroidSchedulerProvider.kt b/data/src/main/java/com/fastaccess/data/repository/AndroidSchedulerProvider.kt new file mode 100644 index 00000000..6f0cfa89 --- /dev/null +++ b/data/src/main/java/com/fastaccess/data/repository/AndroidSchedulerProvider.kt @@ -0,0 +1,20 @@ +package com.fastaccess.data.repository + +import io.reactivex.Scheduler +import io.reactivex.android.schedulers.AndroidSchedulers +import io.reactivex.schedulers.Schedulers + +/** + * Created by Kosh on 2019-05-09. + */ +class AndroidSchedulerProvider : SchedulerProvider { + override fun uiThread(): Scheduler = AndroidSchedulers.mainThread() + override fun ioThread(): Scheduler = Schedulers.io() + override fun computationThread(): Scheduler = Schedulers.computation() +} + +interface SchedulerProvider { + fun uiThread(): Scheduler + fun ioThread(): Scheduler + fun computationThread(): Scheduler +} \ No newline at end of file diff --git a/data/src/main/java/com/fastaccess/data/repository/NotificationRepositoryProvider.kt b/data/src/main/java/com/fastaccess/data/repository/NotificationRepositoryProvider.kt index 9da86d26..4ad3c2f0 100644 --- a/data/src/main/java/com/fastaccess/data/repository/NotificationRepositoryProvider.kt +++ b/data/src/main/java/com/fastaccess/data/repository/NotificationRepositoryProvider.kt @@ -5,7 +5,6 @@ import androidx.paging.DataSource import com.fastaccess.data.model.GroupedNotificationsModel import com.fastaccess.data.persistence.dao.NotificationsDao import com.fastaccess.data.persistence.models.NotificationModel -import com.fastaccess.extension.uiThread import com.fastaccess.github.extensions.map import io.reactivex.Completable import io.reactivex.Maybe @@ -14,7 +13,10 @@ import javax.inject.Inject /** * Created by Kosh on 22.06.18. */ -class NotificationRepositoryProvider @Inject constructor(private val dao: NotificationsDao) : NotificationRepository { +class NotificationRepositoryProvider @Inject constructor( + private val dao: NotificationsDao, + private val schedulerProvider: SchedulerProvider +) : NotificationRepository { override fun getNotifications(unread: Boolean): DataSource.Factory = dao.getNotifications(unread) override fun getAllNotifications(): LiveData> = dao.getAllNotifications(false).map(groupNotifications()) @@ -24,10 +26,14 @@ class NotificationRepositoryProvider @Inject constructor(private val dao: Notifi override fun update(model: NotificationModel): Int = dao.update(model) override fun delete(model: NotificationModel) = dao.delete(model) override fun deleteAll(unread: Boolean) = dao.deleteAll(unread) - override fun markAsRead(id: String): Completable = Completable.fromCallable { dao.markAsRead(id) }.uiThread() - override fun markAllAsRead(): Completable = Completable.fromCallable { dao.markAllAsRead() }.uiThread() + override fun markAsRead(id: String): Completable = Completable.fromCallable { dao.markAsRead(id) } + override fun markAllAsRead(): Completable = Completable.fromCallable { dao.markAllAsRead() } + .subscribeOn(schedulerProvider.ioThread()) + .observeOn(schedulerProvider.uiThread()) + override fun getAllNotificationsAsMaybe(unread: Boolean): Maybe> = Maybe.just(dao.getAllNotificationsBlocking(unread)) - .uiThread() + .subscribeOn(schedulerProvider.ioThread()) + .observeOn(schedulerProvider.uiThread()) /** * Fixes Cannot infer a type for this parameter. Please specify it explicitly. 🤷‍🤷‍🤷‍🤷‍🤷‍🤷‍ diff --git a/data/src/main/java/com/fastaccess/data/repository/UserRepositoryProvider.kt b/data/src/main/java/com/fastaccess/data/repository/UserRepositoryProvider.kt index 17a593a9..58e3e9ae 100644 --- a/data/src/main/java/com/fastaccess/data/repository/UserRepositoryProvider.kt +++ b/data/src/main/java/com/fastaccess/data/repository/UserRepositoryProvider.kt @@ -17,29 +17,36 @@ import javax.inject.Inject * Created by Kosh on 10.06.18. */ -class UserRepositoryProvider @Inject constructor(private val userDao: UserDao, - private val apolloClient: ApolloClient, - private val userService: UserService) : UserRepository { +class UserRepositoryProvider @Inject constructor( + private val userDao: UserDao, + private val apolloClient: ApolloClient, + private val userService: UserService +) : UserRepository { override fun getUserFromRemote(login: String): Observable = Rx2Apollo.from(apolloClient.query(GetProfileQuery(login))) .filter { !it.hasErrors() } .map { it -> return@map it.data()?.user?.let { queryUser -> - UserModel(queryUser.databaseId - ?: 0, queryUser.login, queryUser.avatarUrl.toString(), queryUser.url.toString(), queryUser.name, queryUser.company, + UserModel( + queryUser.databaseId ?: 0, queryUser.login, queryUser.avatarUrl.toString(), + queryUser.url.toString(), queryUser.name, queryUser.company, queryUser.websiteUrl.toString(), queryUser.location, queryUser.email, queryUser.bio, queryUser.createdAt, queryUser.createdAt, queryUser.isViewerCanFollow, queryUser.isViewerIsFollowing, queryUser.isViewer, - queryUser.isDeveloperProgramMember, CountModel(queryUser.followers.totalCount), - CountModel(queryUser.following.totalCount), + queryUser.isDeveloperProgramMember, CountModel(queryUser.followers.totalCount), CountModel(queryUser.following.totalCount), UserOrganizationModel(queryUser.organizations.totalCount, queryUser.organizations.nodes?.asSequence()?.map { UserOrganizationNodesModel(it.avatarUrl.toString(), it.location, it.email, it.login, it.name) - }?.toList()), UserPinnedReposModel(queryUser.pinnedRepositories.totalCount, - queryUser.pinnedRepositories.nodes?.asSequence()?.map { - UserPinnedRepoNodesModel(it.name, it.nameWithOwner, - RepoLanguageModel(it.primaryLanguage?.name, it.primaryLanguage?.color), - CountModel(it.stargazers.totalCount), CountModel(it.issues.totalCount), - CountModel(it.pullRequests.totalCount), it.forkCount) - }?.toList())) + }?.toList()), UserPinnedReposModel( + queryUser.pinnedRepositories.totalCount, + queryUser.pinnedRepositories.nodes?.asSequence()?.map { + UserPinnedRepoNodesModel( + it.name, it.nameWithOwner, + RepoLanguageModel(it.primaryLanguage?.name, it.primaryLanguage?.color), + CountModel(it.stargazers.totalCount), CountModel(it.issues.totalCount), + CountModel(it.pullRequests.totalCount), it.forkCount + ) + }?.toList() + ) + ) }?.apply { userDao.upsert(this) } @@ -50,14 +57,20 @@ class UserRepositoryProvider @Inject constructor(private val userDao: UserDao, override fun getUser(login: String): LiveData = userDao.getUser(login) override fun deleteAll() = userDao.deleteAll() override fun updateUser(userModel: UserModel) = userDao.update(userModel) - override fun isUserBlock(login: String): Observable> = userService.isUserBlocked(login) + override fun isUserBlocked(login: String): Observable> = userService.isUserBlocked(login) - override fun blockUnblockUser(login: String, block: Boolean): Observable> = when (block) { + override fun blockUnblockUser( + login: String, + block: Boolean + ): Observable> = when (block) { true -> userService.blockUser(login) else -> userService.unBlockUser(login) } - override fun followUnfollowUser(login: String, follow: Boolean): Observable> = when (follow) { + override fun followUnfollowUser( + login: String, + follow: Boolean + ): Observable> = when (follow) { true -> userService.followUser(login) else -> userService.unfollowUser(login) } @@ -69,8 +82,16 @@ interface UserRepository { fun getUserBlocking(login: String): UserModel? fun getUserFromRemote(login: String): Observable fun deleteAll() - fun isUserBlock(login: String): Observable> - fun blockUnblockUser(login: String, block: Boolean): Observable> - fun followUnfollowUser(login: String, follow: Boolean): Observable> + fun isUserBlocked(login: String): Observable> + fun blockUnblockUser( + login: String, + block: Boolean + ): Observable> + + fun followUnfollowUser( + login: String, + follow: Boolean + ): Observable> + fun updateUser(userModel: UserModel) } diff --git a/data/src/main/java/com/fastaccess/extension/RxExtension.kt b/data/src/main/java/com/fastaccess/extension/RxExtension.kt deleted file mode 100644 index 7718053b..00000000 --- a/data/src/main/java/com/fastaccess/extension/RxExtension.kt +++ /dev/null @@ -1,39 +0,0 @@ -package com.fastaccess.extension - -import io.reactivex.* -import io.reactivex.android.schedulers.AndroidSchedulers -import io.reactivex.schedulers.Schedulers - -/** - * Created by Kosh on 16.08.18. - */ - -fun Maybe.toObservableDistinct(): Observable = this.subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .toObservable() - .distinctUntilChanged() - -fun Flowable.toObservableDistinct(): Observable = this.subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .toObservable() - .distinctUntilChanged() - -fun Maybe.toObservable(): Observable = this.subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .toObservable() - -fun Observable.uiThread() = this.subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - -fun Observable.uiThreadDistinct() = this.subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .distinctUntilChanged() - -fun Completable.uiThread() = this.subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - -fun Single.uiThread() = this.subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - -fun Maybe.uiThread() = this.subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) \ No newline at end of file diff --git a/domain/src/main/java/com/fastaccess/domain/usecase/base/BaseCompletableUseCase.kt b/domain/src/main/java/com/fastaccess/domain/usecase/base/BaseCompletableUseCase.kt index 38212d75..263e4e63 100644 --- a/domain/src/main/java/com/fastaccess/domain/usecase/base/BaseCompletableUseCase.kt +++ b/domain/src/main/java/com/fastaccess/domain/usecase/base/BaseCompletableUseCase.kt @@ -2,8 +2,6 @@ package com.fastaccess.domain.usecase.base import io.reactivex.Completable import io.reactivex.CompletableObserver -import io.reactivex.android.schedulers.AndroidSchedulers -import io.reactivex.schedulers.Schedulers /** * Created by Kosh on 12.05.18. @@ -13,25 +11,19 @@ abstract class BaseCompletableUseCase : BaseUseCase() { fun disposeAndExecuteObservable(observer: CompletableObserver) { disposeAndExecute(buildCompletable() - .doOnSubscribe { observer.onSubscribe(it) } - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe - ( - { observer.onComplete() }, - { observer.onError(it) } - )) + .doOnSubscribe { observer.onSubscribe(it) } + .subscribe( + { observer.onComplete() }, + { observer.onError(it) } + )) } fun executeObservable(observer: CompletableObserver) { execute(buildCompletable() - .doOnSubscribe { observer.onSubscribe(it) } - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe - ( - { observer.onComplete() }, - { observer.onError(it) } - )) + .doOnSubscribe { observer.onSubscribe(it) } + .subscribe( + { observer.onComplete() }, + { observer.onError(it) } + )) } } diff --git a/domain/src/main/java/com/fastaccess/domain/usecase/base/BaseFlowableUseCase.kt b/domain/src/main/java/com/fastaccess/domain/usecase/base/BaseFlowableUseCase.kt index 3f412336..110e9d9a 100644 --- a/domain/src/main/java/com/fastaccess/domain/usecase/base/BaseFlowableUseCase.kt +++ b/domain/src/main/java/com/fastaccess/domain/usecase/base/BaseFlowableUseCase.kt @@ -1,8 +1,6 @@ package com.fastaccess.domain.usecase.base import io.reactivex.Flowable -import io.reactivex.android.schedulers.AndroidSchedulers -import io.reactivex.schedulers.Schedulers import io.reactivex.subscribers.DisposableSubscriber /** @@ -13,27 +11,21 @@ abstract class BaseFlowableUseCase : BaseUseCase() { fun disposeAndExecuteObservable(observer: DisposableSubscriber) { disposeAndExecute(buildFlowable() - .doOnSubscribe { observer.onSubscribe(it) } - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe - ( - { observer.onNext(it) }, - { observer.onError(it) }, - { observer.onComplete() } - )) + .doOnSubscribe { observer.onSubscribe(it) } + .subscribe( + { observer.onNext(it) }, + { observer.onError(it) }, + { observer.onComplete() } + )) } fun executeObservable(observer: DisposableSubscriber) { execute(buildFlowable() - .doOnSubscribe { observer.onSubscribe(it) } - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe - ( - { observer.onNext(it) }, - { observer.onError(it) }, - { observer.onComplete() } - )) + .doOnSubscribe { observer.onSubscribe(it) } + .subscribe( + { observer.onNext(it) }, + { observer.onError(it) }, + { observer.onComplete() } + )) } } diff --git a/domain/src/main/java/com/fastaccess/domain/usecase/base/BaseMaybeUseCase.kt b/domain/src/main/java/com/fastaccess/domain/usecase/base/BaseMaybeUseCase.kt index f7ca9a9d..f0387d7d 100644 --- a/domain/src/main/java/com/fastaccess/domain/usecase/base/BaseMaybeUseCase.kt +++ b/domain/src/main/java/com/fastaccess/domain/usecase/base/BaseMaybeUseCase.kt @@ -2,8 +2,6 @@ package com.fastaccess.domain.usecase.base import io.reactivex.Maybe import io.reactivex.Observer -import io.reactivex.android.schedulers.AndroidSchedulers -import io.reactivex.schedulers.Schedulers /** * Created by Kosh on 12.05.18. @@ -13,27 +11,21 @@ abstract class BaseMaybeUseCase : BaseUseCase() { fun disposeAndExecuteObservable(observer: Observer) { disposeAndExecute(buildMaybe() - .doOnSubscribe { observer.onSubscribe(it) } - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe - ( - { observer.onNext(it) }, - { observer.onError(it) }, - { observer.onComplete() } - )) + .doOnSubscribe { observer.onSubscribe(it) } + .subscribe( + { observer.onNext(it) }, + { observer.onError(it) }, + { observer.onComplete() } + )) } fun executeObservable(observer: Observer) { execute(buildMaybe() - .doOnSubscribe { observer.onSubscribe(it) } - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe - ( - { observer.onNext(it) }, - { observer.onError(it) }, - { observer.onComplete() } - )) + .doOnSubscribe { observer.onSubscribe(it) } + .subscribe( + { observer.onNext(it) }, + { observer.onError(it) }, + { observer.onComplete() } + )) } } diff --git a/domain/src/main/java/com/fastaccess/domain/usecase/base/BaseObservableUseCase.kt b/domain/src/main/java/com/fastaccess/domain/usecase/base/BaseObservableUseCase.kt index 4129d4c7..ab101493 100644 --- a/domain/src/main/java/com/fastaccess/domain/usecase/base/BaseObservableUseCase.kt +++ b/domain/src/main/java/com/fastaccess/domain/usecase/base/BaseObservableUseCase.kt @@ -2,8 +2,6 @@ package com.fastaccess.domain.usecase.base import io.reactivex.Observable import io.reactivex.Observer -import io.reactivex.android.schedulers.AndroidSchedulers -import io.reactivex.schedulers.Schedulers /** * Created by Kosh on 12.05.18. @@ -13,34 +11,25 @@ abstract class BaseObservableUseCase : BaseUseCase() { fun disposeAndExecuteObservable(observer: Observer) { disposeAndExecute(buildObservable() - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .doOnSubscribe { observer.onSubscribe(it) } - .subscribe - ( - { observer.onNext(it) }, - { observer.onError(it) }, - { observer.onComplete() } - )) + .doOnSubscribe { observer.onSubscribe(it) } + .subscribe( + { observer.onNext(it) }, + { observer.onError(it) }, + { observer.onComplete() } + )) } fun executeObservable(observer: Observer) { execute(buildObservable() - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .doOnSubscribe { observer.onSubscribe(it) } - .subscribe - ( - { observer.onNext(it) }, - { observer.onError(it) }, - { observer.onComplete() } - )) + .doOnSubscribe { observer.onSubscribe(it) } + .subscribe( + { observer.onNext(it) }, + { observer.onError(it) }, + { observer.onComplete() } + )) } fun executeSafely(observable: Observable) { - execute(observable - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe({}, { t -> t.printStackTrace() })) + execute(observable.subscribe({}, { t -> t.printStackTrace() })) } } diff --git a/domain/src/main/java/com/fastaccess/domain/usecase/base/BaseSingleUseCase.kt b/domain/src/main/java/com/fastaccess/domain/usecase/base/BaseSingleUseCase.kt index 058150d6..7542c559 100644 --- a/domain/src/main/java/com/fastaccess/domain/usecase/base/BaseSingleUseCase.kt +++ b/domain/src/main/java/com/fastaccess/domain/usecase/base/BaseSingleUseCase.kt @@ -2,8 +2,6 @@ package com.fastaccess.domain.usecase.base import io.reactivex.Single import io.reactivex.SingleObserver -import io.reactivex.android.schedulers.AndroidSchedulers -import io.reactivex.schedulers.Schedulers /** * Created by Kosh on 12.05.18. @@ -13,25 +11,19 @@ abstract class BaseSingleUseCase : BaseUseCase() { fun disposeAndExecuteObservable(observer: SingleObserver) { disposeAndExecute(buildSingle() - .doOnSubscribe { observer.onSubscribe(it) } - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe - ( - { observer.onSuccess(it) }, - { observer.onError(it) } - )) + .doOnSubscribe { observer.onSubscribe(it) } + .subscribe( + { observer.onSuccess(it) }, + { observer.onError(it) } + )) } fun executeObservable(observer: SingleObserver) { execute(buildSingle() - .doOnSubscribe { observer.onSubscribe(it) } - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe - ( - { observer.onSuccess(it) }, - { observer.onError(it) } - )) + .doOnSubscribe { observer.onSubscribe(it) } + .subscribe( + { observer.onSuccess(it) }, + { observer.onError(it) } + )) } }