mirror of
https://github.com/sudoxnym/habitica-android.git
synced 2026-07-19 20:34:15 +00:00
Begin moving logic out of main activity
This commit is contained in:
parent
a37de3f497
commit
009fc24fbd
38 changed files with 569 additions and 428 deletions
|
|
@ -31,7 +31,6 @@ import com.google.firebase.analytics.FirebaseAnalytics
|
|||
import com.google.firebase.installations.FirebaseInstallations
|
||||
import com.google.firebase.remoteconfig.FirebaseRemoteConfig
|
||||
import com.google.firebase.remoteconfig.FirebaseRemoteConfigSettings
|
||||
import com.habitrpg.android.habitica.api.HostConfig
|
||||
import com.habitrpg.android.habitica.components.AppComponent
|
||||
import com.habitrpg.android.habitica.components.UserComponent
|
||||
import com.habitrpg.android.habitica.data.ApiClient
|
||||
|
|
@ -42,14 +41,12 @@ import com.habitrpg.android.habitica.modules.UserModule
|
|||
import com.habitrpg.android.habitica.modules.UserRepositoryModule
|
||||
import com.habitrpg.android.habitica.proxy.AnalyticsManager
|
||||
import com.habitrpg.android.habitica.ui.activities.BaseActivity
|
||||
import com.habitrpg.android.habitica.ui.activities.IntroActivity
|
||||
import com.habitrpg.android.habitica.ui.activities.LoginActivity
|
||||
import com.habitrpg.android.habitica.ui.helpers.MarkdownParser
|
||||
import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper
|
||||
import io.realm.Realm
|
||||
import io.realm.RealmConfiguration
|
||||
import java.lang.ref.WeakReference
|
||||
import java.util.Locale
|
||||
import javax.inject.Inject
|
||||
|
||||
// contains all HabiticaApplicationLogic except dagger componentInitialisation
|
||||
|
|
@ -295,15 +292,6 @@ abstract class HabiticaBaseApplication : Application(), Application.ActivityLife
|
|||
userComponent = component?.plus(UserModule(), UserRepositoryModule())
|
||||
}
|
||||
|
||||
fun checkUserAuthentication(context: Context, hostConfig: HostConfig?): Boolean {
|
||||
if (hostConfig?.apiKey == null || hostConfig.apiKey == "" || hostConfig.userID == "") {
|
||||
startActivity(IntroActivity::class.java, context)
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
private fun startActivity(activityClass: Class<*>, context: Context) {
|
||||
val intent = Intent(context, activityClass)
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
|
|
|
|||
|
|
@ -101,6 +101,7 @@ import com.habitrpg.android.habitica.ui.fragments.tasks.TeamBoardFragment;
|
|||
import com.habitrpg.android.habitica.ui.viewmodels.AuthenticationViewModel;
|
||||
import com.habitrpg.android.habitica.ui.viewmodels.GroupViewModel;
|
||||
import com.habitrpg.android.habitica.ui.viewmodels.InboxViewModel;
|
||||
import com.habitrpg.android.habitica.ui.viewmodels.MainActivityViewModel;
|
||||
import com.habitrpg.android.habitica.ui.viewmodels.NotificationsViewModel;
|
||||
import com.habitrpg.android.habitica.ui.viewmodels.inventory.equipment.EquipmentOverviewViewModel;
|
||||
import com.habitrpg.android.habitica.ui.views.insufficientCurrency.InsufficientGemsDialog;
|
||||
|
|
@ -346,4 +347,6 @@ public interface UserComponent {
|
|||
void inject(@NotNull AccountPreferenceFragment accountPreferenceFragment);
|
||||
|
||||
void inject(@NotNull AuthenticationViewModel authenticationViewModel);
|
||||
|
||||
void inject(@NotNull MainActivityViewModel mainActivityViewModel);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,15 +1,12 @@
|
|||
package com.habitrpg.android.habitica.data
|
||||
|
||||
import android.content.Context
|
||||
import com.habitrpg.android.habitica.models.ContentResult
|
||||
import com.habitrpg.android.habitica.models.WorldState
|
||||
import io.reactivex.rxjava3.core.Flowable
|
||||
|
||||
interface ContentRepository {
|
||||
interface ContentRepository: BaseRepository {
|
||||
fun retrieveContent(forced: Boolean = false): Flowable<ContentResult>
|
||||
|
||||
fun retrieveContent(context: Context?): Flowable<ContentResult>
|
||||
fun retrieveContent(context: Context?, forced: Boolean): Flowable<ContentResult>
|
||||
|
||||
fun retrieveWorldState(context: Context?): Flowable<WorldState>
|
||||
fun retrieveWorldState(): Flowable<WorldState>
|
||||
fun getWorldState(): Flowable<WorldState>
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ interface UserRepository : BaseRepository {
|
|||
fun retrieveUser(withTasks: Boolean): Flowable<User>
|
||||
fun retrieveUser(withTasks: Boolean = false, forced: Boolean = false, overrideExisting: Boolean = false): Flowable<User>
|
||||
|
||||
fun revive(user: User): Flowable<User>
|
||||
fun revive(): Flowable<User>
|
||||
|
||||
fun resetTutorial()
|
||||
|
||||
|
|
|
|||
|
|
@ -12,24 +12,20 @@ import io.reactivex.rxjava3.core.Flowable
|
|||
import io.realm.RealmList
|
||||
import java.util.*
|
||||
|
||||
abstract class ContentRepositoryImpl<T : ContentLocalRepository>(localRepository: T, apiClient: ApiClient) : BaseRepositoryImpl<T>(localRepository, apiClient), ContentRepository {
|
||||
class ContentRepositoryImpl<T : ContentLocalRepository>(localRepository: T, apiClient: ApiClient, context: Context) : BaseRepositoryImpl<T>(localRepository, apiClient), ContentRepository {
|
||||
|
||||
private val mysteryItem = SpecialItem.makeMysteryItem(context)
|
||||
|
||||
private var lastContentSync = 0L
|
||||
private var lastWorldStateSync = 0L
|
||||
|
||||
override fun retrieveContent(context: Context?): Flowable<ContentResult> {
|
||||
return retrieveContent(context, false)
|
||||
}
|
||||
|
||||
override fun retrieveContent(context: Context?, forced: Boolean): Flowable<ContentResult> {
|
||||
override fun retrieveContent(forced: Boolean): Flowable<ContentResult> {
|
||||
val now = Date().time
|
||||
return if (forced || now - this.lastContentSync > 300000) {
|
||||
lastContentSync = now
|
||||
apiClient.content.doOnNext {
|
||||
context?.let { context ->
|
||||
it.special = RealmList()
|
||||
it.special.add(SpecialItem.makeMysteryItem(context))
|
||||
}
|
||||
it.special = RealmList()
|
||||
it.special.add(mysteryItem)
|
||||
localRepository.saveContent(it)
|
||||
}
|
||||
} else {
|
||||
|
|
@ -37,7 +33,7 @@ abstract class ContentRepositoryImpl<T : ContentLocalRepository>(localRepository
|
|||
}
|
||||
}
|
||||
|
||||
override fun retrieveWorldState(context: Context?): Flowable<WorldState> {
|
||||
override fun retrieveWorldState(): Flowable<WorldState> {
|
||||
val now = Date().time
|
||||
return if (now - this.lastWorldStateSync > 3600000) {
|
||||
lastWorldStateSync = now
|
||||
|
|
|
|||
|
|
@ -94,9 +94,10 @@ class UserRepositoryImpl(localRepository: UserLocalRepository, apiClient: ApiCli
|
|||
}
|
||||
}
|
||||
|
||||
override fun revive(user: User): Flowable<User> =
|
||||
apiClient.revive().map { newUser -> mergeUser(user, newUser) }
|
||||
.flatMap { retrieveUser(false, true) }
|
||||
override fun revive(): Flowable<User> = zipWithLiveUser(apiClient.revive()) { newUser, user ->
|
||||
mergeUser(user, newUser)
|
||||
}
|
||||
.flatMap { retrieveUser(false, true) }
|
||||
|
||||
override fun resetTutorial() {
|
||||
localRepository.getTutorialSteps()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,83 @@
|
|||
package com.habitrpg.android.habitica.interactors
|
||||
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.Canvas
|
||||
import android.view.View
|
||||
import android.widget.FrameLayout
|
||||
import android.widget.ImageView
|
||||
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.models.inventory.Food
|
||||
import com.habitrpg.android.habitica.models.inventory.Pet
|
||||
import com.habitrpg.android.habitica.models.responses.FeedResponse
|
||||
import com.habitrpg.android.habitica.ui.activities.BaseActivity
|
||||
import com.habitrpg.android.habitica.ui.helpers.DataBindingUtils
|
||||
import com.habitrpg.android.habitica.ui.views.SnackbarActivity
|
||||
import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaAlertDialog
|
||||
import io.reactivex.rxjava3.core.Flowable
|
||||
import javax.inject.Inject
|
||||
|
||||
class FeedPetUseCase @Inject
|
||||
constructor(
|
||||
private val inventoryRepository: InventoryRepository,
|
||||
postExecutionThread: PostExecutionThread
|
||||
) : UseCase<FeedPetUseCase.RequestValues, FeedResponse>(postExecutionThread) {
|
||||
override fun buildUseCaseObservable(requestValues: FeedPetUseCase.RequestValues): Flowable<FeedResponse> {
|
||||
return inventoryRepository.feedPet(requestValues.pet, requestValues.food)
|
||||
.doOnNext { feedResponse ->
|
||||
(requestValues.context as? SnackbarActivity)?.showSnackbar(content = feedResponse.message)
|
||||
if (feedResponse.value == -1) {
|
||||
val mountWrapper =
|
||||
View.inflate(
|
||||
requestValues.context,
|
||||
R.layout.pet_imageview,
|
||||
null
|
||||
) as? FrameLayout
|
||||
val mountImageView =
|
||||
mountWrapper?.findViewById(R.id.pet_imageview) as? ImageView
|
||||
|
||||
DataBindingUtils.loadImage(
|
||||
mountImageView,
|
||||
"Mount_Icon_" + requestValues.pet.key
|
||||
)
|
||||
val dialog = HabiticaAlertDialog(requestValues.context)
|
||||
dialog.setTitle(
|
||||
requestValues.context.getString(
|
||||
R.string.evolved_pet_title,
|
||||
requestValues.pet.text
|
||||
)
|
||||
)
|
||||
dialog.setAdditionalContentView(mountWrapper)
|
||||
dialog.addButton(R.string.onwards, true)
|
||||
dialog.addButton(R.string.share, false) { hatchingDialog, _ ->
|
||||
val message =
|
||||
requestValues.context.getString(
|
||||
R.string.share_raised,
|
||||
requestValues.pet.text
|
||||
)
|
||||
val mountImageSideLength = 99
|
||||
val sharedImage = Bitmap.createBitmap(
|
||||
mountImageSideLength,
|
||||
mountImageSideLength,
|
||||
Bitmap.Config.ARGB_8888
|
||||
)
|
||||
val canvas = Canvas(sharedImage)
|
||||
mountImageView?.drawable?.setBounds(
|
||||
0,
|
||||
0,
|
||||
mountImageSideLength,
|
||||
mountImageSideLength
|
||||
)
|
||||
mountImageView?.drawable?.draw(canvas)
|
||||
requestValues.context.shareContent("raisedPet", message, sharedImage)
|
||||
hatchingDialog.dismiss()
|
||||
}
|
||||
dialog.enqueue()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class RequestValues(val pet: Pet, val food: Food, val context: BaseActivity) :
|
||||
UseCase.RequestValues
|
||||
}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
package com.habitrpg.android.habitica.interactors
|
||||
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.Canvas
|
||||
import android.view.View
|
||||
import android.widget.FrameLayout
|
||||
import android.widget.ImageView
|
||||
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.models.inventory.Egg
|
||||
import com.habitrpg.android.habitica.models.inventory.HatchingPotion
|
||||
import com.habitrpg.android.habitica.models.user.Items
|
||||
import com.habitrpg.android.habitica.ui.activities.BaseActivity
|
||||
import com.habitrpg.android.habitica.ui.helpers.DataBindingUtils
|
||||
import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaAlertDialog
|
||||
import io.reactivex.rxjava3.core.Flowable
|
||||
import javax.inject.Inject
|
||||
|
||||
class HatchPetUseCase @Inject
|
||||
constructor(private val inventoryRepository: InventoryRepository, postExecutionThread: PostExecutionThread) : UseCase<HatchPetUseCase.RequestValues, Items>(postExecutionThread) {
|
||||
override fun buildUseCaseObservable(requestValues: RequestValues): Flowable<Items> {
|
||||
return inventoryRepository.hatchPet(requestValues.egg, requestValues.potion) {
|
||||
val petWrapper = View.inflate(requestValues.context, R.layout.pet_imageview, null) as? FrameLayout
|
||||
val petImageView = petWrapper?.findViewById(R.id.pet_imageview) as? ImageView
|
||||
|
||||
DataBindingUtils.loadImage(petImageView, "stable_Pet-" + requestValues.egg.key + "-" + requestValues.potion.key)
|
||||
val potionName = requestValues.potion.text
|
||||
val eggName = requestValues.egg.text
|
||||
val dialog = HabiticaAlertDialog(requestValues.context)
|
||||
dialog.setTitle(requestValues.context.getString(R.string.hatched_pet_title, potionName, eggName))
|
||||
dialog.setAdditionalContentView(petWrapper)
|
||||
dialog.addButton(R.string.equip, true) { _, _ ->
|
||||
inventoryRepository.equip(null, "pet", requestValues.egg.key + "-" + requestValues.potion.key)
|
||||
.subscribe({}, RxErrorHandler.handleEmptyError())
|
||||
}
|
||||
dialog.addButton(R.string.share, false) { hatchingDialog, _ ->
|
||||
val message = requestValues.context.getString(R.string.share_hatched, potionName, eggName)
|
||||
val petImageSideLength = 140
|
||||
val sharedImage = Bitmap.createBitmap(petImageSideLength, petImageSideLength, Bitmap.Config.ARGB_8888)
|
||||
val canvas = Canvas(sharedImage)
|
||||
petImageView?.drawable?.setBounds(0, 0, petImageSideLength, petImageSideLength)
|
||||
petImageView?.drawable?.draw(canvas)
|
||||
requestValues.context.shareContent("hatchedPet", message, sharedImage)
|
||||
hatchingDialog.dismiss()
|
||||
}
|
||||
dialog.setExtraCloseButtonVisibility(View.VISIBLE)
|
||||
dialog.enqueue()
|
||||
}
|
||||
}
|
||||
|
||||
class RequestValues(val potion: HatchingPotion, val egg: Egg, val context: BaseActivity) : UseCase.RequestValues
|
||||
}
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
package com.habitrpg.android.habitica.modules;
|
||||
|
||||
import com.habitrpg.android.habitica.data.ApiClient;
|
||||
import com.habitrpg.android.habitica.data.ContentRepository;
|
||||
import com.habitrpg.android.habitica.data.implementation.ContentRepositoryImpl;
|
||||
import com.habitrpg.android.habitica.data.local.ContentLocalRepository;
|
||||
import com.habitrpg.android.habitica.data.local.implementation.RealmContentLocalRepository;
|
||||
|
||||
import dagger.Module;
|
||||
import dagger.Provides;
|
||||
import io.realm.Realm;
|
||||
|
||||
@Module
|
||||
public class RepositoryModule {
|
||||
@Provides
|
||||
public Realm providesRealm() {
|
||||
return Realm.getDefaultInstance();
|
||||
}
|
||||
|
||||
@Provides
|
||||
public ContentLocalRepository providesContentLocalRepository(Realm realm) { return new RealmContentLocalRepository(realm); }
|
||||
|
||||
@Provides
|
||||
public ContentRepository providesContentRepository(ContentLocalRepository contentLocalRepository, ApiClient apiClient) { return new ContentRepositoryImpl<ContentLocalRepository>(contentLocalRepository, apiClient) {}; }
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
package com.habitrpg.android.habitica.modules
|
||||
|
||||
import android.content.Context
|
||||
import com.habitrpg.android.habitica.data.local.ContentLocalRepository
|
||||
import com.habitrpg.android.habitica.data.local.implementation.RealmContentLocalRepository
|
||||
import com.habitrpg.android.habitica.data.ApiClient
|
||||
import com.habitrpg.android.habitica.data.ContentRepository
|
||||
import com.habitrpg.android.habitica.data.implementation.ContentRepositoryImpl
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import io.realm.Realm
|
||||
|
||||
@Module
|
||||
open class RepositoryModule {
|
||||
@Provides
|
||||
open fun providesRealm(): Realm? {
|
||||
return Realm.getDefaultInstance()
|
||||
}
|
||||
|
||||
@Provides
|
||||
fun providesContentLocalRepository(realm: Realm?): ContentLocalRepository {
|
||||
return RealmContentLocalRepository(realm!!)
|
||||
}
|
||||
|
||||
@Provides
|
||||
fun providesContentRepository(
|
||||
contentLocalRepository: ContentLocalRepository,
|
||||
apiClient: ApiClient,
|
||||
context: Context
|
||||
): ContentRepository {
|
||||
return ContentRepositoryImpl(
|
||||
contentLocalRepository,
|
||||
apiClient,
|
||||
context
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -65,15 +65,15 @@ class UserRepositoryModule {
|
|||
|
||||
@Provides
|
||||
fun providesTaskRepository(
|
||||
localRepository: TaskLocalRepository?,
|
||||
apiClient: ApiClient?,
|
||||
@Named(AppModule.NAMED_USER_ID) userId: String?,
|
||||
appConfigManager: AppConfigManager?,
|
||||
analyticsManager: AnalyticsManager?
|
||||
localRepository: TaskLocalRepository,
|
||||
apiClient: ApiClient,
|
||||
@Named(AppModule.NAMED_USER_ID) userId: String,
|
||||
appConfigManager: AppConfigManager,
|
||||
analyticsManager: AnalyticsManager
|
||||
): TaskRepository {
|
||||
return TaskRepositoryImpl(
|
||||
localRepository!!,
|
||||
apiClient!!,
|
||||
localRepository,
|
||||
apiClient,
|
||||
userId!!,
|
||||
appConfigManager!!,
|
||||
analyticsManager!!
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import android.os.Bundle
|
|||
interface AnalyticsManager {
|
||||
fun logException(t: Throwable)
|
||||
fun setUserIdentifier(identifier: String)
|
||||
fun setUserProperty(identifier: String, value: String)
|
||||
fun logError(msg: String)
|
||||
fun logEvent(eventName: String, data: Bundle)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import com.habitrpg.android.habitica.proxy.AnalyticsManager
|
|||
|
||||
class EmptyAnalyticsManager : AnalyticsManager {
|
||||
|
||||
override fun logException(e: Throwable) {
|
||||
override fun logException(t: Throwable) {
|
||||
// pass
|
||||
}
|
||||
|
||||
|
|
@ -13,6 +13,10 @@ class EmptyAnalyticsManager : AnalyticsManager {
|
|||
// pass
|
||||
}
|
||||
|
||||
override fun setUserProperty(identifier: String, value: String) {
|
||||
// pass
|
||||
}
|
||||
|
||||
override fun logError(msg: String) {
|
||||
// pass
|
||||
}
|
||||
|
|
|
|||
|
|
@ -128,7 +128,6 @@ abstract class BaseActivity : AppCompatActivity() {
|
|||
|
||||
internal open fun loadTheme(sharedPreferences: SharedPreferences, forced: Boolean = false) {
|
||||
val theme = forcedTheme ?: sharedPreferences.getString("theme_name", "purple")
|
||||
val modernHeaderStyle = overrideModernHeader ?: sharedPreferences.getBoolean("modern_header_style", true)
|
||||
if (theme != currentTheme || forced) {
|
||||
if (forcedIsNight ?: isNightMode) {
|
||||
setTheme(
|
||||
|
|
@ -165,10 +164,8 @@ abstract class BaseActivity : AppCompatActivity() {
|
|||
} else {
|
||||
getThemeColor(R.attr.colorPrimaryDark)
|
||||
}
|
||||
if (!(forcedIsNight ?: isNightMode) && modernHeaderStyle) {
|
||||
if (!(forcedIsNight ?: isNightMode)) {
|
||||
window.updateStatusBarColor(getThemeColor(R.attr.headerBackgroundColor), true)
|
||||
} else {
|
||||
window.updateStatusBarColor(getThemeColor(R.attr.statusBarBackground), false)
|
||||
}
|
||||
|
||||
if (currentTheme != null && theme != currentTheme) {
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ class IntroActivity : BaseActivity(), View.OnClickListener, ViewPager.OnPageChan
|
|||
binding.skipButton.setOnClickListener(this)
|
||||
binding.finishButton.setOnClickListener(this)
|
||||
|
||||
compositeSubscription.add(contentRepository.retrieveContent(this).subscribe({ }, RxErrorHandler.handleEmptyError()))
|
||||
compositeSubscription.add(contentRepository.retrieveContent().subscribe({ }, RxErrorHandler.handleEmptyError()))
|
||||
|
||||
window.statusBarColor = ContextCompat.getColor(this, R.color.black_20_alpha)
|
||||
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
|
||||
|
|
|
|||
|
|
@ -5,37 +5,30 @@ import android.app.NotificationManager
|
|||
import android.appwidget.AppWidgetManager
|
||||
import android.content.ComponentName
|
||||
import android.content.Intent
|
||||
import android.content.SharedPreferences
|
||||
import android.content.pm.PackageManager
|
||||
import android.content.res.Configuration
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.Canvas
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.*
|
||||
import android.widget.FrameLayout
|
||||
import android.widget.ImageView
|
||||
import androidx.activity.viewModels
|
||||
import androidx.appcompat.app.ActionBarDrawerToggle
|
||||
import androidx.core.content.edit
|
||||
import androidx.drawerlayout.widget.DrawerLayout
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.navigation.NavDestination
|
||||
import androidx.navigation.findNavController
|
||||
import androidx.navigation.fragment.NavHostFragment
|
||||
import com.google.firebase.analytics.FirebaseAnalytics
|
||||
import com.google.firebase.perf.FirebasePerformance
|
||||
import com.habitrpg.android.habitica.HabiticaBaseApplication
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.api.HostConfig
|
||||
import com.habitrpg.android.habitica.api.MaintenanceApiService
|
||||
import com.habitrpg.android.habitica.components.UserComponent
|
||||
import com.habitrpg.android.habitica.data.*
|
||||
import com.habitrpg.android.habitica.data.local.UserQuestStatus
|
||||
import com.habitrpg.android.habitica.databinding.ActivityMainBinding
|
||||
import com.habitrpg.android.habitica.databinding.DialogFaintBinding
|
||||
import com.habitrpg.android.habitica.extensions.*
|
||||
import com.habitrpg.android.habitica.helpers.*
|
||||
import com.habitrpg.android.habitica.helpers.notifications.PushNotificationManager
|
||||
import com.habitrpg.android.habitica.interactors.CheckClassSelectionUseCase
|
||||
import com.habitrpg.android.habitica.interactors.DisplayItemDropUseCase
|
||||
import com.habitrpg.android.habitica.interactors.NotifyUserUseCase
|
||||
|
|
@ -52,6 +45,7 @@ import com.habitrpg.android.habitica.ui.AvatarWithBarsViewModel
|
|||
import com.habitrpg.android.habitica.ui.TutorialView
|
||||
import com.habitrpg.android.habitica.ui.fragments.NavigationDrawerFragment
|
||||
import com.habitrpg.android.habitica.ui.helpers.DataBindingUtils
|
||||
import com.habitrpg.android.habitica.ui.viewmodels.MainActivityViewModel
|
||||
import com.habitrpg.android.habitica.ui.viewmodels.NotificationsViewModel
|
||||
import com.habitrpg.android.habitica.ui.views.*
|
||||
import com.habitrpg.android.habitica.ui.views.HabiticaSnackbar.SnackbarDisplayType
|
||||
|
|
@ -63,9 +57,6 @@ import com.habitrpg.android.habitica.widget.HabitButtonWidgetProvider
|
|||
import com.habitrpg.android.habitica.widget.TodoListWidgetProvider
|
||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.rxjava3.core.Observable
|
||||
import io.reactivex.rxjava3.functions.Consumer
|
||||
import io.reactivex.rxjava3.schedulers.Schedulers
|
||||
import io.realm.kotlin.isValid
|
||||
import java.util.*
|
||||
import java.util.concurrent.TimeUnit
|
||||
import javax.inject.Inject
|
||||
|
|
@ -78,14 +69,6 @@ open class MainActivity : BaseActivity(), TutorialView.OnTutorialReaction, Snack
|
|||
@Inject
|
||||
internal lateinit var soundManager: SoundManager
|
||||
@Inject
|
||||
internal lateinit var maintenanceService: MaintenanceApiService
|
||||
@Inject
|
||||
internal lateinit var hostConfig: HostConfig
|
||||
@Inject
|
||||
internal lateinit var sharedPreferences: SharedPreferences
|
||||
@Inject
|
||||
internal lateinit var pushNotificationManager: PushNotificationManager
|
||||
@Inject
|
||||
internal lateinit var checkClassSelectionUseCase: CheckClassSelectionUseCase
|
||||
@Inject
|
||||
internal lateinit var displayItemDropUseCase: DisplayItemDropUseCase
|
||||
|
|
@ -98,20 +81,16 @@ open class MainActivity : BaseActivity(), TutorialView.OnTutorialReaction, Snack
|
|||
@Inject
|
||||
internal lateinit var inventoryRepository: InventoryRepository
|
||||
@Inject
|
||||
internal lateinit var contentRepository: ContentRepository
|
||||
@Inject
|
||||
internal lateinit var taskAlarmManager: TaskAlarmManager
|
||||
@Inject
|
||||
internal lateinit var appConfigManager: AppConfigManager
|
||||
|
||||
lateinit var binding: ActivityMainBinding
|
||||
|
||||
val snackbarContainer: ViewGroup
|
||||
get() = binding.snackbarContainer
|
||||
var user: User? = null
|
||||
|
||||
private var avatarInHeader: AvatarWithBarsViewModel? = null
|
||||
var notificationsViewModel: NotificationsViewModel? = null
|
||||
val notificationsViewModel: NotificationsViewModel by viewModels()
|
||||
val viewModel: MainActivityViewModel by viewModels()
|
||||
private var faintDialog: HabiticaAlertDialog? = null
|
||||
private var sideAvatarView: AvatarView? = null
|
||||
private var activeTutorialView: TutorialView? = null
|
||||
|
|
@ -121,9 +100,6 @@ open class MainActivity : BaseActivity(), TutorialView.OnTutorialReaction, Snack
|
|||
private var userQuestStatus = UserQuestStatus.NO_QUEST
|
||||
private var lastNotificationOpen: Long? = null
|
||||
|
||||
val userID: String
|
||||
get() = user?.id ?: ""
|
||||
|
||||
val isAppBarExpanded: Boolean
|
||||
get() = binding.appbar.height - binding.appbar.bottom == 0
|
||||
|
||||
|
|
@ -147,7 +123,10 @@ open class MainActivity : BaseActivity(), TutorialView.OnTutorialReaction, Snack
|
|||
launchTrace?.start()
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
if (!HabiticaBaseApplication.checkUserAuthentication(this, hostConfig)) {
|
||||
if (!viewModel.isAuthenticated) {
|
||||
val intent = Intent(this, IntroActivity::class.java)
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
startActivity(intent)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -156,36 +135,24 @@ open class MainActivity : BaseActivity(), TutorialView.OnTutorialReaction, Snack
|
|||
avatarInHeader = AvatarWithBarsViewModel(this, binding.avatarWithBars, userRepository)
|
||||
sideAvatarView = AvatarView(this, showBackground = true, showMount = false, showPet = false)
|
||||
|
||||
compositeSubscription.add(
|
||||
userRepository.getUser()
|
||||
.subscribe(
|
||||
{ newUser ->
|
||||
this@MainActivity.user = newUser
|
||||
this@MainActivity.setUserData()
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
)
|
||||
)
|
||||
viewModel.user.observe(this) {
|
||||
setUserData(it)
|
||||
}
|
||||
compositeSubscription.add(
|
||||
userRepository.getUserQuestStatus().subscribeWithErrorHandler {
|
||||
userQuestStatus = it
|
||||
}
|
||||
)
|
||||
|
||||
val viewModel = ViewModelProvider(this).get(NotificationsViewModel::class.java)
|
||||
notificationsViewModel = viewModel
|
||||
|
||||
val drawerLayout = findViewById<DrawerLayout>(R.id.drawer_layout)
|
||||
|
||||
drawerFragment = supportFragmentManager.findFragmentById(R.id.navigation_drawer) as? NavigationDrawerFragment
|
||||
|
||||
drawerFragment?.setUp(R.id.navigation_drawer, drawerLayout, viewModel)
|
||||
drawerFragment?.setUp(R.id.navigation_drawer, drawerLayout, notificationsViewModel)
|
||||
|
||||
drawerToggle = object : ActionBarDrawerToggle(
|
||||
this, /* host Activity */
|
||||
drawerLayout, /* DrawerLayout object */
|
||||
R.string.navigation_drawer_open, /* "open drawer" description */
|
||||
R.string.navigation_drawer_close /* "close drawer" description */
|
||||
this,
|
||||
drawerLayout,
|
||||
R.string.navigation_drawer_open,
|
||||
R.string.navigation_drawer_close
|
||||
) {}
|
||||
// Set the drawer toggle as the DrawerListener
|
||||
drawerToggle?.let { drawerLayout.addDrawerListener(it) }
|
||||
|
|
@ -193,8 +160,7 @@ open class MainActivity : BaseActivity(), TutorialView.OnTutorialReaction, Snack
|
|||
private var isOpeningDrawer: Boolean? = null
|
||||
|
||||
override fun onDrawerSlide(drawerView: View, slideOffset: Float) {
|
||||
val modernHeaderStyle = sharedPreferences.getBoolean("modern_header_style", true)
|
||||
if (!isUsingNightModeResources() && modernHeaderStyle) {
|
||||
if (!isUsingNightModeResources()) {
|
||||
if (slideOffset < 0.5f && isOpeningDrawer == null) {
|
||||
window.updateStatusBarColor(getThemeColor(R.attr.colorPrimaryDark), false)
|
||||
isOpeningDrawer = true
|
||||
|
|
@ -207,18 +173,15 @@ open class MainActivity : BaseActivity(), TutorialView.OnTutorialReaction, Snack
|
|||
|
||||
override fun onDrawerOpened(drawerView: View) {
|
||||
hideKeyboard()
|
||||
val modernHeaderStyle = sharedPreferences.getBoolean("modern_header_style", true)
|
||||
if (!isUsingNightModeResources() && modernHeaderStyle) {
|
||||
if (!isUsingNightModeResources()) {
|
||||
window.updateStatusBarColor(getThemeColor(R.attr.colorPrimaryDark), false)
|
||||
}
|
||||
isOpeningDrawer = null
|
||||
|
||||
drawerFragment?.updatePromo()
|
||||
}
|
||||
|
||||
override fun onDrawerClosed(drawerView: View) {
|
||||
val modernHeaderStyle = sharedPreferences.getBoolean("modern_header_style", true)
|
||||
if (!isUsingNightModeResources() && modernHeaderStyle) {
|
||||
if (!isUsingNightModeResources()) {
|
||||
window.updateStatusBarColor(getThemeColor(R.attr.headerBackgroundColor), true)
|
||||
}
|
||||
isOpeningDrawer = null
|
||||
|
|
@ -233,11 +196,7 @@ open class MainActivity : BaseActivity(), TutorialView.OnTutorialReaction, Snack
|
|||
setupNotifications()
|
||||
setupBottomnavigationLayoutListener()
|
||||
|
||||
try {
|
||||
taskAlarmManager.scheduleAllSavedAlarms(sharedPreferences.getBoolean("preventDailyReminder", false))
|
||||
} catch (e: Exception) {
|
||||
analyticsManager.logException(e)
|
||||
}
|
||||
viewModel.onCreate()
|
||||
}
|
||||
|
||||
override fun setTitle(title: CharSequence?) {
|
||||
|
|
@ -249,32 +208,7 @@ open class MainActivity : BaseActivity(), TutorialView.OnTutorialReaction, Snack
|
|||
}
|
||||
|
||||
private fun updateToolbarTitle(destination: NavDestination, arguments: Bundle?) {
|
||||
title = if (destination.id == R.id.promoInfoFragment) {
|
||||
""
|
||||
} else if (destination.id == R.id.petDetailRecyclerFragment || destination.id == R.id.mountDetailRecyclerFragment) {
|
||||
arguments?.getString("type")
|
||||
} else if (destination.label.isNullOrEmpty() && user?.isValid == true) {
|
||||
user?.profile?.name
|
||||
} else if (destination.label != null) {
|
||||
destination.label
|
||||
} else {
|
||||
""
|
||||
}
|
||||
if (destination.id == R.id.petDetailRecyclerFragment || destination.id == R.id.mountDetailRecyclerFragment) {
|
||||
compositeSubscription.add(
|
||||
inventoryRepository.getItem("egg", arguments?.getString("type") ?: "").firstElement().subscribe(
|
||||
{
|
||||
if (!it.isValid()) return@subscribe
|
||||
binding.toolbarTitle.text = if (destination.id == R.id.petDetailRecyclerFragment) {
|
||||
(it as? Egg)?.text
|
||||
} else {
|
||||
(it as? Egg)?.mountText
|
||||
}
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
)
|
||||
)
|
||||
}
|
||||
viewModel.getToolbarTitle(destination.id, destination.label, arguments?.getString("type")) { title = it }
|
||||
drawerFragment?.setSelection(destination.id, null, false)
|
||||
}
|
||||
|
||||
|
|
@ -312,12 +246,7 @@ open class MainActivity : BaseActivity(), TutorialView.OnTutorialReaction, Snack
|
|||
// Sync the toggle state after onRestoreInstanceState has occurred.
|
||||
drawerToggle?.syncState()
|
||||
|
||||
launchScreen = sharedPreferences.getString("launch_screen", "")
|
||||
}
|
||||
|
||||
override fun onRestoreInstanceState(savedInstanceState: Bundle) {
|
||||
super.onRestoreInstanceState(savedInstanceState)
|
||||
Log.e("RESTORED:", savedInstanceState.toString())
|
||||
launchScreen = viewModel.launchScreen
|
||||
}
|
||||
|
||||
override fun onConfigurationChanged(newConfig: Configuration) {
|
||||
|
|
@ -338,13 +267,15 @@ open class MainActivity : BaseActivity(), TutorialView.OnTutorialReaction, Snack
|
|||
override fun onResume() {
|
||||
super.onResume()
|
||||
|
||||
viewModel.onResume()
|
||||
|
||||
val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
|
||||
val navigationController = navHostFragment.navController
|
||||
MainNavigationController.setup(navigationController)
|
||||
navigationController.addOnDestinationChangedListener { _, destination, arguments -> updateToolbarTitle(destination, arguments) }
|
||||
|
||||
if (launchScreen == "/party") {
|
||||
if (user == null || user?.party?.id != null) {
|
||||
if (viewModel.isUserInParty) {
|
||||
MainNavigationController.navigate(R.id.partyFragment)
|
||||
}
|
||||
}
|
||||
|
|
@ -356,12 +287,6 @@ open class MainActivity : BaseActivity(), TutorialView.OnTutorialReaction, Snack
|
|||
}
|
||||
resumeFromActivity = false
|
||||
|
||||
// Track when the app was last opened, so that we can use this to send out special reminders after a week of inactivity
|
||||
sharedPreferences.edit {
|
||||
putLong("lastAppLaunch", Date().time)
|
||||
putBoolean("preventDailyReminder", false)
|
||||
}
|
||||
|
||||
if ((intent.hasExtra("notificationIdentifier") || intent.hasExtra("openURL")) && lastNotificationOpen != intent.getLongExtra("notificationTimeStamp", 0)) {
|
||||
lastNotificationOpen = intent.getLongExtra("notificationTimeStamp", 0)
|
||||
val identifier = intent.getStringExtra("notificationIdentifier") ?: ""
|
||||
|
|
@ -421,51 +346,40 @@ open class MainActivity : BaseActivity(), TutorialView.OnTutorialReaction, Snack
|
|||
findNavController(R.id.nav_host_fragment).navigate(transitionId)
|
||||
}
|
||||
|
||||
private fun setUserData() {
|
||||
private fun setUserData(user: User?) {
|
||||
if (user != null) {
|
||||
val preferences = user?.preferences
|
||||
val preferences = user.preferences
|
||||
|
||||
preferences?.language?.let { apiClient.setLanguageCode(it) }
|
||||
if (preferences?.language != sharedPreferences.getString("language", "en")) {
|
||||
sharedPreferences.edit {
|
||||
putString("language", preferences?.language)
|
||||
}
|
||||
if (preferences?.language != viewModel.preferenceLanguage) {
|
||||
viewModel.preferenceLanguage = preferences?.language
|
||||
}
|
||||
preferences?.sound?.let { soundManager.soundTheme = it }
|
||||
|
||||
displayDeathDialogIfNeeded()
|
||||
YesterdailyDialog.showDialogIfNeeded(this, user?.id, userRepository, taskRepository)
|
||||
YesterdailyDialog.showDialogIfNeeded(this, user.id, userRepository, taskRepository)
|
||||
|
||||
if (user?.flags?.verifiedUsername == false && isActivityVisible) {
|
||||
if (user.flags?.verifiedUsername == false && isActivityVisible) {
|
||||
val intent = Intent(this, VerifyUsernameActivity::class.java)
|
||||
startActivity(intent)
|
||||
}
|
||||
|
||||
val quest = user?.party?.quest
|
||||
val quest = user.party?.quest
|
||||
if (quest?.completed?.isNotBlank() == true) {
|
||||
compositeSubscription.add(
|
||||
inventoryRepository.getQuestContent(user?.party?.quest?.completed ?: "").firstElement().subscribe(
|
||||
inventoryRepository.getQuestContent(user.party?.quest?.completed ?: "").firstElement().subscribe(
|
||||
{
|
||||
QuestCompletedDialog.showWithQuest(this, it)
|
||||
|
||||
userRepository.updateUser("party.quest.completed", "").subscribe({}, RxErrorHandler.handleEmptyError())
|
||||
viewModel.updateUser("party.quest.completed", "")
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
if (user?.flags?.welcomed == false) {
|
||||
compositeSubscription.add(userRepository.updateUser("flags.welcomed", true).subscribe({}, RxErrorHandler.handleEmptyError()))
|
||||
}
|
||||
|
||||
try {
|
||||
val navigationController = findNavController(R.id.nav_host_fragment)
|
||||
if (binding.toolbarTitle.text?.isNotBlank() != true) {
|
||||
navigationController.currentDestination?.let { updateToolbarTitle(it, null) }
|
||||
}
|
||||
} catch (e: java.lang.IllegalStateException) {
|
||||
// Has no Navcontroller right now.
|
||||
if (user.flags?.welcomed == false) {
|
||||
viewModel.updateUser("flags.welcomed", true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -491,44 +405,10 @@ open class MainActivity : BaseActivity(), TutorialView.OnTutorialReaction, Snack
|
|||
inventoryRepository.close()
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
fun feedPet(pet: Pet, food: Food) {
|
||||
compositeSubscription.add(
|
||||
this.inventoryRepository.feedPet(pet, food)
|
||||
.subscribe(
|
||||
{ feedResponse ->
|
||||
HabiticaSnackbar.showSnackbar(snackbarContainer, feedResponse.message, SnackbarDisplayType.NORMAL)
|
||||
if (feedResponse.value == -1) {
|
||||
val mountWrapper = View.inflate(this, R.layout.pet_imageview, null) as? FrameLayout
|
||||
val mountImageView = mountWrapper?.findViewById(R.id.pet_imageview) as? ImageView
|
||||
|
||||
DataBindingUtils.loadImage(mountImageView, "Mount_Icon_" + pet.key)
|
||||
val dialog = HabiticaAlertDialog(this@MainActivity)
|
||||
dialog.setTitle(getString(R.string.evolved_pet_title, pet.text))
|
||||
dialog.setAdditionalContentView(mountWrapper)
|
||||
dialog.addButton(R.string.onwards, true)
|
||||
dialog.addButton(R.string.share, false) { hatchingDialog, _ ->
|
||||
val message = getString(R.string.share_raised, pet.text)
|
||||
val mountImageSideLength = 99
|
||||
val sharedImage = Bitmap.createBitmap(mountImageSideLength, mountImageSideLength, Bitmap.Config.ARGB_8888)
|
||||
val canvas = Canvas(sharedImage)
|
||||
mountImageView?.drawable?.setBounds(0, 0, mountImageSideLength, mountImageSideLength)
|
||||
mountImageView?.drawable?.draw(canvas)
|
||||
shareContent("raisedPet", message, sharedImage)
|
||||
hatchingDialog.dismiss()
|
||||
}
|
||||
dialog.enqueue()
|
||||
}
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
internal fun displayTaskScoringResponse(data: TaskScoringResult?) {
|
||||
if (user != null && data != null) {
|
||||
if (viewModel.user.value != null && data != null) {
|
||||
val damageValue = when (userQuestStatus) {
|
||||
UserQuestStatus.QUEST_BOSS -> data.questDamage
|
||||
else -> 0.0
|
||||
|
|
@ -537,7 +417,7 @@ open class MainActivity : BaseActivity(), TutorialView.OnTutorialReaction, Snack
|
|||
notifyUserUseCase.observable(
|
||||
NotifyUserUseCase.RequestValues(
|
||||
this, snackbarContainer,
|
||||
user, data.experienceDelta, data.healthDelta, data.goldDelta, data.manaDelta, damageValue, data.hasLeveledUp, data.level
|
||||
viewModel.user.value, data.experienceDelta, data.healthDelta, data.goldDelta, data.manaDelta, damageValue, data.hasLeveledUp, data.level
|
||||
)
|
||||
)
|
||||
.subscribe({ }, RxErrorHandler.handleEmptyError())
|
||||
|
|
@ -552,31 +432,22 @@ open class MainActivity : BaseActivity(), TutorialView.OnTutorialReaction, Snack
|
|||
}
|
||||
|
||||
private fun displayDeathDialogIfNeeded() {
|
||||
if (user?.stats?.hp ?: 1.0 > 0) {
|
||||
if (!viewModel.isUserFainted) {
|
||||
return
|
||||
}
|
||||
|
||||
if (this.faintDialog == null && !this.isFinishing) {
|
||||
|
||||
val customView = View.inflate(this, R.layout.dialog_faint, null)
|
||||
if (customView != null) {
|
||||
val hpBarView = customView.findViewById<View>(R.id.hpBar) as? ValueBar
|
||||
|
||||
hpBarView?.setLightBackground(true)
|
||||
hpBarView?.setIcon(HabiticaIconsHelper.imageOfHeartLightBg())
|
||||
|
||||
val dialogAvatarView = customView.findViewById<View>(R.id.avatarView) as? AvatarView
|
||||
user?.let { dialogAvatarView?.setAvatar(it) }
|
||||
}
|
||||
val binding = DialogFaintBinding.inflate(this.layoutInflater)
|
||||
binding.hpBar.setLightBackground(true)
|
||||
binding.hpBar.setIcon(HabiticaIconsHelper.imageOfHeartLightBg())
|
||||
viewModel.user.value?.let { binding.avatarView.setAvatar(it) }
|
||||
|
||||
this.faintDialog = HabiticaAlertDialog(this)
|
||||
faintDialog?.setTitle(R.string.faint_header)
|
||||
faintDialog?.setAdditionalContentView(customView)
|
||||
faintDialog?.setAdditionalContentView(binding.root)
|
||||
faintDialog?.addButton(R.string.faint_button, true) { _, _ ->
|
||||
faintDialog = null
|
||||
user?.let {
|
||||
userRepository.revive(it).subscribe({ }, RxErrorHandler.handleEmptyError())
|
||||
}
|
||||
userRepository.revive().subscribe({ }, RxErrorHandler.handleEmptyError())
|
||||
}
|
||||
soundManager.loadAndPlayAudio(SoundManager.SoundDeath)
|
||||
this.faintDialog?.enqueue()
|
||||
|
|
@ -593,23 +464,7 @@ open class MainActivity : BaseActivity(), TutorialView.OnTutorialReaction, Snack
|
|||
}
|
||||
|
||||
protected fun retrieveUser(forced: Boolean = false) {
|
||||
if (hostConfig.hasAuthentication()) {
|
||||
compositeSubscription.add(
|
||||
contentRepository.retrieveWorldState(this)
|
||||
.flatMap { userRepository.retrieveUser(true, forced) }
|
||||
.doOnNext { user1 ->
|
||||
FirebaseAnalytics.getInstance(this).setUserProperty("has_party", if (user1.party?.id?.isNotEmpty() == true) "true" else "false")
|
||||
FirebaseAnalytics.getInstance(this).setUserProperty("is_subscribed", if (user1.isSubscribed) "true" else "false")
|
||||
FirebaseAnalytics.getInstance(this).setUserProperty("checkin_count", user1.loginIncentives.toString())
|
||||
FirebaseAnalytics.getInstance(this).setUserProperty("level", user1.stats?.lvl?.toString() ?: "")
|
||||
pushNotificationManager.setUser(user1)
|
||||
pushNotificationManager.addPushDeviceUsingStoredToken()
|
||||
}
|
||||
.flatMap { userRepository.retrieveTeamPlans() }
|
||||
.flatMap { contentRepository.retrieveContent(this) }
|
||||
.subscribe({ }, RxErrorHandler.handleEmptyError())
|
||||
)
|
||||
}
|
||||
viewModel.retrieveUser(forced)
|
||||
}
|
||||
|
||||
fun displayTutorialStep(step: TutorialStep, text: String, canBeDeferred: Boolean) {
|
||||
|
|
@ -620,12 +475,7 @@ open class MainActivity : BaseActivity(), TutorialView.OnTutorialReaction, Snack
|
|||
view.onReaction = this
|
||||
view.setCanBeDeferred(canBeDeferred)
|
||||
binding.overlayFrameLayout.addView(view)
|
||||
|
||||
val additionalData = HashMap<String, Any>()
|
||||
additionalData["eventLabel"] = step.identifier + "-android"
|
||||
additionalData["eventValue"] = step.identifier ?: ""
|
||||
additionalData["complete"] = false
|
||||
AmplitudeManager.sendEvent("tutorial", AmplitudeManager.EVENT_CATEGORY_BEHAVIOUR, AmplitudeManager.EVENT_HITTYPE_EVENT, additionalData)
|
||||
viewModel.logTutorialStatus(step, false)
|
||||
}
|
||||
|
||||
fun displayTutorialStep(step: TutorialStep, texts: List<String>, canBeDeferred: Boolean) {
|
||||
|
|
@ -636,27 +486,15 @@ open class MainActivity : BaseActivity(), TutorialView.OnTutorialReaction, Snack
|
|||
view.onReaction = this
|
||||
view.setCanBeDeferred(canBeDeferred)
|
||||
binding.overlayFrameLayout.addView(view)
|
||||
|
||||
val additionalData = HashMap<String, Any>()
|
||||
additionalData["eventLabel"] = step.identifier + "-android"
|
||||
additionalData["eventValue"] = step.identifier ?: ""
|
||||
additionalData["complete"] = false
|
||||
AmplitudeManager.sendEvent("tutorial", AmplitudeManager.EVENT_CATEGORY_BEHAVIOUR, AmplitudeManager.EVENT_HITTYPE_EVENT, additionalData)
|
||||
viewModel.logTutorialStatus(step, false)
|
||||
}
|
||||
|
||||
|
||||
override fun onTutorialCompleted(step: TutorialStep) {
|
||||
compositeSubscription.add(
|
||||
userRepository.updateUser("flags.tutorial." + step.tutorialGroup + "." + step.identifier, true)
|
||||
.subscribe({ }, RxErrorHandler.handleEmptyError())
|
||||
)
|
||||
viewModel.updateUser("flags.tutorial." + step.tutorialGroup + "." + step.identifier, true)
|
||||
binding.overlayFrameLayout.removeView(this.activeTutorialView)
|
||||
this.removeActiveTutorialView()
|
||||
|
||||
val additionalData = HashMap<String, Any>()
|
||||
additionalData["eventLabel"] = step.identifier + "-android"
|
||||
additionalData["eventValue"] = step.identifier ?: ""
|
||||
additionalData["complete"] = true
|
||||
AmplitudeManager.sendEvent("tutorial", AmplitudeManager.EVENT_CATEGORY_BEHAVIOUR, AmplitudeManager.EVENT_HITTYPE_EVENT, additionalData)
|
||||
viewModel.logTutorialStatus(step, true)
|
||||
}
|
||||
|
||||
override fun onTutorialDeferred(step: TutorialStep) {
|
||||
|
|
@ -672,36 +510,25 @@ open class MainActivity : BaseActivity(), TutorialView.OnTutorialReaction, Snack
|
|||
}
|
||||
|
||||
private fun checkMaintenance() {
|
||||
compositeSubscription.add(
|
||||
this.maintenanceService.maintenanceStatus
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(
|
||||
Consumer { maintenanceResponse ->
|
||||
if (maintenanceResponse == null) {
|
||||
return@Consumer
|
||||
}
|
||||
if (maintenanceResponse.activeMaintenance) {
|
||||
val intent = createMaintenanceIntent(maintenanceResponse, false)
|
||||
viewModel.ifNeedsMaintenance { maintenanceResponse ->
|
||||
if (maintenanceResponse.activeMaintenance) {
|
||||
val intent = createMaintenanceIntent(maintenanceResponse, false)
|
||||
startActivity(intent)
|
||||
} else {
|
||||
if (maintenanceResponse.minBuild != null) {
|
||||
try {
|
||||
val packageInfo = packageManager.getPackageInfo(packageName, 0)
|
||||
@Suppress("DEPRECATION")
|
||||
if (packageInfo.versionCode < maintenanceResponse.minBuild) {
|
||||
val intent = createMaintenanceIntent(maintenanceResponse, true)
|
||||
startActivity(intent)
|
||||
} else {
|
||||
if (maintenanceResponse.minBuild != null) {
|
||||
try {
|
||||
val packageInfo = packageManager.getPackageInfo(packageName, 0)
|
||||
@Suppress("DEPRECATION")
|
||||
if (packageInfo.versionCode < maintenanceResponse.minBuild) {
|
||||
val intent = createMaintenanceIntent(maintenanceResponse, true)
|
||||
startActivity(intent)
|
||||
}
|
||||
} catch (e: PackageManager.NameNotFoundException) {
|
||||
RxErrorHandler.reportError(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
)
|
||||
)
|
||||
} catch (e: PackageManager.NameNotFoundException) {
|
||||
RxErrorHandler.reportError(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun createMaintenanceIntent(maintenanceResponse: MaintenanceResponse, isDeprecationNotice: Boolean): Intent {
|
||||
|
|
@ -737,36 +564,4 @@ open class MainActivity : BaseActivity(), TutorialView.OnTutorialReaction, Snack
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun hatchPet(potion: HatchingPotion, egg: Egg) {
|
||||
compositeSubscription.add(
|
||||
this.inventoryRepository.hatchPet(egg, potion) {
|
||||
val petWrapper = View.inflate(this, R.layout.pet_imageview, null) as? FrameLayout
|
||||
val petImageView = petWrapper?.findViewById(R.id.pet_imageview) as? ImageView
|
||||
|
||||
DataBindingUtils.loadImage(petImageView, "stable_Pet-" + egg.key + "-" + potion.key)
|
||||
val potionName = potion.text
|
||||
val eggName = egg.text
|
||||
val dialog = HabiticaAlertDialog(this)
|
||||
dialog.setTitle(getString(R.string.hatched_pet_title, potionName, eggName))
|
||||
dialog.setAdditionalContentView(petWrapper)
|
||||
dialog.addButton(R.string.equip, true) { _, _ ->
|
||||
inventoryRepository.equip(user, "pet", egg.key + "-" + potion.key)
|
||||
.subscribe({}, RxErrorHandler.handleEmptyError())
|
||||
}
|
||||
dialog.addButton(R.string.share, false) { hatchingDialog, _ ->
|
||||
val message = getString(R.string.share_hatched, potionName, eggName)
|
||||
val petImageSideLength = 140
|
||||
val sharedImage = Bitmap.createBitmap(petImageSideLength, petImageSideLength, Bitmap.Config.ARGB_8888)
|
||||
val canvas = Canvas(sharedImage)
|
||||
petImageView?.drawable?.setBounds(0, 0, petImageSideLength, petImageSideLength)
|
||||
petImageView?.drawable?.draw(canvas)
|
||||
shareContent("hatchedPet", message, sharedImage)
|
||||
hatchingDialog.dismiss()
|
||||
}
|
||||
dialog.setExtraCloseButtonVisibility(View.VISIBLE)
|
||||
dialog.enqueue()
|
||||
}.subscribe({ }, RxErrorHandler.handleEmptyError())
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ import android.os.Bundle
|
|||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.widget.*
|
||||
import androidx.activity.viewModels
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.components.UserComponent
|
||||
import com.habitrpg.android.habitica.data.InventoryRepository
|
||||
|
|
@ -30,7 +30,7 @@ class NotificationsActivity : BaseActivity(), androidx.swiperefreshlayout.widget
|
|||
@Inject
|
||||
lateinit var socialRepository: SocialRepository
|
||||
|
||||
lateinit var viewModel: NotificationsViewModel
|
||||
val viewModel: NotificationsViewModel by viewModels()
|
||||
|
||||
var inflater: LayoutInflater? = null
|
||||
|
||||
|
|
@ -50,8 +50,6 @@ class NotificationsActivity : BaseActivity(), androidx.swiperefreshlayout.widget
|
|||
|
||||
inflater = getSystemService(Context.LAYOUT_INFLATER_SERVICE) as? LayoutInflater
|
||||
|
||||
viewModel = ViewModelProvider(this).get(NotificationsViewModel::class.java)
|
||||
|
||||
compositeSubscription.add(
|
||||
viewModel.getNotifications().subscribe(
|
||||
{
|
||||
|
|
|
|||
|
|
@ -10,6 +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.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.proxy.AnalyticsManager
|
||||
import com.habitrpg.android.habitica.ui.activities.MainActivity
|
||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.rxjava3.disposables.CompositeDisposable
|
||||
|
|
@ -25,6 +26,8 @@ abstract class BaseFragment<VB : ViewBinding> : Fragment() {
|
|||
|
||||
@Inject
|
||||
lateinit var tutorialRepository: TutorialRepository
|
||||
@Inject
|
||||
lateinit var analyticsManager: AnalyticsManager
|
||||
|
||||
var tutorialStepIdentifier: String? = null
|
||||
var tutorialText: String? = null
|
||||
|
|
|
|||
|
|
@ -44,8 +44,8 @@ abstract class BaseMainFragment<VB : ViewBinding> : BaseFragment<VB>() {
|
|||
override fun onAttach(context: Context) {
|
||||
super.onAttach(context)
|
||||
|
||||
if (getActivity()?.javaClass == MainActivity::class.java) {
|
||||
user = activity?.user
|
||||
if (activity is MainActivity) {
|
||||
user = activity?.viewModel?.user?.value
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,9 +16,12 @@ import com.habitrpg.android.habitica.extensions.addCloseButton
|
|||
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.interactors.FeedPetUseCase
|
||||
import com.habitrpg.android.habitica.interactors.HatchPetUseCase
|
||||
import com.habitrpg.android.habitica.models.inventory.*
|
||||
import com.habitrpg.android.habitica.models.user.OwnedPet
|
||||
import com.habitrpg.android.habitica.models.user.User
|
||||
import com.habitrpg.android.habitica.ui.activities.BaseActivity
|
||||
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
|
||||
|
|
@ -36,6 +39,11 @@ class ItemDialogFragment : BaseDialogFragment<FragmentItemsBinding>(), SwipeRefr
|
|||
lateinit var socialRepository: SocialRepository
|
||||
@Inject
|
||||
lateinit var userRepository: UserRepository
|
||||
@Inject
|
||||
lateinit var hatchPetUseCase: HatchPetUseCase
|
||||
@Inject
|
||||
lateinit var feedPetUseCase: FeedPetUseCase
|
||||
|
||||
var adapter: ItemRecyclerAdapter? = null
|
||||
var itemType: String? = null
|
||||
var itemTypeText: String? = null
|
||||
|
|
@ -194,7 +202,14 @@ class ItemDialogFragment : BaseDialogFragment<FragmentItemsBinding>(), SwipeRefr
|
|||
}
|
||||
|
||||
private fun feedPet(food: Food) {
|
||||
feedingPet?.let { (activity as? MainActivity)?.feedPet(it, food) }
|
||||
val pet = feedingPet ?: return
|
||||
(activity as? BaseActivity)?.let {
|
||||
compositeSubscription.add(feedPetUseCase.observable(
|
||||
FeedPetUseCase.RequestValues(
|
||||
pet, food,
|
||||
it
|
||||
)).subscribeWithErrorHandler {})
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
|
|
@ -225,7 +240,13 @@ class ItemDialogFragment : BaseDialogFragment<FragmentItemsBinding>(), SwipeRefr
|
|||
|
||||
private fun hatchPet(potion: HatchingPotion, egg: Egg) {
|
||||
dismiss()
|
||||
(activity as? MainActivity)?.hatchPet(potion, egg)
|
||||
(activity as? BaseActivity)?.let {
|
||||
compositeSubscription.add(hatchPetUseCase.observable(
|
||||
HatchPetUseCase.RequestValues(
|
||||
potion, egg,
|
||||
it
|
||||
)).subscribeWithErrorHandler {})
|
||||
}
|
||||
}
|
||||
|
||||
private fun loadItems() {
|
||||
|
|
|
|||
|
|
@ -15,9 +15,12 @@ import com.habitrpg.android.habitica.extensions.addCloseButton
|
|||
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.interactors.HatchPetUseCase
|
||||
import com.habitrpg.android.habitica.interactors.NotifyUserUseCase
|
||||
import com.habitrpg.android.habitica.models.inventory.*
|
||||
import com.habitrpg.android.habitica.models.user.OwnedPet
|
||||
import com.habitrpg.android.habitica.models.user.User
|
||||
import com.habitrpg.android.habitica.ui.activities.BaseActivity
|
||||
import com.habitrpg.android.habitica.ui.activities.MainActivity
|
||||
import com.habitrpg.android.habitica.ui.adapter.inventory.ItemRecyclerAdapter
|
||||
import com.habitrpg.android.habitica.ui.fragments.BaseFragment
|
||||
|
|
@ -35,6 +38,9 @@ class ItemRecyclerFragment : BaseFragment<FragmentItemsBinding>(), SwipeRefreshL
|
|||
lateinit var socialRepository: SocialRepository
|
||||
@Inject
|
||||
lateinit var userRepository: UserRepository
|
||||
@Inject
|
||||
internal lateinit var hatchPetUseCase: HatchPetUseCase
|
||||
|
||||
var adapter: ItemRecyclerAdapter? = null
|
||||
var itemType: String? = null
|
||||
var itemTypeText: String? = null
|
||||
|
|
@ -178,7 +184,13 @@ class ItemRecyclerFragment : BaseFragment<FragmentItemsBinding>(), SwipeRefreshL
|
|||
}
|
||||
|
||||
private fun hatchPet(potion: HatchingPotion, egg: Egg) {
|
||||
(activity as? MainActivity)?.hatchPet(potion, egg)
|
||||
(activity as? BaseActivity)?.let {
|
||||
compositeSubscription.add(hatchPetUseCase.observable(
|
||||
HatchPetUseCase.RequestValues(
|
||||
potion, egg,
|
||||
it
|
||||
)).subscribeWithErrorHandler {})
|
||||
}
|
||||
}
|
||||
|
||||
private fun loadItems() {
|
||||
|
|
|
|||
|
|
@ -149,7 +149,7 @@ open class ShopFragment : BaseMainFragment<FragmentRefreshRecyclerviewBinding>()
|
|||
|
||||
currencyView.hourglassVisibility = View.GONE
|
||||
|
||||
context?.let { FirebaseAnalytics.getInstance(it).logEvent("open_shop", bundleOf(Pair("shopIdentifier", shopIdentifier))) }
|
||||
context?.let { analyticsManager.logEvent("open_shop", bundleOf(Pair("shopIdentifier", shopIdentifier))) }
|
||||
}
|
||||
|
||||
private fun showClassChangeDialog(classIdentifier: String) {
|
||||
|
|
|
|||
|
|
@ -10,10 +10,14 @@ 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.extensions.subscribeWithErrorHandler
|
||||
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.*
|
||||
import com.habitrpg.android.habitica.models.user.OwnedMount
|
||||
import com.habitrpg.android.habitica.models.user.OwnedPet
|
||||
import com.habitrpg.android.habitica.ui.activities.BaseActivity
|
||||
import com.habitrpg.android.habitica.ui.adapter.inventory.PetDetailRecyclerAdapter
|
||||
import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment
|
||||
import com.habitrpg.android.habitica.ui.fragments.inventory.items.ItemDialogFragment
|
||||
|
|
@ -28,6 +32,8 @@ class PetDetailRecyclerFragment :
|
|||
|
||||
@Inject
|
||||
lateinit var inventoryRepository: InventoryRepository
|
||||
@Inject
|
||||
lateinit var feedPetUseCase: FeedPetUseCase
|
||||
|
||||
var adapter: PetDetailRecyclerAdapter = PetDetailRecyclerAdapter()
|
||||
private var animalType: String? = null
|
||||
|
|
@ -192,7 +198,13 @@ class PetDetailRecyclerFragment :
|
|||
|
||||
private fun showFeedingDialog(pet: Pet, food: Food?) {
|
||||
if (food != null) {
|
||||
activity?.feedPet(pet, food)
|
||||
(activity as? BaseActivity)?.let {
|
||||
compositeSubscription.add(feedPetUseCase.observable(
|
||||
FeedPetUseCase.RequestValues(
|
||||
pet, food,
|
||||
it
|
||||
)).subscribeWithErrorHandler {})
|
||||
}
|
||||
return
|
||||
}
|
||||
val fragment = ItemDialogFragment()
|
||||
|
|
|
|||
|
|
@ -139,7 +139,7 @@ class PreferencesFragment : BasePreferencesFragment(), SharedPreferences.OnShare
|
|||
(activity as? SnackbarActivity)?.showSnackbar(
|
||||
content = context?.getString(R.string.reloading_content)
|
||||
)
|
||||
contentRepository.retrieveContent(context, true).subscribe(
|
||||
contentRepository.retrieveContent(true).subscribe(
|
||||
{
|
||||
(activity as? SnackbarActivity)?.showSnackbar(
|
||||
content = context?.getString(R.string.reloaded_content),
|
||||
|
|
@ -220,7 +220,7 @@ class PreferencesFragment : BasePreferencesFragment(), SharedPreferences.OnShare
|
|||
}
|
||||
|
||||
userRepository.updateLanguage(languageHelper.languageCode ?: "en")
|
||||
.flatMap { contentRepository.retrieveContent(context, true) }
|
||||
.flatMap { contentRepository.retrieveContent(true) }
|
||||
.subscribe({ }, RxErrorHandler.handleEmptyError())
|
||||
|
||||
val intent = Intent(activity, MainActivity::class.java)
|
||||
|
|
|
|||
|
|
@ -23,8 +23,6 @@ import javax.inject.Inject
|
|||
|
||||
class GiftPurchaseGemsFragment : BaseFragment<FragmentGiftGemPurchaseBinding>() {
|
||||
|
||||
@Inject
|
||||
lateinit var analyticsManager: AnalyticsManager
|
||||
@Inject
|
||||
lateinit var socialRepository: SocialRepository
|
||||
|
||||
|
|
|
|||
|
|
@ -45,8 +45,6 @@ class SubscriptionFragment : BaseFragment<FragmentSubscriptionBinding>() {
|
|||
return FragmentSubscriptionBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
@Inject
|
||||
lateinit var analyticsManager: AnalyticsManager
|
||||
@Inject
|
||||
lateinit var userRepository: UserRepository
|
||||
@Inject
|
||||
|
|
|
|||
|
|
@ -31,7 +31,11 @@ import io.reactivex.rxjava3.disposables.Disposable
|
|||
import java.util.concurrent.TimeUnit
|
||||
import javax.inject.Inject
|
||||
|
||||
class ChatFragment : BaseFragment<FragmentChatBinding>() {
|
||||
class ChatFragment() : BaseFragment<FragmentChatBinding>() {
|
||||
|
||||
constructor(viewModel: GroupViewModel) : this() {
|
||||
this.viewModel = viewModel
|
||||
}
|
||||
|
||||
override var binding: FragmentChatBinding? = null
|
||||
|
||||
|
|
@ -67,9 +71,7 @@ class ChatFragment : BaseFragment<FragmentChatBinding>() {
|
|||
chatAdapter?.let { adapter ->
|
||||
compositeSubscription.add(
|
||||
adapter.getUserLabelClickFlowable().subscribe(
|
||||
{ userId ->
|
||||
FullProfileActivity.open(userId)
|
||||
},
|
||||
{ userId -> FullProfileActivity.open(userId) },
|
||||
RxErrorHandler.handleEmptyError()
|
||||
)
|
||||
)
|
||||
|
|
@ -95,12 +97,7 @@ class ChatFragment : BaseFragment<FragmentChatBinding>() {
|
|||
}
|
||||
})
|
||||
|
||||
viewModel?.chatmessages?.observe(
|
||||
viewLifecycleOwner,
|
||||
{
|
||||
setChatMessages(it)
|
||||
}
|
||||
)
|
||||
viewModel?.chatmessages?.observe(viewLifecycleOwner, { setChatMessages(it) })
|
||||
|
||||
binding?.chatBarView?.onCommunityGuidelinesAccepted = {
|
||||
viewModel?.updateUser("flags.communityGuidelinesAccepted", true)
|
||||
|
|
@ -131,7 +128,7 @@ class ChatFragment : BaseFragment<FragmentChatBinding>() {
|
|||
}
|
||||
|
||||
private fun startAutoRefreshing() {
|
||||
if (refreshDisposable != null && refreshDisposable?.isDisposed != true) {
|
||||
if (refreshDisposable?.isDisposed != true) {
|
||||
refreshDisposable?.dispose()
|
||||
}
|
||||
refreshDisposable = Observable.interval(30, TimeUnit.SECONDS)
|
||||
|
|
@ -219,11 +216,7 @@ class ChatFragment : BaseFragment<FragmentChatBinding>() {
|
|||
private fun sendChatMessage(chatText: String) {
|
||||
viewModel?.postGroupChat(
|
||||
chatText,
|
||||
{
|
||||
binding?.recyclerView?.scrollToPosition(0)
|
||||
}
|
||||
) {
|
||||
binding?.chatBarView?.message = chatText
|
||||
}
|
||||
{ binding?.recyclerView?.scrollToPosition(0) }
|
||||
) { binding?.chatBarView?.message = chatText }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import android.content.Context
|
|||
import android.os.Bundle
|
||||
import android.view.*
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.fragment.app.viewModels
|
||||
import com.habitrpg.android.habitica.MainNavDirections
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.components.UserComponent
|
||||
|
|
@ -51,7 +51,9 @@ class InboxMessageListFragment : BaseMainFragment<FragmentInboxMessageListBindin
|
|||
private var chatRoomUser: String? = null
|
||||
private var replyToUserUUID: String? = null
|
||||
|
||||
private var viewModel: InboxViewModel? = null
|
||||
private val viewModel: InboxViewModel by viewModels(factoryProducer = {
|
||||
InboxViewModelFactory(replyToUserUUID, chatRoomUser)
|
||||
})
|
||||
private var refreshDisposable: Disposable? = null
|
||||
|
||||
override fun onCreateView(
|
||||
|
|
@ -71,7 +73,6 @@ class InboxMessageListFragment : BaseMainFragment<FragmentInboxMessageListBindin
|
|||
val args = InboxMessageListFragmentArgs.fromBundle(it)
|
||||
setReceivingUser(args.username, args.userID)
|
||||
}
|
||||
viewModel = ViewModelProvider(this, InboxViewModelFactory(replyToUserUUID, chatRoomUser)).get(InboxViewModel::class.java)
|
||||
|
||||
val layoutManager = androidx.recyclerview.widget.LinearLayoutManager(this.getActivity())
|
||||
layoutManager.reverseLayout = true
|
||||
|
|
@ -88,9 +89,7 @@ class InboxMessageListFragment : BaseMainFragment<FragmentInboxMessageListBindin
|
|||
setReceivingUser(member.username, member.id)
|
||||
activity?.title = member.displayName
|
||||
chatAdapter = InboxAdapter(user, member)
|
||||
viewModel?.messages?.observe(
|
||||
this.viewLifecycleOwner
|
||||
) {
|
||||
viewModel.messages.observe(this.viewLifecycleOwner) {
|
||||
markMessagesAsRead(it)
|
||||
chatAdapter?.submitList(it)
|
||||
}
|
||||
|
|
@ -197,32 +196,32 @@ class InboxMessageListFragment : BaseMainFragment<FragmentInboxMessageListBindin
|
|||
}
|
||||
|
||||
private fun refreshConversation() {
|
||||
if (viewModel?.memberID?.isNotBlank() != true) { return }
|
||||
if (viewModel.memberID?.isNotBlank() != true) { return }
|
||||
compositeSubscription.add(
|
||||
this.socialRepository.retrieveInboxMessages(replyToUserUUID ?: "", 0)
|
||||
.subscribe(
|
||||
{}, RxErrorHandler.handleEmptyError(),
|
||||
{
|
||||
viewModel?.invalidateDataSource()
|
||||
viewModel.invalidateDataSource()
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private fun sendMessage(chatText: String) {
|
||||
viewModel?.memberID?.let { userID ->
|
||||
viewModel.memberID?.let { userID ->
|
||||
socialRepository.postPrivateMessage(userID, chatText)
|
||||
.delay(200, TimeUnit.MILLISECONDS)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(
|
||||
{
|
||||
binding?.recyclerView?.scrollToPosition(0)
|
||||
viewModel?.invalidateDataSource()
|
||||
viewModel.invalidateDataSource()
|
||||
},
|
||||
{ error ->
|
||||
RxErrorHandler.reportError(error)
|
||||
if (binding != null) {
|
||||
val alert = HabiticaAlertDialog(binding!!.chatBarView.context)
|
||||
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()
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ package com.habitrpg.android.habitica.ui.fragments.social
|
|||
import android.os.Bundle
|
||||
import android.view.*
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.viewpager2.adapter.FragmentStateAdapter
|
||||
import com.google.android.material.tabs.TabLayoutMediator
|
||||
import com.habitrpg.android.habitica.R
|
||||
|
|
@ -27,10 +27,7 @@ class TavernFragment : BaseMainFragment<FragmentViewpagerBinding>() {
|
|||
return FragmentViewpagerBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
internal lateinit var viewModel: GroupViewModel
|
||||
|
||||
internal var tavernDetailFragment = TavernDetailFragment()
|
||||
private var chatFragment: ChatFragment? = null
|
||||
internal val viewModel: GroupViewModel by viewModels()
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
|
|
@ -48,7 +45,6 @@ class TavernFragment : BaseMainFragment<FragmentViewpagerBinding>() {
|
|||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
viewModel = ViewModelProvider(this).get(GroupViewModel::class.java)
|
||||
viewModel.groupViewType = GroupViewType.GUILD
|
||||
viewModel.setGroupID(Group.TAVERN_ID)
|
||||
|
||||
|
|
@ -90,9 +86,7 @@ class TavernFragment : BaseMainFragment<FragmentViewpagerBinding>() {
|
|||
TavernDetailFragment()
|
||||
}
|
||||
1 -> {
|
||||
chatFragment = ChatFragment()
|
||||
chatFragment?.viewModel = viewModel
|
||||
chatFragment ?: Fragment()
|
||||
ChatFragment(viewModel)
|
||||
}
|
||||
else -> Fragment()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ import com.habitrpg.android.habitica.ui.helpers.setMarkdown
|
|||
import com.habitrpg.android.habitica.ui.viewmodels.GroupViewModel
|
||||
import com.habitrpg.android.habitica.ui.views.HabiticaIcons
|
||||
import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper
|
||||
import com.habitrpg.android.habitica.ui.views.HabiticaSnackbar
|
||||
import com.habitrpg.android.habitica.ui.views.SnackbarActivity
|
||||
import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaAlertDialog
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.delay
|
||||
|
|
@ -75,10 +75,7 @@ class GuildDetailFragment : BaseFragment<FragmentGuildDetailBinding>() {
|
|||
}
|
||||
binding?.joinButton?.setOnClickListener {
|
||||
viewModel?.joinGroup {
|
||||
val activity = activity as? MainActivity
|
||||
if (activity != null) {
|
||||
HabiticaSnackbar.showSnackbar(activity.snackbarContainer, getString(R.string.joined_guild), HabiticaSnackbar.SnackbarDisplayType.NORMAL)
|
||||
}
|
||||
(this.activity as? SnackbarActivity)?.showSnackbar(title = getString(R.string.joined_guild))
|
||||
}
|
||||
}
|
||||
binding?.inviteButton?.setOnClickListener {
|
||||
|
|
@ -86,7 +83,7 @@ class GuildDetailFragment : BaseFragment<FragmentGuildDetailBinding>() {
|
|||
sendInvitesResult.launch(intent)
|
||||
}
|
||||
binding?.leaderWrapper?.setOnClickListener {
|
||||
viewModel?.getGroupData()?.value?.leaderID?.let { leaderID ->
|
||||
viewModel?.leaderID?.let { leaderID ->
|
||||
val profileDirections = MainNavDirections.openProfileActivity(leaderID)
|
||||
MainNavigationController.navigate(profileDirections)
|
||||
}
|
||||
|
|
@ -98,7 +95,7 @@ class GuildDetailFragment : BaseFragment<FragmentGuildDetailBinding>() {
|
|||
return
|
||||
}
|
||||
binding?.leaderAvatarView?.setAvatar(leader)
|
||||
binding?.leaderProfileName?.username = leader.profile?.name
|
||||
binding?.leaderProfileName?.username = leader.displayName
|
||||
binding?.leaderProfileName?.tier = leader.contributor?.level ?: 0
|
||||
binding?.leaderUsername?.text = leader.formattedUsername
|
||||
}
|
||||
|
|
@ -140,7 +137,7 @@ class GuildDetailFragment : BaseFragment<FragmentGuildDetailBinding>() {
|
|||
}
|
||||
|
||||
private fun getGroupChallenges(): List<Challenge> {
|
||||
var groupChallenges = mutableListOf<Challenge>()
|
||||
val groupChallenges = mutableListOf<Challenge>()
|
||||
userRepository.getUser(userId).forEach {
|
||||
it.challenges?.forEach {
|
||||
challengeRepository.getChallenge(it.challengeID).forEach {
|
||||
|
|
@ -156,7 +153,7 @@ class GuildDetailFragment : BaseFragment<FragmentGuildDetailBinding>() {
|
|||
internal fun leaveGuild() {
|
||||
val context = context
|
||||
if (context != null) {
|
||||
var groupChallenges = getGroupChallenges()
|
||||
val groupChallenges = getGroupChallenges()
|
||||
lifecycleScope.launch(Dispatchers.Main) {
|
||||
delay(500)
|
||||
if (groupChallenges.isNotEmpty()) {
|
||||
|
|
@ -188,10 +185,7 @@ class GuildDetailFragment : BaseFragment<FragmentGuildDetailBinding>() {
|
|||
}
|
||||
|
||||
private fun showLeaveSnackbar() {
|
||||
val activity = activity as? MainActivity
|
||||
if (activity != null) {
|
||||
HabiticaSnackbar.showSnackbar(activity.snackbarContainer, getString(R.string.left_guild), HabiticaSnackbar.SnackbarDisplayType.NORMAL)
|
||||
}
|
||||
(this.activity as? MainActivity)?.showSnackbar(title = getString(R.string.left_guild))
|
||||
}
|
||||
|
||||
override fun injectFragment(component: UserComponent) {
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import android.os.Bundle
|
|||
import android.view.*
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.viewpager2.adapter.FragmentStateAdapter
|
||||
import androidx.viewpager2.widget.ViewPager2
|
||||
import com.google.android.material.tabs.TabLayoutMediator
|
||||
|
|
@ -23,7 +23,7 @@ import com.habitrpg.android.habitica.ui.viewmodels.GroupViewType
|
|||
|
||||
class GuildFragment : BaseMainFragment<FragmentViewpagerBinding>() {
|
||||
|
||||
internal lateinit var viewModel: GroupViewModel
|
||||
internal val viewModel: GroupViewModel by viewModels()
|
||||
private var guildInformationFragment: GuildDetailFragment? = null
|
||||
private var chatFragment: ChatFragment? = null
|
||||
|
||||
|
|
@ -51,7 +51,6 @@ class GuildFragment : BaseMainFragment<FragmentViewpagerBinding>() {
|
|||
showsBackButton = true
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
viewModel = ViewModelProvider(this).get(GroupViewModel::class.java)
|
||||
viewModel.groupViewType = GroupViewType.GUILD
|
||||
viewModel.getGroupData().observe(viewLifecycleOwner, { setGroup(it) })
|
||||
viewModel.getIsMemberData().observe(viewLifecycleOwner, { activity?.invalidateOptionsMenu() })
|
||||
|
|
@ -95,10 +94,9 @@ class GuildFragment : BaseMainFragment<FragmentViewpagerBinding>() {
|
|||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||
val guild = viewModel.getGroupData().value
|
||||
if (this.activity != null && guild != null) {
|
||||
if (this.activity != null) {
|
||||
if (viewModel.isMember) {
|
||||
if (this.user != null && this.user?.id == guild.leaderID) {
|
||||
if (viewModel.isLeader) {
|
||||
this.activity?.menuInflater?.inflate(R.menu.guild_admin, menu)
|
||||
} else {
|
||||
this.activity?.menuInflater?.inflate(R.menu.guild_member, menu)
|
||||
|
|
@ -219,7 +217,7 @@ class GuildFragment : BaseMainFragment<FragmentViewpagerBinding>() {
|
|||
private fun setGroup(group: Group?) {
|
||||
this.activity?.invalidateOptionsMenu()
|
||||
|
||||
if (group?.privacy == "public") {
|
||||
if (viewModel.isPublicGuild) {
|
||||
chatFragment?.autocompleteContext = "publicGuild"
|
||||
} else {
|
||||
chatFragment?.autocompleteContext = "privateGuild"
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import android.os.Bundle
|
|||
import android.view.*
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.viewpager2.adapter.FragmentStateAdapter
|
||||
import androidx.viewpager2.widget.ViewPager2
|
||||
import com.google.android.material.tabs.TabLayoutMediator
|
||||
|
|
@ -28,7 +28,7 @@ class PartyFragment : BaseMainFragment<FragmentViewpagerBinding>() {
|
|||
private var chatFragment: ChatFragment? = null
|
||||
private var viewPagerAdapter: FragmentStateAdapter? = null
|
||||
|
||||
internal lateinit var viewModel: PartyViewModel
|
||||
internal val viewModel: PartyViewModel by viewModels()
|
||||
|
||||
override var binding: FragmentViewpagerBinding? = null
|
||||
|
||||
|
|
@ -49,8 +49,6 @@ class PartyFragment : BaseMainFragment<FragmentViewpagerBinding>() {
|
|||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
viewModel = ViewModelProvider(this)
|
||||
.get(PartyViewModel::class.java)
|
||||
viewModel.groupViewType = GroupViewType.PARTY
|
||||
|
||||
viewModel.getGroupData().observe(
|
||||
|
|
|
|||
|
|
@ -439,7 +439,7 @@ open class TaskRecyclerViewFragment : BaseFragment<FragmentRefreshRecyclerviewBi
|
|||
when (taskType) {
|
||||
TaskType.TODO -> taskFilterHelper.setActiveFilter(TaskType.TODO, Task.FILTER_ACTIVE)
|
||||
TaskType.DAILY -> {
|
||||
val user = (activity as? MainActivity)?.user
|
||||
val user = (activity as? MainActivity)?.viewModel?.user?.value
|
||||
if (user?.isValid == true && user.preferences?.dailyDueDefaultView == true) {
|
||||
taskFilterHelper.setActiveFilter(TaskType.DAILY, Task.FILTER_ACTIVE)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,11 @@ import javax.inject.Inject
|
|||
|
||||
abstract class BaseViewModel(initializeComponent: Boolean = true) : ViewModel() {
|
||||
|
||||
val isUserFainted: Boolean
|
||||
get() = (user.value?.stats?.hp ?: 1.0) == 0.0
|
||||
val isUserInParty: Boolean
|
||||
get() = user.value?.hasParty == true
|
||||
|
||||
@Inject
|
||||
lateinit var userRepository: UserRepository
|
||||
|
||||
|
|
@ -42,7 +47,7 @@ abstract class BaseViewModel(initializeComponent: Boolean = true) : ViewModel()
|
|||
|
||||
internal val disposable = CompositeDisposable()
|
||||
|
||||
private fun loadUserFromLocal() {
|
||||
internal fun loadUserFromLocal() {
|
||||
disposable.add(userRepository.getUser().observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe({ _user.value = it }, RxErrorHandler.handleEmptyError()))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -109,6 +109,10 @@ open class GroupViewModel(initializeComponent: Boolean) : BaseViewModel(initiali
|
|||
get() = isMemberData.value ?: false
|
||||
val leaderID: String?
|
||||
get() = group.value?.leaderID
|
||||
val isLeader: Boolean
|
||||
get() = user.value?.id == leaderID
|
||||
val isPublicGuild: Boolean
|
||||
get() = group.value?.privacy == "public"
|
||||
|
||||
fun getGroupData(): LiveData<Group?> = group
|
||||
fun getLeaderData(): LiveData<Member?> = leader
|
||||
|
|
|
|||
|
|
@ -0,0 +1,162 @@
|
|||
package com.habitrpg.android.habitica.ui.viewmodels
|
||||
|
||||
import android.content.SharedPreferences
|
||||
import androidx.core.content.edit
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.api.HostConfig
|
||||
import com.habitrpg.android.habitica.api.MaintenanceApiService
|
||||
import com.habitrpg.android.habitica.components.UserComponent
|
||||
import com.habitrpg.android.habitica.data.ContentRepository
|
||||
import com.habitrpg.android.habitica.data.InventoryRepository
|
||||
import com.habitrpg.android.habitica.data.TaskRepository
|
||||
import com.habitrpg.android.habitica.helpers.AmplitudeManager
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.helpers.TaskAlarmManager
|
||||
import com.habitrpg.android.habitica.helpers.notifications.PushNotificationManager
|
||||
import com.habitrpg.android.habitica.models.TutorialStep
|
||||
import com.habitrpg.android.habitica.models.inventory.Egg
|
||||
import com.habitrpg.android.habitica.models.responses.MaintenanceResponse
|
||||
import com.habitrpg.android.habitica.proxy.AnalyticsManager
|
||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.rxjava3.schedulers.Schedulers
|
||||
import io.realm.kotlin.isValid
|
||||
import java.util.*
|
||||
import javax.inject.Inject
|
||||
|
||||
class MainActivityViewModel: BaseViewModel() {
|
||||
@Inject
|
||||
internal lateinit var hostConfig: HostConfig
|
||||
@Inject
|
||||
internal lateinit var pushNotificationManager: PushNotificationManager
|
||||
@Inject
|
||||
internal lateinit var sharedPreferences: SharedPreferences
|
||||
@Inject
|
||||
internal lateinit var contentRepository: ContentRepository
|
||||
@Inject
|
||||
internal lateinit var taskRepository: TaskRepository
|
||||
@Inject
|
||||
internal lateinit var inventoryRepository: InventoryRepository
|
||||
@Inject
|
||||
internal lateinit var taskAlarmManager: TaskAlarmManager
|
||||
@Inject
|
||||
internal lateinit var analyticsManager: AnalyticsManager
|
||||
@Inject
|
||||
internal lateinit var maintenanceService: MaintenanceApiService
|
||||
|
||||
override fun inject(component: UserComponent) {
|
||||
component.inject(this)
|
||||
}
|
||||
|
||||
val isAuthenticated: Boolean
|
||||
get() = hostConfig.apiKey.isNotBlank() && hostConfig.userID.isNotBlank()
|
||||
val launchScreen: String?
|
||||
get() = sharedPreferences.getString("launch_screen", "")
|
||||
var preferenceLanguage: String?
|
||||
get() = sharedPreferences.getString("language", "en")
|
||||
set(value) {
|
||||
sharedPreferences.edit {
|
||||
putString("language", value)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCleared() {
|
||||
taskRepository.close()
|
||||
inventoryRepository.close()
|
||||
contentRepository.close()
|
||||
super.onCleared()
|
||||
}
|
||||
|
||||
fun onCreate() {
|
||||
try {
|
||||
taskAlarmManager.scheduleAllSavedAlarms(sharedPreferences.getBoolean("preventDailyReminder", false))
|
||||
} catch (e: Exception) {
|
||||
analyticsManager.logException(e)
|
||||
}
|
||||
}
|
||||
|
||||
fun onResume() {
|
||||
// Track when the app was last opened, so that we can use this to send out special reminders after a week of inactivity
|
||||
sharedPreferences.edit {
|
||||
putLong("lastAppLaunch", Date().time)
|
||||
putBoolean("preventDailyReminder", false)
|
||||
}
|
||||
}
|
||||
|
||||
fun retrieveUser(forced: Boolean = false) {
|
||||
if (hostConfig.hasAuthentication()) {
|
||||
disposable.add(
|
||||
contentRepository.retrieveWorldState()
|
||||
.flatMap { userRepository.retrieveUser(true, forced) }
|
||||
.doOnNext { user1 ->
|
||||
analyticsManager.setUserProperty("has_party", if (user1.party?.id?.isNotEmpty() == true) "true" else "false")
|
||||
analyticsManager.setUserProperty("is_subscribed", if (user1.isSubscribed) "true" else "false")
|
||||
analyticsManager.setUserProperty("checkin_count", user1.loginIncentives.toString())
|
||||
analyticsManager.setUserProperty("level", user1.stats?.lvl?.toString() ?: "")
|
||||
pushNotificationManager.setUser(user1)
|
||||
pushNotificationManager.addPushDeviceUsingStoredToken()
|
||||
}
|
||||
.flatMap { userRepository.retrieveTeamPlans() }
|
||||
.flatMap { contentRepository.retrieveContent() }
|
||||
.subscribe({ }, RxErrorHandler.handleEmptyError())
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun logTutorialStatus(step: TutorialStep, complete: Boolean) {
|
||||
val additionalData = HashMap<String, Any>()
|
||||
additionalData["eventLabel"] = step.identifier + "-android"
|
||||
additionalData["eventValue"] = step.identifier ?: ""
|
||||
additionalData["complete"] = complete
|
||||
AmplitudeManager.sendEvent(
|
||||
"tutorial",
|
||||
AmplitudeManager.EVENT_CATEGORY_BEHAVIOUR,
|
||||
AmplitudeManager.EVENT_HITTYPE_EVENT,
|
||||
additionalData
|
||||
)
|
||||
}
|
||||
|
||||
fun ifNeedsMaintenance(onResult: ((MaintenanceResponse) -> Unit)) {
|
||||
disposable.add(
|
||||
this.maintenanceService.maintenanceStatus
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe( { maintenanceResponse ->
|
||||
if (maintenanceResponse == null) {
|
||||
return@subscribe
|
||||
}
|
||||
onResult(maintenanceResponse)
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
fun getToolbarTitle(id: Int, label: CharSequence?, eggType: String?, onSuccess: ((CharSequence?) -> Unit)) {
|
||||
if (id == R.id.petDetailRecyclerFragment || id == R.id.mountDetailRecyclerFragment) {
|
||||
disposable.add(
|
||||
inventoryRepository.getItem("egg", eggType ?: "").firstElement().subscribe(
|
||||
{
|
||||
if (!it.isValid()) return@subscribe
|
||||
onSuccess(
|
||||
if (id == R.id.petDetailRecyclerFragment) {
|
||||
(it as? Egg)?.text
|
||||
} else {
|
||||
(it as? Egg)?.mountText
|
||||
}
|
||||
)
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
)
|
||||
)
|
||||
} else {
|
||||
onSuccess(
|
||||
if (id == R.id.promoInfoFragment) {
|
||||
""
|
||||
} else if (label.isNullOrEmpty() && user.value?.isValid == true) {
|
||||
user.value?.profile?.name
|
||||
} else label ?: ""
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -8,11 +8,14 @@ import android.widget.LinearLayout
|
|||
import androidx.core.graphics.drawable.toBitmap
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.databinding.DialogPetSuggestHatchBinding
|
||||
import com.habitrpg.android.habitica.extensions.subscribeWithErrorHandler
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.interactors.HatchPetUseCase
|
||||
import com.habitrpg.android.habitica.models.inventory.Animal
|
||||
import com.habitrpg.android.habitica.models.inventory.Egg
|
||||
import com.habitrpg.android.habitica.models.inventory.HatchingPotion
|
||||
import com.habitrpg.android.habitica.models.inventory.Item
|
||||
import com.habitrpg.android.habitica.ui.activities.BaseActivity
|
||||
import com.habitrpg.android.habitica.ui.activities.MainActivity
|
||||
import com.habitrpg.android.habitica.ui.helpers.DataBindingUtils
|
||||
import com.habitrpg.android.habitica.ui.views.CurrencyView
|
||||
|
|
@ -20,9 +23,13 @@ import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
|||
import io.reactivex.rxjava3.core.Flowable
|
||||
import io.reactivex.rxjava3.core.Observable
|
||||
import java.util.*
|
||||
import javax.inject.Inject
|
||||
|
||||
class PetSuggestHatchDialog(context: Context) : HabiticaAlertDialog(context) {
|
||||
|
||||
@Inject
|
||||
lateinit var hatchPetUseCase: HatchPetUseCase
|
||||
|
||||
private lateinit var binding: DialogPetSuggestHatchBinding
|
||||
|
||||
init {
|
||||
|
|
@ -75,7 +82,7 @@ class PetSuggestHatchDialog(context: Context) : HabiticaAlertDialog(context) {
|
|||
addButton(R.string.hatch, true, false) { _, _ ->
|
||||
val thisPotion = potion ?: return@addButton
|
||||
val thisEgg = egg ?: return@addButton
|
||||
(getActivity() as? MainActivity)?.hatchPet(thisPotion, thisEgg)
|
||||
hatchPet(thisPotion, thisEgg)
|
||||
}
|
||||
if (hasMount) {
|
||||
setTitle(R.string.hatch_your_pet)
|
||||
|
|
@ -134,7 +141,7 @@ class PetSuggestHatchDialog(context: Context) : HabiticaAlertDialog(context) {
|
|||
.flatMap { activity.userRepository.retrieveUser(true, forced = true) }
|
||||
.subscribe(
|
||||
{
|
||||
(getActivity() as? MainActivity)?.hatchPet(thisPotion, thisEgg)
|
||||
hatchPet(thisPotion, thisEgg)
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
)
|
||||
|
|
@ -159,6 +166,16 @@ class PetSuggestHatchDialog(context: Context) : HabiticaAlertDialog(context) {
|
|||
}
|
||||
}
|
||||
|
||||
private fun hatchPet(potion: HatchingPotion, egg: Egg) {
|
||||
(getActivity() as? BaseActivity)?.let {
|
||||
hatchPetUseCase.observable(
|
||||
HatchPetUseCase.RequestValues(
|
||||
potion, egg,
|
||||
it
|
||||
)).subscribeWithErrorHandler {}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getItemPrice(pet: Animal, item: Item?, hasUnlocked: Boolean): Int {
|
||||
if (pet.type == "drop" || (pet.type == "quest" && hasUnlocked)) {
|
||||
return item?.value ?: 0
|
||||
|
|
|
|||
|
|
@ -19,6 +19,10 @@ class AnalyticsManagerImpl(context: Context) : AnalyticsManager {
|
|||
Amplitude.getInstance().userId = identifier
|
||||
}
|
||||
|
||||
override fun setUserProperty(identifier: String, value: String) {
|
||||
firebaseAnalytics.setUserProperty(identifier, value)
|
||||
}
|
||||
|
||||
override fun logError(msg: String) {
|
||||
FirebaseCrashlytics.getInstance().log(msg)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue