Fix stable display issues

This commit is contained in:
Phillip Thelen 2020-07-30 12:44:01 +02:00
parent 0f2ebdfc7d
commit fb4ab4203d
22 changed files with 124 additions and 74 deletions

View file

@ -162,7 +162,7 @@ android {
multiDexEnabled true
resConfigs "en", "bg", "de", "en-rGB", "es", "fr", "hr-rHR", "in", "it", "iw", "ja", "ko", "lt", "nl", "pl", "pt-rBR", "pt-rPT", "ru", "tr", "zh", "zh-rTW"
versionCode 2497
versionCode 2500
versionName "2.8"
}

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="?attr/colorPrimary" android:state_focused="true"/>
<item android:alpha="0.87" android:color="?attr/colorPrimary" android:state_hovered="true"/>
<item android:alpha="0.12" android:color="?attr/colorPrimary" android:state_enabled="false"/>
<item android:alpha="0.38" android:color="?attr/colorPrimary"/>
</selector>

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/pill_gray"/>
<solid android:color="@color/gray_700"/>
<corners android:radius="20dip"/>
<padding android:left="0dip" android:top="0dip" android:right="0dip" android:bottom="0dip" />
</shape>

View file

@ -17,7 +17,6 @@
android:layout_height="wrap_content"
android:minHeight="?attr/actionBarSize"
android:theme="@style/Toolbar"
android:background="@color/brand_300"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="@style/ThemeOverlay.AppCompat.Dark"/>
@ -47,7 +46,8 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/TaskFormTextInputLayoutAppearance"
app:boxStrokeColor="?attr/colorPrimaryDark"
app:boxStrokeColor="?attr/colorPrimary"
android:backgroundTint="?attr/colorPrimary"
android:alpha="0.75">
<androidx.appcompat.widget.AppCompatEditText
android:id="@+id/text_edit_text"
@ -62,7 +62,8 @@
style="@style/TaskFormTextInputLayoutAppearance"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:boxStrokeColor="?attr/colorPrimaryDark"
app:boxStrokeColor="?attr/colorPrimary"
android:backgroundTint="?attr/colorPrimary"
android:alpha="0.75">
<androidx.appcompat.widget.AppCompatEditText
android:id="@+id/notes_edit_text"

View file

@ -14,16 +14,17 @@
android:layout_weight="1"
tools:text="Test header"
style="@style/Overline"
android:textAppearance="?android:attr/textAppearanceMedium"/>
android:textColor="@color/gray_200"/>
<TextView
android:id="@+id/count_pill"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_height="24dp"
android:visibility="gone"
style="@style/Pill"
android:textSize="10sp"
android:textAllCaps="true"
android:letterSpacing="0.15"
android:gravity="center"
/>
<LinearLayout
android:layout_width="wrap_content"

View file

@ -45,7 +45,7 @@
android:layout_width="80dp"
android:layout_height="80dp"
android:background="@drawable/layout_rounded_bg_gray_700"
android:layout_marginEnd="10dp"
android:layout_marginEnd="13dp"
android:layout_marginStart="@dimen/spacing_small">
<com.facebook.drawee.view.SimpleDraweeView
android:id="@+id/pet_view"

View file

@ -7,13 +7,18 @@
android:background="@drawable/layout_rounded_bg_gray_700"
android:orientation="vertical"
android:padding="8dp">
<FrameLayout
android:id="@+id/image_view_wrapper"
android:layout_width="65dp"
android:layout_height="74dp"
android:layout_gravity="center">
<com.facebook.drawee.view.SimpleDraweeView
android:id="@+id/imageView"
android:layout_width="65dp"
android:layout_height="65dp"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_gravity="center"
app:actualImageScaleType="fitCenter"/>
</FrameLayout>
<ProgressBar
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"

View file

