fix removing likes from messages. Fixes #817

This commit is contained in:
Phillip Thelen 2018-02-12 13:35:08 +01:00
parent 75b13764b7
commit 6de3940e2d
16 changed files with 402 additions and 421 deletions

View file

@ -240,6 +240,7 @@ public class ApiClientImpl implements Action1<Throwable>, ApiClient {
Type questCollectListType = new TypeToken<RealmList<QuestCollect>>() {}.getType();
Type chatMessageListType = new TypeToken<RealmList<ChatMessage>>() {}.getType();
Type challengeListType = new TypeToken<List<Challenge>>() {}.getType();
Type challengeRealmListType = new TypeToken<RealmList<Challenge>>() {}.getType();
Type questDropItemListType = new TypeToken<RealmList<QuestDropItem>>() {}.getType();
//Exclusion strategy needed for DBFlow https://github.com/Raizlabs/DBFlow/issues/121
@ -273,6 +274,7 @@ public class ApiClientImpl implements Action1<Throwable>, ApiClient {
.registerTypeAdapter(questCollectListType, new QuestCollectDeserializer())
.registerTypeAdapter(chatMessageListType, new ChatMessageListDeserializer())
.registerTypeAdapter(challengeListType, new ChallengeListDeserializer())
.registerTypeAdapter(challengeRealmListType, new ChallengeListDeserializer())
.registerTypeAdapter(questDropItemListType, new QuestDropItemsListSerialization())
.registerTypeAdapter(Quest.class, new QuestDeserializer())
.registerTypeAdapter(Member.class, new MemberSerialization())

View file

@ -79,10 +79,9 @@ class RealmSocialLocalRepository(realm: Realm) : RealmBaseLocalRepository(realm)
return
}
if (liked) {
realm.executeTransaction { chatMessage.likes.add(ChatMessageLike(userId)) }
realm.executeTransaction { chatMessage.likes?.add(ChatMessageLike(userId, chatMessage.id)) }
} else {
chatMessage.likes.filter { userId == it.id }
.forEach { like -> realm.executeTransaction { like.deleteFromRealm() } }
chatMessage.likes?.filter { userId == it.id }?.forEach { like -> realm.executeTransaction { like.deleteFromRealm() } }
}
}
@ -122,10 +121,10 @@ class RealmSocialLocalRepository(realm: Realm) : RealmBaseLocalRepository(realm)
if (groupId != null) {
val existingMessages = realm.where(ChatMessage::class.java).equalTo("groupId", groupId).findAll()
val messagesToRemove = ArrayList<ChatMessage>()
for (existingMember in existingMessages) {
val isStillMember = chatMessages.any { existingMember.id != null && existingMember.id == it.id }
for (existingMessage in existingMessages) {
val isStillMember = chatMessages.any { existingMessage.id == it.id }
if (!isStillMember) {
messagesToRemove.add(existingMember)
messagesToRemove.add(existingMessage)
}
}
realm.executeTransaction {

View file

@ -1,124 +0,0 @@
package com.habitrpg.android.habitica.models.social;
import android.content.res.Resources;
import com.habitrpg.android.habitica.R;
import com.habitrpg.android.habitica.models.user.ContributorInfo;
import java.util.Date;
import io.realm.RealmList;
import io.realm.RealmObject;
import io.realm.annotations.Ignore;
import io.realm.annotations.PrimaryKey;
public class ChatMessage extends RealmObject {
@PrimaryKey
public String id;
public String text;
@Ignore
public CharSequence parsedText;
public Long timestamp;
public RealmList<ChatMessageLike> likes;
public int flagCount;
public String uuid;
public ContributorInfo contributor;
public Backer backer;
public String user;
public String sent;
public String groupId;
public boolean isInboxMessage;
public int getContributorColor() {
int rColor = android.R.color.black;
if (contributor != null) {
if (ContributorInfo.CONTRIBUTOR_COLOR_DICT.containsKey(contributor.getLevel())) {
rColor = ContributorInfo.CONTRIBUTOR_COLOR_DICT.get(contributor.getLevel());
}
}
if (backer != null) {
if (backer.npc != null) {
rColor = android.R.color.black;
}
}
return rColor;
}
public int getContributorForegroundColor() {
int rColor = android.R.color.white;
if (backer != null && backer.npc != null) {
rColor = R.color.contributor_npc_font;
}
return rColor;
}
public String getAgoString(Resources res) {
long diff = new Date().getTime() - timestamp;
long diffMinutes = diff / (60 * 1000) % 60;
long diffHours = diff / (60 * 60 * 1000) % 24;
long diffDays = diff / (24 * 60 * 60 * 1000);
if (diffDays != 0) {
if (diffDays == 1) {
return res.getString(R.string.ago_1day);
}
return res.getString(R.string.ago_days, diffDays);
}
if (diffHours != 0) {
if (diffHours == 1) {
return res.getString(R.string.ago_1hour);
}
return res.getString(R.string.ago_hours, diffHours);
}
if (diffMinutes == 1) {
return res.getString(R.string.ago_1Minute);
}
return res.getString(R.string.ago_minutes, diffMinutes);
}
public boolean isSystemMessage() {
return uuid.equals("system");
}
public int getLikeCount() {
if (likes != null) {
return likes.size();
}
return 0;
}
public boolean userLikesMessage(String userId) {
if (likes == null || userId == null) {
return false;
}
for (ChatMessageLike like : likes) {
if (userId.equals(like.id)) {
return true;
}
}
return false;
}
}

View file

@ -0,0 +1,112 @@
package com.habitrpg.android.habitica.models.social
import android.content.res.Resources
import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.models.user.ContributorInfo
import java.util.Date
import io.realm.RealmList
import io.realm.RealmObject
import io.realm.annotations.Ignore
import io.realm.annotations.PrimaryKey
open class ChatMessage : RealmObject() {
@PrimaryKey
var id: String = ""
set(value) {
field = value
likes?.forEach { it.messageId = value }
}
var text: String? = null
@Ignore
var parsedText: CharSequence? = null
var timestamp: Long? = null
var likes: RealmList<ChatMessageLike>? = null
var flagCount: Int = 0
var uuid: String? = null
var contributor: ContributorInfo? = null
var backer: Backer? = null
var user: String? = null
var sent: String? = null
var groupId: String? = null
var isInboxMessage: Boolean = false
val contributorColor: Int
get() {
var rColor = android.R.color.black
val level = contributor?.level
if (level != null) {
if (ContributorInfo.CONTRIBUTOR_COLOR_DICT.get(level, -1) > 0) {
rColor = ContributorInfo.CONTRIBUTOR_COLOR_DICT[level]
}
}
if (backer?.npc != null) {
rColor = android.R.color.black
}
return rColor
}
val contributorForegroundColor: Int
get() {
var rColor = android.R.color.white
if (backer?.npc != null) {
rColor = R.color.contributor_npc_font
}
return rColor
}
val isSystemMessage: Boolean
get() = uuid == "system"
val likeCount: Int
get() = likes?.size ?: 0
fun getAgoString(res: Resources): String {
val diff = Date().time - timestamp!!
val diffMinutes = diff / (60 * 1000) % 60
val diffHours = diff / (60 * 60 * 1000) % 24
val diffDays = diff / (24 * 60 * 60 * 1000)
if (diffDays != 0L) {
return if (diffDays == 1L) {
res.getString(R.string.ago_1day)
} else res.getString(R.string.ago_days, diffDays)
}
if (diffHours != 0L) {
return if (diffHours == 1L) {
res.getString(R.string.ago_1hour)
} else res.getString(R.string.ago_hours, diffHours)
}
return if (diffMinutes == 1L) {
res.getString(R.string.ago_1Minute)
} else res.getString(R.string.ago_minutes, diffMinutes)
}
fun userLikesMessage(userId: String?): Boolean {
return likes?.any { userId == it.id } ?: false
}
}

View file

@ -1,23 +0,0 @@
package com.habitrpg.android.habitica.models.social;
import io.realm.RealmObject;
import io.realm.annotations.PrimaryKey;
/**
* Created by phillip on 30.06.17.
*/
public class ChatMessageLike extends RealmObject {
@PrimaryKey
public String id;
public ChatMessageLike(String id) {
super();
this.id = id;
}
public ChatMessageLike() {
super();
}
}

View file

@ -0,0 +1,31 @@
package com.habitrpg.android.habitica.models.social
import io.realm.RealmObject
import io.realm.annotations.PrimaryKey
/**
* Created by phillip on 30.06.17.
*/
open class ChatMessageLike : RealmObject {
@PrimaryKey
var key: String = ""
var messageId: String = ""
set(value) {
field = value
key = messageId + id
}
var id: String = ""
set(value) {
field = value
key = messageId + id
}
constructor(id: String, messageId: String) : super() {
this.id = id
this.key = messageId + id
}
constructor() : super()
}

View file

@ -1,5 +1,8 @@
package com.habitrpg.android.habitica.models.user;
import android.util.SparseArray;
import android.util.SparseIntArray;
import com.habitrpg.android.habitica.R;
import java.util.HashMap;
@ -9,10 +12,10 @@ import io.realm.annotations.PrimaryKey;
public class ContributorInfo extends RealmObject {
public static final HashMap<Integer, Integer> CONTRIBUTOR_COLOR_DICT;
public static final SparseIntArray CONTRIBUTOR_COLOR_DICT;
static {
CONTRIBUTOR_COLOR_DICT = new HashMap<>();
CONTRIBUTOR_COLOR_DICT = new SparseIntArray();
CONTRIBUTOR_COLOR_DICT.put(0, R.color.contributor_0);
CONTRIBUTOR_COLOR_DICT.put(1, R.color.contributor_1);
CONTRIBUTOR_COLOR_DICT.put(2, R.color.contributor_2);
@ -70,7 +73,7 @@ public class ContributorInfo extends RealmObject {
int rColor = android.R.color.black;
if (CONTRIBUTOR_COLOR_DICT.containsKey(this.level)) {
if (CONTRIBUTOR_COLOR_DICT.get(this.level, -1) > 0) {
rColor = CONTRIBUTOR_COLOR_DICT.get(this.level);
}

View file

@ -149,7 +149,7 @@ public class ChatRecyclerViewAdapter extends RealmRecyclerViewAdapter<ChatMessag
setLikeProperties();
if (userBackground != null) {
if (msg.sent != null && msg.sent.equals("true") && sendingUser != null) {
if (msg.getSent() != null && msg.getSent().equals("true") && sendingUser != null) {
DataBindingUtils.INSTANCE.setRoundedBackgroundInt(userBackground, sendingUser.getContributorColor());
} else {
DataBindingUtils.INSTANCE.setRoundedBackgroundInt(userBackground, msg.getContributorColor());
@ -157,33 +157,33 @@ public class ChatRecyclerViewAdapter extends RealmRecyclerViewAdapter<ChatMessag
}
if (userLabel != null) {
if (msg.sent != null && msg.sent.equals("true")) {
if (msg.getSent() != null && msg.getSent().equals("true")) {
userLabel.setText(sendingUser.getProfile().getName());
} else {
if (msg.user != null && msg.user.length() > 0) {
userLabel.setText(msg.user);
if (msg.getUser() != null && msg.getUser().length() > 0) {
userLabel.setText(msg.getUser());
} else {
userLabel.setText(R.string.system);
}
}
userLabel.setClickable(true);
userLabel.setOnClickListener(view -> userLabelClickEvents.onNext(msg.uuid));
userLabel.setOnClickListener(view -> userLabelClickEvents.onNext(msg.getUuid()));
}
DataBindingUtils.INSTANCE.setForegroundTintColor(userLabel, msg.getContributorForegroundColor());
if (messageText != null) {
messageText.setText(chatMessage.parsedText);
if (msg.parsedText == null) {
messageText.setText(chatMessage.text);
Observable.just(chatMessage.text)
messageText.setText(chatMessage.getParsedText());
if (msg.getParsedText() == null) {
messageText.setText(chatMessage.getText());
Observable.just(chatMessage.getText())
.map(MarkdownParser::parseMarkdown)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(parsedText -> {
chatMessage.parsedText = parsedText;
messageText.setText(chatMessage.parsedText);
chatMessage.setParsedText(parsedText);
messageText.setText(chatMessage.getParsedText());
}, Throwable::printStackTrace);
}
this.messageText.setMovementMethod(LinkMovementMethod.getInstance());
@ -243,7 +243,7 @@ public class ChatRecyclerViewAdapter extends RealmRecyclerViewAdapter<ChatMessag
popupMenu.getMenu().findItem(R.id.menu_chat_delete).setVisible(shouldShowDelete(chatMessage));
popupMenu.getMenu().findItem(R.id.menu_chat_flag).setVisible(!chatMessage.uuid.equals("system"));
popupMenu.getMenu().findItem(R.id.menu_chat_flag).setVisible(!chatMessage.getUuid().equals("system"));
popupMenu.getMenu().findItem(R.id.menu_chat_copy_as_todo).setVisible(false);
popupMenu.getMenu().findItem(R.id.menu_chat_send_pm).setVisible(false);
@ -273,7 +273,7 @@ public class ChatRecyclerViewAdapter extends RealmRecyclerViewAdapter<ChatMessag
}
private boolean shouldShowDelete(ChatMessage chatMsg) {
return !chatMsg.isSystemMessage() && (chatMsg.uuid.equals(userId) || user.getContributor() != null && user.getContributor().getAdmin());
return !chatMsg.isSystemMessage() && (chatMsg.getUuid().equals(userId) || user.getContributor() != null && user.getContributor().getAdmin());
}
@OnClick(R.id.tvLikes)
@ -298,7 +298,7 @@ public class ChatRecyclerViewAdapter extends RealmRecyclerViewAdapter<ChatMessag
}
case R.id.menu_chat_send_pm: {
privateMessageClickEvents.onNext(chatMessage.uuid);
privateMessageClickEvents.onNext(chatMessage.getUuid());
break;
}

View file

@ -152,8 +152,8 @@ public class InboxFragment extends BaseMainFragment
if (messages.size() > 0) {
for (ChatMessage message : messages) {
TextView entry = (TextView) inflater.inflate(R.layout.plain_list_item, this.inboxMessagesListView, false);
entry.setText(message.user);
entry.setTag(message.uuid);
entry.setText(message.getUser());
entry.setTag(message.getUuid());
entry.setOnClickListener(this);
this.inboxMessagesListView.addView(entry);
}

View file

@ -1,75 +0,0 @@
package com.habitrpg.android.habitica.utils;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.habitrpg.android.habitica.models.social.Backer;
import com.habitrpg.android.habitica.models.social.ChatMessage;
import com.habitrpg.android.habitica.models.social.ChatMessageLike;
import com.habitrpg.android.habitica.models.user.ContributorInfo;
import java.lang.reflect.Type;
import java.util.Map;
import io.realm.RealmList;
public class ChatMessageDeserializer implements JsonDeserializer<ChatMessage> {
@Override
public ChatMessage deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
ChatMessage message = new ChatMessage();
JsonObject obj = json.getAsJsonObject();
if (obj.has("id")) {
message.id = obj.get("id").getAsString();
}
if (obj.has("text") && !obj.get("text").isJsonNull() && obj.get("text").isJsonPrimitive()) {
message.text = obj.get("text").getAsString();
}
if (obj.has("timestamp")) {
message.timestamp = obj.get("timestamp").getAsLong();
}
if (obj.has("likes")) {
message.likes = new RealmList<>();
for (Map.Entry<String, JsonElement> likeEntry : obj.getAsJsonObject("likes").entrySet()) {
if (likeEntry.getValue().getAsBoolean()) {
message.likes.add(new ChatMessageLike(likeEntry.getKey()));
}
}
}
if (obj.has("flagCount")) {
message.flagCount = obj.get("flagCount").getAsInt();
}
if (obj.has("uuid")) {
message.uuid = obj.get("uuid").getAsString();
}
if (obj.has("contributor")) {
if (!obj.get("contributor").isJsonNull()) {
if (obj.get("contributor").isJsonObject()) {
message.contributor = context.deserialize(obj.get("contributor"), ContributorInfo.class);
} else {
ContributorInfo contributor = new ContributorInfo();
contributor.setText(obj.get("contributor").getAsString());
message.contributor = contributor;
}
message.contributor.setUserId(message.id);
}
}
if (obj.has("backer")) {
message.backer = context.deserialize(obj.get("backer"), Backer.class);
}
if (obj.has("user")) {
message.user = obj.get("user").getAsString();
}
if (obj.has("sent")) {
message.sent = obj.get("sent").getAsString();
}
return message;
}
}

View file

@ -0,0 +1,71 @@
package com.habitrpg.android.habitica.utils
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.social.Backer
import com.habitrpg.android.habitica.models.social.ChatMessage
import com.habitrpg.android.habitica.models.social.ChatMessageLike
import com.habitrpg.android.habitica.models.user.ContributorInfo
import io.realm.RealmList
import java.lang.reflect.Type
class ChatMessageDeserializer : JsonDeserializer<ChatMessage> {
@Throws(JsonParseException::class)
override fun deserialize(json: JsonElement, typeOfT: Type, context: JsonDeserializationContext): ChatMessage {
val message = ChatMessage()
val obj = json.asJsonObject
if (obj.has("id")) {
message.id = obj.get("id").asString
}
if (obj.has("text") && !obj.get("text").isJsonNull && obj.get("text").isJsonPrimitive) {
message.text = obj.get("text").asString
}
if (obj.has("timestamp")) {
message.timestamp = obj.get("timestamp").asLong
}
if (obj.has("likes")) {
message.likes = RealmList()
for ((key, value) in obj.getAsJsonObject("likes").entrySet()) {
if (value.asBoolean) {
message.likes?.add(ChatMessageLike(key, message.id))
}
}
}
if (obj.has("flagCount")) {
message.flagCount = obj.get("flagCount").asInt
}
if (obj.has("uuid")) {
message.uuid = obj.get("uuid").asString
}
if (obj.has("contributor")) {
if (!obj.get("contributor").isJsonNull) {
if (obj.get("contributor").isJsonObject) {
message.contributor = context.deserialize<ContributorInfo>(obj.get("contributor"), ContributorInfo::class.java)
} else {
val contributor = ContributorInfo()
contributor.text = obj.get("contributor").asString
message.contributor = contributor
}
message.contributor?.userId = message.id
}
}
if (obj.has("backer")) {
message.backer = context.deserialize<Backer>(obj.get("backer"), Backer::class.java)
}
if (obj.has("user")) {
message.user = obj.get("user").asString
}
if (obj.has("sent")) {
message.sent = obj.get("sent").asString
}
return message
}
}

View file

@ -1,31 +0,0 @@
package com.habitrpg.android.habitica.utils;
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.social.ChatMessage;
import java.lang.reflect.Type;
import java.util.Map;
import io.realm.RealmList;
public class ChatMessageListDeserializer implements JsonDeserializer<RealmList<ChatMessage>> {
@Override
public RealmList<ChatMessage> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
RealmList<ChatMessage> messages = new RealmList<>();
if (json.isJsonArray()) {
for (JsonElement element : json.getAsJsonArray()) {
messages.add(context.deserialize(element, ChatMessage.class));
}
} else {
for (Map.Entry<String, JsonElement> entry : json.getAsJsonObject().entrySet()) {
messages.add(context.deserialize(entry.getValue(), ChatMessage.class));
}
}
return messages;
}
}

View file

@ -0,0 +1,30 @@
package com.habitrpg.android.habitica.utils
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.social.ChatMessage
import java.lang.reflect.Type
import io.realm.RealmList
class ChatMessageListDeserializer : JsonDeserializer<RealmList<ChatMessage>> {
@Throws(JsonParseException::class)
override fun deserialize(json: JsonElement, typeOfT: Type, context: JsonDeserializationContext): RealmList<ChatMessage> {
val messages = RealmList<ChatMessage>()
if (json.isJsonArray) {
json.asJsonArray.mapTo(messages) { context.deserialize(it, ChatMessage::class.java) }
} else {
for ((_, value) in json.asJsonObject.entrySet()) {
messages.add(context.deserialize(value, ChatMessage::class.java))
}
}
//Make sure the messageId is set for all likes
messages.forEach { it.id = it.id }
return messages
}
}

View file

@ -1,142 +0,0 @@
package com.habitrpg.android.habitica.utils;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.reflect.TypeToken;
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.social.Challenge;
import com.habitrpg.android.habitica.models.social.ChatMessage;
import com.habitrpg.android.habitica.models.social.UserParty;
import com.habitrpg.android.habitica.models.tasks.TasksOrder;
import com.habitrpg.android.habitica.models.user.Authentication;
import com.habitrpg.android.habitica.models.user.ContributorInfo;
import com.habitrpg.android.habitica.models.user.Flags;
import com.habitrpg.android.habitica.models.user.Inbox;
import com.habitrpg.android.habitica.models.user.Items;
import com.habitrpg.android.habitica.models.user.Preferences;
import com.habitrpg.android.habitica.models.user.Profile;
import com.habitrpg.android.habitica.models.user.Purchases;
import com.habitrpg.android.habitica.models.user.Stats;
import com.habitrpg.android.habitica.models.user.User;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import io.realm.Realm;
import io.realm.RealmList;
public class UserDeserializer implements JsonDeserializer<User> {
@Override
public User deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
User user = new User();
JsonObject obj = json.getAsJsonObject();
if (obj.has("_id")) {
user.setId(obj.get("_id").getAsString());
}
if (obj.has("balance")) {
user.setBalance(obj.get("balance").getAsDouble());
}
if (obj.has("stats")) {
user.setStats(context.deserialize(obj.get("stats"), Stats.class));
}
if (obj.has("inbox")) {
user.setInbox(context.deserialize(obj.get("inbox"), Inbox.class));
for (ChatMessage message : user.getInbox().getMessages()) {
message.isInboxMessage = true;
}
}
if (obj.has("preferences")) {
user.setPreferences(context.deserialize(obj.get("preferences"), Preferences.class));
}
if (obj.has("profile")) {
user.setProfile(context.deserialize(obj.get("profile"), Profile.class));
}
if (obj.has("party")) {
user.setParty(context.deserialize(obj.get("party"), UserParty.class));
if (user.getParty() != null && user.getParty().getQuest() != null) {
user.getParty().getQuest().setId(user.getId());
if (!obj.get("party").getAsJsonObject().get("quest").getAsJsonObject().has("RSVPNeeded")) {
Realm realm = Realm.getDefaultInstance();
Quest quest = realm.where(Quest.class).equalTo("id", user.getId()).findFirst();
if (quest != null && quest.isValid()) {
user.getParty().getQuest().setRSVPNeeded(quest.getRSVPNeeded());
}
}
}
}
if (obj.has("items")) {
user.setItems(context.deserialize(obj.get("items"), Items.class));
}
if (obj.has("auth")) {
user.setAuthentication(context.deserialize(obj.get("auth"), Authentication.class));
}
if (obj.has("flags")) {
user.setFlags(context.deserialize(obj.get("flags"), Flags.class));
}
if (obj.has("contributor")) {
user.setContributor(context.deserialize(obj.get("contributor"), ContributorInfo.class));
}
if (obj.has("invitations")) {
user.setInvitations(context.deserialize(obj.get("invitations"), Invitations.class));
}
if (obj.has("tags")) {
user.setTags(context.deserialize(obj.get("tags"), new TypeToken<RealmList<Tag>>() {
}.getType()));
for (Tag tag : user.getTags()) {
tag.userId = user.getId();
}
}
if (obj.has("tasksOrder")) {
user.setTasksOrder(context.deserialize(obj.get("tasksOrder"), TasksOrder.class));
}
if (obj.has("challenges")) {
user.setChallenges(context.deserialize(obj.get("challenges"), new TypeToken<List<Challenge>>() {
}.getType()));
}
if (obj.has("purchased")) {
user.setPurchased(context.deserialize(obj.get("purchased"), Purchases.class));
if (obj.get("purchased").getAsJsonObject().has("plan")) {
if (obj.get("purchased").getAsJsonObject().get("plan").getAsJsonObject().has("mysteryItems")) {
user.getPurchased().getPlan().mysteryItemCount = obj.get("purchased").getAsJsonObject().get("plan").getAsJsonObject().get("mysteryItems").getAsJsonArray().size();
}
}
}
if (obj.has("pushDevices")) {
user.setPushDevices(new ArrayList<>());
for (JsonElement entry : obj.getAsJsonArray("pushDevices")) {
PushDevice pushDevice = context.deserialize(entry, PushDevice.class);
user.getPushDevices().add(pushDevice);
}
}
if (obj.has("lastCron")) {
user.setLastCron(context.deserialize(obj.get("lastCron"), Date.class));
}
if (obj.has("needsCron")) {
user.setNeedsCron(obj.get("needsCron").getAsBoolean());
}
if (obj.has("achievements")) {
if (obj.getAsJsonObject("achievements").has("streak")) {
try {
user.setStreakCount(obj.getAsJsonObject("achievements").get("streak").getAsInt());
} catch (UnsupportedOperationException ignored) {}
}
}
return user;
}
}

View file

@ -0,0 +1,128 @@
package com.habitrpg.android.habitica.utils
import com.google.gson.JsonDeserializationContext
import com.google.gson.JsonDeserializer
import com.google.gson.JsonElement
import com.google.gson.JsonParseException
import com.google.gson.reflect.TypeToken
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.social.Challenge
import com.habitrpg.android.habitica.models.social.UserParty
import com.habitrpg.android.habitica.models.tasks.TasksOrder
import com.habitrpg.android.habitica.models.user.*
import io.realm.Realm
import io.realm.RealmList
import java.lang.reflect.Type
import java.util.*
class UserDeserializer : JsonDeserializer<User> {
@Throws(JsonParseException::class)
override fun deserialize(json: JsonElement, typeOfT: Type, context: JsonDeserializationContext): User {
val user = User()
val obj = json.asJsonObject
if (obj.has("_id")) {
user.id = obj.get("_id").asString
}
if (obj.has("balance")) {
user.balance = obj.get("balance").asDouble
}
if (obj.has("stats")) {
user.stats = context.deserialize(obj.get("stats"), Stats::class.java)
}
if (obj.has("inbox")) {
user.inbox = context.deserialize(obj.get("inbox"), Inbox::class.java)
for (message in user.inbox.messages) {
message.isInboxMessage = true
}
}
if (obj.has("preferences")) {
user.preferences = context.deserialize(obj.get("preferences"), Preferences::class.java)
}
if (obj.has("profile")) {
user.profile = context.deserialize(obj.get("profile"), Profile::class.java)
}
if (obj.has("party")) {
user.party = context.deserialize(obj.get("party"), UserParty::class.java)
if (user.party != null && user.party.quest != null) {
user.party.quest.id = user.id
if (!obj.get("party").asJsonObject.get("quest").asJsonObject.has("RSVPNeeded")) {
val realm = Realm.getDefaultInstance()
val quest = realm.where(Quest::class.java).equalTo("id", user.id).findFirst()
if (quest != null && quest.isValid) {
user.party.quest.RSVPNeeded = quest.RSVPNeeded
}
}
}
}
if (obj.has("items")) {
user.items = context.deserialize(obj.get("items"), Items::class.java)
}
if (obj.has("auth")) {
user.authentication = context.deserialize(obj.get("auth"), Authentication::class.java)
}
if (obj.has("flags")) {
user.flags = context.deserialize(obj.get("flags"), Flags::class.java)
}
if (obj.has("contributor")) {
user.contributor = context.deserialize(obj.get("contributor"), ContributorInfo::class.java)
}
if (obj.has("invitations")) {
user.invitations = context.deserialize(obj.get("invitations"), Invitations::class.java)
}
if (obj.has("tags")) {
user.tags = context.deserialize(obj.get("tags"), object : TypeToken<RealmList<Tag>>() {
}.type)
for (tag in user.tags) {
tag.userId = user.id
}
}
if (obj.has("tasksOrder")) {
user.tasksOrder = context.deserialize(obj.get("tasksOrder"), TasksOrder::class.java)
}
if (obj.has("challenges")) {
user.challenges = context.deserialize(obj.get("challenges"), object : TypeToken<RealmList<Challenge>>() {}.type)
}
if (obj.has("purchased")) {
user.purchased = context.deserialize(obj.get("purchased"), Purchases::class.java)
if (obj.get("purchased").asJsonObject.has("plan")) {
if (obj.get("purchased").asJsonObject.get("plan").asJsonObject.has("mysteryItems")) {
user.purchased.plan.mysteryItemCount = obj.get("purchased").asJsonObject.get("plan").asJsonObject.get("mysteryItems").asJsonArray.size()
}
}
}
if (obj.has("pushDevices")) {
user.pushDevices = ArrayList()
obj.getAsJsonArray("pushDevices")
.map { context.deserialize<PushDevice>(it, PushDevice::class.java) }
.forEach { user.pushDevices.add(it) }
}
if (obj.has("lastCron")) {
user.lastCron = context.deserialize(obj.get("lastCron"), Date::class.java)
}
if (obj.has("needsCron")) {
user.needsCron = obj.get("needsCron").asBoolean
}
if (obj.has("achievements")) {
if (obj.getAsJsonObject("achievements").has("streak")) {
try {
user.streakCount = obj.getAsJsonObject("achievements").get("streak").asInt
} catch (ignored: UnsupportedOperationException) {
}
}
}
return user
}
}

View file

@ -44,7 +44,7 @@ public class SocialAPITests extends BaseAPITests {
testSubscriber.assertNoErrors();
testSubscriber.assertCompleted();
PostChatMessageResult result = testSubscriber.getOnNextEvents().get(0);
messagesIDs.add(result.message.id);
messagesIDs.add(result.message.getId());
}
/*@Test