mirror of
https://github.com/sudoxnym/habitica-android.git
synced 2026-05-18 03:39:00 +00:00
Implement new faint screen
This commit is contained in:
parent
6c3585040d
commit
fd4c49ecde
17 changed files with 570 additions and 166 deletions
|
|
@ -71,6 +71,13 @@
|
|||
android:screenOrientation="unspecified"
|
||||
tools:ignore="UnusedAttribute">
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".ui.activities.DeathActivity"
|
||||
android:parentActivityName=".ui.activities.MainActivity"
|
||||
android:label="@string/faint_header"
|
||||
android:screenOrientation="unspecified"
|
||||
tools:ignore="UnusedAttribute">
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".ui.activities.NotificationsActivity"
|
||||
android:parentActivityName=".ui.activities.MainActivity"
|
||||
|
|
|
|||
27
Habitica/res/drawable/ad_button_background_content.xml
Normal file
27
Habitica/res/drawable/ad_button_background_content.xml
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
|
||||
<item>
|
||||
<!-- create gradient you want to use with the angle you want to use -->
|
||||
<shape android:shape="rectangle" >
|
||||
<gradient
|
||||
android:angle="0"
|
||||
android:startColor="@color/green_100"
|
||||
android:endColor="@color/green_500" />
|
||||
<corners android:radius="8dp" />
|
||||
</shape>
|
||||
</item>
|
||||
<item
|
||||
android:bottom="3dp"
|
||||
android:left="3dp"
|
||||
android:right="3dp"
|
||||
android:top="3dp">
|
||||
<shape
|
||||
android:shape="rectangle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<solid android:color="@color/content_background" />
|
||||
<corners android:radius="6dp" />
|
||||
</shape>
|
||||
<ripple android:color="@color/white" />
|
||||
</item>
|
||||
</layer-list>
|
||||
BIN
Habitica/res/drawable/death_ghost.png
Normal file
BIN
Habitica/res/drawable/death_ghost.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.7 KiB |
120
Habitica/res/drawable/ic_broken_heart.xml
Normal file
120
Habitica/res/drawable/ic_broken_heart.xml
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="110dp"
|
||||
android:height="110dp"
|
||||
android:viewportWidth="110"
|
||||
android:viewportHeight="110">
|
||||
<path
|
||||
android:pathData="M76.1,18.83l-12.57,6.83l-4.4,9.32l16.97,-9.21l9.04,5.42l0,22l-13.26,18.69l-16.88,11.75l-16.88,-11.75l-13.26,-18.69l0,-22l9.04,-5.42l14.26,7.74l3.02,-5.3l-17.28,-9.38l-15.07,9.05l0,27.12l15.07,21.1l21.1,15.07l21.1,-15.07l15.07,-21.1l0,-27.12z"
|
||||
android:fillColor="#C92B2B"/>
|
||||
<path
|
||||
android:pathData="M75.8,36.31l0.3,0l0,13.87l-10.85,15.07l-10.25,7.53l-10.25,-7.53l-10.85,-15.07l0,-13.87l0.3,0l8.31,4.46l-8.61,-15l-9.04,5.42l0,22l13.26,18.69l16.88,11.75l16.88,-11.75l13.26,-18.69l0,-22l-9.04,-5.42l-8.61,15z"
|
||||
android:fillColor="#FF6165"/>
|
||||
<path
|
||||
android:pathData="M51.24,45.45l-4.68,-9.14l1.6,-2.8l-14.26,-7.74l8.61,15z"
|
||||
android:fillColor="#FF6165"/>
|
||||
<path
|
||||
android:pathData="M51.24,45.45l-4.68,-9.14l1.6,-2.8l-14.26,-7.74l8.61,15z"
|
||||
android:strokeAlpha="0.5"
|
||||
android:fillColor="#FFFFFF"
|
||||
android:fillAlpha="0.5"/>
|
||||
<path
|
||||
android:pathData="M60.87,44.32l6.62,-3.55l8.61,-15l-16.97,9.21l-1.31,2.78z"
|
||||
android:fillColor="#FF6165"/>
|
||||
<path
|
||||
android:pathData="M60.87,44.32l6.62,-3.55l8.61,-15l-16.97,9.21l-1.31,2.78z"
|
||||
android:strokeAlpha="0.25"
|
||||
android:fillColor="#FFFFFF"
|
||||
android:fillAlpha="0.25"/>
|
||||
<path
|
||||
android:pathData="M55,67.67l-4.22,-7.67l0.46,-4.03l-8.73,-15.2l-8.31,-4.46l-0.3,0l0,13.87l10.85,15.07l10.25,7.53l10.25,-7.53l10.85,-15.07l0,-13.87l-0.3,0l-8.31,4.46l-12.49,21.76z"
|
||||
android:fillColor="#FF6165"/>
|
||||
<path
|
||||
android:pathData="M38.12,71.88l16.88,11.75l0,-10.85l-7.95,-5.84z"
|
||||
android:strokeAlpha="0.35"
|
||||
android:fillColor="#B52428"
|
||||
android:fillAlpha="0.35"/>
|
||||
<path
|
||||
android:pathData="M33.9,36.31l0.3,0l8.31,4.46l-8.61,-15l-9.04,5.42l0,22l14.43,4.48l-5.39,-7.49z"
|
||||
android:strokeAlpha="0.5"
|
||||
android:fillColor="#B52428"
|
||||
android:fillAlpha="0.5"/>
|
||||
<path
|
||||
android:pathData="M42.513,40.774l0,0l8.725,15.206l0,0z"
|
||||
android:strokeAlpha="0.5"
|
||||
android:fillColor="#FFFFFF"
|
||||
android:fillAlpha="0.5"/>
|
||||
<path
|
||||
android:pathData="M51.6,61.48l-12.31,-3.81l5.46,7.58l2.3,1.69l5.79,-3.21z"
|
||||
android:strokeAlpha="0.5"
|
||||
android:fillColor="#FFFFFF"
|
||||
android:fillAlpha="0.5"/>
|
||||
<path
|
||||
android:pathData="M52.84,63.73l-5.79,3.21l7.95,5.84l0,-5.11z"
|
||||
android:strokeAlpha="0.35"
|
||||
android:fillColor="#B52428"
|
||||
android:fillAlpha="0.35"/>
|
||||
<path
|
||||
android:pathData="M52.84,63.73l-5.79,3.21l7.95,5.84l0,-5.11z"
|
||||
android:strokeAlpha="0.5"
|
||||
android:fillColor="#FFFFFF"
|
||||
android:fillAlpha="0.5"/>
|
||||
<path
|
||||
android:pathData="M50.78,60l0.46,-4.03l-8.73,-15.2l-8.31,-4.46l-0.3,0l0,13.87l5.39,7.49l12.31,3.81z"
|
||||
android:strokeAlpha="0.5"
|
||||
android:fillColor="#B52428"
|
||||
android:fillAlpha="0.5"/>
|
||||
<path
|
||||
android:pathData="M50.78,60l0.46,-4.03l-8.73,-15.2l-8.31,-4.46l-0.3,0l0,13.87l5.39,7.49l12.31,3.81z"
|
||||
android:strokeAlpha="0.5"
|
||||
android:fillColor="#FFFFFF"
|
||||
android:fillAlpha="0.5"/>
|
||||
<path
|
||||
android:pathData="M52.21,47.34l-0.97,-1.89l-8.73,-4.68l8.73,15.2z"
|
||||
android:fillColor="#FF6165"/>
|
||||
<path
|
||||
android:pathData="M52.21,47.34l-0.97,-1.89l-8.73,-4.68l8.73,15.2z"
|
||||
android:strokeAlpha="0.5"
|
||||
android:fillColor="#FFFFFF"
|
||||
android:fillAlpha="0.5"/>
|
||||
<path
|
||||
android:pathData="M52.21,47.34l-0.97,-1.89l-8.73,-4.68l8.73,15.2z"
|
||||
android:strokeAlpha="0.5"
|
||||
android:fillColor="#FFFFFF"
|
||||
android:fillAlpha="0.5"/>
|
||||
<path
|
||||
android:pathData="M55,60l0,2.53l12.49,-21.76l-6.62,3.55l0.1,0.2z"
|
||||
android:fillColor="#FF6165"/>
|
||||
<path
|
||||
android:pathData="M55,60l0,2.53l12.49,-21.76l-6.62,3.55l0.1,0.2z"
|
||||
android:strokeAlpha="0.25"
|
||||
android:fillColor="#FFFFFF"
|
||||
android:fillAlpha="0.25"/>
|
||||
<path
|
||||
android:pathData="M55,60l0,2.53l12.49,-21.76l-6.62,3.55l0.1,0.2z"
|
||||
android:strokeAlpha="0.5"
|
||||
android:fillColor="#FFFFFF"
|
||||
android:fillAlpha="0.5"/>
|
||||
<path
|
||||
android:pathData="M55,62.53l16.88,9.35l-16.88,11.75z"
|
||||
android:strokeAlpha="0.5"
|
||||
android:fillColor="#FFFFFF"
|
||||
android:fillType="evenOdd"
|
||||
android:fillAlpha="0.5"/>
|
||||
<path
|
||||
android:pathData="M71.88,71.88l13.26,-18.69l-30.14,9.34z"
|
||||
android:strokeAlpha="0.5"
|
||||
android:fillColor="#B52428"
|
||||
android:fillType="evenOdd"
|
||||
android:fillAlpha="0.5"/>
|
||||
<path
|
||||
android:pathData="M55,62.53l21.1,-36.76l9.04,5.42l0,22z"
|
||||
android:strokeAlpha="0.35"
|
||||
android:fillColor="#B52428"
|
||||
android:fillType="evenOdd"
|
||||
android:fillAlpha="0.35"/>
|
||||
<path
|
||||
android:pathData="M75.8,36.31l-8.31,4.46l-12.49,21.76l0,5.14l0,5.11l10.25,-7.53l10.85,-15.07l0,-13.87z"
|
||||
android:strokeAlpha="0.5"
|
||||
android:fillColor="#FFFFFF"
|
||||
android:fillAlpha="0.5"/>
|
||||
</vector>
|
||||
84
Habitica/res/layout/activity_death.xml
Normal file
84
Habitica/res/layout/activity_death.xml
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:background="@color/content_background"
|
||||
android:orientation="vertical"
|
||||
android:gravity="center_horizontal"
|
||||
android:paddingHorizontal="23dp">
|
||||
<androidx.legacy.widget.Space
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1" />
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="157dp">
|
||||
<ImageView
|
||||
android:id="@+id/ghost_view"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@drawable/death_ghost"
|
||||
android:layout_centerHorizontal="true" />
|
||||
<ImageView
|
||||
android:layout_width="110dp"
|
||||
android:layout_height="110dp"
|
||||
android:src="@drawable/ic_broken_heart"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_alignParentBottom="true"/>
|
||||
</RelativeLayout>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/Title2"
|
||||
android:textStyle="bold"
|
||||
android:text="@string/you_ran_out_of_health"
|
||||
android:layout_marginHorizontal="@dimen/spacing_xlarge"
|
||||
android:gravity="center"/>
|
||||
<TextView
|
||||
android:id="@+id/loss_description"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="@dimen/spacing_xlarge"
|
||||
android:layout_marginVertical="@dimen/spacing_medium"
|
||||
android:textColor="@color/text_primary"
|
||||
android:textSize="20sp"
|
||||
android:lineSpacingExtra="4dp"
|
||||
android:gravity="center" />
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/death_description"
|
||||
android:textSize="20sp"
|
||||
android:lineSpacingExtra="4dp"
|
||||
android:textColor="@color/text_secondary"
|
||||
android:layout_marginHorizontal="@dimen/spacing_xlarge"
|
||||
android:gravity="center"/>
|
||||
<androidx.legacy.widget.Space
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1" />
|
||||
<Button
|
||||
android:id="@+id/restart_button"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="69dp"
|
||||
android:text="@string/faint_button"
|
||||
android:textStyle="bold"
|
||||
style="@style/HabiticaButton.Maroon"
|
||||
android:layout_marginBottom="6dp"/>
|
||||
<com.habitrpg.android.habitica.ui.views.ads.AdButton
|
||||
android:id="@+id/ad_button"
|
||||
android:layout_width="match_parent"
|
||||
app:text="@string/watch_ad_to_open"
|
||||
app:activeBackground="@drawable/ad_button_background_content"
|
||||
android:layout_height="60dp"
|
||||
app:textColor="@color/text_primary"/>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:textColor="@color/text_quad"
|
||||
android:text="@string/faint_broken_equipment"
|
||||
android:layout_margin="@dimen/spacing_large"/>
|
||||
</LinearLayout>
|
||||
|
|
@ -82,6 +82,7 @@
|
|||
style="@style/HabitButton"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@drawable/selection_highlight"
|
||||
android:contentDescription="@string/negative_habit_form" />
|
||||
</FrameLayout>
|
||||
</LinearLayout>
|
||||
|
|
|
|||
|
|
@ -164,6 +164,11 @@
|
|||
android:name="value"
|
||||
app:argType="string" />
|
||||
</activity>
|
||||
<activity
|
||||
android:id="@+id/deathActivity"
|
||||
android:name="com.habitrpg.android.habitica.ui.activities.DeathActivity"
|
||||
android:label="@string/faint_header" >
|
||||
</activity>
|
||||
<activity
|
||||
android:id="@+id/subscriptionPurchaseActivity"
|
||||
android:name="com.habitrpg.android.habitica.ui.activities.GemPurchaseActivity"
|
||||
|
|
|
|||
|
|
@ -160,6 +160,8 @@
|
|||
<declare-styleable name="AdButton">
|
||||
<attr name="text" />
|
||||
<attr name="currency" />
|
||||
<attr name="activeBackground" format="integer" />
|
||||
<attr name="textColor" format="color" />
|
||||
</declare-styleable>
|
||||
<declare-styleable name="SparkView">
|
||||
<attr name="color" />
|
||||
|
|
|
|||
|
|
@ -1256,7 +1256,7 @@
|
|||
<string name="oldest">Oldest</string>
|
||||
<string name="sort_by">Sort By</string>
|
||||
<string name="january">January</string>
|
||||
<string name="febuary">Febuary</string>
|
||||
<string name="febuary">February</string>
|
||||
<string name="march">March</string>
|
||||
<string name="april">April</string>
|
||||
<string name="may">May</string>
|
||||
|
|
@ -1270,4 +1270,8 @@
|
|||
<string name="cds_subtitle">Adjust when your day switches over past the default time of midnight.</string>
|
||||
<string name="buy_set">Buy Set</string>
|
||||
<string name="tutorial_reset_confirmation">Your Tutorials were reset</string>
|
||||
<string name="you_ran_out_of_health">You ran out of Health!</string>
|
||||
<string name="death_description">But you can get them all back with hard work! Good luck—you’ll do great.</string>
|
||||
<string name="faint_broken_equipment">Broken equipment can be repurchased from Rewards</string>
|
||||
<string name="faint_loss_description"><![CDATA[You’ll drop to level <b>%d</b>, lose <b>%d</b> Gold, and break <b>a piece of gear</b>…]]></string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -692,6 +692,14 @@
|
|||
<item name="android:backgroundTint">@color/red_100</item>
|
||||
</style>
|
||||
|
||||
<style name="HabiticaButton.Maroon" parent="HabiticaButton">
|
||||
<item name="android:backgroundTint">@color/maroon_100</item>
|
||||
</style>
|
||||
|
||||
<style name="HabiticaButton.Maroon.Small" parent="HabiticaButton.Small">
|
||||
<item name="android:backgroundTint">@color/maroon_100</item>
|
||||
</style>
|
||||
|
||||
<style name="SegmentTitle" parent="Headline">
|
||||
<item name="android:layout_marginBottom">@dimen/spacing_medium</item>
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import com.habitrpg.android.habitica.ui.activities.AdventureGuideActivity;
|
|||
import com.habitrpg.android.habitica.ui.activities.ArmoireActivity;
|
||||
import com.habitrpg.android.habitica.ui.activities.ChallengeFormActivity;
|
||||
import com.habitrpg.android.habitica.ui.activities.ClassSelectionActivity;
|
||||
import com.habitrpg.android.habitica.ui.activities.DeathActivity;
|
||||
import com.habitrpg.android.habitica.ui.activities.FixCharacterValuesActivity;
|
||||
import com.habitrpg.android.habitica.ui.activities.FullProfileActivity;
|
||||
import com.habitrpg.android.habitica.ui.activities.GemPurchaseActivity;
|
||||
|
|
@ -105,6 +106,7 @@ import com.habitrpg.android.habitica.ui.viewmodels.InboxViewModel;
|
|||
import com.habitrpg.android.habitica.ui.viewmodels.MainActivityViewModel;
|
||||
import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel;
|
||||
import com.habitrpg.android.habitica.ui.viewmodels.NotificationsViewModel;
|
||||
import com.habitrpg.android.habitica.ui.viewmodels.StableViewModel;
|
||||
import com.habitrpg.android.habitica.ui.viewmodels.TasksViewModel;
|
||||
import com.habitrpg.android.habitica.ui.viewmodels.inventory.equipment.EquipmentOverviewViewModel;
|
||||
import com.habitrpg.android.habitica.ui.views.dialogs.PetSuggestHatchDialog;
|
||||
|
|
@ -361,4 +363,8 @@ public interface UserComponent {
|
|||
void inject(@NotNull ArmoireActivity armoireActivity);
|
||||
|
||||
void inject(@NotNull TasksViewModel tasksViewModel);
|
||||
|
||||
void inject(@NotNull StableViewModel stableViewModel);
|
||||
|
||||
void inject(@NotNull DeathActivity deathActivity);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,86 @@
|
|||
package com.habitrpg.android.habitica.ui.activities
|
||||
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.components.UserComponent
|
||||
import com.habitrpg.android.habitica.data.InventoryRepository
|
||||
import com.habitrpg.android.habitica.databinding.ActivityDeathBinding
|
||||
import com.habitrpg.android.habitica.extensions.fromHtml
|
||||
import com.habitrpg.android.habitica.extensions.observeOnce
|
||||
import com.habitrpg.android.habitica.helpers.AdHandler
|
||||
import com.habitrpg.android.habitica.helpers.AdType
|
||||
import com.habitrpg.android.habitica.helpers.Animations
|
||||
import com.habitrpg.android.habitica.helpers.AppConfigManager
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel
|
||||
import com.habitrpg.android.habitica.ui.views.ads.AdButton
|
||||
import javax.inject.Inject
|
||||
|
||||
class DeathActivity: BaseActivity() {
|
||||
private lateinit var binding: ActivityDeathBinding
|
||||
|
||||
@Inject
|
||||
internal lateinit var inventoryRepository: InventoryRepository
|
||||
@Inject
|
||||
internal lateinit var appConfigManager: AppConfigManager
|
||||
@Inject
|
||||
lateinit var userViewModel: MainUserViewModel
|
||||
|
||||
override fun getLayoutResId(): Int = R.layout.activity_armoire
|
||||
|
||||
override fun injectActivity(component: UserComponent?) {
|
||||
component?.inject(this)
|
||||
}
|
||||
|
||||
override fun getContentView(): View {
|
||||
binding = ActivityDeathBinding.inflate(layoutInflater)
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
binding.ghostView.startAnimation(Animations.bobbingAnimation())
|
||||
|
||||
userViewModel.user.observeOnce(this) { user ->
|
||||
binding.lossDescription.text = getString(R.string.faint_loss_description, (user?.stats?.lvl ?: 2).toInt() - 1, user?.stats?.gp?.toInt()).fromHtml()
|
||||
}
|
||||
|
||||
if (appConfigManager.enableArmoireAds()) {
|
||||
val handler = AdHandler(this, AdType.FAINT) {
|
||||
if (!it) {
|
||||
return@AdHandler
|
||||
}
|
||||
Log.d("AdHandler", "Reviving user")
|
||||
compositeSubscription.add(
|
||||
userRepository.updateUser("stats.hp", 1).subscribe({
|
||||
finish()
|
||||
}, RxErrorHandler.handleEmptyError())
|
||||
)
|
||||
}
|
||||
handler.prepare {
|
||||
if (it && binding.adButton.state == AdButton.State.LOADING) {
|
||||
binding.adButton.state = AdButton.State.READY
|
||||
} else if (!it) {
|
||||
binding.adButton.visibility = View.INVISIBLE
|
||||
}
|
||||
}
|
||||
binding.adButton.updateForAdType(AdType.ARMOIRE, lifecycleScope)
|
||||
binding.adButton.setOnClickListener {
|
||||
binding.adButton.state = AdButton.State.LOADING
|
||||
handler.show()
|
||||
}
|
||||
} else {
|
||||
binding.adButton.visibility = View.GONE
|
||||
}
|
||||
|
||||
binding.restartButton.setOnClickListener {
|
||||
binding.restartButton.isEnabled = false
|
||||
userRepository.revive().subscribe({
|
||||
finish()
|
||||
}, RxErrorHandler.handleEmptyError())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -9,7 +9,6 @@ import android.content.pm.PackageManager
|
|||
import android.content.res.Configuration
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.KeyEvent
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
|
|
@ -30,7 +29,6 @@ import com.habitrpg.android.habitica.data.InventoryRepository
|
|||
import com.habitrpg.android.habitica.data.TaskRepository
|
||||
import com.habitrpg.android.habitica.data.local.UserQuestStatus
|
||||
import com.habitrpg.android.habitica.databinding.ActivityMainBinding
|
||||
import com.habitrpg.android.habitica.databinding.DialogFaintBinding
|
||||
import com.habitrpg.android.habitica.extensions.dpToPx
|
||||
import com.habitrpg.android.habitica.extensions.getThemeColor
|
||||
import com.habitrpg.android.habitica.extensions.hideKeyboard
|
||||
|
|
@ -38,8 +36,6 @@ import com.habitrpg.android.habitica.extensions.isUsingNightModeResources
|
|||
import com.habitrpg.android.habitica.extensions.observeOnce
|
||||
import com.habitrpg.android.habitica.extensions.subscribeWithErrorHandler
|
||||
import com.habitrpg.android.habitica.extensions.updateStatusBarColor
|
||||
import com.habitrpg.android.habitica.helpers.AdHandler
|
||||
import com.habitrpg.android.habitica.helpers.AdType
|
||||
import com.habitrpg.android.habitica.helpers.AmplitudeManager
|
||||
import com.habitrpg.android.habitica.helpers.AppConfigManager
|
||||
import com.habitrpg.android.habitica.helpers.MainNavigationController
|
||||
|
|
@ -59,22 +55,20 @@ import com.habitrpg.android.habitica.ui.TutorialView
|
|||
import com.habitrpg.android.habitica.ui.fragments.NavigationDrawerFragment
|
||||
import com.habitrpg.android.habitica.ui.viewmodels.MainActivityViewModel
|
||||
import com.habitrpg.android.habitica.ui.viewmodels.NotificationsViewModel
|
||||
import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper
|
||||
import com.habitrpg.android.habitica.ui.views.SnackbarActivity
|
||||
import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaAlertDialog
|
||||
import com.habitrpg.android.habitica.ui.views.dialogs.QuestCompletedDialog
|
||||
import com.habitrpg.android.habitica.ui.views.yesterdailies.YesterdailyDialog
|
||||
import com.habitrpg.android.habitica.widget.AvatarStatsWidgetProvider
|
||||
import com.habitrpg.android.habitica.widget.DailiesWidgetProvider
|
||||
import com.habitrpg.android.habitica.widget.HabitButtonWidgetProvider
|
||||
import com.habitrpg.android.habitica.widget.TodoListWidgetProvider
|
||||
import javax.inject.Inject
|
||||
import kotlin.time.DurationUnit
|
||||
import kotlin.time.toDuration
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
import kotlin.time.DurationUnit
|
||||
import kotlin.time.toDuration
|
||||
|
||||
open class MainActivity : BaseActivity(), SnackbarActivity {
|
||||
private var launchScreen: String? = null
|
||||
|
|
@ -104,7 +98,6 @@ open class MainActivity : BaseActivity(), SnackbarActivity {
|
|||
private var avatarInHeader: AvatarWithBarsViewModel? = null
|
||||
val notificationsViewModel: NotificationsViewModel by viewModels()
|
||||
val viewModel: MainActivityViewModel by viewModels()
|
||||
private var faintDialog: HabiticaAlertDialog? = null
|
||||
private var sideAvatarView: AvatarView? = null
|
||||
private var drawerFragment: NavigationDrawerFragment? = null
|
||||
var drawerToggle: ActionBarDrawerToggle? = null
|
||||
|
|
@ -456,36 +449,8 @@ open class MainActivity : BaseActivity(), SnackbarActivity {
|
|||
return
|
||||
}
|
||||
|
||||
if (this.faintDialog == null && !this.isFinishing) {
|
||||
|
||||
val binding = DialogFaintBinding.inflate(this.layoutInflater)
|
||||
binding.hpBar.setLightBackground(true)
|
||||
binding.hpBar.setIcon(HabiticaIconsHelper.imageOfHeartLightBg())
|
||||
viewModel.user.value?.let { binding.avatarView.setAvatar(it) }
|
||||
|
||||
this.faintDialog = HabiticaAlertDialog(this)
|
||||
faintDialog?.setTitle(R.string.faint_header)
|
||||
faintDialog?.setAdditionalContentView(binding.root)
|
||||
faintDialog?.addButton(R.string.faint_button, true) { _, _ ->
|
||||
faintDialog = null
|
||||
userRepository.revive().subscribe({ }, RxErrorHandler.handleEmptyError())
|
||||
}
|
||||
if (AdHandler.isAllowed(AdType.FAINT)) {
|
||||
val handler = AdHandler(this, AdType.FAINT) {
|
||||
Log.d("AdHandler", "Reviving user")
|
||||
compositeSubscription.add(
|
||||
userRepository.updateUser("stats.hp", 50)
|
||||
.subscribe({}, RxErrorHandler.handleEmptyError())
|
||||
)
|
||||
}
|
||||
handler.prepare()
|
||||
faintDialog?.addButton(R.string.watch_ad_to_revive, true) { _, _ ->
|
||||
faintDialog = null
|
||||
handler.show()
|
||||
}
|
||||
}
|
||||
soundManager.loadAndPlayAudio(SoundManager.SoundDeath)
|
||||
this.faintDialog?.enqueue()
|
||||
if (!this.isFinishing) {
|
||||
MainNavigationController.navigate(R.id.deathActivity)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,17 +4,21 @@ import android.os.Bundle
|
|||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.viewpager2.adapter.FragmentStateAdapter
|
||||
import com.google.android.material.tabs.TabLayoutMediator
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.components.UserComponent
|
||||
import com.habitrpg.android.habitica.databinding.FragmentViewpagerBinding
|
||||
import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment
|
||||
import com.habitrpg.android.habitica.ui.viewmodels.StableViewModel
|
||||
|
||||
class StableFragment : BaseMainFragment<FragmentViewpagerBinding>() {
|
||||
|
||||
override var binding: FragmentViewpagerBinding? = null
|
||||
|
||||
private val viewModel: StableViewModel by viewModels()
|
||||
|
||||
override fun createBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentViewpagerBinding {
|
||||
return FragmentViewpagerBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,40 +1,40 @@
|
|||
package com.habitrpg.android.habitica.ui.fragments.inventory.stable
|
||||
|
||||
import android.app.Application
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.components.UserComponent
|
||||
import com.habitrpg.android.habitica.data.InventoryRepository
|
||||
import com.habitrpg.android.habitica.data.UserRepository
|
||||
import com.habitrpg.android.habitica.databinding.FragmentRefreshRecyclerviewBinding
|
||||
import com.habitrpg.android.habitica.extensions.getTranslatedType
|
||||
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
|
||||
import com.habitrpg.android.habitica.models.inventory.HatchingPotion
|
||||
import com.habitrpg.android.habitica.models.inventory.StableSection
|
||||
import com.habitrpg.android.habitica.models.user.OwnedMount
|
||||
import com.habitrpg.android.habitica.models.user.OwnedObject
|
||||
import com.habitrpg.android.habitica.models.user.OwnedPet
|
||||
import com.habitrpg.android.habitica.ui.adapter.inventory.StableRecyclerAdapter
|
||||
import com.habitrpg.android.habitica.ui.fragments.BaseFragment
|
||||
import com.habitrpg.android.habitica.ui.helpers.EmptyItem
|
||||
import com.habitrpg.android.habitica.ui.helpers.MarginDecoration
|
||||
import com.habitrpg.android.habitica.ui.helpers.SafeDefaultItemAnimator
|
||||
import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel
|
||||
import io.reactivex.rxjava3.core.Flowable
|
||||
import com.habitrpg.android.habitica.ui.viewmodels.StableViewModel
|
||||
import com.habitrpg.android.habitica.ui.viewmodels.StableViewModelFactory
|
||||
import io.reactivex.rxjava3.core.Maybe
|
||||
import io.reactivex.rxjava3.kotlin.combineLatest
|
||||
import javax.inject.Inject
|
||||
|
||||
class StableRecyclerFragment :
|
||||
BaseFragment<FragmentRefreshRecyclerviewBinding>(),
|
||||
SwipeRefreshLayout.OnRefreshListener {
|
||||
|
||||
private val viewModel: StableViewModel by viewModels(factoryProducer = {
|
||||
StableViewModelFactory(context?.applicationContext as? Application, itemType)
|
||||
})
|
||||
|
||||
@Inject
|
||||
lateinit var inventoryRepository: InventoryRepository
|
||||
@Inject
|
||||
|
|
@ -106,11 +106,10 @@ class StableRecyclerFragment :
|
|||
adapter?.animalIngredientsRetriever = { animal, callback ->
|
||||
Maybe.zip(
|
||||
inventoryRepository.getItems(Egg::class.java, arrayOf(animal.animal)).firstElement(),
|
||||
inventoryRepository.getItems(HatchingPotion::class.java, arrayOf(animal.color)).firstElement(),
|
||||
{ eggs, potions ->
|
||||
Pair(eggs.first() as? Egg, potions.first() as? HatchingPotion)
|
||||
}
|
||||
).subscribe(
|
||||
inventoryRepository.getItems(HatchingPotion::class.java, arrayOf(animal.color)).firstElement()
|
||||
) { eggs, potions ->
|
||||
Pair(eggs.first() as? Egg, potions.first() as? HatchingPotion)
|
||||
}.subscribe(
|
||||
{
|
||||
callback(it)
|
||||
},
|
||||
|
|
@ -159,118 +158,24 @@ class StableRecyclerFragment :
|
|||
}
|
||||
|
||||
private fun loadItems() {
|
||||
val observable: Maybe<out List<Animal>> = if ("pets" == itemType) {
|
||||
inventoryRepository.getPets().firstElement()
|
||||
} else {
|
||||
inventoryRepository.getMounts().firstElement()
|
||||
viewModel.items.observe(viewLifecycleOwner) {
|
||||
adapter?.setItemList(it)
|
||||
}
|
||||
val ownedObservable: Flowable<out Map<String, OwnedObject>> = if ("pets" == itemType) {
|
||||
inventoryRepository.getOwnedPets()
|
||||
} else {
|
||||
inventoryRepository.getOwnedMounts()
|
||||
}.map {
|
||||
val animalMap = mutableMapOf<String, OwnedObject>()
|
||||
it.forEach { animal ->
|
||||
val castedAnimal = animal as? OwnedObject ?: return@forEach
|
||||
animalMap[castedAnimal.key ?: ""] = castedAnimal
|
||||
}
|
||||
animalMap
|
||||
viewModel.eggs.observe(viewLifecycleOwner) {
|
||||
adapter?.setEggs(it)
|
||||
}
|
||||
viewModel.ownedItems.observe(viewLifecycleOwner) {
|
||||
adapter?.setOwnedItems(it)
|
||||
}
|
||||
viewModel.mounts.observe(viewLifecycleOwner) {
|
||||
adapter?.setExistingMounts(it)
|
||||
}
|
||||
viewModel.ownedMounts.observe(viewLifecycleOwner) {
|
||||
adapter?.setOwnedMounts(it)
|
||||
}
|
||||
|
||||
compositeSubscription.add(
|
||||
inventoryRepository.getItems(Egg::class.java)
|
||||
.map {
|
||||
val eggMap = mutableMapOf<String, Egg>()
|
||||
it.forEach { egg ->
|
||||
eggMap[egg.key] = egg as Egg
|
||||
}
|
||||
eggMap
|
||||
}
|
||||
.subscribe(
|
||||
{
|
||||
adapter?.setEggs(it)
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
)
|
||||
)
|
||||
compositeSubscription.add(
|
||||
ownedObservable.combineLatest(observable.toFlowable())
|
||||
.map { (ownedAnimals, unsortedAnimals) ->
|
||||
mapAnimals(unsortedAnimals, ownedAnimals)
|
||||
}
|
||||
.subscribe({ items -> adapter?.setItemList(items) }, RxErrorHandler.handleEmptyError())
|
||||
)
|
||||
compositeSubscription.add(inventoryRepository.getOwnedItems(true).subscribe({ adapter?.setOwnedItems(it) }, RxErrorHandler.handleEmptyError()))
|
||||
compositeSubscription.add(inventoryRepository.getMounts().subscribe({ adapter?.setExistingMounts(it) }, RxErrorHandler.handleEmptyError()))
|
||||
compositeSubscription.add(
|
||||
inventoryRepository.getOwnedMounts()
|
||||
.map { ownedMounts ->
|
||||
val mountMap = mutableMapOf<String, OwnedMount>()
|
||||
ownedMounts.forEach { mountMap[it.key ?: ""] = it }
|
||||
return@map mountMap
|
||||
}
|
||||
.subscribe({ adapter?.setOwnedMounts(it) }, RxErrorHandler.handleEmptyError())
|
||||
)
|
||||
}
|
||||
|
||||
private fun mapAnimals(unsortedAnimals: List<Animal>, ownedAnimals: Map<String, OwnedObject>): ArrayList<Any> {
|
||||
val items = ArrayList<Any>()
|
||||
var lastAnimal: Animal = unsortedAnimals.firstOrNull() ?: return items
|
||||
var lastSection: StableSection? = null
|
||||
for (animal in unsortedAnimals) {
|
||||
val identifier = if (animal.animal.isNotEmpty() && (animal.type != "special" && animal.type != "wacky")) animal.animal else animal.key
|
||||
val lastIdentifier = if (lastAnimal.animal.isNotEmpty()) lastAnimal.animal else lastAnimal.key
|
||||
if (animal.type == "premium") {
|
||||
if (!items.contains(lastAnimal)) {
|
||||
items.add(lastAnimal)
|
||||
}
|
||||
lastAnimal = items.first { (it as? Animal)?.animal == animal.animal } as Animal
|
||||
} else if (identifier != lastIdentifier || animal === unsortedAnimals[unsortedAnimals.size - 1]) {
|
||||
if (!((lastAnimal.type == "special") && lastAnimal.numberOwned == 0) && !items.contains(lastAnimal)) {
|
||||
items.add(lastAnimal)
|
||||
}
|
||||
lastAnimal = animal
|
||||
}
|
||||
|
||||
if (animal.type != lastSection?.key && animal.type != "premium") {
|
||||
if (items.size > 0 && items[items.size - 1].javaClass == StableSection::class.java) {
|
||||
items.removeAt(items.size - 1)
|
||||
}
|
||||
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
|
||||
}
|
||||
val isOwned = when (itemType) {
|
||||
"pets" -> {
|
||||
val ownedPet = ownedAnimals[animal.key] as? OwnedPet
|
||||
ownedPet?.trained ?: 0 > 0
|
||||
}
|
||||
"mounts" -> {
|
||||
val ownedMount = ownedAnimals[animal.key] as? OwnedMount
|
||||
ownedMount?.owned == true
|
||||
}
|
||||
else -> false
|
||||
}
|
||||
lastAnimal.totalNumber += 1
|
||||
lastSection?.totalCount = (lastSection?.totalCount ?: 0) + 1
|
||||
if (isOwned) {
|
||||
lastAnimal.numberOwned += 1
|
||||
lastSection?.ownedCount = (lastSection?.ownedCount ?: 0) + 1
|
||||
}
|
||||
}
|
||||
if (!((lastAnimal.type == "premium" || lastAnimal.type == "special") && lastAnimal.numberOwned == 0)) {
|
||||
items.add(lastAnimal)
|
||||
}
|
||||
|
||||
items.add(0, "header")
|
||||
items.removeAll { it is StableSection && (it.key as? String) == "special" && it.ownedCount == 0 }
|
||||
return items
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val ITEM_TYPE_KEY = "CLASS_TYPE_KEY"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,173 @@
|
|||
package com.habitrpg.android.habitica.ui.viewmodels
|
||||
|
||||
import android.app.Application
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.components.UserComponent
|
||||
import com.habitrpg.android.habitica.data.InventoryRepository
|
||||
import com.habitrpg.android.habitica.extensions.getTranslatedType
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.models.inventory.Animal
|
||||
import com.habitrpg.android.habitica.models.inventory.Egg
|
||||
import com.habitrpg.android.habitica.models.inventory.Mount
|
||||
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.OwnedObject
|
||||
import com.habitrpg.android.habitica.models.user.OwnedPet
|
||||
import io.reactivex.rxjava3.core.Flowable
|
||||
import io.reactivex.rxjava3.core.Maybe
|
||||
import io.reactivex.rxjava3.kotlin.combineLatest
|
||||
import javax.inject.Inject
|
||||
|
||||
class StableViewModel(private val application: Application?, private val itemType: String?): BaseViewModel() {
|
||||
|
||||
@Inject
|
||||
lateinit var inventoryRepository: InventoryRepository
|
||||
|
||||
override fun inject(component: UserComponent) {
|
||||
component.inject(this)
|
||||
}
|
||||
|
||||
init {
|
||||
loadItems()
|
||||
}
|
||||
|
||||
private val _items: MutableLiveData<List<Any>> = MutableLiveData()
|
||||
val items: LiveData<List<Any>> = _items
|
||||
private val _eggs: MutableLiveData<Map<String, Egg>> = MutableLiveData()
|
||||
val eggs: LiveData<Map<String, Egg>> = _eggs
|
||||
private val _ownedItems: MutableLiveData<Map<String, OwnedItem>> = MutableLiveData()
|
||||
val ownedItems: LiveData<Map<String, OwnedItem>> = _ownedItems
|
||||
private val _mounts: MutableLiveData<List<Mount>> = MutableLiveData()
|
||||
val mounts: LiveData<List<Mount>> = _mounts
|
||||
private val _ownedMounts: MutableLiveData<Map<String, OwnedMount>> = MutableLiveData()
|
||||
val ownedMounts: LiveData<Map<String, OwnedMount>> = _ownedMounts
|
||||
|
||||
private fun loadItems() {
|
||||
val observable: Maybe<out List<Animal>> = if ("pets" == itemType) {
|
||||
inventoryRepository.getPets().firstElement()
|
||||
} else {
|
||||
inventoryRepository.getMounts().firstElement()
|
||||
}
|
||||
val ownedObservable: Flowable<out Map<String, OwnedObject>> = if ("pets" == itemType) {
|
||||
inventoryRepository.getOwnedPets()
|
||||
} else {
|
||||
inventoryRepository.getOwnedMounts()
|
||||
}.map {
|
||||
val animalMap = mutableMapOf<String, OwnedObject>()
|
||||
it.forEach { animal ->
|
||||
val castedAnimal = animal as? OwnedObject ?: return@forEach
|
||||
animalMap[castedAnimal.key ?: ""] = castedAnimal
|
||||
}
|
||||
animalMap
|
||||
}
|
||||
|
||||
disposable.add(
|
||||
inventoryRepository.getItems(Egg::class.java)
|
||||
.map {
|
||||
val eggMap = mutableMapOf<String, Egg>()
|
||||
it.forEach { egg ->
|
||||
eggMap[egg.key] = egg as Egg
|
||||
}
|
||||
eggMap
|
||||
}
|
||||
.subscribe(
|
||||
{
|
||||
_eggs.value = it
|
||||
},
|
||||
RxErrorHandler.handleEmptyError()
|
||||
)
|
||||
)
|
||||
disposable.add(
|
||||
ownedObservable.combineLatest(observable.toFlowable())
|
||||
.map { (ownedAnimals, unsortedAnimals) ->
|
||||
mapAnimals(unsortedAnimals, ownedAnimals)
|
||||
}
|
||||
.subscribe({ _items.value = it }, RxErrorHandler.handleEmptyError())
|
||||
)
|
||||
disposable.add(inventoryRepository.getOwnedItems(true).subscribe({ _ownedItems.value = it }, RxErrorHandler.handleEmptyError()))
|
||||
disposable.add(inventoryRepository.getMounts().subscribe({ _mounts.value = it }, RxErrorHandler.handleEmptyError()))
|
||||
disposable.add(
|
||||
inventoryRepository.getOwnedMounts()
|
||||
.map { ownedMounts ->
|
||||
val mountMap = mutableMapOf<String, OwnedMount>()
|
||||
ownedMounts.forEach { mountMap[it.key ?: ""] = it }
|
||||
return@map mountMap
|
||||
}
|
||||
.subscribe({ _ownedMounts.value = it }, RxErrorHandler.handleEmptyError())
|
||||
)
|
||||
}
|
||||
|
||||
private fun mapAnimals(unsortedAnimals: List<Animal>, ownedAnimals: Map<String, OwnedObject>): ArrayList<Any> {
|
||||
val items = ArrayList<Any>()
|
||||
var lastAnimal: Animal = unsortedAnimals.firstOrNull() ?: return items
|
||||
var lastSection: StableSection? = null
|
||||
for (animal in unsortedAnimals) {
|
||||
val identifier = if (animal.animal.isNotEmpty() && (animal.type != "special" && animal.type != "wacky")) animal.animal else animal.key
|
||||
val lastIdentifier = if (lastAnimal.animal.isNotEmpty()) lastAnimal.animal else lastAnimal.key
|
||||
if (animal.type == "premium") {
|
||||
if (!items.contains(lastAnimal)) {
|
||||
items.add(lastAnimal)
|
||||
}
|
||||
lastAnimal = items.first { (it as? Animal)?.animal == animal.animal } as Animal
|
||||
} else if (identifier != lastIdentifier || animal === unsortedAnimals[unsortedAnimals.size - 1]) {
|
||||
if (!((lastAnimal.type == "special") && lastAnimal.numberOwned == 0) && !items.contains(lastAnimal)) {
|
||||
items.add(lastAnimal)
|
||||
}
|
||||
lastAnimal = animal
|
||||
}
|
||||
|
||||
if (animal.type != lastSection?.key && animal.type != "premium") {
|
||||
if (items.size > 0 && items[items.size - 1].javaClass == StableSection::class.java) {
|
||||
items.removeAt(items.size - 1)
|
||||
}
|
||||
val title = if (itemType == "pets") {
|
||||
application?.getString(R.string.pet_category, animal.getTranslatedType(application))
|
||||
} else {
|
||||
application?.getString(R.string.mount_category, animal.getTranslatedType(application))
|
||||
}
|
||||
val section = StableSection(animal.type, title ?: "")
|
||||
items.add(section)
|
||||
lastSection = section
|
||||
}
|
||||
val isOwned = when (itemType) {
|
||||
"pets" -> {
|
||||
val ownedPet = ownedAnimals[animal.key] as? OwnedPet
|
||||
ownedPet?.trained ?: 0 > 0
|
||||
}
|
||||
"mounts" -> {
|
||||
val ownedMount = ownedAnimals[animal.key] as? OwnedMount
|
||||
ownedMount?.owned == true
|
||||
}
|
||||
else -> false
|
||||
}
|
||||
lastAnimal.totalNumber += 1
|
||||
lastSection?.totalCount = (lastSection?.totalCount ?: 0) + 1
|
||||
if (isOwned) {
|
||||
lastAnimal.numberOwned += 1
|
||||
lastSection?.ownedCount = (lastSection?.ownedCount ?: 0) + 1
|
||||
}
|
||||
}
|
||||
if (!((lastAnimal.type == "premium" || lastAnimal.type == "special") && lastAnimal.numberOwned == 0)) {
|
||||
items.add(lastAnimal)
|
||||
}
|
||||
|
||||
items.add(0, "header")
|
||||
items.removeAll { it is StableSection && (it.key as? String) == "special" && it.ownedCount == 0 }
|
||||
return items
|
||||
}
|
||||
}
|
||||
|
||||
class StableViewModelFactory(
|
||||
private val application: Application?,
|
||||
private val itemType: String?
|
||||
) : ViewModelProvider.Factory {
|
||||
|
||||
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
||||
return StableViewModel(application, itemType) as T
|
||||
}
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@ package com.habitrpg.android.habitica.ui.views.ads
|
|||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.view.Gravity
|
||||
import android.view.View
|
||||
import android.widget.LinearLayout
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.lifecycle.LifecycleCoroutineScope
|
||||
|
|
@ -13,13 +14,13 @@ import com.habitrpg.android.habitica.extensions.getShortRemainingString
|
|||
import com.habitrpg.android.habitica.extensions.layoutInflater
|
||||
import com.habitrpg.android.habitica.helpers.AdHandler
|
||||
import com.habitrpg.android.habitica.helpers.AdType
|
||||
import java.util.Date
|
||||
import kotlin.time.DurationUnit
|
||||
import kotlin.time.toDuration
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import java.util.Date
|
||||
import kotlin.time.DurationUnit
|
||||
import kotlin.time.toDuration
|
||||
|
||||
class AdButton @JvmOverloads constructor(
|
||||
context: Context,
|
||||
|
|
@ -42,6 +43,8 @@ class AdButton @JvmOverloads constructor(
|
|||
private var nextAdDate: Date? = null
|
||||
private val binding = AdButtonBinding.inflate(context.layoutInflater, this)
|
||||
|
||||
private var activeBackgroundRes: Int = R.drawable.ad_button_background
|
||||
|
||||
var text: String = ""
|
||||
set(value) {
|
||||
field = value
|
||||
|
|
@ -56,10 +59,14 @@ class AdButton @JvmOverloads constructor(
|
|||
)?.let { attributes ->
|
||||
text = attributes.getString(R.styleable.AdButton_text) ?: ""
|
||||
binding.currencyView.currency = attributes.getString(R.styleable.AdButton_currency)
|
||||
activeBackgroundRes = attributes.getResourceId(R.styleable.AdButton_activeBackground, R.drawable.ad_button_background)
|
||||
binding.textView.setTextColor(attributes.getColor(R.styleable.AdButton_textColor, ContextCompat.getColor(context, R.color.white)))
|
||||
}
|
||||
binding.textView.setTextColor(ContextCompat.getColor(context, R.color.white))
|
||||
binding.currencyView.setTextColor(ContextCompat.getColor(context, R.color.white))
|
||||
binding.currencyView.value = 0.0
|
||||
if (binding.currencyView.currency?.isNotBlank() != true) {
|
||||
binding.currencyView.visibility = View.GONE
|
||||
}
|
||||
gravity = Gravity.CENTER
|
||||
state = State.READY
|
||||
}
|
||||
|
|
@ -72,7 +79,7 @@ class AdButton @JvmOverloads constructor(
|
|||
binding.textView.alpha = 1.0f
|
||||
binding.textView.visibility = VISIBLE
|
||||
binding.currencyView.visibility = VISIBLE
|
||||
setBackgroundResource(R.drawable.ad_button_background)
|
||||
setBackgroundResource(activeBackgroundRes)
|
||||
}
|
||||
State.UNAVAILABLE -> {
|
||||
binding.loadingIndicator.visibility = GONE
|
||||
|
|
|
|||
Loading…
Reference in a new issue