diff --git a/Habitica/build.gradle b/Habitica/build.gradle index 478f70b74..58ba32d0e 100644 --- a/Habitica/build.gradle +++ b/Habitica/build.gradle @@ -142,6 +142,7 @@ dependencies { implementation 'com.willowtreeapps:signinwithapplebutton:0.3' implementation project(':shared') + implementation project(':common') ktlint('com.pinterest:ktlint:0.45.2') { attributes { diff --git a/Habitica/res/layout/achievement_grid_item.xml b/Habitica/res/layout/achievement_grid_item.xml index ff310f861..f888c452c 100644 --- a/Habitica/res/layout/achievement_grid_item.xml +++ b/Habitica/res/layout/achievement_grid_item.xml @@ -22,7 +22,7 @@ - - - - - - - - @@ -369,7 +369,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" tools:text="#" /> - diff --git a/Habitica/res/layout/activity_gift_subscription.xml b/Habitica/res/layout/activity_gift_subscription.xml index 8ad042ac1..d10e84f86 100644 --- a/Habitica/res/layout/activity_gift_subscription.xml +++ b/Habitica/res/layout/activity_gift_subscription.xml @@ -29,7 +29,7 @@ android:layout_height="wrap_content" android:orientation="vertical" android:layout_marginTop="@dimen/spacing_large"> - - - - - - - - - - - - - - - diff --git a/Habitica/res/layout/dialog_pet_suggest_hatch.xml b/Habitica/res/layout/dialog_pet_suggest_hatch.xml index 48a40aaaf..bdf898fd3 100644 --- a/Habitica/res/layout/dialog_pet_suggest_hatch.xml +++ b/Habitica/res/layout/dialog_pet_suggest_hatch.xml @@ -22,7 +22,7 @@ android:background="@drawable/layout_rounded_bg_window" android:layout_centerVertical="true" android:layout_alignParentStart="true"> - - - diff --git a/Habitica/res/layout/dialog_purchase_content_item.xml b/Habitica/res/layout/dialog_purchase_content_item.xml index 1c1cf936f..c910de3c1 100644 --- a/Habitica/res/layout/dialog_purchase_content_item.xml +++ b/Habitica/res/layout/dialog_purchase_content_item.xml @@ -11,7 +11,7 @@ tools:parentTag="LinearLayout" tools:orientation="vertical"> - diff --git a/Habitica/res/layout/dialog_purchase_content_quest.xml b/Habitica/res/layout/dialog_purchase_content_quest.xml index ca22596ad..3a4515b82 100644 --- a/Habitica/res/layout/dialog_purchase_content_quest.xml +++ b/Habitica/res/layout/dialog_purchase_content_quest.xml @@ -10,7 +10,7 @@ tools:parentTag="LinearLayout" tools:orientation="vertical"> - diff --git a/Habitica/res/layout/dialog_purchase_customization.xml b/Habitica/res/layout/dialog_purchase_customization.xml index 617fbad52..1c2af5923 100644 --- a/Habitica/res/layout/dialog_purchase_customization.xml +++ b/Habitica/res/layout/dialog_purchase_customization.xml @@ -6,7 +6,7 @@ android:layout_height="wrap_content" tools:parentTag="android.widget.LinearLayout"> - - diff --git a/Habitica/res/layout/dialog_won_challenge.xml b/Habitica/res/layout/dialog_won_challenge.xml index 58c57dffc..8d32be4b0 100644 --- a/Habitica/res/layout/dialog_won_challenge.xml +++ b/Habitica/res/layout/dialog_won_challenge.xml @@ -25,7 +25,7 @@ android:layout_height="wrap_content" android:layout_gravity="center" android:src="@drawable/sparkles_left" /> - - - - - - - - @@ -101,7 +101,7 @@ android:background="@drawable/layout_rounded_bg_window" android:padding="@dimen/spacing_medium" android:layout_marginBottom="@dimen/spacing_medium"> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/UserRepositoryImpl.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/UserRepositoryImpl.kt index fa48cf115..3258baa09 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/UserRepositoryImpl.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/UserRepositoryImpl.kt @@ -6,7 +6,7 @@ import com.habitrpg.android.habitica.data.TaskRepository import com.habitrpg.android.habitica.data.UserRepository import com.habitrpg.android.habitica.data.local.UserLocalRepository import com.habitrpg.android.habitica.data.local.UserQuestStatus -import com.habitrpg.android.habitica.extensions.Optional +import com.habitrpg.common.habitica.extensions.Optional import com.habitrpg.android.habitica.extensions.filterMapEmpty import com.habitrpg.android.habitica.helpers.AppConfigManager import com.habitrpg.android.habitica.helpers.RxErrorHandler diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/extensions/RxJava-Extensions.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/extensions/RxJava-Extensions.kt index e7998c3d2..52ef4419f 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/extensions/RxJava-Extensions.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/extensions/RxJava-Extensions.kt @@ -1,5 +1,6 @@ package com.habitrpg.android.habitica.extensions +import com.habitrpg.common.habitica.extensions.Optional import io.reactivex.rxjava3.core.Flowable import io.reactivex.rxjava3.core.Maybe import io.reactivex.rxjava3.core.Observable diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/AppConfigManager.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/AppConfigManager.kt index 81a2eda4e..d79ad13d4 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/AppConfigManager.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/AppConfigManager.kt @@ -12,7 +12,7 @@ import com.habitrpg.android.habitica.models.promotions.HabiticaPromotion import com.habitrpg.android.habitica.models.promotions.HabiticaWebPromotion import com.habitrpg.android.habitica.models.promotions.getHabiticaPromotionFromKey -class AppConfigManager(contentRepository: ContentRepository?) { +class AppConfigManager(contentRepository: ContentRepository?): com.habitrpg.common.habitica.helpers.AppConfigManager() { private var worldState: WorldState? = null @@ -35,7 +35,7 @@ class AppConfigManager(contentRepository: ContentRepository?) { return remoteConfig.getLong("maxChatLength") } - fun spriteSubstitutions(): Map> { + override fun spriteSubstitutions(): Map> { val type = object : TypeToken>>() {}.type return Gson().fromJson(remoteConfig.getString("spriteSubstitutions"), type) } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/UserStatComputer.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/UserStatComputer.kt index b15b2f1ad..35adcdf5a 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/UserStatComputer.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/UserStatComputer.kt @@ -1,7 +1,6 @@ package com.habitrpg.android.habitica.helpers import com.habitrpg.android.habitica.R -import com.habitrpg.android.habitica.models.Avatar import com.habitrpg.android.habitica.models.inventory.Equipment import com.habitrpg.android.habitica.models.user.Stats @@ -25,7 +24,7 @@ class UserStatComputer { var stats: String? = null } - fun computeClassBonus(equipmentList: List, user: Avatar): List { + fun computeClassBonus(equipmentList: List, user: com.habitrpg.common.habitica.models.Avatar): List { val skillRows = ArrayList() var strAttributes = 0f diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/interactors/FeedPetUseCase.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/interactors/FeedPetUseCase.kt index d5a991b8a..600a500a6 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/interactors/FeedPetUseCase.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/interactors/FeedPetUseCase.kt @@ -12,8 +12,8 @@ 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.loadImage -import com.habitrpg.android.habitica.ui.views.PixelArtView +import com.habitrpg.common.habitica.extensions.loadImage +import com.habitrpg.common.habitica.views.PixelArtView import com.habitrpg.android.habitica.ui.views.SnackbarActivity import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaAlertDialog import io.reactivex.rxjava3.core.Flowable diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/interactors/HatchPetUseCase.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/interactors/HatchPetUseCase.kt index 7efa3b856..a6b08896e 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/interactors/HatchPetUseCase.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/interactors/HatchPetUseCase.kt @@ -13,8 +13,8 @@ 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.loadImage -import com.habitrpg.android.habitica.ui.views.PixelArtView +import com.habitrpg.common.habitica.extensions.loadImage +import com.habitrpg.common.habitica.views.PixelArtView import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaAlertDialog import io.reactivex.rxjava3.core.Flowable import javax.inject.Inject diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/interactors/LevelUpUseCase.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/interactors/LevelUpUseCase.kt index 615a88601..116a782d5 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/interactors/LevelUpUseCase.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/interactors/LevelUpUseCase.kt @@ -9,7 +9,7 @@ import com.habitrpg.android.habitica.helpers.RxErrorHandler import com.habitrpg.android.habitica.helpers.SoundManager import com.habitrpg.android.habitica.models.user.Stats import com.habitrpg.android.habitica.models.user.User -import com.habitrpg.android.habitica.ui.AvatarView +import com.habitrpg.common.habitica.views.AvatarView import com.habitrpg.android.habitica.ui.activities.BaseActivity import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper import com.habitrpg.android.habitica.ui.views.HabiticaSnackbar diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/interactors/ShowNotificationInteractor.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/interactors/ShowNotificationInteractor.kt index c77e0f389..401cadfd4 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/interactors/ShowNotificationInteractor.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/interactors/ShowNotificationInteractor.kt @@ -13,9 +13,9 @@ import com.habitrpg.android.habitica.models.notifications.ChallengeWonData import com.habitrpg.android.habitica.models.notifications.FirstDropData import com.habitrpg.android.habitica.models.notifications.LoginIncentiveData import com.habitrpg.android.habitica.models.user.User -import com.habitrpg.android.habitica.ui.helpers.loadImage +import com.habitrpg.common.habitica.extensions.loadImage import com.habitrpg.android.habitica.ui.views.HabiticaSnackbar -import com.habitrpg.android.habitica.ui.views.PixelArtView +import com.habitrpg.common.habitica.views.PixelArtView import com.habitrpg.android.habitica.ui.views.SnackbarActivity import com.habitrpg.android.habitica.ui.views.dialogs.AchievementDialog import com.habitrpg.android.habitica.ui.views.dialogs.FirstDropDialog diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/Avatar.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/models/Avatar.kt deleted file mode 100644 index e9a393c6c..000000000 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/models/Avatar.kt +++ /dev/null @@ -1,22 +0,0 @@ -package com.habitrpg.android.habitica.models - -import com.habitrpg.android.habitica.models.user.Outfit -import com.habitrpg.android.habitica.models.user.Stats - -/** - * Created by phillip on 29.06.17. - */ -interface Avatar { - val currentMount: String? - val currentPet: String? - val sleep: Boolean - val stats: Stats? - val preferences: AvatarPreferences? - val flags: AvatarFlags? - val gemCount: Int - val hourglassCount: Int - val costume: Outfit? - val equipped: Outfit? - val hasClass: Boolean - fun isValid(): Boolean -} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/members/Member.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/models/members/Member.kt index d947b4c1a..05fbd9bf6 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/models/members/Member.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/models/members/Member.kt @@ -1,7 +1,6 @@ package com.habitrpg.android.habitica.models.members import com.google.gson.annotations.SerializedName -import com.habitrpg.android.habitica.models.Avatar import com.habitrpg.android.habitica.models.BaseMainObject import com.habitrpg.android.habitica.models.social.UserParty import com.habitrpg.android.habitica.models.user.Authentication @@ -12,6 +11,7 @@ import com.habitrpg.android.habitica.models.user.Items import com.habitrpg.android.habitica.models.user.Outfit import com.habitrpg.android.habitica.models.user.Profile import com.habitrpg.android.habitica.models.user.Stats +import com.habitrpg.common.habitica.models.Avatar import io.realm.RealmModel import io.realm.RealmObject import io.realm.annotations.PrimaryKey diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/members/MemberFlags.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/models/members/MemberFlags.kt index 4e74fdbd6..caf08c00b 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/models/members/MemberFlags.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/models/members/MemberFlags.kt @@ -1,6 +1,6 @@ package com.habitrpg.android.habitica.models.members -import com.habitrpg.android.habitica.models.AvatarFlags +import com.habitrpg.common.habitica.models.AvatarFlags import io.realm.RealmObject import io.realm.annotations.RealmClass diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/members/MemberPreferences.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/models/members/MemberPreferences.kt index 452ff4ca9..c25ce6c88 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/models/members/MemberPreferences.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/models/members/MemberPreferences.kt @@ -1,12 +1,13 @@ package com.habitrpg.android.habitica.models.members -import com.habitrpg.android.habitica.models.AvatarPreferences import com.habitrpg.android.habitica.models.user.Hair +import com.habitrpg.common.habitica.models.AvatarPreferences import io.realm.RealmObject import io.realm.annotations.RealmClass @RealmClass(embedded = true) -open class MemberPreferences : RealmObject(), AvatarPreferences { +open class MemberPreferences : RealmObject(), + AvatarPreferences { override var hair: Hair? = null override var costume: Boolean = false diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/social/UserStyles.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/models/social/UserStyles.kt index 3d9525312..a04c9d2f9 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/models/social/UserStyles.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/models/social/UserStyles.kt @@ -1,7 +1,5 @@ package com.habitrpg.android.habitica.models.social -import com.habitrpg.android.habitica.models.Avatar -import com.habitrpg.android.habitica.models.AvatarFlags import com.habitrpg.android.habitica.models.user.Items import com.habitrpg.android.habitica.models.user.Outfit import com.habitrpg.android.habitica.models.user.Preferences @@ -10,7 +8,7 @@ import io.realm.RealmObject import io.realm.annotations.RealmClass @RealmClass(embedded = true) -open class UserStyles : RealmObject(), Avatar { +open class UserStyles : RealmObject(), com.habitrpg.common.habitica.models.Avatar { override val currentMount: String? get() = items?.currentMount @@ -38,7 +36,7 @@ open class UserStyles : RealmObject(), Avatar { override var stats: Stats? = null override var preferences: Preferences? = null - override val flags: AvatarFlags? + override val flags: com.habitrpg.common.habitica.models.AvatarFlags? get() = null private var items: Items? = null } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/Buffs.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/Buffs.kt index 9bddd0664..395e9637e 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/Buffs.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/Buffs.kt @@ -2,26 +2,27 @@ package com.habitrpg.android.habitica.models.user import com.google.gson.annotations.SerializedName import com.habitrpg.android.habitica.models.BaseObject +import com.habitrpg.common.habitica.models.AvatarBuffs import io.realm.RealmObject import io.realm.annotations.RealmClass @RealmClass(embedded = true) -open class Buffs : RealmObject(), BaseObject { - var con: Float? = null - var str: Float? = null - var per: Float? = null +open class Buffs : RealmObject(), AvatarBuffs, BaseObject { + override var con: Float? = null + override var str: Float? = null + override var per: Float? = null @SerializedName("int") - var _int: Float? = null - var seafoam: Boolean? = null + override var _int: Float? = null + override var seafoam: Boolean? = null get() { return field ?: false } - var spookySparkles: Boolean? = null + override var spookySparkles: Boolean? = null get() { return field ?: false } - var shinySeed: Boolean? = null + override var shinySeed: Boolean? = null get() { return field ?: false } - var snowball: Boolean? = null + override var snowball: Boolean? = null get() { return field ?: false } - var streaks: Boolean? = null + override var streaks: Boolean? = null get() { return field ?: false } fun merge(stats: Buffs?) { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/Flags.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/Flags.kt index 395ebb521..ea1672c92 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/Flags.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/Flags.kt @@ -1,6 +1,5 @@ package com.habitrpg.android.habitica.models.user -import com.habitrpg.android.habitica.models.AvatarFlags import com.habitrpg.android.habitica.models.BaseObject import com.habitrpg.android.habitica.models.TutorialStep import io.realm.RealmList @@ -8,7 +7,7 @@ import io.realm.RealmObject import io.realm.annotations.RealmClass @RealmClass(embedded = true) -open class Flags : RealmObject(), BaseObject, AvatarFlags { +open class Flags : RealmObject(), BaseObject, com.habitrpg.common.habitica.models.AvatarFlags { var tutorial: RealmList? = null var showTour = false var dropsEnabled = false diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/Hair.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/Hair.kt index 5b6064aca..a80745db6 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/Hair.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/Hair.kt @@ -1,17 +1,18 @@ package com.habitrpg.android.habitica.models.user import com.habitrpg.android.habitica.models.BaseObject +import com.habitrpg.common.habitica.models.AvatarHair import io.realm.RealmObject import io.realm.annotations.RealmClass @RealmClass(embedded = true) -open class Hair : RealmObject, BaseObject { - var mustache: Int = 0 - var beard: Int = 0 - var bangs: Int = 0 - var base: Int = 0 - var flower: Int = 0 - var color: String? = null +open class Hair : RealmObject, BaseObject, AvatarHair { + final override var mustache: Int = 0 + final override var beard: Int = 0 + final override var bangs: Int = 0 + final override var base: Int = 0 + final override var flower: Int = 0 + final override var color: String? = null constructor() @@ -23,8 +24,4 @@ open class Hair : RealmObject, BaseObject { this.color = color this.flower = flower } - - fun isAvailable(hairId: Int): Boolean { - return hairId > 0 - } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/Outfit.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/Outfit.kt index f21cebb92..ed8a84cf3 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/Outfit.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/Outfit.kt @@ -1,35 +1,20 @@ package com.habitrpg.android.habitica.models.user -import android.text.TextUtils import com.google.gson.annotations.SerializedName import com.habitrpg.android.habitica.models.BaseObject +import com.habitrpg.common.habitica.models.AvatarOutfit import io.realm.RealmObject import io.realm.annotations.RealmClass @RealmClass(embedded = true) -open class Outfit : RealmObject(), BaseObject { - var armor: String = "" - var back: String = "" - var body: String = "" - var head: String = "" - var shield: String = "" - var weapon: String = "" +open class Outfit : RealmObject(), BaseObject, AvatarOutfit { + override var armor: String = "" + override var back: String = "" + override var body: String = "" + override var head: String = "" + override var shield: String = "" + override var weapon: String = "" @SerializedName("eyewear") - var eyeWear: String = "" - var headAccessory: String = "" - - fun isAvailable(outfit: String): Boolean { - return !TextUtils.isEmpty(outfit) && !outfit.endsWith("base_0") - } - - fun updateWith(newOutfit: Outfit) { - this.armor = newOutfit.armor - this.back = newOutfit.back - this.body = newOutfit.body - this.eyeWear = newOutfit.eyeWear - this.head = newOutfit.head - this.headAccessory = newOutfit.headAccessory - this.shield = newOutfit.shield - this.weapon = newOutfit.weapon - } + override var eyeWear: String = "" + override var headAccessory: String = "" } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/Preferences.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/Preferences.kt index 770c8dfd5..38df6c5d9 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/Preferences.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/Preferences.kt @@ -1,8 +1,8 @@ package com.habitrpg.android.habitica.models.user import com.google.gson.annotations.SerializedName -import com.habitrpg.android.habitica.models.AvatarPreferences import com.habitrpg.android.habitica.models.BaseObject +import com.habitrpg.common.habitica.models.AvatarPreferences import io.realm.RealmObject import io.realm.annotations.RealmClass diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/Stats.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/Stats.kt index 3d67a6118..b93f3d0a6 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/Stats.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/Stats.kt @@ -4,11 +4,12 @@ import android.content.Context import com.google.gson.annotations.SerializedName import com.habitrpg.android.habitica.R import com.habitrpg.android.habitica.models.BaseObject +import com.habitrpg.common.habitica.models.AvatarStats import io.realm.RealmObject import io.realm.annotations.RealmClass @RealmClass(embedded = true) -open class Stats : RealmObject(), BaseObject { +open class Stats : RealmObject(), AvatarStats, BaseObject { @SerializedName("con") var constitution: Int? = null @SerializedName("str") @@ -18,43 +19,36 @@ open class Stats : RealmObject(), BaseObject { @SerializedName("int") var intelligence: Int? = null var training: Training? = null - var buffs: Buffs? = null - var points: Int? = null - var lvl: Int? = null + override var buffs: Buffs? = null + override var points: Int? = null + override var lvl: Int? = null @SerializedName("class") - var habitClass: String? = null - var gp: Double? = null - var exp: Double? = null - var mp: Double? = null - var hp: Double? = null - var toNextLevel: Int? = null + override var habitClass: String? = null + override var gp: Double? = null + override var exp: Double? = null + override var mp: Double? = null + override var hp: Double? = null + override var toNextLevel: Int? = null get() = if (field != null) field else 0 set(value) { if (value != 0) { field = value } } - var maxHealth: Int? = null + override var maxHealth: Int? = null get() = if (field != null) field else 0 set(value) { if (value != 0) { field = value } } - var maxMP: Int? = null + override var maxMP: Int? = null get() = if (field != null) field else 0 set(value) { if (value != 0) { field = value } } - val isBuffed: Boolean - get() { - return buffs?.str ?: 0f > 0 || - buffs?.con ?: 0f > 0 || - buffs?._int ?: 0f > 0 || - buffs?.per ?: 0f > 0 - } fun getTranslatedClassName(context: Context): String { return when (habitClass) { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/User.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/User.kt index c0f5b74f6..9ba8c6bb8 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/User.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/User.kt @@ -2,7 +2,6 @@ package com.habitrpg.android.habitica.models.user import com.google.gson.annotations.SerializedName import com.habitrpg.android.habitica.R -import com.habitrpg.android.habitica.models.Avatar import com.habitrpg.android.habitica.models.BaseMainObject import com.habitrpg.android.habitica.models.PushDevice import com.habitrpg.android.habitica.models.QuestAchievement @@ -13,6 +12,7 @@ import com.habitrpg.android.habitica.models.social.ChallengeMembership import com.habitrpg.android.habitica.models.social.UserParty import com.habitrpg.android.habitica.models.tasks.TaskList import com.habitrpg.android.habitica.models.tasks.TasksOrder +import com.habitrpg.common.habitica.models.Avatar import io.realm.RealmList import io.realm.RealmObject import io.realm.annotations.Ignore diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/AvatarWithBarsViewModel.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/AvatarWithBarsViewModel.kt index 31f25edc3..5a2280465 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/AvatarWithBarsViewModel.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/AvatarWithBarsViewModel.kt @@ -13,13 +13,14 @@ import com.habitrpg.android.habitica.databinding.AvatarWithBarsBinding import com.habitrpg.android.habitica.helpers.Animations import com.habitrpg.android.habitica.helpers.HealthFormatter import com.habitrpg.android.habitica.helpers.MainNavigationController -import com.habitrpg.android.habitica.models.Avatar import com.habitrpg.android.habitica.models.user.Stats import com.habitrpg.android.habitica.models.user.User import com.habitrpg.android.habitica.ui.activities.mainActivityCreatedAt import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper import java.util.Date +import com.habitrpg.common.habitica.models.Avatar +import io.reactivex.rxjava3.disposables.Disposable import java.util.Locale import kotlin.math.floor @@ -59,7 +60,7 @@ class AvatarWithBarsViewModel( binding.avatarView.setAvatar(user) - if (stats.habitClass != null) { + if (stats.habitClass != null && stats is Stats) { userClass = stats.getTranslatedClassName(context) } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/ItemDetailDialog.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/ItemDetailDialog.kt index 76a6deaf1..83e7e5a62 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/ItemDetailDialog.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/ItemDetailDialog.kt @@ -9,9 +9,9 @@ import android.widget.LinearLayout import android.widget.TextView import androidx.appcompat.app.AlertDialog import com.habitrpg.android.habitica.R -import com.habitrpg.android.habitica.ui.helpers.loadImage +import com.habitrpg.common.habitica.extensions.loadImage import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper -import com.habitrpg.android.habitica.ui.views.PixelArtView +import com.habitrpg.common.habitica.views.PixelArtView class ItemDetailDialog(context: Context) : AlertDialog(context) { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/AdventureGuideActivity.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/AdventureGuideActivity.kt index 8f57c73e7..fec58474a 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/AdventureGuideActivity.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/AdventureGuideActivity.kt @@ -19,6 +19,7 @@ import com.habitrpg.android.habitica.models.user.User import com.habitrpg.android.habitica.ui.helpers.loadImage import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel import javax.inject.Inject +import com.habitrpg.common.habitica.extensions.loadImage class AdventureGuideActivity : BaseActivity() { private lateinit var binding: ActivityAdventureGuideBinding diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/ArmoireActivity.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/ArmoireActivity.kt index 9ff8d6f9a..da0306dbf 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/ArmoireActivity.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/ArmoireActivity.kt @@ -21,7 +21,7 @@ import com.habitrpg.android.habitica.helpers.AdType import com.habitrpg.android.habitica.helpers.Animations import com.habitrpg.android.habitica.helpers.AppConfigManager import com.habitrpg.android.habitica.helpers.RxErrorHandler -import com.habitrpg.android.habitica.ui.helpers.loadImage +import com.habitrpg.common.habitica.extensions.loadImage import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel import com.habitrpg.android.habitica.ui.views.ads.AdButton import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaBottomSheetDialog diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/FullProfileActivity.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/FullProfileActivity.kt index 621aafdd1..f786ca593 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/FullProfileActivity.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/FullProfileActivity.kt @@ -34,11 +34,11 @@ import com.habitrpg.android.habitica.models.user.Stats import com.habitrpg.android.habitica.ui.AvatarWithBarsViewModel import com.habitrpg.android.habitica.ui.adapter.social.AchievementProfileAdapter import com.habitrpg.android.habitica.ui.helpers.RecyclerViewState -import com.habitrpg.android.habitica.ui.helpers.loadImage +import com.habitrpg.common.habitica.extensions.loadImage import com.habitrpg.android.habitica.ui.helpers.setMarkdown import com.habitrpg.android.habitica.ui.views.HabiticaSnackbar import com.habitrpg.android.habitica.ui.views.HabiticaSnackbar.SnackbarDisplayType -import com.habitrpg.android.habitica.ui.views.PixelArtView +import com.habitrpg.common.habitica.views.PixelArtView import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaAlertDialog import io.reactivex.rxjava3.core.Flowable import kotlinx.coroutines.Dispatchers diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/MainActivity.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/MainActivity.kt index fba9ff855..23ae67adb 100755 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/MainActivity.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/MainActivity.kt @@ -50,7 +50,7 @@ import com.habitrpg.android.habitica.models.TutorialStep import com.habitrpg.android.habitica.models.responses.MaintenanceResponse import com.habitrpg.android.habitica.models.responses.TaskScoringResult import com.habitrpg.android.habitica.models.user.User -import com.habitrpg.android.habitica.ui.AvatarView +import com.habitrpg.common.habitica.views.AvatarView import com.habitrpg.android.habitica.ui.AvatarWithBarsViewModel import com.habitrpg.android.habitica.ui.TutorialView import com.habitrpg.android.habitica.ui.fragments.NavigationDrawerFragment diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/AchievementsAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/AchievementsAdapter.kt index cb63d4516..0e80c9eb0 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/AchievementsAdapter.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/AchievementsAdapter.kt @@ -11,8 +11,8 @@ import com.habitrpg.android.habitica.databinding.AchievementSectionHeaderBinding import com.habitrpg.android.habitica.extensions.inflate import com.habitrpg.android.habitica.models.Achievement import com.habitrpg.android.habitica.models.QuestAchievement -import com.habitrpg.android.habitica.ui.helpers.loadImage -import com.habitrpg.android.habitica.ui.views.PixelArtView +import com.habitrpg.common.habitica.extensions.loadImage +import com.habitrpg.common.habitica.views.PixelArtView import com.habitrpg.android.habitica.ui.views.dialogs.AchievementDetailDialog class AchievementsAdapter : RecyclerView.Adapter() { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/CustomizationEquipmentRecyclerViewAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/CustomizationEquipmentRecyclerViewAdapter.kt index 8b30fb146..ae798c8b6 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/CustomizationEquipmentRecyclerViewAdapter.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/CustomizationEquipmentRecyclerViewAdapter.kt @@ -13,9 +13,9 @@ import com.habitrpg.android.habitica.databinding.CustomizationGridItemBinding import com.habitrpg.android.habitica.helpers.MainNavigationController import com.habitrpg.android.habitica.models.inventory.CustomizationSet import com.habitrpg.android.habitica.models.inventory.Equipment -import com.habitrpg.android.habitica.ui.helpers.loadImage +import com.habitrpg.common.habitica.extensions.loadImage import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper -import com.habitrpg.android.habitica.ui.views.PixelArtView +import com.habitrpg.common.habitica.views.PixelArtView import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaAlertDialog import io.reactivex.rxjava3.core.BackpressureStrategy import io.reactivex.rxjava3.core.Flowable diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/CustomizationRecyclerViewAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/CustomizationRecyclerViewAdapter.kt index ccc25f0b3..7bdc99946 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/CustomizationRecyclerViewAdapter.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/CustomizationRecyclerViewAdapter.kt @@ -18,6 +18,7 @@ import com.habitrpg.android.habitica.models.inventory.CustomizationSet import com.habitrpg.android.habitica.models.shops.ShopItem import com.habitrpg.android.habitica.ui.AvatarView import com.habitrpg.android.habitica.ui.helpers.loadImage +import com.habitrpg.common.habitica.extensions.loadImage import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaAlertDialog import com.habitrpg.android.habitica.ui.views.shops.PurchaseDialog import io.reactivex.rxjava3.core.BackpressureStrategy diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/SkillsRecyclerViewAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/SkillsRecyclerViewAdapter.kt index daf589343..43262ebc8 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/SkillsRecyclerViewAdapter.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/SkillsRecyclerViewAdapter.kt @@ -13,7 +13,7 @@ import com.habitrpg.android.habitica.extensions.inflate import com.habitrpg.android.habitica.extensions.isUsingNightModeResources import com.habitrpg.android.habitica.models.Skill import com.habitrpg.android.habitica.models.user.OwnedItem -import com.habitrpg.android.habitica.ui.helpers.loadImage +import com.habitrpg.common.habitica.extensions.loadImage import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper import io.reactivex.rxjava3.core.BackpressureStrategy import io.reactivex.rxjava3.core.Flowable diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/EquipmentRecyclerViewAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/EquipmentRecyclerViewAdapter.kt index cccb09944..ba218b5b8 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/EquipmentRecyclerViewAdapter.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/EquipmentRecyclerViewAdapter.kt @@ -12,7 +12,7 @@ import com.habitrpg.android.habitica.R import com.habitrpg.android.habitica.databinding.GearListItemBinding import com.habitrpg.android.habitica.models.inventory.Equipment import com.habitrpg.android.habitica.ui.adapter.BaseRecyclerViewAdapter -import com.habitrpg.android.habitica.ui.helpers.loadImage +import com.habitrpg.common.habitica.extensions.loadImage import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper import io.reactivex.rxjava3.subjects.PublishSubject diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/ItemRecyclerAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/ItemRecyclerAdapter.kt index 63d27e613..6a12908e1 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/ItemRecyclerAdapter.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/ItemRecyclerAdapter.kt @@ -20,7 +20,7 @@ import com.habitrpg.android.habitica.models.user.OwnedItem import com.habitrpg.android.habitica.models.user.OwnedPet import com.habitrpg.android.habitica.models.user.User import com.habitrpg.android.habitica.ui.adapter.BaseRecyclerViewAdapter -import com.habitrpg.android.habitica.ui.helpers.loadImage +import com.habitrpg.common.habitica.extensions.loadImage import com.habitrpg.android.habitica.ui.menu.BottomSheetMenu import com.habitrpg.android.habitica.ui.menu.BottomSheetMenuItem import com.habitrpg.android.habitica.ui.views.dialogs.DetailDialog diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/PetDetailRecyclerAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/PetDetailRecyclerAdapter.kt index d30effe4f..ca6c57903 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/PetDetailRecyclerAdapter.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/PetDetailRecyclerAdapter.kt @@ -16,7 +16,7 @@ import com.habitrpg.android.habitica.models.inventory.StableSection import com.habitrpg.android.habitica.models.user.OwnedItem import com.habitrpg.android.habitica.models.user.OwnedMount import com.habitrpg.android.habitica.models.user.OwnedPet -import com.habitrpg.android.habitica.ui.helpers.loadImage +import com.habitrpg.common.habitica.extensions.loadImage import com.habitrpg.android.habitica.ui.viewHolders.PetViewHolder import com.habitrpg.android.habitica.ui.viewHolders.SectionViewHolder import com.habitrpg.android.habitica.ui.views.dialogs.PetSuggestHatchDialog diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/StableRecyclerAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/StableRecyclerAdapter.kt index d780fefc2..e409e17bd 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/StableRecyclerAdapter.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/StableRecyclerAdapter.kt @@ -20,11 +20,11 @@ import com.habitrpg.android.habitica.models.inventory.StableSection import com.habitrpg.android.habitica.models.user.OwnedItem import com.habitrpg.android.habitica.models.user.OwnedMount import com.habitrpg.android.habitica.ui.fragments.inventory.stable.StableFragmentDirections -import com.habitrpg.android.habitica.ui.helpers.loadImage +import com.habitrpg.common.habitica.extensions.loadImage import com.habitrpg.android.habitica.ui.viewHolders.MountViewHolder import com.habitrpg.android.habitica.ui.viewHolders.PetViewHolder import com.habitrpg.android.habitica.ui.viewHolders.SectionViewHolder -import com.habitrpg.android.habitica.ui.views.PixelArtView +import com.habitrpg.common.habitica.views.PixelArtView import io.reactivex.rxjava3.core.BackpressureStrategy import io.reactivex.rxjava3.core.Flowable import io.reactivex.rxjava3.subjects.PublishSubject diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/AchievementProfileAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/AchievementProfileAdapter.kt index 7e4043d31..30cdd87a8 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/AchievementProfileAdapter.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/AchievementProfileAdapter.kt @@ -8,7 +8,7 @@ import com.habitrpg.android.habitica.databinding.ProfileAchievementItemBinding import com.habitrpg.android.habitica.extensions.inflate import com.habitrpg.android.habitica.models.Achievement import com.habitrpg.android.habitica.ui.activities.MainActivity -import com.habitrpg.android.habitica.ui.helpers.loadImage +import com.habitrpg.common.habitica.extensions.loadImage import com.habitrpg.android.habitica.ui.viewHolders.SectionViewHolder import com.habitrpg.android.habitica.ui.views.dialogs.AchievementDetailDialog diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/AboutFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/AboutFragment.kt index 7bc78f54f..52c7dd2d1 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/AboutFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/AboutFragment.kt @@ -17,7 +17,7 @@ import com.habitrpg.android.habitica.databinding.FragmentAboutBinding import com.habitrpg.android.habitica.helpers.AppConfigManager import com.habitrpg.android.habitica.helpers.MainNavigationController import com.habitrpg.android.habitica.modules.AppModule -import com.habitrpg.android.habitica.ui.helpers.DataBindingUtils +import com.habitrpg.common.habitica.extensions.DataBindingUtils import com.plattysoft.leonids.ParticleSystem import javax.inject.Inject import javax.inject.Named diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemDialogFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemDialogFragment.kt index be68782fd..24bfc8ab3 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemDialogFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemDialogFragment.kt @@ -33,7 +33,7 @@ import com.habitrpg.android.habitica.ui.adapter.inventory.ItemRecyclerAdapter import com.habitrpg.android.habitica.ui.fragments.BaseDialogFragment import com.habitrpg.android.habitica.ui.helpers.EmptyItem import com.habitrpg.android.habitica.ui.helpers.SafeDefaultItemAnimator -import com.habitrpg.android.habitica.ui.helpers.loadImage +import com.habitrpg.common.habitica.extensions.loadImage import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel import com.habitrpg.android.habitica.ui.views.dialogs.OpenedMysteryitemDialog import io.reactivex.rxjava3.disposables.CompositeDisposable diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemRecyclerFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemRecyclerFragment.kt index 613ff7f57..5e7186238 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemRecyclerFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemRecyclerFragment.kt @@ -39,7 +39,7 @@ import com.habitrpg.android.habitica.ui.adapter.inventory.ItemRecyclerAdapter import com.habitrpg.android.habitica.ui.fragments.BaseFragment import com.habitrpg.android.habitica.ui.helpers.EmptyItem import com.habitrpg.android.habitica.ui.helpers.SafeDefaultItemAnimator -import com.habitrpg.android.habitica.ui.helpers.loadImage +import com.habitrpg.common.habitica.extensions.loadImage import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel import com.habitrpg.android.habitica.ui.views.HabiticaSnackbar import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaAlertDialog diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/purchases/SubscriptionFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/purchases/SubscriptionFragment.kt index 9cf9b8746..69a532a73 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/purchases/SubscriptionFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/purchases/SubscriptionFragment.kt @@ -26,7 +26,7 @@ import com.habitrpg.android.habitica.models.user.User import com.habitrpg.android.habitica.ui.activities.GiftSubscriptionActivity import com.habitrpg.android.habitica.ui.fragments.BaseFragment import com.habitrpg.android.habitica.ui.fragments.PromoInfoFragment -import com.habitrpg.android.habitica.ui.helpers.loadImage +import com.habitrpg.common.habitica.extensions.loadImage import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaAlertDialog import com.habitrpg.android.habitica.ui.views.subscriptions.SubscriptionOptionView import javax.inject.Inject diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/InboxOverviewFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/InboxOverviewFragment.kt index fbcec8bdf..27ca514cc 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/InboxOverviewFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/InboxOverviewFragment.kt @@ -20,7 +20,8 @@ import com.habitrpg.android.habitica.helpers.AppConfigManager import com.habitrpg.android.habitica.helpers.MainNavigationController import com.habitrpg.android.habitica.helpers.RxErrorHandler import com.habitrpg.android.habitica.models.social.InboxConversation -import com.habitrpg.android.habitica.ui.AvatarView +import com.habitrpg.android.habitica.modules.AppModule +import com.habitrpg.common.habitica.views.AvatarView import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment import com.habitrpg.android.habitica.ui.helpers.dismissKeyboard import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/QuestDetailFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/QuestDetailFragment.kt index 7b38eb0d9..9198a531b 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/QuestDetailFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/QuestDetailFragment.kt @@ -25,7 +25,7 @@ import com.habitrpg.android.habitica.models.social.Group import com.habitrpg.android.habitica.modules.AppModule import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment import com.habitrpg.android.habitica.ui.helpers.MarkdownParser -import com.habitrpg.android.habitica.ui.helpers.loadImage +import com.habitrpg.common.habitica.extensions.loadImage import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaAlertDialog import javax.inject.Inject diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/NoPartyFragmentFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/NoPartyFragmentFragment.kt index aeecdc6c0..a9680a9ee 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/NoPartyFragmentFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/NoPartyFragmentFragment.kt @@ -24,10 +24,10 @@ import com.habitrpg.android.habitica.databinding.FragmentNoPartyBinding import com.habitrpg.android.habitica.helpers.AppConfigManager import com.habitrpg.android.habitica.helpers.MainNavigationController import com.habitrpg.android.habitica.helpers.RxErrorHandler -import com.habitrpg.android.habitica.ui.AvatarView +import com.habitrpg.common.habitica.views.AvatarView import com.habitrpg.android.habitica.ui.activities.GroupFormActivity import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment -import com.habitrpg.android.habitica.ui.helpers.DataBindingUtils +import com.habitrpg.common.habitica.extensions.DataBindingUtils import com.habitrpg.android.habitica.ui.helpers.setMarkdown import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel import com.habitrpg.android.habitica.ui.views.HabiticaSnackbar diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/PartyDetailFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/PartyDetailFragment.kt index 5bc17e90d..4ec764e8d 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/PartyDetailFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/PartyDetailFragment.kt @@ -28,14 +28,14 @@ import com.habitrpg.android.habitica.models.social.Challenge import com.habitrpg.android.habitica.models.social.Group import com.habitrpg.android.habitica.models.user.User import com.habitrpg.android.habitica.modules.AppModule -import com.habitrpg.android.habitica.ui.AvatarView +import com.habitrpg.common.habitica.views.AvatarView import com.habitrpg.android.habitica.ui.activities.FullProfileActivity import com.habitrpg.android.habitica.ui.activities.MainActivity import com.habitrpg.android.habitica.ui.fragments.BaseFragment import com.habitrpg.android.habitica.ui.fragments.inventory.items.ItemDialogFragment -import com.habitrpg.android.habitica.ui.helpers.DataBindingUtils +import com.habitrpg.common.habitica.extensions.DataBindingUtils import com.habitrpg.android.habitica.ui.helpers.dismissKeyboard -import com.habitrpg.android.habitica.ui.helpers.loadImage +import com.habitrpg.common.habitica.extensions.loadImage import com.habitrpg.android.habitica.ui.helpers.setMarkdown import com.habitrpg.android.habitica.ui.viewHolders.GroupMemberViewHolder import com.habitrpg.android.habitica.ui.viewmodels.PartyViewModel diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/ChatRecyclerViewHolder.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/ChatRecyclerViewHolder.kt index 34553b1dc..768a12e78 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/ChatRecyclerViewHolder.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/ChatRecyclerViewHolder.kt @@ -18,12 +18,12 @@ import com.habitrpg.android.habitica.helpers.RxErrorHandler import com.habitrpg.android.habitica.models.members.Member import com.habitrpg.android.habitica.models.social.ChatMessage import com.habitrpg.android.habitica.models.user.User -import com.habitrpg.android.habitica.ui.helpers.DataBindingUtils import com.habitrpg.android.habitica.ui.helpers.MarkdownParser import com.habitrpg.android.habitica.ui.helpers.setParsedMarkdown 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.common.habitica.extensions.DataBindingUtils import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers import io.reactivex.rxjava3.core.Maybe import io.reactivex.rxjava3.schedulers.Schedulers diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/MountViewHolder.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/MountViewHolder.kt index fcfa755e7..77cb28d8b 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/MountViewHolder.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/MountViewHolder.kt @@ -9,7 +9,7 @@ import com.habitrpg.android.habitica.R import com.habitrpg.android.habitica.databinding.MountOverviewItemBinding import com.habitrpg.android.habitica.extensions.inflate import com.habitrpg.android.habitica.models.inventory.Mount -import com.habitrpg.android.habitica.ui.helpers.DataBindingUtils +import com.habitrpg.common.habitica.extensions.DataBindingUtils import com.habitrpg.android.habitica.ui.menu.BottomSheetMenu import com.habitrpg.android.habitica.ui.menu.BottomSheetMenuItem import io.reactivex.rxjava3.subjects.PublishSubject diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/PetViewHolder.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/PetViewHolder.kt index 3822661bf..f17959cfe 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/PetViewHolder.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/PetViewHolder.kt @@ -13,7 +13,7 @@ import com.habitrpg.android.habitica.models.inventory.Egg import com.habitrpg.android.habitica.models.inventory.Food import com.habitrpg.android.habitica.models.inventory.HatchingPotion import com.habitrpg.android.habitica.models.inventory.Pet -import com.habitrpg.android.habitica.ui.helpers.DataBindingUtils +import com.habitrpg.common.habitica.extensions.DataBindingUtils import com.habitrpg.android.habitica.ui.menu.BottomSheetMenu import com.habitrpg.android.habitica.ui.menu.BottomSheetMenuItem import com.habitrpg.android.habitica.ui.views.dialogs.PetSuggestHatchDialog diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/ShopItemViewHolder.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/ShopItemViewHolder.kt index 4b094a75a..b1f8ec202 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/ShopItemViewHolder.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/ShopItemViewHolder.kt @@ -10,7 +10,7 @@ import com.habitrpg.android.habitica.databinding.RowShopitemBinding import com.habitrpg.android.habitica.extensions.dpToPx import com.habitrpg.android.habitica.extensions.isUsingNightModeResources import com.habitrpg.android.habitica.models.shops.ShopItem -import com.habitrpg.android.habitica.ui.helpers.loadImage +import com.habitrpg.common.habitica.extensions.loadImage import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper import com.habitrpg.android.habitica.ui.views.shops.PurchaseDialog diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewmodels/GroupViewModel.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewmodels/GroupViewModel.kt index b06bb9a68..9e511bbf2 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewmodels/GroupViewModel.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewmodels/GroupViewModel.kt @@ -6,8 +6,8 @@ import androidx.lifecycle.MutableLiveData import com.habitrpg.android.habitica.components.UserComponent import com.habitrpg.android.habitica.data.ChallengeRepository import com.habitrpg.android.habitica.data.SocialRepository -import com.habitrpg.android.habitica.extensions.Optional -import com.habitrpg.android.habitica.extensions.asOptional +import com.habitrpg.common.habitica.extensions.Optional +import com.habitrpg.common.habitica.extensions.asOptional import com.habitrpg.android.habitica.extensions.filterOptionalDoOnEmpty import com.habitrpg.android.habitica.helpers.MainNavigationController import com.habitrpg.android.habitica.helpers.NotificationsManager diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewmodels/InboxViewModel.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewmodels/InboxViewModel.kt index 9ca856d34..620b45ef2 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewmodels/InboxViewModel.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewmodels/InboxViewModel.kt @@ -10,8 +10,8 @@ import androidx.paging.PositionalDataSource import androidx.paging.toLiveData import com.habitrpg.android.habitica.components.UserComponent import com.habitrpg.android.habitica.data.SocialRepository -import com.habitrpg.android.habitica.extensions.Optional -import com.habitrpg.android.habitica.extensions.asOptional +import com.habitrpg.common.habitica.extensions.Optional +import com.habitrpg.common.habitica.extensions.asOptional import com.habitrpg.android.habitica.extensions.filterOptionalDoOnEmpty import com.habitrpg.android.habitica.helpers.RxErrorHandler import com.habitrpg.android.habitica.models.members.Member diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/EquipmentItemRow.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/EquipmentItemRow.kt index 3904587cd..e67cf420f 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/EquipmentItemRow.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/EquipmentItemRow.kt @@ -7,7 +7,7 @@ import android.widget.LinearLayout import com.habitrpg.android.habitica.R import com.habitrpg.android.habitica.databinding.ItemImageRowBinding import com.habitrpg.android.habitica.extensions.layoutInflater -import com.habitrpg.android.habitica.ui.helpers.loadImage +import com.habitrpg.common.habitica.extensions.loadImage class EquipmentItemRow(context: Context, attrs: AttributeSet?) : LinearLayout(context, attrs) { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/HabiticaProgressBar.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/HabiticaProgressBar.kt index b551f0233..acfb362a8 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/HabiticaProgressBar.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/HabiticaProgressBar.kt @@ -13,7 +13,7 @@ import androidx.core.widget.ImageViewCompat import com.habitrpg.android.habitica.R import com.habitrpg.android.habitica.databinding.ProgressBarBinding import com.habitrpg.android.habitica.extensions.layoutInflater -import com.habitrpg.android.habitica.ui.helpers.DataBindingUtils +import com.habitrpg.common.habitica.extensions.DataBindingUtils import kotlin.math.min class HabiticaProgressBar(context: Context, attrs: AttributeSet?) : FrameLayout(context, attrs) { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/NPCBannerView.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/NPCBannerView.kt index 5fb3ba45d..e561695c6 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/NPCBannerView.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/NPCBannerView.kt @@ -12,7 +12,7 @@ import com.habitrpg.android.habitica.R import com.habitrpg.android.habitica.databinding.NpcBannerBinding import com.habitrpg.android.habitica.extensions.layoutInflater import com.habitrpg.android.habitica.helpers.RxErrorHandler -import com.habitrpg.android.habitica.ui.helpers.DataBindingUtils +import com.habitrpg.common.habitica.extensions.DataBindingUtils import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers import io.reactivex.rxjava3.core.Observable import kotlin.math.roundToInt diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/dialogs/AchievementDetailDialog.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/dialogs/AchievementDetailDialog.kt index e310f98fb..ac374a498 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/dialogs/AchievementDetailDialog.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/dialogs/AchievementDetailDialog.kt @@ -8,8 +8,8 @@ import com.habitrpg.android.habitica.databinding.DialogAchievementDetailBinding import com.habitrpg.android.habitica.extensions.addCloseButton import com.habitrpg.android.habitica.extensions.fromHtml import com.habitrpg.android.habitica.models.Achievement -import com.habitrpg.android.habitica.ui.helpers.loadImage -import com.habitrpg.android.habitica.ui.views.PixelArtView +import com.habitrpg.common.habitica.extensions.loadImage +import com.habitrpg.common.habitica.views.PixelArtView class AchievementDetailDialog(val achievement: Achievement, context: Context) : HabiticaAlertDialog(context) { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/dialogs/AchievementDialog.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/dialogs/AchievementDialog.kt index 3c68fc3b6..f85431655 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/dialogs/AchievementDialog.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/dialogs/AchievementDialog.kt @@ -12,7 +12,7 @@ import com.habitrpg.android.habitica.extensions.layoutInflater import com.habitrpg.android.habitica.helpers.MainNavigationController import com.habitrpg.android.habitica.models.Notification import com.habitrpg.android.habitica.models.user.User -import com.habitrpg.android.habitica.ui.helpers.loadImage +import com.habitrpg.common.habitica.extensions.loadImage class AchievementDialog(context: Context) : HabiticaAlertDialog(context) { var isLastOnboardingAchievement: Boolean = false diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/dialogs/FirstDropDialog.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/dialogs/FirstDropDialog.kt index 13919e580..a9bb0a56c 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/dialogs/FirstDropDialog.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/dialogs/FirstDropDialog.kt @@ -4,8 +4,8 @@ import android.content.Context import android.view.LayoutInflater import com.habitrpg.android.habitica.R import com.habitrpg.android.habitica.helpers.MainNavigationController -import com.habitrpg.android.habitica.ui.helpers.loadImage -import com.habitrpg.android.habitica.ui.views.PixelArtView +import com.habitrpg.common.habitica.extensions.loadImage +import com.habitrpg.common.habitica.views.PixelArtView class FirstDropDialog(context: Context) : HabiticaAlertDialog(context) { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/dialogs/PetSuggestHatchDialog.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/dialogs/PetSuggestHatchDialog.kt index c09503234..46e5977ef 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/dialogs/PetSuggestHatchDialog.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/dialogs/PetSuggestHatchDialog.kt @@ -18,8 +18,8 @@ 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.helpers.loadImage +import com.habitrpg.common.habitica.extensions.DataBindingUtils +import com.habitrpg.common.habitica.extensions.loadImage import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers import io.reactivex.rxjava3.core.Flowable import io.reactivex.rxjava3.core.Observable diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/dialogs/QuestCompletedDialogContent.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/dialogs/QuestCompletedDialogContent.kt index 8f4e046d7..9954ea4d0 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/dialogs/QuestCompletedDialogContent.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/dialogs/QuestCompletedDialogContent.kt @@ -15,9 +15,9 @@ import com.habitrpg.android.habitica.extensions.fromHtml import com.habitrpg.android.habitica.extensions.layoutInflater import com.habitrpg.android.habitica.models.inventory.QuestContent import com.habitrpg.android.habitica.models.inventory.QuestDropItem -import com.habitrpg.android.habitica.ui.helpers.loadImage +import com.habitrpg.common.habitica.extensions.loadImage import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper -import com.habitrpg.android.habitica.ui.views.PixelArtView +import com.habitrpg.common.habitica.views.PixelArtView class QuestCompletedDialogContent : LinearLayout { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/dialogs/WonChallengeDialog.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/dialogs/WonChallengeDialog.kt index ddcbe0ed0..ac1880ee7 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/dialogs/WonChallengeDialog.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/dialogs/WonChallengeDialog.kt @@ -8,8 +8,8 @@ import android.widget.TextView import com.habitrpg.android.habitica.R import com.habitrpg.android.habitica.extensions.fromHtml import com.habitrpg.android.habitica.models.notifications.ChallengeWonData -import com.habitrpg.android.habitica.ui.helpers.loadImage -import com.habitrpg.android.habitica.ui.views.PixelArtView +import com.habitrpg.common.habitica.extensions.loadImage +import com.habitrpg.common.habitica.views.PixelArtView class WonChallengeDialog(context: Context) : HabiticaAlertDialog(context) { fun configure(data: ChallengeWonData?) { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/equipment/EquipmentOverviewItem.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/equipment/EquipmentOverviewItem.kt index 62146b185..77280c013 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/equipment/EquipmentOverviewItem.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/equipment/EquipmentOverviewItem.kt @@ -9,7 +9,7 @@ import androidx.core.content.ContextCompat import com.habitrpg.android.habitica.R import com.habitrpg.android.habitica.databinding.EquipmentOverviewItemBinding import com.habitrpg.android.habitica.extensions.layoutInflater -import com.habitrpg.android.habitica.ui.helpers.loadImage +import com.habitrpg.common.habitica.extensions.loadImage import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper class EquipmentOverviewItem @JvmOverloads constructor( diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialogBackgroundContent.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialogBackgroundContent.kt index fbb8ed811..a078a789d 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialogBackgroundContent.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialogBackgroundContent.kt @@ -4,7 +4,6 @@ import android.content.Context import android.widget.TextView import com.habitrpg.android.habitica.databinding.PurchaseDialogBackgroundBinding import com.habitrpg.android.habitica.extensions.layoutInflater -import com.habitrpg.android.habitica.models.Avatar import com.habitrpg.android.habitica.models.shops.ShopItem import com.habitrpg.android.habitica.ui.AvatarView import com.habitrpg.android.habitica.ui.views.PixelArtView diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialogBaseContent.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialogBaseContent.kt index 6bf12be43..ddeb9fcde 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialogBaseContent.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialogBaseContent.kt @@ -4,7 +4,7 @@ import android.content.Context import android.widget.TextView import com.habitrpg.android.habitica.databinding.DialogPurchaseContentItemBinding import com.habitrpg.android.habitica.extensions.layoutInflater -import com.habitrpg.android.habitica.ui.views.PixelArtView +import com.habitrpg.common.habitica.views.PixelArtView class PurchaseDialogBaseContent(context: Context) : PurchaseDialogContent(context) { val binding = DialogPurchaseContentItemBinding.inflate(context.layoutInflater, this) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialogContent.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialogContent.kt index ac391c128..69d4d342f 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialogContent.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialogContent.kt @@ -10,9 +10,9 @@ import com.habitrpg.android.habitica.extensions.dpToPx import com.habitrpg.android.habitica.extensions.fromHtml import com.habitrpg.android.habitica.models.inventory.QuestContent import com.habitrpg.android.habitica.models.shops.ShopItem -import com.habitrpg.android.habitica.ui.helpers.DataBindingUtils -import com.habitrpg.android.habitica.ui.helpers.loadImage -import com.habitrpg.android.habitica.ui.views.PixelArtView +import com.habitrpg.common.habitica.extensions.DataBindingUtils +import com.habitrpg.common.habitica.extensions.loadImage +import com.habitrpg.common.habitica.views.PixelArtView abstract class PurchaseDialogContent @JvmOverloads constructor( context: Context, diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialogCustomizationContent.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialogCustomizationContent.kt index d91dad862..1b7a41f33 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialogCustomizationContent.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialogCustomizationContent.kt @@ -4,7 +4,7 @@ import android.content.Context import android.widget.TextView import com.habitrpg.android.habitica.databinding.DialogPurchaseCustomizationBinding import com.habitrpg.android.habitica.extensions.layoutInflater -import com.habitrpg.android.habitica.ui.views.PixelArtView +import com.habitrpg.common.habitica.views.PixelArtView class PurchaseDialogCustomizationContent(context: Context) : PurchaseDialogContent(context) { val binding = DialogPurchaseCustomizationBinding.inflate(context.layoutInflater, this) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialogCustomizationSetContent.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialogCustomizationSetContent.kt index 888f0d50c..e62c1d1a5 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialogCustomizationSetContent.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialogCustomizationSetContent.kt @@ -8,8 +8,8 @@ import com.habitrpg.android.habitica.databinding.DialogPurchaseCustomizationsetB import com.habitrpg.android.habitica.extensions.dpToPx import com.habitrpg.android.habitica.extensions.layoutInflater import com.habitrpg.android.habitica.models.shops.ShopItem -import com.habitrpg.android.habitica.ui.helpers.loadImage -import com.habitrpg.android.habitica.ui.views.PixelArtView +import com.habitrpg.common.habitica.extensions.loadImage +import com.habitrpg.common.habitica.views.PixelArtView class PurchaseDialogCustomizationSetContent(context: Context) : PurchaseDialogContent(context) { val binding = DialogPurchaseCustomizationsetBinding.inflate(context.layoutInflater, this) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialogGearContent.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialogGearContent.kt index 14db2a4f2..f5ca941cf 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialogGearContent.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialogGearContent.kt @@ -8,7 +8,7 @@ import com.habitrpg.android.habitica.databinding.DialogPurchaseContentGearBindin import com.habitrpg.android.habitica.extensions.layoutInflater import com.habitrpg.android.habitica.models.inventory.Equipment import com.habitrpg.android.habitica.models.shops.ShopItem -import com.habitrpg.android.habitica.ui.views.PixelArtView +import com.habitrpg.common.habitica.views.PixelArtView internal class PurchaseDialogGearContent(context: Context) : PurchaseDialogContent(context) { val binding = DialogPurchaseContentGearBinding.inflate(context.layoutInflater, this) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialogGemsContent.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialogGemsContent.kt index 01aa92c4c..792bed60b 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialogGemsContent.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialogGemsContent.kt @@ -7,7 +7,7 @@ import com.habitrpg.android.habitica.extensions.asDrawable import com.habitrpg.android.habitica.extensions.layoutInflater import com.habitrpg.android.habitica.models.shops.ShopItem import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper -import com.habitrpg.android.habitica.ui.views.PixelArtView +import com.habitrpg.common.habitica.views.PixelArtView internal class PurchaseDialogGemsContent(context: Context) : PurchaseDialogContent(context) { internal val binding = DialogPurchaseGemsBinding.inflate(context.layoutInflater, this) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialogItemContent.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialogItemContent.kt index 948ba73fb..042e7f4d8 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialogItemContent.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialogItemContent.kt @@ -5,7 +5,7 @@ import android.widget.TextView import com.habitrpg.android.habitica.databinding.DialogPurchaseContentItemBinding import com.habitrpg.android.habitica.extensions.layoutInflater import com.habitrpg.android.habitica.models.shops.ShopItem -import com.habitrpg.android.habitica.ui.views.PixelArtView +import com.habitrpg.common.habitica.views.PixelArtView class PurchaseDialogItemContent(context: Context) : PurchaseDialogContent(context) { private val binding = DialogPurchaseContentItemBinding.inflate(context.layoutInflater, this) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialogQuestContent.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialogQuestContent.kt index ec3a500b2..7e6fdc1b1 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialogQuestContent.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialogQuestContent.kt @@ -12,9 +12,9 @@ import com.habitrpg.android.habitica.databinding.DialogPurchaseContentQuestBindi import com.habitrpg.android.habitica.extensions.layoutInflater import com.habitrpg.android.habitica.models.inventory.QuestContent import com.habitrpg.android.habitica.models.inventory.QuestDropItem -import com.habitrpg.android.habitica.ui.helpers.loadImage +import com.habitrpg.common.habitica.extensions.loadImage import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper -import com.habitrpg.android.habitica.ui.views.PixelArtView +import com.habitrpg.common.habitica.views.PixelArtView class PurchaseDialogQuestContent(context: Context) : PurchaseDialogContent(context) { private val binding = DialogPurchaseContentQuestBinding.inflate(context.layoutInflater, this) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/social/OldQuestProgressView.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/social/OldQuestProgressView.kt index 23b1bb696..59f1dd919 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/social/OldQuestProgressView.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/social/OldQuestProgressView.kt @@ -17,7 +17,7 @@ import com.habitrpg.android.habitica.models.inventory.QuestContent import com.habitrpg.android.habitica.models.inventory.QuestProgress import com.habitrpg.android.habitica.models.inventory.QuestProgressCollect import com.habitrpg.android.habitica.models.user.User -import com.habitrpg.android.habitica.ui.helpers.loadImage +import com.habitrpg.common.habitica.extensions.loadImage import com.habitrpg.android.habitica.ui.views.HabiticaIcons import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/social/QuestProgressView.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/social/QuestProgressView.kt index b16876a7c..eb0406f30 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/social/QuestProgressView.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/social/QuestProgressView.kt @@ -25,8 +25,8 @@ import com.habitrpg.android.habitica.models.inventory.Quest import com.habitrpg.android.habitica.models.inventory.QuestContent import com.habitrpg.android.habitica.models.inventory.QuestProgressCollect import com.habitrpg.android.habitica.models.user.User -import com.habitrpg.android.habitica.ui.helpers.DataBindingUtils -import com.habitrpg.android.habitica.ui.helpers.loadImage +import com.habitrpg.common.habitica.extensions.DataBindingUtils +import com.habitrpg.common.habitica.extensions.loadImage import com.habitrpg.android.habitica.ui.helpers.setMarkdown import com.habitrpg.android.habitica.ui.views.HabiticaIcons import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/widget/AvatarStatsWidgetProvider.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/AvatarStatsWidgetProvider.kt index b43e6d762..b9d735b51 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/widget/AvatarStatsWidgetProvider.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/AvatarStatsWidgetProvider.kt @@ -16,7 +16,7 @@ import com.habitrpg.android.habitica.helpers.HealthFormatter import com.habitrpg.android.habitica.helpers.NumberAbbreviator import com.habitrpg.android.habitica.helpers.RxErrorHandler import com.habitrpg.android.habitica.models.user.User -import com.habitrpg.android.habitica.ui.AvatarView +import com.habitrpg.common.habitica.views.AvatarView import com.habitrpg.android.habitica.ui.activities.MainActivity import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper diff --git a/common/.gitignore b/common/.gitignore new file mode 100644 index 000000000..42afabfd2 --- /dev/null +++ b/common/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/common/build.gradle b/common/build.gradle new file mode 100644 index 000000000..871507c17 --- /dev/null +++ b/common/build.gradle @@ -0,0 +1,46 @@ +plugins { + id 'com.android.library' + id 'org.jetbrains.kotlin.android' +} + +android { + compileSdk 32 + + defaultConfig { + minSdk 21 + targetSdk 32 + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + consumerProguardFiles "consumer-rules.pro" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + + kotlinOptions { + jvmTarget = JavaVersion.VERSION_1_8.toString() + } +} + +dependencies { + + implementation 'androidx.core:core-ktx:1.7.0' + implementation 'androidx.appcompat:appcompat:1.4.1' + implementation 'com.google.android.material:material:1.6.0' + + // Image Management Library + implementation("io.coil-kt:coil:1.4.0") + implementation("io.coil-kt:coil-gif:1.4.0") + + testImplementation 'junit:junit:4.13.2' + androidTestImplementation 'androidx.test.ext:junit:1.1.3' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' +} \ No newline at end of file diff --git a/common/consumer-rules.pro b/common/consumer-rules.pro new file mode 100644 index 000000000..e69de29bb diff --git a/common/proguard-rules.pro b/common/proguard-rules.pro new file mode 100644 index 000000000..481bb4348 --- /dev/null +++ b/common/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/common/src/androidTest/java/com/habitrpg/common/habitica/ExampleInstrumentedTest.kt b/common/src/androidTest/java/com/habitrpg/common/habitica/ExampleInstrumentedTest.kt new file mode 100644 index 000000000..9e4a0be54 --- /dev/null +++ b/common/src/androidTest/java/com/habitrpg/common/habitica/ExampleInstrumentedTest.kt @@ -0,0 +1,24 @@ +package com.habitrpg.common.habitica + +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.ext.junit.runners.AndroidJUnit4 + +import org.junit.Test +import org.junit.runner.RunWith + +import org.junit.Assert.* + +/** + * Instrumented test, which will execute on an Android device. + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +@RunWith(AndroidJUnit4::class) +class ExampleInstrumentedTest { + @Test + fun useAppContext() { + // Context of the app under test. + val appContext = InstrumentationRegistry.getInstrumentation().targetContext + assertEquals("com.habitrpg.common.habitica.test", appContext.packageName) + } +} \ No newline at end of file diff --git a/common/src/main/AndroidManifest.xml b/common/src/main/AndroidManifest.xml new file mode 100644 index 000000000..411eba234 --- /dev/null +++ b/common/src/main/AndroidManifest.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/helpers/DataBindingUtils.kt b/common/src/main/java/com/habitrpg/common/habitica/extensions/DataBindingUtils.kt similarity index 95% rename from Habitica/src/main/java/com/habitrpg/android/habitica/ui/helpers/DataBindingUtils.kt rename to common/src/main/java/com/habitrpg/common/habitica/extensions/DataBindingUtils.kt index 5200028c9..5f556ec29 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/helpers/DataBindingUtils.kt +++ b/common/src/main/java/com/habitrpg/common/habitica/extensions/DataBindingUtils.kt @@ -1,4 +1,4 @@ -package com.habitrpg.android.habitica.ui.helpers +package com.habitrpg.common.habitica.extensions import android.content.Context import android.graphics.PorterDuff @@ -11,10 +11,10 @@ import androidx.core.content.res.ResourcesCompat import androidx.core.graphics.drawable.toBitmap import coil.imageLoader import coil.request.ImageRequest -import com.habitrpg.android.habitica.R import com.habitrpg.android.habitica.extensions.setTintWith -import com.habitrpg.android.habitica.helpers.AppConfigManager -import com.habitrpg.android.habitica.ui.views.PixelArtView +import com.habitrpg.common.habitica.R +import com.habitrpg.common.habitica.helpers.AppConfigManager +import com.habitrpg.common.habitica.views.PixelArtView import java.util.Collections import java.util.Date @@ -101,7 +101,7 @@ object DataBindingUtils { private var spriteSubstitutions: Map = HashMap() get() { if (Date().time - (lastSubstitutionCheck?.time ?: 0) > 180000) { - field = AppConfigManager(null).spriteSubstitutions()["generic"] ?: HashMap() + field = AppConfigManager().spriteSubstitutions()["generic"] ?: HashMap() lastSubstitutionCheck = Date() } return field diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/extensions/Drawable-Extendsions.kt b/common/src/main/java/com/habitrpg/common/habitica/extensions/Drawable-Extendsions.kt similarity index 100% rename from Habitica/src/main/java/com/habitrpg/android/habitica/extensions/Drawable-Extendsions.kt rename to common/src/main/java/com/habitrpg/common/habitica/extensions/Drawable-Extendsions.kt diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/extensions/Int-Extensions.kt b/common/src/main/java/com/habitrpg/common/habitica/extensions/Int-Extensions.kt similarity index 100% rename from Habitica/src/main/java/com/habitrpg/android/habitica/extensions/Int-Extensions.kt rename to common/src/main/java/com/habitrpg/common/habitica/extensions/Int-Extensions.kt diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/extensions/Optional.kt b/common/src/main/java/com/habitrpg/common/habitica/extensions/Optional.kt similarity index 82% rename from Habitica/src/main/java/com/habitrpg/android/habitica/extensions/Optional.kt rename to common/src/main/java/com/habitrpg/common/habitica/extensions/Optional.kt index 701d619f3..7b2a62423 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/extensions/Optional.kt +++ b/common/src/main/java/com/habitrpg/common/habitica/extensions/Optional.kt @@ -1,4 +1,4 @@ -package com.habitrpg.android.habitica.extensions +package com.habitrpg.common.habitica.extensions data class Optional(val value: T?) { val isEmpty = value == null diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/extensions/String-Extensions.kt b/common/src/main/java/com/habitrpg/common/habitica/extensions/String-Extensions.kt similarity index 100% rename from Habitica/src/main/java/com/habitrpg/android/habitica/extensions/String-Extensions.kt rename to common/src/main/java/com/habitrpg/common/habitica/extensions/String-Extensions.kt diff --git a/common/src/main/java/com/habitrpg/common/habitica/helpers/AppConfigManager.kt b/common/src/main/java/com/habitrpg/common/habitica/helpers/AppConfigManager.kt new file mode 100644 index 000000000..941eae549 --- /dev/null +++ b/common/src/main/java/com/habitrpg/common/habitica/helpers/AppConfigManager.kt @@ -0,0 +1,9 @@ +package com.habitrpg.common.habitica.helpers + +open class AppConfigManager() { + + open fun spriteSubstitutions(): Map> { + // TODO actual implementation + return emptyMap() + } +} \ No newline at end of file diff --git a/common/src/main/java/com/habitrpg/common/habitica/models/Avatar.kt b/common/src/main/java/com/habitrpg/common/habitica/models/Avatar.kt new file mode 100644 index 000000000..5f0c6fa66 --- /dev/null +++ b/common/src/main/java/com/habitrpg/common/habitica/models/Avatar.kt @@ -0,0 +1,17 @@ +package com.habitrpg.common.habitica.models + + +interface Avatar { + val currentMount: String? + val currentPet: String? + val sleep: Boolean + val stats: AvatarStats? + val preferences: AvatarPreferences? + val flags: AvatarFlags? + val gemCount: Int + val hourglassCount: Int + val costume: AvatarOutfit? + val equipped: AvatarOutfit? + val hasClass: Boolean + fun isValid(): Boolean +} \ No newline at end of file diff --git a/common/src/main/java/com/habitrpg/common/habitica/models/AvatarBuffs.kt b/common/src/main/java/com/habitrpg/common/habitica/models/AvatarBuffs.kt new file mode 100644 index 000000000..1c1ae1531 --- /dev/null +++ b/common/src/main/java/com/habitrpg/common/habitica/models/AvatarBuffs.kt @@ -0,0 +1,14 @@ +package com.habitrpg.common.habitica.models + +interface AvatarBuffs { + var con: Float? + var str: Float? + var per: Float? + var _int: Float? + + var seafoam: Boolean? + var spookySparkles: Boolean? + var shinySeed: Boolean? + var snowball: Boolean? + var streaks: Boolean? +} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/AvatarFlags.kt b/common/src/main/java/com/habitrpg/common/habitica/models/AvatarFlags.kt similarity index 54% rename from Habitica/src/main/java/com/habitrpg/android/habitica/models/AvatarFlags.kt rename to common/src/main/java/com/habitrpg/common/habitica/models/AvatarFlags.kt index 4e59e94de..a3a972e89 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/models/AvatarFlags.kt +++ b/common/src/main/java/com/habitrpg/common/habitica/models/AvatarFlags.kt @@ -1,5 +1,5 @@ -package com.habitrpg.android.habitica.models +package com.habitrpg.common.habitica.models interface AvatarFlags { var classSelected: Boolean -} +} \ No newline at end of file diff --git a/common/src/main/java/com/habitrpg/common/habitica/models/AvatarHair.kt b/common/src/main/java/com/habitrpg/common/habitica/models/AvatarHair.kt new file mode 100644 index 000000000..937a12ac2 --- /dev/null +++ b/common/src/main/java/com/habitrpg/common/habitica/models/AvatarHair.kt @@ -0,0 +1,14 @@ +package com.habitrpg.common.habitica.models + +interface AvatarHair { + var mustache: Int + var beard: Int + var bangs: Int + var base: Int + var flower: Int + var color: String? + + fun isAvailable(hairId: Int): Boolean { + return hairId > 0 + } +} diff --git a/common/src/main/java/com/habitrpg/common/habitica/models/AvatarOutfit.kt b/common/src/main/java/com/habitrpg/common/habitica/models/AvatarOutfit.kt new file mode 100644 index 000000000..7745e5663 --- /dev/null +++ b/common/src/main/java/com/habitrpg/common/habitica/models/AvatarOutfit.kt @@ -0,0 +1,30 @@ +package com.habitrpg.common.habitica.models + +import android.text.TextUtils + +interface AvatarOutfit { + var armor: String + var back: String + var body: String + var head: String + var shield: String + var weapon: String + var eyeWear: String + var headAccessory: String + + + fun isAvailable(outfit: String): Boolean { + return !TextUtils.isEmpty(outfit) && !outfit.endsWith("base_0") + } + + fun updateWith(newOutfit: AvatarOutfit) { + this.armor = newOutfit.armor + this.back = newOutfit.back + this.body = newOutfit.body + this.eyeWear = newOutfit.eyeWear + this.head = newOutfit.head + this.headAccessory = newOutfit.headAccessory + this.shield = newOutfit.shield + this.weapon = newOutfit.weapon + } +} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/AvatarPreferences.kt b/common/src/main/java/com/habitrpg/common/habitica/models/AvatarPreferences.kt similarity index 65% rename from Habitica/src/main/java/com/habitrpg/android/habitica/models/AvatarPreferences.kt rename to common/src/main/java/com/habitrpg/common/habitica/models/AvatarPreferences.kt index b576faef8..336db2f2d 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/models/AvatarPreferences.kt +++ b/common/src/main/java/com/habitrpg/common/habitica/models/AvatarPreferences.kt @@ -1,9 +1,7 @@ -package com.habitrpg.android.habitica.models - -import com.habitrpg.android.habitica.models.user.Hair +package com.habitrpg.common.habitica.models interface AvatarPreferences { - val hair: Hair? + val hair: AvatarHair? val costume: Boolean val sleep: Boolean val shirt: String? @@ -12,4 +10,4 @@ interface AvatarPreferences { val background: String? val chair: String? val disableClasses: Boolean -} +} \ No newline at end of file diff --git a/common/src/main/java/com/habitrpg/common/habitica/models/AvatarStats.kt b/common/src/main/java/com/habitrpg/common/habitica/models/AvatarStats.kt new file mode 100644 index 000000000..da25846c5 --- /dev/null +++ b/common/src/main/java/com/habitrpg/common/habitica/models/AvatarStats.kt @@ -0,0 +1,23 @@ +package com.habitrpg.common.habitica.models + +interface AvatarStats { + val buffs: AvatarBuffs? + var habitClass: String? + var points: Int? + var lvl: Int? + var gp: Double? + var exp: Double? + var mp: Double? + var hp: Double? + + var toNextLevel: Int? + var maxHealth: Int? + var maxMP: Int? + val isBuffed: Boolean + get() { + return buffs?.str ?: 0f > 0 || + buffs?.con ?: 0f > 0 || + buffs?._int ?: 0f > 0 || + buffs?.per ?: 0f > 0 + } +} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/AvatarView.kt b/common/src/main/java/com/habitrpg/common/habitica/views/AvatarView.kt similarity index 89% rename from Habitica/src/main/java/com/habitrpg/android/habitica/ui/AvatarView.kt rename to common/src/main/java/com/habitrpg/common/habitica/views/AvatarView.kt index a20d6a80f..77eab7905 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/AvatarView.kt +++ b/common/src/main/java/com/habitrpg/common/habitica/views/AvatarView.kt @@ -1,505 +1,509 @@ -package com.habitrpg.android.habitica.ui - -import android.content.Context -import android.graphics.Bitmap -import android.graphics.Canvas -import android.graphics.Matrix -import android.graphics.PointF -import android.graphics.Rect -import android.graphics.RectF -import android.graphics.drawable.Drawable -import android.text.TextUtils -import android.util.AttributeSet -import android.widget.FrameLayout -import android.widget.ImageView -import androidx.core.graphics.drawable.toBitmap -import androidx.core.view.marginStart -import androidx.core.view.marginTop -import coil.clear -import coil.load -import coil.target.ImageViewTarget -import com.habitrpg.android.habitica.BuildConfig -import com.habitrpg.android.habitica.R -import com.habitrpg.android.habitica.extensions.dpToPx -import com.habitrpg.android.habitica.helpers.AppConfigManager -import com.habitrpg.android.habitica.models.Avatar -import com.habitrpg.android.habitica.ui.helpers.DataBindingUtils -import java.util.Date -import java.util.EnumMap -import java.util.concurrent.atomic.AtomicInteger - -class AvatarView : FrameLayout { - - private var showBackground = true - private var showMount = true - private var showPet = true - private var showSleeping = true - private var hasBackground: Boolean = false - private var preview: Map? = null - private var backgroundForPurchase: String? = null - private var hasMount: Boolean = false - private var hasPet: Boolean = false - private val imageViewHolder = mutableListOf() - private var avatar: Avatar? = null - private var avatarRectF: RectF? = null - private val avatarMatrix = Matrix() - private val numberLayersInProcess = AtomicInteger(0) - private var avatarImageConsumer: ((Bitmap?) -> Unit)? = null - private var avatarBitmap: Bitmap? = null - private var avatarCanvas: Canvas? = null - private var currentLayers: Map? = null - - private val layerMap: Map - get() { - val avatar = this.avatar ?: return emptyMap() - return getLayerMap(avatar, true) - } - - private var spriteSubstitutions: Map> = HashMap() - get() { - if (Date().time - (lastSubstitutionCheck?.time ?: 0) > 180000) { - field = AppConfigManager(null).spriteSubstitutions() - lastSubstitutionCheck = Date() - } - return field - } - private var lastSubstitutionCheck: Date? = null - - private val originalRect: Rect - get() = if (showMount || showPet) FULL_HERO_RECT else if (showBackground) COMPACT_HERO_RECT else HERO_ONLY_RECT - - private val avatarImage: Bitmap? - get() { - if (BuildConfig.DEBUG && (avatar == null || avatarRectF == null)) { - error("Assertion failed") - } - val canvasRect = Rect(0, 0, 140.dpToPx(context), 147.dpToPx(context)) - if (canvasRect.isEmpty) return null - avatarBitmap = Bitmap.createBitmap(canvasRect.width(), canvasRect.height(), Bitmap.Config.ARGB_8888) - avatarBitmap?.let { avatarCanvas = Canvas(it) } - imageViewHolder.forEach { - val lp = it.layoutParams - val bitmap = it.drawable?.toBitmap(lp.width, lp.height) ?: return@forEach - avatarCanvas?.drawBitmap(bitmap, Rect(0, 0, bitmap.width, bitmap.height), Rect(it.marginStart, it.marginTop, bitmap.width, bitmap.height), null) - } - - return avatarBitmap - } - - constructor(context: Context) : super(context) { - init(null, 0) - } - - constructor(context: Context, attrs: AttributeSet) : super(context, attrs) { - init(attrs, 0) - } - - constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle) { - init(attrs, defStyle) - } - - constructor(context: Context, showBackground: Boolean, showMount: Boolean, showPet: Boolean) : super(context) { - this.showBackground = showBackground - this.showMount = showMount - this.showPet = showPet - } - - private fun init(attrs: AttributeSet?, defStyle: Int) { - // Load attributes - val a = context.obtainStyledAttributes( - attrs, R.styleable.AvatarView, defStyle, 0 - ) - - try { - showBackground = a.getBoolean(R.styleable.AvatarView_showBackground, true) - showMount = a.getBoolean(R.styleable.AvatarView_showMount, true) - showPet = a.getBoolean(R.styleable.AvatarView_showPet, true) - showSleeping = a.getBoolean(R.styleable.AvatarView_showSleeping, true) - } finally { - a.recycle() - } - - setWillNotDraw(false) - } - - private fun showLayers(layerMap: Map) { - var i = 0 - - currentLayers = layerMap - - numberLayersInProcess.set(layerMap.size) - - for ((layerKey, layerName) in layerMap) { - val layerNumber = i++ - - val imageView = if (imageViewHolder.size <= layerNumber) { - val newImageView = ImageView(context) - newImageView.scaleType = ImageView.ScaleType.MATRIX - addView(newImageView) - imageViewHolder.add(newImageView) - newImageView - } else { - imageViewHolder[layerNumber] - } - - if (imageView.tag == layerName) { - continue - } - imageView.tag = layerName - imageView.clear() - imageView.setImageResource(0) - - imageView.load(DataBindingUtils.BASE_IMAGE_URL + DataBindingUtils.getFullFilename(layerName)) { - allowHardware(false) - target(object : ImageViewTarget(imageView) { - override fun onError(error: Drawable?) { - super.onError(error) - onLayerComplete() - } - - override fun onSuccess(result: Drawable) { - super.onSuccess(result) - val bounds = getLayerBounds(layerKey, layerName, result) - imageView.imageMatrix = avatarMatrix - val layoutParams = imageView.layoutParams as? LayoutParams - layoutParams?.topMargin = bounds.top - layoutParams?.marginStart = bounds.left - layoutParams?.width = bounds.right - layoutParams?.height = bounds.bottom - imageView.layoutParams = layoutParams - onLayerComplete() - } - }) - } - } - while (i < (imageViewHolder.size)) { - imageViewHolder[i].clear() - imageViewHolder[i].setImageResource(0) - imageViewHolder[i].tag = null - i++ - } - } - - private fun getLayerMap(avatar: Avatar, resetHasAttributes: Boolean): Map { - val layerMap = getAvatarLayerMap(avatar, spriteSubstitutions) - - if (resetHasAttributes) { - hasPet = false - hasMount = hasPet - hasBackground = hasMount - } - - var mountName = avatar.currentMount - if (showMount && mountName?.isNotEmpty() == true) { - mountName = substituteOrReturn(spriteSubstitutions["mounts"], mountName) - layerMap[LayerType.MOUNT_BODY] = "Mount_Body_$mountName" - layerMap[LayerType.MOUNT_HEAD] = "Mount_Head_$mountName" - if (resetHasAttributes) hasMount = true - } - - var petName = avatar.currentPet - if (showPet && petName?.isNotEmpty() == true) { - petName = substituteOrReturn(spriteSubstitutions["pets"], petName) - layerMap[LayerType.PET] = "Pet-$petName" - if (resetHasAttributes) hasPet = true - } - - var backgroundName = avatar.preferences?.background -// if (backgroundForPurchase != null) { - if (preview != null) { - layerMap[preview?.keys?.first()] = preview?.values?.first() - if (resetHasAttributes) hasBackground = true - } else if (showBackground && backgroundName?.isNotEmpty() == true) { - backgroundName = substituteOrReturn(spriteSubstitutions["backgrounds"], backgroundName) - layerMap[LayerType.BACKGROUND] = "background_$backgroundName" - if (resetHasAttributes) hasBackground = true - } - - if (showSleeping && avatar.sleep) { - layerMap[LayerType.ZZZ] = "zzz" - } - - return layerMap - } - - private fun substituteOrReturn(substitutions: Map?, name: String): String { - for (key in substitutions?.keys ?: arrayListOf()) { - if (name.contains(key)) { - return substitutions?.get(key) ?: name - } - } - return name - } - - @Suppress("ReturnCount") - private fun getAvatarLayerMap(avatar: Avatar, substitutions: Map>): EnumMap { - val layerMap = EnumMap(LayerType::class.java) - - if (!avatar.isValid()) { - return layerMap - } - - val prefs = avatar.preferences ?: return layerMap - val outfit = if (prefs.costume) { - avatar.costume - } else { - avatar.equipped - } - - var hasVisualBuffs = false - - avatar.stats?.buffs?.let { buffs -> - if (buffs.snowball == true) { - layerMap[LayerType.VISUAL_BUFF] = "avatar_snowball_" + avatar.stats?.habitClass - hasVisualBuffs = true - } - - if (buffs.seafoam == true) { - layerMap[LayerType.VISUAL_BUFF] = "seafoam_star" - hasVisualBuffs = true - } - - if (buffs.shinySeed == true) { - layerMap[LayerType.VISUAL_BUFF] = "avatar_floral_" + avatar.stats?.habitClass - hasVisualBuffs = true - } - - if (buffs.spookySparkles == true) { - layerMap[LayerType.VISUAL_BUFF] = "ghost" - hasVisualBuffs = true - } - } - - val substitutedVisualBuff = substitutions["visualBuff"]?.get("full") - if (substitutedVisualBuff != null) { - layerMap[LayerType.VISUAL_BUFF] = substitutedVisualBuff - hasVisualBuffs = true - } - - val hair = prefs.hair - if (!hasVisualBuffs) { - if (!TextUtils.isEmpty(prefs.chair)) { - layerMap[LayerType.CHAIR] = prefs.chair - } - - if (outfit != null) { - if (!TextUtils.isEmpty(outfit.back) && "back_base_0" != outfit.back) { - layerMap[LayerType.BACK] = outfit.back - } - if (outfit.isAvailable(outfit.armor)) { - layerMap[LayerType.ARMOR] = prefs.size + "_" + outfit.armor - } - if (outfit.isAvailable(outfit.body)) { - layerMap[LayerType.BODY] = outfit.body - } - if (outfit.isAvailable(outfit.eyeWear)) { - layerMap[LayerType.EYEWEAR] = outfit.eyeWear - } - if (outfit.isAvailable(outfit.head)) { - layerMap[LayerType.HEAD] = outfit.head - } - if (outfit.isAvailable(outfit.headAccessory)) { - layerMap[LayerType.HEAD_ACCESSORY] = outfit.headAccessory - } - if (outfit.isAvailable(outfit.shield)) { - layerMap[LayerType.SHIELD] = outfit.shield - } - if (outfit.isAvailable(outfit.weapon)) { - layerMap[LayerType.WEAPON] = outfit.weapon - } - } - - layerMap[LayerType.SKIN] = "skin_" + prefs.skin + if (prefs.sleep) "_sleep" else "" - layerMap[LayerType.SHIRT] = prefs.size + "_shirt_" + prefs.shirt - layerMap[LayerType.HEAD_0] = "head_0" - - if (hair != null) { - val hairColor = hair.color - - if (hair.isAvailable(hair.base)) { - layerMap[LayerType.HAIR_BASE] = "hair_base_" + hair.base + "_" + hairColor - } - if (hair.isAvailable(hair.bangs)) { - layerMap[LayerType.HAIR_BANGS] = "hair_bangs_" + hair.bangs + "_" + hairColor - } - if (hair.isAvailable(hair.mustache)) { - layerMap[LayerType.HAIR_MUSTACHE] = "hair_mustache_" + hair.mustache + "_" + hairColor - } - if (hair.isAvailable(hair.beard)) { - layerMap[LayerType.HAIR_BEARD] = "hair_beard_" + hair.beard + "_" + hairColor - } - } - } - - if (hair != null && hair.isAvailable(hair.flower)) { - layerMap[LayerType.HAIR_FLOWER] = "hair_flower_" + hair.flower - } - - return layerMap - } - - private fun getLayerBounds(layerType: LayerType, layerName: String, drawable: Drawable): Rect { - var offset: PointF? = null - val bounds = Rect(0, 0, drawable.intrinsicWidth, drawable.intrinsicHeight) - val boundsF = RectF(bounds) - - // lookup layer specific offset - when (layerName) { - "weapon_special_critical" -> offset = if (showMount || showPet) { - // full hero box - when { - hasMount -> PointF(13.0f, 12.0f) - hasPet -> PointF(13.0f, 24.5f + 12.0f) - else -> PointF(13.0f, 28.0f + 12.0f) - } - } else if (showBackground) { - // compact hero box - PointF(-12.0f, 18.0f + 12.0f) - } else { - // hero only box - PointF(-12.0f, 12.0f) - } - } - - // otherwise lookup default layer type based offset - if (offset == null) { - when (layerType) { - LayerType.BACKGROUND -> if (!(showMount || showPet)) { - offset = PointF(-25.0f, 0.0f) // compact hero box - } - LayerType.MOUNT_BODY, LayerType.MOUNT_HEAD -> offset = PointF(25.0f, 18.0f) // full hero box - LayerType.CHAIR, LayerType.BACK, LayerType.SKIN, LayerType.SHIRT, LayerType.ARMOR, LayerType.BODY, LayerType.HEAD_0, LayerType.HAIR_BASE, LayerType.HAIR_BANGS, LayerType.HAIR_MUSTACHE, LayerType.HAIR_BEARD, LayerType.EYEWEAR, LayerType.VISUAL_BUFF, LayerType.HEAD, LayerType.HEAD_ACCESSORY, LayerType.HAIR_FLOWER, LayerType.SHIELD, LayerType.WEAPON, LayerType.ZZZ -> if (showMount || showPet) { - // full hero box - offset = when { - hasMount -> if (layerMap[LayerType.MOUNT_HEAD]?.contains("Kangaroo") == true) { - PointF(25.0f, 18f) - } else { - PointF(25.0f, 0f) - } - hasPet -> PointF(25.0f, 24.5f) - else -> PointF(25.0f, 28.0f) - } - } else if (showBackground) { - // compact hero box - offset = PointF(0.0f, 18.0f) - } - LayerType.PET -> offset = PointF(0f, (FULL_HERO_RECT.height() - bounds.height()).toFloat()) - } - } - - if (offset != null) { - when (layerName) { - "head_special_0" -> offset = PointF(offset.x - 3, offset.y - 18) - "weapon_special_0" -> offset = PointF(offset.x - 12, offset.y + 4) - "weapon_special_1" -> offset = PointF(offset.x - 12, offset.y + 4) - "weapon_special_critical" -> offset = PointF(offset.x - 12, offset.y + 4) - "head_special_1" -> offset = PointF(offset.x, offset.y + 3) - } - - val translateMatrix = Matrix() - translateMatrix.setTranslate(offset.x, offset.y) - translateMatrix.mapRect(boundsF) - } - - // resize bounds to fit and keep original aspect ratio - avatarMatrix.mapRect(boundsF) - boundsF.round(bounds) - - return bounds - } - - private fun onLayerComplete() { - if (numberLayersInProcess.decrementAndGet() == 0) { - avatarImageConsumer?.invoke(avatarImage) - } - } - - fun onAvatarImageReady(consumer: ((Bitmap?) -> Unit)) { - avatarImageConsumer = consumer - if (imageViewHolder.size > 0 && numberLayersInProcess.get() == 0) { - avatarImageConsumer?.invoke(avatarImage) - } else { - initAvatarRectMatrix() - showLayers(layerMap) - } - } - - fun setAvatar(avatar: Avatar, preview: Map? = null) { - val oldUser = this.avatar - this.avatar = avatar - preview?.let { this.preview = preview } - - var equals = false - if (oldUser != null) { - val newLayerMap = getLayerMap(avatar, false) - - equals = currentLayers == newLayerMap - } - if (!equals) { - invalidate() - } - } - - private fun initAvatarRectMatrix() { - if (avatarRectF == null) { - val srcRect = originalRect - // full hero box when showMount and showPet is enabled (140w * 147h) - // compact hero box when only showBackground is enabled (114w * 114h) - // hero only box when all show settings disabled (90w * 90h) - val width = if (this.width > 0) this.width.toFloat() else 140.dpToPx(context).toFloat() - val height = if (this.height > 0) this.height.toFloat() else 147.dpToPx(context).toFloat() - avatarRectF = RectF(0f, 0f, width, height) - avatarMatrix.setRectToRect(RectF(srcRect), avatarRectF, Matrix.ScaleToFit.START) - avatarRectF = RectF(srcRect) - avatarMatrix.mapRect(avatarRectF) - } - } - - override fun onDraw(canvas: Canvas?) { - super.onDraw(canvas) - - initAvatarRectMatrix() - - // draw only when user is set - if (avatar?.isValid() != true) return - - showLayers(layerMap) - } - - override fun invalidateDrawable(drawable: Drawable) { - invalidate() - if (avatarCanvas != null) draw(avatarCanvas) - } - - enum class LayerType { - BACKGROUND, - MOUNT_BODY, - CHAIR, - BACK, - SKIN, - SHIRT, - ARMOR, - BODY, - HEAD_0, - HAIR_BASE, - HAIR_BANGS, - HAIR_MUSTACHE, - HAIR_BEARD, - EYEWEAR, - VISUAL_BUFF, - HEAD, - HEAD_ACCESSORY, - HAIR_FLOWER, - SHIELD, - WEAPON, - MOUNT_HEAD, - ZZZ, - PET - } - - companion object { - private val FULL_HERO_RECT = Rect(0, 0, 140, 147) - private val COMPACT_HERO_RECT = Rect(0, 0, 114, 114) - private val HERO_ONLY_RECT = Rect(0, 0, 90, 90) - } -} +package com.habitrpg.common.habitica.views + +import android.content.Context +import android.graphics.Bitmap +import android.graphics.Canvas +import android.graphics.Matrix +import android.graphics.PointF +import android.graphics.Rect +import android.graphics.RectF +import android.graphics.drawable.Drawable +import android.text.TextUtils +import android.util.AttributeSet +import android.widget.FrameLayout +import android.widget.ImageView +import androidx.core.graphics.drawable.toBitmap +import androidx.core.view.marginStart +import androidx.core.view.marginTop +import coil.clear +import coil.load +import com.habitrpg.common.habitica.BuildConfig +import com.habitrpg.android.habitica.extensions.dpToPx +import com.habitrpg.common.habitica.R +import com.habitrpg.common.habitica.extensions.DataBindingUtils +import com.habitrpg.common.habitica.helpers.AppConfigManager +import com.habitrpg.common.habitica.models.Avatar +import java.util.Date +import java.util.EnumMap +import java.util.concurrent.atomic.AtomicInteger + +class AvatarView : FrameLayout { + + private var showBackground = true + private var showMount = true + private var showPet = true + private var showSleeping = true + private var hasBackground: Boolean = false + private var hasMount: Boolean = false + private var hasPet: Boolean = false + private val imageViewHolder = mutableListOf() + private var avatar: Avatar? = null + private var avatarRectF: RectF? = null + private val avatarMatrix = Matrix() + private val numberLayersInProcess = AtomicInteger(0) + private var avatarImageConsumer: ((Bitmap?) -> Unit)? = null + private var avatarBitmap: Bitmap? = null + private var avatarCanvas: Canvas? = null + private var currentLayers: Map? = null + + private val layerMap: Map + get() { + val avatar = this.avatar ?: return emptyMap() + return getLayerMap(avatar, true) + } + + private var spriteSubstitutions: Map> = HashMap() + get() { + if (Date().time - (lastSubstitutionCheck?.time ?: 0) > 180000) { + field = AppConfigManager().spriteSubstitutions() + lastSubstitutionCheck = Date() + } + return field + } + private var lastSubstitutionCheck: Date? = null + + private val originalRect: Rect + get() = if (showMount || showPet) FULL_HERO_RECT else if (showBackground) COMPACT_HERO_RECT else HERO_ONLY_RECT + + private val avatarImage: Bitmap? + get() { + if (BuildConfig.DEBUG && (avatar == null || avatarRectF == null)) { + error("Assertion failed") + } + val canvasRect = Rect(0, 0, 140.dpToPx(context), 147.dpToPx(context)) + if (canvasRect.isEmpty) return null + avatarBitmap = Bitmap.createBitmap( + canvasRect.width(), + canvasRect.height(), + Bitmap.Config.ARGB_8888 + ) + avatarBitmap?.let { avatarCanvas = Canvas(it) } + imageViewHolder.forEach { + val lp = it.layoutParams + val bitmap = it.drawable?.toBitmap(lp.width, lp.height) ?: return@forEach + avatarCanvas?.drawBitmap(bitmap, + Rect(0, 0, bitmap.width, bitmap.height), + Rect(it.marginStart, it.marginTop, bitmap.width, bitmap.height), null) + } + + return avatarBitmap + } + + constructor(context: Context) : super(context) { + init(null, 0) + } + + constructor(context: Context, attrs: AttributeSet) : super(context, attrs) { + init(attrs, 0) + } + + constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle) { + init(attrs, defStyle) + } + + constructor(context: Context, showBackground: Boolean, showMount: Boolean, showPet: Boolean) : super(context) { + this.showBackground = showBackground + this.showMount = showMount + this.showPet = showPet + } + + private fun init(attrs: AttributeSet?, defStyle: Int) { + // Load attributes + val a = context.obtainStyledAttributes( + attrs, R.styleable.AvatarView, defStyle, 0 + ) + + try { + showBackground = a.getBoolean(R.styleable.AvatarView_showBackground, true) + showMount = a.getBoolean(R.styleable.AvatarView_showMount, true) + showPet = a.getBoolean(R.styleable.AvatarView_showPet, true) + showSleeping = a.getBoolean(R.styleable.AvatarView_showSleeping, true) + } finally { + a.recycle() + } + + setWillNotDraw(false) + } + + private fun showLayers(layerMap: Map) { + var i = 0 + + currentLayers = layerMap + + numberLayersInProcess.set(layerMap.size) + + for ((layerKey, layerName) in layerMap) { + val layerNumber = i++ + + val imageView = if (imageViewHolder.size <= layerNumber) { + val newImageView = ImageView(context) + newImageView.scaleType = ImageView.ScaleType.MATRIX + addView(newImageView) + imageViewHolder.add(newImageView) + newImageView + } else { + imageViewHolder[layerNumber] + } + + if (imageView.tag == layerName) { + continue + } + imageView.tag = layerName + imageView.clear() + imageView.setImageResource(0) + + imageView.load( + DataBindingUtils.BASE_IMAGE_URL + DataBindingUtils.getFullFilename( + layerName + ) + ) { + allowHardware(false) + target(object : coil.target.ImageViewTarget(imageView) { + override fun onError(error: Drawable?) { + super.onError(error) + onLayerComplete() + } + + override fun onSuccess(result: Drawable) { + super.onSuccess(result) + val bounds = getLayerBounds(layerKey, layerName, result) + imageView.imageMatrix = avatarMatrix + val layoutParams = imageView.layoutParams as? LayoutParams + layoutParams?.topMargin = bounds.top + layoutParams?.marginStart = bounds.left + layoutParams?.width = bounds.right + layoutParams?.height = bounds.bottom + imageView.layoutParams = layoutParams + onLayerComplete() + } + }) + } + } + while (i < (imageViewHolder.size)) { + imageViewHolder[i].clear() + imageViewHolder[i].setImageResource(0) + imageViewHolder[i].tag = null + i++ + } + } + + private fun getLayerMap(avatar: Avatar, resetHasAttributes: Boolean): Map { + val layerMap = getAvatarLayerMap(avatar, spriteSubstitutions) + + if (resetHasAttributes) { + hasPet = false + hasMount = hasPet + hasBackground = hasMount + } + + var mountName = avatar.currentMount + if (showMount && mountName?.isNotEmpty() == true) { + mountName = substituteOrReturn(spriteSubstitutions["mounts"], mountName) + layerMap[LayerType.MOUNT_BODY] = "Mount_Body_$mountName" + layerMap[LayerType.MOUNT_HEAD] = "Mount_Head_$mountName" + if (resetHasAttributes) hasMount = true + } + + var petName = avatar.currentPet + if (showPet && petName?.isNotEmpty() == true) { + petName = substituteOrReturn(spriteSubstitutions["pets"], petName) + layerMap[LayerType.PET] = "Pet-$petName" + if (resetHasAttributes) hasPet = true + } + + var backgroundName = avatar.preferences?.background + if (showBackground && backgroundName?.isNotEmpty() == true) { + backgroundName = substituteOrReturn(spriteSubstitutions["backgrounds"], backgroundName) + layerMap[LayerType.BACKGROUND] = "background_$backgroundName" + if (resetHasAttributes) hasBackground = true + } + + if (showSleeping && avatar.sleep) { + layerMap[LayerType.ZZZ] = "zzz" + } + + return layerMap + } + + private fun substituteOrReturn(substitutions: Map?, name: String): String { + for (key in substitutions?.keys ?: arrayListOf()) { + if (name.contains(key)) { + return substitutions?.get(key) ?: name + } + } + return name + } + + @Suppress("ReturnCount") + private fun getAvatarLayerMap(avatar: Avatar, substitutions: Map>): EnumMap { + val layerMap = EnumMap(LayerType::class.java) + + if (!avatar.isValid()) { + return layerMap + } + + val prefs = avatar.preferences ?: return layerMap + val outfit = if (prefs.costume) { + avatar.costume + } else { + avatar.equipped + } + + var hasVisualBuffs = false + + avatar.stats?.buffs?.let { buffs -> + if (buffs.snowball == true) { + layerMap[LayerType.VISUAL_BUFF] = "avatar_snowball_" + avatar.stats?.habitClass + hasVisualBuffs = true + } + + if (buffs.seafoam == true) { + layerMap[LayerType.VISUAL_BUFF] = "seafoam_star" + hasVisualBuffs = true + } + + if (buffs.shinySeed == true) { + layerMap[LayerType.VISUAL_BUFF] = "avatar_floral_" + avatar.stats?.habitClass + hasVisualBuffs = true + } + + if (buffs.spookySparkles == true) { + layerMap[LayerType.VISUAL_BUFF] = "ghost" + hasVisualBuffs = true + } + } + + val substitutedVisualBuff = substitutions["visualBuff"]?.get("full") + if (substitutedVisualBuff != null) { + layerMap[LayerType.VISUAL_BUFF] = substitutedVisualBuff + hasVisualBuffs = true + } + + val hair = prefs.hair + if (!hasVisualBuffs) { + if (!TextUtils.isEmpty(prefs.chair)) { + layerMap[LayerType.CHAIR] = prefs.chair + } + + if (outfit != null) { + if (!TextUtils.isEmpty(outfit.back) && "back_base_0" != outfit.back) { + layerMap[LayerType.BACK] = outfit.back + } + if (outfit.isAvailable(outfit.armor)) { + layerMap[LayerType.ARMOR] = prefs.size + "_" + outfit.armor + } + if (outfit.isAvailable(outfit.body)) { + layerMap[LayerType.BODY] = outfit.body + } + if (outfit.isAvailable(outfit.eyeWear)) { + layerMap[LayerType.EYEWEAR] = outfit.eyeWear + } + if (outfit.isAvailable(outfit.head)) { + layerMap[LayerType.HEAD] = outfit.head + } + if (outfit.isAvailable(outfit.headAccessory)) { + layerMap[LayerType.HEAD_ACCESSORY] = outfit.headAccessory + } + if (outfit.isAvailable(outfit.shield)) { + layerMap[LayerType.SHIELD] = outfit.shield + } + if (outfit.isAvailable(outfit.weapon)) { + layerMap[LayerType.WEAPON] = outfit.weapon + } + } + + layerMap[LayerType.SKIN] = "skin_" + prefs.skin + if (prefs.sleep) "_sleep" else "" + layerMap[LayerType.SHIRT] = prefs.size + "_shirt_" + prefs.shirt + layerMap[LayerType.HEAD_0] = "head_0" + + if (hair != null) { + val hairColor = hair.color + + if (hair.isAvailable(hair.base)) { + layerMap[LayerType.HAIR_BASE] = "hair_base_" + hair.base + "_" + hairColor + } + if (hair.isAvailable(hair.bangs)) { + layerMap[LayerType.HAIR_BANGS] = "hair_bangs_" + hair.bangs + "_" + hairColor + } + if (hair.isAvailable(hair.mustache)) { + layerMap[LayerType.HAIR_MUSTACHE] = "hair_mustache_" + hair.mustache + "_" + hairColor + } + if (hair.isAvailable(hair.beard)) { + layerMap[LayerType.HAIR_BEARD] = "hair_beard_" + hair.beard + "_" + hairColor + } + } + } + + if (hair != null && hair.isAvailable(hair.flower)) { + layerMap[LayerType.HAIR_FLOWER] = "hair_flower_" + hair.flower + } + + return layerMap + } + + private fun getLayerBounds(layerType: LayerType, layerName: String, drawable: Drawable): Rect { + var offset: PointF? = null + val bounds = Rect(0, 0, drawable.intrinsicWidth, drawable.intrinsicHeight) + val boundsF = RectF(bounds) + + // lookup layer specific offset + when (layerName) { + "weapon_special_critical" -> offset = if (showMount || showPet) { + // full hero box + when { + hasMount -> PointF(13.0f, 12.0f) + hasPet -> PointF(13.0f, 24.5f + 12.0f) + else -> PointF(13.0f, 28.0f + 12.0f) + } + } else if (showBackground) { + // compact hero box + PointF(-12.0f, 18.0f + 12.0f) + } else { + // hero only box + PointF(-12.0f, 12.0f) + } + } + + // otherwise lookup default layer type based offset + if (offset == null) { + when (layerType) { + LayerType.BACKGROUND -> if (!(showMount || showPet)) { + offset = PointF(-25.0f, 0.0f) // compact hero box + } + LayerType.MOUNT_BODY, LayerType.MOUNT_HEAD -> offset = + PointF(25.0f, 18.0f) // full hero box + LayerType.CHAIR, LayerType.BACK, LayerType.SKIN, LayerType.SHIRT, LayerType.ARMOR, LayerType.BODY, LayerType.HEAD_0, LayerType.HAIR_BASE, LayerType.HAIR_BANGS, LayerType.HAIR_MUSTACHE, LayerType.HAIR_BEARD, LayerType.EYEWEAR, LayerType.VISUAL_BUFF, LayerType.HEAD, LayerType.HEAD_ACCESSORY, LayerType.HAIR_FLOWER, LayerType.SHIELD, LayerType.WEAPON, LayerType.ZZZ -> if (showMount || showPet) { + // full hero box + offset = when { + hasMount -> if (layerMap[LayerType.MOUNT_HEAD]?.contains("Kangaroo") == true) { + PointF(25.0f, 18f) + } else { + PointF(25.0f, 0f) + } + hasPet -> PointF(25.0f, 24.5f) + else -> PointF(25.0f, 28.0f) + } + } else if (showBackground) { + // compact hero box + offset = PointF(0.0f, 18.0f) + } + LayerType.PET -> offset = + PointF(0f, (FULL_HERO_RECT.height() - bounds.height()).toFloat()) + } + } + + if (offset != null) { + when (layerName) { + "head_special_0" -> offset = PointF(offset.x - 3, offset.y - 18) + "weapon_special_0" -> offset = PointF(offset.x - 12, offset.y + 4) + "weapon_special_1" -> offset = PointF(offset.x - 12, offset.y + 4) + "weapon_special_critical" -> offset = PointF(offset.x - 12, offset.y + 4) + "head_special_1" -> offset = PointF(offset.x, offset.y + 3) + } + + val translateMatrix = Matrix() + translateMatrix.setTranslate(offset.x, offset.y) + translateMatrix.mapRect(boundsF) + } + + // resize bounds to fit and keep original aspect ratio + avatarMatrix.mapRect(boundsF) + boundsF.round(bounds) + + return bounds + } + + private fun onLayerComplete() { + if (numberLayersInProcess.decrementAndGet() == 0) { + avatarImageConsumer?.invoke(avatarImage) + } + } + + fun onAvatarImageReady(consumer: ((Bitmap?) -> Unit)) { + avatarImageConsumer = consumer + if (imageViewHolder.size > 0 && numberLayersInProcess.get() == 0) { + avatarImageConsumer?.invoke(avatarImage) + } else { + initAvatarRectMatrix() + showLayers(layerMap) + } + } + + fun setAvatar(avatar: Avatar) { + val oldUser = this.avatar + this.avatar = avatar + + var equals = false + if (oldUser != null) { + val newLayerMap = getLayerMap(avatar, false) + + equals = currentLayers == newLayerMap + } + if (!equals) { + invalidate() + } + } + + private fun initAvatarRectMatrix() { + if (avatarRectF == null) { + val srcRect = originalRect + // full hero box when showMount and showPet is enabled (140w * 147h) + // compact hero box when only showBackground is enabled (114w * 114h) + // hero only box when all show settings disabled (90w * 90h) + val width = if (this.width > 0) this.width.toFloat() else 140.dpToPx(context).toFloat() + val height = if (this.height > 0) this.height.toFloat() else 147.dpToPx(context).toFloat() + avatarRectF = RectF(0f, 0f, width, height) + avatarMatrix.setRectToRect(RectF(srcRect), avatarRectF, Matrix.ScaleToFit.START) + avatarRectF = RectF(srcRect) + avatarMatrix.mapRect(avatarRectF) + } + } + + override fun onDraw(canvas: Canvas?) { + super.onDraw(canvas) + + initAvatarRectMatrix() + + // draw only when user is set + if (avatar?.isValid() != true) return + + showLayers(layerMap) + } + + override fun invalidateDrawable(drawable: Drawable) { + invalidate() + if (avatarCanvas != null) draw(avatarCanvas) + } + + enum class LayerType { + BACKGROUND, + MOUNT_BODY, + CHAIR, + BACK, + SKIN, + SHIRT, + ARMOR, + BODY, + HEAD_0, + HAIR_BASE, + HAIR_BANGS, + HAIR_MUSTACHE, + HAIR_BEARD, + EYEWEAR, + VISUAL_BUFF, + HEAD, + HEAD_ACCESSORY, + HAIR_FLOWER, + SHIELD, + WEAPON, + MOUNT_HEAD, + ZZZ, + PET + } + + companion object { + private val FULL_HERO_RECT = Rect(0, 0, 140, 147) + private val COMPACT_HERO_RECT = Rect(0, 0, 114, 114) + private val HERO_ONLY_RECT = Rect(0, 0, 90, 90) + } +} \ No newline at end of file diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/PixelArtView.kt b/common/src/main/java/com/habitrpg/common/habitica/views/PixelArtView.kt similarity index 97% rename from Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/PixelArtView.kt rename to common/src/main/java/com/habitrpg/common/habitica/views/PixelArtView.kt index 413c747af..2d795e96e 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/PixelArtView.kt +++ b/common/src/main/java/com/habitrpg/common/habitica/views/PixelArtView.kt @@ -1,4 +1,4 @@ -package com.habitrpg.android.habitica.ui.views +package com.habitrpg.common.habitica.views import android.content.Context import android.graphics.Bitmap diff --git a/common/src/main/res/drawable/layout_rounded_bg.xml b/common/src/main/res/drawable/layout_rounded_bg.xml new file mode 100644 index 000000000..b086829ae --- /dev/null +++ b/common/src/main/res/drawable/layout_rounded_bg.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/common/src/main/res/values/attrs.xml b/common/src/main/res/values/attrs.xml new file mode 100644 index 000000000..2dd19d865 --- /dev/null +++ b/common/src/main/res/values/attrs.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/common/src/test/java/com/habitrpg/common/habitica/ExampleUnitTest.kt b/common/src/test/java/com/habitrpg/common/habitica/ExampleUnitTest.kt new file mode 100644 index 000000000..759425045 --- /dev/null +++ b/common/src/test/java/com/habitrpg/common/habitica/ExampleUnitTest.kt @@ -0,0 +1,17 @@ +package com.habitrpg.common.habitica + +import org.junit.Test + +import org.junit.Assert.* + +/** + * Example local unit test, which will execute on the development machine (host). + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +class ExampleUnitTest { + @Test + fun addition_isCorrect() { + assertEquals(4, 2 + 2) + } +} \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index aa64f9dd7..68aeea8b3 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,2 +1,4 @@ include ':shared' -include 'Habitica', ':Habitica' \ No newline at end of file +include 'Habitica', ':Habitica' +include ':wearos' +include ':common' diff --git a/wearos/.gitignore b/wearos/.gitignore new file mode 100644 index 000000000..42afabfd2 --- /dev/null +++ b/wearos/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/wearos/build.gradle b/wearos/build.gradle new file mode 100644 index 000000000..85e812abc --- /dev/null +++ b/wearos/build.gradle @@ -0,0 +1,39 @@ +plugins { + id 'com.android.application' + id 'org.jetbrains.kotlin.android' +} + +android { + compileSdk 32 + + defaultConfig { + applicationId "com.habitrpg.wearos.habitica" + minSdk 26 + targetSdk 32 + versionCode 1 + versionName "1.0" + + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + buildFeatures { + viewBinding true + } +} + +dependencies { + + implementation 'androidx.core:core-ktx:1.7.0' + implementation 'com.google.android.gms:play-services-wearable:17.1.0' + implementation 'androidx.percentlayout:percentlayout:1.0.0' + implementation 'androidx.legacy:legacy-support-v4:1.0.0' + implementation 'androidx.recyclerview:recyclerview:1.2.1' + implementation 'androidx.wear:wear:1.2.0' + + implementation project(':common') +} \ No newline at end of file diff --git a/wearos/proguard-rules.pro b/wearos/proguard-rules.pro new file mode 100644 index 000000000..481bb4348 --- /dev/null +++ b/wearos/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/wearos/src/main/AndroidManifest.xml b/wearos/src/main/AndroidManifest.xml new file mode 100644 index 000000000..24a913094 --- /dev/null +++ b/wearos/src/main/AndroidManifest.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/wearos/src/main/java/com/habitrpg/wearos/habitica/MainActivity.kt b/wearos/src/main/java/com/habitrpg/wearos/habitica/MainActivity.kt new file mode 100644 index 000000000..a552e90bf --- /dev/null +++ b/wearos/src/main/java/com/habitrpg/wearos/habitica/MainActivity.kt @@ -0,0 +1,17 @@ +package com.habitrpg.wearos.habitica + +import android.app.Activity +import android.os.Bundle +import com.habitrpg.wearos.habitica.databinding.ActivityMainBinding + +class MainActivity : Activity() { + + private lateinit var binding: ActivityMainBinding + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + binding = ActivityMainBinding.inflate(layoutInflater) + setContentView(binding.root) + } +} \ No newline at end of file diff --git a/wearos/src/main/res/layout/activity_main.xml b/wearos/src/main/res/layout/activity_main.xml new file mode 100644 index 000000000..81d28e870 --- /dev/null +++ b/wearos/src/main/res/layout/activity_main.xml @@ -0,0 +1,26 @@ + + + + + + + + + \ No newline at end of file diff --git a/wearos/src/main/res/mipmap-hdpi/ic_launcher.webp b/wearos/src/main/res/mipmap-hdpi/ic_launcher.webp new file mode 100644 index 000000000..c209e78ec Binary files /dev/null and b/wearos/src/main/res/mipmap-hdpi/ic_launcher.webp differ diff --git a/wearos/src/main/res/mipmap-mdpi/ic_launcher.webp b/wearos/src/main/res/mipmap-mdpi/ic_launcher.webp new file mode 100644 index 000000000..4f0f1d64e Binary files /dev/null and b/wearos/src/main/res/mipmap-mdpi/ic_launcher.webp differ diff --git a/wearos/src/main/res/mipmap-xhdpi/ic_launcher.webp b/wearos/src/main/res/mipmap-xhdpi/ic_launcher.webp new file mode 100644 index 000000000..948a3070f Binary files /dev/null and b/wearos/src/main/res/mipmap-xhdpi/ic_launcher.webp differ diff --git a/wearos/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/wearos/src/main/res/mipmap-xxhdpi/ic_launcher.webp new file mode 100644 index 000000000..28d4b77f9 Binary files /dev/null and b/wearos/src/main/res/mipmap-xxhdpi/ic_launcher.webp differ diff --git a/wearos/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/wearos/src/main/res/mipmap-xxxhdpi/ic_launcher.webp new file mode 100644 index 000000000..aa7d6427e Binary files /dev/null and b/wearos/src/main/res/mipmap-xxxhdpi/ic_launcher.webp differ diff --git a/wearos/src/main/res/values-round/strings.xml b/wearos/src/main/res/values-round/strings.xml new file mode 100644 index 000000000..d74c66c62 --- /dev/null +++ b/wearos/src/main/res/values-round/strings.xml @@ -0,0 +1,3 @@ + + Hello Round World! + \ No newline at end of file diff --git a/wearos/src/main/res/values/dimens.xml b/wearos/src/main/res/values/dimens.xml new file mode 100644 index 000000000..1a7ba4a1a --- /dev/null +++ b/wearos/src/main/res/values/dimens.xml @@ -0,0 +1,15 @@ + + + + 0dp + + + 5dp + \ No newline at end of file diff --git a/wearos/src/main/res/values/strings.xml b/wearos/src/main/res/values/strings.xml new file mode 100644 index 000000000..56db6aa67 --- /dev/null +++ b/wearos/src/main/res/values/strings.xml @@ -0,0 +1,8 @@ + + Habitica + + Hello Square World! + \ No newline at end of file