@ -15,12 +15,18 @@
android:orientation="vertical"
android:background="@drawable/layout_rounded_bg_shopitem"
android:layout_centerInParent="true">
<FrameLayout
android:layout_width="68dp"
android:layout_height="58dp"
android:layout_gravity="center">
<com.facebook.drawee.view.SimpleDraweeView
android:id="@+id/imageView"
android:layout_width="@dimen/pet_image_width"
android:layout_height="58dp"
android:layout_gravity="center_horizontal"
app:actualImageScaleType="fitCenter" />
android:layout_width="68dp"
android:layout_height="68dp"
android:layout_gravity="center"
app:actualImageScaleType="fitCenter"
/>
</FrameLayout>
<TextView
android:layout_width="match_parent"
android:layout_height="18dp"

View file

@ -1082,4 +1082,6 @@
<string name="keep_x_tasks">Keep %d Tasks</string>
<string name="delete_x_tasks">Delete %d Tasks</string>
<string name="challenge_task_name">%s Challenge Task</string>
<string name="pet_category">%s Pets</string>
<string name="mount_category">%s Mounts</string>
</resources>

View file

@ -273,7 +273,7 @@
<style name="Toolbar" parent="Base.ThemeOverlay.AppCompat.ActionBar">
<item name="android:textColorPrimary">?attr/toolbarContentColor</item>
<item name="textColorSecondary">?attr/toolbarContentColor</item>
<item name="background">?attr/colorPrimaryDark</item>
<item name="background">?attr/colorPrimary</item>
<item name="actionMenuTextColor">?attr/toolbarContentColor</item>
<item name="android:actionMenuTextColor">?attr/toolbarContentColor</item>
</style>
@ -387,6 +387,7 @@
<item name="android:paddingLeft">@dimen/pill_horizontal_padding</item>
<item name="android:paddingTop">@dimen/pill_vertical_padding</item>
<item name="android:paddingBottom">@dimen/pill_vertical_padding</item>
<item name="android:textColor">@color/gray_200</item>
</style>
<style name="Pill.White">
@ -634,7 +635,10 @@
<item name="boxBackgroundColor">@color/white_75_alpha</item>
<item name="android:textColor">?attr/colorPrimaryText</item>
<item name="android:textColorHint">@color/textColorLight</item>
<item name="colorControlNormal">@color/white</item>
<item name="colorControlNormal">?attr/colorPrimary</item>
<item name="colorControlActivated">?attr/colorPrimary</item>
<item name="colorControlHighlight">?attr/colorPrimary</item>
<item name="colorAccent">?attr/colorPrimary</item>
<item name="hintTextAppearance">@style/TaskFormHintTextAppearance</item>
</style>
@ -649,9 +653,9 @@
<item name="boxBackgroundColor">@color/taskform_gray</item>
<item name="android:textColor">?attr/colorPrimaryText</item>
<item name="android:textColorHint">@color/gray_300</item>
<item name="android:colorControlNormal">@color/gray_400</item>
<item name="android:colorControlActivated">@color/brand_400</item>
<item name="android:colorControlHighlight">@color/brand_400</item>
<item name="android:colorControlNormal">?attr/colorPrimary</item>
<item name="android:colorControlActivated">?attr/colorPrimary</item>
<item name="android:colorControlHighlight">?attr/colorPrimary</item>
<item name="android:colorAccent">@color/brand_400</item>
</style>

View file

@ -9,16 +9,14 @@ fun Animal.getTranslatedType(c: Context?): String {
return type
}
var currType: String = when (type) {
"drop" -> c?.getString(R.string.standard).toString()
"quest" -> c?.getString(R.string.quest).toString()
"wacky" -> c?.getString(R.string.wacky).toString()
"special" -> c?.getString(R.string.special).toString()
"premium" -> c?.getString(R.string.magic_potion).toString()
return when (type) {
"drop" -> c.getString(R.string.standard)
"quest" -> c.getString(R.string.quest)
"wacky" -> c.getString(R.string.wacky)
"special" -> c.getString(R.string.special)
"premium" -> c.getString(R.string.magic_potion)
else -> {
type
}
}
return currType
}

View file

@ -118,12 +118,10 @@ class TaskFormActivity : BaseActivity() {
private var tintColor: Int = 0
set(value) {
field = value
upperTextWrapper.setBackgroundColor(value)
taskDifficultyButtons.tintColor = value
habitScoringButtons.tintColor = value
habitResetStreakButtons.tintColor = value
taskSchedulingControls.tintColor = value
supportActionBar?.setBackgroundDrawable(ColorDrawable(value))
updateTagViewsColors()
}
@ -153,12 +151,22 @@ class TaskFormActivity : BaseActivity() {
} else {
"purple"
}
super.onCreate(savedInstanceState)
if (forcedTheme == "yellow") {
taskDifficultyButtons.textTintColor = ContextCompat.getColor(this, R.color.yellow_5)
habitScoringButtons.textTintColor = ContextCompat.getColor(this, R.color.yellow_5)
}
setSupportActionBar(toolbar)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
supportActionBar?.setDisplayShowHomeEnabled(true)
tintColor = getThemeColor(R.attr.taskFormTint)
val upperTintColor = getThemeColor(R.attr.colorAccent)
supportActionBar?.setBackgroundDrawable(ColorDrawable(upperTintColor))
upperTextWrapper.setBackgroundColor(upperTintColor)
isChallengeTask = bundle.getBoolean(IS_CHALLENGE_TASK, false)
@ -172,7 +180,7 @@ class TaskFormActivity : BaseActivity() {
setTagViews()
}, RxErrorHandler.handleEmptyError()))
compositeSubscription.add(userRepository.getUser().subscribe(Consumer {
usesTaskAttributeStats = it.preferences?.allocationMode == "taskbased"
usesTaskAttributeStats = it.preferences?.allocationMode == "taskbased" && it.preferences?.automaticAllocation == true
configureForm()
}, RxErrorHandler.handleEmptyError()))

View file

@ -36,7 +36,7 @@ class MountDetailRecyclerAdapter : androidx.recyclerview.widget.RecyclerView.Ada
override fun onBindViewHolder(holder: androidx.recyclerview.widget.RecyclerView.ViewHolder, position: Int) {
when (val obj = this.itemList[position]) {
is String -> (holder as? SectionViewHolder)?.bind(obj)
is StableSection -> (holder as? SectionViewHolder)?.bind(obj)
is Mount -> (holder as? MountViewHolder)?.bind(obj, ownedMounts?.get(obj.key ?: "")?.owned == true)
}
}

View file

