mirror of
https://github.com/sudoxnym/habitica-android.git
synced 2026-07-15 02:31:57 +00:00
Revert saving notifications to Realm through User, use PopupNotificationsManager instead
Combine Notification & GlobalNotification models since they model the same thing
This commit is contained in:
parent
a4583c479a
commit
a78897cda7
20 changed files with 145 additions and 257 deletions
|
|
@ -5,6 +5,7 @@ import com.google.gson.GsonBuilder;
|
|||
import com.google.gson.reflect.TypeToken;
|
||||
import com.habitrpg.android.habitica.models.ContentResult;
|
||||
import com.habitrpg.android.habitica.models.FAQArticle;
|
||||
import com.habitrpg.android.habitica.models.Notification;
|
||||
import com.habitrpg.android.habitica.models.Skill;
|
||||
import com.habitrpg.android.habitica.models.Tag;
|
||||
import com.habitrpg.android.habitica.models.TutorialStep;
|
||||
|
|
@ -17,7 +18,6 @@ import com.habitrpg.android.habitica.models.inventory.Quest;
|
|||
import com.habitrpg.android.habitica.models.inventory.QuestCollect;
|
||||
import com.habitrpg.android.habitica.models.inventory.QuestDropItem;
|
||||
import com.habitrpg.android.habitica.models.members.Member;
|
||||
import com.habitrpg.android.habitica.models.notifications.GlobalNotification;
|
||||
import com.habitrpg.android.habitica.models.responses.FeedResponse;
|
||||
import com.habitrpg.android.habitica.models.social.Challenge;
|
||||
import com.habitrpg.android.habitica.models.social.ChatMessage;
|
||||
|
|
@ -119,7 +119,7 @@ public class GSonFactoryCreator {
|
|||
.registerTypeAdapter(Member.class, new MemberSerialization())
|
||||
.registerTypeAdapter(WorldState.class, new WorldStateSerialization())
|
||||
.registerTypeAdapter(FindUsernameResult.class, new FindUsernameResultDeserializer())
|
||||
.registerTypeAdapter(GlobalNotification.class, new NotificationDeserializer())
|
||||
.registerTypeAdapter(Notification.class, new NotificationDeserializer())
|
||||
.setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
|
||||
.create();
|
||||
return GsonConverterFactory.create(gson);
|
||||
|
|
|
|||
|
|
@ -73,11 +73,11 @@ class ApiClientImpl//private OnHabitsAPIResult mResultListener;
|
|||
observable
|
||||
.filter { it.data != null }
|
||||
.map { habitResponse ->
|
||||
if (habitResponse.notifications != null) {
|
||||
popupNotificationsManager.showNotificationDialog(habitResponse.notifications)
|
||||
}
|
||||
habitResponse.data
|
||||
}
|
||||
if (habitResponse.notifications != null) {
|
||||
popupNotificationsManager.setNotifications(habitResponse.notifications)
|
||||
}
|
||||
habitResponse.data
|
||||
}
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.doOnError(this)
|
||||
|
|
|
|||
|
|
@ -2,12 +2,16 @@ package com.habitrpg.android.habitica.helpers;
|
|||
|
||||
import android.content.Context;
|
||||
import androidx.annotation.Nullable;
|
||||
import io.reactivex.BackpressureStrategy;
|
||||
import io.reactivex.Flowable;
|
||||
import io.reactivex.subjects.BehaviorSubject;
|
||||
|
||||
import com.habitrpg.android.habitica.R;
|
||||
import com.habitrpg.android.habitica.data.ApiClient;
|
||||
import com.habitrpg.android.habitica.events.ShowCheckinDialog;
|
||||
import com.habitrpg.android.habitica.events.ShowSnackbarEvent;
|
||||
import com.habitrpg.android.habitica.models.Notification;
|
||||
import com.habitrpg.android.habitica.models.notifications.LoginIncentiveData;
|
||||
import com.habitrpg.android.habitica.ui.views.HabiticaSnackbar;
|
||||
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
|
|
@ -26,11 +30,24 @@ public class PopupNotificationsManager {
|
|||
private ApiClient apiClient;
|
||||
private Context context;
|
||||
|
||||
private BehaviorSubject<List<Notification>> notifications;
|
||||
|
||||
// @TODO: A queue for displaying alert dialogues
|
||||
|
||||
public PopupNotificationsManager(Context context) {
|
||||
this.seenNotifications = new HashMap<>();
|
||||
this.context = context;
|
||||
this.notifications = BehaviorSubject.create();
|
||||
}
|
||||
|
||||
public void setNotifications(List<Notification> current) {
|
||||
this.notifications.onNext(current);
|
||||
|
||||
this.showNotificationDialog(current);
|
||||
}
|
||||
|
||||
public Flowable<List<Notification>> getNotifications() {
|
||||
return this.notifications.toFlowable(BackpressureStrategy.LATEST);
|
||||
}
|
||||
|
||||
public void setApiClient(@Nullable ApiClient apiClient) {
|
||||
|
|
@ -38,15 +55,16 @@ public class PopupNotificationsManager {
|
|||
}
|
||||
|
||||
Boolean displayNotification(Notification notification) {
|
||||
String nextUnlockText = context.getString(R.string.nextPrizeUnlocks, notification.data.nextRewardAt);
|
||||
if (notification.data.rewardKey != null) {
|
||||
LoginIncentiveData notificationData = (LoginIncentiveData)notification.getData();
|
||||
String nextUnlockText = context.getString(R.string.nextPrizeUnlocks, notificationData.getNextRewardAt());
|
||||
if (notificationData.getRewardKey() != null) {
|
||||
ShowCheckinDialog event = new ShowCheckinDialog();
|
||||
event.notification = notification;
|
||||
event.nextUnlockText = nextUnlockText;
|
||||
EventBus.getDefault().post(event);
|
||||
} else {
|
||||
ShowSnackbarEvent event = new ShowSnackbarEvent();
|
||||
event.title = notification.data.message;
|
||||
event.title = notificationData.getMessage();
|
||||
event.text = nextUnlockText;
|
||||
event.type = HabiticaSnackbar.SnackbarDisplayType.BLUE;
|
||||
EventBus.getDefault().post(event);
|
||||
|
|
|
|||
|
|
@ -1,88 +0,0 @@
|
|||
package com.habitrpg.android.habitica.models;
|
||||
|
||||
/**
|
||||
* Created by krh12 on 11/28/2016.
|
||||
*/
|
||||
|
||||
import com.habitrpg.android.habitica.models.notifications.NotificationData;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class Notification {
|
||||
|
||||
public NotificationData data;
|
||||
private String type;
|
||||
private String createdAt;
|
||||
private String id;
|
||||
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
|
||||
|
||||
/**
|
||||
* @return The type
|
||||
*/
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param type The type
|
||||
*/
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The createdAt
|
||||
*/
|
||||
public String getCreatedAt() {
|
||||
return createdAt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param createdAt The createdAt
|
||||
*/
|
||||
public void setCreatedAt(String createdAt) {
|
||||
this.createdAt = createdAt;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
* The data
|
||||
*/
|
||||
// public T getData() {
|
||||
// return data;
|
||||
// }
|
||||
|
||||
/**
|
||||
*
|
||||
* @param data
|
||||
* The data
|
||||
*/
|
||||
// public void setData(T data) {
|
||||
// this.data = data;
|
||||
// }
|
||||
|
||||
/**
|
||||
* @return The id
|
||||
*/
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param id The id
|
||||
*/
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Map<String, Object> getAdditionalProperties() {
|
||||
return this.additionalProperties;
|
||||
}
|
||||
|
||||
public void setAdditionalProperty(String name, Object value) {
|
||||
this.additionalProperties.put(name, value);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
package com.habitrpg.android.habitica.models
|
||||
|
||||
import com.habitrpg.android.habitica.models.notifications.*
|
||||
|
||||
class Notification {
|
||||
enum class Type(val type: String) {
|
||||
LOGIN_INCENTIVE("LOGIN_INCENTIVE"),
|
||||
NEW_STUFF("NEW_STUFF"),
|
||||
NEW_CHAT_MESSAGE("NEW_CHAT_MESSAGE"),
|
||||
NEW_MYSTERY_ITEMS("NEW_MYSTERY_ITEMS"),
|
||||
UNALLOCATED_STATS_POINTS("UNALLOCATED_STATS_POINTS");
|
||||
}
|
||||
|
||||
var id: String = ""
|
||||
|
||||
var type: String? = null
|
||||
var seen: Boolean? = null
|
||||
|
||||
var data: NotificationData? = null
|
||||
|
||||
fun getDataType(): java.lang.reflect.Type? {
|
||||
return when (type) {
|
||||
Type.LOGIN_INCENTIVE.type -> LoginIncentiveData::class.java
|
||||
Type.NEW_STUFF.type -> NewStuffData::class.java
|
||||
Type.NEW_CHAT_MESSAGE.type -> NewChatMessageData::class.java
|
||||
Type.UNALLOCATED_STATS_POINTS.type -> UnallocatedPointsData::class.java
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,65 +0,0 @@
|
|||
package com.habitrpg.android.habitica.models.notifications
|
||||
|
||||
import io.realm.RealmObject
|
||||
import io.realm.annotations.PrimaryKey
|
||||
import java.lang.reflect.Type
|
||||
|
||||
enum class NotificationType(val type: String) {
|
||||
NEW_STUFF("NEW_STUFF"),
|
||||
NEW_CHAT_MESSAGE("NEW_CHAT_MESSAGE"),
|
||||
NEW_MYSTERY_ITEMS("NEW_MYSTERY_ITEMS"),
|
||||
UNALLOCATED_STATS_POINTS("UNALLOCATED_STATS_POINTS");
|
||||
|
||||
companion object {
|
||||
fun contains(type: String?): Boolean {
|
||||
return NotificationType.values().map { it.type }.contains(type)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents Habitica "Global notifications", i.e. the notifications about chat messages
|
||||
* (in Guilds and Party), Party & Quest invitations, unallocated stat points etc.
|
||||
*
|
||||
* These are different from other kind of notifications, such as Push notifications and
|
||||
* Popup notifications.
|
||||
*/
|
||||
open class GlobalNotification : RealmObject() {
|
||||
|
||||
@PrimaryKey
|
||||
var id: String = ""
|
||||
|
||||
var type: String? = null
|
||||
var seen: Boolean? = null
|
||||
|
||||
var newStuffData: NewStuffData? = null
|
||||
var newChatMessageData: NewChatMessageData? = null
|
||||
var unallocatedPointsData: UnallocatedPointsData? = null
|
||||
|
||||
// Workaround for Realms lack of polymorphism
|
||||
fun getData(): GlobalNotificationData? {
|
||||
return when (type) {
|
||||
NotificationType.NEW_STUFF.type -> newStuffData
|
||||
NotificationType.NEW_CHAT_MESSAGE.type -> newChatMessageData
|
||||
NotificationType.UNALLOCATED_STATS_POINTS.type -> unallocatedPointsData
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
fun setData(data: GlobalNotificationData?) {
|
||||
when (type) {
|
||||
NotificationType.NEW_STUFF.type -> newStuffData = data as NewStuffData?
|
||||
NotificationType.NEW_CHAT_MESSAGE.type -> newChatMessageData = data as NewChatMessageData?
|
||||
NotificationType.UNALLOCATED_STATS_POINTS.type -> unallocatedPointsData = data as UnallocatedPointsData?
|
||||
}
|
||||
}
|
||||
|
||||
fun getDataType(): Type? {
|
||||
return when (type) {
|
||||
NotificationType.NEW_STUFF.type -> NewStuffData::class.java
|
||||
NotificationType.NEW_CHAT_MESSAGE.type -> NewChatMessageData::class.java
|
||||
NotificationType.UNALLOCATED_STATS_POINTS.type -> UnallocatedPointsData::class.java
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
package com.habitrpg.android.habitica.models.notifications
|
||||
|
||||
import io.realm.RealmModel
|
||||
|
||||
interface GlobalNotificationData : RealmModel
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
package com.habitrpg.android.habitica.models.notifications
|
||||
|
||||
open class LoginIncentiveData : NotificationData {
|
||||
|
||||
var message: String? = null
|
||||
var nextRewardAt: Int? = null
|
||||
var rewardText: String? = null
|
||||
var rewardKey: List<String>? = null
|
||||
var reward: List<Reward>? = null
|
||||
|
||||
}
|
||||
|
|
@ -1,7 +1,5 @@
|
|||
package com.habitrpg.android.habitica.models.notifications
|
||||
|
||||
import io.realm.RealmObject
|
||||
|
||||
open class NewChatMessageData : RealmObject(), GlobalNotificationData {
|
||||
open class NewChatMessageData : NotificationData {
|
||||
var group: NotificationGroup? = null
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
package com.habitrpg.android.habitica.models.notifications
|
||||
|
||||
import io.realm.RealmObject
|
||||
|
||||
open class NewStuffData : RealmObject(), GlobalNotificationData {
|
||||
open class NewStuffData : NotificationData {
|
||||
var title: String? = null
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,18 +0,0 @@
|
|||
package com.habitrpg.android.habitica.models.notifications;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by krh12 on 11/30/2016.
|
||||
*/
|
||||
|
||||
public class NotificationData {
|
||||
|
||||
public String groupId;
|
||||
public String message;
|
||||
public Integer nextRewardAt;
|
||||
public String rewardText;
|
||||
public List<String> rewardKey;
|
||||
public List<Reward> reward;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
package com.habitrpg.android.habitica.models.notifications
|
||||
|
||||
interface NotificationData
|
||||
|
|
@ -1,8 +1,6 @@
|
|||
package com.habitrpg.android.habitica.models.notifications
|
||||
|
||||
import io.realm.RealmObject
|
||||
|
||||
open class NotificationGroup : RealmObject() {
|
||||
open class NotificationGroup {
|
||||
var id: String = ""
|
||||
|
||||
var name: String? = null
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
package com.habitrpg.android.habitica.models.notifications
|
||||
|
||||
import io.realm.RealmObject
|
||||
|
||||
open class UnallocatedPointsData : RealmObject(), GlobalNotificationData {
|
||||
open class UnallocatedPointsData : NotificationData {
|
||||
var points: Int? = null
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ import com.habitrpg.android.habitica.models.Avatar
|
|||
import com.habitrpg.android.habitica.models.PushDevice
|
||||
import com.habitrpg.android.habitica.models.Tag
|
||||
import com.habitrpg.android.habitica.models.invitations.Invitations
|
||||
import com.habitrpg.android.habitica.models.notifications.GlobalNotification
|
||||
import com.habitrpg.android.habitica.models.social.ChallengeMembership
|
||||
import com.habitrpg.android.habitica.models.social.UserParty
|
||||
import com.habitrpg.android.habitica.models.tasks.TaskList
|
||||
|
|
@ -123,8 +122,6 @@ open class User : RealmObject(), Avatar {
|
|||
@Ignore
|
||||
var pushDevices: List<PushDevice>? = null
|
||||
|
||||
var notifications = RealmList<GlobalNotification>()
|
||||
|
||||
var purchased: Purchases? = null
|
||||
set(purchased) {
|
||||
field = purchased
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ import com.habitrpg.android.habitica.helpers.*
|
|||
import com.habitrpg.android.habitica.helpers.notifications.PushNotificationManager
|
||||
import com.habitrpg.android.habitica.interactors.*
|
||||
import com.habitrpg.android.habitica.models.TutorialStep
|
||||
import com.habitrpg.android.habitica.models.notifications.LoginIncentiveData
|
||||
import com.habitrpg.android.habitica.models.responses.MaintenanceResponse
|
||||
import com.habitrpg.android.habitica.models.responses.TaskScoringResult
|
||||
import com.habitrpg.android.habitica.models.tasks.Task
|
||||
|
|
@ -827,19 +828,20 @@ open class MainActivity : BaseActivity(), TutorialView.OnTutorialReaction {
|
|||
|
||||
@Subscribe
|
||||
fun showCheckinDialog(event: ShowCheckinDialog) {
|
||||
val title = event.notification.data.message
|
||||
val notificationData = event.notification.data as LoginIncentiveData
|
||||
val title = notificationData.message
|
||||
|
||||
val factory = LayoutInflater.from(this)
|
||||
val view = factory.inflate(R.layout.dialog_login_incentive, null)
|
||||
|
||||
val imageView = view.findViewById<View>(R.id.imageView) as? SimpleDraweeView
|
||||
var imageKey = event.notification.data.rewardKey[0]
|
||||
var imageKey = notificationData.rewardKey!!.get(0)
|
||||
if (imageKey.contains("armor")) {
|
||||
imageKey = "slim_$imageKey"
|
||||
}
|
||||
DataBindingUtils.loadImage(imageView, imageKey)
|
||||
|
||||
val youEarnedMessage = this.getString(R.string.checkInRewardEarned, event.notification.data.rewardText)
|
||||
val youEarnedMessage = this.getString(R.string.checkInRewardEarned, notificationData.rewardText)
|
||||
|
||||
val titleTextView = TextView(this)
|
||||
titleTextView.setBackgroundResource(R.color.blue_100)
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import androidx.lifecycle.ViewModelProviders
|
|||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.components.AppComponent
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.models.Notification
|
||||
import com.habitrpg.android.habitica.models.notifications.*
|
||||
import com.habitrpg.android.habitica.ui.viewmodels.NotificationsViewModel
|
||||
import io.reactivex.functions.Consumer
|
||||
|
|
@ -25,7 +26,7 @@ class NotificationsActivity : BaseActivity(), androidx.swiperefreshlayout.widget
|
|||
|
||||
override fun getLayoutResId(): Int = R.layout.activity_notifications
|
||||
|
||||
private var notifications: List<GlobalNotification> = emptyList()
|
||||
private var notifications: List<Notification> = emptyList()
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
|
@ -65,7 +66,7 @@ class NotificationsActivity : BaseActivity(), androidx.swiperefreshlayout.widget
|
|||
}, RxErrorHandler.handleEmptyError()))
|
||||
}
|
||||
|
||||
private fun setNotifications(notifications: List<GlobalNotification>) {
|
||||
private fun setNotifications(notifications: List<Notification>) {
|
||||
this.notifications = notifications
|
||||
|
||||
if (notification_items == null) {
|
||||
|
|
@ -86,17 +87,17 @@ class NotificationsActivity : BaseActivity(), androidx.swiperefreshlayout.widget
|
|||
)
|
||||
}
|
||||
|
||||
private fun displayNotificationsListView(notifications: List<GlobalNotification>) {
|
||||
private fun displayNotificationsListView(notifications: List<Notification>) {
|
||||
notification_items.addView(
|
||||
createNotificationsHeaderView(notifications.count())
|
||||
)
|
||||
|
||||
notifications.map {
|
||||
val item: View? = when (it.type) {
|
||||
NotificationType.NEW_CHAT_MESSAGE.type -> createNewChatMessageNotification(it)
|
||||
NotificationType.NEW_STUFF.type -> createNewStuffNotification(it)
|
||||
NotificationType.UNALLOCATED_STATS_POINTS.type -> createUnallocatedStatsNotification(it)
|
||||
NotificationType.NEW_MYSTERY_ITEMS.type -> createMysteryItemsNotification(it)
|
||||
Notification.Type.NEW_CHAT_MESSAGE.type -> createNewChatMessageNotification(it)
|
||||
Notification.Type.NEW_STUFF.type -> createNewStuffNotification(it)
|
||||
Notification.Type.UNALLOCATED_STATS_POINTS.type -> createUnallocatedStatsNotification(it)
|
||||
Notification.Type.NEW_MYSTERY_ITEMS.type -> createMysteryItemsNotification(it)
|
||||
//TODO rest of the notification types
|
||||
else -> null
|
||||
}
|
||||
|
|
@ -117,8 +118,8 @@ class NotificationsActivity : BaseActivity(), androidx.swiperefreshlayout.widget
|
|||
return header
|
||||
}
|
||||
|
||||
private fun createNewChatMessageNotification(notification: GlobalNotification): View? {
|
||||
val data = notification.getData() as? NewChatMessageData
|
||||
private fun createNewChatMessageNotification(notification: Notification): View? {
|
||||
val data = notification.data as? NewChatMessageData
|
||||
val stringId = if (viewModel.isPartyMessage(data)) R.string.new_msg_party else R.string.new_msg_guild
|
||||
|
||||
return createNotificationItem(
|
||||
|
|
@ -127,8 +128,8 @@ class NotificationsActivity : BaseActivity(), androidx.swiperefreshlayout.widget
|
|||
)
|
||||
}
|
||||
|
||||
private fun createNewStuffNotification(notification: GlobalNotification): View? {
|
||||
val data = notification.getData() as? NewStuffData
|
||||
private fun createNewStuffNotification(notification: Notification): View? {
|
||||
val data = notification.data as? NewStuffData
|
||||
val text = fromHtml("<b>" + getString(R.string.new_bailey_update) + "</b><br>" + data?.title)
|
||||
|
||||
return createNotificationItem(
|
||||
|
|
@ -138,8 +139,8 @@ class NotificationsActivity : BaseActivity(), androidx.swiperefreshlayout.widget
|
|||
)
|
||||
}
|
||||
|
||||
private fun createUnallocatedStatsNotification(notification: GlobalNotification): View? {
|
||||
val data = notification.getData() as? UnallocatedPointsData
|
||||
private fun createUnallocatedStatsNotification(notification: Notification): View? {
|
||||
val data = notification.data as? UnallocatedPointsData
|
||||
|
||||
return createNotificationItem(
|
||||
notification,
|
||||
|
|
@ -148,7 +149,7 @@ class NotificationsActivity : BaseActivity(), androidx.swiperefreshlayout.widget
|
|||
)
|
||||
}
|
||||
|
||||
private fun createMysteryItemsNotification(notification: GlobalNotification): View? {
|
||||
private fun createMysteryItemsNotification(notification: Notification): View? {
|
||||
return createNotificationItem(
|
||||
notification,
|
||||
fromHtml(getString(R.string.new_subscriber_item)),
|
||||
|
|
@ -156,7 +157,7 @@ class NotificationsActivity : BaseActivity(), androidx.swiperefreshlayout.widget
|
|||
)
|
||||
}
|
||||
|
||||
private fun createNotificationItem(notification: GlobalNotification, messageText: CharSequence, imageResourceId: Int? = null): View? {
|
||||
private fun createNotificationItem(notification: Notification, messageText: CharSequence, imageResourceId: Int? = null): View? {
|
||||
val item = inflater.inflate(R.layout.notification_item, notification_items, false)
|
||||
|
||||
val dismissButton = item?.findViewById(R.id.dismiss_button) as? ImageView
|
||||
|
|
|
|||
|
|
@ -1,28 +1,53 @@
|
|||
package com.habitrpg.android.habitica.ui.viewmodels
|
||||
|
||||
import com.habitrpg.android.habitica.components.AppComponent
|
||||
import com.habitrpg.android.habitica.helpers.PopupNotificationsManager
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.models.notifications.GlobalNotification
|
||||
import com.habitrpg.android.habitica.models.Notification
|
||||
import com.habitrpg.android.habitica.models.notifications.NewChatMessageData
|
||||
import com.habitrpg.android.habitica.models.notifications.NotificationType
|
||||
import com.habitrpg.android.habitica.models.social.UserParty
|
||||
import io.reactivex.Flowable
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.functions.Consumer
|
||||
import io.realm.RealmList
|
||||
import java.util.HashMap
|
||||
import javax.inject.Inject
|
||||
|
||||
open class NotificationsViewModel : BaseViewModel() {
|
||||
var party: UserParty? = null
|
||||
@Inject
|
||||
lateinit var notificationsManager: PopupNotificationsManager
|
||||
|
||||
/**
|
||||
* A list of notification types handled by this component.
|
||||
* NOTE: Those not listed here won't be shown in the notification panel
|
||||
*/
|
||||
private val supportedNotificationTypes = listOf(
|
||||
Notification.Type.NEW_STUFF.type,
|
||||
Notification.Type.NEW_CHAT_MESSAGE.type,
|
||||
Notification.Type.NEW_MYSTERY_ITEMS.type,
|
||||
Notification.Type.UNALLOCATED_STATS_POINTS.type
|
||||
)
|
||||
|
||||
/**
|
||||
* Keep track of users party so we can determine which chat notifications are party chat
|
||||
* instead of guild chat notifications.
|
||||
*/
|
||||
private var party: UserParty? = null
|
||||
|
||||
override fun inject(component: AppComponent) {
|
||||
component.inject(this)
|
||||
}
|
||||
|
||||
fun getNotifications(): Flowable<List<GlobalNotification>> {
|
||||
return userRepository.getUser()
|
||||
.doOnEach { party = it.value?.party }
|
||||
.map { filterSupportedTypes(it.notifications) }
|
||||
init {
|
||||
disposable.add(userRepository.getUser()
|
||||
.subscribe(Consumer {
|
||||
party = it.party
|
||||
}, RxErrorHandler.handleEmptyError()))
|
||||
}
|
||||
|
||||
|
||||
fun getNotifications(): Flowable<List<Notification>> {
|
||||
return notificationsManager.notifications
|
||||
.map { filterSupportedTypes(it) }
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
}
|
||||
|
||||
|
|
@ -38,12 +63,12 @@ open class NotificationsViewModel : BaseViewModel() {
|
|||
.distinctUntilChanged()
|
||||
}
|
||||
|
||||
fun refreshNotifications(): Flowable<RealmList<GlobalNotification>> {
|
||||
return userRepository.retrieveUser(withTasks = false, forced = true).map { it.notifications }
|
||||
fun refreshNotifications(): Flowable<*> {
|
||||
return userRepository.retrieveUser(withTasks = false, forced = true)
|
||||
}
|
||||
|
||||
private fun filterSupportedTypes(notifications: List<GlobalNotification>): List<GlobalNotification> {
|
||||
return notifications.filter { NotificationType.contains(it.type) }
|
||||
private fun filterSupportedTypes(notifications: List<Notification>): List<Notification> {
|
||||
return notifications.filter { supportedNotificationTypes.contains(it.type) }
|
||||
}
|
||||
|
||||
fun isPartyMessage(data: NewChatMessageData?): Boolean {
|
||||
|
|
@ -54,15 +79,12 @@ open class NotificationsViewModel : BaseViewModel() {
|
|||
return party?.id == data.group?.id
|
||||
}
|
||||
|
||||
fun dismissNotification(notification: GlobalNotification) {
|
||||
fun dismissNotification(notification: Notification) {
|
||||
disposable.add(userRepository.readNotification(notification.id)
|
||||
.subscribe(Consumer {
|
||||
// TODO better way to handle updates than reload whole user ??
|
||||
refreshNotifications()
|
||||
}, RxErrorHandler.handleEmptyError()))
|
||||
.subscribe(Consumer {}, RxErrorHandler.handleEmptyError()))
|
||||
}
|
||||
|
||||
fun dismissAllNotifications(notifications: List<GlobalNotification>) {
|
||||
fun dismissAllNotifications(notifications: List<Notification>) {
|
||||
if (notifications.isEmpty()) {
|
||||
return
|
||||
}
|
||||
|
|
@ -71,12 +93,10 @@ open class NotificationsViewModel : BaseViewModel() {
|
|||
notificationIds["notificationIds"] = notifications.map { notification -> notification.id }
|
||||
|
||||
disposable.add(userRepository.readNotifications(notificationIds)
|
||||
.subscribe(Consumer {
|
||||
refreshNotifications()
|
||||
}, RxErrorHandler.handleEmptyError()))
|
||||
.subscribe(Consumer {}, RxErrorHandler.handleEmptyError()))
|
||||
}
|
||||
|
||||
fun markNotificationsAsSeen(notifications: List<GlobalNotification>) {
|
||||
fun markNotificationsAsSeen(notifications: List<Notification>) {
|
||||
val unseenIds = notifications.filter { notification -> notification.seen != true }
|
||||
.map { notification -> notification.id }
|
||||
|
||||
|
|
@ -88,9 +108,7 @@ open class NotificationsViewModel : BaseViewModel() {
|
|||
notificationIds["notificationIds"] = unseenIds
|
||||
|
||||
disposable.add(userRepository.seeNotifications(notificationIds)
|
||||
.subscribe(Consumer {
|
||||
refreshNotifications()
|
||||
}, RxErrorHandler.handleEmptyError()))
|
||||
.subscribe(Consumer {}, RxErrorHandler.handleEmptyError()))
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,13 +4,13 @@ import com.google.gson.JsonDeserializationContext
|
|||
import com.google.gson.JsonDeserializer
|
||||
import com.google.gson.JsonElement
|
||||
import com.google.gson.JsonParseException
|
||||
import com.habitrpg.android.habitica.models.notifications.*
|
||||
import com.habitrpg.android.habitica.models.Notification
|
||||
import java.lang.reflect.Type
|
||||
|
||||
class NotificationDeserializer : JsonDeserializer<GlobalNotification> {
|
||||
class NotificationDeserializer : JsonDeserializer<Notification> {
|
||||
@Throws(JsonParseException::class)
|
||||
override fun deserialize(json: JsonElement, typeOfT: Type, context: JsonDeserializationContext): GlobalNotification {
|
||||
val notification = GlobalNotification()
|
||||
override fun deserialize(json: JsonElement, typeOfT: Type, context: JsonDeserializationContext): Notification {
|
||||
val notification = Notification()
|
||||
val obj = json.asJsonObject
|
||||
|
||||
if (obj.has("id")) {
|
||||
|
|
@ -27,9 +27,7 @@ class NotificationDeserializer : JsonDeserializer<GlobalNotification> {
|
|||
|
||||
val dataType = notification.getDataType()
|
||||
if (obj.has("data") && dataType != null) {
|
||||
notification.setData(
|
||||
context.deserialize(obj.getAsJsonObject("data"), dataType)
|
||||
)
|
||||
notification.data = context.deserialize(obj.getAsJsonObject("data"), dataType)
|
||||
}
|
||||
|
||||
return notification
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ import com.habitrpg.android.habitica.models.PushDevice
|
|||
import com.habitrpg.android.habitica.models.Tag
|
||||
import com.habitrpg.android.habitica.models.inventory.Quest
|
||||
import com.habitrpg.android.habitica.models.invitations.Invitations
|
||||
import com.habitrpg.android.habitica.models.notifications.GlobalNotification
|
||||
import com.habitrpg.android.habitica.models.social.ChallengeMembership
|
||||
import com.habitrpg.android.habitica.models.social.UserParty
|
||||
import com.habitrpg.android.habitica.models.tasks.TasksOrder
|
||||
|
|
@ -110,11 +109,6 @@ class UserDeserializer : JsonDeserializer<User> {
|
|||
.forEach { (user.pushDevices as? ArrayList<PushDevice>)?.add(it) }
|
||||
}
|
||||
|
||||
if (obj.has("notifications")) {
|
||||
user.notifications = context.deserialize(obj.get("notifications"), object: TypeToken<RealmList<GlobalNotification>>() {
|
||||
}.type)
|
||||
}
|
||||
|
||||
if (obj.has("lastCron")) {
|
||||
user.lastCron = context.deserialize(obj.get("lastCron"), Date::class.java)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue