diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ApiClientImpl.java b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ApiClientImpl.java index 933fa394f..d0c59a880 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ApiClientImpl.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ApiClientImpl.java @@ -240,6 +240,7 @@ public class ApiClientImpl implements Action1, ApiClient { Type questCollectListType = new TypeToken>() {}.getType(); Type chatMessageListType = new TypeToken>() {}.getType(); Type challengeListType = new TypeToken>() {}.getType(); + Type challengeRealmListType = new TypeToken>() {}.getType(); Type questDropItemListType = new TypeToken>() {}.getType(); //Exclusion strategy needed for DBFlow https://github.com/Raizlabs/DBFlow/issues/121 @@ -273,6 +274,7 @@ public class ApiClientImpl implements Action1, 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()) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmSocialLocalRepository.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmSocialLocalRepository.kt index 498e5a33e..8b98d9dfb 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmSocialLocalRepository.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmSocialLocalRepository.kt @@ -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() - 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 { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/social/ChatMessage.java b/Habitica/src/main/java/com/habitrpg/android/habitica/models/social/ChatMessage.java deleted file mode 100644 index 377de072e..000000000 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/models/social/ChatMessage.java +++ /dev/null @@ -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 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; - } -} - diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/social/ChatMessage.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/models/social/ChatMessage.kt new file mode 100644 index 000000000..13adce0ff --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/models/social/ChatMessage.kt @@ -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? = 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 + } +} + diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/social/ChatMessageLike.java b/Habitica/src/main/java/com/habitrpg/android/habitica/models/social/ChatMessageLike.java deleted file mode 100644 index a390bca5f..000000000 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/models/social/ChatMessageLike.java +++ /dev/null @@ -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(); - } -} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/social/ChatMessageLike.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/models/social/ChatMessageLike.kt new file mode 100644 index 000000000..5da625807 --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/models/social/ChatMessageLike.kt @@ -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() +} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/ContributorInfo.java b/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/ContributorInfo.java index 24af33960..1eb1589a5 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/ContributorInfo.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/ContributorInfo.java @@ -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 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); } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/ChatRecyclerViewAdapter.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/ChatRecyclerViewAdapter.java index 4a300e5e3..e3a73d2ae 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/ChatRecyclerViewAdapter.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/ChatRecyclerViewAdapter.java @@ -149,7 +149,7 @@ public class ChatRecyclerViewAdapter extends RealmRecyclerViewAdapter 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 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); } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/utils/ChatMessageDeserializer.java b/Habitica/src/main/java/com/habitrpg/android/habitica/utils/ChatMessageDeserializer.java deleted file mode 100644 index 0af1c5b0b..000000000 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/utils/ChatMessageDeserializer.java +++ /dev/null @@ -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 { - @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 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; - } -} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/utils/ChatMessageDeserializer.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/utils/ChatMessageDeserializer.kt new file mode 100644 index 000000000..746f139f6 --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/utils/ChatMessageDeserializer.kt @@ -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 { + @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(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(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 + } +} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/utils/ChatMessageListDeserializer.java b/Habitica/src/main/java/com/habitrpg/android/habitica/utils/ChatMessageListDeserializer.java deleted file mode 100644 index 11403996c..000000000 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/utils/ChatMessageListDeserializer.java +++ /dev/null @@ -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> { - @Override - public RealmList deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { - RealmList messages = new RealmList<>(); - - if (json.isJsonArray()) { - for (JsonElement element : json.getAsJsonArray()) { - messages.add(context.deserialize(element, ChatMessage.class)); - } - } else { - for (Map.Entry entry : json.getAsJsonObject().entrySet()) { - messages.add(context.deserialize(entry.getValue(), ChatMessage.class)); - } - } - - return messages; - } -} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/utils/ChatMessageListDeserializer.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/utils/ChatMessageListDeserializer.kt new file mode 100644 index 000000000..3628f9789 --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/utils/ChatMessageListDeserializer.kt @@ -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> { + @Throws(JsonParseException::class) + override fun deserialize(json: JsonElement, typeOfT: Type, context: JsonDeserializationContext): RealmList { + val messages = RealmList() + + 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 + } +} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/utils/UserDeserializer.java b/Habitica/src/main/java/com/habitrpg/android/habitica/utils/UserDeserializer.java deleted file mode 100644 index f6bc18a57..000000000 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/utils/UserDeserializer.java +++ /dev/null @@ -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 { - @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>() { - }.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>() { - }.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; - } -} \ No newline at end of file diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/utils/UserDeserializer.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/utils/UserDeserializer.kt new file mode 100644 index 000000000..ea2636904 --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/utils/UserDeserializer.kt @@ -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 { + @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>() { + + }.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>() {}.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(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 + } +} \ No newline at end of file diff --git a/Habitica/src/test/java/com/habitrpg/android/habitica/api/SocialAPITests.java b/Habitica/src/test/java/com/habitrpg/android/habitica/api/SocialAPITests.java index 82a07746f..8676d5bfc 100644 --- a/Habitica/src/test/java/com/habitrpg/android/habitica/api/SocialAPITests.java +++ b/Habitica/src/test/java/com/habitrpg/android/habitica/api/SocialAPITests.java @@ -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