finish analytics rework

This commit is contained in:
Phillip Thelen 2023-08-04 13:24:13 +02:00
parent bf43a3c96c
commit fc6dee4f6a
24 changed files with 134 additions and 135 deletions

View file

@ -27,7 +27,6 @@ import com.habitrpg.android.habitica.models.inventory.QuestContent
import com.habitrpg.android.habitica.models.user.User
import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel
import com.habitrpg.common.habitica.api.HostConfig
import com.habitrpg.common.habitica.helpers.AnalyticsManager
import com.habitrpg.common.habitica.helpers.ExceptionHandler
import com.kaspersky.kaspresso.testcases.api.testcase.TestCase
import io.mockk.clearAllMocks
@ -61,7 +60,6 @@ open class HabiticaTestCase : TestCase() {
val soundManager: SoundManager = mockk(relaxed = true)
val notificationsManager: NotificationsManager = mockk(relaxed = true)
val hostConfig: HostConfig = mockk(relaxed = true)
val analyticsManager: AnalyticsManager = mockk(relaxed = true)
val maintenanceService: MaintenanceApiService = mockk(relaxed = true)
val tagRepository: TagRepository = mockk(relaxed = true)
val hatchPetUseCase: HatchPetUseCase = mockk(relaxed = true)
@ -126,7 +124,6 @@ open class HabiticaTestCase : TestCase() {
if (it.returnType == SharedPreferences::class.starProjectedType) assign(it, obj, sharedPreferences)
if (it.returnType == NotificationsManager::class.starProjectedType) assign(it, obj, notificationsManager)
if (it.returnType == HostConfig::class.starProjectedType) assign(it, obj, hostConfig)
if (it.returnType == AnalyticsManager::class.starProjectedType) assign(it, obj, analyticsManager)
if (it.returnType == MaintenanceApiService::class.starProjectedType) assign(it, obj, maintenanceService)
if (it.returnType == TagRepository::class.starProjectedType) assign(it, obj, tagRepository)
if (it.returnType == FeedPetUseCase::class.starProjectedType) assign(it, obj, feedPetUseCase)

View file

@ -17,12 +17,19 @@ import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatDelegate
import androidx.core.content.edit
import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleObserver
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.OnLifecycleEvent
import androidx.lifecycle.ProcessLifecycleOwner
import androidx.preference.PreferenceManager
import com.google.android.gms.wearable.Wearable
import com.google.firebase.installations.FirebaseInstallations
import com.google.firebase.remoteconfig.FirebaseRemoteConfig
import com.google.firebase.remoteconfig.FirebaseRemoteConfigSettings
import com.habitrpg.android.habitica.data.ApiClient
import com.habitrpg.android.habitica.extensions.DateUtils
import com.habitrpg.android.habitica.helpers.AdHandler
import com.habitrpg.android.habitica.helpers.Analytics
import com.habitrpg.android.habitica.helpers.notifications.PushNotificationManager
@ -31,7 +38,6 @@ import com.habitrpg.android.habitica.ui.activities.BaseActivity
import com.habitrpg.android.habitica.ui.activities.LoginActivity
import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper
import com.habitrpg.common.habitica.extensions.setupCoil
import com.habitrpg.common.habitica.helpers.AnalyticsManager
import com.habitrpg.common.habitica.helpers.ExceptionHandler
import com.habitrpg.common.habitica.helpers.LanguageHelper
import com.habitrpg.common.habitica.helpers.MarkdownParser
@ -41,8 +47,52 @@ import io.realm.Realm
import io.realm.RealmConfiguration
import kotlinx.coroutines.MainScope
import java.lang.ref.WeakReference
import java.util.Date
import javax.inject.Inject
class ApplicationLifecycleTracker(private val sharedPreferences: SharedPreferences): DefaultLifecycleObserver {
private var lastResumeTime = 0L
override fun onResume(owner : LifecycleOwner) {
super.onResume(owner)
lastResumeTime = Date().time
}
override fun onPause(owner : LifecycleOwner) {
super.onPause(owner)
val duration = Date().time - lastResumeTime
addDurationToDay(duration / 1000)
}
private fun addDurationToDay(duration: Long) {
var currentTotal = sharedPreferences.getLong("usage_time_total", 0L)
currentTotal += duration
var currentDay = Date()
if (sharedPreferences.contains("usage_time_day")) {
currentDay = Date(sharedPreferences.getLong("usage_time_day", 0L))
}
var current = sharedPreferences.getLong("usage_time_current", 0L)
if (!DateUtils.isSameDay(currentDay, Date())) {
var average = sharedPreferences.getLong("usage_time_daily_average", 0L)
var observedDays = sharedPreferences.getInt("usage_time_day_count", 0)
average = ((average * observedDays) + current) / (observedDays + 1)
sharedPreferences.edit {
putInt("usage_time_day_count", ++observedDays)
putLong("usage_time_daily_average", average)
}
Analytics.setUserProperty("usage_time_daily_average", average)
Analytics.setUserProperty("usage_time_total", currentTotal)
current = 0
currentDay = Date()
}
current += duration
sharedPreferences.edit {
putLong("usage_time_current", current)
putLong("usage_time_total", currentTotal)
putLong("usage_time_day", currentDay.time)
}
}
}
@HiltAndroidApp
abstract class HabiticaBaseApplication : Application(), Application.ActivityLifecycleCallbacks {
@Inject
@ -51,15 +101,14 @@ abstract class HabiticaBaseApplication : Application(), Application.ActivityLife
@Inject
internal lateinit var sharedPrefs: SharedPreferences
@Inject
internal lateinit var analyticsManager: AnalyticsManager
@Inject
internal lateinit var pushNotificationManager: PushNotificationManager
@Inject
internal lateinit var authenticationHandler: AuthenticationHandler
private lateinit var lifecycleTracker: ApplicationLifecycleTracker
/**
* For better performance billing class should be used as singleton
*/
@ -67,6 +116,9 @@ abstract class HabiticaBaseApplication : Application(), Application.ActivityLife
override fun onCreate() {
super.onCreate()
lifecycleTracker = ApplicationLifecycleTracker(sharedPrefs)
ProcessLifecycleOwner.get().lifecycle.addObserver(lifecycleTracker);
if (!BuildConfig.DEBUG) {
try {
Analytics.initialize(this)
@ -96,8 +148,9 @@ abstract class HabiticaBaseApplication : Application(), Application.ActivityLife
checkIfNewVersion()
}
private fun setupAdHandler() {
AdHandler.setup(sharedPrefs, analyticsManager)
AdHandler.setup(sharedPrefs)
}
private fun setLocale() {

View file

@ -39,7 +39,6 @@ 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.api.Server
import com.habitrpg.common.habitica.helpers.AnalyticsManager
import com.habitrpg.common.habitica.models.HabitResponse
import com.habitrpg.common.habitica.models.PurchaseValidationRequest
import com.habitrpg.common.habitica.models.PurchaseValidationResult
@ -73,7 +72,6 @@ import javax.net.ssl.SSLException
class ApiClientImpl(
private val converter: Converter.Factory,
override val hostConfig: HostConfig,
private val analyticsManager: AnalyticsManager,
private val notificationsManager: NotificationsManager,
private val context: Context
) : ApiClient {
@ -104,7 +102,6 @@ class ApiClientImpl(
private var hadError = false
init {
Analytics.setUserID(this.hostConfig.userID)
buildRetrofit()
}

View file

@ -1,11 +1,12 @@
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.local.TaskLocalRepository
import com.habitrpg.android.habitica.helpers.Analytics
import com.habitrpg.android.habitica.helpers.AppConfigManager
import com.habitrpg.android.habitica.helpers.EventCategory
import com.habitrpg.android.habitica.helpers.HitType
import com.habitrpg.android.habitica.interactors.ScoreTaskLocallyInteractor
import com.habitrpg.android.habitica.models.BaseMainObject
import com.habitrpg.android.habitica.models.responses.BulkTaskScoringData
@ -15,7 +16,6 @@ import com.habitrpg.android.habitica.models.tasks.TaskList
import com.habitrpg.android.habitica.models.user.OwnedItem
import com.habitrpg.android.habitica.models.user.User
import com.habitrpg.android.habitica.modules.AuthenticationHandler
import com.habitrpg.common.habitica.helpers.AnalyticsManager
import com.habitrpg.common.habitica.helpers.launchCatching
import com.habitrpg.shared.habitica.models.responses.TaskDirection
import com.habitrpg.shared.habitica.models.responses.TaskDirectionData
@ -39,7 +39,6 @@ class TaskRepositoryImpl(
apiClient: ApiClient,
authenticationHandler: AuthenticationHandler,
val appConfigManager: AppConfigManager,
val analyticsManager: AnalyticsManager
) : BaseRepositoryImpl<TaskLocalRepository>(localRepository, apiClient, authenticationHandler), TaskRepository {
private var lastTaskAction: Long = 0
@ -102,12 +101,14 @@ class TaskRepositoryImpl(
val thisUser = user ?: localRepository.getUser(authenticationHandler.currentUserID ?: "").firstOrNull() ?: return null
// save local task changes
Analytics.logEvent(
Analytics.sendEvent(
"task_scored",
bundleOf(
Pair("type", task.type),
Pair("scored_up", up),
Pair("value", task.value)
EventCategory.BEHAVIOUR,
HitType.EVENT,
mapOf(
"type" to (task.type ?: ""),
"scored_up" to up,
"value" to task.value
)
)
if (res.lvl == 0) {

View file

@ -18,7 +18,6 @@ import com.habitrpg.android.habitica.models.user.Stats
import com.habitrpg.android.habitica.models.user.User
import com.habitrpg.android.habitica.models.user.UserQuestStatus
import com.habitrpg.android.habitica.modules.AuthenticationHandler
import com.habitrpg.common.habitica.helpers.AnalyticsManager
import com.habitrpg.common.habitica.models.Notification
import com.habitrpg.common.habitica.models.notifications.NewStuffData
import com.habitrpg.shared.habitica.models.responses.TaskDirection
@ -41,7 +40,6 @@ class UserRepositoryImpl(
authenticationHandler: AuthenticationHandler,
private val taskRepository: TaskRepository,
private val appConfigManager: AppConfigManager,
private val analyticsManager: AnalyticsManager
) : BaseRepositoryImpl<UserLocalRepository>(localRepository, apiClient, authenticationHandler), UserRepository {
companion object {

View file

@ -24,6 +24,15 @@ class DateUtils {
cal.set(Calendar.MILLISECOND, 0)
return cal.time
}
fun isSameDay(date1 : Date, date2 : Date) : Boolean {
val cal1 = Calendar.getInstance()
val cal2 = Calendar.getInstance()
cal1.time = date1
cal2.time = date2
return cal1[Calendar.DAY_OF_YEAR] == cal2[Calendar.DAY_OF_YEAR] &&
cal1[Calendar.YEAR] == cal2[Calendar.YEAR]
}
}
}

View file

@ -18,7 +18,6 @@ import com.google.android.gms.ads.rewarded.RewardedAdLoadCallback
import com.google.firebase.analytics.FirebaseAnalytics
import com.google.firebase.crashlytics.FirebaseCrashlytics
import com.habitrpg.android.habitica.BuildConfig
import com.habitrpg.common.habitica.helpers.AnalyticsManager
import java.io.UnsupportedEncodingException
import java.security.MessageDigest
import java.util.Date
@ -75,7 +74,6 @@ class AdHandler(val activity: Activity, val type: AdType, val rewardAction: (Boo
DISABLED
}
private lateinit var analyticsManager: AnalyticsManager
private lateinit var sharedPreferences: SharedPreferences
const val TAG = "AdHandler"
@ -144,9 +142,8 @@ class AdHandler(val activity: Activity, val type: AdType, val rewardAction: (Boo
}
}
fun setup(sharedPrefs: SharedPreferences, analyticsManager: AnalyticsManager) {
fun setup(sharedPrefs: SharedPreferences) {
this.sharedPreferences = sharedPrefs
this.analyticsManager = analyticsManager
for (type in AdType.values()) {
val time = sharedPrefs.getLong("nextAd${type.name}", 0)
@ -228,10 +225,12 @@ class AdHandler(val activity: Activity, val type: AdType, val rewardAction: (Boo
}
override fun onUserEarnedReward(rewardItem: RewardItem) {
analyticsManager.logEvent(
Analytics.sendEvent(
"adRewardEarned",
bundleOf(
Pair("type", type.name)
EventCategory.BEHAVIOUR,
HitType.EVENT,
mapOf(
"type" to type.name
)
)
FirebaseAnalytics.getInstance(activity).logEvent(

View file

@ -54,11 +54,15 @@ object Analytics {
data.putAll(additionalData)
}
if (eventAction != null) {
if (target == null || target == AnalyticsTarget.AMPLITUDE) {
amplitude.track(eventAction, data)
if (this::amplitude.isInitialized) {
if (target == null || target == AnalyticsTarget.AMPLITUDE) {
amplitude.track(eventAction, data)
}
}
if (target == null || target == AnalyticsTarget.FIREBASE) {
firebase.logEvent(eventAction, bundleOf(*data.toList().toTypedArray()))
if (this::firebase.isInitialized) {
if (target == null || target == AnalyticsTarget.FIREBASE) {
firebase.logEvent(eventAction, bundleOf(*data.toList().toTypedArray()))
}
}
}
}
@ -85,17 +89,28 @@ object Analytics {
sharedPrefs.getString("launch_screen", "")?.let {
identify.set("launch_screen", it)
}
amplitude.identify(identify)
if (this::amplitude.isInitialized) {
amplitude.identify(identify)
}
}
fun setUserID(userID: String) {
amplitude.setUserId(userID)
if (this::amplitude.isInitialized) {
amplitude.setUserId(userID)
}
FirebaseCrashlytics.getInstance().setUserId(userID)
firebase.setUserId(userID)
if (this::firebase.isInitialized) {
firebase.setUserId(userID)
}
}
fun setUserProperty(identifier: String, value: String) {
firebase.setUserProperty(identifier, value)
fun setUserProperty(identifier: String, value: Any?) {
if (this::amplitude.isInitialized) {
amplitude.identify(mapOf(identifier to value))
}
if (this::firebase.isInitialized) {
firebase.setUserProperty(identifier, value?.toString())
}
}
fun logError(msg: String) {

View file

@ -4,7 +4,6 @@ import android.app.Activity
import android.content.Context
import android.content.SharedPreferences
import androidx.core.content.edit
import androidx.core.os.bundleOf
import androidx.lifecycle.asFlow
import com.android.billingclient.api.AcknowledgePurchaseParams
import com.android.billingclient.api.BillingClient
@ -32,7 +31,6 @@ import com.habitrpg.android.habitica.models.user.User
import com.habitrpg.android.habitica.ui.activities.PurchaseActivity
import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel
import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaAlertDialog
import com.habitrpg.common.habitica.helpers.AnalyticsManager
import com.habitrpg.common.habitica.helpers.ExceptionHandler
import com.habitrpg.common.habitica.helpers.launchCatching
import com.habitrpg.common.habitica.models.IAPGift
@ -55,7 +53,6 @@ import kotlin.time.toDuration
class PurchaseHandler(
private val context: Context,
private val analyticsManager: AnalyticsManager,
private val apiClient: ApiClient,
private val userViewModel: MainUserViewModel
) : PurchasesUpdatedListener, PurchasesResponseListener {
@ -349,7 +346,7 @@ class PurchaseHandler(
try {
apiClient.validateSubscription(validationRequest)
processedPurchase(purchase)
Analytics.sendEvent("user_subscribed", bundleOf(Pair("sku", sku)))
Analytics.sendEvent("user_subscribed", EventCategory.BEHAVIOUR, HitType.EVENT, mapOf("sku" to (sku ?: "")))
CoroutineScope(Dispatchers.IO).launch(ExceptionHandler.coroutine()) {
acknowledgePurchase(purchase)
}

View file

@ -9,7 +9,6 @@ import com.habitrpg.android.habitica.data.implementation.ApiClientImpl.Companion
import com.habitrpg.android.habitica.helpers.MainNotificationsManager
import com.habitrpg.android.habitica.helpers.NotificationsManager
import com.habitrpg.common.habitica.api.HostConfig
import com.habitrpg.common.habitica.helpers.AnalyticsManager
import com.habitrpg.common.habitica.helpers.KeyHelper
import dagger.Module
import dagger.Provides
@ -50,14 +49,12 @@ open class ApiModule {
fun providesApiHelper(
gsonConverter: GsonConverterFactory,
hostConfig: HostConfig,
analyticsManager: AnalyticsManager,
notificationsManager: NotificationsManager,
@ApplicationContext context: Context
): ApiClient {
val apiClient = ApiClientImpl(
gsonConverter,
hostConfig,
analyticsManager,
notificationsManager,
context
)

View file

@ -1,22 +1,12 @@
package com.habitrpg.android.habitica.modules
import android.content.Context
import com.habitrpg.android.habitica.proxy.implementation.EmptyAnalyticsManager
import com.habitrpg.common.habitica.helpers.AnalyticsManager
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
import javax.inject.Singleton
// provide proxy class for libraries(to avoid 65k limit)
@InstallIn(SingletonComponent::class)
@Module
open class DeveloperModule {
@Provides
@Singleton
open fun provideAnalyticsManager(@ApplicationContext context: Context): AnalyticsManager {
return EmptyAnalyticsManager()
}
}

View file

@ -43,7 +43,6 @@ import com.habitrpg.android.habitica.data.local.implementation.RealmUserLocalRep
import com.habitrpg.android.habitica.helpers.AppConfigManager
import com.habitrpg.android.habitica.helpers.PurchaseHandler
import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel
import com.habitrpg.common.habitica.helpers.AnalyticsManager
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
@ -71,14 +70,12 @@ class UserRepositoryModule {
apiClient: ApiClient,
authenticationHandler: AuthenticationHandler,
appConfigManager: AppConfigManager,
analyticsManager: AnalyticsManager
): TaskRepository {
return TaskRepositoryImpl(
localRepository,
apiClient,
authenticationHandler,
appConfigManager,
analyticsManager
appConfigManager
)
}
@ -122,7 +119,6 @@ class UserRepositoryModule {
authenticationHandler: AuthenticationHandler,
taskRepository: TaskRepository,
appConfigManager: AppConfigManager,
analyticsManager: AnalyticsManager
): UserRepository {
return UserRepositoryImpl(
localRepository,
@ -130,7 +126,6 @@ class UserRepositoryModule {
authenticationHandler,
taskRepository,
appConfigManager,
analyticsManager
)
}
@ -211,10 +206,9 @@ class UserRepositoryModule {
@Singleton
fun providesPurchaseHandler(
@ApplicationContext context: Context,
analyticsManager: AnalyticsManager,
apiClient: ApiClient,
userViewModel: MainUserViewModel
): PurchaseHandler {
return PurchaseHandler(context, analyticsManager, apiClient, userViewModel)
return PurchaseHandler(context, apiClient, userViewModel)
}
}

View file

@ -1,8 +0,0 @@
package com.habitrpg.android.habitica.proxy.implementation
import android.os.Bundle
import com.habitrpg.common.habitica.helpers.AnalyticsManager
class EmptyAnalyticsManager : AnalyticsManager {
}

View file

@ -16,7 +16,6 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatDelegate
import androidx.appcompat.widget.Toolbar
import androidx.core.content.ContextCompat
import androidx.core.os.bundleOf
import androidx.lifecycle.lifecycleScope
import androidx.preference.PreferenceManager
import com.habitrpg.android.habitica.HabiticaApplication
@ -24,13 +23,15 @@ import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.data.UserRepository
import com.habitrpg.android.habitica.extensions.forceLocale
import com.habitrpg.android.habitica.extensions.updateStatusBarColor
import com.habitrpg.android.habitica.helpers.Analytics
import com.habitrpg.android.habitica.helpers.EventCategory
import com.habitrpg.android.habitica.helpers.HitType
import com.habitrpg.android.habitica.helpers.NotificationsManager
import com.habitrpg.android.habitica.interactors.ShowNotificationInteractor
import com.habitrpg.android.habitica.ui.helpers.ToolbarColorHelper
import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaAlertDialog
import com.habitrpg.common.habitica.extensions.getThemeColor
import com.habitrpg.common.habitica.extensions.isUsingNightModeResources
import com.habitrpg.common.habitica.helpers.AnalyticsManager
import com.habitrpg.common.habitica.helpers.ExceptionHandler
import com.habitrpg.common.habitica.helpers.LanguageHelper
import com.habitrpg.common.habitica.helpers.launchCatching
@ -45,9 +46,6 @@ abstract class BaseActivity : AppCompatActivity() {
@Inject
lateinit var userRepository: UserRepository
@Inject
internal lateinit var analyticsManager: AnalyticsManager
private var currentTheme: String? = null
private var isNightMode: Boolean = false
internal var forcedTheme: String? = null
@ -227,7 +225,7 @@ abstract class BaseActivity : AppCompatActivity() {
}
fun shareContent(identifier: String, message: String, image: Bitmap? = null) {
analyticsManager.logEvent("shared", bundleOf(Pair("identifier", identifier)))
Analytics.sendEvent("shared", EventCategory.BEHAVIOUR, HitType.EVENT, mapOf("identifier" to identifier))
val sharingIntent = Intent(Intent.ACTION_SEND)
sharingIntent.type = "*/*"
sharingIntent.putExtra(Intent.EXTRA_TEXT, message)

View file

@ -27,7 +27,6 @@ import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateMapOf
import androidx.compose.runtime.toMutableStateList
import androidx.core.content.ContextCompat
import androidx.core.os.bundleOf
import androidx.core.view.children
import androidx.core.view.forEachIndexed
import androidx.core.view.isVisible
@ -81,6 +80,8 @@ import javax.inject.Inject
@AndroidEntryPoint
class TaskFormActivity : BaseActivity() {
private val viewModel: TaskFormViewModel by viewModels()
private lateinit var binding: ActivityTaskFormBinding
@ -123,10 +124,14 @@ class TaskFormActivity : BaseActivity() {
val alert = HabiticaAlertDialog(this)
alert.setTitle(R.string.push_notification_system_settings_title)
alert.setMessage(R.string.push_notification_system_settings_description)
alert.addButton(R.string.settings, true, false) { _, _ ->
val notifSettingIntent: Intent = Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
.putExtra(Settings.EXTRA_APP_PACKAGE, applicationContext?.packageName)
alert.addButton(R.string.settings, isPrimary = true, isDestructive = false) { _, _ ->
val notifSettingIntent: Intent = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
.putExtra(Settings.EXTRA_APP_PACKAGE, applicationContext?.packageName)
} else {
return@addButton
}
startActivity(notifSettingIntent)
}
alert.addButton(R.string.cancel, false) { _, _ ->
@ -416,8 +421,7 @@ class TaskFormActivity : BaseActivity() {
val alert = HabiticaAlertDialog(this)
alert.setTitle(R.string.unsaved_changes)
alert.setMessage(R.string.discard_changes_to_task_message)
alert.addButton(R.string.discard, true, true) { _, _ ->
analyticsManager.logEvent("discard_task", bundleOf(Pair("is_creating", isCreating)))
alert.addButton(R.string.discard, isPrimary = true, isDestructive = true) { _, _ ->
super.onBackPressed()
}
alert.addButton(R.string.cancel, false) { _, _ ->
@ -657,7 +661,7 @@ class TaskFormActivity : BaseActivity() {
binding.habitResetStreakButtons.visibility = View.GONE
assignedIDs =
task.group?.assignedUsersDetail?.map { it.assignedUserID }?.filterNotNull()
task.group?.assignedUsersDetail?.mapNotNull { it.assignedUserID }
?.toMutableStateList() ?: mutableStateListOf()
task.group?.assignedUsersDetail?.forEach {
it.completedDate?.let { date ->
@ -770,7 +774,7 @@ class TaskFormActivity : BaseActivity() {
val assignChanges = mapOf(
"assign" to mutableListOf<String>(),
"unassign" to mutableListOf<String>()
"unassign" to mutableListOf()
)
if (groupID != null && thisTask.group?.groupID == null) {
thisTask.group = TaskGroupPlan()
@ -795,9 +799,6 @@ class TaskFormActivity : BaseActivity() {
} else {
taskRepository.updateTaskInBackground(thisTask, assignChanges)
}
if (isDiscardCancelled) {
analyticsManager.logEvent("back_to_task", bundleOf(Pair("is_creating", isCreating)))
}
if (thisTask.type == TaskType.DAILY || thisTask.type == TaskType.TODO) {
taskAlarmManager.scheduleAlarmsForTask(thisTask)
@ -877,7 +878,7 @@ class TaskFormActivity : BaseActivity() {
lifecycleScope.launch(Dispatchers.Main) {
challengeRepository.leaveChallenge(it, "keep-all")
taskRepository.deleteTask(task?.id ?: "")
userRepository.retrieveUser(true, true)
userRepository.retrieveUser(withTasks = true, forced = true)
}
}
}
@ -889,7 +890,7 @@ class TaskFormActivity : BaseActivity() {
challenge?.let {
lifecycleScope.launch(Dispatchers.Main) {
challengeRepository.leaveChallenge(it, "remove-all")
userRepository.retrieveUser(true, true)
userRepository.retrieveUser(withTasks = true, forced = true)
}
}
}
@ -921,17 +922,17 @@ class TaskFormActivity : BaseActivity() {
) { _, _ ->
lifecycleScope.launch(Dispatchers.Main) {
taskRepository.unlinkAllTasks(task.challengeID, "keep-all")
userRepository.retrieveUser(true, true)
userRepository.retrieveUser(withTasks = true, forced = true)
}
}
dialog.addButton(
getString(R.string.delete_x_tasks, taskCount),
false,
true
isPrimary = false,
isDestructive = true
) { _, _ ->
lifecycleScope.launch(Dispatchers.Main) {
taskRepository.unlinkAllTasks(task.challengeID, "remove-all")
userRepository.retrieveUser(true, true)
userRepository.retrieveUser(withTasks = true, forced = true)
}
}
dialog.setExtraCloseButtonVisibility(View.VISIBLE)

View file

@ -9,7 +9,6 @@ import androidx.lifecycle.lifecycleScope
import androidx.viewbinding.ViewBinding
import com.habitrpg.android.habitica.data.TutorialRepository
import com.habitrpg.android.habitica.ui.activities.MainActivity
import com.habitrpg.common.habitica.helpers.AnalyticsManager
import com.habitrpg.common.habitica.helpers.launchCatching
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.firstOrNull
@ -25,9 +24,6 @@ abstract class BaseFragment<VB : ViewBinding> : Fragment() {
@Inject
lateinit var tutorialRepository: TutorialRepository
@Inject
lateinit var analyticsManager: AnalyticsManager
var tutorialStepIdentifier: String? = null
protected var tutorialCanBeDeferred = true
var tutorialTexts: List<String> = ArrayList()

View file

@ -9,7 +9,6 @@ import androidx.compose.foundation.layout.Row
import androidx.compose.runtime.mutableStateOf
import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.unit.dp
import androidx.core.os.bundleOf
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.GridLayoutManager
import com.habitrpg.android.habitica.R
@ -206,8 +205,6 @@ open class ShopFragment : BaseMainFragment<FragmentRefreshRecyclerviewBinding>()
view.post { setGridSpanCount(view.width) }
context?.let { analyticsManager.logEvent("open_shop", bundleOf(Pair("shopIdentifier", shopIdentifier))) }
lifecycleScope.launchCatching {
inventoryRepository.getOwnedItems()
.collect { adapter?.setOwnedItems(it) }

View file

@ -24,7 +24,6 @@ import com.habitrpg.android.habitica.helpers.Analytics
import com.habitrpg.android.habitica.modules.AuthenticationHandler
import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaAlertDialog
import com.habitrpg.common.habitica.api.HostConfig
import com.habitrpg.common.habitica.helpers.AnalyticsManager
import com.habitrpg.common.habitica.helpers.KeyHelper
import com.habitrpg.common.habitica.helpers.launchCatching
import com.habitrpg.common.habitica.models.auth.UserAuthResponse
@ -38,7 +37,6 @@ class AuthenticationViewModel @Inject constructor(
val sharedPrefs: SharedPreferences,
val authenticationHandler: AuthenticationHandler,
val hostConfig: HostConfig,
val analyticsManager: AnalyticsManager,
private val keyHelper: KeyHelper?
) {
var googleEmail: String? = null

View file

@ -20,7 +20,6 @@ import com.habitrpg.android.habitica.models.TutorialStep
import com.habitrpg.android.habitica.models.inventory.Egg
import com.habitrpg.android.habitica.ui.TutorialView
import com.habitrpg.common.habitica.api.HostConfig
import com.habitrpg.common.habitica.helpers.AnalyticsManager
import com.habitrpg.common.habitica.helpers.ExceptionHandler
import com.habitrpg.common.habitica.helpers.launchCatching
import com.habitrpg.shared.habitica.models.responses.MaintenanceResponse
@ -42,7 +41,6 @@ class MainActivityViewModel @Inject constructor(
val taskRepository: TaskRepository,
val inventoryRepository: InventoryRepository,
val taskAlarmManager: TaskAlarmManager,
val analyticsManager: AnalyticsManager,
val maintenanceService: MaintenanceApiService
) : BaseViewModel(userRepository, userViewModel), TutorialView.OnTutorialReaction {

View file

@ -15,7 +15,6 @@ import com.habitrpg.android.habitica.helpers.MainNavigationController
import com.habitrpg.android.habitica.helpers.PurchaseHandler
import com.habitrpg.android.habitica.helpers.PurchaseTypes
import com.habitrpg.android.habitica.interactors.InsufficientGemsUseCase
import com.habitrpg.common.habitica.helpers.AnalyticsManager
import com.habitrpg.common.habitica.helpers.launchCatching
import dagger.hilt.EntryPoint
import dagger.hilt.InstallIn
@ -37,9 +36,6 @@ class InsufficientGemsDialog(val parentActivity: Activity, var gemPrice: Int) :
@Inject
lateinit var configManager: AppConfigManager
@Inject
lateinit var analyticsManager: AnalyticsManager
@Inject
lateinit var purchaseHandler: PurchaseHandler
@ -47,7 +43,6 @@ class InsufficientGemsDialog(val parentActivity: Activity, var gemPrice: Int) :
@InstallIn(SingletonComponent::class)
interface InsufficientGemsDialogEntryPoint {
fun configManager(): AppConfigManager
fun analyticsManager(): AnalyticsManager
fun purchaseHandler(): PurchaseHandler
fun insufficientGemsUseCase(): InsufficientGemsUseCase
}
@ -57,7 +52,6 @@ class InsufficientGemsDialog(val parentActivity: Activity, var gemPrice: Int) :
val hiltEntryPoint = EntryPointAccessors.fromApplication(parentActivity, InsufficientGemsDialogEntryPoint::class.java)
insufficientGemsUseCase = hiltEntryPoint.insufficientGemsUseCase()
configManager = hiltEntryPoint.configManager()
analyticsManager = hiltEntryPoint.analyticsManager()
purchaseHandler = hiltEntryPoint.purchaseHandler()
}

View file

@ -2,11 +2,6 @@ package com.habitrpg.android.habitica
import android.content.Context
import com.habitrpg.android.habitica.modules.DeveloperModule
import com.habitrpg.android.habitica.proxy.AnalyticsManagerImpl
import com.habitrpg.common.habitica.helpers.AnalyticsManager
class ReleaseDeveloperModule : DeveloperModule() {
override fun provideAnalyticsManager(context: Context): AnalyticsManager {
return AnalyticsManagerImpl(context)
}
}

View file

@ -1,13 +0,0 @@
package com.habitrpg.android.habitica.proxy
import android.content.Context
import android.os.Bundle
import com.google.firebase.analytics.FirebaseAnalytics
import com.google.firebase.crashlytics.FirebaseCrashlytics
import com.habitrpg.common.habitica.helpers.AnalyticsManager
class AnalyticsManagerImpl(context: Context) : AnalyticsManager {
private val firebaseAnalytics = FirebaseAnalytics.getInstance(context)
}

View file

@ -1,4 +0,0 @@
package com.habitrpg.common.habitica.helpers
interface AnalyticsManager {
}

View file

@ -1,2 +1,2 @@
NAME=4.2.4
CODE=6271
CODE=6291