mirror of
https://github.com/sudoxnym/habitica-android.git
synced 2026-04-14 11:46:32 +00:00
Begin migrating from RxJava to coroutines
This commit is contained in:
parent
bf5bb9939b
commit
03d5648003
138 changed files with 1788 additions and 1912 deletions
|
|
@ -3,7 +3,6 @@ package com.habitrpg.android.habitica
|
|||
import android.content.SharedPreferences
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import com.habitrpg.android.habitica.api.GSonFactoryCreator
|
||||
import com.habitrpg.common.habitica.api.HostConfig
|
||||
import com.habitrpg.android.habitica.api.MaintenanceApiService
|
||||
import com.habitrpg.android.habitica.data.ApiClient
|
||||
import com.habitrpg.android.habitica.data.ContentRepository
|
||||
|
|
@ -14,9 +13,9 @@ import com.habitrpg.android.habitica.data.TaskRepository
|
|||
import com.habitrpg.android.habitica.data.TutorialRepository
|
||||
import com.habitrpg.android.habitica.data.UserRepository
|
||||
import com.habitrpg.android.habitica.helpers.AppConfigManager
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.android.habitica.helpers.MainNavigationController
|
||||
import com.habitrpg.android.habitica.helpers.NotificationsManager
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.helpers.SoundManager
|
||||
import com.habitrpg.android.habitica.interactors.FeedPetUseCase
|
||||
import com.habitrpg.android.habitica.interactors.HatchPetUseCase
|
||||
|
|
@ -29,22 +28,23 @@ import com.habitrpg.android.habitica.models.inventory.QuestContent
|
|||
import com.habitrpg.android.habitica.models.user.User
|
||||
import com.habitrpg.android.habitica.proxy.AnalyticsManager
|
||||
import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel
|
||||
import com.habitrpg.common.habitica.api.HostConfig
|
||||
import com.kaspersky.kaspresso.testcases.api.testcase.TestCase
|
||||
import io.mockk.clearAllMocks
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import io.mockk.mockkObject
|
||||
import io.mockk.slot
|
||||
import io.reactivex.rxjava3.core.BackpressureStrategy
|
||||
import io.reactivex.rxjava3.core.Flowable
|
||||
import io.reactivex.rxjava3.subjects.PublishSubject
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
import org.junit.Before
|
||||
import java.io.InputStreamReader
|
||||
import java.lang.reflect.Type
|
||||
import kotlin.reflect.KCallable
|
||||
import kotlin.reflect.KMutableProperty1
|
||||
import kotlin.reflect.full.starProjectedType
|
||||
import kotlin.reflect.jvm.javaField
|
||||
import org.junit.Before
|
||||
|
||||
open class HabiticaTestCase : TestCase() {
|
||||
val gson = GSonFactoryCreator.createGson()
|
||||
|
|
@ -68,8 +68,7 @@ open class HabiticaTestCase : TestCase() {
|
|||
val hatchPetUseCase: HatchPetUseCase = mockk(relaxed = true)
|
||||
val feedPetUseCase: FeedPetUseCase = mockk(relaxed = true)
|
||||
|
||||
val userSubject = PublishSubject.create<User>()
|
||||
val userEvents: Flowable<User> = userSubject.toFlowable(BackpressureStrategy.DROP)
|
||||
val userState = MutableStateFlow<User?>(null)
|
||||
var user = User()
|
||||
lateinit var content: ContentResult
|
||||
|
||||
|
|
@ -85,27 +84,27 @@ open class HabiticaTestCase : TestCase() {
|
|||
user = loadJsonFile("user", User::class.java)
|
||||
user.stats?.lvl = 20
|
||||
user.stats?.points = 30
|
||||
every { userRepository.getUser() } returns userEvents
|
||||
every { userRepository.getUser() } returns userState
|
||||
every { userViewModel.user } returns MutableLiveData<User?>(user)
|
||||
mockkObject(RxErrorHandler)
|
||||
every { RxErrorHandler.reportError(capture(errorSlot)) } answers {
|
||||
mockkObject(ExceptionHandler)
|
||||
every { ExceptionHandler.reportError(capture(errorSlot)) } answers {
|
||||
throw errorSlot.captured
|
||||
}
|
||||
every { socialRepository.getUnmanagedCopy(capture(unmanagedSlot)) } answers { unmanagedSlot.captured }
|
||||
content = loadJsonFile("content", ContentResult::class.java)
|
||||
every { inventoryRepository.getPets() } returns Flowable.just(content.pets)
|
||||
every { inventoryRepository.getMounts() } returns Flowable.just(content.mounts)
|
||||
every { inventoryRepository.getPets() } returns flowOf(content.pets)
|
||||
every { inventoryRepository.getMounts() } returns flowOf(content.mounts)
|
||||
every { inventoryRepository.getItemsFlowable(Food::class.java) } returns Flowable.just(content.food)
|
||||
every { inventoryRepository.getItemsFlowable(Egg::class.java) } returns Flowable.just(content.eggs)
|
||||
every { inventoryRepository.getItemsFlowable(HatchingPotion::class.java) } returns Flowable.just(content.hatchingPotions)
|
||||
every { inventoryRepository.getItemsFlowable(QuestContent::class.java) } returns Flowable.just(content.quests)
|
||||
|
||||
every { inventoryRepository.getItemsFlowable(Food::class.java, any()) } returns Flowable.just(content.food)
|
||||
every { inventoryRepository.getItemsFlowable(Egg::class.java, any()) } answers {
|
||||
Flowable.just(content.eggs)
|
||||
every { inventoryRepository.getItems(Food::class.java, any()) } returns flowOf(content.food)
|
||||
every { inventoryRepository.getItems(Egg::class.java, any()) } answers {
|
||||
flowOf(content.eggs)
|
||||
}
|
||||
every { inventoryRepository.getItemsFlowable(HatchingPotion::class.java, any()) } returns Flowable.just(content.hatchingPotions)
|
||||
every { inventoryRepository.getItemsFlowable(QuestContent::class.java, any()) } returns Flowable.just(content.quests)
|
||||
every { inventoryRepository.getItems(HatchingPotion::class.java, any()) } returns flowOf(content.hatchingPotions)
|
||||
every { inventoryRepository.getItems(QuestContent::class.java, any()) } returns flowOf(content.quests)
|
||||
}
|
||||
|
||||
internal fun <T> loadJsonFile(s: String, type: Type): T {
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ class StatsFragmentTest : FragmentTestCase<StatsFragment, FragmentStatsBinding,
|
|||
fun setUpUser() {
|
||||
user.stats?.lvl = 20
|
||||
user.stats?.points = 30
|
||||
userSubject.onNext(user)
|
||||
userState.onNext(user)
|
||||
|
||||
every { inventoryRepository.getEquipment(listOf()) } returns Flowable.just(listOf())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ internal class ItemRecyclerFragmentTest : FragmentTestCase<ItemRecyclerFragment,
|
|||
items = (items + items).sortedBy { it.key }
|
||||
Flowable.just(items)
|
||||
}
|
||||
every { inventoryRepository.getItemsFlowable(Food::class.java, any()) } answers {
|
||||
every { inventoryRepository.getItems(Food::class.java, any()) } answers {
|
||||
Flowable.just((content.eggs + content.eggs).sortedBy { it.key })
|
||||
}
|
||||
fragment.itemType = "food"
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ import com.habitrpg.android.habitica.components.AppComponent
|
|||
import com.habitrpg.android.habitica.components.UserComponent
|
||||
import com.habitrpg.android.habitica.data.ApiClient
|
||||
import com.habitrpg.android.habitica.helpers.AdHandler
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.android.habitica.helpers.notifications.PushNotificationManager
|
||||
import com.habitrpg.android.habitica.modules.UserModule
|
||||
import com.habitrpg.android.habitica.modules.UserRepositoryModule
|
||||
|
|
@ -86,7 +86,7 @@ abstract class HabiticaBaseApplication : Application(), Application.ActivityLife
|
|||
}
|
||||
setupCoil()
|
||||
|
||||
RxErrorHandler.init(analyticsManager)
|
||||
ExceptionHandler.init(analyticsManager)
|
||||
|
||||
FirebaseAnalytics.getInstance(this).setUserProperty("app_testing_level", BuildConfig.TESTING_LEVEL)
|
||||
|
||||
|
|
@ -120,7 +120,6 @@ abstract class HabiticaBaseApplication : Application(), Application.ActivityLife
|
|||
.deleteRealmIfMigrationNeeded()
|
||||
.allowWritesOnUiThread(true)
|
||||
.compactOnLaunch { totalBytes, usedBytes ->
|
||||
|
||||
// Compact if the file is over 100MB in size and less than 50% 'used'
|
||||
val oneHundredMB = 50 * 1024 * 1024
|
||||
(totalBytes > oneHundredMB) && (usedBytes / totalBytes) < 0.5
|
||||
|
|
|
|||
|
|
@ -26,13 +26,13 @@ import com.habitrpg.android.habitica.models.tasks.TaskList
|
|||
import com.habitrpg.android.habitica.models.user.Items
|
||||
import com.habitrpg.android.habitica.models.user.Stats
|
||||
import com.habitrpg.android.habitica.models.user.User
|
||||
import com.habitrpg.common.habitica.models.HabitResponse
|
||||
import com.habitrpg.common.habitica.models.PurchaseValidationRequest
|
||||
import com.habitrpg.common.habitica.models.PurchaseValidationResult
|
||||
import com.habitrpg.common.habitica.models.auth.UserAuth
|
||||
import com.habitrpg.common.habitica.models.auth.UserAuthResponse
|
||||
import com.habitrpg.common.habitica.models.auth.UserAuthSocial
|
||||
import com.habitrpg.shared.habitica.models.responses.FeedResponse
|
||||
import com.habitrpg.common.habitica.models.HabitResponse
|
||||
import com.habitrpg.shared.habitica.models.responses.Status
|
||||
import com.habitrpg.shared.habitica.models.responses.TaskDirectionData
|
||||
import com.habitrpg.shared.habitica.models.responses.VerifyUsernameResponse
|
||||
|
|
@ -49,27 +49,27 @@ import retrofit2.http.Query
|
|||
|
||||
@JvmSuppressWildcards
|
||||
interface ApiService {
|
||||
@get:GET("status")
|
||||
val status: Flowable<HabitResponse<Status>>
|
||||
@GET("status")
|
||||
suspend fun getStatus(): HabitResponse<Status>
|
||||
|
||||
/* user API */
|
||||
|
||||
@get:GET("user/")
|
||||
val user: Flowable<HabitResponse<User>>
|
||||
@GET("user/")
|
||||
suspend fun getUser(): HabitResponse<User>
|
||||
|
||||
@GET("inbox/messages")
|
||||
fun getInboxMessages(@Query("conversation") uuid: String, @Query("page") page: Int): Flowable<HabitResponse<List<ChatMessage>>>
|
||||
suspend fun getInboxMessages(@Query("conversation") uuid: String, @Query("page") page: Int): HabitResponse<List<ChatMessage>>
|
||||
@GET("inbox/conversations")
|
||||
fun getInboxConversations(): Flowable<HabitResponse<List<InboxConversation>>>
|
||||
|
||||
@get:GET("tasks/user")
|
||||
val tasks: Flowable<HabitResponse<TaskList>>
|
||||
@GET("tasks/user")
|
||||
suspend fun getTasks(): HabitResponse<TaskList>
|
||||
|
||||
@get:GET("world-state")
|
||||
val worldState: Flowable<HabitResponse<WorldState>>
|
||||
@GET("world-state")
|
||||
suspend fun worldState(): HabitResponse<WorldState>
|
||||
|
||||
@GET("content")
|
||||
fun getContent(@Query("language") language: String?): Flowable<HabitResponse<ContentResult>>
|
||||
suspend fun getContent(@Query("language") language: String?): HabitResponse<ContentResult>
|
||||
|
||||
@PUT("user/")
|
||||
fun updateUser(@Body updateDictionary: Map<String, Any>): Flowable<HabitResponse<User>>
|
||||
|
|
@ -177,10 +177,10 @@ interface ApiService {
|
|||
fun loginApple(@Body auth: Map<String, Any>): Flowable<HabitResponse<UserAuthResponse>>
|
||||
|
||||
@POST("user/sleep")
|
||||
fun sleep(): Flowable<HabitResponse<Boolean>>
|
||||
suspend fun sleep(): HabitResponse<Boolean>
|
||||
|
||||
@POST("user/revive")
|
||||
fun revive(): Flowable<HabitResponse<User>>
|
||||
suspend fun revive(): HabitResponse<User>
|
||||
|
||||
@POST("user/class/cast/{skill}")
|
||||
fun useSkill(
|
||||
|
|
@ -193,13 +193,13 @@ interface ApiService {
|
|||
fun useSkill(@Path("skill") skillName: String, @Query("targetType") targetType: String): Flowable<HabitResponse<SkillResponse>>
|
||||
|
||||
@POST("user/change-class")
|
||||
fun changeClass(): Flowable<HabitResponse<User>>
|
||||
suspend fun changeClass(): HabitResponse<User>
|
||||
|
||||
@POST("user/change-class")
|
||||
fun changeClass(@Query("class") className: String): Flowable<HabitResponse<User>>
|
||||
suspend fun changeClass(@Query("class") className: String): HabitResponse<User>
|
||||
|
||||
@POST("user/disable-classes")
|
||||
fun disableClasses(): Flowable<HabitResponse<User>>
|
||||
suspend fun disableClasses(): HabitResponse<User>
|
||||
|
||||
@POST("user/mark-pms-read")
|
||||
fun markPrivateMessagesRead(): Flowable<Void>
|
||||
|
|
@ -210,25 +210,25 @@ interface ApiService {
|
|||
fun listGroups(@Query("type") type: String): Flowable<HabitResponse<List<Group>>>
|
||||
|
||||
@GET("groups/{gid}")
|
||||
fun getGroup(@Path("gid") groupId: String): Flowable<HabitResponse<Group>>
|
||||
suspend fun getGroup(@Path("gid") groupId: String): HabitResponse<Group>
|
||||
|
||||
@POST("groups")
|
||||
fun createGroup(@Body item: Group): Flowable<HabitResponse<Group>>
|
||||
suspend fun createGroup(@Body item: Group): HabitResponse<Group>
|
||||
|
||||
@PUT("groups/{id}")
|
||||
fun updateGroup(@Path("id") id: String, @Body item: Group): Flowable<HabitResponse<Group>>
|
||||
suspend fun updateGroup(@Path("id") id: String, @Body item: Group): HabitResponse<Group>
|
||||
|
||||
@POST("groups/{groupID}/removeMember/{userID}")
|
||||
fun removeMemberFromGroup(@Path("groupID") groupID: String, @Path("userID") userID: String): Flowable<HabitResponse<Void>>
|
||||
suspend fun removeMemberFromGroup(@Path("groupID") groupID: String, @Path("userID") userID: String): HabitResponse<Void>
|
||||
|
||||
@GET("groups/{gid}/chat")
|
||||
fun listGroupChat(@Path("gid") groupId: String): Flowable<HabitResponse<List<ChatMessage>>>
|
||||
suspend fun listGroupChat(@Path("gid") groupId: String): HabitResponse<List<ChatMessage>>
|
||||
|
||||
@POST("groups/{gid}/join")
|
||||
fun joinGroup(@Path("gid") groupId: String): Flowable<HabitResponse<Group>>
|
||||
suspend fun joinGroup(@Path("gid") groupId: String): HabitResponse<Group>
|
||||
|
||||
@POST("groups/{gid}/leave")
|
||||
fun leaveGroup(@Path("gid") groupId: String, @Query("keepChallenges") keepChallenges: String): Flowable<HabitResponse<Void>>
|
||||
suspend fun leaveGroup(@Path("gid") groupId: String, @Query("keepChallenges") keepChallenges: String): HabitResponse<Void>
|
||||
|
||||
@POST("groups/{gid}/chat")
|
||||
fun postGroupChat(@Path("gid") groupId: String, @Body message: Map<String, String>): Flowable<HabitResponse<PostChatMessageResult>>
|
||||
|
|
@ -240,17 +240,17 @@ interface ApiService {
|
|||
fun deleteInboxMessage(@Path("messageId") messageId: String): Flowable<HabitResponse<Void>>
|
||||
|
||||
@GET("groups/{gid}/members")
|
||||
fun getGroupMembers(
|
||||
suspend fun getGroupMembers(
|
||||
@Path("gid") groupId: String,
|
||||
@Query("includeAllPublicFields") includeAllPublicFields: Boolean?
|
||||
): Flowable<HabitResponse<List<Member>>>
|
||||
): HabitResponse<List<Member>>
|
||||
|
||||
@GET("groups/{gid}/members")
|
||||
fun getGroupMembers(
|
||||
suspend fun getGroupMembers(
|
||||
@Path("gid") groupId: String,
|
||||
@Query("includeAllPublicFields") includeAllPublicFields: Boolean?,
|
||||
@Query("lastId") lastId: String
|
||||
): Flowable<HabitResponse<List<Member>>>
|
||||
): HabitResponse<List<Member>>
|
||||
|
||||
// Like returns the full chat list
|
||||
@POST("groups/{gid}/chat/{mid}/like")
|
||||
|
|
@ -300,7 +300,7 @@ interface ApiService {
|
|||
fun validateSubscription(@Body request: PurchaseValidationRequest): Flowable<HabitResponse<Void>>
|
||||
|
||||
@GET("/iap/android/subscribe/cancel")
|
||||
fun cancelSubscription(): Flowable<HabitResponse<Void>>
|
||||
suspend fun cancelSubscription(): HabitResponse<Void>
|
||||
|
||||
@POST("/iap/android/norenew-subscribe")
|
||||
fun validateNoRenewSubscription(@Body request: PurchaseValidationRequest): Flowable<HabitResponse<Void>>
|
||||
|
|
@ -310,16 +310,16 @@ interface ApiService {
|
|||
|
||||
// Members URL
|
||||
@GET("members/{mid}")
|
||||
fun getMember(@Path("mid") memberId: String): Flowable<HabitResponse<Member>>
|
||||
suspend fun getMember(@Path("mid") memberId: String): HabitResponse<Member>
|
||||
|
||||
@GET("members/username/{username}")
|
||||
fun getMemberWithUsername(@Path("username") username: String): Flowable<HabitResponse<Member>>
|
||||
suspend fun getMemberWithUsername(@Path("username") username: String): HabitResponse<Member>
|
||||
|
||||
@GET("members/{mid}/achievements")
|
||||
fun getMemberAchievements(@Path("mid") memberId: String, @Query("lang") language: String?): Flowable<HabitResponse<List<Achievement>>>
|
||||
|
||||
@POST("members/send-private-message")
|
||||
fun postPrivateMessage(@Body messageDetails: Map<String, String>): Flowable<HabitResponse<PostChatMessageResult>>
|
||||
suspend fun postPrivateMessage(@Body messageDetails: Map<String, String>): HabitResponse<PostChatMessageResult>
|
||||
|
||||
@GET("members/find/{username}")
|
||||
fun findUsernames(
|
||||
|
|
@ -440,7 +440,7 @@ interface ApiService {
|
|||
fun blockMember(@Path("userID") userID: String): Flowable<HabitResponse<List<String>>>
|
||||
|
||||
@POST("user/reroll")
|
||||
fun reroll(): Flowable<HabitResponse<User>>
|
||||
suspend fun reroll(): HabitResponse<User>
|
||||
|
||||
// Team Plans
|
||||
|
||||
|
|
@ -448,5 +448,5 @@ interface ApiService {
|
|||
fun getTeamPlans(): Flowable<HabitResponse<List<TeamPlan>>>
|
||||
|
||||
@GET("tasks/group/{groupID}")
|
||||
fun getTeamPlanTasks(@Path("groupID") groupId: String): Flowable<HabitResponse<TaskList>>
|
||||
suspend fun getTeamPlanTasks(@Path("groupID") groupId: String): HabitResponse<TaskList>
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,12 +27,12 @@ import com.habitrpg.android.habitica.models.user.Items
|
|||
import com.habitrpg.android.habitica.models.user.Stats
|
||||
import com.habitrpg.android.habitica.models.user.User
|
||||
import com.habitrpg.common.habitica.api.HostConfig
|
||||
import com.habitrpg.common.habitica.models.HabitResponse
|
||||
import com.habitrpg.common.habitica.models.PurchaseValidationRequest
|
||||
import com.habitrpg.common.habitica.models.PurchaseValidationResult
|
||||
import com.habitrpg.common.habitica.models.auth.UserAuthResponse
|
||||
import com.habitrpg.shared.habitica.models.responses.ErrorResponse
|
||||
import com.habitrpg.shared.habitica.models.responses.FeedResponse
|
||||
import com.habitrpg.common.habitica.models.HabitResponse
|
||||
import com.habitrpg.shared.habitica.models.responses.Status
|
||||
import com.habitrpg.shared.habitica.models.responses.TaskDirectionData
|
||||
import com.habitrpg.shared.habitica.models.responses.VerifyUsernameResponse
|
||||
|
|
@ -44,23 +44,19 @@ interface ApiClient {
|
|||
|
||||
val hostConfig: HostConfig
|
||||
|
||||
val status: Flowable<Status>
|
||||
|
||||
val content: Flowable<ContentResult>
|
||||
suspend fun getStatus(): Status?
|
||||
|
||||
/* user API */
|
||||
|
||||
val user: Flowable<User>
|
||||
|
||||
val tasks: Flowable<TaskList>
|
||||
suspend fun getTasks(): TaskList?
|
||||
|
||||
/* challenges api */
|
||||
|
||||
fun getUserChallenges(page: Int, memberOnly: Boolean): Flowable<List<Challenge>>
|
||||
|
||||
val worldState: Flowable<WorldState>
|
||||
suspend fun getWorldState(): WorldState?
|
||||
fun setLanguageCode(languageCode: String)
|
||||
fun getContent(language: String): Flowable<ContentResult>
|
||||
suspend fun getContent(language: String? = null): ContentResult?
|
||||
|
||||
fun updateUser(updateDictionary: Map<String, Any>): Flowable<User>
|
||||
|
||||
|
|
@ -83,7 +79,7 @@ interface ApiClient {
|
|||
fun purchaseSpecialSpell(key: String): Flowable<Void>
|
||||
fun validateSubscription(request: PurchaseValidationRequest): Flowable<Any>
|
||||
fun validateNoRenewSubscription(request: PurchaseValidationRequest): Flowable<Any>
|
||||
fun cancelSubscription(): Flowable<Void>
|
||||
suspend fun cancelSubscription(): Void?
|
||||
|
||||
fun sellItem(itemType: String, itemKey: String): Flowable<User>
|
||||
|
||||
|
|
@ -127,19 +123,16 @@ interface ApiClient {
|
|||
|
||||
fun loginApple(authToken: String): Flowable<UserAuthResponse>
|
||||
|
||||
fun sleep(): Flowable<Boolean>
|
||||
|
||||
fun revive(): Flowable<User>
|
||||
suspend fun sleep(): Boolean?
|
||||
suspend fun revive(): User?
|
||||
|
||||
fun useSkill(skillName: String, targetType: String, targetId: String): Flowable<SkillResponse>
|
||||
|
||||
fun useSkill(skillName: String, targetType: String): Flowable<SkillResponse>
|
||||
|
||||
fun changeClass(): Flowable<User>
|
||||
suspend fun changeClass(className: String?): User?
|
||||
|
||||
fun changeClass(className: String): Flowable<User>
|
||||
|
||||
fun disableClasses(): Flowable<User>
|
||||
suspend fun disableClasses(): User?
|
||||
|
||||
fun markPrivateMessagesRead(): Flowable<Void>
|
||||
|
||||
|
|
@ -147,26 +140,26 @@ interface ApiClient {
|
|||
|
||||
fun listGroups(type: String): Flowable<List<Group>>
|
||||
|
||||
fun getGroup(groupId: String): Flowable<Group>
|
||||
suspend fun getGroup(groupId: String): Group?
|
||||
|
||||
fun createGroup(group: Group): Flowable<Group>
|
||||
fun updateGroup(id: String, item: Group): Flowable<Group>
|
||||
fun removeMemberFromGroup(groupID: String, userID: String): Flowable<Void>
|
||||
suspend fun createGroup(group: Group): Group?
|
||||
suspend fun updateGroup(id: String, item: Group): Group?
|
||||
suspend fun removeMemberFromGroup(groupID: String, userID: String): Void?
|
||||
|
||||
fun listGroupChat(groupId: String): Flowable<List<ChatMessage>>
|
||||
suspend fun listGroupChat(groupId: String): List<ChatMessage>?
|
||||
|
||||
fun joinGroup(groupId: String): Flowable<Group>
|
||||
suspend fun joinGroup(groupId: String): Group?
|
||||
|
||||
fun leaveGroup(groupId: String, keepChallenges: String): Flowable<Void>
|
||||
suspend fun leaveGroup(groupId: String, keepChallenges: String): Void?
|
||||
|
||||
fun postGroupChat(groupId: String, message: Map<String, String>): Flowable<PostChatMessageResult>
|
||||
|
||||
fun deleteMessage(groupId: String, messageId: String): Flowable<Void>
|
||||
fun deleteInboxMessage(id: String): Flowable<Void>
|
||||
|
||||
fun getGroupMembers(groupId: String, includeAllPublicFields: Boolean?): Flowable<List<Member>>
|
||||
suspend fun getGroupMembers(groupId: String, includeAllPublicFields: Boolean?): List<Member>?
|
||||
|
||||
fun getGroupMembers(groupId: String, includeAllPublicFields: Boolean?, lastId: String): Flowable<List<Member>>
|
||||
suspend fun getGroupMembers(groupId: String, includeAllPublicFields: Boolean?, lastId: String): List<Member>?
|
||||
|
||||
// Like returns the full chat list
|
||||
fun likeMessage(groupId: String, mid: String): Flowable<ChatMessage>
|
||||
|
|
@ -199,12 +192,12 @@ interface ApiClient {
|
|||
fun changeCustomDayStart(updateObject: Map<String, Any>): Flowable<User>
|
||||
|
||||
// Members URL
|
||||
fun getMember(memberId: String): Flowable<Member>
|
||||
fun getMemberWithUsername(username: String): Flowable<Member>
|
||||
suspend fun getMember(memberId: String): Member?
|
||||
suspend fun getMemberWithUsername(username: String): Member?
|
||||
|
||||
fun getMemberAchievements(memberId: String): Flowable<List<Achievement>>
|
||||
|
||||
fun postPrivateMessage(messageDetails: Map<String, String>): Flowable<PostChatMessageResult>
|
||||
suspend fun postPrivateMessage(messageDetails: Map<String, String>): PostChatMessageResult?
|
||||
|
||||
fun retrieveShopIventory(identifier: String): Flowable<Shop>
|
||||
|
||||
|
|
@ -243,8 +236,8 @@ interface ApiClient {
|
|||
|
||||
fun hasAuthenticationKeys(): Boolean
|
||||
|
||||
fun retrieveUser(withTasks: Boolean): Flowable<User>
|
||||
fun retrieveInboxMessages(uuid: String, page: Int): Flowable<List<ChatMessage>>
|
||||
suspend fun retrieveUser(withTasks: Boolean = false): User?
|
||||
suspend fun retrieveInboxMessages(uuid: String, page: Int): List<ChatMessage>?
|
||||
fun retrieveInboxConversations(): Flowable<List<InboxConversation>>
|
||||
|
||||
fun <T : Any> configureApiCallObserver(): FlowableTransformer<HabitResponse<T>, T>
|
||||
|
|
@ -253,7 +246,7 @@ interface ApiClient {
|
|||
|
||||
fun runCron(): Flowable<Void>
|
||||
|
||||
fun reroll(): Flowable<User>
|
||||
suspend fun reroll(): User?
|
||||
|
||||
fun resetAccount(): Flowable<Void>
|
||||
fun deleteAccount(password: String): Flowable<Void>
|
||||
|
|
@ -282,5 +275,5 @@ interface ApiClient {
|
|||
fun unlinkAllTasks(challengeID: String?, keepOption: String): Flowable<Void>
|
||||
fun blockMember(userID: String): Flowable<List<String>>
|
||||
fun getTeamPlans(): Flowable<List<TeamPlan>>
|
||||
fun getTeamPlanTasks(teamID: String): Flowable<TaskList>
|
||||
suspend fun getTeamPlanTasks(teamID: String): TaskList?
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@ import com.habitrpg.android.habitica.models.ContentResult
|
|||
import com.habitrpg.android.habitica.models.WorldState
|
||||
import io.reactivex.rxjava3.core.Flowable
|
||||
|
||||
interface ContentRepository : BaseRepository {
|
||||
fun retrieveContent(forced: Boolean = false): Flowable<ContentResult>
|
||||
interface ContentRepository: BaseRepository {
|
||||
suspend fun retrieveContent(forced: Boolean = false): ContentResult?
|
||||
|
||||
fun retrieveWorldState(): Flowable<WorldState>
|
||||
suspend fun retrieveWorldState(): WorldState?
|
||||
fun getWorldState(): Flowable<WorldState>
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ interface InventoryRepository : BaseRepository {
|
|||
fun getPets(): Flow<List<Pet>>
|
||||
|
||||
fun getOwnedPets(): Flow<List<OwnedPet>>
|
||||
fun getQuestContent(key: String): Flowable<QuestContent>
|
||||
fun getQuestContent(key: String): Flow<QuestContent?>
|
||||
fun getQuestContent(keys: List<String>): Flow<List<QuestContent>>
|
||||
|
||||
fun getEquipment(searchedKeys: List<String>): Flowable<out List<Equipment>>
|
||||
|
|
@ -86,7 +86,7 @@ interface InventoryRepository : BaseRepository {
|
|||
fun purchaseItem(purchaseType: String, key: String, purchaseQuantity: Int): Flowable<Void>
|
||||
|
||||
fun togglePinnedItem(item: ShopItem): Flowable<List<ShopItem>>
|
||||
fun getItemsFlowable(itemClass: Class<out Item>, keys: Array<String>): Flow<List<Item>>
|
||||
fun getItems(itemClass: Class<out Item>, keys: Array<String>): Flow<List<Item>>
|
||||
fun getItemsFlowable(itemClass: Class<out Item>): Flowable<out List<Item>>
|
||||
fun getItems(itemClass: Class<out Item>): Flow<List<Item>>
|
||||
fun getLatestMysteryItem(): Flowable<Equipment>
|
||||
|
|
|
|||
|
|
@ -11,14 +11,14 @@ import com.habitrpg.android.habitica.models.social.GroupMembership
|
|||
import com.habitrpg.android.habitica.models.social.InboxConversation
|
||||
import com.habitrpg.android.habitica.models.user.User
|
||||
import io.reactivex.rxjava3.core.Flowable
|
||||
import io.reactivex.rxjava3.core.Single
|
||||
import io.realm.RealmResults
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
interface SocialRepository : BaseRepository {
|
||||
fun getPublicGuilds(): Flowable<out List<Group>>
|
||||
|
||||
fun getUserGroups(type: String?): Flowable<out List<Group>>
|
||||
fun retrieveGroupChat(groupId: String): Single<List<ChatMessage>>
|
||||
fun getUserGroups(type: String?): Flow<List<Group>>
|
||||
suspend fun retrieveGroupChat(groupId: String): List<ChatMessage>?
|
||||
fun getGroupChat(groupId: String): Flowable<out List<ChatMessage>>
|
||||
|
||||
fun markMessagesSeen(seenGroupId: String)
|
||||
|
|
@ -40,52 +40,51 @@ interface SocialRepository : BaseRepository {
|
|||
|
||||
fun postGroupChat(groupId: String, message: String): Flowable<PostChatMessageResult>
|
||||
|
||||
fun retrieveGroup(id: String): Flowable<Group>
|
||||
suspend fun retrieveGroup(id: String): Group?
|
||||
fun getGroup(id: String?): Flow<Group?>
|
||||
fun getGroupFlowable(id: String?): Flowable<Group>
|
||||
|
||||
fun leaveGroup(id: String?, keepChallenges: Boolean): Flowable<Group>
|
||||
suspend fun leaveGroup(id: String?, keepChallenges: Boolean): Group?
|
||||
|
||||
fun joinGroup(id: String?): Flowable<Group>
|
||||
suspend fun joinGroup(id: String?): Group?
|
||||
|
||||
fun createGroup(
|
||||
suspend fun createGroup(
|
||||
name: String?,
|
||||
description: String?,
|
||||
leader: String?,
|
||||
type: String?,
|
||||
privacy: String?,
|
||||
leaderCreateChallenge: Boolean?
|
||||
): Flowable<Group>
|
||||
): Group?
|
||||
|
||||
fun updateGroup(
|
||||
suspend fun updateGroup(
|
||||
group: Group?,
|
||||
name: String?,
|
||||
description: String?,
|
||||
leader: String?,
|
||||
leaderCreateChallenge: Boolean?
|
||||
): Flowable<Group>
|
||||
): Group?
|
||||
|
||||
fun retrieveGroups(type: String): Flowable<List<Group>>
|
||||
fun getGroups(type: String): Flowable<out List<Group>>
|
||||
|
||||
fun getInboxMessages(replyToUserID: String?): Flowable<out List<ChatMessage>>
|
||||
fun retrieveInboxMessages(uuid: String, page: Int): Flowable<List<ChatMessage>>
|
||||
fun getInboxMessages(replyToUserID: String?): Flow<RealmResults<ChatMessage>>
|
||||
suspend fun retrieveInboxMessages(uuid: String, page: Int): List<ChatMessage>?
|
||||
fun retrieveInboxConversations(): Flowable<List<InboxConversation>>
|
||||
fun getInboxConversations(): Flowable<out List<InboxConversation>>
|
||||
fun postPrivateMessage(
|
||||
fun getInboxConversations(): Flow<RealmResults<InboxConversation>>
|
||||
suspend fun postPrivateMessage(
|
||||
recipientId: String,
|
||||
messageObject: HashMap<String, String>
|
||||
): Flowable<List<ChatMessage>>
|
||||
): List<ChatMessage>?
|
||||
|
||||
fun postPrivateMessage(recipientId: String, message: String): Flowable<List<ChatMessage>>
|
||||
suspend fun postPrivateMessage(recipientId: String, message: String): List<ChatMessage>?
|
||||
|
||||
fun getGroupMembers(id: String): Flow<List<Member>>
|
||||
fun retrieveGroupMembers(id: String, includeAllPublicFields: Boolean): Flowable<List<Member>>
|
||||
suspend fun getGroupMembers(id: String): Flow<List<Member>>
|
||||
suspend fun retrieveGroupMembers(id: String, includeAllPublicFields: Boolean): List<Member>?
|
||||
|
||||
fun inviteToGroup(id: String, inviteData: Map<String, Any>): Flowable<List<Void>>
|
||||
|
||||
fun getMember(userId: String?): Flowable<Member>
|
||||
fun getMemberWithUsername(username: String?): Flowable<Member>
|
||||
suspend fun retrieveMember(userId: String?): Member?
|
||||
suspend fun retrieveMemberWithUsername(username: String?): Member?
|
||||
|
||||
fun findUsernames(
|
||||
username: String,
|
||||
|
|
@ -97,8 +96,8 @@ interface SocialRepository : BaseRepository {
|
|||
|
||||
fun markSomePrivateMessagesAsRead(user: User?, messages: List<ChatMessage>)
|
||||
|
||||
fun transferGroupOwnership(groupID: String, userID: String): Flowable<Group>
|
||||
fun removeMemberFromGroup(groupID: String, userID: String): Flowable<List<Member>>
|
||||
suspend fun transferGroupOwnership(groupID: String, userID: String): Group?
|
||||
suspend fun removeMemberFromGroup(groupID: String, userID: String): List<Member>?
|
||||
|
||||
fun acceptQuest(user: User?, partyId: String = "party"): Flowable<Void>
|
||||
fun rejectQuest(user: User?, partyId: String = "party"): Flowable<Void>
|
||||
|
|
@ -117,7 +116,7 @@ interface SocialRepository : BaseRepository {
|
|||
|
||||
fun transferGems(giftedID: String, amount: Int): Flowable<Void>
|
||||
|
||||
fun getGroupMembership(id: String): Flowable<GroupMembership>
|
||||
fun getGroupMembership(id: String): Flow<GroupMembership?>
|
||||
fun getGroupMemberships(): Flowable<out List<GroupMembership>>
|
||||
fun blockMember(userID: String): Flowable<List<String>>
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ interface TaskRepository : BaseRepository {
|
|||
fun getTasksFlowable(taskType: TaskType, userID: String? = null, includedGroupIDs: Array<String>): Flowable<out List<Task>>
|
||||
fun saveTasks(userId: String, order: TasksOrder, tasks: TaskList)
|
||||
|
||||
fun retrieveTasks(userId: String, tasksOrder: TasksOrder): Flowable<TaskList>
|
||||
suspend fun retrieveTasks(userId: String, tasksOrder: TasksOrder): TaskList?
|
||||
fun retrieveTasks(userId: String, tasksOrder: TasksOrder, dueDate: Date): Flowable<TaskList>
|
||||
|
||||
fun taskChecked(
|
||||
|
|
|
|||
|
|
@ -26,18 +26,13 @@ interface UserRepository : BaseRepository {
|
|||
fun updateUser(updateData: Map<String, Any>): Flowable<User>
|
||||
fun updateUser(key: String, value: Any): Flowable<User>
|
||||
|
||||
fun retrieveUser(withTasks: Boolean): Flowable<User>
|
||||
fun retrieveUser(
|
||||
withTasks: Boolean = false,
|
||||
forced: Boolean = false,
|
||||
overrideExisting: Boolean = false
|
||||
): Flowable<User>
|
||||
suspend fun retrieveUser(withTasks: Boolean = false, forced: Boolean = false, overrideExisting: Boolean = false): User?
|
||||
|
||||
fun revive(): Flowable<User>
|
||||
suspend fun revive(): User?
|
||||
|
||||
fun resetTutorial(): Maybe<User>
|
||||
|
||||
fun sleep(user: User): Flowable<User>
|
||||
suspend fun sleep(user: User): User?
|
||||
|
||||
fun getSkills(user: User): Flowable<out List<Skill>>
|
||||
|
||||
|
|
@ -46,17 +41,14 @@ interface UserRepository : BaseRepository {
|
|||
fun useSkill(key: String, target: String?, taskId: String): Flowable<SkillResponse>
|
||||
fun useSkill(key: String, target: String?): Flowable<SkillResponse>
|
||||
|
||||
fun changeClass(): Flowable<User>
|
||||
|
||||
fun disableClasses(): Flowable<User>
|
||||
|
||||
fun changeClass(selectedClass: String): Flowable<User>
|
||||
suspend fun disableClasses(): User?
|
||||
suspend fun changeClass(selectedClass: String? = null): User?
|
||||
|
||||
fun unlockPath(path: String, price: Int): Flowable<UnlockResponse>
|
||||
fun unlockPath(customization: Customization): Flowable<UnlockResponse>
|
||||
|
||||
fun runCron(tasks: MutableList<Task>)
|
||||
fun runCron()
|
||||
suspend fun runCron(tasks: MutableList<Task>)
|
||||
suspend fun runCron()
|
||||
|
||||
fun readNotification(id: String): Flowable<List<Any>>
|
||||
fun readNotifications(notificationIds: Map<String, List<String>>): Flowable<List<Any>>
|
||||
|
|
@ -66,7 +58,7 @@ interface UserRepository : BaseRepository {
|
|||
|
||||
fun updateLanguage(languageCode: String): Flowable<User>
|
||||
|
||||
fun resetAccount(): Flowable<User>
|
||||
suspend fun resetAccount(): User?
|
||||
fun deleteAccount(password: String): Flowable<Void>
|
||||
|
||||
fun sendPasswordResetEmail(email: String): Flowable<Void>
|
||||
|
|
@ -86,9 +78,9 @@ interface UserRepository : BaseRepository {
|
|||
|
||||
fun getUserQuestStatus(): Flowable<UserQuestStatus>
|
||||
|
||||
fun reroll(): Flowable<User>
|
||||
suspend fun reroll(): User?
|
||||
fun retrieveTeamPlans(): Flowable<List<TeamPlan>>
|
||||
fun getTeamPlans(): Flow<List<TeamPlan>>
|
||||
fun retrieveTeamPlan(teamID: String): Flowable<Group>
|
||||
suspend fun retrieveTeamPlan(teamID: String): Group?
|
||||
fun getTeamPlan(teamID: String): Flowable<Group>
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ import com.habitrpg.android.habitica.R
|
|||
import com.habitrpg.android.habitica.api.ApiService
|
||||
import com.habitrpg.android.habitica.api.GSonFactoryCreator
|
||||
import com.habitrpg.android.habitica.data.ApiClient
|
||||
import com.habitrpg.android.habitica.extensions.filterMap
|
||||
import com.habitrpg.android.habitica.helpers.NotificationsManager
|
||||
import com.habitrpg.android.habitica.models.Achievement
|
||||
import com.habitrpg.android.habitica.models.ContentResult
|
||||
|
|
@ -40,6 +39,7 @@ import com.habitrpg.android.habitica.models.user.User
|
|||
import com.habitrpg.android.habitica.proxy.AnalyticsManager
|
||||
import com.habitrpg.common.habitica.api.HostConfig
|
||||
import com.habitrpg.common.habitica.api.Server
|
||||
import com.habitrpg.common.habitica.models.HabitResponse
|
||||
import com.habitrpg.common.habitica.models.PurchaseValidationRequest
|
||||
import com.habitrpg.common.habitica.models.PurchaseValidationResult
|
||||
import com.habitrpg.common.habitica.models.auth.UserAuth
|
||||
|
|
@ -48,7 +48,6 @@ import com.habitrpg.common.habitica.models.auth.UserAuthSocial
|
|||
import com.habitrpg.common.habitica.models.auth.UserAuthSocialTokens
|
||||
import com.habitrpg.shared.habitica.models.responses.ErrorResponse
|
||||
import com.habitrpg.shared.habitica.models.responses.FeedResponse
|
||||
import com.habitrpg.common.habitica.models.HabitResponse
|
||||
import com.habitrpg.shared.habitica.models.responses.Status
|
||||
import com.habitrpg.shared.habitica.models.responses.TaskDirectionData
|
||||
import com.habitrpg.shared.habitica.models.responses.VerifyUsernameResponse
|
||||
|
|
@ -90,19 +89,31 @@ class ApiClientImpl(
|
|||
|
||||
private val apiCallTransformer = FlowableTransformer<HabitResponse<Any>, Any> { observable ->
|
||||
observable
|
||||
.filterMap { habitResponse ->
|
||||
habitResponse.notifications?.let {
|
||||
notificationsManager.setNotifications(it)
|
||||
}
|
||||
if (hadError) {
|
||||
hideConnectionProblemDialog()
|
||||
}
|
||||
habitResponse.data
|
||||
.filter { it.data != null }
|
||||
.map { habitResponse ->
|
||||
processResponse(habitResponse)
|
||||
}
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.doOnError(this)
|
||||
}
|
||||
|
||||
private fun <T> processResponse(habitResponse: HabitResponse<T>): T? {
|
||||
habitResponse.notifications?.let {
|
||||
notificationsManager.setNotifications(it)
|
||||
}
|
||||
return habitResponse.data
|
||||
}
|
||||
|
||||
suspend fun <T> handleSuspendCall(apiCall: suspend () -> HabitResponse<T>): T? {
|
||||
try {
|
||||
return processResponse(apiCall())
|
||||
} catch (throwable: Throwable) {
|
||||
accept(throwable)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
private var languageCode: String? = null
|
||||
private var lastAPICallURL: String? = null
|
||||
private var hadError = false
|
||||
|
|
@ -268,25 +279,15 @@ class ApiClientImpl(
|
|||
}
|
||||
}
|
||||
|
||||
override fun retrieveUser(withTasks: Boolean): Flowable<User> {
|
||||
|
||||
var userObservable = this.user
|
||||
|
||||
if (withTasks) {
|
||||
val tasksObservable = this.tasks
|
||||
|
||||
userObservable = Flowable.zip(
|
||||
userObservable, tasksObservable
|
||||
) { habitRPGUser, tasks ->
|
||||
habitRPGUser.tasks = tasks
|
||||
habitRPGUser
|
||||
}
|
||||
}
|
||||
return userObservable
|
||||
override suspend fun retrieveUser(withTasks: Boolean): User? {
|
||||
val user = handleSuspendCall { apiService.getUser() }
|
||||
val tasks = getTasks()
|
||||
user?.tasks = tasks
|
||||
return user
|
||||
}
|
||||
|
||||
override fun retrieveInboxMessages(uuid: String, page: Int): Flowable<List<ChatMessage>> {
|
||||
return apiService.getInboxMessages(uuid, page).compose(configureApiCallObserver())
|
||||
override suspend fun retrieveInboxMessages(uuid: String, page: Int): List<ChatMessage>? {
|
||||
return handleSuspendCall { apiService.getInboxMessages(uuid, page) }
|
||||
}
|
||||
|
||||
override fun retrieveInboxConversations(): Flowable<List<InboxConversation>> {
|
||||
|
|
@ -345,16 +346,12 @@ class ApiClientImpl(
|
|||
this.languageCode = languageCode
|
||||
}
|
||||
|
||||
override val status: Flowable<Status>
|
||||
get() = apiService.status.compose(configureApiCallObserver())
|
||||
override suspend fun getStatus(): Status? = handleSuspendCall { apiService.getStatus() }
|
||||
|
||||
override fun getContent(language: String): Flowable<ContentResult> {
|
||||
return apiService.getContent(language).compose(configureApiCallObserver())
|
||||
override suspend fun getContent(language: String?): ContentResult? {
|
||||
return handleSuspendCall { apiService.getContent(language) }
|
||||
}
|
||||
|
||||
override val user: Flowable<User>
|
||||
get() = apiService.user.compose(configureApiCallObserver())
|
||||
|
||||
override fun updateUser(updateDictionary: Map<String, Any>): Flowable<User> {
|
||||
return apiService.updateUser(updateDictionary).compose(configureApiCallObserver())
|
||||
}
|
||||
|
|
@ -399,8 +396,8 @@ class ApiClientImpl(
|
|||
return apiService.validateNoRenewSubscription(request).compose(configureApiCallObserver())
|
||||
}
|
||||
|
||||
override fun cancelSubscription(): Flowable<Void> {
|
||||
return apiService.cancelSubscription().compose(configureApiCallObserver())
|
||||
override suspend fun cancelSubscription(): Void? {
|
||||
return processResponse(apiService.cancelSubscription())
|
||||
}
|
||||
|
||||
override fun purchaseHourglassItem(type: String, itemKey: String): Flowable<Void> {
|
||||
|
|
@ -436,8 +433,7 @@ class ApiClientImpl(
|
|||
return apiService.hatchPet(eggKey, hatchingPotionKey).compose(configureApiCallObserver())
|
||||
}
|
||||
|
||||
override val tasks: Flowable<TaskList>
|
||||
get() = apiService.tasks.compose(configureApiCallObserver())
|
||||
override suspend fun getTasks(): TaskList? = handleSuspendCall { apiService.getTasks() }
|
||||
|
||||
override fun getTasks(type: String): Flowable<TaskList> {
|
||||
return apiService.getTasks(type).compose(configureApiCallObserver())
|
||||
|
|
@ -499,13 +495,9 @@ class ApiClientImpl(
|
|||
return apiService.deleteTag(id).compose(configureApiCallObserver())
|
||||
}
|
||||
|
||||
override fun sleep(): Flowable<Boolean> {
|
||||
return apiService.sleep().compose(configureApiCallObserver())
|
||||
}
|
||||
override suspend fun sleep(): Boolean? = handleSuspendCall { apiService.sleep() }
|
||||
|
||||
override fun revive(): Flowable<User> {
|
||||
return apiService.revive().compose(configureApiCallObserver())
|
||||
}
|
||||
override suspend fun revive(): User? = handleSuspendCall { apiService.revive() }
|
||||
|
||||
override fun useSkill(skillName: String, targetType: String, targetId: String): Flowable<SkillResponse> {
|
||||
return apiService.useSkill(skillName, targetType, targetId).compose(configureApiCallObserver())
|
||||
|
|
@ -515,17 +507,17 @@ class ApiClientImpl(
|
|||
return apiService.useSkill(skillName, targetType).compose(configureApiCallObserver())
|
||||
}
|
||||
|
||||
override fun changeClass(): Flowable<User> {
|
||||
return apiService.changeClass().compose(configureApiCallObserver())
|
||||
override suspend fun changeClass(className: String?): User? {
|
||||
return handleSuspendCall {
|
||||
if (className != null) {
|
||||
apiService.changeClass(className)
|
||||
} else {
|
||||
apiService.changeClass()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun changeClass(className: String): Flowable<User> {
|
||||
return apiService.changeClass(className).compose(configureApiCallObserver())
|
||||
}
|
||||
|
||||
override fun disableClasses(): Flowable<User> {
|
||||
return apiService.disableClasses().compose(configureApiCallObserver())
|
||||
}
|
||||
override suspend fun disableClasses(): User? = handleSuspendCall { apiService.disableClasses() }
|
||||
|
||||
override fun markPrivateMessagesRead(): Flowable<Void> {
|
||||
// This is necessary, because the API call returns weird data.
|
||||
|
|
@ -539,32 +531,32 @@ class ApiClientImpl(
|
|||
return apiService.listGroups(type).compose(configureApiCallObserver())
|
||||
}
|
||||
|
||||
override fun getGroup(groupId: String): Flowable<Group> {
|
||||
return apiService.getGroup(groupId).compose(configureApiCallObserver())
|
||||
override suspend fun getGroup(groupId: String): Group? {
|
||||
return processResponse(apiService.getGroup(groupId))
|
||||
}
|
||||
|
||||
override fun createGroup(group: Group): Flowable<Group> {
|
||||
return apiService.createGroup(group).compose(configureApiCallObserver())
|
||||
override suspend fun createGroup(group: Group): Group? {
|
||||
return processResponse(apiService.createGroup(group))
|
||||
}
|
||||
|
||||
override fun updateGroup(id: String, item: Group): Flowable<Group> {
|
||||
return apiService.updateGroup(id, item).compose(configureApiCallObserver())
|
||||
override suspend fun updateGroup(id: String, item: Group): Group? {
|
||||
return processResponse(apiService.updateGroup(id, item))
|
||||
}
|
||||
|
||||
override fun removeMemberFromGroup(groupID: String, userID: String): Flowable<Void> {
|
||||
return apiService.removeMemberFromGroup(groupID, userID).compose(configureApiCallObserver())
|
||||
override suspend fun removeMemberFromGroup(groupID: String, userID: String): Void? {
|
||||
return processResponse(apiService.removeMemberFromGroup(groupID, userID))
|
||||
}
|
||||
|
||||
override fun listGroupChat(groupId: String): Flowable<List<ChatMessage>> {
|
||||
return apiService.listGroupChat(groupId).compose(configureApiCallObserver())
|
||||
override suspend fun listGroupChat(groupId: String): List<ChatMessage>? {
|
||||
return processResponse(apiService.listGroupChat(groupId))
|
||||
}
|
||||
|
||||
override fun joinGroup(groupId: String): Flowable<Group> {
|
||||
return apiService.joinGroup(groupId).compose(configureApiCallObserver())
|
||||
override suspend fun joinGroup(groupId: String): Group? {
|
||||
return processResponse(apiService.joinGroup(groupId))
|
||||
}
|
||||
|
||||
override fun leaveGroup(groupId: String, keepChallenges: String): Flowable<Void> {
|
||||
return apiService.leaveGroup(groupId, keepChallenges).compose(configureApiCallObserver())
|
||||
override suspend fun leaveGroup(groupId: String, keepChallenges: String): Void? {
|
||||
return processResponse(apiService.leaveGroup(groupId, keepChallenges))
|
||||
}
|
||||
|
||||
override fun postGroupChat(groupId: String, message: Map<String, String>): Flowable<PostChatMessageResult> {
|
||||
|
|
@ -578,12 +570,12 @@ class ApiClientImpl(
|
|||
return apiService.deleteInboxMessage(id).compose(configureApiCallObserver())
|
||||
}
|
||||
|
||||
override fun getGroupMembers(groupId: String, includeAllPublicFields: Boolean?): Flowable<List<Member>> {
|
||||
return apiService.getGroupMembers(groupId, includeAllPublicFields).compose(configureApiCallObserver())
|
||||
override suspend fun getGroupMembers(groupId: String, includeAllPublicFields: Boolean?): List<Member>? {
|
||||
return processResponse(apiService.getGroupMembers(groupId, includeAllPublicFields))
|
||||
}
|
||||
|
||||
override fun getGroupMembers(groupId: String, includeAllPublicFields: Boolean?, lastId: String): Flowable<List<Member>> {
|
||||
return apiService.getGroupMembers(groupId, includeAllPublicFields, lastId).compose(configureApiCallObserver())
|
||||
override suspend fun getGroupMembers(groupId: String, includeAllPublicFields: Boolean?, lastId: String): List<Member>? {
|
||||
return processResponse(apiService.getGroupMembers(groupId, includeAllPublicFields, lastId))
|
||||
}
|
||||
|
||||
override fun likeMessage(groupId: String, mid: String): Flowable<ChatMessage> {
|
||||
|
|
@ -646,13 +638,8 @@ class ApiClientImpl(
|
|||
return apiService.changeCustomDayStart(updateObject).compose(configureApiCallObserver())
|
||||
}
|
||||
|
||||
override fun getMember(memberId: String): Flowable<Member> {
|
||||
return apiService.getMember(memberId).compose(configureApiCallObserver())
|
||||
}
|
||||
|
||||
override fun getMemberWithUsername(username: String): Flowable<Member> {
|
||||
return apiService.getMemberWithUsername(username).compose(configureApiCallObserver())
|
||||
}
|
||||
override suspend fun getMember(memberId: String) = processResponse(apiService.getMember(memberId))
|
||||
override suspend fun getMemberWithUsername(username: String) = processResponse(apiService.getMemberWithUsername(username))
|
||||
|
||||
override fun getMemberAchievements(memberId: String): Flowable<List<Achievement>> {
|
||||
return apiService.getMemberAchievements(memberId, languageCode).compose(configureApiCallObserver())
|
||||
|
|
@ -662,8 +649,8 @@ class ApiClientImpl(
|
|||
return apiService.findUsernames(username, context, id).compose(configureApiCallObserver())
|
||||
}
|
||||
|
||||
override fun postPrivateMessage(messageDetails: Map<String, String>): Flowable<PostChatMessageResult> {
|
||||
return apiService.postPrivateMessage(messageDetails).compose(configureApiCallObserver())
|
||||
override suspend fun postPrivateMessage(messageDetails: Map<String, String>): PostChatMessageResult? {
|
||||
return handleSuspendCall { apiService.postPrivateMessage(messageDetails) }
|
||||
}
|
||||
|
||||
override fun retrieveShopIventory(identifier: String): Flowable<Shop> {
|
||||
|
|
@ -738,9 +725,6 @@ class ApiClientImpl(
|
|||
return apiService.seeNotifications(notificationIds).compose(configureApiCallObserver())
|
||||
}
|
||||
|
||||
override val content: Flowable<ContentResult>
|
||||
get() = apiService.getContent(languageCode).compose(configureApiCallObserver())
|
||||
|
||||
override fun openMysteryItem(): Flowable<Equipment> {
|
||||
return apiService.openMysteryItem().compose(configureApiCallObserver())
|
||||
}
|
||||
|
|
@ -749,9 +733,7 @@ class ApiClientImpl(
|
|||
return apiService.runCron().compose(configureApiCallObserver())
|
||||
}
|
||||
|
||||
override fun reroll(): Flowable<User> {
|
||||
return apiService.reroll().compose(configureApiCallObserver())
|
||||
}
|
||||
override suspend fun reroll(): User? = handleSuspendCall { apiService.reroll() }
|
||||
|
||||
override fun resetAccount(): Flowable<Void> {
|
||||
return apiService.resetAccount().compose(configureApiCallObserver())
|
||||
|
|
@ -825,8 +807,8 @@ class ApiClientImpl(
|
|||
return apiService.getTeamPlans().compose(configureApiCallObserver())
|
||||
}
|
||||
|
||||
override fun getTeamPlanTasks(teamID: String): Flowable<TaskList> {
|
||||
return apiService.getTeamPlanTasks(teamID).compose(configureApiCallObserver())
|
||||
override suspend fun getTeamPlanTasks(teamID: String): TaskList? {
|
||||
return processResponse(apiService.getTeamPlanTasks(teamID))
|
||||
}
|
||||
|
||||
override fun bulkAllocatePoints(
|
||||
|
|
@ -849,8 +831,7 @@ class ApiClientImpl(
|
|||
return apiService.retrieveMarketGear(languageCode).compose(configureApiCallObserver())
|
||||
}
|
||||
|
||||
override val worldState: Flowable<WorldState>
|
||||
get() = apiService.worldState.compose(configureApiCallObserver())
|
||||
override suspend fun getWorldState(): WorldState? = handleSuspendCall { apiService.worldState() }
|
||||
|
||||
companion object {
|
||||
fun createGsonFactory(): GsonConverterFactory {
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import com.habitrpg.android.habitica.models.ContentResult
|
|||
import com.habitrpg.android.habitica.models.WorldState
|
||||
import com.habitrpg.android.habitica.models.inventory.SpecialItem
|
||||
import io.reactivex.rxjava3.core.Flowable
|
||||
import io.realm.RealmList
|
||||
import java.util.Date
|
||||
|
||||
class ContentRepositoryImpl<T : ContentLocalRepository>(
|
||||
|
|
@ -22,34 +23,33 @@ class ContentRepositoryImpl<T : ContentLocalRepository>(
|
|||
private var lastContentSync = 0L
|
||||
private var lastWorldStateSync = 0L
|
||||
|
||||
override fun retrieveContent(forced: Boolean): Flowable<ContentResult> {
|
||||
override suspend fun retrieveContent(forced: Boolean): ContentResult? {
|
||||
val now = Date().time
|
||||
return if (forced || now - this.lastContentSync > 300000) {
|
||||
if (forced || now - this.lastContentSync > 300000) {
|
||||
val content = apiClient.getContent() ?: return null
|
||||
lastContentSync = now
|
||||
apiClient.content.doOnNext {
|
||||
it.special.add(mysteryItem)
|
||||
localRepository.saveContent(it)
|
||||
}
|
||||
} else {
|
||||
Flowable.just(ContentResult())
|
||||
content.special = RealmList()
|
||||
content.special.add(mysteryItem)
|
||||
localRepository.saveContent(content)
|
||||
return content
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
override fun retrieveWorldState(): Flowable<WorldState> {
|
||||
override suspend fun retrieveWorldState(): WorldState? {
|
||||
val now = Date().time
|
||||
return if (now - this.lastWorldStateSync > 3600000) {
|
||||
if (now - this.lastWorldStateSync > 3600000) {
|
||||
val state = apiClient.getWorldState() ?: return null
|
||||
lastWorldStateSync = now
|
||||
apiClient.worldState.doOnNext {
|
||||
localRepository.saveWorldState(it)
|
||||
for (event in it.events) {
|
||||
if (event.aprilFools != null && event.isCurrentlyActive) {
|
||||
AprilFoolsHandler.handle(event.aprilFools, event.end)
|
||||
}
|
||||
localRepository.save(state)
|
||||
for (event in state.events) {
|
||||
if (event.aprilFools != null && event.isCurrentlyActive) {
|
||||
AprilFoolsHandler.handle(event.aprilFools, event.end)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Flowable.just(WorldState())
|
||||
return state
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
override fun getWorldState(): Flowable<WorldState> {
|
||||
|
|
|
|||
|
|
@ -31,13 +31,9 @@ class InventoryRepositoryImpl(
|
|||
userID: String,
|
||||
var appConfigManager: AppConfigManager
|
||||
) : BaseRepositoryImpl<InventoryLocalRepository>(localRepository, apiClient, userID), InventoryRepository {
|
||||
override fun getQuestContent(keys: List<String>): Flow<List<QuestContent>> {
|
||||
return localRepository.getQuestContent(keys)
|
||||
}
|
||||
override fun getQuestContent(keys: List<String>) = localRepository.getQuestContent(keys)
|
||||
|
||||
override fun getQuestContent(key: String): Flowable<QuestContent> {
|
||||
return localRepository.getQuestContent(key)
|
||||
}
|
||||
override fun getQuestContent(key: String) = localRepository.getQuestContent(key)
|
||||
|
||||
override fun getEquipment(searchedKeys: List<String>): Flowable<out List<Equipment>> {
|
||||
return localRepository.getEquipment(searchedKeys)
|
||||
|
|
@ -75,7 +71,7 @@ class InventoryRepositoryImpl(
|
|||
return localRepository.getOwnedItems(userID, includeZero)
|
||||
}
|
||||
|
||||
override fun getItemsFlowable(itemClass: Class<out Item>, keys: Array<String>): Flow<List<Item>> {
|
||||
override fun getItems(itemClass: Class<out Item>, keys: Array<String>): Flow<List<Item>> {
|
||||
return localRepository.getItemsFlowable(itemClass, keys)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import com.habitrpg.android.habitica.BuildConfig
|
|||
import com.habitrpg.android.habitica.data.ApiClient
|
||||
import com.habitrpg.android.habitica.data.SocialRepository
|
||||
import com.habitrpg.android.habitica.data.local.SocialLocalRepository
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.android.habitica.models.Achievement
|
||||
import com.habitrpg.android.habitica.models.inventory.Quest
|
||||
import com.habitrpg.android.habitica.models.members.Member
|
||||
|
|
@ -16,12 +16,10 @@ import com.habitrpg.android.habitica.models.social.GroupMembership
|
|||
import com.habitrpg.android.habitica.models.social.InboxConversation
|
||||
import com.habitrpg.android.habitica.models.user.User
|
||||
import io.reactivex.rxjava3.core.Flowable
|
||||
import io.reactivex.rxjava3.core.Single
|
||||
import kotlinx.coroutines.MainScope
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.emptyFlow
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.launch
|
||||
import retrofit2.HttpException
|
||||
import kotlinx.coroutines.flow.firstOrNull
|
||||
import java.util.UUID
|
||||
|
||||
class SocialRepositoryImpl(
|
||||
|
|
@ -29,45 +27,31 @@ class SocialRepositoryImpl(
|
|||
apiClient: ApiClient,
|
||||
userID: String
|
||||
) : BaseRepositoryImpl<SocialLocalRepository>(localRepository, apiClient, userID), SocialRepository {
|
||||
override fun transferGroupOwnership(groupID: String, userID: String): Flowable<Group> {
|
||||
return localRepository.getGroupFlowable(groupID)
|
||||
.map {
|
||||
val group = localRepository.getUnmanagedCopy(it)
|
||||
group.leaderID = userID
|
||||
group
|
||||
}
|
||||
.flatMap {
|
||||
apiClient.updateGroup(it.id, it)
|
||||
}
|
||||
override suspend fun transferGroupOwnership(groupID: String, userID: String): Group? {
|
||||
val group = localRepository.getGroup(groupID).first()?.let { localRepository.getUnmanagedCopy(it) }
|
||||
group?.leaderID = userID
|
||||
return group?.let { apiClient.updateGroup(groupID, it) }
|
||||
}
|
||||
|
||||
override fun removeMemberFromGroup(groupID: String, userID: String): Flowable<List<Member>> {
|
||||
return apiClient.removeMemberFromGroup(groupID, userID)
|
||||
.flatMap {
|
||||
retrieveGroupMembers(groupID, true)
|
||||
}
|
||||
override suspend fun removeMemberFromGroup(groupID: String, userID: String): List<Member>? {
|
||||
apiClient.removeMemberFromGroup(groupID, userID)
|
||||
return retrieveGroupMembers(groupID, true)
|
||||
}
|
||||
|
||||
override fun blockMember(userID: String): Flowable<List<String>> {
|
||||
return apiClient.blockMember(userID)
|
||||
}
|
||||
|
||||
override fun getGroupMembership(id: String): Flowable<GroupMembership> {
|
||||
return localRepository.getGroupMembership(userID, id)
|
||||
}
|
||||
override fun getGroupMembership(id: String) = localRepository.getGroupMembership(userID, id)
|
||||
|
||||
override fun getGroupMemberships(): Flowable<out List<GroupMembership>> {
|
||||
return localRepository.getGroupMemberships(userID)
|
||||
}
|
||||
|
||||
override fun retrieveGroupChat(groupId: String): Single<List<ChatMessage>> {
|
||||
return apiClient.listGroupChat(groupId)
|
||||
.flatMap { Flowable.fromIterable(it) }
|
||||
.map { chatMessage ->
|
||||
chatMessage.groupId = groupId
|
||||
chatMessage
|
||||
}
|
||||
.toList()
|
||||
override suspend fun retrieveGroupChat(groupId: String): List<ChatMessage>? {
|
||||
val messages = apiClient.listGroupChat(groupId)
|
||||
messages?.forEach { it.groupId = groupId }
|
||||
return messages
|
||||
}
|
||||
|
||||
override fun getGroupChat(groupId: String): Flowable<out List<ChatMessage>> {
|
||||
|
|
@ -75,7 +59,7 @@ class SocialRepositoryImpl(
|
|||
}
|
||||
|
||||
override fun markMessagesSeen(seenGroupId: String) {
|
||||
apiClient.seenMessages(seenGroupId).subscribe({ }, RxErrorHandler.handleEmptyError())
|
||||
apiClient.seenMessages(seenGroupId).subscribe({ }, ExceptionHandler.rx())
|
||||
}
|
||||
|
||||
override fun flagMessage(chatMessageID: String, additionalInfo: String, groupID: String?): Flowable<Void> {
|
||||
|
|
@ -131,76 +115,70 @@ class SocialRepositoryImpl(
|
|||
return postGroupChat(groupId, messageObject)
|
||||
}
|
||||
|
||||
override fun retrieveGroup(id: String): Flowable<Group> {
|
||||
return Flowable.zip(
|
||||
apiClient.getGroup(id).doOnNext { localRepository.saveGroup(it) },
|
||||
retrieveGroupChat(id)
|
||||
.toFlowable()
|
||||
) { group, _ ->
|
||||
group
|
||||
}.doOnError {
|
||||
if (it is HttpException && it.code() == 404) {
|
||||
MainScope().launch {
|
||||
val group = localRepository.getGroup(id).first()
|
||||
if (group != null) {
|
||||
localRepository.delete(group)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
override suspend fun retrieveGroup(id: String): Group? {
|
||||
val group = apiClient.getGroup(id)
|
||||
group?.let { localRepository.saveGroup(it) }
|
||||
retrieveGroupChat(id)
|
||||
return group
|
||||
}
|
||||
|
||||
override fun getGroup(id: String?) = id?.let { localRepository.getGroup(it) } ?: emptyFlow()
|
||||
override fun getGroupFlowable(id: String?): Flowable<Group> = id?.let { localRepository.getGroupFlowable(it) } ?: Flowable.empty()
|
||||
|
||||
override fun leaveGroup(id: String?, keepChallenges: Boolean): Flowable<Group> {
|
||||
override fun getGroup(id: String?): Flow<Group?> {
|
||||
if (id?.isNotBlank() != true) {
|
||||
return Flowable.empty()
|
||||
return emptyFlow()
|
||||
}
|
||||
return apiClient.leaveGroup(id, if (keepChallenges) "remain-in-challenges" else "leave-challenges")
|
||||
.doOnNext { localRepository.updateMembership(userID, id, false) }
|
||||
.flatMapMaybe { localRepository.getGroupFlowable(id).firstElement() }
|
||||
return localRepository.getGroup(id)
|
||||
}
|
||||
|
||||
override fun joinGroup(id: String?): Flowable<Group> {
|
||||
override suspend fun leaveGroup(id: String?, keepChallenges: Boolean): Group? {
|
||||
if (id?.isNotBlank() != true) {
|
||||
return Flowable.empty()
|
||||
return null
|
||||
}
|
||||
return apiClient.joinGroup(id)
|
||||
.doOnNext { group ->
|
||||
localRepository.updateMembership(userID, id, true)
|
||||
localRepository.save(group)
|
||||
}
|
||||
|
||||
apiClient.leaveGroup(id, if (keepChallenges) "remain-in-challenges" else "leave-challenges")
|
||||
localRepository.updateMembership(userID, id, false)
|
||||
return localRepository.getGroup(id).firstOrNull()
|
||||
}
|
||||
|
||||
override fun createGroup(
|
||||
override suspend fun joinGroup(id: String?): Group? {
|
||||
if (id?.isNotBlank() != true) {
|
||||
return null
|
||||
}
|
||||
val group = apiClient.joinGroup(id)
|
||||
group?.let {
|
||||
localRepository.updateMembership(userID, id, true)
|
||||
localRepository.save(group)
|
||||
}
|
||||
return group
|
||||
}
|
||||
|
||||
override suspend fun createGroup(
|
||||
name: String?,
|
||||
description: String?,
|
||||
leader: String?,
|
||||
type: String?,
|
||||
privacy: String?,
|
||||
leaderCreateChallenge: Boolean?
|
||||
): Flowable<Group> {
|
||||
): Group? {
|
||||
val group = Group()
|
||||
group.name = name
|
||||
group.description = description
|
||||
group.type = type
|
||||
group.leaderID = leader
|
||||
group.privacy = privacy
|
||||
return apiClient.createGroup(group).doOnNext {
|
||||
localRepository.save(it)
|
||||
}
|
||||
val savedGroup = apiClient.createGroup(group)
|
||||
savedGroup?.let { localRepository.save(it) }
|
||||
return savedGroup
|
||||
}
|
||||
|
||||
override fun updateGroup(
|
||||
override suspend fun updateGroup(
|
||||
group: Group?,
|
||||
name: String?,
|
||||
description: String?,
|
||||
leader: String?,
|
||||
leaderCreateChallenge: Boolean?
|
||||
): Flowable<Group> {
|
||||
): Group? {
|
||||
if (group == null) {
|
||||
return Flowable.empty()
|
||||
return null
|
||||
}
|
||||
val copiedGroup = localRepository.getUnmanagedCopy(group)
|
||||
copiedGroup.name = name
|
||||
|
|
@ -224,21 +202,21 @@ class SocialRepositoryImpl(
|
|||
}
|
||||
}
|
||||
|
||||
override fun getGroups(type: String): Flowable<out List<Group>> = localRepository.getGroups(type)
|
||||
override fun getGroups(type: String) = localRepository.getGroups(type)
|
||||
|
||||
override fun getPublicGuilds(): Flowable<out List<Group>> = localRepository.getPublicGuilds()
|
||||
override fun getPublicGuilds() = localRepository.getPublicGuilds()
|
||||
|
||||
override fun getInboxConversations(): Flowable<out List<InboxConversation>> = localRepository.getInboxConversation(userID)
|
||||
override fun getInboxConversations() = localRepository.getInboxConversation(userID)
|
||||
|
||||
override fun getInboxMessages(replyToUserID: String?): Flowable<out List<ChatMessage>> = localRepository.getInboxMessages(userID, replyToUserID)
|
||||
override fun getInboxMessages(replyToUserID: String?) = localRepository.getInboxMessages(userID, replyToUserID)
|
||||
|
||||
override fun retrieveInboxMessages(uuid: String, page: Int): Flowable<List<ChatMessage>> {
|
||||
return apiClient.retrieveInboxMessages(uuid, page).doOnNext { messages ->
|
||||
messages.forEach {
|
||||
it.isInboxMessage = true
|
||||
}
|
||||
localRepository.saveInboxMessages(userID, uuid, messages, page)
|
||||
override suspend fun retrieveInboxMessages(uuid: String, page: Int): List<ChatMessage>? {
|
||||
val messages = apiClient.retrieveInboxMessages(uuid, page) ?: return null
|
||||
messages.forEach {
|
||||
it.isInboxMessage = true
|
||||
}
|
||||
localRepository.saveInboxMessages(userID, uuid, messages, page)
|
||||
return messages
|
||||
}
|
||||
|
||||
override fun retrieveInboxConversations(): Flowable<List<InboxConversation>> {
|
||||
|
|
@ -247,29 +225,31 @@ class SocialRepositoryImpl(
|
|||
}
|
||||
}
|
||||
|
||||
override fun postPrivateMessage(recipientId: String, messageObject: HashMap<String, String>): Flowable<List<ChatMessage>> {
|
||||
return apiClient.postPrivateMessage(messageObject).flatMap { retrieveInboxMessages(recipientId, 0) }
|
||||
override suspend fun postPrivateMessage(recipientId: String, messageObject: HashMap<String, String>): List<ChatMessage>? {
|
||||
val message = apiClient.postPrivateMessage(messageObject)
|
||||
return retrieveInboxMessages(recipientId, 0)
|
||||
}
|
||||
|
||||
override fun postPrivateMessage(recipientId: String, message: String): Flowable<List<ChatMessage>> {
|
||||
override suspend fun postPrivateMessage(recipientId: String, message: String): List<ChatMessage>? {
|
||||
val messageObject = HashMap<String, String>()
|
||||
messageObject["message"] = message
|
||||
messageObject["toUserId"] = recipientId
|
||||
return postPrivateMessage(recipientId, messageObject)
|
||||
}
|
||||
|
||||
override fun getGroupMembers(id: String) = localRepository.getGroupMembers(id)
|
||||
override suspend fun getGroupMembers(id: String) = localRepository.getGroupMembers(id)
|
||||
|
||||
override fun retrieveGroupMembers(id: String, includeAllPublicFields: Boolean): Flowable<List<Member>> {
|
||||
return apiClient.getGroupMembers(id, includeAllPublicFields)
|
||||
.doOnNext { members -> localRepository.saveGroupMembers(id, members) }
|
||||
override suspend fun retrieveGroupMembers(id: String, includeAllPublicFields: Boolean): List<Member>? {
|
||||
val members = apiClient.getGroupMembers(id, includeAllPublicFields)
|
||||
members?.let { localRepository.saveGroupMembers(id, it) }
|
||||
return members
|
||||
}
|
||||
|
||||
override fun inviteToGroup(id: String, inviteData: Map<String, Any>): Flowable<List<Void>> = apiClient.inviteToGroup(id, inviteData)
|
||||
|
||||
override fun getMember(userId: String?): Flowable<Member> {
|
||||
override suspend fun retrieveMember(userId: String?): Member? {
|
||||
return if (userId == null) {
|
||||
Flowable.empty()
|
||||
null
|
||||
} else {
|
||||
try {
|
||||
apiClient.getMember(UUID.fromString(userId).toString())
|
||||
|
|
@ -279,8 +259,8 @@ class SocialRepositoryImpl(
|
|||
}
|
||||
}
|
||||
|
||||
override fun getMemberWithUsername(username: String?): Flowable<Member> {
|
||||
return getMember(username)
|
||||
override suspend fun retrieveMemberWithUsername(username: String?): Member? {
|
||||
return retrieveMember(username)
|
||||
}
|
||||
|
||||
override fun findUsernames(username: String, context: String?, id: String?): Flowable<List<FindUsernameResult>> {
|
||||
|
|
@ -315,7 +295,7 @@ class SocialRepositoryImpl(
|
|||
}
|
||||
}
|
||||
|
||||
override fun getUserGroups(type: String?): Flowable<out List<Group>> = localRepository.getUserGroups(userID, type)
|
||||
override fun getUserGroups(type: String?) = localRepository.getUserGroups(userID, type)
|
||||
|
||||
override fun acceptQuest(user: User?, partyId: String): Flowable<Void> {
|
||||
return apiClient.acceptQuest(partyId)
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import com.habitrpg.android.habitica.data.ApiClient
|
|||
import com.habitrpg.android.habitica.data.TaskRepository
|
||||
import com.habitrpg.android.habitica.data.local.TaskLocalRepository
|
||||
import com.habitrpg.android.habitica.helpers.AppConfigManager
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.android.habitica.interactors.ScoreTaskLocallyInteractor
|
||||
import com.habitrpg.android.habitica.models.BaseMainObject
|
||||
import com.habitrpg.android.habitica.models.responses.BulkTaskScoringData
|
||||
|
|
@ -49,9 +49,10 @@ class TaskRepositoryImpl(
|
|||
localRepository.saveTasks(userId, order, tasks)
|
||||
}
|
||||
|
||||
override fun retrieveTasks(userId: String, tasksOrder: TasksOrder): Flowable<TaskList> {
|
||||
return this.apiClient.tasks
|
||||
.doOnNext { res -> this.localRepository.saveTasks(userId, tasksOrder, res) }
|
||||
override suspend fun retrieveTasks(userId: String, tasksOrder: TasksOrder): TaskList? {
|
||||
val tasks = apiClient.getTasks() ?: return null
|
||||
this.localRepository.saveTasks(userId, tasksOrder, tasks)
|
||||
return tasks
|
||||
}
|
||||
|
||||
override fun retrieveCompletedTodos(userId: String?): Flowable<TaskList> {
|
||||
|
|
@ -309,11 +310,11 @@ class TaskRepositoryImpl(
|
|||
getTask(taskid).map { localRepository.getUnmanagedCopy(it) }
|
||||
|
||||
override fun updateTaskInBackground(task: Task) {
|
||||
updateTask(task).subscribe({ }, RxErrorHandler.handleEmptyError())
|
||||
updateTask(task).subscribe({ }, ExceptionHandler.rx())
|
||||
}
|
||||
|
||||
override fun createTaskInBackground(task: Task) {
|
||||
createTask(task).subscribe({ }, RxErrorHandler.handleEmptyError())
|
||||
createTask(task).subscribe({ }, ExceptionHandler.rx())
|
||||
}
|
||||
|
||||
override fun getTaskCopies(userId: String): Flow<List<Task>> =
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
package com.habitrpg.android.habitica.data.implementation
|
||||
|
||||
import androidx.core.os.bundleOf
|
||||
import com.habitrpg.android.habitica.data.ApiClient
|
||||
import com.habitrpg.android.habitica.data.TaskRepository
|
||||
import com.habitrpg.android.habitica.data.UserRepository
|
||||
|
|
@ -8,7 +7,7 @@ import com.habitrpg.android.habitica.data.local.UserLocalRepository
|
|||
import com.habitrpg.android.habitica.models.user.UserQuestStatus
|
||||
import com.habitrpg.android.habitica.extensions.filterMapEmpty
|
||||
import com.habitrpg.android.habitica.helpers.AppConfigManager
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.android.habitica.models.Achievement
|
||||
import com.habitrpg.android.habitica.models.QuestAchievement
|
||||
import com.habitrpg.android.habitica.models.Skill
|
||||
|
|
@ -28,7 +27,9 @@ import com.habitrpg.shared.habitica.models.tasks.Attribute
|
|||
import io.reactivex.rxjava3.core.Flowable
|
||||
import io.reactivex.rxjava3.core.Maybe
|
||||
import io.reactivex.rxjava3.functions.BiFunction
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.util.Date
|
||||
import java.util.GregorianCalendar
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
|
@ -70,45 +71,39 @@ class UserRepositoryImpl(
|
|||
return updateUser(userID, key, value)
|
||||
}
|
||||
|
||||
override fun retrieveUser(withTasks: Boolean): Flowable<User> =
|
||||
retrieveUser(withTasks, false)
|
||||
|
||||
@Suppress("ReturnCount")
|
||||
override fun retrieveUser(withTasks: Boolean, forced: Boolean, overrideExisting: Boolean): Flowable<User> {
|
||||
override suspend fun retrieveUser(withTasks: Boolean, forced: Boolean, overrideExisting: Boolean): User? {
|
||||
// Only retrieve again after 3 minutes or it's forced.
|
||||
if (forced || this.lastSync == null || Date().time - (this.lastSync?.time ?: 0) > 180000) {
|
||||
val user = apiClient.retrieveUser(withTasks) ?: return null
|
||||
lastSync = Date()
|
||||
return apiClient.retrieveUser(withTasks)
|
||||
.doOnNext { localRepository.saveUser(it, overrideExisting) }
|
||||
.doOnNext { user ->
|
||||
if (withTasks) {
|
||||
val id = user.id
|
||||
val tasksOrder = user.tasksOrder
|
||||
val tasks = user.tasks
|
||||
if (id != null && tasksOrder != null && tasks != null) {
|
||||
taskRepository.saveTasks(id, tasksOrder, tasks)
|
||||
}
|
||||
}
|
||||
}
|
||||
.flatMap { user ->
|
||||
val calendar = GregorianCalendar()
|
||||
val timeZone = calendar.timeZone
|
||||
val offset = -TimeUnit.MINUTES.convert(timeZone.getOffset(calendar.timeInMillis).toLong(), TimeUnit.MILLISECONDS)
|
||||
if (offset.toInt() != (user.preferences?.timezoneOffset ?: 0)) {
|
||||
return@flatMap updateUser(user.id ?: "", "preferences.timezoneOffset", offset.toString())
|
||||
} else {
|
||||
return@flatMap Flowable.just(user)
|
||||
}
|
||||
localRepository.saveUser(user)
|
||||
if (withTasks) {
|
||||
val id = user.id
|
||||
val tasksOrder = user.tasksOrder
|
||||
val tasks = user.tasks
|
||||
if (id != null && tasksOrder != null && tasks != null) {
|
||||
taskRepository.saveTasks(id, tasksOrder, tasks)
|
||||
}
|
||||
}
|
||||
val calendar = GregorianCalendar()
|
||||
val timeZone = calendar.timeZone
|
||||
val offset = -TimeUnit.MINUTES.convert(timeZone.getOffset(calendar.timeInMillis).toLong(), TimeUnit.MILLISECONDS)
|
||||
/*if (offset.toInt() != user.preferences?.timezoneOffset ?: 0) {
|
||||
return@flatMap updateUser(user.id ?: "", "preferences.timezoneOffset", offset.toString())
|
||||
} else {
|
||||
return@flatMap Flowable.just(user)
|
||||
}*/
|
||||
return user
|
||||
} else {
|
||||
return localRepository.getUserFlowable(userID).take(1)
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
override fun revive(): Flowable<User> = zipWithLiveUser(apiClient.revive()) { newUser, user ->
|
||||
mergeUser(user, newUser)
|
||||
override suspend fun revive(): User? {
|
||||
apiClient.revive()
|
||||
return retrieveUser(false, true)
|
||||
}
|
||||
.flatMap { retrieveUser(false, true) }
|
||||
|
||||
override fun resetTutorial(): Maybe<User> {
|
||||
return localRepository.getTutorialSteps()
|
||||
|
|
@ -123,9 +118,13 @@ class UserRepositoryImpl(
|
|||
.flatMap { updateData -> updateUser(updateData).firstElement() }
|
||||
}
|
||||
|
||||
override fun sleep(user: User): Flowable<User> {
|
||||
localRepository.modify(user) { it.preferences?.sleep = !(it.preferences?.sleep ?: false) }
|
||||
return apiClient.sleep().map { user }
|
||||
override suspend fun sleep(user: User): User {
|
||||
val newValue = !(user.preferences?.sleep ?: false)
|
||||
localRepository.modify(user) { it.preferences?.sleep = newValue }
|
||||
if (apiClient.sleep() != true) {
|
||||
localRepository.modify(user) { it.preferences?.sleep = !newValue }
|
||||
}
|
||||
return user
|
||||
}
|
||||
|
||||
override fun getSkills(user: User): Flowable<out List<Skill>> =
|
||||
|
|
@ -137,7 +136,7 @@ class UserRepositoryImpl(
|
|||
override fun useSkill(key: String, target: String?, taskId: String): Flowable<SkillResponse> {
|
||||
return zipWithLiveUser(apiClient.useSkill(key, target ?: "", taskId)) { response, user ->
|
||||
response.hpDiff = (response.user?.stats?.hp ?: 0.0) - (user.stats?.hp ?: 0.0)
|
||||
response.expDiff = (response.user?.stats?.exp ?: 0.0) - (user.stats?.exp ?: 0.0)
|
||||
response.expDiff =(response.user?.stats?.exp ?: 0.0) - (user.stats?.exp ?: 0.0)
|
||||
response.goldDiff = (response.user?.stats?.gp ?: 0.0) - (user.stats?.gp ?: 0.0)
|
||||
response.damage = (response.user?.party?.quest?.progress?.up ?: 0.0f) - (user.party?.quest?.progress?.up ?: 0.0f)
|
||||
response.user?.let { mergeUser(user, it) }
|
||||
|
|
@ -148,7 +147,7 @@ class UserRepositoryImpl(
|
|||
override fun useSkill(key: String, target: String?): Flowable<SkillResponse> {
|
||||
return zipWithLiveUser(apiClient.useSkill(key, target ?: "")) { response, user ->
|
||||
response.hpDiff = (response.user?.stats?.hp ?: 0.0) - (user.stats?.hp ?: 0.0)
|
||||
response.expDiff = (response.user?.stats?.exp ?: 0.0) - (user.stats?.exp ?: 0.0)
|
||||
response.expDiff =(response.user?.stats?.exp ?: 0.0) - (user.stats?.exp ?: 0.0)
|
||||
response.goldDiff = (response.user?.stats?.gp ?: 0.0) - (user.stats?.gp ?: 0.0)
|
||||
response.damage = (response.user?.party?.quest?.progress?.up ?: 0.0f) - (user.party?.quest?.progress?.up ?: 0.0f)
|
||||
response.user?.let { mergeUser(user, it) }
|
||||
|
|
@ -156,12 +155,15 @@ class UserRepositoryImpl(
|
|||
}
|
||||
}
|
||||
|
||||
override fun changeClass(): Flowable<User> = apiClient.changeClass().flatMap { retrieveUser(withTasks = false, forced = true) }
|
||||
override suspend fun disableClasses(): User? = apiClient.disableClasses()
|
||||
|
||||
override fun disableClasses(): Flowable<User> = apiClient.disableClasses().flatMap { retrieveUser(withTasks = false, forced = true) }
|
||||
override suspend fun changeClass(selectedClass: String?): User? {
|
||||
return apiClient.changeClass(selectedClass)
|
||||
}
|
||||
|
||||
override fun changeClass(selectedClass: String): Flowable<User> = apiClient.changeClass(selectedClass)
|
||||
.flatMap { retrieveUser(false) }
|
||||
override fun unlockPath(customization: Customization): Flowable<UnlockResponse> {
|
||||
return unlockPath(customization.path, customization.price ?: 0)
|
||||
}
|
||||
|
||||
override fun unlockPath(path: String, price: Int): Flowable<UnlockResponse> {
|
||||
return zipWithLiveUser(apiClient.unlockPath(path)) { unlockResponse, copiedUser ->
|
||||
|
|
@ -175,11 +177,7 @@ class UserRepositoryImpl(
|
|||
}
|
||||
}
|
||||
|
||||
override fun unlockPath(customization: Customization): Flowable<UnlockResponse> {
|
||||
return unlockPath(customization.unlockPath, customization.price ?: 0)
|
||||
}
|
||||
|
||||
override fun runCron() {
|
||||
override suspend fun runCron() {
|
||||
runCron(ArrayList())
|
||||
}
|
||||
|
||||
|
|
@ -188,9 +186,8 @@ class UserRepositoryImpl(
|
|||
return localRepository.getUserQuestStatus(userID)
|
||||
}
|
||||
|
||||
override fun reroll(): Flowable<User> {
|
||||
override suspend fun reroll(): User? {
|
||||
return apiClient.reroll()
|
||||
.flatMap { retrieveUser(true, true, true) }
|
||||
}
|
||||
|
||||
override fun readNotifications(notificationIds: Map<String, List<String>>): Flowable<List<Any>> =
|
||||
|
|
@ -210,8 +207,9 @@ class UserRepositoryImpl(
|
|||
.doOnNext { apiClient.setLanguageCode(languageCode) }
|
||||
}
|
||||
|
||||
override fun resetAccount(): Flowable<User> {
|
||||
return apiClient.resetAccount().flatMap { retrieveUser(withTasks = true, forced = true) }
|
||||
override suspend fun resetAccount(): User? {
|
||||
apiClient.resetAccount()
|
||||
return retrieveUser(withTasks = true, forced = true)
|
||||
}
|
||||
|
||||
override fun deleteAccount(password: String): Flowable<Void> =
|
||||
|
|
@ -262,7 +260,7 @@ class UserRepositoryImpl(
|
|||
liveUser.stats?.points = liveUser.stats?.points?.dec()
|
||||
}
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
ExceptionHandler.rx()
|
||||
)
|
||||
return zipWithLiveUser(apiClient.allocatePoint(stat.value)) { stats, user ->
|
||||
localRepository.modify(user) { liveUser ->
|
||||
|
|
@ -295,26 +293,33 @@ class UserRepositoryImpl(
|
|||
stats
|
||||
}
|
||||
|
||||
override fun runCron(tasks: MutableList<Task>) {
|
||||
var observable: Maybe<Any> = localRepository.getUserFlowable(userID).firstElement()
|
||||
.filter { it.needsCron }
|
||||
.map { user ->
|
||||
localRepository.modify(user) { liveUser ->
|
||||
liveUser.needsCron = false
|
||||
liveUser.lastCron = Date()
|
||||
override suspend fun runCron(tasks: MutableList<Task>) {
|
||||
withContext(Dispatchers.Main) {
|
||||
var observable: Maybe<Any> = localRepository.getUserFlowable(userID).firstElement()
|
||||
.filter { it.needsCron }
|
||||
.map { user ->
|
||||
localRepository.modify(user) { liveUser ->
|
||||
liveUser.needsCron = false
|
||||
liveUser.lastCron = Date()
|
||||
}
|
||||
user
|
||||
}
|
||||
user
|
||||
if (tasks.isNotEmpty()) {
|
||||
val scoringList = mutableListOf<Map<String, String>>()
|
||||
for (task in tasks) {
|
||||
val map = mutableMapOf<String, String>()
|
||||
map["id"] = task.id ?: ""
|
||||
map["direction"] = TaskDirection.UP.text
|
||||
scoringList.add(map)
|
||||
}
|
||||
observable = observable.flatMap { taskRepository.bulkScoreTasks(scoringList).firstElement() }
|
||||
}
|
||||
if (tasks.isNotEmpty()) {
|
||||
val scoringList = tasks.map { mapOf(Pair("id", it.id ?: ""), Pair("direction", TaskDirection.UP.text)) }
|
||||
observable = observable.flatMap { taskRepository.bulkScoreTasks(scoringList).firstElement() }
|
||||
observable.flatMap { apiClient.runCron().firstElement() }
|
||||
// .flatMap {
|
||||
// this.retrieveUser(withTasks = true, forced = true)
|
||||
// }
|
||||
.subscribe({ }, ExceptionHandler.rx())
|
||||
}
|
||||
observable.flatMap { apiClient.runCron().firstElement() }
|
||||
.flatMap { this.retrieveUser(withTasks = true, forced = true).firstElement() }
|
||||
.subscribe({ }, {
|
||||
analyticsManager.logEvent("cron failed", bundleOf(Pair("error", it.localizedMessage)))
|
||||
RxErrorHandler.reportError(it)
|
||||
})
|
||||
}
|
||||
|
||||
override fun useCustomization(type: String, category: String?, identifier: String): Flowable<User> {
|
||||
|
|
@ -340,7 +345,7 @@ class UserRepositoryImpl(
|
|||
}
|
||||
}
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
ExceptionHandler.rx()
|
||||
)
|
||||
}
|
||||
var updatePath = "preferences.$type"
|
||||
|
|
@ -375,22 +380,17 @@ class UserRepositoryImpl(
|
|||
return localRepository.getTeamPlans(userID)
|
||||
}
|
||||
|
||||
override fun retrieveTeamPlan(teamID: String): Flowable<Group> {
|
||||
return Flowable.zip(
|
||||
apiClient.getGroup(teamID), apiClient.getTeamPlanTasks(teamID)
|
||||
) { team, tasks ->
|
||||
team.tasks = tasks
|
||||
team
|
||||
override suspend fun retrieveTeamPlan(teamID: String): Group? {
|
||||
val team = apiClient.getGroup(teamID) ?: return null
|
||||
team.tasks = apiClient.getTeamPlanTasks(teamID)
|
||||
localRepository.save(team)
|
||||
val id = team.id
|
||||
val tasksOrder = team.tasksOrder
|
||||
val tasks = team.tasks
|
||||
if (id.isNotBlank() && tasksOrder != null && tasks != null) {
|
||||
taskRepository.saveTasks(id, tasksOrder, tasks)
|
||||
}
|
||||
.doOnNext { localRepository.save(it) }
|
||||
.doOnNext { team ->
|
||||
val id = team.id
|
||||
val tasksOrder = team.tasksOrder
|
||||
val tasks = team.tasks
|
||||
if (id.isNotBlank() && tasksOrder != null && tasks != null) {
|
||||
taskRepository.saveTasks(id, tasksOrder, tasks)
|
||||
}
|
||||
}
|
||||
return team
|
||||
}
|
||||
|
||||
override fun getTeamPlan(teamID: String): Flowable<Group> {
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ interface InventoryLocalRepository : ContentLocalRepository {
|
|||
fun getOwnedPets(userID: String): Flow<List<OwnedPet>>
|
||||
|
||||
fun getInAppRewards(): Flowable<out List<ShopItem>>
|
||||
fun getQuestContent(key: String): Flowable<QuestContent>
|
||||
fun getQuestContent(key: String): Flow<QuestContent?>
|
||||
fun getQuestContent(keys: List<String>): Flow<List<QuestContent>>
|
||||
|
||||
fun getEquipment(searchedKeys: List<String>): Flowable<out List<Equipment>>
|
||||
|
|
|
|||
|
|
@ -7,16 +7,16 @@ import com.habitrpg.android.habitica.models.social.GroupMembership
|
|||
import com.habitrpg.android.habitica.models.social.InboxConversation
|
||||
import com.habitrpg.android.habitica.models.user.User
|
||||
import io.reactivex.rxjava3.core.Flowable
|
||||
import io.realm.RealmResults
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
interface SocialLocalRepository : BaseLocalRepository {
|
||||
fun getPublicGuilds(): Flowable<out List<Group>>
|
||||
|
||||
fun getUserGroups(userID: String, type: String?): Flowable<out List<Group>>
|
||||
fun getUserGroups(userID: String, type: String?): Flow<List<Group>>
|
||||
fun getGroups(type: String): Flowable<out List<Group>>
|
||||
|
||||
fun getGroup(id: String): Flow<Group?>
|
||||
fun getGroupFlowable(id: String): Flowable<Group>
|
||||
fun saveGroup(group: Group)
|
||||
|
||||
fun getGroupChat(groupId: String): Flowable<out List<ChatMessage>>
|
||||
|
|
@ -39,13 +39,13 @@ interface SocialLocalRepository : BaseLocalRepository {
|
|||
|
||||
fun doesGroupExist(id: String): Boolean
|
||||
fun updateMembership(userId: String, id: String, isMember: Boolean)
|
||||
fun getGroupMembership(userId: String, id: String): Flowable<GroupMembership>
|
||||
fun getGroupMembership(userId: String, id: String): Flow<GroupMembership?>
|
||||
fun getGroupMemberships(userId: String): Flowable<out List<GroupMembership>>
|
||||
fun rejectGroupInvitation(userID: String, groupID: String)
|
||||
|
||||
fun getInboxMessages(userId: String, replyToUserID: String?): Flowable<out List<ChatMessage>>
|
||||
fun getInboxMessages(userId: String, replyToUserID: String?): Flow<RealmResults<ChatMessage>>
|
||||
|
||||
fun getInboxConversation(userId: String): Flowable<out List<InboxConversation>>
|
||||
fun getInboxConversation(userId: String): Flow<RealmResults<InboxConversation>>
|
||||
fun saveGroupMemberships(userID: String?, memberships: List<GroupMembership>)
|
||||
fun saveInboxMessages(
|
||||
userID: String,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
package com.habitrpg.android.habitica.data.local.implementation
|
||||
|
||||
import com.habitrpg.android.habitica.data.local.InventoryLocalRepository
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.android.habitica.models.inventory.Egg
|
||||
import com.habitrpg.android.habitica.models.inventory.Equipment
|
||||
import com.habitrpg.android.habitica.models.inventory.Food
|
||||
|
|
@ -39,14 +39,12 @@ class RealmInventoryLocalRepository(realm: Realm) : RealmContentLocalRepository(
|
|||
.filter { it.isLoaded }
|
||||
}
|
||||
|
||||
override fun getQuestContent(key: String): Flowable<QuestContent> {
|
||||
return RxJavaBridge.toV3Flowable(
|
||||
realm.where(QuestContent::class.java).equalTo("key", key)
|
||||
override fun getQuestContent(key: String): Flow<QuestContent?> {
|
||||
return realm.where(QuestContent::class.java).equalTo("key", key)
|
||||
.findAll()
|
||||
.asFlowable()
|
||||
.toFlow()
|
||||
.filter { content -> content.isLoaded && content.isValid && !content.isEmpty() }
|
||||
.map { content -> content.first() }
|
||||
)
|
||||
}
|
||||
|
||||
override fun getEquipment(searchedKeys: List<String>): Flowable<out List<Equipment>> {
|
||||
|
|
@ -240,7 +238,7 @@ class RealmInventoryLocalRepository(realm: Realm) : RealmContentLocalRepository(
|
|||
}
|
||||
|
||||
override fun changeOwnedCount(type: String, key: String, userID: String, amountToAdd: Int) {
|
||||
getOwnedItem(userID, type, key, true).firstElement().subscribe({ changeOwnedCount(it, amountToAdd) }, RxErrorHandler.handleEmptyError())
|
||||
getOwnedItem(userID, type, key, true).firstElement().subscribe({ changeOwnedCount(it, amountToAdd) }, ExceptionHandler.rx())
|
||||
}
|
||||
|
||||
override fun changeOwnedCount(item: OwnedItem, amountToAdd: Int?) {
|
||||
|
|
|
|||
|
|
@ -14,21 +14,21 @@ import io.reactivex.rxjava3.core.Flowable
|
|||
import io.realm.Realm
|
||||
import io.realm.Sort
|
||||
import io.realm.kotlin.toFlow
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.filter
|
||||
import kotlinx.coroutines.flow.flatMapLatest
|
||||
import kotlinx.coroutines.flow.map
|
||||
|
||||
class RealmSocialLocalRepository(realm: Realm) : RealmBaseLocalRepository(realm), SocialLocalRepository {
|
||||
|
||||
override fun getGroupMembership(userId: String, id: String): Flowable<GroupMembership> = RxJavaBridge.toV3Flowable(
|
||||
realm.where(GroupMembership::class.java)
|
||||
override fun getGroupMembership(userId: String, id: String) = realm.where(GroupMembership::class.java)
|
||||
.equalTo("userID", userId)
|
||||
.equalTo("groupID", id)
|
||||
.findAll()
|
||||
.asFlowable()
|
||||
.toFlow()
|
||||
.filter { it.isLoaded && it.isNotEmpty() }
|
||||
.map { it.first() }
|
||||
)
|
||||
|
||||
override fun getGroupMemberships(userId: String): Flowable<out List<GroupMembership>> = RxJavaBridge.toV3Flowable(
|
||||
realm.where(GroupMembership::class.java)
|
||||
|
|
@ -134,29 +134,25 @@ class RealmSocialLocalRepository(realm: Realm) : RealmBaseLocalRepository(realm)
|
|||
.filter { it.isLoaded }
|
||||
)
|
||||
|
||||
override fun getUserGroups(userID: String, type: String?): Flowable<out List<Group>> = RxJavaBridge.toV3Flowable(
|
||||
realm.where(GroupMembership::class.java)
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
override fun getUserGroups(userID: String, type: String?) = realm.where(GroupMembership::class.java)
|
||||
.equalTo("userID", userID)
|
||||
.findAll()
|
||||
.asFlowable()
|
||||
.filter { it.isLoaded }
|
||||
)
|
||||
.flatMap { memberships ->
|
||||
RxJavaBridge.toV3Flowable(
|
||||
realm.where(Group::class.java)
|
||||
.equalTo("type", type ?: "guild")
|
||||
.notEqualTo("id", Group.TAVERN_ID)
|
||||
.`in`(
|
||||
"id",
|
||||
memberships.map {
|
||||
return@map it.groupID
|
||||
}.toTypedArray()
|
||||
)
|
||||
.sort("memberCount", Sort.DESCENDING)
|
||||
.findAll()
|
||||
.asFlowable()
|
||||
.filter { it.isLoaded }
|
||||
)
|
||||
.toFlow()
|
||||
.filter { it.isLoaded }
|
||||
.flatMapLatest { memberships ->
|
||||
realm.where(Group::class.java)
|
||||
.equalTo("type", type ?: "guild")
|
||||
.notEqualTo("id", Group.TAVERN_ID)
|
||||
.`in`(
|
||||
"id",
|
||||
memberships.map {
|
||||
return@map it.groupID
|
||||
}.toTypedArray()
|
||||
)
|
||||
.sort("memberCount", Sort.DESCENDING)
|
||||
.findAll()
|
||||
.toFlow()
|
||||
}
|
||||
|
||||
override fun getGroups(type: String): Flowable<out List<Group>> {
|
||||
|
|
@ -169,17 +165,6 @@ class RealmSocialLocalRepository(realm: Realm) : RealmBaseLocalRepository(realm)
|
|||
)
|
||||
}
|
||||
|
||||
override fun getGroupFlowable(id: String): Flowable<Group> {
|
||||
return RxJavaBridge.toV3Flowable(
|
||||
realm.where(Group::class.java)
|
||||
.equalTo("id", id)
|
||||
.findAll()
|
||||
.asFlowable()
|
||||
.filter { group -> group.isLoaded && group.isValid && !group.isEmpty() }
|
||||
.map { groups -> groups.first() }
|
||||
)
|
||||
}
|
||||
|
||||
override fun getGroup(id: String): Flow<Group?> {
|
||||
return realm.where(Group::class.java)
|
||||
.equalTo("id", id)
|
||||
|
|
@ -205,13 +190,10 @@ class RealmSocialLocalRepository(realm: Realm) : RealmBaseLocalRepository(realm)
|
|||
executeTransaction { chatMessage?.deleteFromRealm() }
|
||||
}
|
||||
|
||||
override fun getGroupMembers(partyId: String): Flow<List<Member>> {
|
||||
return realm.where(Member::class.java)
|
||||
override fun getGroupMembers(partyId: String) = realm.where(Member::class.java)
|
||||
.equalTo("party.id", partyId)
|
||||
.findAll()
|
||||
.toFlow()
|
||||
.filter { it.isLoaded }
|
||||
}
|
||||
.toFlow()
|
||||
|
||||
override fun updateRSVPNeeded(user: User?, newValue: Boolean) {
|
||||
executeTransaction { user?.party?.quest?.RSVPNeeded = newValue }
|
||||
|
|
@ -302,27 +284,19 @@ class RealmSocialLocalRepository(realm: Realm) : RealmBaseLocalRepository(realm)
|
|||
return party != null && party.isValid
|
||||
}
|
||||
|
||||
override fun getInboxMessages(userId: String, replyToUserID: String?): Flowable<out List<ChatMessage>> {
|
||||
return RxJavaBridge.toV3Flowable(
|
||||
realm.where(ChatMessage::class.java)
|
||||
override fun getInboxMessages(userId: String, replyToUserID: String?) = realm.where(ChatMessage::class.java)
|
||||
.equalTo("isInboxMessage", true)
|
||||
.equalTo("uuid", replyToUserID)
|
||||
.equalTo("userID", userId)
|
||||
.sort("timestamp", Sort.DESCENDING)
|
||||
.findAll()
|
||||
.asFlowable()
|
||||
.toFlow()
|
||||
.filter { it.isLoaded }
|
||||
)
|
||||
}
|
||||
|
||||
override fun getInboxConversation(userId: String): Flowable<out List<InboxConversation>> {
|
||||
return RxJavaBridge.toV3Flowable(
|
||||
realm.where(InboxConversation::class.java)
|
||||
override fun getInboxConversation(userId: String) = realm.where(InboxConversation::class.java)
|
||||
.equalTo("userID", userId)
|
||||
.sort("timestamp", Sort.DESCENDING)
|
||||
.findAll()
|
||||
.asFlowable()
|
||||
.toFlow()
|
||||
.filter { it.isLoaded }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
package com.habitrpg.android.habitica.extensions
|
||||
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import io.reactivex.rxjava3.core.Flowable
|
||||
import io.reactivex.rxjava3.disposables.Disposable
|
||||
import io.reactivex.rxjava3.functions.Consumer
|
||||
|
||||
fun <T : Any> Flowable<T>.subscribeWithErrorHandler(function: Consumer<T>): Disposable {
|
||||
return subscribe(function, RxErrorHandler.handleEmptyError())
|
||||
return subscribe(function, ExceptionHandler.rx())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ class AppConfigManager(contentRepository: ContentRepository?): com.habitrpg.comm
|
|||
{
|
||||
worldState = it
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
ExceptionHandler.rx()
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,24 +4,31 @@ import android.util.Log
|
|||
import com.habitrpg.android.habitica.BuildConfig
|
||||
import com.habitrpg.android.habitica.proxy.AnalyticsManager
|
||||
import io.reactivex.rxjava3.functions.Consumer
|
||||
import java.io.EOFException
|
||||
import java.io.IOException
|
||||
import kotlinx.coroutines.CoroutineExceptionHandler
|
||||
import okhttp3.internal.http2.ConnectionShutdownException
|
||||
import retrofit2.HttpException
|
||||
import java.io.EOFException
|
||||
import java.io.IOException
|
||||
|
||||
class RxErrorHandler {
|
||||
class ExceptionHandler {
|
||||
private var analyticsManager: AnalyticsManager? = null
|
||||
|
||||
companion object {
|
||||
|
||||
private var instance: RxErrorHandler? = null
|
||||
private var instance = ExceptionHandler()
|
||||
|
||||
fun init(analyticsManager: AnalyticsManager) {
|
||||
instance = RxErrorHandler()
|
||||
instance?.analyticsManager = analyticsManager
|
||||
instance.analyticsManager = analyticsManager
|
||||
}
|
||||
|
||||
fun handleEmptyError(): Consumer<Throwable> {
|
||||
fun coroutine(handler: ((Throwable) -> Unit)? = null): CoroutineExceptionHandler {
|
||||
return CoroutineExceptionHandler { _, throwable ->
|
||||
reportError(throwable)
|
||||
handler?.invoke(throwable)
|
||||
}
|
||||
}
|
||||
|
||||
fun rx(): Consumer<Throwable> {
|
||||
// Can't be turned into a lambda, because it then doesn't work for some reason.
|
||||
return Consumer { reportError(it) }
|
||||
}
|
||||
|
|
@ -40,7 +47,7 @@ class RxErrorHandler {
|
|||
!retrofit2.adapter.rxjava3.HttpException::class.java.isAssignableFrom(throwable.javaClass) &&
|
||||
throwable !is ConnectionShutdownException
|
||||
) {
|
||||
instance?.analyticsManager?.logException(throwable)
|
||||
instance.analyticsManager?.logException(throwable)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -120,6 +120,6 @@ class MainNotificationsManager: NotificationsManager {
|
|||
|
||||
private fun readNotification(notification: Notification) {
|
||||
apiClient?.get()?.readNotification(notification.id)
|
||||
?.subscribe({ }, RxErrorHandler.handleEmptyError())
|
||||
?.subscribe({ }, ExceptionHandler.rx())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@ import com.habitrpg.android.habitica.HabiticaBaseApplication
|
|||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.data.ApiClient
|
||||
import com.habitrpg.android.habitica.extensions.addOkButton
|
||||
import com.habitrpg.android.habitica.extensions.subscribeWithErrorHandler
|
||||
import com.habitrpg.android.habitica.models.user.User
|
||||
import com.habitrpg.android.habitica.proxy.AnalyticsManager
|
||||
import com.habitrpg.android.habitica.ui.activities.PurchaseActivity
|
||||
|
|
@ -34,9 +33,9 @@ import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaAlertDialog
|
|||
import com.habitrpg.common.habitica.models.IAPGift
|
||||
import com.habitrpg.common.habitica.models.PurchaseValidationRequest
|
||||
import com.habitrpg.common.habitica.models.Transaction
|
||||
import io.reactivex.rxjava3.core.Flowable
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.MainScope
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
|
|
@ -88,7 +87,7 @@ class PurchaseHandler(
|
|||
return
|
||||
}
|
||||
BillingClient.BillingResponseCode.ITEM_ALREADY_OWNED -> {
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
CoroutineScope(Dispatchers.IO).launch(ExceptionHandler.coroutine()) {
|
||||
for (purchase in purchases) {
|
||||
consume(purchase)
|
||||
}
|
||||
|
|
@ -220,7 +219,7 @@ class PurchaseHandler(
|
|||
apiClient.validatePurchase(validationRequest).subscribe({
|
||||
processedPurchase(purchase)
|
||||
val gift = removeGift(sku)
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
CoroutineScope(Dispatchers.IO).launch(ExceptionHandler.coroutine()) {
|
||||
consume(purchase)
|
||||
}
|
||||
displayConfirmationDialog(purchase, gift?.second)
|
||||
|
|
@ -233,7 +232,7 @@ class PurchaseHandler(
|
|||
apiClient.validateNoRenewSubscription(validationRequest).subscribe({
|
||||
processedPurchase(purchase)
|
||||
val gift = removeGift(sku)
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
CoroutineScope(Dispatchers.IO).launch(ExceptionHandler.coroutine()) {
|
||||
consume(purchase)
|
||||
}
|
||||
displayConfirmationDialog(purchase, gift?.second)
|
||||
|
|
@ -246,7 +245,7 @@ class PurchaseHandler(
|
|||
apiClient.validateSubscription(validationRequest).subscribe({
|
||||
processedPurchase(purchase)
|
||||
analyticsManager.logEvent("user_subscribed", bundleOf(Pair("sku", sku)))
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
CoroutineScope(Dispatchers.IO).launch(ExceptionHandler.coroutine()) {
|
||||
acknowledgePurchase(purchase)
|
||||
}
|
||||
displayConfirmationDialog(purchase)
|
||||
|
|
@ -269,7 +268,9 @@ class PurchaseHandler(
|
|||
}
|
||||
|
||||
private fun processedPurchase(purchase: Purchase) {
|
||||
userViewModel.userRepository.retrieveUser(false, true).subscribeWithErrorHandler {}
|
||||
MainScope().launch(ExceptionHandler.coroutine()) {
|
||||
userViewModel.userRepository.retrieveUser(false, true)
|
||||
}
|
||||
}
|
||||
|
||||
private fun buildValidationRequest(purchase: Purchase): PurchaseValidationRequest {
|
||||
|
|
@ -297,7 +298,7 @@ class PurchaseHandler(
|
|||
if (res.message != null && res.message == "RECEIPT_ALREADY_USED") {
|
||||
processedPurchase(purchase)
|
||||
removeGift(purchase.skus.firstOrNull())
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
CoroutineScope(Dispatchers.IO).launch(ExceptionHandler.coroutine()) {
|
||||
consume(purchase)
|
||||
}
|
||||
return
|
||||
|
|
@ -332,9 +333,9 @@ class PurchaseHandler(
|
|||
return fallback
|
||||
}
|
||||
|
||||
fun cancelSubscription(): Flowable<User> {
|
||||
return apiClient.cancelSubscription()
|
||||
.flatMap { userViewModel.userRepository.retrieveUser(false, true) }
|
||||
suspend fun cancelSubscription(): User? {
|
||||
apiClient.cancelSubscription()
|
||||
return userViewModel.userRepository.retrieveUser(false, true)
|
||||
}
|
||||
|
||||
private fun durationString(sku: String): String {
|
||||
|
|
@ -371,7 +372,7 @@ class PurchaseHandler(
|
|||
}
|
||||
|
||||
private fun displayConfirmationDialog(purchase: Purchase, giftedTo: String? = null) {
|
||||
CoroutineScope(Dispatchers.Main).launch {
|
||||
CoroutineScope(Dispatchers.Main).launch(ExceptionHandler.coroutine()) {
|
||||
val application = (context as? HabiticaBaseApplication)
|
||||
?: (context.applicationContext as? HabiticaBaseApplication) ?: return@launch
|
||||
val sku = purchase.skus.firstOrNull() ?: return@launch
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ class SoundFile(val theme: String, private val fileName: String) {
|
|||
player?.start()
|
||||
} catch (e: IllegalStateException) {
|
||||
} catch (e: Exception) {
|
||||
RxErrorHandler.reportError(e)
|
||||
ExceptionHandler.reportError(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ class SoundManager {
|
|||
soundFiles.add(SoundFile(soundTheme, SoundReward))
|
||||
soundFiles.add(SoundFile(soundTheme, SoundTodo))
|
||||
soundFileLoader.download(soundFiles)
|
||||
.subscribe({}, RxErrorHandler.handleEmptyError())
|
||||
.subscribe({}, ExceptionHandler.rx())
|
||||
}
|
||||
|
||||
fun loadAndPlayAudio(type: String) {
|
||||
|
|
@ -54,7 +54,7 @@ class SoundManager {
|
|||
loadedSoundFiles[type] = file
|
||||
file.play()
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
ExceptionHandler.rx()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ class TaskAlarmManager(
|
|||
taskRepository.getTaskCopy(taskId)
|
||||
.filter { task -> task.isValid && task.isManaged && TaskType.DAILY == task.type }
|
||||
.firstElement()
|
||||
.subscribe({ this.setAlarmsForTask(it) }, RxErrorHandler.handleEmptyError())
|
||||
.subscribe({ this.setAlarmsForTask(it) }, ExceptionHandler.rx())
|
||||
}
|
||||
|
||||
suspend fun scheduleAllSavedAlarms(preventDailyReminder: Boolean) {
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ class HabiticaFirebaseMessagingService : FirebaseMessagingService() {
|
|||
pushNotificationManager.displayNotification(remoteMessage)
|
||||
|
||||
if (remoteMessage.data["identifier"]?.contains(PushNotificationManager.WON_CHALLENGE_PUSH_NOTIFICATION_KEY) == true) {
|
||||
// userRepository.retrieveUser(true).subscribe({}, RxErrorHandler.handleEmptyError())
|
||||
// userRepository.retrieveUser(true).subscribe({}, ExceptionHandler.rx())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import com.google.firebase.messaging.FirebaseMessaging
|
|||
import com.google.firebase.messaging.RemoteMessage
|
||||
import com.habitrpg.android.habitica.data.ApiClient
|
||||
import com.habitrpg.android.habitica.helpers.AmplitudeManager
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.android.habitica.models.user.User
|
||||
|
||||
class PushNotificationManager(
|
||||
|
|
@ -46,7 +46,7 @@ class PushNotificationManager(
|
|||
val pushDeviceData = HashMap<String, String>()
|
||||
pushDeviceData["regId"] = this.refreshedToken
|
||||
pushDeviceData["type"] = "android"
|
||||
apiClient.addPushDevice(pushDeviceData).subscribe({ }, RxErrorHandler.handleEmptyError())
|
||||
apiClient.addPushDevice(pushDeviceData).subscribe({ }, ExceptionHandler.rx())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -54,7 +54,7 @@ class PushNotificationManager(
|
|||
if (this.refreshedToken.isEmpty()) {
|
||||
return
|
||||
}
|
||||
apiClient.deletePushDevice(this.refreshedToken).subscribe({ }, RxErrorHandler.handleEmptyError())
|
||||
apiClient.deletePushDevice(this.refreshedToken).subscribe({ }, ExceptionHandler.rx())
|
||||
}
|
||||
|
||||
private fun userHasPushDevice(): Boolean {
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import android.widget.FrameLayout
|
|||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.data.InventoryRepository
|
||||
import com.habitrpg.android.habitica.executors.PostExecutionThread
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.android.habitica.models.inventory.Egg
|
||||
import com.habitrpg.android.habitica.models.inventory.HatchingPotion
|
||||
import com.habitrpg.android.habitica.models.user.Items
|
||||
|
|
@ -37,7 +37,7 @@ constructor(
|
|||
dialog.setAdditionalContentView(petWrapper)
|
||||
dialog.addButton(R.string.equip, true) { _, _ ->
|
||||
inventoryRepository.equip("pet", requestValues.egg.key + "-" + requestValues.potion.key)
|
||||
.subscribe({}, RxErrorHandler.handleEmptyError())
|
||||
.subscribe({}, ExceptionHandler.rx())
|
||||
}
|
||||
dialog.addButton(R.string.share, false) { hatchingDialog, _ ->
|
||||
val message = requestValues.context.getString(R.string.share_hatched, potionName, eggName)
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import android.view.ViewGroup
|
|||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.databinding.DialogLevelup10Binding
|
||||
import com.habitrpg.android.habitica.executors.PostExecutionThread
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.android.habitica.helpers.SoundManager
|
||||
import com.habitrpg.android.habitica.models.user.Stats
|
||||
import com.habitrpg.android.habitica.models.user.User
|
||||
|
|
@ -94,7 +94,7 @@ constructor(
|
|||
|
||||
private fun showClassSelection(requestValues: RequestValues) {
|
||||
checkClassSelectionUseCase.observable(CheckClassSelectionUseCase.RequestValues(requestValues.user, true, null, requestValues.activity))
|
||||
.subscribe({ }, RxErrorHandler.handleEmptyError())
|
||||
.subscribe({ }, ExceptionHandler.rx())
|
||||
}
|
||||
|
||||
class RequestValues(
|
||||
|
|
|
|||
|
|
@ -14,14 +14,13 @@ import androidx.core.util.Pair
|
|||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.data.UserRepository
|
||||
import com.habitrpg.android.habitica.executors.PostExecutionThread
|
||||
import com.habitrpg.android.habitica.extensions.filterMap
|
||||
import com.habitrpg.shared.habitica.extensions.round
|
||||
import com.habitrpg.android.habitica.models.user.Stats
|
||||
import com.habitrpg.android.habitica.models.user.User
|
||||
import com.habitrpg.android.habitica.ui.activities.BaseActivity
|
||||
import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper
|
||||
import com.habitrpg.android.habitica.ui.views.HabiticaSnackbar
|
||||
import com.habitrpg.android.habitica.ui.views.HabiticaSnackbar.SnackbarDisplayType
|
||||
import com.habitrpg.shared.habitica.extensions.round
|
||||
import io.reactivex.rxjava3.core.Flowable
|
||||
import javax.inject.Inject
|
||||
import kotlin.math.abs
|
||||
|
|
@ -48,8 +47,9 @@ constructor(
|
|||
}
|
||||
if (requestValues.hasLeveledUp == true) {
|
||||
return@defer levelUpUseCase.observable(LevelUpUseCase.RequestValues(requestValues.user, requestValues.level, requestValues.context, requestValues.snackbarTargetView))
|
||||
.flatMap { userRepository.retrieveUser(true) }
|
||||
.filterMap { it.stats }
|
||||
// TODO: .flatMap { userRepository.retrieveUser(true) }
|
||||
.flatMap { userRepository.getUserFlowable().firstElement().toFlowable() }
|
||||
.map { it.stats }
|
||||
} else {
|
||||
return@defer Flowable.just(stats)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import android.widget.TextView
|
|||
import androidx.lifecycle.LifecycleCoroutineScope
|
||||
import com.google.firebase.analytics.FirebaseAnalytics
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.android.habitica.models.user.User
|
||||
import com.habitrpg.android.habitica.ui.views.HabiticaSnackbar
|
||||
import com.habitrpg.android.habitica.ui.views.SnackbarActivity
|
||||
|
|
@ -126,7 +127,7 @@ class ShowNotificationInteractor(
|
|||
} else {
|
||||
200
|
||||
}
|
||||
lifecycleScope.launch {
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
delay(delayTime)
|
||||
lifecycleScope.launch(context = Dispatchers.Main) {
|
||||
val dialog = AchievementDialog(activity)
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import android.os.Parcelable
|
|||
import android.text.Spanned
|
||||
import com.google.gson.annotations.SerializedName
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.android.habitica.models.BaseMainObject
|
||||
import com.habitrpg.android.habitica.models.Tag
|
||||
import com.habitrpg.common.habitica.helpers.MarkdownParser
|
||||
|
|
@ -436,7 +436,7 @@ open class Task : RealmObject, BaseMainObject, Parcelable, BaseTask {
|
|||
i += 1
|
||||
}
|
||||
} catch (e: JSONException) {
|
||||
RxErrorHandler.reportError(e)
|
||||
ExceptionHandler.reportError(e)
|
||||
}
|
||||
}
|
||||
this.weeksOfMonth = weeksOfMonth.toList()
|
||||
|
|
@ -465,7 +465,7 @@ open class Task : RealmObject, BaseMainObject, Parcelable, BaseTask {
|
|||
i += 1
|
||||
}
|
||||
} catch (e: JSONException) {
|
||||
RxErrorHandler.reportError(e)
|
||||
ExceptionHandler.reportError(e)
|
||||
}
|
||||
}
|
||||
this.daysOfMonth = daysOfMonth
|
||||
|
|
|
|||
|
|
@ -1,44 +0,0 @@
|
|||
package com.habitrpg.android.habitica.modules;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
|
||||
import com.habitrpg.android.habitica.BuildConfig;
|
||||
import com.habitrpg.android.habitica.data.TaskRepository;
|
||||
import com.habitrpg.android.habitica.data.UserRepository;
|
||||
import com.habitrpg.android.habitica.helpers.TaskAlarmManager;
|
||||
import com.habitrpg.android.habitica.helpers.UserScope;
|
||||
import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel;
|
||||
|
||||
import javax.inject.Named;
|
||||
|
||||
import dagger.Module;
|
||||
import dagger.Provides;
|
||||
|
||||
@Module
|
||||
public class UserModule {
|
||||
public static final String NAMED_USER_ID = "userId";
|
||||
|
||||
@Provides
|
||||
@UserScope
|
||||
TaskAlarmManager providesTaskAlarmManager(Context context, TaskRepository taskRepository, @Named(NAMED_USER_ID) String userId) {
|
||||
return new TaskAlarmManager(context, taskRepository, userId);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Named(NAMED_USER_ID)
|
||||
@UserScope
|
||||
public String providesUserID(SharedPreferences sharedPreferences) {
|
||||
if (BuildConfig.DEBUG && !BuildConfig.TEST_USER_ID.isEmpty()) {
|
||||
return BuildConfig.TEST_USER_ID;
|
||||
} else {
|
||||
return sharedPreferences.getString("UserID", "");
|
||||
}
|
||||
}
|
||||
|
||||
@Provides
|
||||
@UserScope
|
||||
MainUserViewModel providesUserViewModel(String userID, UserRepository userRepository) {
|
||||
return new MainUserViewModel(userID, userRepository);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
package com.habitrpg.android.habitica.modules
|
||||
|
||||
import android.content.Context
|
||||
import android.content.SharedPreferences
|
||||
import com.habitrpg.android.habitica.BuildConfig
|
||||
import com.habitrpg.android.habitica.data.SocialRepository
|
||||
import com.habitrpg.android.habitica.data.TaskRepository
|
||||
import com.habitrpg.android.habitica.data.UserRepository
|
||||
import com.habitrpg.android.habitica.helpers.TaskAlarmManager
|
||||
import com.habitrpg.android.habitica.helpers.UserScope
|
||||
import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import javax.inject.Named
|
||||
|
||||
@Module
|
||||
class UserModule {
|
||||
@Provides
|
||||
@UserScope
|
||||
fun providesTaskAlarmManager(
|
||||
context: Context,
|
||||
taskRepository: TaskRepository,
|
||||
@Named(NAMED_USER_ID) userId: String
|
||||
): TaskAlarmManager {
|
||||
return TaskAlarmManager(context, taskRepository, userId)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Named(NAMED_USER_ID)
|
||||
@UserScope
|
||||
fun providesUserID(sharedPreferences: SharedPreferences): String {
|
||||
return if (BuildConfig.DEBUG && BuildConfig.TEST_USER_ID.isNotEmpty()) {
|
||||
BuildConfig.TEST_USER_ID
|
||||
} else {
|
||||
sharedPreferences.getString("UserID", "") ?: ""
|
||||
}
|
||||
}
|
||||
|
||||
@Provides
|
||||
@UserScope
|
||||
fun providesUserViewModel(
|
||||
@Named(NAMED_USER_ID) userID: String,
|
||||
userRepository: UserRepository,
|
||||
socialRepository: SocialRepository
|
||||
) = MainUserViewModel(userID, userRepository, socialRepository)
|
||||
|
||||
companion object {
|
||||
const val NAMED_USER_ID = "userId"
|
||||
}
|
||||
}
|
||||
|
|
@ -14,9 +14,11 @@ import com.habitrpg.android.habitica.data.ApiClient
|
|||
import com.habitrpg.android.habitica.data.SocialRepository
|
||||
import com.habitrpg.android.habitica.data.TaskRepository
|
||||
import com.habitrpg.android.habitica.data.UserRepository
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.android.habitica.interactors.NotifyUserUseCase
|
||||
import com.habitrpg.android.habitica.models.user.User
|
||||
import kotlinx.coroutines.MainScope
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
class LocalNotificationActionReceiver : BroadcastReceiver() {
|
||||
|
|
@ -56,30 +58,34 @@ class LocalNotificationActionReceiver : BroadcastReceiver() {
|
|||
when (action) {
|
||||
context?.getString(R.string.accept_party_invite) -> {
|
||||
groupID?.let {
|
||||
socialRepository.joinGroup(it).subscribe({ }, RxErrorHandler.handleEmptyError())
|
||||
MainScope().launch(ExceptionHandler.coroutine()) {
|
||||
socialRepository.joinGroup(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
context?.getString(R.string.reject_party_invite) -> {
|
||||
groupID?.let {
|
||||
socialRepository.rejectGroupInvite(it)
|
||||
.subscribe({ }, RxErrorHandler.handleEmptyError())
|
||||
.subscribe({ }, ExceptionHandler.rx())
|
||||
}
|
||||
}
|
||||
context?.getString(R.string.accept_quest_invite) -> {
|
||||
socialRepository.acceptQuest(user).subscribe({ }, RxErrorHandler.handleEmptyError())
|
||||
socialRepository.acceptQuest(user).subscribe({ }, ExceptionHandler.rx())
|
||||
}
|
||||
context?.getString(R.string.reject_quest_invite) -> {
|
||||
socialRepository.rejectQuest(user).subscribe({ }, RxErrorHandler.handleEmptyError())
|
||||
socialRepository.rejectQuest(user).subscribe({ }, ExceptionHandler.rx())
|
||||
}
|
||||
context?.getString(R.string.accept_guild_invite) -> {
|
||||
groupID?.let {
|
||||
socialRepository.joinGroup(it).subscribe({ }, RxErrorHandler.handleEmptyError())
|
||||
MainScope().launch(ExceptionHandler.coroutine()) {
|
||||
socialRepository.joinGroup(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
context?.getString(R.string.reject_guild_invite) -> {
|
||||
groupID?.let {
|
||||
socialRepository.rejectGroupInvite(it)
|
||||
.subscribe({ }, RxErrorHandler.handleEmptyError())
|
||||
.subscribe({ }, ExceptionHandler.rx())
|
||||
}
|
||||
}
|
||||
context?.getString(R.string.group_message_reply) -> {
|
||||
|
|
@ -91,7 +97,7 @@ class LocalNotificationActionReceiver : BroadcastReceiver() {
|
|||
NotificationManagerCompat.from(c).cancel(it.hashCode())
|
||||
}
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
ExceptionHandler.rx()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -99,8 +105,9 @@ class LocalNotificationActionReceiver : BroadcastReceiver() {
|
|||
context?.getString(R.string.inbox_message_reply) -> {
|
||||
senderID?.let {
|
||||
getMessageText(context?.getString(R.string.inbox_message_reply))?.let { message ->
|
||||
socialRepository.postPrivateMessage(it, message)
|
||||
.subscribe({ }, RxErrorHandler.handleEmptyError())
|
||||
MainScope().launch(ExceptionHandler.coroutine()) {
|
||||
socialRepository.postPrivateMessage(it, message)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -109,13 +116,13 @@ class LocalNotificationActionReceiver : BroadcastReceiver() {
|
|||
taskRepository.taskChecked(null, it, up = true, force = false) {
|
||||
}.subscribe({
|
||||
val pair = NotifyUserUseCase.getNotificationAndAddStatsToUserAsText(
|
||||
it?.experienceDelta,
|
||||
it?.healthDelta,
|
||||
it?.goldDelta,
|
||||
it?.manaDelta
|
||||
it.experienceDelta,
|
||||
it.healthDelta,
|
||||
it.goldDelta,
|
||||
it.manaDelta
|
||||
)
|
||||
showToast(pair.first)
|
||||
}, RxErrorHandler.handleEmptyError())
|
||||
}, ExceptionHandler.rx())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import com.habitrpg.android.habitica.R
|
|||
import com.habitrpg.android.habitica.data.TaskRepository
|
||||
import com.habitrpg.android.habitica.data.UserRepository
|
||||
import com.habitrpg.android.habitica.extensions.withImmutableFlag
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.android.habitica.helpers.TaskAlarmManager
|
||||
import com.habitrpg.android.habitica.models.tasks.Task
|
||||
import com.habitrpg.android.habitica.models.user.User
|
||||
|
|
@ -76,7 +76,7 @@ class NotificationPublisher : BroadcastReceiver() {
|
|||
notify(intent, buildNotification(wasInactive, pair.second.authentication?.timestamps?.createdAt))
|
||||
}
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
ExceptionHandler.rx()
|
||||
)
|
||||
} else {
|
||||
notify(intent, buildNotification(wasInactive))
|
||||
|
|
|
|||
|
|
@ -5,10 +5,10 @@ import android.content.Context
|
|||
import android.content.Intent
|
||||
import android.content.SharedPreferences
|
||||
import com.habitrpg.android.habitica.HabiticaBaseApplication
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.android.habitica.helpers.TaskAlarmManager
|
||||
import com.habitrpg.shared.habitica.HLogger
|
||||
import com.habitrpg.shared.habitica.LogLevel
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.MainScope
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
|
@ -25,7 +25,7 @@ class TaskAlarmBootReceiver : BroadcastReceiver() {
|
|||
return
|
||||
}
|
||||
HabiticaBaseApplication.userComponent?.inject(this)
|
||||
MainScope().launch(Dispatchers.Main) {
|
||||
MainScope().launch(ExceptionHandler.coroutine()) {
|
||||
taskAlarmManager.scheduleAllSavedAlarms(sharedPreferences.getBoolean("preventDailyReminder", false))
|
||||
}
|
||||
HLogger.log(LogLevel.INFO, this::javaClass.name, "onReceive")
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import com.habitrpg.android.habitica.HabiticaBaseApplication
|
|||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.data.TaskRepository
|
||||
import com.habitrpg.android.habitica.extensions.withImmutableFlag
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.android.habitica.helpers.TaskAlarmManager
|
||||
import com.habitrpg.android.habitica.models.tasks.Task
|
||||
import com.habitrpg.shared.habitica.models.tasks.TaskType
|
||||
|
|
@ -52,7 +52,7 @@ class TaskReceiver : BroadcastReceiver() {
|
|||
|
||||
createNotification(context, it)
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
ExceptionHandler.rx()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,8 @@ import com.habitrpg.android.habitica.databinding.ActivityArmoireBinding
|
|||
import com.habitrpg.android.habitica.helpers.AdHandler
|
||||
import com.habitrpg.android.habitica.helpers.AdType
|
||||
import com.habitrpg.android.habitica.helpers.AppConfigManager
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.common.habitica.extensions.loadImage
|
||||
import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel
|
||||
import com.habitrpg.android.habitica.ui.views.ads.AdButton
|
||||
import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaBottomSheetDialog
|
||||
|
|
@ -93,7 +94,7 @@ class ArmoireActivity : BaseActivity() {
|
|||
binding.adButton.visibility = View.INVISIBLE
|
||||
hasAnimatedChanges = false
|
||||
gold = null
|
||||
}, RxErrorHandler.handleEmptyError())
|
||||
}, ExceptionHandler.rx())
|
||||
)
|
||||
}
|
||||
handler.prepare {
|
||||
|
|
@ -116,7 +117,7 @@ class ArmoireActivity : BaseActivity() {
|
|||
finish()
|
||||
}
|
||||
binding.equipButton.setOnClickListener {
|
||||
equipmentKey?.let { it1 -> inventoryRepository.equip("equipped", it1).subscribe({}, RxErrorHandler.handleEmptyError()) }
|
||||
equipmentKey?.let { it1 -> inventoryRepository.equip("equipped", it1).subscribe({}, ExceptionHandler.rx()) }
|
||||
finish()
|
||||
}
|
||||
binding.dropRateButton.setOnClickListener {
|
||||
|
|
|
|||
|
|
@ -26,10 +26,11 @@ import com.habitrpg.android.habitica.HabiticaBaseApplication
|
|||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.components.UserComponent
|
||||
import com.habitrpg.android.habitica.data.UserRepository
|
||||
import com.habitrpg.android.habitica.extensions.subscribeWithErrorHandler
|
||||
import com.habitrpg.common.habitica.extensions.getThemeColor
|
||||
import com.habitrpg.common.habitica.extensions.isUsingNightModeResources
|
||||
import com.habitrpg.android.habitica.extensions.updateStatusBarColor
|
||||
import com.habitrpg.android.habitica.helpers.NotificationsManager
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.android.habitica.interactors.ShowNotificationInteractor
|
||||
import com.habitrpg.android.habitica.proxy.AnalyticsManager
|
||||
import com.habitrpg.android.habitica.ui.helpers.ToolbarColorHelper
|
||||
|
|
@ -38,6 +39,7 @@ import com.habitrpg.common.habitica.extensions.getThemeColor
|
|||
import com.habitrpg.common.habitica.extensions.isUsingNightModeResources
|
||||
import com.habitrpg.common.habitica.helpers.LanguageHelper
|
||||
import io.reactivex.rxjava3.disposables.CompositeDisposable
|
||||
import kotlinx.coroutines.launch
|
||||
import java.util.Date
|
||||
import java.util.Locale
|
||||
import javax.inject.Inject
|
||||
|
|
@ -94,16 +96,16 @@ abstract class BaseActivity : AppCompatActivity() {
|
|||
injectActivity(HabiticaBaseApplication.userComponent)
|
||||
setContentView(getContentView())
|
||||
compositeSubscription = CompositeDisposable()
|
||||
compositeSubscription.add(
|
||||
notificationsManager.displayNotificationEvents.subscribe(
|
||||
{
|
||||
if (ShowNotificationInteractor(this, lifecycleScope).handleNotification(it)) {
|
||||
compositeSubscription.add(userRepository.retrieveUser(false, true).subscribeWithErrorHandler {})
|
||||
compositeSubscription.add(notificationsManager.displayNotificationEvents.subscribe(
|
||||
{
|
||||
if (ShowNotificationInteractor(this, lifecycleScope).handleNotification(it)) {
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
userRepository.retrieveUser(false, true)
|
||||
}
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
)
|
||||
)
|
||||
}
|
||||
},
|
||||
ExceptionHandler.rx()
|
||||
))
|
||||
}
|
||||
|
||||
override fun onRestart() {
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@ import com.habitrpg.android.habitica.data.ChallengeRepository
|
|||
import com.habitrpg.android.habitica.data.SocialRepository
|
||||
import com.habitrpg.android.habitica.databinding.ActivityCreateChallengeBinding
|
||||
import com.habitrpg.android.habitica.extensions.addCloseButton
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.android.habitica.helpers.MainNavigationController
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.models.social.Challenge
|
||||
import com.habitrpg.android.habitica.models.social.Group
|
||||
import com.habitrpg.android.habitica.models.tasks.Task
|
||||
|
|
@ -41,6 +41,7 @@ import com.habitrpg.shared.habitica.models.tasks.TaskType
|
|||
import io.reactivex.rxjava3.core.Flowable
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.firstOrNull
|
||||
import kotlinx.coroutines.launch
|
||||
import java.util.UUID
|
||||
import javax.inject.Inject
|
||||
|
|
@ -156,7 +157,7 @@ class ChallengeFormActivity : BaseActivity() {
|
|||
{ throwable ->
|
||||
dialog?.dismiss()
|
||||
savingInProgress = false
|
||||
RxErrorHandler.reportError(throwable)
|
||||
ExceptionHandler.reportError(throwable)
|
||||
}
|
||||
)
|
||||
)
|
||||
|
|
@ -337,36 +338,26 @@ class ChallengeFormActivity : BaseActivity() {
|
|||
}
|
||||
|
||||
locationAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
|
||||
compositeSubscription.add(
|
||||
socialRepository.getUserGroups("guild").zipWith(
|
||||
userRepository.getUserFlowable()
|
||||
.map { it.party?.id ?: "" }
|
||||
.distinctUntilChanged()
|
||||
.flatMap {
|
||||
if (it.isBlank()) {
|
||||
return@flatMap Flowable.empty<Group>()
|
||||
}
|
||||
socialRepository.retrieveGroup(it)
|
||||
}
|
||||
) { user, groups -> Pair(user, groups) }
|
||||
.subscribe(
|
||||
{ groups ->
|
||||
val mutableGroups = groups.first.toMutableList()
|
||||
if (groups.first.firstOrNull { it.id == "00000000-0000-4000-A000-000000000000" } == null) {
|
||||
val tavern = Group()
|
||||
tavern.id = "00000000-0000-4000-A000-000000000000"
|
||||
tavern.name = getString(R.string.public_challenge)
|
||||
mutableGroups.add(0, tavern)
|
||||
}
|
||||
if (groups.second != null) {
|
||||
mutableGroups.add(groups.second)
|
||||
}
|
||||
locationAdapter.clear()
|
||||
locationAdapter.addAll(mutableGroups)
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
)
|
||||
)
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
val groups = socialRepository.getUserGroups("guild").firstOrNull()?.toMutableList() ?: return@launch
|
||||
val partyID = userRepository.getUser().firstOrNull()?.party?.id
|
||||
val party = if (partyID?.isNotBlank() == true) {
|
||||
socialRepository.retrieveGroup(partyID)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
if (groups.firstOrNull { it.id == "00000000-0000-4000-A000-000000000000" } == null) {
|
||||
val tavern = Group()
|
||||
tavern.id = "00000000-0000-4000-A000-000000000000"
|
||||
tavern.name = getString(R.string.public_challenge)
|
||||
groups.add(0, tavern)
|
||||
}
|
||||
if (party != null) {
|
||||
groups.add(party)
|
||||
}
|
||||
locationAdapter.clear()
|
||||
locationAdapter.addAll(groups)
|
||||
}
|
||||
|
||||
binding.challengeLocationSpinner.adapter = locationAdapter
|
||||
binding.challengeLocationSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
|
||||
|
|
@ -399,7 +390,7 @@ class ChallengeFormActivity : BaseActivity() {
|
|||
addReward.text -> openNewTaskActivity(TaskType.REWARD, null)
|
||||
}
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
ExceptionHandler.rx()
|
||||
)
|
||||
)
|
||||
|
||||
|
|
@ -438,7 +429,7 @@ class ChallengeFormActivity : BaseActivity() {
|
|||
}
|
||||
checkPrizeAndMinimumForTavern()
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
ExceptionHandler.rx()
|
||||
)
|
||||
challengeRepository.getChallengeTasks(it).subscribe(
|
||||
{ tasks ->
|
||||
|
|
@ -446,7 +437,7 @@ class ChallengeFormActivity : BaseActivity() {
|
|||
addOrUpdateTaskInList(task, true)
|
||||
}
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
ExceptionHandler.rx()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,24 +8,25 @@ import android.view.MenuItem
|
|||
import android.view.View
|
||||
import android.widget.TextView
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.navigation.navArgs
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.components.UserComponent
|
||||
import com.habitrpg.android.habitica.databinding.ActivityClassSelectionBinding
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.android.habitica.models.user.Gear
|
||||
import com.habitrpg.android.habitica.models.user.Items
|
||||
import com.habitrpg.android.habitica.models.user.Outfit
|
||||
import com.habitrpg.android.habitica.models.user.Preferences
|
||||
import com.habitrpg.android.habitica.models.user.User
|
||||
import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel
|
||||
import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper
|
||||
import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaAlertDialog
|
||||
import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaProgressDialog
|
||||
import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper
|
||||
import io.reactivex.rxjava3.functions.Consumer
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
class ClassSelectionActivity : BaseActivity(), Consumer<User> {
|
||||
class ClassSelectionActivity : BaseActivity() {
|
||||
|
||||
@Inject
|
||||
lateinit var userViewModel: MainUserViewModel
|
||||
|
|
@ -85,10 +86,10 @@ class ClassSelectionActivity : BaseActivity(), Consumer<User> {
|
|||
}
|
||||
|
||||
if (!isInitialSelection) {
|
||||
compositeSubscription.add(
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
userRepository.changeClass()
|
||||
.subscribe({ classWasUnset = true }, RxErrorHandler.handleEmptyError())
|
||||
)
|
||||
classWasUnset
|
||||
}
|
||||
}
|
||||
|
||||
binding.healerWrapper.setOnClickListener { newClass = "healer" }
|
||||
|
|
@ -254,20 +255,26 @@ class ClassSelectionActivity : BaseActivity(), Consumer<User> {
|
|||
private fun optOutOfClasses() {
|
||||
shouldFinish = true
|
||||
this.displayProgressDialog(getString(R.string.opting_out_progress))
|
||||
compositeSubscription.add(userRepository.disableClasses().subscribe(this, RxErrorHandler.handleEmptyError()))
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
userRepository.disableClasses()
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
private fun selectClass(selectedClass: String) {
|
||||
shouldFinish = true
|
||||
this.displayProgressDialog(getString(R.string.changing_class_progress))
|
||||
compositeSubscription.add(userRepository.changeClass(selectedClass).subscribe(this, RxErrorHandler.handleEmptyError()))
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
userRepository.changeClass(selectedClass)
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
private fun displayProgressDialog(progressText: String) {
|
||||
HabiticaProgressDialog.show(this, progressText)
|
||||
}
|
||||
|
||||
override fun accept(user: User) {
|
||||
private fun dismiss() {
|
||||
if (shouldFinish == true) {
|
||||
progressDialog?.dismiss()
|
||||
finish()
|
||||
|
|
|
|||
|
|
@ -15,12 +15,13 @@ import com.habitrpg.android.habitica.extensions.observeOnce
|
|||
import com.habitrpg.android.habitica.helpers.AdHandler
|
||||
import com.habitrpg.android.habitica.helpers.AdType
|
||||
import com.habitrpg.android.habitica.helpers.AppConfigManager
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel
|
||||
import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper
|
||||
import com.habitrpg.android.habitica.ui.views.ads.AdButton
|
||||
import com.habitrpg.common.habitica.helpers.Animations
|
||||
import com.plattysoft.leonids.ParticleSystem
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
class DeathActivity: BaseActivity() {
|
||||
|
|
@ -59,7 +60,7 @@ class DeathActivity: BaseActivity() {
|
|||
compositeSubscription.add(
|
||||
userRepository.updateUser("stats.hp", 1).subscribe({
|
||||
finish()
|
||||
}, RxErrorHandler.handleEmptyError())
|
||||
}, ExceptionHandler.rx())
|
||||
)
|
||||
}
|
||||
handler.prepare {
|
||||
|
|
@ -80,9 +81,10 @@ class DeathActivity: BaseActivity() {
|
|||
|
||||
binding.restartButton.setOnClickListener {
|
||||
binding.restartButton.isEnabled = false
|
||||
userRepository.revive().subscribe({
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
userRepository.revive()
|
||||
finish()
|
||||
}, RxErrorHandler.handleEmptyError())
|
||||
}
|
||||
}
|
||||
startAnimating()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import android.widget.TableRow
|
|||
import android.widget.TextView
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.os.bundleOf
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.components.UserComponent
|
||||
import com.habitrpg.android.habitica.data.ApiClient
|
||||
|
|
@ -20,8 +21,8 @@ import com.habitrpg.android.habitica.data.InventoryRepository
|
|||
import com.habitrpg.android.habitica.data.SocialRepository
|
||||
import com.habitrpg.android.habitica.databinding.ActivityFullProfileBinding
|
||||
import com.habitrpg.android.habitica.extensions.addCancelButton
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.android.habitica.helpers.MainNavigationController
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.helpers.UserStatComputer
|
||||
import com.habitrpg.android.habitica.models.Achievement
|
||||
import com.habitrpg.android.habitica.models.inventory.Equipment
|
||||
|
|
@ -82,7 +83,12 @@ class FullProfileActivity : BaseActivity() {
|
|||
|
||||
setTitle(R.string.profile_loading_data)
|
||||
|
||||
compositeSubscription.add(socialRepository.getMember(this.userID).subscribe({ this.updateView(it) }, RxErrorHandler.handleEmptyError()))
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
val member = socialRepository.retrieveMember(userID)
|
||||
if (member != null) {
|
||||
updateView(member)
|
||||
}
|
||||
}
|
||||
avatarWithBars = AvatarWithBarsViewModel(this, binding.avatarWithBars)
|
||||
|
||||
binding.avatarWithBars.root.setBackgroundColor(ContextCompat.getColor(this, R.color.transparent))
|
||||
|
|
@ -96,15 +102,13 @@ class FullProfileActivity : BaseActivity() {
|
|||
binding.sendMessageButton.setOnClickListener { showSendMessageToUserDialog() }
|
||||
binding.giftGemsButton.setOnClickListener { MainNavigationController.navigate(R.id.giftGemsActivity, bundleOf(Pair("userID", userID), Pair("username", null))) }
|
||||
binding.giftSubscriptionButton.setOnClickListener { MainNavigationController.navigate(R.id.giftSubscriptionActivity, bundleOf(Pair("userID", userID), Pair("username", null))) }
|
||||
compositeSubscription.add(
|
||||
userRepository.getUserFlowable().subscribe(
|
||||
{
|
||||
blocks = it.inbox?.blocks ?: listOf()
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
userRepository.getUser()
|
||||
.collect {
|
||||
blocks = it?.inbox?.blocks ?: listOf()
|
||||
binding.blockedDisclaimerView.visibility = if (isUserBlocked()) View.VISIBLE else View.GONE
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
|
|
@ -168,13 +172,14 @@ class FullProfileActivity : BaseActivity() {
|
|||
|
||||
private fun useBlock() {
|
||||
compositeSubscription.add(
|
||||
socialRepository.blockMember(userID).flatMap {
|
||||
userRepository.retrieveUser()
|
||||
}.subscribe(
|
||||
socialRepository.blockMember(userID).subscribe(
|
||||
{
|
||||
invalidateOptionsMenu()
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
userRepository.retrieveUser()
|
||||
invalidateOptionsMenu()
|
||||
}
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
ExceptionHandler.rx()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
@ -227,16 +232,16 @@ class FullProfileActivity : BaseActivity() {
|
|||
|
||||
avatarWithBars?.updateData(user)
|
||||
|
||||
compositeSubscription.add(loadItemDataByOutfit(user.equipped).subscribe({ gear -> this.gotGear(gear, user) }, RxErrorHandler.handleEmptyError()))
|
||||
compositeSubscription.add(loadItemDataByOutfit(user.equipped).subscribe({ gear -> this.gotGear(gear, user) }, ExceptionHandler.rx()))
|
||||
|
||||
if (user.preferences?.costume == true) {
|
||||
compositeSubscription.add(loadItemDataByOutfit(user.costume).subscribe({ this.gotCostume(it) }, RxErrorHandler.handleEmptyError()))
|
||||
compositeSubscription.add(loadItemDataByOutfit(user.costume).subscribe({ this.gotCostume(it) }, ExceptionHandler.rx()))
|
||||
} else {
|
||||
binding.costumeCard.visibility = View.GONE
|
||||
}
|
||||
|
||||
// Load the members achievements now
|
||||
compositeSubscription.add(socialRepository.getMemberAchievements(this.userID).subscribe({ this.fillAchievements(it) }, RxErrorHandler.handleEmptyError()))
|
||||
compositeSubscription.add(socialRepository.getMemberAchievements(this.userID).subscribe({ this.fillAchievements(it) }, ExceptionHandler.rx()))
|
||||
}
|
||||
|
||||
private fun updatePetsMountsView(user: Member) {
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package com.habitrpg.android.habitica.ui.activities
|
|||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.navigation.navArgs
|
||||
import androidx.viewpager2.adapter.FragmentStateAdapter
|
||||
import com.google.android.material.tabs.TabLayoutMediator
|
||||
|
|
@ -11,12 +12,14 @@ import com.habitrpg.android.habitica.components.UserComponent
|
|||
import com.habitrpg.android.habitica.data.SocialRepository
|
||||
import com.habitrpg.android.habitica.databinding.ActivityGiftGemsBinding
|
||||
import com.habitrpg.android.habitica.helpers.AppConfigManager
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.android.habitica.helpers.PurchaseHandler
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.models.members.Member
|
||||
import com.habitrpg.android.habitica.ui.fragments.purchases.GiftBalanceGemsFragment
|
||||
import com.habitrpg.android.habitica.ui.fragments.purchases.GiftPurchaseGemsFragment
|
||||
import com.habitrpg.android.habitica.ui.views.CurrencyView
|
||||
import kotlinx.coroutines.flow.firstOrNull
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
class GiftGemsActivity : PurchaseActivity() {
|
||||
|
|
@ -74,27 +77,17 @@ class GiftGemsActivity : PurchaseActivity() {
|
|||
|
||||
setViewPagerAdapter()
|
||||
|
||||
compositeSubscription.add(
|
||||
socialRepository.getMember(giftedUsername ?: giftedUserID).firstElement().subscribe(
|
||||
{
|
||||
giftedMember = it
|
||||
giftedUserID = it.id
|
||||
giftedUsername = it.username
|
||||
purchaseFragment?.giftedMember = it
|
||||
balanceFragment?.giftedMember = it
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
)
|
||||
)
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
val member = socialRepository.retrieveMember(giftedUsername ?: giftedUserID) ?: return@launch
|
||||
giftedMember = member
|
||||
giftedUserID = member.id
|
||||
giftedUsername = member.username
|
||||
purchaseFragment?.giftedMember = member
|
||||
balanceFragment?.giftedMember = member
|
||||
|
||||
compositeSubscription.add(
|
||||
userRepository.getUserFlowable().subscribe(
|
||||
{
|
||||
currencyView.value = it.gemCount.toDouble()
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
)
|
||||
)
|
||||
val user = userRepository.getUser().firstOrNull()
|
||||
currencyView.value = user?.gemCount?.toDouble() ?: 0.0
|
||||
}
|
||||
}
|
||||
|
||||
private fun setViewPagerAdapter() {
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package com.habitrpg.android.habitica.ui.activities
|
|||
import android.annotation.SuppressLint
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.navigation.navArgs
|
||||
import com.android.billingclient.api.SkuDetails
|
||||
import com.habitrpg.android.habitica.R
|
||||
|
|
@ -10,15 +11,15 @@ import com.habitrpg.android.habitica.components.UserComponent
|
|||
import com.habitrpg.android.habitica.data.SocialRepository
|
||||
import com.habitrpg.android.habitica.databinding.ActivityGiftSubscriptionBinding
|
||||
import com.habitrpg.android.habitica.helpers.AppConfigManager
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.android.habitica.helpers.PurchaseHandler
|
||||
import com.habitrpg.android.habitica.helpers.PurchaseTypes
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.ui.views.subscriptions.SubscriptionOptionView
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import javax.inject.Inject
|
||||
|
||||
class GiftSubscriptionActivity : PurchaseActivity() {
|
||||
|
||||
|
|
@ -70,20 +71,15 @@ class GiftSubscriptionActivity : PurchaseActivity() {
|
|||
binding.subscriptionButton.setOnClickListener {
|
||||
selectedSubscriptionSku?.let { sku -> purchaseSubscription(sku) }
|
||||
}
|
||||
|
||||
compositeSubscription.add(
|
||||
socialRepository.getMember(giftedUsername ?: giftedUserID).subscribe(
|
||||
{
|
||||
binding.avatarView.setAvatar(it)
|
||||
binding.displayNameTextView.username = it.profile?.name
|
||||
binding.displayNameTextView.tier = it.contributor?.level ?: 0
|
||||
binding.usernameTextView.text = "@${it.username}"
|
||||
giftedUserID = it.id
|
||||
giftedUsername = it.username
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
)
|
||||
)
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
val member = socialRepository.retrieveMember(giftedUsername ?: giftedUserID) ?: return@launch
|
||||
binding.avatarView.setAvatar(member)
|
||||
binding.displayNameTextView.username = member.profile?.name
|
||||
binding.displayNameTextView.tier = member.contributor?.level ?: 0
|
||||
binding.usernameTextView.text = "@${member.username}"
|
||||
giftedUserID = member.id
|
||||
giftedUsername = member.username
|
||||
}
|
||||
|
||||
if (appConfigManager.activePromo()?.identifier == "g1g1") {
|
||||
binding.giftSubscriptionContainer.visibility = View.VISIBLE
|
||||
|
|
@ -94,7 +90,7 @@ class GiftSubscriptionActivity : PurchaseActivity() {
|
|||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
CoroutineScope(Dispatchers.IO).launch(ExceptionHandler.coroutine()) {
|
||||
val subscriptions = purchaseHandler.getAllGiftSubscriptionProducts()
|
||||
skus = subscriptions
|
||||
withContext(Dispatchers.Main) {
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import android.view.MenuItem
|
|||
import android.widget.TextView
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.components.UserComponent
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.common.habitica.helpers.setMarkdown
|
||||
import okhttp3.Call
|
||||
import okhttp3.Callback
|
||||
|
|
@ -31,7 +31,7 @@ class GuidelinesActivity : BaseActivity() {
|
|||
val request = Request.Builder().url("https://s3.amazonaws.com/habitica-assets/mobileApp/endpoint/community-guidelines.md").build()
|
||||
client.newCall(request).enqueue(object : Callback {
|
||||
override fun onFailure(call: Call, e: IOException) {
|
||||
RxErrorHandler.reportError(e)
|
||||
ExceptionHandler.reportError(e)
|
||||
}
|
||||
|
||||
@Throws(IOException::class)
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import com.habitrpg.android.habitica.R
|
|||
import com.habitrpg.android.habitica.components.UserComponent
|
||||
import com.habitrpg.android.habitica.data.TaskRepository
|
||||
import com.habitrpg.android.habitica.databinding.WidgetConfigureHabitButtonBinding
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.android.habitica.modules.AppModule
|
||||
import com.habitrpg.android.habitica.ui.adapter.SkillTasksRecyclerViewAdapter
|
||||
import com.habitrpg.android.habitica.widget.HabitButtonWidgetProvider
|
||||
|
|
@ -77,11 +77,11 @@ class HabitButtonWidgetActivity : BaseActivity() {
|
|||
adapter = SkillTasksRecyclerViewAdapter()
|
||||
adapter?.getTaskSelectionEvents()?.subscribe(
|
||||
{ task -> taskSelected(task.id) },
|
||||
RxErrorHandler.handleEmptyError()
|
||||
ExceptionHandler.rx()
|
||||
)?.let { compositeSubscription.add(it) }
|
||||
binding.recyclerView.adapter = adapter
|
||||
|
||||
CoroutineScope(Dispatchers.Main + job).launch {
|
||||
CoroutineScope(Dispatchers.Main + job).launch(ExceptionHandler.coroutine()) {
|
||||
adapter?.data = taskRepository.getTasks(TaskType.HABIT, userId, emptyArray()).firstOrNull() ?: listOf()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,14 +10,16 @@ import androidx.core.content.res.ResourcesCompat
|
|||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import androidx.fragment.app.FragmentStatePagerAdapter
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.viewpager.widget.ViewPager
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.components.UserComponent
|
||||
import com.habitrpg.android.habitica.data.ContentRepository
|
||||
import com.habitrpg.android.habitica.databinding.ActivityIntroBinding
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.android.habitica.ui.fragments.setup.IntroFragment
|
||||
import com.viewpagerindicator.IconPagerAdapter
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
class IntroActivity : BaseActivity(), View.OnClickListener, ViewPager.OnPageChangeListener {
|
||||
|
|
@ -44,7 +46,9 @@ class IntroActivity : BaseActivity(), View.OnClickListener, ViewPager.OnPageChan
|
|||
binding.skipButton.setOnClickListener(this)
|
||||
binding.finishButton.setOnClickListener(this)
|
||||
|
||||
compositeSubscription.add(contentRepository.retrieveContent().subscribe({ }, RxErrorHandler.handleEmptyError()))
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
contentRepository.retrieveContent()
|
||||
}
|
||||
|
||||
window.statusBarColor = ContextCompat.getColor(this, R.color.black_20_alpha)
|
||||
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ import com.habitrpg.android.habitica.extensions.addOkButton
|
|||
import com.habitrpg.android.habitica.extensions.updateStatusBarColor
|
||||
import com.habitrpg.android.habitica.helpers.AmplitudeManager
|
||||
import com.habitrpg.android.habitica.helpers.AppConfigManager
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.android.habitica.models.user.User
|
||||
import com.habitrpg.android.habitica.ui.helpers.dismissKeyboard
|
||||
import com.habitrpg.android.habitica.ui.viewmodels.AuthenticationViewModel
|
||||
|
|
@ -86,7 +86,7 @@ class LoginActivity : BaseActivity() {
|
|||
{ handleAuthResponse(it) },
|
||||
{
|
||||
hideProgress()
|
||||
RxErrorHandler.reportError(it)
|
||||
ExceptionHandler.reportError(it)
|
||||
}
|
||||
)
|
||||
} else {
|
||||
|
|
@ -101,7 +101,7 @@ class LoginActivity : BaseActivity() {
|
|||
{ handleAuthResponse(it) },
|
||||
{
|
||||
hideProgress()
|
||||
RxErrorHandler.reportError(it)
|
||||
ExceptionHandler.reportError(it)
|
||||
Log.d("LoginActivity", ": ${it.message}", it)
|
||||
}
|
||||
)
|
||||
|
|
@ -261,12 +261,12 @@ class LoginActivity : BaseActivity() {
|
|||
} catch (e: Exception) {
|
||||
// Wearable API is not available on this device.
|
||||
}
|
||||
compositeSubscription.add(
|
||||
userRepository.retrieveUser(true)
|
||||
.subscribe({
|
||||
handleAuthResponse(it, response.newUser)
|
||||
}, RxErrorHandler.handleEmptyError())
|
||||
)
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
val user = userRepository.retrieveUser(true)
|
||||
if (user != null) {
|
||||
handleAuthResponse(user, response.newUser)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleAuthResponse(user: User, isNew: Boolean) {
|
||||
|
|
@ -276,20 +276,15 @@ class LoginActivity : BaseActivity() {
|
|||
if (isRegistering) {
|
||||
FirebaseAnalytics.getInstance(this).logEvent("user_registered", null)
|
||||
}
|
||||
compositeSubscription.add(
|
||||
userRepository.retrieveUser(withTasks = true, forced = true)
|
||||
.subscribe(
|
||||
{
|
||||
if (isNew) {
|
||||
this.startSetupActivity()
|
||||
} else {
|
||||
this.startMainActivity()
|
||||
AmplitudeManager.sendEvent("login", AmplitudeManager.EVENT_CATEGORY_BEHAVIOUR, AmplitudeManager.EVENT_HITTYPE_EVENT)
|
||||
}
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
)
|
||||
)
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
userRepository.retrieveUser(true, true)
|
||||
if (isNew) {
|
||||
startSetupActivity()
|
||||
} else {
|
||||
startMainActivity()
|
||||
AmplitudeManager.sendEvent("login", AmplitudeManager.EVENT_CATEGORY_BEHAVIOUR, AmplitudeManager.EVENT_HITTYPE_EVENT)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
|
|
@ -455,7 +450,7 @@ class LoginActivity : BaseActivity() {
|
|||
alertDialog.setMessage(R.string.forgot_password_description)
|
||||
alertDialog.setAdditionalContentView(input)
|
||||
alertDialog.addButton(R.string.send, true) { _, _ ->
|
||||
userRepository.sendPasswordResetEmail(input.text.toString()).subscribe({ showPasswordEmailConfirmation() }, RxErrorHandler.handleEmptyError())
|
||||
userRepository.sendPasswordResetEmail(input.text.toString()).subscribe({ showPasswordEmailConfirmation() }, ExceptionHandler.rx())
|
||||
}
|
||||
alertDialog.addCancelButton()
|
||||
alertDialog.show()
|
||||
|
|
|
|||
|
|
@ -37,9 +37,9 @@ import com.habitrpg.android.habitica.extensions.subscribeWithErrorHandler
|
|||
import com.habitrpg.android.habitica.extensions.updateStatusBarColor
|
||||
import com.habitrpg.android.habitica.helpers.AmplitudeManager
|
||||
import com.habitrpg.android.habitica.helpers.AppConfigManager
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.android.habitica.helpers.MainNavigationController
|
||||
import com.habitrpg.android.habitica.helpers.NotificationOpenHandler
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.helpers.SoundManager
|
||||
import com.habitrpg.android.habitica.interactors.CheckClassSelectionUseCase
|
||||
import com.habitrpg.android.habitica.interactors.DisplayItemDropUseCase
|
||||
|
|
@ -68,6 +68,7 @@ import com.habitrpg.shared.habitica.models.responses.TaskScoringResult
|
|||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.firstOrNull
|
||||
import kotlinx.coroutines.launch
|
||||
import java.util.Date
|
||||
import javax.inject.Inject
|
||||
|
|
@ -130,8 +131,8 @@ open class MainActivity : BaseActivity(), SnackbarActivity {
|
|||
}
|
||||
try {
|
||||
launchTrace = FirebasePerformance.getInstance().newTrace("MainActivityLaunch")
|
||||
} catch (e: Exception) {
|
||||
// pass
|
||||
} catch (e: IllegalStateException) {
|
||||
ExceptionHandler.reportError(e)
|
||||
}
|
||||
launchTrace?.start()
|
||||
super.onCreate(savedInstanceState)
|
||||
|
|
@ -393,16 +394,13 @@ open class MainActivity : BaseActivity(), SnackbarActivity {
|
|||
|
||||
val quest = user.party?.quest
|
||||
if (quest?.completed?.isNotBlank() == true) {
|
||||
compositeSubscription.add(
|
||||
inventoryRepository.getQuestContent(user.party?.quest?.completed ?: "").firstElement().subscribe(
|
||||
{
|
||||
QuestCompletedDialog.showWithQuest(this, it)
|
||||
|
||||
viewModel.updateUser("party.quest.completed", "")
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
)
|
||||
)
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
val questContent = inventoryRepository.getQuestContent(user.party?.quest?.completed ?: "").firstOrNull()
|
||||
if (questContent != null) {
|
||||
QuestCompletedDialog.showWithQuest(this@MainActivity, questContent)
|
||||
}
|
||||
viewModel.updateUser("party.quest.completed", "")
|
||||
}
|
||||
}
|
||||
|
||||
if (user.flags?.welcomed == false) {
|
||||
|
|
@ -451,14 +449,14 @@ open class MainActivity : BaseActivity(), SnackbarActivity {
|
|||
viewModel.user.value, data.experienceDelta, data.healthDelta, data.goldDelta, data.manaDelta, damageValue, data.hasLeveledUp, data.level
|
||||
)
|
||||
)
|
||||
.subscribe({ }, RxErrorHandler.handleEmptyError())
|
||||
.subscribe({ }, ExceptionHandler.rx())
|
||||
)
|
||||
}
|
||||
|
||||
val showItemsFound = userQuestStatus == UserQuestStatus.QUEST_COLLECT
|
||||
compositeSubscription.add(
|
||||
displayItemDropUseCase.observable(DisplayItemDropUseCase.RequestValues(data, this, snackbarContainer, showItemsFound))
|
||||
.subscribe({ }, RxErrorHandler.handleEmptyError())
|
||||
.subscribe({ }, ExceptionHandler.rx())
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -517,7 +515,7 @@ open class MainActivity : BaseActivity(), SnackbarActivity {
|
|||
startActivity(intent)
|
||||
}
|
||||
} catch (e: PackageManager.NameNotFoundException) {
|
||||
RxErrorHandler.reportError(e)
|
||||
ExceptionHandler.reportError(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import com.habitrpg.android.habitica.api.MaintenanceApiService
|
|||
import com.habitrpg.android.habitica.components.UserComponent
|
||||
import com.habitrpg.android.habitica.data.ApiClient
|
||||
import com.habitrpg.android.habitica.databinding.ActivityMaintenanceBinding
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.common.habitica.helpers.setMarkdown
|
||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.rxjava3.schedulers.Schedulers
|
||||
|
|
@ -76,7 +76,7 @@ class MaintenanceActivity : BaseActivity() {
|
|||
finish()
|
||||
}
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
ExceptionHandler.rx()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,15 +13,17 @@ import android.widget.RatingBar
|
|||
import android.widget.TextView
|
||||
import androidx.activity.viewModels
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.components.UserComponent
|
||||
import com.habitrpg.android.habitica.data.InventoryRepository
|
||||
import com.habitrpg.android.habitica.data.SocialRepository
|
||||
import com.habitrpg.android.habitica.databinding.ActivityNotificationsBinding
|
||||
import com.habitrpg.android.habitica.extensions.fromHtml
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.common.habitica.models.Notification
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.android.habitica.models.inventory.QuestContent
|
||||
import com.habitrpg.android.habitica.ui.viewmodels.NotificationsViewModel
|
||||
import com.habitrpg.common.habitica.models.Notification
|
||||
import com.habitrpg.common.habitica.models.notifications.GroupTaskApprovedData
|
||||
import com.habitrpg.common.habitica.models.notifications.GroupTaskNeedsWorkData
|
||||
import com.habitrpg.common.habitica.models.notifications.GroupTaskRequiresApprovalData
|
||||
|
|
@ -31,7 +33,8 @@ import com.habitrpg.common.habitica.models.notifications.NewStuffData
|
|||
import com.habitrpg.common.habitica.models.notifications.PartyInvitationData
|
||||
import com.habitrpg.common.habitica.models.notifications.QuestInvitationData
|
||||
import com.habitrpg.common.habitica.models.notifications.UnallocatedPointsData
|
||||
import com.habitrpg.android.habitica.ui.viewmodels.NotificationsViewModel
|
||||
import kotlinx.coroutines.flow.firstOrNull
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
class NotificationsActivity : BaseActivity(), androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener {
|
||||
|
|
@ -68,7 +71,7 @@ class NotificationsActivity : BaseActivity(), androidx.swiperefreshlayout.widget
|
|||
this.setNotifications(it)
|
||||
viewModel.markNotificationsAsSeen(it)
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
ExceptionHandler.rx()
|
||||
)
|
||||
)
|
||||
|
||||
|
|
@ -90,14 +93,10 @@ class NotificationsActivity : BaseActivity(), androidx.swiperefreshlayout.widget
|
|||
override fun onRefresh() {
|
||||
binding.notificationsRefreshLayout.isRefreshing = true
|
||||
|
||||
compositeSubscription.add(
|
||||
viewModel.refreshNotifications().subscribe(
|
||||
{
|
||||
binding.notificationsRefreshLayout.isRefreshing = false
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
)
|
||||
)
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
viewModel.refreshNotifications()
|
||||
binding.notificationsRefreshLayout.isRefreshing = false
|
||||
}
|
||||
}
|
||||
|
||||
private fun setNotifications(notifications: List<Notification>) {
|
||||
|
|
@ -314,16 +313,12 @@ class NotificationsActivity : BaseActivity(), androidx.swiperefreshlayout.widget
|
|||
// hide view until we have loaded quest data and populated the values
|
||||
view?.visibility = View.GONE
|
||||
|
||||
compositeSubscription.add(
|
||||
inventoryRepository.getQuestContent(data?.questKey ?: "")
|
||||
.firstElement()
|
||||
.subscribe(
|
||||
{
|
||||
updateQuestInvitationView(view, it)
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
)
|
||||
)
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
val questContent = inventoryRepository.getQuestContent(data?.questKey ?: "").firstOrNull()
|
||||
if (questContent != null) {
|
||||
updateQuestInvitationView(view, questContent)
|
||||
}
|
||||
}
|
||||
|
||||
return view
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import com.habitrpg.android.habitica.components.UserComponent
|
|||
import com.habitrpg.android.habitica.data.SocialRepository
|
||||
import com.habitrpg.android.habitica.databinding.ActivityReportMessageBinding
|
||||
import com.habitrpg.common.habitica.extensions.getThemeColor
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.android.habitica.ui.helpers.dismissKeyboard
|
||||
import com.habitrpg.common.habitica.helpers.setMarkdown
|
||||
import javax.inject.Inject
|
||||
|
|
@ -98,7 +98,7 @@ class ReportMessageActivity : BaseActivity() {
|
|||
.doOnError { isReporting = false }
|
||||
.subscribe(
|
||||
{ finish() },
|
||||
RxErrorHandler.handleEmptyError()
|
||||
ExceptionHandler.rx()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,23 +14,25 @@ import androidx.core.content.edit
|
|||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import androidx.fragment.app.FragmentPagerAdapter
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.preference.PreferenceManager
|
||||
import androidx.viewpager.widget.ViewPager
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.common.habitica.api.HostConfig
|
||||
import com.habitrpg.android.habitica.components.UserComponent
|
||||
import com.habitrpg.android.habitica.data.ApiClient
|
||||
import com.habitrpg.android.habitica.data.InventoryRepository
|
||||
import com.habitrpg.android.habitica.data.TaskRepository
|
||||
import com.habitrpg.android.habitica.databinding.ActivitySetupBinding
|
||||
import com.habitrpg.android.habitica.helpers.AmplitudeManager
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.android.habitica.models.user.User
|
||||
import com.habitrpg.android.habitica.ui.fragments.setup.AvatarSetupFragment
|
||||
import com.habitrpg.android.habitica.ui.fragments.setup.TaskSetupFragment
|
||||
import com.habitrpg.android.habitica.ui.fragments.setup.WelcomeFragment
|
||||
import com.habitrpg.common.habitica.api.HostConfig
|
||||
import com.viewpagerindicator.IconPagerAdapter
|
||||
import io.reactivex.rxjava3.core.BackpressureStrategy
|
||||
import kotlinx.coroutines.launch
|
||||
import java.util.Calendar
|
||||
import java.util.Locale
|
||||
import javax.inject.Inject
|
||||
|
|
@ -69,8 +71,12 @@ class SetupActivity : BaseActivity(), ViewPager.OnPageChangeListener {
|
|||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
compositeSubscription.add(userRepository.getUserFlowable().subscribe({ this.onUserReceived(it) }, RxErrorHandler.handleEmptyError()))
|
||||
compositeSubscription.add(userRepository.retrieveUser().subscribe({}, RxErrorHandler.handleEmptyError()))
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
userRepository.getUser().collect { onUserReceived(it) }
|
||||
}
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
userRepository.retrieveUser(true, true)
|
||||
}
|
||||
val additionalData = HashMap<String, Any>()
|
||||
additionalData["status"] = "displayed"
|
||||
AmplitudeManager.sendEvent("setup", AmplitudeManager.EVENT_CATEGORY_BEHAVIOUR, AmplitudeManager.EVENT_HITTYPE_EVENT, additionalData)
|
||||
|
|
@ -80,7 +86,7 @@ class SetupActivity : BaseActivity(), ViewPager.OnPageChangeListener {
|
|||
if (language == currentDeviceLanguage) {
|
||||
compositeSubscription.add(
|
||||
apiClient.registrationLanguage(currentDeviceLanguage)
|
||||
.subscribe({ }, RxErrorHandler.handleEmptyError())
|
||||
.subscribe({ }, ExceptionHandler.rx())
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -135,7 +141,7 @@ class SetupActivity : BaseActivity(), ViewPager.OnPageChangeListener {
|
|||
this.completedSetup = true
|
||||
createdTasks = true
|
||||
newTasks?.let {
|
||||
this.taskRepository.createTasks(it).subscribe({ onUserReceived(user) }, RxErrorHandler.handleEmptyError())
|
||||
this.taskRepository.createTasks(it).subscribe({ onUserReceived(user) }, ExceptionHandler.rx())
|
||||
}
|
||||
} else if (binding.viewPager.currentItem == 0) {
|
||||
|
||||
|
|
@ -211,7 +217,7 @@ class SetupActivity : BaseActivity(), ViewPager.OnPageChangeListener {
|
|||
}
|
||||
startMainActivity()
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
ExceptionHandler.rx()
|
||||
)
|
||||
)
|
||||
return
|
||||
|
|
@ -235,7 +241,7 @@ class SetupActivity : BaseActivity(), ViewPager.OnPageChangeListener {
|
|||
compositeSubscription.add(
|
||||
userRepository.updateUser("profile.name", displayName)
|
||||
.flatMap { userRepository.updateLoginName(username).toFlowable() }
|
||||
.subscribe({ }, RxErrorHandler.handleEmptyError())
|
||||
.subscribe({ }, ExceptionHandler.rx())
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,9 +10,13 @@ import com.habitrpg.android.habitica.R
|
|||
import com.habitrpg.android.habitica.components.UserComponent
|
||||
import com.habitrpg.android.habitica.data.SocialRepository
|
||||
import com.habitrpg.android.habitica.databinding.ActivitySkillMembersBinding
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.android.habitica.ui.adapter.social.PartyMemberRecyclerViewAdapter
|
||||
import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel
|
||||
import kotlinx.coroutines.flow.filterNotNull
|
||||
import kotlinx.coroutines.flow.flatMapConcat
|
||||
import kotlinx.coroutines.flow.flatMapLatest
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
|
|
@ -54,16 +58,16 @@ class SkillMemberActivity : BaseActivity() {
|
|||
setResult(Activity.RESULT_OK, resultIntent)
|
||||
finish()
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
ExceptionHandler.rx()
|
||||
)?.let { compositeSubscription.add(it) }
|
||||
binding.recyclerView.adapter = viewAdapter
|
||||
|
||||
val user = userViewModel.user.value
|
||||
lifecycleScope.launch {
|
||||
socialRepository.getGroupMembers(user?.party?.id ?: "")
|
||||
.collect {
|
||||
viewAdapter?.data = it
|
||||
}
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
userRepository.getUser()
|
||||
.map { it?.party?.id }
|
||||
.filterNotNull()
|
||||
.flatMapLatest { socialRepository.getGroupMembers(it) }
|
||||
.collect { viewAdapter?.data = it }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import com.habitrpg.android.habitica.R
|
|||
import com.habitrpg.android.habitica.components.UserComponent
|
||||
import com.habitrpg.android.habitica.data.TaskRepository
|
||||
import com.habitrpg.android.habitica.databinding.ActivitySkillTasksBinding
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.android.habitica.models.tasks.Task
|
||||
import com.habitrpg.shared.habitica.models.tasks.TaskType
|
||||
import com.habitrpg.android.habitica.modules.AppModule
|
||||
|
|
@ -60,7 +60,7 @@ class SkillTasksActivity : BaseActivity() {
|
|||
1 -> TaskType.DAILY
|
||||
else -> TaskType.TODO
|
||||
}
|
||||
compositeSubscription.add(fragment.getTaskSelectionEvents().subscribe({ task -> taskSelected(task) }, RxErrorHandler.handleEmptyError()))
|
||||
compositeSubscription.add(fragment.getTaskSelectionEvents().subscribe({ task -> taskSelected(task) }, ExceptionHandler.rx()))
|
||||
viewFragmentsDictionary.put(position, fragment)
|
||||
return fragment
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import androidx.core.os.bundleOf
|
|||
import androidx.core.view.children
|
||||
import androidx.core.view.forEachIndexed
|
||||
import androidx.core.widget.NestedScrollView
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.components.UserComponent
|
||||
import com.habitrpg.android.habitica.data.ChallengeRepository
|
||||
|
|
@ -30,7 +31,9 @@ import com.habitrpg.android.habitica.data.TaskRepository
|
|||
import com.habitrpg.android.habitica.databinding.ActivityTaskFormBinding
|
||||
import com.habitrpg.android.habitica.extensions.OnChangeTextWatcher
|
||||
import com.habitrpg.android.habitica.extensions.addCancelButton
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.common.habitica.extensions.dpToPx
|
||||
import com.habitrpg.common.habitica.extensions.getThemeColor
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.android.habitica.helpers.TaskAlarmManager
|
||||
import com.habitrpg.android.habitica.models.Tag
|
||||
import com.habitrpg.android.habitica.models.social.Challenge
|
||||
|
|
@ -46,6 +49,8 @@ import com.habitrpg.shared.habitica.models.tasks.HabitResetOption
|
|||
import com.habitrpg.shared.habitica.models.tasks.TaskType
|
||||
import io.realm.RealmList
|
||||
import java.util.Date
|
||||
import kotlinx.coroutines.launch
|
||||
import java.util.*
|
||||
import javax.inject.Inject
|
||||
|
||||
class TaskFormActivity : BaseActivity() {
|
||||
|
|
@ -160,7 +165,7 @@ class TaskFormActivity : BaseActivity() {
|
|||
tags = it
|
||||
setTagViews()
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
ExceptionHandler.rx()
|
||||
)
|
||||
)
|
||||
userViewModel.user.observe(this) {
|
||||
|
|
@ -216,12 +221,12 @@ class TaskFormActivity : BaseActivity() {
|
|||
binding.challengeNameView.visibility = View.VISIBLE
|
||||
disableEditingForUneditableFieldsInChallengeTask()
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
ExceptionHandler.rx()
|
||||
)
|
||||
)
|
||||
}
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
ExceptionHandler.rx()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
@ -582,7 +587,7 @@ class TaskFormActivity : BaseActivity() {
|
|||
alert.setTitle(R.string.are_you_sure)
|
||||
alert.addButton(R.string.delete_task, true) { _, _ ->
|
||||
if (task?.isValid != true) return@addButton
|
||||
task?.id?.let { taskRepository.deleteTask(it).subscribe({ }, RxErrorHandler.handleEmptyError()) }
|
||||
task?.id?.let { taskRepository.deleteTask(it).subscribe({ }, ExceptionHandler.rx()) }
|
||||
finish()
|
||||
}
|
||||
alert.addCancelButton()
|
||||
|
|
@ -602,12 +607,14 @@ class TaskFormActivity : BaseActivity() {
|
|||
compositeSubscription.add(
|
||||
challengeRepository.leaveChallenge(it, "keep-all")
|
||||
.flatMap { taskRepository.deleteTask(task?.id ?: "") }
|
||||
.flatMap { userRepository.retrieveUser(true, true) }
|
||||
.subscribe(
|
||||
{
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
userRepository.retrieveUser(true, true)
|
||||
}
|
||||
finish()
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
ExceptionHandler.rx()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
@ -616,12 +623,14 @@ class TaskFormActivity : BaseActivity() {
|
|||
challenge?.let {
|
||||
compositeSubscription.add(
|
||||
challengeRepository.leaveChallenge(it, "remove-all")
|
||||
.flatMap { userRepository.retrieveUser(true, true) }
|
||||
.subscribe(
|
||||
{
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
userRepository.retrieveUser(true, true)
|
||||
}
|
||||
finish()
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
ExceptionHandler.rx()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
@ -629,7 +638,7 @@ class TaskFormActivity : BaseActivity() {
|
|||
alert.setExtraCloseButtonVisibility(View.VISIBLE)
|
||||
alert.show()
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
ExceptionHandler.rx()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
@ -648,28 +657,32 @@ class TaskFormActivity : BaseActivity() {
|
|||
dialog.setMessage(this.getString(R.string.broken_challenge_description, taskCount))
|
||||
dialog.addButton(this.getString(R.string.keep_x_tasks, taskCount), true) { _, _ ->
|
||||
taskRepository.unlinkAllTasks(task.challengeID, "keep-all")
|
||||
.flatMap { userRepository.retrieveUser(true, true) }
|
||||
.subscribe(
|
||||
{
|
||||
finish()
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
)
|
||||
{
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
userRepository.retrieveUser(true, true)
|
||||
}
|
||||
finish()
|
||||
},
|
||||
ExceptionHandler.rx()
|
||||
)
|
||||
}
|
||||
dialog.addButton(this.getString(R.string.delete_x_tasks, taskCount), false, true) { _, _ ->
|
||||
taskRepository.unlinkAllTasks(task.challengeID, "remove-all")
|
||||
.flatMap { userRepository.retrieveUser(true, true) }
|
||||
.subscribe(
|
||||
{
|
||||
finish()
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
)
|
||||
{
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
userRepository.retrieveUser(true, true)
|
||||
}
|
||||
finish()
|
||||
},
|
||||
ExceptionHandler.rx()
|
||||
)
|
||||
}
|
||||
dialog.setExtraCloseButtonVisibility(View.VISIBLE)
|
||||
dialog.show()
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
ExceptionHandler.rx()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,17 +6,20 @@ import android.os.Bundle
|
|||
import android.text.method.LinkMovementMethod
|
||||
import android.view.View
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.components.UserComponent
|
||||
import com.habitrpg.android.habitica.databinding.ActivityVerifyUsernameBinding
|
||||
import com.habitrpg.android.habitica.extensions.OnChangeTextWatcher
|
||||
import com.habitrpg.android.habitica.extensions.runDelayed
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper
|
||||
import com.habitrpg.android.habitica.ui.views.HabiticaSnackbar
|
||||
import io.reactivex.rxjava3.core.BackpressureStrategy
|
||||
import io.reactivex.rxjava3.core.Flowable
|
||||
import io.reactivex.rxjava3.subjects.PublishSubject
|
||||
import kotlinx.coroutines.flow.firstOrNull
|
||||
import kotlinx.coroutines.launch
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
class VerifyUsernameActivity : BaseActivity() {
|
||||
|
|
@ -90,25 +93,23 @@ class VerifyUsernameActivity : BaseActivity() {
|
|||
binding.issuesTextView.visibility = View.VISIBLE
|
||||
binding.issuesTextView.text = it.issues.joinToString("\n")
|
||||
}
|
||||
},
|
||||
{ displayNameUsable, usernameUsable -> displayNameUsable && usernameUsable.isUsable }
|
||||
)
|
||||
}
|
||||
) { displayNameUsable, usernameUsable -> displayNameUsable && usernameUsable.isUsable }
|
||||
.subscribe(
|
||||
{
|
||||
binding.confirmUsernameButton.isEnabled = it
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
ExceptionHandler.rx()
|
||||
)
|
||||
)
|
||||
|
||||
compositeSubscription.add(
|
||||
userRepository.getUserFlowable().firstElement().subscribe {
|
||||
binding.displayNameEditText.setText(it.profile?.name)
|
||||
displayNameVerificationEvents.onNext(it.profile?.name ?: "")
|
||||
binding.usernameEditText.setText(it.authentication?.localAuthentication?.username)
|
||||
usernameVerificationEvents.onNext(it.username ?: "")
|
||||
}
|
||||
)
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
val user = userRepository.getUser().firstOrNull()
|
||||
binding.displayNameEditText.setText(user?.profile?.name)
|
||||
displayNameVerificationEvents.onNext(user?.profile?.name ?: "")
|
||||
binding.usernameEditText.setText(user?.authentication?.localAuthentication?.username)
|
||||
usernameVerificationEvents.onNext(user?.username ?: "")
|
||||
}
|
||||
}
|
||||
|
||||
private fun confirmNames() {
|
||||
|
|
@ -118,7 +119,7 @@ class VerifyUsernameActivity : BaseActivity() {
|
|||
.flatMap { userRepository.updateLoginName(binding.usernameEditText.text.toString()).toFlowable() }
|
||||
.doOnComplete { showConfirmationAndFinish() }
|
||||
.doOnEach { binding.confirmUsernameButton.isClickable = true }
|
||||
.subscribe({ }, RxErrorHandler.handleEmptyError())
|
||||
.subscribe({ }, ExceptionHandler.rx())
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import io.reactivex.rxjava3.core.BackpressureStrategy
|
|||
import io.reactivex.rxjava3.core.Flowable
|
||||
import io.reactivex.rxjava3.subjects.PublishSubject
|
||||
|
||||
class InboxAdapter(private var user: User?, private var replyToUser: Member) : PagedListAdapter<ChatMessage, ChatRecyclerViewHolder>(DIFF_CALLBACK) {
|
||||
class InboxAdapter(private var user: User?, private var replyToUser: Member?) : PagedListAdapter<ChatMessage, ChatRecyclerViewHolder>(DIFF_CALLBACK) {
|
||||
private val FIRST_MESSAGE = 0
|
||||
private val NORMAL_MESSAGE = 1
|
||||
|
||||
|
|
@ -43,7 +43,7 @@ class InboxAdapter(private var user: User?, private var replyToUser: Member) : P
|
|||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ChatRecyclerViewHolder {
|
||||
return if (viewType == FIRST_MESSAGE) ChatRecyclerIntroViewHolder(parent.inflate(R.layout.tavern_chat_intro_item), replyToUser.id!!)
|
||||
return if (viewType == FIRST_MESSAGE) ChatRecyclerIntroViewHolder(parent.inflate(R.layout.tavern_chat_intro_item), replyToUser?.id ?: "")
|
||||
else ChatRecyclerMessageViewHolder(parent.inflate(R.layout.chat_item), user?.id ?: "", false)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ import com.habitrpg.android.habitica.R
|
|||
import com.habitrpg.android.habitica.components.UserComponent
|
||||
import com.habitrpg.android.habitica.data.InventoryRepository
|
||||
import com.habitrpg.android.habitica.databinding.FragmentRefreshRecyclerviewBinding
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.android.habitica.ui.adapter.AchievementsAdapter
|
||||
import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel
|
||||
import kotlinx.coroutines.flow.combine
|
||||
|
|
@ -93,7 +93,7 @@ class AchievementsFragment : BaseMainFragment<FragmentRefreshRecyclerviewBinding
|
|||
|
||||
binding?.refreshLayout?.setOnRefreshListener(this)
|
||||
|
||||
lifecycleScope.launch {
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
userRepository.getAchievements().combine(userRepository.getQuestAchievements()) { achievements, questAchievements ->
|
||||
return@combine Pair(achievements, questAchievements)
|
||||
}.combine(userRepository.getQuestAchievements()
|
||||
|
|
@ -171,7 +171,7 @@ class AchievementsFragment : BaseMainFragment<FragmentRefreshRecyclerviewBinding
|
|||
userRepository.retrieveAchievements().subscribe(
|
||||
{
|
||||
},
|
||||
RxErrorHandler.handleEmptyError(), { binding?.refreshLayout?.isRefreshing = false }
|
||||
ExceptionHandler.rx(), { binding?.refreshLayout?.isRefreshing = false }
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import com.habitrpg.android.habitica.HabiticaBaseApplication
|
|||
import com.habitrpg.android.habitica.components.UserComponent
|
||||
import com.habitrpg.android.habitica.data.TutorialRepository
|
||||
import com.habitrpg.android.habitica.helpers.AmplitudeManager
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.android.habitica.ui.activities.MainActivity
|
||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.rxjava3.disposables.CompositeDisposable
|
||||
|
|
@ -80,7 +80,7 @@ abstract class BaseDialogFragment<VB : ViewBinding> : BottomSheetDialogFragment(
|
|||
mainActivity.displayTutorialStep(step, tutorialTexts, tutorialCanBeDeferred)
|
||||
}
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
ExceptionHandler.rx()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import androidx.viewbinding.ViewBinding
|
|||
import com.habitrpg.android.habitica.HabiticaBaseApplication
|
||||
import com.habitrpg.android.habitica.components.UserComponent
|
||||
import com.habitrpg.android.habitica.data.TutorialRepository
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.android.habitica.proxy.AnalyticsManager
|
||||
import com.habitrpg.android.habitica.ui.activities.MainActivity
|
||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
||||
|
|
@ -84,7 +84,7 @@ abstract class BaseFragment<VB : ViewBinding> : Fragment() {
|
|||
mainActivity.displayTutorialStep(step, tutorialTexts, tutorialCanBeDeferred)
|
||||
}
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
ExceptionHandler.rx()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,10 +29,11 @@ import com.habitrpg.android.habitica.databinding.DrawerMainBinding
|
|||
import com.habitrpg.android.habitica.extensions.getMinuteOrSeconds
|
||||
import com.habitrpg.android.habitica.extensions.getRemainingString
|
||||
import com.habitrpg.android.habitica.extensions.getShortRemainingString
|
||||
import com.habitrpg.common.habitica.extensions.getThemeColor
|
||||
import com.habitrpg.android.habitica.extensions.subscribeWithErrorHandler
|
||||
import com.habitrpg.android.habitica.helpers.AppConfigManager
|
||||
import com.habitrpg.android.habitica.helpers.MainNavigationController
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.android.habitica.models.WorldStateEvent
|
||||
import com.habitrpg.android.habitica.models.inventory.Item
|
||||
import com.habitrpg.android.habitica.models.promotions.HabiticaPromotion
|
||||
|
|
@ -140,7 +141,7 @@ class NavigationDrawerFragment : DialogFragment() {
|
|||
{
|
||||
setSelection(it.transitionId, it.bundle, true)
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
ExceptionHandler.rx()
|
||||
)
|
||||
)
|
||||
subscriptions?.add(
|
||||
|
|
@ -151,7 +152,7 @@ class NavigationDrawerFragment : DialogFragment() {
|
|||
}
|
||||
updatePromo()
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
ExceptionHandler.rx()
|
||||
)
|
||||
)
|
||||
|
||||
|
|
@ -172,12 +173,12 @@ class NavigationDrawerFragment : DialogFragment() {
|
|||
updateSeasonalMenuEntries(gearEvent, pair.second)
|
||||
}
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
ExceptionHandler.rx()
|
||||
)
|
||||
)
|
||||
|
||||
if (configManager.enableTeamBoards()) {
|
||||
lifecycleScope.launch {
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
userRepository.getTeamPlans()
|
||||
.distinctUntilChanged()
|
||||
.collect {
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import com.habitrpg.android.habitica.databinding.FragmentStatsBinding
|
|||
import com.habitrpg.android.habitica.extensions.addOkButton
|
||||
import com.habitrpg.common.habitica.extensions.getThemeColor
|
||||
import com.habitrpg.android.habitica.extensions.setScaledPadding
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.android.habitica.helpers.UserStatComputer
|
||||
import com.habitrpg.shared.habitica.models.tasks.Attribute
|
||||
import com.habitrpg.android.habitica.models.user.Stats
|
||||
|
|
@ -132,7 +132,7 @@ class StatsFragment : BaseMainFragment<FragmentStatsBinding>() {
|
|||
|
||||
binding?.automaticAllocationSwitch?.setOnCheckedChangeListener { _, isChecked ->
|
||||
userRepository.updateUser("preferences.automaticAllocation", isChecked)
|
||||
.subscribe({}, RxErrorHandler.handleEmptyError())
|
||||
.subscribe({}, ExceptionHandler.rx())
|
||||
}
|
||||
|
||||
binding?.strengthStatsView?.allocateAction = { allocatePoint(Attribute.STRENGTH) }
|
||||
|
|
@ -163,7 +163,7 @@ class StatsFragment : BaseMainFragment<FragmentStatsBinding>() {
|
|||
userRepository.updateUser(
|
||||
"preferences.allocationMode",
|
||||
allocationMode
|
||||
).subscribe({}, RxErrorHandler.handleEmptyError())
|
||||
).subscribe({}, ExceptionHandler.rx())
|
||||
)
|
||||
binding?.distributeEvenlyButton?.isChecked = allocationMode == Stats.AUTO_ALLOCATE_FLAT
|
||||
binding?.distributeClassButton?.isChecked = allocationMode == Stats.AUTO_ALLOCATE_CLASSBASED
|
||||
|
|
@ -179,7 +179,7 @@ class StatsFragment : BaseMainFragment<FragmentStatsBinding>() {
|
|||
|
||||
private fun allocatePoint(stat: Attribute) {
|
||||
compositeSubscription.add(
|
||||
userRepository.allocatePoint(stat).subscribe({ }, RxErrorHandler.handleEmptyError())
|
||||
userRepository.allocatePoint(stat).subscribe({ }, ExceptionHandler.rx())
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -326,7 +326,7 @@ class StatsFragment : BaseMainFragment<FragmentStatsBinding>() {
|
|||
binding?.constitutionStatsView?.equipmentValue = constitution
|
||||
binding?.perceptionStatsView?.equipmentValue = perception
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
ExceptionHandler.rx()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import android.view.ViewGroup
|
|||
import android.widget.CheckBox
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.view.doOnLayout
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||
import com.google.android.flexbox.AlignItems
|
||||
import com.google.android.flexbox.FlexDirection.ROW
|
||||
|
|
@ -24,7 +25,7 @@ import com.habitrpg.android.habitica.data.InventoryRepository
|
|||
import com.habitrpg.android.habitica.databinding.BottomSheetBackgroundsFilterBinding
|
||||
import com.habitrpg.android.habitica.databinding.FragmentRefreshRecyclerviewBinding
|
||||
import com.habitrpg.android.habitica.extensions.setTintWith
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.android.habitica.models.CustomizationFilter
|
||||
import com.habitrpg.android.habitica.models.inventory.Customization
|
||||
import com.habitrpg.android.habitica.models.user.OwnedCustomization
|
||||
|
|
@ -41,6 +42,7 @@ import io.reactivex.rxjava3.core.BackpressureStrategy
|
|||
import io.reactivex.rxjava3.kotlin.combineLatest
|
||||
import io.reactivex.rxjava3.subjects.BehaviorSubject
|
||||
import io.reactivex.rxjava3.subjects.PublishSubject
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
class AvatarCustomizationFragment :
|
||||
|
|
@ -81,22 +83,19 @@ class AvatarCustomizationFragment :
|
|||
adapter.getSelectCustomizationEvents()
|
||||
.flatMap { customization ->
|
||||
if (customization.type == "background") {
|
||||
val using = if (customization.identifier?.isBlank() != false) {
|
||||
customization.unlockPath + activeCustomization
|
||||
} else customization.unlockPath
|
||||
userRepository.unlockPath(using, 0)
|
||||
.flatMap { userRepository.retrieveUser(false, true, true) }
|
||||
userRepository.unlockPath(customization)
|
||||
//TODO: .flatMap { userRepository.retrieveUser(false, true, true) }
|
||||
} else {
|
||||
userRepository.useCustomization(customization.type ?: "", customization.category, customization.identifier ?: "")
|
||||
}
|
||||
}
|
||||
.subscribe({ }, RxErrorHandler.handleEmptyError())
|
||||
.subscribe({ }, ExceptionHandler.rx())
|
||||
)
|
||||
|
||||
compositeSubscription.add(
|
||||
this.inventoryRepository.getInAppRewards()
|
||||
.map { rewards -> rewards.map { it.key } }
|
||||
.subscribe({ adapter.setPinnedItemKeys(it) }, RxErrorHandler.handleEmptyError())
|
||||
.subscribe({ adapter.setPinnedItemKeys(it) }, ExceptionHandler.rx())
|
||||
)
|
||||
|
||||
return super.onCreateView(inflater, container, savedInstanceState)
|
||||
|
|
@ -212,12 +211,12 @@ class AvatarCustomizationFragment :
|
|||
)
|
||||
}
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
ExceptionHandler.rx()
|
||||
)
|
||||
)
|
||||
if (type == "hair" && (category == "beard" || category == "mustache")) {
|
||||
val otherCategory = if (category == "mustache") "beard" else "mustache"
|
||||
compositeSubscription.add(customizationRepository.getCustomizations(type, otherCategory, true).subscribe({ adapter.additionalSetItems = it }, RxErrorHandler.handleEmptyError()))
|
||||
compositeSubscription.add(customizationRepository.getCustomizations(type, otherCategory, true).subscribe({ adapter.additionalSetItems = it }, ExceptionHandler.rx()))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -270,14 +269,10 @@ class AvatarCustomizationFragment :
|
|||
}
|
||||
|
||||
override fun onRefresh() {
|
||||
compositeSubscription.add(
|
||||
userRepository.retrieveUser(withTasks = false, forced = true).subscribe(
|
||||
{
|
||||
binding?.refreshLayout?.isRefreshing = false
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
)
|
||||
)
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
userRepository.retrieveUser(true, true)
|
||||
binding?.refreshLayout?.isRefreshing = false
|
||||
}
|
||||
}
|
||||
|
||||
fun showFilterDialog() {
|
||||
|
|
|
|||
|
|
@ -4,13 +4,14 @@ import android.os.Bundle
|
|||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.components.UserComponent
|
||||
import com.habitrpg.android.habitica.data.InventoryRepository
|
||||
import com.habitrpg.android.habitica.databinding.FragmentRefreshRecyclerviewBinding
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.android.habitica.models.responses.UnlockResponse
|
||||
import com.habitrpg.android.habitica.models.user.User
|
||||
import com.habitrpg.android.habitica.ui.adapter.CustomizationEquipmentRecyclerViewAdapter
|
||||
|
|
@ -19,6 +20,7 @@ import com.habitrpg.android.habitica.ui.helpers.MarginDecoration
|
|||
import com.habitrpg.android.habitica.ui.helpers.SafeDefaultItemAnimator
|
||||
import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel
|
||||
import io.reactivex.rxjava3.core.Flowable
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
class AvatarEquipmentFragment :
|
||||
|
|
@ -55,14 +57,14 @@ class AvatarEquipmentFragment :
|
|||
val key = (if (equipment.key?.isNotBlank() != true) activeEquipment else equipment.key) ?: ""
|
||||
inventoryRepository.equip(if (userViewModel.user.value?.preferences?.costume == true) "costume" else "equipped", key)
|
||||
}
|
||||
.subscribe({ }, RxErrorHandler.handleEmptyError())
|
||||
.subscribe({ }, ExceptionHandler.rx())
|
||||
)
|
||||
compositeSubscription.add(
|
||||
adapter.getUnlockCustomizationEvents()
|
||||
.flatMap<UnlockResponse> {
|
||||
Flowable.empty()
|
||||
}
|
||||
.subscribe({ }, RxErrorHandler.handleEmptyError())
|
||||
.subscribe({ }, ExceptionHandler.rx())
|
||||
)
|
||||
return super.onCreateView(inflater, container, savedInstanceState)
|
||||
}
|
||||
|
|
@ -110,7 +112,7 @@ class AvatarEquipmentFragment :
|
|||
{
|
||||
adapter.setEquipment(it)
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
ExceptionHandler.rx()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
@ -148,13 +150,9 @@ class AvatarEquipmentFragment :
|
|||
}
|
||||
|
||||
override fun onRefresh() {
|
||||
compositeSubscription.add(
|
||||
userRepository.retrieveUser(false, true).subscribe(
|
||||
{
|
||||
binding?.refreshLayout?.isRefreshing = false
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
)
|
||||
)
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
userRepository.retrieveUser(true, true)
|
||||
binding?.refreshLayout?.isRefreshing = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import android.widget.AdapterView
|
|||
import com.habitrpg.android.habitica.components.UserComponent
|
||||
import com.habitrpg.android.habitica.databinding.FragmentAvatarOverviewBinding
|
||||
import com.habitrpg.android.habitica.helpers.MainNavigationController
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.android.habitica.models.user.User
|
||||
import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment
|
||||
import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel
|
||||
|
|
@ -99,7 +99,7 @@ class AvatarOverviewFragment : BaseMainFragment<FragmentAvatarOverviewBinding>()
|
|||
|
||||
compositeSubscription.add(
|
||||
userRepository.updateUser("preferences.size", newSize)
|
||||
.subscribe({ }, RxErrorHandler.handleEmptyError())
|
||||
.subscribe({ }, ExceptionHandler.rx())
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import android.os.Bundle
|
|||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.recyclerview.widget.DividerItemDecoration
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||
|
|
@ -12,11 +13,12 @@ import com.habitrpg.android.habitica.components.UserComponent
|
|||
import com.habitrpg.android.habitica.data.InventoryRepository
|
||||
import com.habitrpg.android.habitica.databinding.FragmentRefreshRecyclerviewBinding
|
||||
import com.habitrpg.android.habitica.helpers.MainNavigationController
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.android.habitica.ui.adapter.inventory.EquipmentRecyclerViewAdapter
|
||||
import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment
|
||||
import com.habitrpg.common.habitica.helpers.EmptyItem
|
||||
import com.habitrpg.android.habitica.ui.helpers.SafeDefaultItemAnimator
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
class EquipmentDetailFragment :
|
||||
|
|
@ -45,7 +47,7 @@ class EquipmentDetailFragment :
|
|||
): View? {
|
||||
compositeSubscription.add(
|
||||
this.adapter.equipEvents.flatMapMaybe { key -> inventoryRepository.equipGear(key, isCostume ?: false).firstElement() }
|
||||
.subscribe({ }, RxErrorHandler.handleEmptyError())
|
||||
.subscribe({ }, ExceptionHandler.rx())
|
||||
)
|
||||
return super.onCreateView(inflater, container, savedInstanceState)
|
||||
}
|
||||
|
|
@ -80,7 +82,7 @@ class EquipmentDetailFragment :
|
|||
binding?.recyclerView?.addItemDecoration(DividerItemDecoration(getActivity(), DividerItemDecoration.VERTICAL))
|
||||
binding?.recyclerView?.itemAnimator = SafeDefaultItemAnimator()
|
||||
|
||||
type?.let { type -> inventoryRepository.getOwnedEquipment(type).subscribe({ this.adapter.data = it }, RxErrorHandler.handleEmptyError()) }
|
||||
type?.let { type -> inventoryRepository.getOwnedEquipment(type).subscribe({ this.adapter.data = it }, ExceptionHandler.rx()) }
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
|
|
@ -93,13 +95,9 @@ class EquipmentDetailFragment :
|
|||
}
|
||||
|
||||
override fun onRefresh() {
|
||||
compositeSubscription.add(
|
||||
userRepository.retrieveUser(false, true).subscribe(
|
||||
{
|
||||
binding?.refreshLayout?.isRefreshing = false
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
)
|
||||
)
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
userRepository.retrieveUser(true, true)
|
||||
binding?.refreshLayout?.isRefreshing = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,8 +15,8 @@ import com.habitrpg.android.habitica.databinding.FragmentItemsDialogBinding
|
|||
import com.habitrpg.android.habitica.extensions.addCloseButton
|
||||
import com.habitrpg.android.habitica.extensions.observeOnce
|
||||
import com.habitrpg.android.habitica.extensions.subscribeWithErrorHandler
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.android.habitica.helpers.MainNavigationController
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.interactors.FeedPetUseCase
|
||||
import com.habitrpg.android.habitica.interactors.HatchPetUseCase
|
||||
import com.habitrpg.android.habitica.models.inventory.Egg
|
||||
|
|
@ -31,11 +31,11 @@ import com.habitrpg.android.habitica.models.user.User
|
|||
import com.habitrpg.android.habitica.ui.activities.MainActivity
|
||||
import com.habitrpg.android.habitica.ui.adapter.inventory.ItemRecyclerAdapter
|
||||
import com.habitrpg.android.habitica.ui.fragments.BaseDialogFragment
|
||||
import com.habitrpg.common.habitica.helpers.EmptyItem
|
||||
import com.habitrpg.android.habitica.ui.helpers.SafeDefaultItemAnimator
|
||||
import com.habitrpg.common.habitica.extensions.loadImage
|
||||
import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel
|
||||
import com.habitrpg.android.habitica.ui.views.dialogs.OpenedMysteryitemDialog
|
||||
import com.habitrpg.common.habitica.extensions.loadImage
|
||||
import com.habitrpg.common.habitica.helpers.EmptyItem
|
||||
import io.reactivex.rxjava3.disposables.CompositeDisposable
|
||||
import kotlinx.coroutines.flow.firstOrNull
|
||||
import kotlinx.coroutines.flow.map
|
||||
|
|
@ -188,22 +188,24 @@ class ItemDialogFragment : BaseDialogFragment<FragmentItemsDialogBinding>() {
|
|||
compositeSubscription.add(
|
||||
adapter.getSellItemFlowable()
|
||||
.flatMap { item -> inventoryRepository.sellItem(item) }
|
||||
.subscribe({ }, RxErrorHandler.handleEmptyError())
|
||||
.subscribe({ }, ExceptionHandler.rx())
|
||||
)
|
||||
|
||||
compositeSubscription.add(
|
||||
adapter.getQuestInvitationFlowable()
|
||||
.flatMap { quest -> inventoryRepository.inviteToQuest(quest) }
|
||||
.flatMap { socialRepository.retrieveGroup("party") }
|
||||
.subscribe(
|
||||
{
|
||||
if (isModal) {
|
||||
dismiss()
|
||||
} else {
|
||||
MainNavigationController.navigate(R.id.partyFragment)
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
socialRepository.retrieveGroup("party")
|
||||
if (isModal) {
|
||||
dismiss()
|
||||
} else {
|
||||
MainNavigationController.navigate(R.id.partyFragment)
|
||||
}
|
||||
}
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
ExceptionHandler.rx()
|
||||
)
|
||||
)
|
||||
compositeSubscription.add(
|
||||
|
|
@ -219,13 +221,13 @@ class ItemDialogFragment : BaseDialogFragment<FragmentItemsDialogBinding>() {
|
|||
dialog.binding.titleView.text = it.text
|
||||
dialog.binding.descriptionView.text = it.notes
|
||||
dialog.addButton(R.string.equip, true) { _, _ ->
|
||||
inventoryRepository.equip("equipped", it.key ?: "").subscribe({}, RxErrorHandler.handleEmptyError())
|
||||
inventoryRepository.equip("equipped", it.key ?: "").subscribe({}, ExceptionHandler.rx())
|
||||
}
|
||||
dialog.addCloseButton()
|
||||
dialog.enqueue()
|
||||
}
|
||||
}
|
||||
.subscribe({ }, RxErrorHandler.handleEmptyError())
|
||||
.subscribe({ }, ExceptionHandler.rx())
|
||||
)
|
||||
compositeSubscription.add(adapter.hatchPetEvents.subscribeWithErrorHandler { hatchPet(it.first, it.second) })
|
||||
compositeSubscription.add(adapter.feedPetEvents.subscribeWithErrorHandler { feedPet(it) })
|
||||
|
|
@ -285,7 +287,7 @@ class ItemDialogFragment : BaseDialogFragment<FragmentItemsDialogBinding>() {
|
|||
else -> Egg::class.java
|
||||
}
|
||||
itemType?.let { type ->
|
||||
lifecycleScope.launch {
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
inventoryRepository.getOwnedItems(type)
|
||||
.onEach { items ->
|
||||
val filteredItems = if (isFeeding) {
|
||||
|
|
@ -296,7 +298,7 @@ class ItemDialogFragment : BaseDialogFragment<FragmentItemsDialogBinding>() {
|
|||
adapter?.data = filteredItems
|
||||
}
|
||||
.map { items -> items.mapNotNull { it.key } }
|
||||
.map { inventoryRepository.getItemsFlowable(itemClass, it.toTypedArray()).firstOrNull() }
|
||||
.map { inventoryRepository.getItems(itemClass, it.toTypedArray()).firstOrNull() }
|
||||
.collect {
|
||||
val itemMap = mutableMapOf<String, Item>()
|
||||
for (item in it ?: emptyList()) {
|
||||
|
|
@ -306,10 +308,10 @@ class ItemDialogFragment : BaseDialogFragment<FragmentItemsDialogBinding>() {
|
|||
}
|
||||
|
||||
}
|
||||
lifecycleScope.launch {
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
inventoryRepository.getPets().collect { adapter?.setExistingPets(it) }
|
||||
}
|
||||
lifecycleScope.launch {
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
inventoryRepository.getOwnedPets().map { ownedPets ->
|
||||
val petMap = mutableMapOf<String, OwnedPet>()
|
||||
ownedPets.forEach { petMap[it.key ?: ""] = it }
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ import com.habitrpg.android.habitica.extensions.addCloseButton
|
|||
import com.habitrpg.android.habitica.extensions.observeOnce
|
||||
import com.habitrpg.android.habitica.extensions.subscribeWithErrorHandler
|
||||
import com.habitrpg.android.habitica.helpers.MainNavigationController
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.android.habitica.interactors.HatchPetUseCase
|
||||
import com.habitrpg.android.habitica.models.inventory.Egg
|
||||
import com.habitrpg.android.habitica.models.inventory.Food
|
||||
|
|
@ -37,13 +37,13 @@ import com.habitrpg.android.habitica.ui.activities.MainActivity
|
|||
import com.habitrpg.android.habitica.ui.activities.SkillMemberActivity
|
||||
import com.habitrpg.android.habitica.ui.adapter.inventory.ItemRecyclerAdapter
|
||||
import com.habitrpg.android.habitica.ui.fragments.BaseFragment
|
||||
import com.habitrpg.common.habitica.helpers.EmptyItem
|
||||
import com.habitrpg.android.habitica.ui.helpers.SafeDefaultItemAnimator
|
||||
import com.habitrpg.common.habitica.extensions.loadImage
|
||||
import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel
|
||||
import com.habitrpg.android.habitica.ui.views.HabiticaSnackbar
|
||||
import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaAlertDialog
|
||||
import com.habitrpg.android.habitica.ui.views.dialogs.OpenedMysteryitemDialog
|
||||
import com.habitrpg.common.habitica.extensions.loadImage
|
||||
import com.habitrpg.common.habitica.helpers.EmptyItem
|
||||
import io.reactivex.rxjava3.core.Flowable
|
||||
import kotlinx.coroutines.flow.firstOrNull
|
||||
import kotlinx.coroutines.flow.map
|
||||
|
|
@ -147,18 +147,18 @@ class ItemRecyclerFragment : BaseFragment<FragmentItemsBinding>(), SwipeRefreshL
|
|||
compositeSubscription.add(
|
||||
adapter.getSellItemFlowable()
|
||||
.flatMap { item -> inventoryRepository.sellItem(item) }
|
||||
.subscribe({ }, RxErrorHandler.handleEmptyError())
|
||||
.subscribe({ }, ExceptionHandler.rx())
|
||||
)
|
||||
|
||||
compositeSubscription.add(
|
||||
adapter.getQuestInvitationFlowable()
|
||||
.flatMap { quest -> inventoryRepository.inviteToQuest(quest) }
|
||||
.flatMap { socialRepository.retrieveGroup("party") }
|
||||
//.flatMap { socialRepository.retrieveGroup("party") }
|
||||
.subscribe(
|
||||
{
|
||||
MainNavigationController.navigate(R.id.partyFragment)
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
ExceptionHandler.rx()
|
||||
)
|
||||
)
|
||||
compositeSubscription.add(
|
||||
|
|
@ -174,13 +174,13 @@ class ItemRecyclerFragment : BaseFragment<FragmentItemsBinding>(), SwipeRefreshL
|
|||
dialog.binding.titleView.text = it.text
|
||||
dialog.binding.descriptionView.text = it.notes
|
||||
dialog.addButton(R.string.equip, true) { _, _ ->
|
||||
inventoryRepository.equip("equipped", it.key ?: "").subscribe({}, RxErrorHandler.handleEmptyError())
|
||||
inventoryRepository.equip("equipped", it.key ?: "").subscribe({}, ExceptionHandler.rx())
|
||||
}
|
||||
dialog.addCloseButton()
|
||||
dialog.enqueue()
|
||||
}
|
||||
}
|
||||
.subscribe({ }, RxErrorHandler.handleEmptyError())
|
||||
.subscribe({ }, ExceptionHandler.rx())
|
||||
)
|
||||
compositeSubscription.add(adapter.startHatchingEvents.subscribeWithErrorHandler { showHatchingDialog(it) })
|
||||
compositeSubscription.add(adapter.hatchPetEvents.subscribeWithErrorHandler { hatchPet(it.first, it.second) })
|
||||
|
|
@ -211,12 +211,10 @@ class ItemRecyclerFragment : BaseFragment<FragmentItemsBinding>(), SwipeRefreshL
|
|||
|
||||
override fun onRefresh() {
|
||||
binding?.refreshLayout?.isRefreshing = true
|
||||
compositeSubscription.add(
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
userRepository.retrieveUser(true, true)
|
||||
.doOnTerminate {
|
||||
binding?.refreshLayout?.isRefreshing = false
|
||||
}.subscribe({ }, RxErrorHandler.handleEmptyError())
|
||||
)
|
||||
binding?.refreshLayout?.isRefreshing = false
|
||||
}
|
||||
}
|
||||
|
||||
private fun hatchPet(potion: HatchingPotion, egg: Egg) {
|
||||
|
|
@ -237,34 +235,25 @@ class ItemRecyclerFragment : BaseFragment<FragmentItemsBinding>(), SwipeRefreshL
|
|||
alert?.setTitle(R.string.quest_party_required_title)
|
||||
alert?.setMessage(R.string.quest_party_required_description)
|
||||
alert?.addButton(R.string.create_new_party, true, false) { _, _ ->
|
||||
socialRepository.createGroup(
|
||||
getString(R.string.usernames_party, user?.profile?.name),
|
||||
"",
|
||||
user?.id,
|
||||
"party",
|
||||
"",
|
||||
false
|
||||
)
|
||||
.flatMap {
|
||||
userRepository.retrieveUser(false, true)
|
||||
.filter { it.hasParty }
|
||||
.flatMap { socialRepository.retrieveGroup("party") }
|
||||
.flatMap { group1 ->
|
||||
socialRepository.retrieveGroupMembers(
|
||||
group1.id,
|
||||
true
|
||||
)
|
||||
}
|
||||
}
|
||||
.subscribe(
|
||||
{
|
||||
MainNavigationController.navigate(
|
||||
R.id.partyFragment,
|
||||
bundleOf(Pair("partyID", user?.party?.id))
|
||||
)
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
val group = socialRepository.createGroup(
|
||||
getString(R.string.usernames_party, user?.profile?.name),
|
||||
"",
|
||||
user?.id,
|
||||
"party",
|
||||
"",
|
||||
false
|
||||
)
|
||||
val user = userRepository.retrieveUser(false, true)
|
||||
if (user?.hasParty == true) {
|
||||
val party = socialRepository.retrieveGroup("party")
|
||||
socialRepository.retrieveGroupMembers(party?.id ?: "", true)
|
||||
MainNavigationController.navigate(
|
||||
R.id.partyFragment,
|
||||
bundleOf(Pair("partyID", user.party?.id))
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
alert?.addButton(R.string.close, false) { _, _ ->
|
||||
alert.dismiss()
|
||||
|
|
@ -282,14 +271,14 @@ class ItemRecyclerFragment : BaseFragment<FragmentItemsBinding>(), SwipeRefreshL
|
|||
else -> Egg::class.java
|
||||
}
|
||||
itemType?.let { type ->
|
||||
lifecycleScope.launch {
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
inventoryRepository.getOwnedItems(type)
|
||||
.onEach { items ->
|
||||
adapter?.data = items
|
||||
}
|
||||
.map { items -> items.mapNotNull { it.key } }
|
||||
.map {
|
||||
inventoryRepository.getItemsFlowable(itemClass, it.toTypedArray()).firstOrNull()
|
||||
inventoryRepository.getItems(itemClass, it.toTypedArray()).firstOrNull()
|
||||
}
|
||||
.collect {
|
||||
val itemMap = mutableMapOf<String, Item>()
|
||||
|
|
@ -299,10 +288,10 @@ class ItemRecyclerFragment : BaseFragment<FragmentItemsBinding>(), SwipeRefreshL
|
|||
adapter?.items = itemMap
|
||||
}
|
||||
}
|
||||
lifecycleScope.launch {
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
inventoryRepository.getPets().collect { adapter?.setExistingPets(it) }
|
||||
}
|
||||
lifecycleScope.launch {
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
inventoryRepository.getOwnedPets().map { ownedPets ->
|
||||
val petMap = mutableMapOf<String, OwnedPet>()
|
||||
ownedPets.forEach { petMap[it.key ?: ""] = it }
|
||||
|
|
@ -340,7 +329,7 @@ class ItemRecyclerFragment : BaseFragment<FragmentItemsBinding>(), SwipeRefreshL
|
|||
compositeSubscription.add(
|
||||
observable.subscribe(
|
||||
{ this.displaySpecialItemResult(specialItem) },
|
||||
RxErrorHandler.handleEmptyError()
|
||||
ExceptionHandler.rx()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,9 +12,8 @@ import com.habitrpg.android.habitica.components.UserComponent
|
|||
import com.habitrpg.android.habitica.data.InventoryRepository
|
||||
import com.habitrpg.android.habitica.data.SocialRepository
|
||||
import com.habitrpg.android.habitica.databinding.FragmentRefreshRecyclerviewBinding
|
||||
import com.habitrpg.android.habitica.extensions.subscribeWithErrorHandler
|
||||
import com.habitrpg.android.habitica.helpers.AppConfigManager
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.android.habitica.models.shops.Shop
|
||||
import com.habitrpg.android.habitica.models.shops.ShopCategory
|
||||
import com.habitrpg.android.habitica.models.shops.ShopItem
|
||||
|
|
@ -137,16 +136,11 @@ open class ShopFragment : BaseMainFragment<FragmentRefreshRecyclerviewBinding>()
|
|||
updateCurrencyView(it)
|
||||
}
|
||||
|
||||
lifecycleScope.launch {
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
socialRepository.getGroup(Group.TAVERN_ID)
|
||||
.filter { it?.hasActiveQuest == true }
|
||||
.filter { group ->
|
||||
group?.quest?.rageStrikes?.any { it.key == shopIdentifier } ?: false
|
||||
}
|
||||
.filter { group ->
|
||||
group?.quest?.rageStrikes?.filter { it.key == shopIdentifier }
|
||||
?.get(0)?.wasHit == true
|
||||
}
|
||||
.filter { group -> group?.quest?.rageStrikes?.any { it.key == shopIdentifier } ?: false }
|
||||
.filter { group -> group?.quest?.rageStrikes?.filter { it.key == shopIdentifier }?.get(0)?.wasHit == true }
|
||||
.collect {
|
||||
adapter?.shopSpriteSuffix = "_" + it?.quest?.key
|
||||
}
|
||||
|
|
@ -164,7 +158,8 @@ open class ShopFragment : BaseMainFragment<FragmentRefreshRecyclerviewBinding>()
|
|||
val alert = HabiticaAlertDialog(context)
|
||||
alert.setTitle(getString(R.string.class_confirmation_price, classIdentifier, 3))
|
||||
alert.addButton(R.string.choose_class, true) { _, _ ->
|
||||
userRepository.changeClass(classIdentifier).subscribeWithErrorHandler {
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
userRepository.changeClass(classIdentifier)
|
||||
}
|
||||
}
|
||||
alert.addButton(R.string.dialog_go_back, false)
|
||||
|
|
@ -224,7 +219,7 @@ open class ShopFragment : BaseMainFragment<FragmentRefreshRecyclerviewBinding>()
|
|||
},
|
||||
{
|
||||
binding?.recyclerView?.state = RecyclerViewState.FAILED
|
||||
RxErrorHandler.reportError(it)
|
||||
ExceptionHandler.reportError(it)
|
||||
},
|
||||
{
|
||||
binding?.refreshLayout?.isRefreshing = false
|
||||
|
|
@ -234,12 +229,12 @@ open class ShopFragment : BaseMainFragment<FragmentRefreshRecyclerviewBinding>()
|
|||
|
||||
compositeSubscription.add(
|
||||
this.inventoryRepository.getOwnedItems()
|
||||
.subscribe({ adapter?.setOwnedItems(it) }, RxErrorHandler.handleEmptyError())
|
||||
.subscribe({ adapter?.setOwnedItems(it) }, ExceptionHandler.rx())
|
||||
)
|
||||
compositeSubscription.add(
|
||||
this.inventoryRepository.getInAppRewards()
|
||||
.map { rewards -> rewards.map { it.key } }
|
||||
.subscribe({ adapter?.setPinnedItemKeys(it) }, RxErrorHandler.handleEmptyError())
|
||||
.subscribe({ adapter?.setPinnedItemKeys(it) }, ExceptionHandler.rx())
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -289,7 +284,7 @@ open class ShopFragment : BaseMainFragment<FragmentRefreshRecyclerviewBinding>()
|
|||
this.gearCategories = it.categories
|
||||
adapter?.gearCategories = it.categories
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
ExceptionHandler.rx()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import com.habitrpg.android.habitica.components.UserComponent
|
|||
import com.habitrpg.android.habitica.data.InventoryRepository
|
||||
import com.habitrpg.android.habitica.databinding.FragmentRefreshRecyclerviewBinding
|
||||
import com.habitrpg.android.habitica.extensions.getTranslatedType
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.android.habitica.models.inventory.Mount
|
||||
import com.habitrpg.android.habitica.models.inventory.StableSection
|
||||
import com.habitrpg.android.habitica.models.user.OwnedMount
|
||||
|
|
@ -102,7 +102,7 @@ class MountDetailRecyclerFragment :
|
|||
{
|
||||
adapter?.currentMount = it.currentMount
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
ExceptionHandler.rx()
|
||||
)?.let { compositeSubscription.add(it) }
|
||||
}
|
||||
userViewModel.user.observe(viewLifecycleOwner) { adapter?.currentMount = it?.currentMount }
|
||||
|
|
@ -136,7 +136,7 @@ class MountDetailRecyclerFragment :
|
|||
|
||||
private fun loadItems() {
|
||||
if (animalType != null || animalGroup != null) {
|
||||
lifecycleScope.launch {
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
val mounts = inventoryRepository.getMounts(animalType, animalGroup, animalColor).firstOrNull() ?: emptyList()
|
||||
inventoryRepository.getOwnedMounts().map { ownedMounts ->
|
||||
val mountMap = mutableMapOf<String, OwnedMount>()
|
||||
|
|
@ -173,13 +173,9 @@ class MountDetailRecyclerFragment :
|
|||
}
|
||||
|
||||
override fun onRefresh() {
|
||||
compositeSubscription.add(
|
||||
userRepository.retrieveUser(false, true).subscribe(
|
||||
{
|
||||
binding?.refreshLayout?.isRefreshing = false
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
)
|
||||
)
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
userRepository.retrieveUser(false, true)
|
||||
binding?.refreshLayout?.isRefreshing = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import com.habitrpg.android.habitica.data.InventoryRepository
|
|||
import com.habitrpg.android.habitica.databinding.FragmentRefreshRecyclerviewBinding
|
||||
import com.habitrpg.android.habitica.extensions.getTranslatedType
|
||||
import com.habitrpg.android.habitica.extensions.subscribeWithErrorHandler
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.android.habitica.interactors.FeedPetUseCase
|
||||
import com.habitrpg.android.habitica.models.inventory.Egg
|
||||
import com.habitrpg.android.habitica.models.inventory.Food
|
||||
|
|
@ -111,11 +111,11 @@ class PetDetailRecyclerFragment :
|
|||
}
|
||||
binding?.recyclerView?.layoutManager = layoutManager
|
||||
adapter.animalIngredientsRetriever = { animal, callback ->
|
||||
lifecycleScope.launch {
|
||||
val egg = inventoryRepository.getItemsFlowable(Egg::class.java, arrayOf(animal.animal))
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
val egg = inventoryRepository.getItems(Egg::class.java, arrayOf(animal.animal))
|
||||
.firstOrNull()?.firstOrNull() as? Egg
|
||||
val potion =
|
||||
inventoryRepository.getItemsFlowable(HatchingPotion::class.java, arrayOf(animal.color))
|
||||
inventoryRepository.getItems(HatchingPotion::class.java, arrayOf(animal.color))
|
||||
.firstOrNull()?.firstOrNull() as? HatchingPotion
|
||||
callback(Pair(egg, potion))
|
||||
}
|
||||
|
|
@ -131,7 +131,7 @@ class PetDetailRecyclerFragment :
|
|||
{
|
||||
adapter.currentPet = it.currentPet
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
ExceptionHandler.rx()
|
||||
)
|
||||
)
|
||||
userViewModel.user.observe(viewLifecycleOwner) { adapter.currentPet = it?.currentPet }
|
||||
|
|
@ -140,7 +140,7 @@ class PetDetailRecyclerFragment :
|
|||
it.first,
|
||||
it.second
|
||||
)
|
||||
}, RxErrorHandler.handleEmptyError()))
|
||||
}, ExceptionHandler.rx()))
|
||||
|
||||
view.post { setGridSpanCount(view.width) }
|
||||
}
|
||||
|
|
@ -171,7 +171,7 @@ class PetDetailRecyclerFragment :
|
|||
|
||||
private fun loadItems() {
|
||||
if (animalType?.isNotEmpty() == true || animalGroup?.isNotEmpty() == true) {
|
||||
lifecycleScope.launch {
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
inventoryRepository.getOwnedMounts()
|
||||
.map { ownedMounts ->
|
||||
val mountMap = mutableMapOf<String, OwnedMount>()
|
||||
|
|
@ -181,9 +181,9 @@ class PetDetailRecyclerFragment :
|
|||
}
|
||||
compositeSubscription.add(
|
||||
inventoryRepository.getOwnedItems(true)
|
||||
.subscribe({ adapter.setOwnedItems(it) }, RxErrorHandler.handleEmptyError())
|
||||
.subscribe({ adapter.setOwnedItems(it) }, ExceptionHandler.rx())
|
||||
)
|
||||
lifecycleScope.launch {
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
val mounts = inventoryRepository.getMounts(
|
||||
animalType,
|
||||
animalGroup,
|
||||
|
|
@ -256,13 +256,9 @@ class PetDetailRecyclerFragment :
|
|||
}
|
||||
|
||||
override fun onRefresh() {
|
||||
compositeSubscription.add(
|
||||
userRepository.retrieveUser(false, true).subscribe(
|
||||
{
|
||||
binding?.refreshLayout?.isRefreshing = false
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
)
|
||||
)
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
userRepository.retrieveUser(false, true)
|
||||
binding?.refreshLayout?.isRefreshing = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import com.habitrpg.android.habitica.data.InventoryRepository
|
|||
import com.habitrpg.android.habitica.data.UserRepository
|
||||
import com.habitrpg.android.habitica.databinding.FragmentRefreshRecyclerviewBinding
|
||||
import com.habitrpg.android.habitica.helpers.AppConfigManager
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.android.habitica.models.inventory.Egg
|
||||
import com.habitrpg.android.habitica.models.inventory.HatchingPotion
|
||||
import com.habitrpg.android.habitica.ui.adapter.inventory.StableRecyclerAdapter
|
||||
|
|
@ -106,9 +106,9 @@ class StableRecyclerFragment :
|
|||
if (adapter == null) {
|
||||
adapter = StableRecyclerAdapter()
|
||||
adapter?.animalIngredientsRetriever = { animal, callback ->
|
||||
lifecycleScope.launch {
|
||||
val egg = inventoryRepository.getItemsFlowable(Egg::class.java, arrayOf(animal.animal)).firstOrNull()?.firstOrNull() as? Egg
|
||||
val potion = inventoryRepository.getItemsFlowable(HatchingPotion::class.java, arrayOf(animal.color)).firstOrNull()?.firstOrNull() as? HatchingPotion
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
val egg = inventoryRepository.getItems(Egg::class.java, arrayOf(animal.animal)).firstOrNull()?.firstOrNull() as? Egg
|
||||
val potion = inventoryRepository.getItems(HatchingPotion::class.java, arrayOf(animal.color)).firstOrNull()?.firstOrNull() as? HatchingPotion
|
||||
callback(Pair(egg, potion))
|
||||
}
|
||||
}
|
||||
|
|
@ -121,7 +121,7 @@ class StableRecyclerFragment :
|
|||
compositeSubscription.add(
|
||||
it.getEquipFlowable()
|
||||
.flatMap { key -> inventoryRepository.equip(if (itemType == "pets") "pet" else "mount", key) }
|
||||
.subscribe({ }, RxErrorHandler.handleEmptyError())
|
||||
.subscribe({ }, ExceptionHandler.rx())
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -179,13 +179,9 @@ class StableRecyclerFragment :
|
|||
}
|
||||
|
||||
override fun onRefresh() {
|
||||
compositeSubscription.add(
|
||||
userRepository.retrieveUser(false, true).subscribe(
|
||||
{
|
||||
binding?.refreshLayout?.isRefreshing = false
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
)
|
||||
)
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
userRepository.retrieveUser(true, true)
|
||||
binding?.refreshLayout?.isRefreshing = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import androidx.core.content.ContextCompat
|
|||
import androidx.core.content.ContextCompat.getSystemService
|
||||
import androidx.core.util.PatternsCompat
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.preference.EditTextPreference
|
||||
import androidx.preference.Preference
|
||||
import com.google.android.material.textfield.TextInputLayout
|
||||
|
|
@ -22,8 +23,10 @@ import com.habitrpg.android.habitica.R
|
|||
import com.habitrpg.android.habitica.data.ApiClient
|
||||
import com.habitrpg.android.habitica.extensions.addCancelButton
|
||||
import com.habitrpg.android.habitica.extensions.addCloseButton
|
||||
import com.habitrpg.common.habitica.extensions.dpToPx
|
||||
import com.habitrpg.common.habitica.extensions.layoutInflater
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.android.habitica.helpers.MainNavigationController
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.models.user.User
|
||||
import com.habitrpg.android.habitica.ui.activities.FixCharacterValuesActivity
|
||||
import com.habitrpg.android.habitica.ui.fragments.preferences.HabiticaAccountDialog.AccountUpdateConfirmed
|
||||
|
|
@ -36,8 +39,7 @@ import com.habitrpg.android.habitica.ui.views.ValidatingEditText
|
|||
import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaAlertDialog
|
||||
import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaProgressDialog
|
||||
import com.habitrpg.common.habitica.api.HostConfig
|
||||
import com.habitrpg.common.habitica.extensions.dpToPx
|
||||
import com.habitrpg.common.habitica.extensions.layoutInflater
|
||||
import kotlinx.coroutines.launch
|
||||
import retrofit2.HttpException
|
||||
import javax.inject.Inject
|
||||
|
||||
|
|
@ -203,8 +205,11 @@ class AccountPreferenceFragment :
|
|||
dialog.setTitle(R.string.are_you_sure)
|
||||
dialog.addButton(R.string.disconnect, true) { _, _ ->
|
||||
apiClient.disconnectSocial(network)
|
||||
.flatMap { userRepository.retrieveUser(true, true) }
|
||||
.subscribe({ displayDisconnectSuccess(networkName) }, RxErrorHandler.handleEmptyError())
|
||||
.subscribe({
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
userRepository.retrieveUser(true, true)
|
||||
}
|
||||
displayDisconnectSuccess(networkName) }, ExceptionHandler.rx())
|
||||
}
|
||||
dialog.addCancelButton()
|
||||
dialog.show()
|
||||
|
|
@ -252,7 +257,7 @@ class AccountPreferenceFragment :
|
|||
showSingleEntryDialog(value, title) {
|
||||
if (value != it) {
|
||||
userRepository.updateUser(path, it ?: "")
|
||||
.subscribe({}, RxErrorHandler.handleEmptyError())
|
||||
.subscribe({}, ExceptionHandler.rx())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -278,9 +283,7 @@ class AccountPreferenceFragment :
|
|||
userRepository.updatePassword(
|
||||
oldPasswordEditText?.text ?: "",
|
||||
passwordEditText.text ?: "",
|
||||
passwordRepeatEditText.text ?: ""
|
||||
)
|
||||
.flatMap { userRepository.retrieveUser(true, true) }
|
||||
passwordRepeatEditText.text ?: "")
|
||||
.subscribe(
|
||||
{
|
||||
(activity as? SnackbarActivity)?.showSnackbar(
|
||||
|
|
@ -288,7 +291,7 @@ class AccountPreferenceFragment :
|
|||
displayType = HabiticaSnackbar.SnackbarDisplayType.SUCCESS
|
||||
)
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
ExceptionHandler.rx()
|
||||
)
|
||||
dialog.dismiss()
|
||||
}
|
||||
|
|
@ -327,7 +330,6 @@ class AccountPreferenceFragment :
|
|||
if ((showEmail && emailEditText?.isValid != true) || passwordEditText?.isValid != true || passwordRepeatEditText?.isValid != true) return@addButton
|
||||
val email = if (showEmail) emailEditText?.text else user?.authentication?.findFirstSocialEmail()
|
||||
apiClient.registerUser(user?.username ?: "", email ?: "", passwordEditText.text ?: "", passwordRepeatEditText?.text ?: "")
|
||||
.flatMap { userRepository.retrieveUser(true, true) }
|
||||
.subscribe(
|
||||
{
|
||||
(activity as? SnackbarActivity)?.showSnackbar(
|
||||
|
|
@ -335,7 +337,7 @@ class AccountPreferenceFragment :
|
|||
displayType = HabiticaSnackbar.SnackbarDisplayType.SUCCESS
|
||||
)
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
ExceptionHandler.rx()
|
||||
)
|
||||
dialog.dismiss()
|
||||
}
|
||||
|
|
@ -366,12 +368,14 @@ class AccountPreferenceFragment :
|
|||
emailEditText?.showErrorIfNecessary()
|
||||
if (emailEditText?.isValid != true) return@addButton
|
||||
userRepository.updateEmail(emailEditText.text.toString(), passwordEditText?.text.toString())
|
||||
.flatMap { userRepository.retrieveUser(true, true) }
|
||||
.subscribe(
|
||||
{
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
userRepository.retrieveUser(true, true)
|
||||
}
|
||||
configurePreference(findPreference("email"), emailEditText.text.toString())
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
ExceptionHandler.rx()
|
||||
)
|
||||
dialog.dismiss()
|
||||
}
|
||||
|
|
@ -385,7 +389,7 @@ class AccountPreferenceFragment :
|
|||
private fun showLoginNameDialog() {
|
||||
showSingleEntryDialog(user?.username, getString(R.string.username)) {
|
||||
userRepository.updateLoginName(it ?: "")
|
||||
.subscribe({}, RxErrorHandler.handleEmptyError())
|
||||
.subscribe({}, ExceptionHandler.rx())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -450,7 +454,7 @@ class AccountPreferenceFragment :
|
|||
errorDialog?.addCloseButton()
|
||||
errorDialog?.show()
|
||||
}
|
||||
RxErrorHandler.reportError(throwable)
|
||||
ExceptionHandler.reportError(throwable)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
|
@ -475,7 +479,7 @@ class AccountPreferenceFragment :
|
|||
dialog.setMessage(R.string.confirm_username_description)
|
||||
dialog.addButton(R.string.confirm, true) { _, _ ->
|
||||
userRepository.updateLoginName(user?.authentication?.localAuthentication?.username ?: "")
|
||||
.subscribe({ }, RxErrorHandler.handleEmptyError())
|
||||
.subscribe({ }, ExceptionHandler.rx())
|
||||
}
|
||||
dialog.addCancelButton()
|
||||
dialog.show()
|
||||
|
|
@ -483,19 +487,10 @@ class AccountPreferenceFragment :
|
|||
|
||||
private fun resetAccount() {
|
||||
val dialog = HabiticaProgressDialog.show(context, R.string.resetting_account)
|
||||
compositeSubscription.add(
|
||||
userRepository.resetAccount().subscribe({
|
||||
dialog?.dismiss()
|
||||
accountDialog.dismiss()
|
||||
(activity as? SnackbarActivity)?.showSnackbar(
|
||||
content = context?.getString(R.string.account_reset),
|
||||
displayType = HabiticaSnackbar.SnackbarDisplayType.SUCCESS
|
||||
)
|
||||
}) { throwable ->
|
||||
dialog?.dismiss()
|
||||
RxErrorHandler.reportError(throwable)
|
||||
}
|
||||
)
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
userRepository.resetAccount()
|
||||
dialog?.dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
private fun copyValue(name: String, value: CharSequence?) {
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import android.content.SharedPreferences
|
|||
import android.os.Bundle
|
||||
import androidx.preference.CheckBoxPreference
|
||||
import com.habitrpg.android.habitica.HabiticaBaseApplication
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.android.habitica.models.user.User
|
||||
|
||||
class EmailNotificationsPreferencesFragment : BasePreferencesFragment(), SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
|
|
@ -73,7 +73,7 @@ class EmailNotificationsPreferencesFragment : BasePreferencesFragment(), SharedP
|
|||
else -> null
|
||||
}
|
||||
if (pathKey != null) {
|
||||
compositeSubscription.add(userRepository.updateUser("preferences.emailNotifications.$pathKey", sharedPreferences.getBoolean(key, false)).subscribe({ }, RxErrorHandler.handleEmptyError()))
|
||||
compositeSubscription.add(userRepository.updateUser("preferences.emailNotifications.$pathKey", sharedPreferences.getBoolean(key, false)).subscribe({ }, ExceptionHandler.rx()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ import com.habitrpg.android.habitica.data.ApiClient
|
|||
import com.habitrpg.android.habitica.data.ContentRepository
|
||||
import com.habitrpg.android.habitica.extensions.addCancelButton
|
||||
import com.habitrpg.android.habitica.helpers.AppConfigManager
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.android.habitica.helpers.SoundManager
|
||||
import com.habitrpg.android.habitica.helpers.TaskAlarmManager
|
||||
import com.habitrpg.android.habitica.helpers.notifications.PushNotificationManager
|
||||
|
|
@ -69,7 +69,7 @@ class PreferencesFragment : BasePreferencesFragment(), SharedPreferences.OnShare
|
|||
super.onViewCreated(view, savedInstanceState)
|
||||
listView.itemAnimator = null
|
||||
|
||||
userRepository.retrieveTeamPlans().subscribe({}, RxErrorHandler.handleEmptyError())
|
||||
userRepository.retrieveTeamPlans().subscribe({}, ExceptionHandler.rx())
|
||||
}
|
||||
|
||||
override fun setupPreferences() {
|
||||
|
|
@ -152,20 +152,24 @@ class PreferencesFragment : BasePreferencesFragment(), SharedPreferences.OnShare
|
|||
(activity as? SnackbarActivity)?.showSnackbar(
|
||||
content = context?.getString(R.string.reloading_content)
|
||||
)
|
||||
contentRepository.retrieveContent(true).subscribe(
|
||||
{
|
||||
(activity as? SnackbarActivity)?.showSnackbar(
|
||||
content = context?.getString(R.string.reloaded_content),
|
||||
displayType = HabiticaSnackbar.SnackbarDisplayType.SUCCESS
|
||||
)
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
)
|
||||
reloadContent(true)
|
||||
}
|
||||
}
|
||||
return super.onPreferenceTreeClick(preference)
|
||||
}
|
||||
|
||||
private fun reloadContent(withConfirmation: Boolean) {
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
contentRepository.retrieveContent(true)
|
||||
if (withConfirmation) {
|
||||
(activity as? SnackbarActivity)?.showSnackbar(
|
||||
content = context?.getString(R.string.reloaded_content),
|
||||
displayType = HabiticaSnackbar.SnackbarDisplayType.SUCCESS
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun logout() {
|
||||
context?.let { context ->
|
||||
val dialog = HabiticaAlertDialog(context)
|
||||
|
|
@ -180,7 +184,9 @@ class PreferencesFragment : BasePreferencesFragment(), SharedPreferences.OnShare
|
|||
}
|
||||
|
||||
private val classSelectionResult = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
|
||||
userRepository.retrieveUser(true, forced = true)
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
userRepository.retrieveUser(true, true)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String?) {
|
||||
|
|
@ -216,7 +222,7 @@ class PreferencesFragment : BasePreferencesFragment(), SharedPreferences.OnShare
|
|||
"cds_time" -> {
|
||||
val timeval = sharedPreferences.getString("cds_time", "0") ?: "0"
|
||||
val hour = Integer.parseInt(timeval)
|
||||
userRepository.changeCustomDayStart(hour).subscribe({ }, RxErrorHandler.handleEmptyError())
|
||||
userRepository.changeCustomDayStart(hour).subscribe({ }, ExceptionHandler.rx())
|
||||
val preference = findPreference<ListPreference>(key)
|
||||
preference?.summary = preference?.entry
|
||||
}
|
||||
|
|
@ -234,8 +240,7 @@ class PreferencesFragment : BasePreferencesFragment(), SharedPreferences.OnShare
|
|||
}
|
||||
|
||||
userRepository.updateLanguage(languageHelper.languageCode ?: "en")
|
||||
.flatMap { contentRepository.retrieveContent(true) }
|
||||
.subscribe({ }, RxErrorHandler.handleEmptyError())
|
||||
.subscribe({ reloadContent(false) }, ExceptionHandler.rx())
|
||||
|
||||
val intent = Intent(activity, MainActivity::class.java)
|
||||
this.startActivity(intent)
|
||||
|
|
@ -246,7 +251,7 @@ class PreferencesFragment : BasePreferencesFragment(), SharedPreferences.OnShare
|
|||
if (newAudioTheme != null) {
|
||||
compositeSubscription.add(
|
||||
userRepository.updateUser("preferences.sound", newAudioTheme)
|
||||
.subscribe({ }, RxErrorHandler.handleEmptyError())
|
||||
.subscribe({ }, ExceptionHandler.rx())
|
||||
)
|
||||
soundManager.soundTheme = newAudioTheme
|
||||
soundManager.preloadAllFiles()
|
||||
|
|
@ -261,7 +266,7 @@ class PreferencesFragment : BasePreferencesFragment(), SharedPreferences.OnShare
|
|||
activity.reload()
|
||||
}
|
||||
"dailyDueDefaultView" -> userRepository.updateUser("preferences.dailyDueDefaultView", sharedPreferences.getBoolean(key, false))
|
||||
.subscribe({ }, RxErrorHandler.handleEmptyError())
|
||||
.subscribe({ }, ExceptionHandler.rx())
|
||||
"server_url" -> {
|
||||
apiClient.updateServerUrl(sharedPreferences.getString(key, ""))
|
||||
findPreference<Preference>(key)?.summary = sharedPreferences.getString(key, "")
|
||||
|
|
@ -279,7 +284,7 @@ class PreferencesFragment : BasePreferencesFragment(), SharedPreferences.OnShare
|
|||
if (user?.inbox?.optOut != isDisabled) {
|
||||
compositeSubscription.add(
|
||||
userRepository.updateUser("inbox.optOut", isDisabled)
|
||||
.subscribe({ }, RxErrorHandler.handleEmptyError())
|
||||
.subscribe({ }, ExceptionHandler.rx())
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -385,7 +390,7 @@ class PreferencesFragment : BasePreferencesFragment(), SharedPreferences.OnShare
|
|||
} else if (newValue == false && currentIds.contains(team.id)) {
|
||||
currentIds.remove(team.id)
|
||||
}
|
||||
userRepository.updateUser("preferences.tasks.mirrorGroupTasks", currentIds).subscribe({}, RxErrorHandler.handleEmptyError())
|
||||
userRepository.updateUser("preferences.tasks.mirrorGroupTasks", currentIds).subscribe({}, ExceptionHandler.rx())
|
||||
true
|
||||
}
|
||||
groupCategory?.addPreference(newPreference)
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import android.content.SharedPreferences
|
|||
import android.os.Bundle
|
||||
import androidx.preference.CheckBoxPreference
|
||||
import com.habitrpg.android.habitica.HabiticaBaseApplication
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.android.habitica.models.user.User
|
||||
|
||||
class PushNotificationsPreferencesFragment : BasePreferencesFragment(), SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
|
|
@ -75,7 +75,7 @@ class PushNotificationsPreferencesFragment : BasePreferencesFragment(), SharedPr
|
|||
else -> null
|
||||
}
|
||||
if (pathKey != null) {
|
||||
compositeSubscription.add(userRepository.updateUser("preferences.pushNotifications.$pathKey", sharedPreferences.getBoolean(key, false)).subscribe({ }, RxErrorHandler.handleEmptyError()))
|
||||
compositeSubscription.add(userRepository.updateUser("preferences.pushNotifications.$pathKey", sharedPreferences.getBoolean(key, false)).subscribe({ }, ExceptionHandler.rx()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import com.habitrpg.android.habitica.databinding.FragmentGemPurchaseBinding
|
|||
import com.habitrpg.android.habitica.extensions.addCancelButton
|
||||
import com.habitrpg.android.habitica.helpers.AmplitudeManager
|
||||
import com.habitrpg.android.habitica.helpers.AppConfigManager
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.android.habitica.helpers.PurchaseHandler
|
||||
import com.habitrpg.android.habitica.helpers.PurchaseTypes
|
||||
import com.habitrpg.android.habitica.models.promotions.PromoType
|
||||
|
|
@ -99,7 +100,7 @@ class GemsPurchaseFragment : BaseFragment<FragmentGemPurchaseBinding>() {
|
|||
}
|
||||
|
||||
private fun loadInventory() {
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
CoroutineScope(Dispatchers.IO).launch(ExceptionHandler.coroutine()) {
|
||||
val skus = purchaseHandler.getAllGemSKUs()
|
||||
withContext(Dispatchers.Main) {
|
||||
for (sku in skus) {
|
||||
|
|
|
|||
|
|
@ -5,13 +5,15 @@ import android.os.Bundle
|
|||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.habitrpg.android.habitica.components.UserComponent
|
||||
import com.habitrpg.android.habitica.data.SocialRepository
|
||||
import com.habitrpg.android.habitica.data.UserRepository
|
||||
import com.habitrpg.android.habitica.databinding.FragmentGiftGemBalanceBinding
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.android.habitica.models.members.Member
|
||||
import com.habitrpg.android.habitica.ui.fragments.BaseFragment
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
class GiftBalanceGemsFragment : BaseFragment<FragmentGiftGemBalanceBinding>() {
|
||||
|
|
@ -64,14 +66,16 @@ class GiftBalanceGemsFragment : BaseFragment<FragmentGiftGemBalanceBinding>() {
|
|||
giftedMember?.id?.let {
|
||||
compositeSubscription.add(
|
||||
socialRepository.transferGems(it, amount)
|
||||
.flatMap { userRepository.retrieveUser(false, true) }
|
||||
.doOnError {
|
||||
isGifting = false
|
||||
}
|
||||
.subscribe(
|
||||
{
|
||||
activity?.finish()
|
||||
}, RxErrorHandler.handleEmptyError()
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
userRepository.retrieveUser(false)
|
||||
}
|
||||
activity?.finish()
|
||||
}, ExceptionHandler.rx()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,16 +9,17 @@ import com.android.billingclient.api.SkuDetails
|
|||
import com.habitrpg.android.habitica.components.UserComponent
|
||||
import com.habitrpg.android.habitica.data.SocialRepository
|
||||
import com.habitrpg.android.habitica.databinding.FragmentGiftGemPurchaseBinding
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.android.habitica.helpers.PurchaseHandler
|
||||
import com.habitrpg.android.habitica.helpers.PurchaseTypes
|
||||
import com.habitrpg.android.habitica.models.members.Member
|
||||
import com.habitrpg.android.habitica.ui.GemPurchaseOptionsView
|
||||
import com.habitrpg.android.habitica.ui.fragments.BaseFragment
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import javax.inject.Inject
|
||||
|
||||
class GiftPurchaseGemsFragment : BaseFragment<FragmentGiftGemPurchaseBinding>() {
|
||||
|
||||
|
|
@ -54,7 +55,7 @@ class GiftPurchaseGemsFragment : BaseFragment<FragmentGiftGemPurchaseBinding>()
|
|||
}
|
||||
|
||||
fun setupCheckout() {
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
CoroutineScope(Dispatchers.IO).launch(ExceptionHandler.coroutine()) {
|
||||
val skus = purchaseHandler?.getAllGemSKUs()
|
||||
withContext(Dispatchers.Main) {
|
||||
for (sku in skus ?: emptyList()) {
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import android.view.View
|
|||
import android.view.ViewGroup
|
||||
import android.widget.EditText
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.android.billingclient.api.SkuDetails
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.components.UserComponent
|
||||
|
|
@ -15,20 +16,20 @@ import com.habitrpg.android.habitica.data.InventoryRepository
|
|||
import com.habitrpg.android.habitica.data.UserRepository
|
||||
import com.habitrpg.android.habitica.databinding.FragmentSubscriptionBinding
|
||||
import com.habitrpg.android.habitica.extensions.addCancelButton
|
||||
import com.habitrpg.common.habitica.extensions.isUsingNightModeResources
|
||||
import com.habitrpg.common.habitica.extensions.layoutInflater
|
||||
import com.habitrpg.android.habitica.helpers.AmplitudeManager
|
||||
import com.habitrpg.android.habitica.helpers.AppConfigManager
|
||||
import com.habitrpg.android.habitica.helpers.PurchaseHandler
|
||||
import com.habitrpg.android.habitica.helpers.PurchaseTypes
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.android.habitica.models.user.User
|
||||
import com.habitrpg.android.habitica.ui.activities.GiftSubscriptionActivity
|
||||
import com.habitrpg.android.habitica.ui.fragments.BaseFragment
|
||||
import com.habitrpg.android.habitica.ui.fragments.PromoInfoFragment
|
||||
import com.habitrpg.common.habitica.extensions.loadImage
|
||||
import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaAlertDialog
|
||||
import com.habitrpg.android.habitica.ui.views.subscriptions.SubscriptionOptionView
|
||||
import com.habitrpg.common.habitica.extensions.isUsingNightModeResources
|
||||
import com.habitrpg.common.habitica.extensions.layoutInflater
|
||||
import com.habitrpg.common.habitica.extensions.loadImage
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
|
|
@ -93,7 +94,7 @@ class SubscriptionFragment : BaseFragment<FragmentSubscriptionBinding>() {
|
|||
binding?.subBenefitsMysteryItemIcon?.loadImage("shop_set_mystery_${it.key?.split("_")?.last()}")
|
||||
binding?.subBenefitsMysteryItemText?.text = context?.getString(R.string.subscribe_listitem3_description_new, it.text)
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
ExceptionHandler.rx()
|
||||
)
|
||||
)
|
||||
|
||||
|
|
@ -108,15 +109,11 @@ class SubscriptionFragment : BaseFragment<FragmentSubscriptionBinding>() {
|
|||
}
|
||||
|
||||
private fun refresh() {
|
||||
compositeSubscription.add(
|
||||
userRepository.retrieveUser(withTasks = false, forced = true).subscribe(
|
||||
{
|
||||
this.setUser(it)
|
||||
binding?.refreshLayout?.isRefreshing = false
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
)
|
||||
)
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
val user = userRepository.retrieveUser(true)
|
||||
user?.let { setUser(it) }
|
||||
binding?.refreshLayout?.isRefreshing = false
|
||||
}
|
||||
}
|
||||
|
||||
override fun injectFragment(component: UserComponent) {
|
||||
|
|
@ -124,7 +121,7 @@ class SubscriptionFragment : BaseFragment<FragmentSubscriptionBinding>() {
|
|||
}
|
||||
|
||||
fun loadInventory() {
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
CoroutineScope(Dispatchers.IO).launch(ExceptionHandler.coroutine()) {
|
||||
val subscriptions = purchaseHandler.getAllSubscriptionProducts()
|
||||
skus = subscriptions
|
||||
withContext(Dispatchers.Main) {
|
||||
|
|
@ -227,17 +224,16 @@ class SubscriptionFragment : BaseFragment<FragmentSubscriptionBinding>() {
|
|||
}
|
||||
|
||||
private fun checkIfNeedsCancellation() {
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
CoroutineScope(Dispatchers.IO).launch(ExceptionHandler.coroutine()) {
|
||||
val newestSubscription = purchaseHandler.checkForSubscription()
|
||||
if (user?.purchased?.plan?.paymentMethod == "Google" &&
|
||||
user?.purchased?.plan?.isActive == true &&
|
||||
user?.purchased?.plan?.dateTerminated == null &&
|
||||
(newestSubscription?.isAutoRenewing != true)
|
||||
) {
|
||||
compositeSubscription.add(
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
purchaseHandler.cancelSubscription()
|
||||
.subscribe({ }, RxErrorHandler.handleEmptyError())
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,16 +8,20 @@ import android.view.LayoutInflater
|
|||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.components.UserComponent
|
||||
import com.habitrpg.android.habitica.data.UserRepository
|
||||
import com.habitrpg.android.habitica.databinding.FragmentWelcomeBinding
|
||||
import com.habitrpg.android.habitica.extensions.OnChangeTextWatcher
|
||||
import com.habitrpg.android.habitica.extensions.subscribeWithErrorHandler
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.android.habitica.ui.fragments.BaseFragment
|
||||
import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper
|
||||
import io.reactivex.rxjava3.core.BackpressureStrategy
|
||||
import io.reactivex.rxjava3.subjects.PublishSubject
|
||||
import kotlinx.coroutines.flow.firstOrNull
|
||||
import kotlinx.coroutines.launch
|
||||
import java.util.concurrent.TimeUnit
|
||||
import javax.inject.Inject
|
||||
|
||||
|
|
@ -100,14 +104,13 @@ class WelcomeFragment : BaseFragment<FragmentWelcomeBinding>() {
|
|||
}
|
||||
)
|
||||
|
||||
compositeSubscription.add(
|
||||
userRepository.getUserFlowable().firstElement().subscribe {
|
||||
binding?.displayNameEditText?.setText(it.profile?.name)
|
||||
displayNameVerificationEvents.onNext(it.profile?.name ?: "")
|
||||
binding?.usernameEditText?.setText(it.username)
|
||||
usernameVerificationEvents.onNext(it.username ?: "")
|
||||
}
|
||||
)
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
val user = userRepository.getUser().firstOrNull()
|
||||
binding?.displayNameEditText?.setText(user?.profile?.name)
|
||||
displayNameVerificationEvents.onNext(user?.profile?.name ?: "")
|
||||
binding?.usernameEditText?.setText(user?.authentication?.localAuthentication?.username)
|
||||
usernameVerificationEvents.onNext(user?.username ?: "")
|
||||
}
|
||||
}
|
||||
|
||||
override fun injectFragment(component: UserComponent) {
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import androidx.recyclerview.widget.LinearLayoutManager
|
|||
import com.habitrpg.android.habitica.components.UserComponent
|
||||
import com.habitrpg.android.habitica.data.TaskRepository
|
||||
import com.habitrpg.android.habitica.databinding.FragmentRecyclerviewBinding
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.android.habitica.models.tasks.Task
|
||||
import com.habitrpg.android.habitica.ui.adapter.SkillTasksRecyclerViewAdapter
|
||||
import com.habitrpg.android.habitica.ui.fragments.BaseFragment
|
||||
|
|
@ -59,7 +59,7 @@ class SkillTasksRecyclerViewFragment : BaseFragment<FragmentRecyclerviewBinding>
|
|||
{
|
||||
taskSelectionEvents.onNext(it)
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
ExceptionHandler.rx()
|
||||
)
|
||||
)
|
||||
binding?.recyclerView?.adapter = adapter
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import com.habitrpg.android.habitica.R
|
|||
import com.habitrpg.android.habitica.components.UserComponent
|
||||
import com.habitrpg.android.habitica.databinding.FragmentSkillsBinding
|
||||
import com.habitrpg.android.habitica.extensions.subscribeWithErrorHandler
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.android.habitica.models.Skill
|
||||
import com.habitrpg.android.habitica.models.responses.SkillResponse
|
||||
import com.habitrpg.android.habitica.models.user.User
|
||||
|
|
@ -91,7 +91,7 @@ class SkillsFragment : BaseMainFragment<FragmentSkillsBinding>() {
|
|||
allEntries.add(item)
|
||||
}
|
||||
return@combineLatest allEntries
|
||||
}.subscribe({ skills -> adapter?.setSkillList(skills) }, RxErrorHandler.handleEmptyError())
|
||||
}.subscribe({ skills -> adapter?.setSkillList(skills) }, ExceptionHandler.rx())
|
||||
}
|
||||
|
||||
private fun onSkillSelected(skill: Skill) {
|
||||
|
|
@ -128,7 +128,7 @@ class SkillsFragment : BaseMainFragment<FragmentSkillsBinding>() {
|
|||
}
|
||||
}
|
||||
if (response.damage > 0) {
|
||||
lifecycleScope.launch {
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
delay(2000L)
|
||||
if (!isAdded) return@launch
|
||||
showSnackbar(
|
||||
|
|
@ -140,7 +140,9 @@ class SkillsFragment : BaseMainFragment<FragmentSkillsBinding>() {
|
|||
)
|
||||
}
|
||||
}
|
||||
compositeSubscription.add(userRepository.retrieveUser(false).subscribe({ }, RxErrorHandler.handleEmptyError()))
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
userRepository.retrieveUser(true)
|
||||
}
|
||||
}
|
||||
|
||||
private val taskSelectionResult = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
|
||||
|
|
@ -167,7 +169,7 @@ class SkillsFragment : BaseMainFragment<FragmentSkillsBinding>() {
|
|||
compositeSubscription.add(
|
||||
observable.subscribe(
|
||||
{ skillResponse -> this.displaySkillResult(skill, skillResponse) },
|
||||
RxErrorHandler.handleEmptyError()
|
||||
ExceptionHandler.rx()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,8 +13,8 @@ import com.habitrpg.android.habitica.R
|
|||
import com.habitrpg.android.habitica.components.UserComponent
|
||||
import com.habitrpg.android.habitica.databinding.FragmentChatBinding
|
||||
import com.habitrpg.android.habitica.helpers.AppConfigManager
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.android.habitica.helpers.MainNavigationController
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.models.social.ChatMessage
|
||||
import com.habitrpg.android.habitica.ui.activities.FullProfileActivity
|
||||
import com.habitrpg.android.habitica.ui.activities.MainActivity
|
||||
|
|
@ -72,13 +72,13 @@ class ChatFragment() : BaseFragment<FragmentChatBinding>() {
|
|||
compositeSubscription.add(
|
||||
adapter.getUserLabelClickFlowable().subscribe(
|
||||
{ userId -> FullProfileActivity.open(userId) },
|
||||
RxErrorHandler.handleEmptyError()
|
||||
ExceptionHandler.rx()
|
||||
)
|
||||
)
|
||||
compositeSubscription.add(adapter.getDeleteMessageFlowable().subscribe({ this.showDeleteConfirmationDialog(it) }, RxErrorHandler.handleEmptyError()))
|
||||
compositeSubscription.add(adapter.getFlagMessageClickFlowable().subscribe({ this.showFlagConfirmationDialog(it) }, RxErrorHandler.handleEmptyError()))
|
||||
compositeSubscription.add(adapter.getReplyMessageEvents().subscribe({ setReplyTo(it) }, RxErrorHandler.handleEmptyError()))
|
||||
compositeSubscription.add(adapter.getCopyMessageFlowable().subscribe({ this.copyMessageToClipboard(it) }, RxErrorHandler.handleEmptyError()))
|
||||
compositeSubscription.add(adapter.getDeleteMessageFlowable().subscribe({ this.showDeleteConfirmationDialog(it) }, ExceptionHandler.rx()))
|
||||
compositeSubscription.add(adapter.getFlagMessageClickFlowable().subscribe({ this.showFlagConfirmationDialog(it) }, ExceptionHandler.rx()))
|
||||
compositeSubscription.add(adapter.getReplyMessageEvents().subscribe({ setReplyTo(it) }, ExceptionHandler.rx()))
|
||||
compositeSubscription.add(adapter.getCopyMessageFlowable().subscribe({ this.copyMessageToClipboard(it) }, ExceptionHandler.rx()))
|
||||
adapter.onMessageLike = { viewModel?.likeMessage(it) }
|
||||
}
|
||||
|
||||
|
|
@ -141,7 +141,7 @@ class ChatFragment() : BaseFragment<FragmentChatBinding>() {
|
|||
{
|
||||
refresh()
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
ExceptionHandler.rx()
|
||||
)
|
||||
refresh()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import android.view.View
|
|||
import android.view.ViewGroup
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.habitrpg.android.habitica.MainNavDirections
|
||||
import com.habitrpg.android.habitica.R
|
||||
|
|
@ -20,14 +21,13 @@ import com.habitrpg.android.habitica.data.SocialRepository
|
|||
import com.habitrpg.android.habitica.databinding.FragmentInboxMessageListBinding
|
||||
import com.habitrpg.android.habitica.extensions.addOkButton
|
||||
import com.habitrpg.android.habitica.helpers.AppConfigManager
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.android.habitica.helpers.MainNavigationController
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.models.social.ChatMessage
|
||||
import com.habitrpg.android.habitica.ui.activities.FullProfileActivity
|
||||
import com.habitrpg.android.habitica.ui.activities.MainActivity
|
||||
import com.habitrpg.android.habitica.ui.adapter.social.InboxAdapter
|
||||
import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment
|
||||
import com.habitrpg.android.habitica.ui.helpers.KeyboardUtil
|
||||
import com.habitrpg.android.habitica.ui.helpers.SafeDefaultItemAnimator
|
||||
import com.habitrpg.android.habitica.ui.viewmodels.InboxViewModel
|
||||
import com.habitrpg.android.habitica.ui.viewmodels.InboxViewModelFactory
|
||||
|
|
@ -37,8 +37,12 @@ import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaAlertDialog
|
|||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.rxjava3.core.Observable
|
||||
import io.reactivex.rxjava3.disposables.Disposable
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import java.util.concurrent.TimeUnit
|
||||
import javax.inject.Inject
|
||||
import kotlin.time.DurationUnit
|
||||
import kotlin.time.toDuration
|
||||
|
||||
class InboxMessageListFragment : BaseMainFragment<FragmentInboxMessageListBinding>() {
|
||||
|
||||
|
|
@ -84,48 +88,44 @@ class InboxMessageListFragment : BaseMainFragment<FragmentInboxMessageListBindin
|
|||
layoutManager.reverseLayout = true
|
||||
layoutManager.stackFromEnd = false
|
||||
binding?.recyclerView?.layoutManager = layoutManager
|
||||
val observable = if (replyToUserUUID?.isNotBlank() == true) {
|
||||
apiClient.getMember(replyToUserUUID!!)
|
||||
} else {
|
||||
apiClient.getMemberWithUsername(chatRoomUser ?: "")
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
val member = if (replyToUserUUID?.isNotBlank() == true) {
|
||||
apiClient.getMember(replyToUserUUID!!)
|
||||
} else {
|
||||
apiClient.getMemberWithUsername(chatRoomUser ?: "")
|
||||
}
|
||||
setReceivingUser(member?.username, member?.id)
|
||||
activity?.title = member?.displayName
|
||||
chatAdapter = InboxAdapter(viewModel.user.value, member)
|
||||
chatAdapter?.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {
|
||||
override fun onItemRangeInserted(positionStart: Int, itemCount: Int) {
|
||||
if (positionStart == 0) {
|
||||
binding?.recyclerView?.scrollToPosition(0)
|
||||
}
|
||||
}
|
||||
})
|
||||
binding?.recyclerView?.adapter = chatAdapter
|
||||
binding?.recyclerView?.itemAnimator = SafeDefaultItemAnimator()
|
||||
chatAdapter?.let { adapter ->
|
||||
compositeSubscription.add(
|
||||
adapter.getUserLabelClickFlowable().subscribe(
|
||||
{
|
||||
FullProfileActivity.open(it)
|
||||
},
|
||||
ExceptionHandler.rx()
|
||||
)
|
||||
)
|
||||
compositeSubscription.add(adapter.getDeleteMessageFlowable().subscribe({ showDeleteConfirmationDialog(it) }, ExceptionHandler.rx()))
|
||||
compositeSubscription.add(adapter.getFlagMessageClickFlowable().subscribe({ showFlagConfirmationDialog(it) }, ExceptionHandler.rx()))
|
||||
compositeSubscription.add(adapter.getCopyMessageFlowable().subscribe({ copyMessageToClipboard(it) }, ExceptionHandler.rx()))
|
||||
}
|
||||
}
|
||||
|
||||
viewModel.messages.observe(viewLifecycleOwner) {
|
||||
markMessagesAsRead(it)
|
||||
chatAdapter?.submitList(it)
|
||||
}
|
||||
compositeSubscription.add(
|
||||
observable.subscribe(
|
||||
{ member ->
|
||||
setReceivingUser(member.username, member.id)
|
||||
activity?.title = member.displayName
|
||||
chatAdapter = InboxAdapter(viewModel.user.value, member)
|
||||
chatAdapter?.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {
|
||||
override fun onItemRangeInserted(positionStart: Int, itemCount: Int) {
|
||||
if (positionStart == 0) {
|
||||
binding?.recyclerView?.scrollToPosition(0)
|
||||
}
|
||||
}
|
||||
})
|
||||
viewModel.messages.observe(this.viewLifecycleOwner) {
|
||||
markMessagesAsRead(it)
|
||||
chatAdapter?.submitList(it)
|
||||
}
|
||||
|
||||
binding?.recyclerView?.adapter = chatAdapter
|
||||
binding?.recyclerView?.itemAnimator = SafeDefaultItemAnimator()
|
||||
chatAdapter?.let { adapter ->
|
||||
compositeSubscription.add(
|
||||
adapter.getUserLabelClickFlowable().subscribe(
|
||||
{
|
||||
FullProfileActivity.open(it)
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
)
|
||||
)
|
||||
compositeSubscription.add(adapter.getDeleteMessageFlowable().subscribe({ this.showDeleteConfirmationDialog(it) }, RxErrorHandler.handleEmptyError()))
|
||||
compositeSubscription.add(adapter.getFlagMessageClickFlowable().subscribe({ this.showFlagConfirmationDialog(it) }, RxErrorHandler.handleEmptyError()))
|
||||
compositeSubscription.add(adapter.getCopyMessageFlowable().subscribe({ this.copyMessageToClipboard(it) }, RxErrorHandler.handleEmptyError()))
|
||||
}
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
)
|
||||
)
|
||||
|
||||
binding?.chatBarView?.sendAction = { sendMessage(it) }
|
||||
binding?.chatBarView?.maxChatLength = configManager.maxChatLength()
|
||||
|
|
@ -196,7 +196,7 @@ class InboxMessageListFragment : BaseMainFragment<FragmentInboxMessageListBindin
|
|||
{
|
||||
refreshConversation()
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
ExceptionHandler.rx()
|
||||
)
|
||||
refreshConversation()
|
||||
}
|
||||
|
|
@ -210,39 +210,29 @@ class InboxMessageListFragment : BaseMainFragment<FragmentInboxMessageListBindin
|
|||
|
||||
private fun refreshConversation() {
|
||||
if (viewModel.memberID?.isNotBlank() != true) { return }
|
||||
compositeSubscription.add(
|
||||
this.socialRepository.retrieveInboxMessages(replyToUserUUID ?: "", 0)
|
||||
.subscribe(
|
||||
{}, RxErrorHandler.handleEmptyError(),
|
||||
{
|
||||
viewModel.invalidateDataSource()
|
||||
}
|
||||
)
|
||||
)
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
socialRepository.retrieveInboxMessages(replyToUserUUID ?: "", 0)
|
||||
viewModel.invalidateDataSource()
|
||||
}
|
||||
}
|
||||
|
||||
private fun sendMessage(chatText: String) {
|
||||
viewModel.memberID?.let { userID ->
|
||||
socialRepository.postPrivateMessage(userID, chatText)
|
||||
.delay(200, TimeUnit.MILLISECONDS)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(
|
||||
{
|
||||
viewModel.invalidateDataSource()
|
||||
},
|
||||
{ error ->
|
||||
RxErrorHandler.reportError(error)
|
||||
binding?.let {
|
||||
val alert = HabiticaAlertDialog(it.chatBarView.context)
|
||||
alert.setTitle("You cannot reply to this conversation")
|
||||
alert.setMessage("This user is unable to receive your private message")
|
||||
alert.addOkButton()
|
||||
alert.show()
|
||||
}
|
||||
binding?.chatBarView?.message = chatText
|
||||
}
|
||||
)
|
||||
KeyboardUtil.dismissKeyboard(getActivity())
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine { error ->
|
||||
ExceptionHandler.reportError(error)
|
||||
binding?.let {
|
||||
val alert = HabiticaAlertDialog(it.chatBarView.context)
|
||||
alert.setTitle("You cannot reply to this conversation")
|
||||
alert.setMessage("This user is unable to receive your private message")
|
||||
alert.addOkButton()
|
||||
alert.show()
|
||||
}
|
||||
binding?.chatBarView?.message = chatText
|
||||
}) {
|
||||
socialRepository.postPrivateMessage(userID, chatText)
|
||||
delay(200.toDuration(DurationUnit.MILLISECONDS))
|
||||
viewModel.invalidateDataSource()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -274,7 +264,7 @@ class InboxMessageListFragment : BaseMainFragment<FragmentInboxMessageListBindin
|
|||
.setTitle(R.string.confirm_delete_tag_title)
|
||||
.setMessage(R.string.confirm_delete_tag_message)
|
||||
.setIcon(android.R.drawable.ic_dialog_alert)
|
||||
.setPositiveButton(R.string.yes) { _, _ -> socialRepository.deleteMessage(chatMessage).subscribe({ }, RxErrorHandler.handleEmptyError()) }
|
||||
.setPositiveButton(R.string.yes) { _, _ -> socialRepository.deleteMessage(chatMessage).subscribe({ }, ExceptionHandler.rx()) }
|
||||
.setNegativeButton(R.string.no, null).show()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import android.view.MenuItem
|
|||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.TextView
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.habitrpg.android.habitica.BuildConfig
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.components.UserComponent
|
||||
|
|
@ -17,15 +18,16 @@ import com.habitrpg.android.habitica.databinding.DialogChooseMessageRecipientBin
|
|||
import com.habitrpg.android.habitica.databinding.FragmentInboxBinding
|
||||
import com.habitrpg.android.habitica.extensions.getAgoString
|
||||
import com.habitrpg.android.habitica.helpers.AppConfigManager
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.android.habitica.helpers.MainNavigationController
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.models.social.InboxConversation
|
||||
import com.habitrpg.common.habitica.views.AvatarView
|
||||
import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment
|
||||
import com.habitrpg.android.habitica.ui.helpers.dismissKeyboard
|
||||
import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel
|
||||
import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaAlertDialog
|
||||
import com.habitrpg.android.habitica.ui.views.UsernameLabel
|
||||
import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaAlertDialog
|
||||
import com.habitrpg.common.habitica.views.AvatarView
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
class InboxOverviewFragment : BaseMainFragment<FragmentInboxBinding>(), androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener, View.OnClickListener {
|
||||
|
|
@ -49,7 +51,7 @@ class InboxOverviewFragment : BaseMainFragment<FragmentInboxBinding>(), androidx
|
|||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
this.hidesToolbar = true
|
||||
compositeSubscription.add(this.socialRepository.markPrivateMessagesRead(null).subscribe({ }, RxErrorHandler.handleEmptyError()))
|
||||
compositeSubscription.add(this.socialRepository.markPrivateMessagesRead(null).subscribe({ }, ExceptionHandler.rx()))
|
||||
return super.onCreateView(inflater, container, savedInstanceState)
|
||||
}
|
||||
|
||||
|
|
@ -67,14 +69,11 @@ class InboxOverviewFragment : BaseMainFragment<FragmentInboxBinding>(), androidx
|
|||
}
|
||||
|
||||
private fun loadMessages() {
|
||||
compositeSubscription.add(
|
||||
socialRepository.getInboxConversations().subscribe(
|
||||
{
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
socialRepository.getInboxConversations().collect {
|
||||
setInboxMessages(it)
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
|
|
@ -116,18 +115,17 @@ class InboxOverviewFragment : BaseMainFragment<FragmentInboxBinding>(), androidx
|
|||
binding.errorTextView.visibility = View.GONE
|
||||
binding.progressCircular.visibility = View.VISIBLE
|
||||
val username = binding.uuidEditText.text?.toString() ?: ""
|
||||
socialRepository.getMemberWithUsername(username)
|
||||
.subscribe(
|
||||
{
|
||||
alert.dismiss()
|
||||
openInboxMessages("", username)
|
||||
binding.progressCircular.visibility = View.GONE
|
||||
},
|
||||
{
|
||||
binding.errorTextView.visibility = View.VISIBLE
|
||||
binding.progressCircular.visibility = View.GONE
|
||||
}
|
||||
)
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
val member = socialRepository.retrieveMemberWithUsername(username)
|
||||
if (member != null) {
|
||||
alert.dismiss()
|
||||
openInboxMessages("", username)
|
||||
binding.progressCircular.visibility = View.GONE
|
||||
} else {
|
||||
binding.errorTextView.visibility = View.VISIBLE
|
||||
binding.progressCircular.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
}
|
||||
alert.addButton(getString(R.string.action_cancel), false) { _, _ ->
|
||||
thisActivity.dismissKeyboard()
|
||||
|
|
@ -149,7 +147,7 @@ class InboxOverviewFragment : BaseMainFragment<FragmentInboxBinding>(), androidx
|
|||
{
|
||||
binding?.inboxRefreshLayout?.isRefreshing = false
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
ExceptionHandler.rx()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,14 +10,15 @@ import android.view.ViewGroup
|
|||
import android.widget.TextView
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.text.toHtml
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.components.UserComponent
|
||||
import com.habitrpg.android.habitica.data.InventoryRepository
|
||||
import com.habitrpg.android.habitica.data.SocialRepository
|
||||
import com.habitrpg.android.habitica.databinding.FragmentQuestDetailBinding
|
||||
import com.habitrpg.android.habitica.extensions.fromHtml
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.android.habitica.helpers.HapticFeedbackManager
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.models.inventory.Quest
|
||||
import com.habitrpg.android.habitica.models.inventory.QuestContent
|
||||
import com.habitrpg.android.habitica.models.members.Member
|
||||
|
|
@ -28,6 +29,12 @@ import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel
|
|||
import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaAlertDialog
|
||||
import com.habitrpg.common.habitica.extensions.loadImage
|
||||
import com.habitrpg.common.habitica.helpers.MarkdownParser
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.filterNotNull
|
||||
import kotlinx.coroutines.flow.flatMapLatest
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Named
|
||||
|
||||
|
|
@ -72,30 +79,22 @@ class QuestDetailFragment : BaseMainFragment<FragmentQuestDetailBinding>() {
|
|||
binding?.questCancelButton?.setOnClickListener { onQuestCancel() }
|
||||
binding?.questLeaveButton?.setOnClickListener { onQuestLeave() }
|
||||
|
||||
compositeSubscription.add(
|
||||
userRepository.getUserFlowable()
|
||||
.map {
|
||||
it.party?.id ?: ""
|
||||
}
|
||||
.skipWhile { it.isBlank() }
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
userRepository.getUser()
|
||||
.map { it?.party?.id }
|
||||
.filterNotNull()
|
||||
.distinctUntilChanged()
|
||||
.flatMap { socialRepository.getGroupFlowable(it) }
|
||||
.doOnNext { updateParty(it) }
|
||||
.map {
|
||||
it.quest?.key ?: ""
|
||||
}
|
||||
.skipWhile {
|
||||
it.isBlank()
|
||||
}
|
||||
.flatMapLatest { socialRepository.getGroup(it) }
|
||||
.onEach { updateParty(it) }
|
||||
.map { it?.quest?.key }
|
||||
.filterNotNull()
|
||||
.distinctUntilChanged()
|
||||
.flatMap { inventoryRepository.getQuestContent(it) }
|
||||
.subscribe(
|
||||
{
|
||||
updateQuestContent(it)
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
)
|
||||
)
|
||||
.flatMapLatest { inventoryRepository.getQuestContent(it) }
|
||||
.filterNotNull()
|
||||
.collect {
|
||||
updateQuestContent(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateParty(group: Group?) {
|
||||
|
|
@ -105,16 +104,12 @@ class QuestDetailFragment : BaseMainFragment<FragmentQuestDetailBinding>() {
|
|||
party = group
|
||||
quest = group.quest
|
||||
setQuestParticipants(group.quest?.participants)
|
||||
compositeSubscription.add(
|
||||
socialRepository.getMember(quest?.leader).subscribe(
|
||||
{ member ->
|
||||
if (context != null && binding?.questLeaderView != null) {
|
||||
binding?.questLeaderView?.text = context?.getString(R.string.quest_leader_header, member.displayName)
|
||||
}
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
)
|
||||
)
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
val member = socialRepository.retrieveMember(quest?.leader)
|
||||
if (context != null && binding?.questLeaderView != null) {
|
||||
binding?.questLeaderView?.text = context?.getString(R.string.quest_leader_header, member?.displayName)
|
||||
}
|
||||
}
|
||||
|
||||
val user = userViewModel.user.value
|
||||
if (binding?.questResponseWrapper != null) {
|
||||
|
|
@ -223,7 +218,7 @@ class QuestDetailFragment : BaseMainFragment<FragmentQuestDetailBinding>() {
|
|||
val party = party
|
||||
if (party != null) {
|
||||
socialRepository.forceStartQuest(party)
|
||||
.subscribe({ }, RxErrorHandler.handleEmptyError())
|
||||
.subscribe({ }, ExceptionHandler.rx())
|
||||
}
|
||||
}
|
||||
alert.addButton(R.string.no, false)
|
||||
|
|
@ -239,10 +234,12 @@ class QuestDetailFragment : BaseMainFragment<FragmentQuestDetailBinding>() {
|
|||
.setMessage(R.string.quest_abort_message)
|
||||
.setPositiveButton(R.string.yes) { _, _ ->
|
||||
party?.id?.let { partyID ->
|
||||
@Suppress("DEPRECATION")
|
||||
socialRepository.abortQuest(partyID)
|
||||
.flatMap { userRepository.retrieveUser() }
|
||||
.subscribe({ getActivity()?.supportFragmentManager?.popBackStack() }, RxErrorHandler.handleEmptyError())
|
||||
.subscribe({
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
userRepository.retrieveUser(true)
|
||||
}
|
||||
getActivity()?.supportFragmentManager?.popBackStack() }, ExceptionHandler.rx())
|
||||
}
|
||||
}.setNegativeButton(R.string.no) { _, _ -> }
|
||||
builder.show()
|
||||
|
|
@ -251,10 +248,13 @@ class QuestDetailFragment : BaseMainFragment<FragmentQuestDetailBinding>() {
|
|||
alert.setMessage(R.string.quest_cancel_message)
|
||||
alert.addButton(R.string.yes, true) { _, _ ->
|
||||
party?.id?.let { partyID ->
|
||||
@Suppress("DEPRECATION")
|
||||
socialRepository.cancelQuest(partyID)
|
||||
.flatMap { userRepository.retrieveUser() }
|
||||
.subscribe({ getActivity()?.supportFragmentManager?.popBackStack() }, RxErrorHandler.handleEmptyError())
|
||||
.subscribe({
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
userRepository.retrieveUser(true)
|
||||
}
|
||||
getActivity()?.supportFragmentManager?.popBackStack()
|
||||
}, ExceptionHandler.rx())
|
||||
}
|
||||
}
|
||||
alert.addButton(R.string.no, false)
|
||||
|
|
@ -269,11 +269,13 @@ class QuestDetailFragment : BaseMainFragment<FragmentQuestDetailBinding>() {
|
|||
.setMessage(if (quest?.active == true) R.string.quest_leave_message else R.string.quest_leave_message_nostart)
|
||||
.setPositiveButton(R.string.yes) { _, _ ->
|
||||
party?.id?.let { partyID ->
|
||||
@Suppress("DEPRECATION")
|
||||
socialRepository.leaveQuest(partyID)
|
||||
.flatMap { userRepository.retrieveUser() }
|
||||
.flatMap { socialRepository.retrieveGroup(partyID) }
|
||||
.subscribe({ getActivity()?.supportFragmentManager?.popBackStack() }, RxErrorHandler.handleEmptyError())
|
||||
.subscribe({
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
socialRepository.retrieveGroup(partyID)
|
||||
userRepository.retrieveUser(true)
|
||||
}
|
||||
getActivity()?.supportFragmentManager?.popBackStack() }, ExceptionHandler.rx())
|
||||
}
|
||||
}.setNegativeButton(R.string.no) { _, _ -> }
|
||||
builder.show()
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import android.widget.FrameLayout
|
|||
import android.widget.TextView
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.components.UserComponent
|
||||
import com.habitrpg.android.habitica.data.InventoryRepository
|
||||
|
|
@ -19,8 +20,8 @@ import com.habitrpg.android.habitica.data.UserRepository
|
|||
import com.habitrpg.android.habitica.databinding.FragmentTavernDetailBinding
|
||||
import com.habitrpg.android.habitica.extensions.setTintWith
|
||||
import com.habitrpg.android.habitica.helpers.AppConfigManager
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.android.habitica.helpers.MainNavigationController
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.models.inventory.QuestContent
|
||||
import com.habitrpg.android.habitica.models.social.Group
|
||||
import com.habitrpg.android.habitica.models.user.User
|
||||
|
|
@ -29,6 +30,11 @@ import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel
|
|||
import com.habitrpg.android.habitica.ui.views.UsernameLabel
|
||||
import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaAlertDialog
|
||||
import com.habitrpg.common.habitica.models.PlayerTier
|
||||
import kotlinx.coroutines.flow.filter
|
||||
import kotlinx.coroutines.flow.firstOrNull
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
class TavernDetailFragment : BaseFragment<FragmentTavernDetailBinding>() {
|
||||
|
|
@ -73,33 +79,30 @@ class TavernDetailFragment : BaseFragment<FragmentTavernDetailBinding>() {
|
|||
addPlayerTiers()
|
||||
bindButtons()
|
||||
|
||||
compositeSubscription.add(
|
||||
socialRepository.getGroupFlowable(Group.TAVERN_ID)
|
||||
.doOnNext { if (!it.hasActiveQuest) binding?.worldBossSection?.visibility = View.GONE }
|
||||
.filter { it.hasActiveQuest }
|
||||
.doOnNext {
|
||||
binding?.questProgressView?.progress = it.quest
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
socialRepository.getGroup(Group.TAVERN_ID)
|
||||
.onEach { if (it?.hasActiveQuest == false) binding?.worldBossSection?.visibility = View.GONE }
|
||||
.filter { it != null && it.hasActiveQuest }
|
||||
.onEach {
|
||||
binding?.questProgressView?.progress = it?.quest
|
||||
binding?.shopHeader?.descriptionView?.setText(R.string.tavern_description_world_boss)
|
||||
val filtered = it.quest?.rageStrikes?.filter { strike -> strike.key == "tavern" }
|
||||
if (filtered?.size ?: 0 > 0 && filtered?.get(0)?.wasHit == true) {
|
||||
val filtered = it?.quest?.rageStrikes?.filter { strike -> strike.key == "tavern" }
|
||||
if ((filtered?.size ?: 0) > 0 && filtered?.get(0)?.wasHit == true) {
|
||||
val key = it.quest?.key
|
||||
if (key != null) {
|
||||
shopSpriteSuffix = key
|
||||
}
|
||||
}
|
||||
}
|
||||
.flatMapMaybe { inventoryRepository.getQuestContent(it.quest?.key ?: "").firstElement() }
|
||||
.subscribe(
|
||||
{
|
||||
binding?.questProgressView?.quest = it
|
||||
binding?.worldBossSection?.visibility = View.VISIBLE
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
)
|
||||
)
|
||||
|
||||
compositeSubscription.add(socialRepository.retrieveGroup(Group.TAVERN_ID).subscribe({ }, RxErrorHandler.handleEmptyError()))
|
||||
.map { inventoryRepository.getQuestContent(it?.quest?.key ?: "").firstOrNull() }
|
||||
.collect {
|
||||
binding?.questProgressView?.quest = it
|
||||
binding?.worldBossSection?.visibility = View.VISIBLE
|
||||
}
|
||||
}
|
||||
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) { socialRepository.retrieveGroup(Group.TAVERN_ID) }
|
||||
|
||||
user?.let { binding?.questProgressView?.configure(it) }
|
||||
}
|
||||
|
||||
|
|
@ -112,7 +115,9 @@ class TavernDetailFragment : BaseFragment<FragmentTavernDetailBinding>() {
|
|||
|
||||
private fun bindButtons() {
|
||||
binding?.innButton?.setOnClickListener {
|
||||
user?.let { user -> userRepository.sleep(user).subscribe({ }, RxErrorHandler.handleEmptyError()) }
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
user?.let { user -> userRepository.sleep(user) }
|
||||
}
|
||||
}
|
||||
binding?.guidelinesButton?.setOnClickListener {
|
||||
MainNavigationController.navigate(R.id.guidelinesActivity)
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import android.view.MenuItem
|
|||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.net.toUri
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.components.UserComponent
|
||||
import com.habitrpg.android.habitica.data.ChallengeRepository
|
||||
|
|
@ -19,8 +20,8 @@ import com.habitrpg.android.habitica.databinding.DialogChallengeDetailTaskGroupB
|
|||
import com.habitrpg.android.habitica.databinding.FragmentChallengeDetailBinding
|
||||
import com.habitrpg.android.habitica.extensions.addCloseButton
|
||||
import com.habitrpg.android.habitica.extensions.inflate
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.android.habitica.helpers.MainNavigationController
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.models.members.Member
|
||||
import com.habitrpg.android.habitica.models.social.Challenge
|
||||
import com.habitrpg.android.habitica.models.tasks.Task
|
||||
|
|
@ -32,11 +33,12 @@ import com.habitrpg.android.habitica.ui.viewHolders.tasks.HabitViewHolder
|
|||
import com.habitrpg.android.habitica.ui.viewHolders.tasks.RewardViewHolder
|
||||
import com.habitrpg.android.habitica.ui.viewHolders.tasks.TodoViewHolder
|
||||
import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel
|
||||
import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper
|
||||
import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaAlertDialog
|
||||
import com.habitrpg.common.habitica.helpers.EmojiParser
|
||||
import com.habitrpg.common.habitica.helpers.setMarkdown
|
||||
import com.habitrpg.shared.habitica.models.tasks.TaskType
|
||||
import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper
|
||||
import kotlinx.coroutines.launch
|
||||
import retrofit2.HttpException
|
||||
import javax.inject.Inject
|
||||
|
||||
|
|
@ -101,10 +103,11 @@ class ChallengeDetailFragment : BaseMainFragment<FragmentChallengeDetailBinding>
|
|||
return@map (it.leaderId ?: "")
|
||||
}
|
||||
.filter { it.isNotEmpty() }
|
||||
.flatMap { creatorID ->
|
||||
return@flatMap socialRepository.getMember(creatorID)
|
||||
}
|
||||
.subscribe({ set(it) }, RxErrorHandler.handleEmptyError())
|
||||
.subscribe({
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
set(socialRepository.retrieveMember(it))
|
||||
}
|
||||
}, ExceptionHandler.rx())
|
||||
)
|
||||
compositeSubscription.add(
|
||||
challengeRepository.getChallengeTasks(id).subscribe(
|
||||
|
|
@ -142,7 +145,7 @@ class ChallengeDetailFragment : BaseMainFragment<FragmentChallengeDetailBinding>
|
|||
addRewards(rewards)
|
||||
}
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
ExceptionHandler.rx()
|
||||
)
|
||||
)
|
||||
|
||||
|
|
@ -151,7 +154,7 @@ class ChallengeDetailFragment : BaseMainFragment<FragmentChallengeDetailBinding>
|
|||
{ isMember ->
|
||||
setJoined(isMember)
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
ExceptionHandler.rx()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
@ -159,8 +162,11 @@ class ChallengeDetailFragment : BaseMainFragment<FragmentChallengeDetailBinding>
|
|||
binding?.joinButton?.setOnClickListener {
|
||||
challenge?.let { challenge ->
|
||||
challengeRepository.joinChallenge(challenge)
|
||||
.flatMap { userRepository.retrieveUser(true) }
|
||||
.subscribe({}, RxErrorHandler.handleEmptyError())
|
||||
.subscribe({
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
userRepository.retrieveUser(true)
|
||||
}
|
||||
}, ExceptionHandler.rx())
|
||||
}
|
||||
}
|
||||
binding?.leaveButton?.setOnClickListener { showChallengeLeaveDialog() }
|
||||
|
|
@ -230,7 +236,7 @@ class ChallengeDetailFragment : BaseMainFragment<FragmentChallengeDetailBinding>
|
|||
if (it is HttpException && it.code() == 404) {
|
||||
MainNavigationController.navigateBack()
|
||||
}
|
||||
RxErrorHandler.reportError(it)
|
||||
ExceptionHandler.reportError(it)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -245,7 +251,8 @@ class ChallengeDetailFragment : BaseMainFragment<FragmentChallengeDetailBinding>
|
|||
binding?.participantCount?.text = challenge.memberCount.toString()
|
||||
}
|
||||
|
||||
private fun set(creator: Member) {
|
||||
private fun set(creator: Member?) {
|
||||
if (creator == null) return
|
||||
binding?.creatorAvatarview?.setAvatar(creator)
|
||||
binding?.creatorLabel?.tier = creator.contributor?.level ?: 0
|
||||
binding?.creatorLabel?.username = creator.displayName
|
||||
|
|
@ -335,11 +342,11 @@ class ChallengeDetailFragment : BaseMainFragment<FragmentChallengeDetailBinding>
|
|||
alert.setMessage(this.getString(R.string.challenge_leave_description))
|
||||
alert.addButton(R.string.leave_keep_tasks, true) { _, _ ->
|
||||
val challenge = challenge ?: return@addButton
|
||||
challengeRepository.leaveChallenge(challenge, "keep-all").subscribe({}, RxErrorHandler.handleEmptyError())
|
||||
challengeRepository.leaveChallenge(challenge, "keep-all").subscribe({}, ExceptionHandler.rx())
|
||||
}
|
||||
alert.addButton(R.string.leave_delete_tasks, isPrimary = false, isDestructive = true) { _, _ ->
|
||||
val challenge = challenge ?: return@addButton
|
||||
challengeRepository.leaveChallenge(challenge, "remove-all").subscribe({}, RxErrorHandler.handleEmptyError())
|
||||
challengeRepository.leaveChallenge(challenge, "remove-all").subscribe({}, ExceptionHandler.rx())
|
||||
}
|
||||
alert.setExtraCloseButtonVisibility(View.VISIBLE)
|
||||
alert.show()
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import android.os.Bundle
|
|||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.components.UserComponent
|
||||
|
|
@ -11,8 +12,8 @@ import com.habitrpg.android.habitica.data.ChallengeRepository
|
|||
import com.habitrpg.android.habitica.data.SocialRepository
|
||||
import com.habitrpg.android.habitica.data.UserRepository
|
||||
import com.habitrpg.android.habitica.databinding.FragmentRefreshRecyclerviewBinding
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.android.habitica.helpers.MainNavigationController
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.models.social.Challenge
|
||||
import com.habitrpg.android.habitica.models.social.Group
|
||||
import com.habitrpg.android.habitica.modules.AppModule
|
||||
|
|
@ -21,7 +22,8 @@ import com.habitrpg.android.habitica.ui.fragments.BaseFragment
|
|||
import com.habitrpg.android.habitica.ui.helpers.SafeDefaultItemAnimator
|
||||
import com.habitrpg.common.habitica.helpers.EmptyItem
|
||||
import io.reactivex.rxjava3.core.Flowable
|
||||
import io.reactivex.rxjava3.kotlin.Flowables
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Named
|
||||
|
||||
|
|
@ -66,7 +68,7 @@ class ChallengeListFragment : BaseFragment<FragmentRefreshRecyclerviewBinding>()
|
|||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
challengeAdapter = ChallengesListViewAdapter(viewUserChallengesOnly, userId)
|
||||
challengeAdapter?.getOpenDetailFragmentFlowable()?.subscribe({ openDetailFragment(it) }, RxErrorHandler.handleEmptyError())
|
||||
challengeAdapter?.getOpenDetailFragmentFlowable()?.subscribe({ openDetailFragment(it) }, ExceptionHandler.rx())
|
||||
?.let { compositeSubscription.add(it) }
|
||||
|
||||
binding?.refreshLayout?.setOnRefreshListener(this)
|
||||
|
|
@ -83,16 +85,15 @@ class ChallengeListFragment : BaseFragment<FragmentRefreshRecyclerviewBinding>()
|
|||
binding?.recyclerView?.setBackgroundResource(R.color.content_background)
|
||||
}
|
||||
|
||||
compositeSubscription.add(
|
||||
Flowables.combineLatest(socialRepository.getGroupFlowable(Group.TAVERN_ID), socialRepository.getUserGroups("guild")).subscribe(
|
||||
{
|
||||
this.filterGroups = mutableListOf()
|
||||
filterGroups?.add(it.first)
|
||||
filterGroups?.addAll(it.second)
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
)
|
||||
)
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
socialRepository.getGroup(Group.TAVERN_ID).combine(socialRepository.getUserGroups("guild")) { tavern, guilds ->
|
||||
return@combine Pair(tavern, guilds)
|
||||
}.collect {
|
||||
this@ChallengeListFragment.filterGroups = mutableListOf()
|
||||
it.first?.let { tavern -> filterGroups?.add(tavern) }
|
||||
filterGroups?.addAll(it.second)
|
||||
}
|
||||
}
|
||||
|
||||
binding?.recyclerView?.itemAnimator = SafeDefaultItemAnimator()
|
||||
|
||||
|
|
@ -144,7 +145,7 @@ class ChallengeListFragment : BaseFragment<FragmentRefreshRecyclerviewBinding>()
|
|||
this.challenges = challenges
|
||||
challengeAdapter?.updateUnfilteredData(challenges)
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
ExceptionHandler.rx()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
@ -164,7 +165,7 @@ class ChallengeListFragment : BaseFragment<FragmentRefreshRecyclerviewBinding>()
|
|||
}
|
||||
nextPageToLoad += 1
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
ExceptionHandler.rx()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,17 +5,19 @@ import android.view.LayoutInflater
|
|||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.appcompat.widget.SearchView
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.components.UserComponent
|
||||
import com.habitrpg.android.habitica.data.SocialRepository
|
||||
import com.habitrpg.android.habitica.databinding.FragmentRefreshRecyclerviewBinding
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.android.habitica.ui.adapter.social.GuildListAdapter
|
||||
import com.habitrpg.android.habitica.ui.fragments.BaseFragment
|
||||
import com.habitrpg.common.habitica.helpers.EmptyItem
|
||||
import com.habitrpg.android.habitica.ui.helpers.KeyboardUtil
|
||||
import com.habitrpg.android.habitica.ui.helpers.SafeDefaultItemAnimator
|
||||
import com.habitrpg.common.habitica.helpers.EmptyItem
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
class GuildListFragment : BaseFragment<FragmentRefreshRecyclerviewBinding>(), SearchView.OnQueryTextListener, SearchView.OnCloseListener, SwipeRefreshLayout.OnRefreshListener {
|
||||
|
|
@ -52,7 +54,12 @@ class GuildListFragment : BaseFragment<FragmentRefreshRecyclerviewBinding>(), Se
|
|||
|
||||
viewAdapter.onlyShowUsersGuilds = onlyShowUsersGuilds
|
||||
if (onlyShowUsersGuilds) {
|
||||
compositeSubscription.add(socialRepository.getUserGroups("guild").subscribe({ viewAdapter.setUnfilteredData(it) }, RxErrorHandler.handleEmptyError()))
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
socialRepository.getUserGroups("guild")
|
||||
.collect {
|
||||
viewAdapter.setUnfilteredData(it)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
compositeSubscription.add(
|
||||
this.socialRepository.getPublicGuilds()
|
||||
|
|
@ -60,7 +67,7 @@ class GuildListFragment : BaseFragment<FragmentRefreshRecyclerviewBinding>(), Se
|
|||
{ groups ->
|
||||
this@GuildListFragment.viewAdapter.setUnfilteredData(groups)
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
ExceptionHandler.rx()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
@ -79,7 +86,7 @@ class GuildListFragment : BaseFragment<FragmentRefreshRecyclerviewBinding>(), Se
|
|||
{
|
||||
binding?.refreshLayout?.isRefreshing = false
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
ExceptionHandler.rx()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,21 +16,23 @@ import android.widget.TextView
|
|||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.core.graphics.drawable.toBitmap
|
||||
import androidx.core.os.bundleOf
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.google.firebase.analytics.FirebaseAnalytics
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.components.UserComponent
|
||||
import com.habitrpg.android.habitica.data.SocialRepository
|
||||
import com.habitrpg.android.habitica.databinding.FragmentNoPartyBinding
|
||||
import com.habitrpg.android.habitica.helpers.AppConfigManager
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.android.habitica.helpers.MainNavigationController
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.common.habitica.views.AvatarView
|
||||
import com.habitrpg.android.habitica.ui.activities.GroupFormActivity
|
||||
import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment
|
||||
import com.habitrpg.common.habitica.extensions.DataBindingUtils
|
||||
import com.habitrpg.common.habitica.helpers.setMarkdown
|
||||
import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel
|
||||
import com.habitrpg.android.habitica.ui.views.HabiticaSnackbar
|
||||
import com.habitrpg.common.habitica.extensions.DataBindingUtils
|
||||
import com.habitrpg.common.habitica.helpers.setMarkdown
|
||||
import com.habitrpg.common.habitica.views.AvatarView
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
|
|
@ -64,36 +66,34 @@ class NoPartyFragmentFragment : BaseMainFragment<FragmentNoPartyBinding>() {
|
|||
binding?.refreshLayout?.setOnRefreshListener { this.refresh() }
|
||||
|
||||
binding?.invitationsView?.acceptCall = {
|
||||
socialRepository.joinGroup(it)
|
||||
.flatMap { userRepository.retrieveUser(false) }
|
||||
.subscribe(
|
||||
{
|
||||
parentFragmentManager.popBackStack()
|
||||
MainNavigationController.navigate(
|
||||
R.id.partyFragment,
|
||||
bundleOf(Pair("partyID", userViewModel.partyID))
|
||||
)
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
socialRepository.joinGroup(it)
|
||||
userRepository.retrieveUser(false)
|
||||
parentFragmentManager.popBackStack()
|
||||
MainNavigationController.navigate(
|
||||
R.id.partyFragment,
|
||||
bundleOf(Pair("partyID", userViewModel.partyID))
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
binding?.invitationsView?.rejectCall = {
|
||||
socialRepository.rejectGroupInvite(it).subscribe({ }, RxErrorHandler.handleEmptyError())
|
||||
socialRepository.rejectGroupInvite(it).subscribe({ }, ExceptionHandler.rx())
|
||||
binding?.invitationWrapper?.visibility = View.GONE
|
||||
}
|
||||
|
||||
binding?.invitationsView?.setLeader = { leader ->
|
||||
compositeSubscription.add(
|
||||
socialRepository.getMember(leader)
|
||||
.subscribe(
|
||||
{
|
||||
binding?.root?.findViewById<AvatarView>(R.id.groupleader_avatar_view)?.setAvatar(it)
|
||||
binding?.root?.findViewById<TextView>(R.id.groupleader_text_view)?.text = getString(R.string.invitation_title, it.displayName, binding?.invitationsView?.groupName)
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
)
|
||||
)
|
||||
binding?.invitationsView?.setLeader = { leaderID ->
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
val leader = socialRepository.retrieveMember(leaderID) ?: return@launch
|
||||
binding?.root?.findViewById<AvatarView>(R.id.groupleader_avatar_view)
|
||||
?.setAvatar(leader)
|
||||
binding?.root?.findViewById<TextView>(R.id.groupleader_text_view)?.text =
|
||||
getString(
|
||||
R.string.invitation_title,
|
||||
leader.displayName,
|
||||
binding?.invitationsView?.groupName
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
binding?.usernameTextview?.setOnClickListener {
|
||||
|
|
@ -153,42 +153,38 @@ class NoPartyFragmentFragment : BaseMainFragment<FragmentNoPartyBinding>() {
|
|||
if (it.resultCode == Activity.RESULT_OK) {
|
||||
val bundle = it.data?.extras
|
||||
if (bundle?.getString("groupType") == "party") {
|
||||
socialRepository.createGroup(
|
||||
bundle.getString("name"),
|
||||
bundle.getString("description"),
|
||||
bundle.getString("leader"),
|
||||
"party",
|
||||
bundle.getString("privacy"),
|
||||
bundle.getBoolean("leaderCreateChallenge")
|
||||
)
|
||||
.flatMap {
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
val group = socialRepository.createGroup(
|
||||
bundle.getString("name"),
|
||||
bundle.getString("description"),
|
||||
bundle.getString("leader"),
|
||||
"party",
|
||||
bundle.getString("privacy"),
|
||||
bundle.getBoolean("leaderCreateChallenge")
|
||||
)
|
||||
userRepository.retrieveUser(false)
|
||||
if (isAdded) {
|
||||
parentFragmentManager.popBackStack()
|
||||
}
|
||||
MainNavigationController.navigate(
|
||||
R.id.partyFragment,
|
||||
bundleOf(Pair("partyID", userViewModel.partyID))
|
||||
)
|
||||
}
|
||||
.subscribe(
|
||||
{
|
||||
if (isAdded) {
|
||||
parentFragmentManager.popBackStack()
|
||||
}
|
||||
MainNavigationController.navigate(
|
||||
R.id.partyFragment,
|
||||
bundleOf(Pair("partyID", userViewModel.partyID))
|
||||
)
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun refresh() {
|
||||
compositeSubscription.add(
|
||||
userRepository.retrieveUser(false, forced = true)
|
||||
.filter { it.hasParty }
|
||||
.flatMap { socialRepository.retrieveGroup("party") }
|
||||
.flatMap { group1 -> socialRepository.retrieveGroupMembers(group1.id, true) }
|
||||
.doOnComplete { binding?.refreshLayout?.isRefreshing = false }
|
||||
.subscribe({ }, RxErrorHandler.handleEmptyError())
|
||||
)
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
val user = userRepository.retrieveUser(false, true)
|
||||
if (user?.hasParty == true) {
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
val group = socialRepository.retrieveGroup("party")
|
||||
socialRepository.retrieveGroupMembers(group?.id ?: "", true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
|
|
|
|||
|
|
@ -17,32 +17,33 @@ import com.habitrpg.android.habitica.data.InventoryRepository
|
|||
import com.habitrpg.android.habitica.data.SocialRepository
|
||||
import com.habitrpg.android.habitica.data.UserRepository
|
||||
import com.habitrpg.android.habitica.databinding.FragmentPartyDetailBinding
|
||||
import com.habitrpg.common.habitica.extensions.dpToPx
|
||||
import com.habitrpg.android.habitica.extensions.inflate
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.android.habitica.helpers.HapticFeedbackManager
|
||||
import com.habitrpg.android.habitica.helpers.MainNavigationController
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.models.inventory.QuestContent
|
||||
import com.habitrpg.android.habitica.models.members.Member
|
||||
import com.habitrpg.android.habitica.models.social.Challenge
|
||||
import com.habitrpg.android.habitica.models.social.Group
|
||||
import com.habitrpg.android.habitica.models.user.User
|
||||
import com.habitrpg.android.habitica.modules.AppModule
|
||||
import com.habitrpg.common.habitica.views.AvatarView
|
||||
import com.habitrpg.android.habitica.ui.activities.FullProfileActivity
|
||||
import com.habitrpg.android.habitica.ui.activities.MainActivity
|
||||
import com.habitrpg.android.habitica.ui.fragments.BaseFragment
|
||||
import com.habitrpg.android.habitica.ui.fragments.inventory.items.ItemDialogFragment
|
||||
import com.habitrpg.common.habitica.extensions.DataBindingUtils
|
||||
import com.habitrpg.android.habitica.ui.helpers.dismissKeyboard
|
||||
import com.habitrpg.common.habitica.extensions.loadImage
|
||||
import com.habitrpg.common.habitica.helpers.setMarkdown
|
||||
import com.habitrpg.android.habitica.ui.viewHolders.GroupMemberViewHolder
|
||||
import com.habitrpg.android.habitica.ui.viewmodels.PartyViewModel
|
||||
import com.habitrpg.android.habitica.ui.views.HabiticaSnackbar
|
||||
import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaAlertDialog
|
||||
import com.habitrpg.common.habitica.extensions.DataBindingUtils
|
||||
import com.habitrpg.common.habitica.extensions.dpToPx
|
||||
import com.habitrpg.common.habitica.extensions.loadImage
|
||||
import com.habitrpg.common.habitica.helpers.setMarkdown
|
||||
import com.habitrpg.common.habitica.views.AvatarView
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.firstOrNull
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Named
|
||||
|
|
@ -95,28 +96,29 @@ class PartyDetailFragment : BaseFragment<FragmentPartyDetailBinding>() {
|
|||
|
||||
binding?.invitationsView?.acceptCall = {
|
||||
viewModel?.joinGroup(it) {
|
||||
compositeSubscription.add(
|
||||
userRepository.retrieveUser(false)
|
||||
.subscribe { user ->
|
||||
parentFragmentManager.popBackStack()
|
||||
MainNavigationController.navigate(
|
||||
R.id.partyFragment,
|
||||
bundleOf(Pair("partyID", user.party?.id))
|
||||
)
|
||||
}
|
||||
)
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
val user = userRepository.retrieveUser(false)
|
||||
parentFragmentManager.popBackStack()
|
||||
MainNavigationController.navigate(
|
||||
R.id.partyFragment,
|
||||
bundleOf(Pair("partyID", user?.party?.id))
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
binding?.invitationsView?.rejectCall = {
|
||||
socialRepository.rejectGroupInvite(it)
|
||||
.flatMap { userRepository.retrieveUser(false, true) }
|
||||
.subscribe({ }, RxErrorHandler.handleEmptyError())
|
||||
.subscribe({
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
userRepository.retrieveUser(false, true)
|
||||
}
|
||||
}, ExceptionHandler.rx())
|
||||
}
|
||||
|
||||
viewModel?.getGroupData()?.observe(viewLifecycleOwner, { updateParty(it) })
|
||||
viewModel?.user?.observe(viewLifecycleOwner, { updateUser(it) })
|
||||
viewModel?.getMembersData()?.observe(viewLifecycleOwner, { updateMembersList(it) })
|
||||
viewModel?.getGroupData()?.observe(viewLifecycleOwner) { updateParty(it) }
|
||||
viewModel?.user?.observe(viewLifecycleOwner) { updateUser(it) }
|
||||
viewModel?.getMembersData()?.observe(viewLifecycleOwner) { updateMembersList(it) }
|
||||
}
|
||||
|
||||
private fun refreshParty() {
|
||||
|
|
@ -141,8 +143,10 @@ class PartyDetailFragment : BaseFragment<FragmentPartyDetailBinding>() {
|
|||
binding?.questImageWrapper?.visibility = View.VISIBLE
|
||||
lifecycleScope.launch(Dispatchers.Main) {
|
||||
delay(500)
|
||||
inventoryRepository.getQuestContent(party.quest?.key ?: "")
|
||||
.subscribe({ this@PartyDetailFragment.updateQuestContent(it) }, RxErrorHandler.handleEmptyError())
|
||||
val content = inventoryRepository.getQuestContent(party.quest?.key ?: "").firstOrNull()
|
||||
if (content != null) {
|
||||
updateQuestContent(content)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
binding?.newQuestButton?.visibility = View.VISIBLE
|
||||
|
|
@ -184,16 +188,17 @@ class PartyDetailFragment : BaseFragment<FragmentPartyDetailBinding>() {
|
|||
val groupName = invitation.name
|
||||
|
||||
leaderID.let { id ->
|
||||
compositeSubscription.add(
|
||||
socialRepository.getMember(id)
|
||||
.subscribe(
|
||||
{ member ->
|
||||
binding?.root?.findViewById<AvatarView>(R.id.groupleader_avatar_view)?.setAvatar(member)
|
||||
binding?.root?.findViewById<TextView>(R.id.groupleader_text_view)?.text = getString(R.string.invitation_title, member.displayName, groupName)
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
val member = socialRepository.retrieveMember(id) ?: return@launch
|
||||
binding?.root?.findViewById<AvatarView>(R.id.groupleader_avatar_view)
|
||||
?.setAvatar(member)
|
||||
binding?.root?.findViewById<TextView>(R.id.groupleader_text_view)?.text =
|
||||
getString(
|
||||
R.string.invitation_title,
|
||||
member.displayName,
|
||||
groupName
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
view?.findViewById<Button>(R.id.accept_button)?.setOnClickListener {
|
||||
|
|
@ -263,7 +268,7 @@ class PartyDetailFragment : BaseFragment<FragmentPartyDetailBinding>() {
|
|||
val leaderID = viewModel?.leaderID
|
||||
members?.forEachIndexed { index, member ->
|
||||
val memberView = (
|
||||
if (binding?.membersWrapper?.childCount ?: 0 > index) {
|
||||
if ((binding?.membersWrapper?.childCount ?: 0) > index) {
|
||||
binding?.membersWrapper?.getChildAt(index)
|
||||
} else {
|
||||
val view = binding?.membersWrapper?.inflate(R.layout.party_member, false)
|
||||
|
|
@ -299,18 +304,15 @@ class PartyDetailFragment : BaseFragment<FragmentPartyDetailBinding>() {
|
|||
|
||||
val addMessageDialog = context?.let { HabiticaAlertDialog(it) }
|
||||
addMessageDialog?.addButton(android.R.string.ok, true) { _, _ ->
|
||||
socialRepository.postPrivateMessage(userID, emojiEditText.text.toString())
|
||||
.subscribe(
|
||||
{
|
||||
(activity as? MainActivity)?.snackbarContainer?.let { it1 ->
|
||||
HabiticaSnackbar.showSnackbar(
|
||||
it1,
|
||||
String.format(getString(R.string.profile_message_sent_to), username), HabiticaSnackbar.SnackbarDisplayType.NORMAL
|
||||
)
|
||||
}
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
)
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
socialRepository.postPrivateMessage(userID, emojiEditText.text.toString())
|
||||
(activity as? MainActivity)?.snackbarContainer?.let { it1 ->
|
||||
HabiticaSnackbar.showSnackbar(
|
||||
it1,
|
||||
String.format(getString(R.string.profile_message_sent_to), username), HabiticaSnackbar.SnackbarDisplayType.NORMAL
|
||||
)
|
||||
}
|
||||
}
|
||||
activity?.dismissKeyboard()
|
||||
}
|
||||
addMessageDialog?.addButton(android.R.string.cancel, false) { _, _ -> activity?.dismissKeyboard() }
|
||||
|
|
@ -321,18 +323,15 @@ class PartyDetailFragment : BaseFragment<FragmentPartyDetailBinding>() {
|
|||
private fun showTransferOwnerShipDialog(userID: String, displayName: String) {
|
||||
val dialog = context?.let { HabiticaAlertDialog(it) }
|
||||
dialog?.addButton(R.string.transfer, true) { _, _ ->
|
||||
socialRepository.transferGroupOwnership(viewModel?.groupID ?: "", userID)
|
||||
.subscribe(
|
||||
{
|
||||
(activity as? MainActivity)?.snackbarContainer?.let { it1 ->
|
||||
HabiticaSnackbar.showSnackbar(
|
||||
it1,
|
||||
String.format(getString(R.string.transferred_ownership), displayName), HabiticaSnackbar.SnackbarDisplayType.NORMAL
|
||||
)
|
||||
}
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
)
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
socialRepository.transferGroupOwnership(viewModel?.groupID ?: "", userID)
|
||||
(activity as? MainActivity)?.snackbarContainer?.let { it1 ->
|
||||
HabiticaSnackbar.showSnackbar(
|
||||
it1,
|
||||
String.format(getString(R.string.transferred_ownership), displayName), HabiticaSnackbar.SnackbarDisplayType.NORMAL
|
||||
)
|
||||
}
|
||||
}
|
||||
activity?.dismissKeyboard()
|
||||
}
|
||||
dialog?.addButton(android.R.string.cancel, false) { _, _ -> activity?.dismissKeyboard() }
|
||||
|
|
@ -344,18 +343,15 @@ class PartyDetailFragment : BaseFragment<FragmentPartyDetailBinding>() {
|
|||
private fun showRemoveMemberDialog(userID: String, displayName: String) {
|
||||
val dialog = context?.let { HabiticaAlertDialog(it) }
|
||||
dialog?.addButton(R.string.remove, true) { _, _ ->
|
||||
socialRepository.removeMemberFromGroup(viewModel?.groupID ?: "", userID)
|
||||
.subscribe(
|
||||
{
|
||||
(activity as? MainActivity)?.snackbarContainer?.let { it1 ->
|
||||
HabiticaSnackbar.showSnackbar(
|
||||
it1,
|
||||
String.format(getString(R.string.removed_member), displayName), HabiticaSnackbar.SnackbarDisplayType.NORMAL
|
||||
)
|
||||
}
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
)
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
socialRepository.removeMemberFromGroup(viewModel?.groupID ?: "", userID)
|
||||
(activity as? MainActivity)?.snackbarContainer?.let { it1 ->
|
||||
HabiticaSnackbar.showSnackbar(
|
||||
it1,
|
||||
String.format(getString(R.string.removed_member), displayName), HabiticaSnackbar.SnackbarDisplayType.NORMAL
|
||||
)
|
||||
}
|
||||
}
|
||||
activity?.dismissKeyboard()
|
||||
}
|
||||
dialog?.addButton(android.R.string.cancel, false) { _, _ -> activity?.dismissKeyboard() }
|
||||
|
|
@ -373,7 +369,7 @@ class PartyDetailFragment : BaseFragment<FragmentPartyDetailBinding>() {
|
|||
}
|
||||
|
||||
private fun getGroupChallenges(): List<Challenge> {
|
||||
var groupChallenges = mutableListOf<Challenge>()
|
||||
val groupChallenges = mutableListOf<Challenge>()
|
||||
userRepository.getUserFlowable().forEach {
|
||||
it.challenges?.forEach {
|
||||
challengeRepository.getChallenge(it.challengeID).forEach {
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue