Begin improving dialog display

This commit is contained in:
Phillip Thelen 2019-08-28 13:04:32 +02:00
parent b227be907a
commit 656162ecb7
15 changed files with 148 additions and 40 deletions

View file

@ -152,7 +152,7 @@ android {
buildConfigField "String", "TESTING_LEVEL", "\"production\""
multiDexEnabled true
versionCode 2211
versionCode 2219
versionName "2.1"
}

View file

@ -26,7 +26,6 @@
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:paddingBottom="@dimen/spacing_large"
style="@style/Headline6"
tools:text="This is the title"
android:visibility="gone"
tools:visibility="visible"
@ -41,8 +40,6 @@
android:gravity="center_horizontal"
android:visibility="gone"
tools:visibility="visible"
android:textColor="?textColorSecondary"
style="@style/Body2"
tools:text="This is the message"
android:paddingBottom="@dimen/spacing_medium"
android:paddingStart="@dimen/alert_side_padding"
@ -99,7 +96,6 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/close"
android:textColor="?colorAccent"
android:background="@drawable/alert_dialog_background"
android:layout_marginTop="@dimen/spacing_large"
android:visibility="gone"

View file

@ -815,4 +815,22 @@
<string name="removed_member">%s was removed from the group</string>
<string name="mystery_item_received">You open the box and receive a %s</string>
<string name="see_what_s_new">See what\'s new</string>
<string name="view_achievements">View Achievements</string>
<string name="achievement_title">You got an Achievement!</string>
<string name="partyUpTitle">Party Up</string>
<string name="partyUpDescription">You teamed up with a party member!</string>
<string name="partyOnTitle">Party On</string>
<string name="partyOnDescription">Your party grew to 4 members!</string>
<string name="beastMasterTitle">Beast Master</string>
<string name="beastMasterDescription">You have earned the \\\"Beast Master\\\" Achievement for collecting all the pets!</string>
<string name="mountMasterTitle">Mount Master</string>
<string name="mountMasterDescription">You have earned the \\\"Mount Master\\\" achievement for taming all the mounts!</string>
<string name="triadBingoTitle">Triad Bingo</string>
<string name="triadBingoDescription">You have earned the \\\"Triad Bingo\\\" achievement for finding all the pets, taming all the mounts, and finding all the pets again!</string>
<string name="joinedGuildTitle">Joined a Guild</string>
<string name="joinedGuildDescription">Ventured into the social side of Habitica by joining a Guild!</string>
<string name="joinedChallengeTitle">Joined a Challenge</string>
<string name="joinedChallengeDescription">You put themselves to the test by joining a Challenge!</string>
<string name="inviteFriendTitle">Invited a Friend</string>
<string name="inviteFriendDescription">invitedinvited a friend (or friends) who joined you on your adventure!</string>
</resources>

View file

@ -0,0 +1,3 @@
package com.habitrpg.android.habitica.events
class ShowAchievementDialog(var type: String)

View file

@ -3,6 +3,7 @@ package com.habitrpg.android.habitica.helpers
import android.content.Context
import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.data.ApiClient
import com.habitrpg.android.habitica.events.ShowAchievementDialog
import com.habitrpg.android.habitica.events.ShowCheckinDialog
import com.habitrpg.android.habitica.events.ShowSnackbarEvent
import com.habitrpg.android.habitica.models.Notification
@ -10,18 +11,13 @@ import com.habitrpg.android.habitica.models.notifications.LoginIncentiveData
import com.habitrpg.android.habitica.ui.views.HabiticaSnackbar
import io.reactivex.BackpressureStrategy
import io.reactivex.Flowable
import io.reactivex.functions.Consumer
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.subjects.BehaviorSubject
import org.greenrobot.eventbus.EventBus
import java.util.*
/**
* Created by krh12 on 12/9/2016.
*/
class NotificationsManager (private val context: Context) {
// @TODO: A queue for displaying alert dialogues
private var compositeSubscription = CompositeDisposable()
private val seenNotifications: MutableMap<String, Boolean>
private var apiClient: ApiClient? = null
@ -58,12 +54,25 @@ class NotificationsManager (private val context: Context) {
.map {
val notificationDisplayed = when (it.type) {
Notification.Type.LOGIN_INCENTIVE.type -> displayLoginIncentiveNotification(it)
Notification.Type.ACHIEVEMENT_PARTY_UP.type -> displayAchievementNotification(it)
Notification.Type.ACHIEVEMENT_PARTY_ON.type -> displayAchievementNotification(it)
Notification.Type.ACHIEVEMENT_BEAST_MASTER.type -> displayAchievementNotification(it)
Notification.Type.ACHIEVEMENT_MOUNT_MASTER.type -> displayAchievementNotification(it)
Notification.Type.ACHIEVEMENT_TRIAD_BINGO.type -> displayAchievementNotification(it)
Notification.Type.ACHIEVEMENT_GUILD_JOINED.type -> displayAchievementNotification(it)
Notification.Type.ACHIEVEMENT_CHALLENGE_JOINED.type -> displayAchievementNotification(it)
Notification.Type.ACHIEVEMENT_INVITED_FRIEND.type -> displayAchievementNotification(it)
else -> false
}
if (notificationDisplayed == true) {
this.seenNotifications[it.id] = true
/*if (apiClient != null) {
apiClient?.readNotification(it.id)
?.subscribe(Consumer {}, RxErrorHandler.handleEmptyError())
}*/
}
}
return true
@ -83,12 +92,13 @@ class NotificationsManager (private val context: Context) {
event.text = nextUnlockText
event.type = HabiticaSnackbar.SnackbarDisplayType.BLUE
EventBus.getDefault().post(event)
if (apiClient != null) {
// @TODO: This should be handled somewhere else? MAybe we notifiy via event
apiClient?.readNotification(notification.id)
?.subscribe(Consumer {}, RxErrorHandler.handleEmptyError())
}
}
return true
}
private fun displayAchievementNotification(notification: Notification): Boolean {
EventBus.getDefault().post(ShowAchievementDialog(notification.type ?: ""))
return true
}
}

View file

@ -50,7 +50,7 @@ constructor(private val soundManager: SoundManager, threadExecutor: ThreadExecut
alert.addButton(R.string.not_now, false)
if (!requestValues.activity.isFinishing) {
alert.show()
alert.enqueue()
}
} else {
val customView = requestValues.activity.layoutInflater.inflate(R.layout.dialog_levelup, null)
@ -76,7 +76,7 @@ constructor(private val soundManager: SoundManager, threadExecutor: ThreadExecut
}
if (!requestValues.activity.isFinishing) {
alert.show()
alert.enqueue()
}
}

View file

@ -14,10 +14,20 @@ class Notification {
GROUP_TASK_REQUIRES_APPROVAL("GROUP_TASK_REQUIRES_APPROVAL"),
UNALLOCATED_STATS_POINTS("UNALLOCATED_STATS_POINTS"),
//Achievements
ACHIEVEMENT_PARTY_UP("ACHIEVEMENT_PARTY_UP"),
ACHIEVEMENT_PARTY_ON("ACHIEVEMENT_PARTY_ON"),
ACHIEVEMENT_BEAST_MASTER("ACHIEVEMENT_BEAST_MASTER"),
ACHIEVEMENT_MOUNT_MASTER("ACHIEVEMENT_MOUNT_MASTER"),
ACHIEVEMENT_TRIAD_BINGO("ACHIEVEMENT_TRIAD_BINGO"),
ACHIEVEMENT_GUILD_JOINED("GUILD_JOINED_ACHIEVEMENT"),
ACHIEVEMENT_CHALLENGE_JOINED("CHALLENGE_JOINED_ACHIEVEMENT"),
ACHIEVEMENT_INVITED_FRIEND("INVITED_FRIEND_ACHIEVEMENT"),
// Custom notification types (created by this app)
GUILD_INVITATION("GUILD_INVITATION"),
PARTY_INVITATION("PARTY_INVITATION"),
QUEST_INVITATION("QUEST_INVITATION");
QUEST_INVITATION("QUEST_INVITATION"),
}
var id: String = ""

View file

@ -3,10 +3,10 @@ package com.habitrpg.android.habitica.ui.activities
import android.content.SharedPreferences
import android.content.res.Configuration
import android.os.Bundle
import androidx.preference.PreferenceManager
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatDelegate
import androidx.appcompat.widget.Toolbar
import androidx.preference.PreferenceManager
import com.habitrpg.android.habitica.HabiticaApplication
import com.habitrpg.android.habitica.HabiticaBaseApplication
import com.habitrpg.android.habitica.R
@ -139,7 +139,7 @@ abstract class BaseActivity : AppCompatActivity() {
alert.setTitle(event.title)
alert.setMessage(event.message)
alert.addButton(android.R.string.ok, isPrimary = true, isDestructive = false, function = null)
alert.show()
alert.enqueue()
}
fun reload() {

View file

@ -197,7 +197,7 @@ class ChallengeFormActivity : BaseActivity() {
if (errorMessages.count() > 0) {
val alert = HabiticaAlertDialog(this)
alert.setMessage(errorMessages.joinToString("\n"))
alert.show()
alert.enqueue()
}
return errorMessages.size == 0
}

View file

@ -20,8 +20,8 @@ import com.habitrpg.android.habitica.helpers.RxErrorHandler
import com.habitrpg.android.habitica.models.user.*
import com.habitrpg.android.habitica.ui.AvatarView
import com.habitrpg.android.habitica.ui.helpers.bindView
import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaAlertDialog
import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper
import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaAlertDialog
import io.reactivex.functions.Consumer
import javax.inject.Inject
@ -264,7 +264,7 @@ class ClassSelectionActivity : BaseActivity(), Consumer<User> {
alert.setTitle(getString(R.string.class_changed, className))
alert.setMessage(getString(R.string.class_changed_description))
alert.addButton(getString(R.string.complete_tutorial), true)
alert.show()
alert.enqueue()
}
private fun optOutOfClasses() {

View file

@ -273,7 +273,7 @@ class GiftIAPActivity: BaseActivity() {
dialog.dismiss()
finish()
}
alert.show()
alert.enqueue()
}
private fun consumePurchase(purchase: Purchase) {

View file

@ -11,7 +11,6 @@ import android.graphics.Bitmap
import android.graphics.Canvas
import android.os.Bundle
import android.os.Handler
import androidx.preference.PreferenceManager
import android.util.Log
import android.view.*
import android.widget.FrameLayout
@ -35,10 +34,7 @@ import com.habitrpg.android.habitica.api.HostConfig
import com.habitrpg.android.habitica.api.MaintenanceApiService
import com.habitrpg.android.habitica.components.UserComponent
import com.habitrpg.android.habitica.data.*
import com.habitrpg.android.habitica.events.ShareEvent
import com.habitrpg.android.habitica.events.ShowCheckinDialog
import com.habitrpg.android.habitica.events.ShowConnectionProblemEvent
import com.habitrpg.android.habitica.events.ShowSnackbarEvent
import com.habitrpg.android.habitica.events.*
import com.habitrpg.android.habitica.events.commands.FeedCommand
import com.habitrpg.android.habitica.extensions.DateUtils
import com.habitrpg.android.habitica.extensions.subscribeWithErrorHandler
@ -67,6 +63,7 @@ import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper
import com.habitrpg.android.habitica.ui.views.HabiticaSnackbar
import com.habitrpg.android.habitica.ui.views.HabiticaSnackbar.SnackbarDisplayType
import com.habitrpg.android.habitica.ui.views.ValueBar
import com.habitrpg.android.habitica.ui.views.dialogs.AchievementDialog
import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaAlertDialog
import com.habitrpg.android.habitica.ui.views.navigation.HabiticaBottomNavigationView
import com.habitrpg.android.habitica.ui.views.yesterdailies.YesterdailyDialog
@ -423,7 +420,7 @@ open class MainActivity : BaseActivity(), TutorialView.OnTutorialReaction {
EventBus.getDefault().post(event1)
hatchingDialog.dismiss()
}
dialog.show()
dialog.enqueue()
}
}, RxErrorHandler.handleEmptyError()))
}
@ -470,7 +467,7 @@ open class MainActivity : BaseActivity(), TutorialView.OnTutorialReaction {
}
}
soundManager.loadAndPlayAudio(SoundManager.SoundDeath)
this.faintDialog?.show()
this.faintDialog?.enqueue()
}
}
@ -655,6 +652,18 @@ open class MainActivity : BaseActivity(), TutorialView.OnTutorialReaction {
}, RxErrorHandler.handleEmptyError()))
}
@Subscribe
fun showAchievementDialog(event: ShowAchievementDialog) {
compositeSubscription.add(Completable.complete()
.observeOn(AndroidSchedulers.mainThread())
.subscribe(Action {
val dialog = AchievementDialog(this)
dialog.setType(event.type)
dialog.enqueue()
}, RxErrorHandler.handleEmptyError()))
}
override fun onEvent(event: ShowConnectionProblemEvent) {
if (event.title != null) {
super.onEvent(event)
@ -694,7 +703,7 @@ open class MainActivity : BaseActivity(), TutorialView.OnTutorialReaction {
EventBus.getDefault().post(event1)
hatchingDialog.dismiss()
}
dialog.show()
dialog.enqueue()
}.subscribe(Consumer { }, RxErrorHandler.handleEmptyError()))
}

View file

@ -0,0 +1,33 @@
package com.habitrpg.android.habitica.ui.views.dialogs
import android.content.Context
import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.helpers.MainNavigationController
import com.habitrpg.android.habitica.models.Notification
class AchievementDialog(context: Context) : HabiticaAlertDialog(context) {
fun setType(type: String) {
when (type) {
Notification.Type.ACHIEVEMENT_PARTY_UP.type -> configure(R.string.partyUpTitle, R.string.partyUpDescription, "partyUp")
Notification.Type.ACHIEVEMENT_PARTY_ON.type -> configure(R.string.partyOnTitle, R.string.partyOnDescription, "partyOn")
Notification.Type.ACHIEVEMENT_BEAST_MASTER.type -> configure(R.string.beastMasterTitle, R.string.beastMasterDescription, "rat")
Notification.Type.ACHIEVEMENT_MOUNT_MASTER.type -> configure(R.string.mountMasterTitle, R.string.mountMasterDescription, "wolf")
Notification.Type.ACHIEVEMENT_TRIAD_BINGO.type -> configure(R.string.triadBingoTitle, R.string.triadBingoDescription, "triadbingo")
Notification.Type.ACHIEVEMENT_GUILD_JOINED.type -> configure(R.string.joinedGuildTitle, R.string.joinedGuildDescription, "guild")
Notification.Type.ACHIEVEMENT_CHALLENGE_JOINED.type -> configure(R.string.joinedChallengeTitle, R.string.joinedChallengeDescription, "challenge")
Notification.Type.ACHIEVEMENT_INVITED_FRIEND.type -> configure(R.string.inviteFriendTitle, R.string.inviteFriendDescription, "friends")
}
}
private fun configure(titleID: Int, descriptionID: Int, iconName: String) {
setTitle(R.string.achievement_title)
addButton(R.string.onwards, true)
addButton(R.string.view_achievements, isPrimary = false, isDestructive = false) { _, _ ->
MainNavigationController.navigate(R.id.achievementsFragment)
}
}
}

View file

@ -152,17 +152,17 @@ open class HabiticaAlertDialog(context: Context) : AlertDialog(context, R.style.
fun addButton(string: String, isPrimary: Boolean, isDestructive: Boolean = false, function: ((HabiticaAlertDialog, Int) -> Unit)? = null): Button {
val button: Button = if (isPrimary) {
if (isDestructive) {
buttonsWrapper.inflate(R.layout.dialog_habitica_primary_destructive_button) as Button
buttonsWrapper.inflate(R.layout.dialog_habitica_primary_destructive_button) as? Button
} else {
buttonsWrapper.inflate(R.layout.dialog_habitica_primary_button) as Button
buttonsWrapper.inflate(R.layout.dialog_habitica_primary_button) as? Button
}
} else {
val button = buttonsWrapper.inflate(R.layout.dialog_habitica_secondary_button) as Button
val button = buttonsWrapper.inflate(R.layout.dialog_habitica_secondary_button) as? Button
if (isDestructive) {
button.setTextColor(ContextCompat.getColor(context, R.color.red_100))
button?.setTextColor(ContextCompat.getColor(context, R.color.red_100))
}
button
}
} ?: Button(context)
button.text = string
button.minWidth = 147.dpToPx(context)
button.setScaledPadding(context, 20, 0, 20, 0)
@ -197,4 +197,33 @@ open class HabiticaAlertDialog(context: Context) : AlertDialog(context, R.style.
buttonView.layoutParams = layoutParams
buttonView.elevation = 10f
}
fun enqueue() {
addToQueue(this)
}
override fun dismiss() {
showNextInQueue(this)
super.dismiss()
}
companion object {
private var dialogQueue = mutableListOf<HabiticaAlertDialog>()
private fun showNextInQueue(currentDialog: HabiticaAlertDialog) {
if (dialogQueue.first() == currentDialog) {
dialogQueue.removeAt(0)
}
if (dialogQueue.size > 0) {
dialogQueue[0].show()
}
}
private fun addToQueue(dialog: HabiticaAlertDialog) {
if (dialogQueue.isEmpty()) {
dialog.show()
}
dialogQueue.add(dialog)
}
}
}

View file

@ -191,7 +191,7 @@ class YesterdailyDialog private constructor(context: Context, private val userRe
dialog.setCancelable(false)
dialog.setCanceledOnTouchOutside(false)
if (!activity.isFinishing) {
dialog.show()
dialog.enqueue()
}
}
}