@ -4,6 +4,7 @@ import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.facebook.drawee.view.SimpleDraweeView
import com.habitrpg.android.habitica.R
@ -24,6 +25,7 @@ import io.reactivex.subjects.PublishSubject
class StableRecyclerAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
var shopSpriteSuffix: String? = null
private var eggs: Map<String, Egg> = mapOf()
var animalIngredientsRetriever: ((Animal) -> Pair<Egg?, HatchingPotion?>)? = null
var itemType: String? = null
@ -53,7 +55,14 @@ class StableRecyclerAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
when (val item = this.itemList[position]) {
"header" -> (holder as? StableHeaderViewHolder)?.bind()
is StableSection -> (holder as? SectionViewHolder)?.bind(item)
is StableSection -> {
if (item.key == "drop") {
val params = holder.itemView.layoutParams as GridLayoutManager.LayoutParams
params.topMargin = -30
holder.itemView.layoutParams = params
}
(holder as? SectionViewHolder)?.bind(item)
}
is Animal -> {
val isIndividualAnimal = item.type == "special" || item.type == "wacky"
if (isIndividualAnimal) {
@ -109,11 +118,12 @@ class StableRecyclerAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
notifyDataSetChanged()
}
internal class StableHeaderViewHolder(parent: ViewGroup) : RecyclerView.ViewHolder(parent.inflate(R.layout.shop_header)) {
internal inner class StableHeaderViewHolder(parent: ViewGroup) : RecyclerView.ViewHolder(parent.inflate(R.layout.shop_header)) {
private var binding: ShopHeaderBinding = ShopHeaderBinding.bind(itemView)
fun bind() {
binding.npcBannerView.shopSpriteSuffix = shopSpriteSuffix ?: ""
binding.npcBannerView.identifier = "stable"
binding.namePlate.setText(R.string.stable_owner)
binding.descriptionView.visibility = View.GONE

View file

@ -135,7 +135,8 @@ class MountDetailRecyclerFragment : BaseMainFragment() {
for (mount in unsortedAnimals) {
if (mount.type == "wacky" || mount.type == "special") continue
if (mount.type != lastMount?.type) {
currentSection = StableSection(mount.type, mount.getTranslatedType(context))
val title = context?.getString(R.string.pet_category, mount.getTranslatedType(context))
currentSection = StableSection(mount.type, title ?: "")
items.add(currentSection)
}
currentSection?.let {

View file

@ -24,6 +24,7 @@ import com.habitrpg.android.habitica.ui.helpers.bindView
import com.habitrpg.android.habitica.ui.helpers.resetViews
import io.reactivex.functions.BiFunction
import io.reactivex.functions.Consumer
import io.reactivex.rxkotlin.combineLatest
import io.realm.RealmResults
import org.greenrobot.eventbus.Subscribe
import java.util.ArrayList
@ -140,35 +141,35 @@ class PetDetailRecyclerFragment : BaseMainFragment() {
}
.subscribe(Consumer { adapter.setOwnedMounts(it) }, RxErrorHandler.handleEmptyError()))
compositeSubscription.add(inventoryRepository.getOwnedItems(true).subscribe(Consumer { adapter.setOwnedItems(it) }, RxErrorHandler.handleEmptyError()))
compositeSubscription.add(inventoryRepository.getPets(animalType, animalGroup, animalColor).zipWith(inventoryRepository.getOwnedPets()
compositeSubscription.add(inventoryRepository.getPets(animalType, animalGroup, animalColor).combineLatest(inventoryRepository.getOwnedPets()
.map { ownedPets ->
val petMap = mutableMapOf<String, OwnedPet>()
ownedPets.forEach { petMap[it.key ?: ""] = it }
return@map petMap
}.doOnNext {
adapter.setOwnedPets(it)
}, BiFunction<RealmResults<out Pet>, Map<String, OwnedObject>, List<Any>> { unsortedAnimals, ownedAnimals ->
}).map {
val items = mutableListOf<Any>()
var lastPet: Pet? = null
var currentSection: StableSection? = null
for (pet in unsortedAnimals) {
for (pet in it.first) {
if (pet.type == "wacky" || pet.type == "special") continue
if (pet.type != lastPet?.type) {
currentSection = StableSection(pet.type, pet.getTranslatedType(context))
val title = context?.getString(R.string.pet_category, pet.getTranslatedType(context))
currentSection = StableSection(pet.type, title ?: "")
items.add(currentSection)
}
currentSection?.let {
it.totalCount += 1
if (ownedAnimals.containsKey(pet.key)) {
it.ownedCount += 1
currentSection?.let {section ->
section.totalCount += 1
if (it.second.containsKey(pet.key)) {
section.ownedCount += 1
}
}
items.add(pet)
lastPet = pet
}
items
})
.subscribe(Consumer { adapter.setItemList(it) }, RxErrorHandler.handleEmptyError()))
}.subscribe(Consumer { adapter.setItemList(it) }, RxErrorHandler.handleEmptyError()))
compositeSubscription.add(inventoryRepository.getMounts(animalType, animalGroup, animalColor).subscribe(Consumer<RealmResults<Mount>> { adapter.setExistingMounts(it) }, RxErrorHandler.handleEmptyError()))
}
}

View file

@ -10,6 +10,7 @@ import com.habitrpg.android.habitica.components.UserComponent
import com.habitrpg.android.habitica.data.InventoryRepository
import com.habitrpg.android.habitica.extensions.getTranslatedType
import com.habitrpg.android.habitica.extensions.inflate
import com.habitrpg.android.habitica.helpers.AppConfigManager
import com.habitrpg.android.habitica.helpers.RxErrorHandler
import com.habitrpg.android.habitica.models.inventory.Animal
import com.habitrpg.android.habitica.models.inventory.Egg
@ -31,6 +32,8 @@ class StableRecyclerFragment : BaseFragment() {
@Inject
lateinit var inventoryRepository: InventoryRepository
@Inject
lateinit var configManager: AppConfigManager
private val recyclerView: RecyclerViewEmptySupport? by bindView(R.id.recyclerView)
private val emptyView: TextView? by bindView(R.id.emptyView)
@ -92,6 +95,7 @@ class StableRecyclerFragment : BaseFragment() {
Pair(egg as? Egg, potion as? HatchingPotion)
}
adapter?.itemType = this.itemType
adapter?.shopSpriteSuffix = configManager.shopSpriteSuffix()
recyclerView?.adapter = adapter
recyclerView?.itemAnimator = SafeDefaultItemAnimator()
@ -185,7 +189,12 @@ class StableRecyclerFragment : BaseFragment() {
if (items.size > 0 && items[items.size - 1].javaClass == StableSection::class.java) {
items.removeAt(items.size - 1)
}
val section = StableSection(animal.type, animal.getTranslatedType(context))
val title = if (itemType == "pets") {
context?.getString(R.string.pet_category, animal.getTranslatedType(context))
} else {
context?.getString(R.string.mount_category, animal.getTranslatedType(context))
}
val section = StableSection(animal.type, title ?: "")
items.add(section)
lastSection = section
}

View file

@ -61,7 +61,7 @@ class PetViewHolder(parent: ViewGroup, private val equipEvents: PublishSubject<S
this.hasUnlockedEgg = hasUnlockedEgg
this.hasUnlockedPotion = hasUnlockedPotion
this.hasMount = hasMount
binding.imageView.visibility = View.VISIBLE
binding.imageViewWrapper.visibility = View.VISIBLE
binding.itemWrapper.visibility = View.GONE
binding.checkmarkView.visibility = View.GONE
@ -85,7 +85,7 @@ class PetViewHolder(parent: ViewGroup, private val equipEvents: PublishSubject<S
binding.trainedProgressBar.visibility = View.GONE
binding.imageView.alpha = 0.2f
if (canHatch) {
binding.imageView.visibility = View.GONE
binding.imageViewWrapper.visibility = View.GONE
binding.itemWrapper.visibility = View.VISIBLE
binding.checkmarkView.visibility = View.VISIBLE
itemView.setBackgroundResource(R.drawable.layout_rounded_bg_gray_700_brand_border)

View file

@ -38,6 +38,7 @@ import com.habitrpg.android.habitica.ui.views.insufficientCurrency.InsufficientG
import com.habitrpg.android.habitica.ui.views.insufficientCurrency.InsufficientGoldDialog
import com.habitrpg.android.habitica.ui.views.insufficientCurrency.InsufficientHourglassesDialog
import com.habitrpg.android.habitica.ui.views.insufficientCurrency.InsufficientSubscriberGemsDialog
import com.habitrpg.android.habitica.ui.views.tasks.form.StepperValueFormView
import io.reactivex.Flowable
import io.reactivex.Maybe
import io.reactivex.disposables.CompositeDisposable
@ -100,37 +101,31 @@ class PurchaseDialog(context: Context, component: UserComponent?, val item: Shop
val contentView: PurchaseDialogContent
when {
shopItem.isTypeItem -> {
val itemContent = PurchaseDialogItemContent(context)
if (shopItem.canPurchaseBulk) {
itemContent.stepperView.visibility = View.VISIBLE
itemContent.stepperView.onValueChanged = {
purchaseQuantity = it.toInt()
updatePurchaseTotal()
}
} else {
itemContent.stepperView.visibility = View.GONE
}
contentView = itemContent
}
shopItem.isTypeQuest -> {
shopItem.isTypeItem -> contentView = PurchaseDialogItemContent(context)
shopItem.isTypeQuest -> {
contentView = PurchaseDialogQuestContent(context)
inventoryRepository.getQuestContent(shopItem.key).firstElement().subscribe(Consumer { contentView.setQuestContent(it) }, RxErrorHandler.handleEmptyError())
}
shopItem.isTypeGear -> {
shopItem.isTypeGear -> {
contentView = PurchaseDialogGearContent(context)
inventoryRepository.getEquipment(shopItem.key).firstElement().subscribe(Consumer { contentView.setEquipment(it) }, RxErrorHandler.handleEmptyError())
checkGearClass()
}
"gems" == shopItem.purchaseType -> {
val gemContent = PurchaseDialogGemsContent(context)
gemContent.stepperView.onValueChanged = {
"gems" == shopItem.purchaseType -> contentView = PurchaseDialogGemsContent(context)
else -> contentView = PurchaseDialogBaseContent(context)
}
val stepperView = contentView.findViewById<StepperValueFormView>(R.id.stepper_view)
if (stepperView != null) {
if (shopItem.canPurchaseBulk) {
stepperView.visibility = View.VISIBLE
stepperView.onValueChanged = {
purchaseQuantity = it.toInt()
updatePurchaseTotal()
}
contentView = gemContent
} else {
stepperView.visibility = View.GONE
}
else -> contentView = PurchaseDialogBaseContent(context)
}
amountErrorLabel = contentView.findViewById(R.id.amount_error_label)

View file

@ -29,13 +29,14 @@ class HabitScoringButtonsView @JvmOverloads constructor(
var tintColor: Int = ContextCompat.getColor(context, R.color.brand_300)
var textTintColor: Int? = null
var isPositive = true
set(value) {
field = value
positiveImageView.setImageDrawable(HabiticaIconsHelper.imageOfHabitControlPlus(tintColor, value).asDrawable(resources))
if (value) {
positiveTextView.setTextColor(tintColor)
positiveTextView.setTextColor(textTintColor ?: tintColor)
positiveView.contentDescription = toContentDescription(R.string.positive_habit_form, R.string.on)
positiveTextView.typeface = Typeface.create("sans-serif-medium", Typeface.NORMAL)
} else {
@ -50,7 +51,7 @@ class HabitScoringButtonsView @JvmOverloads constructor(
field = value
negativeImageView.setImageDrawable(HabiticaIconsHelper.imageOfHabitControlMinus(tintColor, value).asDrawable(resources))
if (value) {
negativeTextView.setTextColor(tintColor)
negativeTextView.setTextColor(textTintColor ?: tintColor)
negativeView.contentDescription = toContentDescription(R.string.negative_habit_form, R.string.on)
negativeTextView.typeface = Typeface.create("sans-serif-medium", Typeface.NORMAL)
} else {

View file

@ -21,6 +21,7 @@ class TaskDifficultyButtons @JvmOverloads constructor(
) : LinearLayout(context, attrs, defStyleAttr) {
var tintColor: Int = ContextCompat.getColor(context, R.color.brand_300)
var textTintColor: Int? = null
var selectedDifficulty: Float = 1f
set(value) {
field = value
@ -58,7 +59,7 @@ class TaskDifficultyButtons @JvmOverloads constructor(
var difficultyColor = ContextCompat.getColor(context, R.color.white)
if (isActive) {
view.findViewById<ImageView>(R.id.image_view).background.mutate().setTint(tintColor)
view.findViewById<TextView>(R.id.text_view).setTextColor(tintColor)
view.findViewById<TextView>(R.id.text_view).setTextColor(textTintColor ?: tintColor)
view.findViewById<TextView>(R.id.text_view).typeface = Typeface.create("sans-serif-medium", Typeface.NORMAL)
} else {
view.findViewById<ImageView>(R.id.image_view).background.mutate().setTint(ContextCompat.getColor(context, R.color.taskform_gray))

View file

@ -11,8 +11,8 @@
"type": "SINGLE",
"filters": [],
"properties": [],
"versionCode": 2459,
"versionName": "2459",
"versionCode": 2500,
"versionName": "2500",
"enabled": true,
"outputFile": "Habitica-staff-release.apk"
}