Removed unused resources

refactoring
unread messages view
unread counter
avatar in toolbar
This commit is contained in:
2021-09-12 03:39:28 +03:00
parent f7c8d6e1c8
commit da21035fba
210 changed files with 803 additions and 6736 deletions
@@ -1,9 +0,0 @@
package com.meloda.fast.api
import com.meloda.fast.api.loader.UsersLoader
object LoadManager {
val users = UsersLoader()
}
@@ -1,5 +1,6 @@
package com.meloda.fast.api
import androidx.lifecycle.MutableLiveData
import com.meloda.fast.api.model.VkUser
import com.meloda.fast.common.AppGlobal
@@ -31,6 +32,6 @@ object UserConfig {
fun isLoggedIn() = userId > 0 && accessToken.isNotBlank()
var vkUser: VkUser? = null
val vkUser = MutableLiveData<VkUser?>(null)
}
@@ -1,16 +1,30 @@
package com.meloda.fast.api
import android.content.Context
import android.graphics.drawable.Drawable
import androidx.core.content.ContextCompat
import com.meloda.fast.R
import com.meloda.fast.api.model.VkGroup
import com.meloda.fast.api.model.VkGroupCall
import com.meloda.fast.api.model.VkMessage
import com.meloda.fast.api.model.VkUser
import com.meloda.fast.api.model.attachments.*
import com.meloda.fast.api.model.base.BaseVkMessage
import com.meloda.fast.api.model.base.attachments.BaseVkAttachmentItem
import com.meloda.fast.api.network.VKErrors
object VkUtils {
fun isValidationRequired(throwable: Throwable): Boolean {
if (throwable !is VKException) return false
return throwable.error == VKErrors.NEED_VALIDATION
}
fun isCaptchaRequired(throwable: Throwable): Boolean {
if (throwable !is VKException) return false
return throwable.error == VKErrors.NEED_CAPTCHA
}
fun parseForwards(baseForwards: List<BaseVkMessage>?): List<VkMessage>? {
if (baseForwards.isNullOrEmpty()) return null
@@ -114,6 +128,12 @@ object VkUtils {
initiatorId = call.initiatorId
)
}
BaseVkAttachmentItem.AttachmentType.GROUP_CALL_IN_PROGRESS -> {
val groupCall = baseAttachment.groupCall ?: continue
attachments += VkGroupCall(
initiatorId = groupCall.initiatorId
)
}
else -> continue
}
}
@@ -315,6 +335,52 @@ object VkUtils {
}
}
fun getAttachmentConversationIcon(context: Context, message: VkMessage): Drawable? {
message.geoType?.let {
return ContextCompat.getDrawable(context, R.drawable.ic_map_marker)
}
if (message.attachments.isNullOrEmpty()) return null
return message.attachments?.let { attachments ->
if (attachments.size == 1 || isAttachmentsHaveOneType(attachments)) {
getAttachmentTypeByClass(attachments[0])?.let {
getAttachmentIconByType(
context,
it
)
}
} else {
ContextCompat.getDrawable(context, R.drawable.ic_baseline_attach_file_24)
}
}
}
fun getAttachmentIconByType(
context: Context,
attachmentType: BaseVkAttachmentItem.AttachmentType
): Drawable? {
val resId = when (attachmentType) {
BaseVkAttachmentItem.AttachmentType.PHOTO -> R.drawable.ic_attachment_photo
BaseVkAttachmentItem.AttachmentType.VIDEO -> R.drawable.ic_attachment_video
BaseVkAttachmentItem.AttachmentType.AUDIO -> R.drawable.ic_attachment_audio
BaseVkAttachmentItem.AttachmentType.FILE -> R.drawable.ic_attachment_file
BaseVkAttachmentItem.AttachmentType.LINK -> R.drawable.ic_attachment_link
BaseVkAttachmentItem.AttachmentType.VOICE -> R.drawable.ic_attachment_voice
BaseVkAttachmentItem.AttachmentType.MINI_APP -> R.drawable.ic_attachment_mini_app
BaseVkAttachmentItem.AttachmentType.STICKER -> R.drawable.ic_attachment_sticker
BaseVkAttachmentItem.AttachmentType.GIFT -> R.drawable.ic_attachment_gift
BaseVkAttachmentItem.AttachmentType.WALL -> R.drawable.ic_attachment_wall
BaseVkAttachmentItem.AttachmentType.GRAFFITI -> R.drawable.ic_attachment_graffiti
BaseVkAttachmentItem.AttachmentType.POLL -> R.drawable.ic_attachment_poll
BaseVkAttachmentItem.AttachmentType.WALL_REPLY -> R.drawable.ic_attachment_wall_reply
BaseVkAttachmentItem.AttachmentType.CALL -> R.drawable.ic_attachment_call
BaseVkAttachmentItem.AttachmentType.GROUP_CALL_IN_PROGRESS -> R.drawable.ic_attachment_group_call
}
return ContextCompat.getDrawable(context, resId)
}
fun isAttachmentsHaveOneType(attachments: List<VkAttachment>): Boolean {
if (attachments.isEmpty()) return true
if (attachments.size == 1) return true
@@ -344,6 +410,7 @@ object VkUtils {
is VkPoll -> BaseVkAttachmentItem.AttachmentType.POLL
is VkWallReply -> BaseVkAttachmentItem.AttachmentType.WALL_REPLY
is VkCall -> BaseVkAttachmentItem.AttachmentType.CALL
is VkGroupCall -> BaseVkAttachmentItem.AttachmentType.GROUP_CALL_IN_PROGRESS
else -> null
}
}
@@ -1,8 +0,0 @@
package com.meloda.fast.api.loader
abstract class Loader<T> {
abstract suspend fun load(params: MutableMap<String, Any>): List<T>
abstract suspend fun loadSingle(params: MutableMap<String, Any>): T
}
@@ -1,35 +0,0 @@
package com.meloda.fast.api.loader
import com.meloda.fast.api.model.VkUser
class UsersLoader : Loader<VkUser>() {
suspend fun load(
usersIds: List<Int>,
fields: String = ""
) = load(
mutableMapOf(
"usersIds" to usersIds.joinToString { it.toString() },
"fields" to fields
)
)
override suspend fun load(params: MutableMap<String, Any>): List<VkUser> {
val usersIds: String = params["usersIds"] as String
val fields: String = params["fields"] as String
// val users = repo.getById(
// UsersGetRequest(
// usersIds = usersIds.split(",").map { it.toInt() },
// fields = fields
// )
// )
return emptyList()
}
override suspend fun loadSingle(params: MutableMap<String, Any>): VkUser {
return load(params)[0]
}
}
@@ -11,7 +11,14 @@ data class VkConversation(
val title: String?,
val photo200: String?,
val type: String,
val callInProgress: Boolean
val callInProgress: Boolean,
val isPhantom: Boolean,
val lastConversationMessageId: Int,
val inRead: Int,
val outRead: Int,
val isMarkedUnread: Boolean,
val lastMessageId: Int,
val unreadCount: Int?
) {
@Ignore
var lastMessage: VkMessage? = null
@@ -20,4 +27,9 @@ data class VkConversation(
fun isUser() = type == "user"
fun isGroup() = type == "group"
fun isInUnread() = inRead != lastMessageId
fun isOutUnread() = outRead != lastMessageId
fun isUnread() = isInUnread() || isOutUnread()
}
@@ -0,0 +1,7 @@
package com.meloda.fast.api.model
import com.meloda.fast.api.model.attachments.VkAttachment
data class VkGroupCall(
val initiatorId: Int
) : VkAttachment()
@@ -33,7 +33,9 @@ data class BaseVkConversation(
@SerializedName("chat_settings")
val chatSettings: ChatSettings?,
@SerializedName("call_in_progress")
val callInProgress: CallInProgress?
val callInProgress: CallInProgress?,
@SerializedName("unread_count")
val unreadCount: Int?
) : Parcelable {
fun asVkConversation(lastMessage: VkMessage? = null) = VkConversation(
@@ -41,7 +43,14 @@ data class BaseVkConversation(
title = chatSettings?.title,
photo200 = chatSettings?.photo?.photo200,
type = peer.type,
callInProgress = callInProgress != null
callInProgress = callInProgress != null,
isPhantom = chatSettings?.isDisappearing == true,
lastConversationMessageId = lastConversationMessageId,
inRead = inRead,
outRead = outRead,
isMarkedUnread = isMarkedUnread,
lastMessageId = lastMessageId,
unreadCount = unreadCount
).apply { this.lastMessage = lastMessage }
@Parcelize
@@ -24,7 +24,9 @@ data class BaseVkAttachmentItem(
val poll: BaseVkPoll?,
@SerializedName("wall_reply")
val wallReply: BaseVkWallReply?,
val call: BaseVkCall?
val call: BaseVkCall?,
@SerializedName("group_call_in_progress")
val groupCall: BaseVkGroupCall?
) : Parcelable {
fun getPreparedType() = AttachmentType.parse(type)
@@ -43,7 +45,8 @@ data class BaseVkAttachmentItem(
GRAFFITI("graffiti"),
POLL("poll"),
WALL_REPLY("wall_reply"),
CALL("call")
CALL("call"),
GROUP_CALL_IN_PROGRESS("group_call_in_progress")
;
companion object {
@@ -0,0 +1,22 @@
package com.meloda.fast.api.model.base.attachments
import android.os.Parcelable
import com.google.gson.annotations.SerializedName
import kotlinx.parcelize.Parcelize
@Parcelize
data class BaseVkGroupCall(
@SerializedName("initiator_id")
val initiatorId: Int,
@SerializedName("join_link")
val joinLink: String,
val participants: Participants
) : Parcelable {
@Parcelize
data class Participants(
val list: List<Int>,
val count: Int
) : Parcelable
}
@@ -1,76 +0,0 @@
package com.meloda.fast.api.model.old
import org.json.JSONArray
import java.util.*
object VKAttachments {
fun parse(array: JSONArray): ArrayList<VKModel> {
val attachments = ArrayList<VKModel>(array.length())
for (i in 0 until array.length()) {
var attachment = array.optJSONObject(i) ?: continue
if (attachment.has("attachment")) {
attachment = attachment.optJSONObject("attachment") ?: continue
}
val type = Type.fromString(attachment.optString("type"))
val jsonObject = attachment.optJSONObject(type.value) ?: continue
when (type) {
// Type.PHOTO -> attachments.add(oldVKPhoto(jsonObject))
// Type.AUDIO -> attachments.add(oldVKAudio(jsonObject))
// Type.VIDEO -> attachments.add(oldVKVideo(jsonObject))
// Type.DOCUMENT -> attachments.add(oldVKDocument(jsonObject))
// Type.STICKER -> attachments.add(oldVKSticker(jsonObject))
// Type.LINK -> attachments.add(oldVKLink(jsonObject))
// Type.GIFT -> attachments.add(VKGift(jsonObject))
// Type.VOICE_MESSAGE -> attachments.add(oldVKAudioMessage(jsonObject))
// Type.GRAFFITI -> attachments.add(VKGraffiti(jsonObject))
Type.POLL -> attachments.add(oldVKPoll(jsonObject))
Type.CALL -> attachments.add(VKCall(jsonObject))
// Type.WALL_POST -> attachments.add(VKWall(jsonObject))
Type.WALL_REPLY -> attachments.add(oldVKComment(jsonObject))
// Type.GEOLOCATION -> attachments.add(oldVKGeolocation(jsonObject))
else -> continue
}
}
return attachments
}
enum class Type(val value: String) {
NONE("none"),
PHOTO("photo"),
VIDEO("video"),
AUDIO("audio"),
AUDIO_PLAYLIST("audio_playlist"),
DOCUMENT("doc"),
LINK("link"),
STICKER("sticker"),
GIFT("gift"),
VOICE_MESSAGE("audio_message"),
GRAFFITI("graffiti"),
POLL("poll"),
GEOLOCATION("geo"),
WALL_POST("wall"),
WALL_REPLY("wall_reply"),
CALL("call"),
STORY("story"),
POINT("point"),
MARKET("market"),
ARTICLE("article"),
PODCAST("podcast"),
MONEY_REQUEST("money_request");
companion object {
fun fromString(value: String): Type {
for (v in values()) {
if (v.value == value) return v
}
return NONE
}
}
}
}
@@ -1,38 +0,0 @@
package com.meloda.fast.api.model.old
import org.json.JSONObject
class VKCall() : VKModel() {
companion object {
const val serialVersionUID: Long = 1L
}
override val attachmentType = VKAttachments.Type.CALL
var initiatorId: Int = 0
var receiverId: Int = 0
var state: State = State.NONE
var time: Int = 0
var duration: Int = 0
constructor(o: JSONObject) : this() {
initiatorId = o.optInt("initiator_id", -1)
receiverId = o.optInt("receiver_id", -1)
state = State.fromString(o.optString("state"))
time = o.optInt("time")
duration = o.optInt("duration")
}
enum class State(val value: String) {
NONE("none"),
REACHED("reached"),
CANCELLED_INITIATOR("canceled_by_initiator"),
CANCELLED_RECEIVER("canceled_by_receiver");
companion object {
fun fromString(value: String) = values().first { it.value == value }
}
}
}
@@ -1,14 +0,0 @@
package com.meloda.fast.api.model.old
import java.util.*
class VKLongPollHistory : VKModel() {
override val attachmentType = VKAttachments.Type.NONE
private val lpMessages: ArrayList<oldVKMessage>? = null
private val messages: ArrayList<oldVKMessage>? = null
private val profiles: ArrayList<oldVKUser>? = null
private val groups: ArrayList<oldVKGroup>? = null //TODO: использовать
}
@@ -1,19 +0,0 @@
package com.meloda.fast.api.model.old
import org.json.JSONObject
class VKLongPollServer() : VKModel() {
override val attachmentType = VKAttachments.Type.NONE
var key: String = ""
var server: String = ""
var ts: Long = 0
constructor(o: JSONObject) : this() {
key = o.optString("key")
server = o.optString("server").replace("\\", "")
ts = o.optLong("ts")
}
}
@@ -1,15 +0,0 @@
package com.meloda.fast.api.model.old
import com.meloda.fast.api.model.old.VKAttachments
import com.meloda.fast.base.adapter.BaseItem
import java.io.Serializable
abstract class VKModel : BaseItem(), Serializable {
abstract val attachmentType: VKAttachments.Type
companion object {
const val serialVersionUID = 1L
}
}
@@ -1,31 +0,0 @@
package com.meloda.fast.api.model.old
import org.json.JSONObject
class oldVKAudio() : VKModel() {
companion object {
const val serialVersionUID: Long = 1L
}
override val attachmentType = VKAttachments.Type.AUDIO
var id: Int = 0
var ownerId: Int = 0
var artist: String = ""
var title: String = ""
var duration: Int = 0
var url: String = ""
var date: Int = 0
constructor(o: JSONObject) : this() {
id = o.optInt("id", -1)
ownerId = o.optInt("owner_id", -1)
artist = o.optString("artist")
title = o.optString("title")
duration = o.optInt("duration")
url = o.optString("url")
date = o.optInt("date")
}
}
@@ -1,31 +0,0 @@
package com.meloda.fast.api.model.old
import org.json.JSONObject
class oldVKAudioMessage() : VKModel() {
companion object {
const val serialVersionUID: Long = 1L
}
override val attachmentType = VKAttachments.Type.VOICE_MESSAGE
var duration: Int = 0
var waveform: ArrayList<Int> = arrayListOf()
var linkOgg: String = ""
var linkMp3: String = ""
constructor(o: JSONObject) : this() {
duration = o.optInt("duration")
linkOgg = o.optString("link_ogg")
linkMp3 = o.optString("link_mp3")
o.optJSONArray("waveform")?.let {
val waveform = ArrayList<Int>()
for (i in 0 until it.length()) {
waveform.add(it.optInt(i))
}
this.waveform = waveform
}
}
}
@@ -1,15 +0,0 @@
package com.meloda.fast.api.model.old
import org.json.JSONObject
class oldVKComment() : VKModel() { //https://vk.com/dev/objects/comment
companion object {
const val serialVersionUID: Long = 1L
}
override val attachmentType = VKAttachments.Type.WALL_REPLY
constructor(o: JSONObject) : this() {}
}
@@ -1,156 +0,0 @@
package com.meloda.fast.api.model.old
import org.json.JSONObject
class oldVKConversation() : VKModel(), Cloneable {
override val attachmentType = VKAttachments.Type.NONE
companion object {
const val serialVersionUID: Long = 1L
var profiles = arrayListOf<oldVKUser>()
var groups = arrayListOf<oldVKGroup>()
var conversationsCount: Int = 0
var count: Int = 0
}
var isAllowed: Boolean = false
var notAllowedReason: Reason = Reason.NULL
var inReadMessageId: Int = 0
var outReadMessageId: Int = 0
var lastMessageId: Int = 0
var unreadCount: Int = 0
var id: Int = 0
var intType: Int = 0
var type: Type = Type.NULL
var localId: Int = 0
var notificationsEnabled: Boolean = false
var disabledUntil: Int = 0
var isDisabledForever: Boolean = false
var isNoSound: Boolean = false
var membersCount: Int = 0
var title: String? = null
var pinnedMessage: oldVKMessage? = null
var intState: Int = 0
var state: State = State.IN
var lastMessage: oldVKMessage = oldVKMessage()
var isGroupChannel: Boolean = false
var photo50: String = ""
var photo100: String = ""
var photo200: String = ""
var peerUser: oldVKUser? = null
var peerGroup: oldVKGroup? = null
constructor(o: JSONObject) : this() {
inReadMessageId = o.optInt("in_read")
outReadMessageId = o.optInt("out_read")
lastMessageId = o.optInt("last_message_id", -1)
unreadCount = o.optInt("unread_count", 0)
o.optJSONObject("peer")?.let {
id = it.optInt("id", -1)
type = Type.fromString(it.optString("type"))
localId = it.optInt("local_id")
}
o.optJSONObject("push_settings")?.let {
disabledUntil = it.optInt("disabled_until")
isDisabledForever = it.optBoolean("disabled_forever")
isNoSound = it.optBoolean("no_sound")
}
o.optJSONObject("can_write")?.let {
isAllowed = it.optBoolean("allowed")
notAllowedReason = Reason.fromInt(it.optInt("reason", -1))
}
o.optJSONObject("chat_settings")?.let {
membersCount = it.optInt("members_count")
title = it.optString("title")
if (title?.isBlank() == true) title = null
it.optJSONObject("pinned_message")?.let { pinned ->
pinnedMessage = oldVKMessage(pinned)
}
state = State.fromString(it.optString("state"))
it.optJSONObject("photo")?.let { photo ->
photo50 = photo.optString("photo_50")
photo100 = photo.optString("photo_100")
photo200 = photo.optString("photo_200")
}
isGroupChannel = it.optBoolean("is_group_channel")
}
}
fun isNotificationsDisabled() = (isDisabledForever || disabledUntil > 0 || isNoSound)
fun isChat() = type == Type.CHAT
fun isUser() = type == Type.USER
fun isGroup() = type == Type.GROUP
override fun toString() = title ?: ""
public override fun clone() = super.clone() as oldVKConversation
enum class Type(val value: String) {
NULL("null"),
USER("user"),
CHAT("chat"),
GROUP("group");
companion object {
fun fromString(value: String) = values().first { it.value == value }
}
}
enum class State(val value: String) {
IN("in"),
KICKED("kicked"),
LEFT("left");
companion object {
fun fromString(value: String) = values().first { it.value == value }
}
}
enum class Reason(val value: Int) {
NULL(-1),
U(0),
BLOCKED_DELETED(18),
BLACKLISTED(900),
BLOCKED_GROUP_MESSAGES(901),
PRIVACY_SETTINGS(902),
GROUP_DISABLED_MESSAGES(915),
GROUP_BLOCKED_MESSAGES(916),
NO_ACCESS_CHAT(917),
NO_ACCESS_EMAIL(918),
U1(925),
NO_ACCESS_COMMUNITY(203);
companion object {
fun fromInt(value: Int) = values().first { it.value == value }
}
}
}
@@ -1,101 +0,0 @@
package com.meloda.fast.api.model.old
import org.json.JSONObject
import java.io.Serializable
import java.util.*
class oldVKDocument() : VKModel() {
override val attachmentType = VKAttachments.Type.DOCUMENT
companion object {
const val serialVersionUID: Long = 1L
}
var id: Int = 0
var ownerId: Int = 0
var title: String = ""
var size: Int = 0
var ext: String = ""
var url: String = ""
var date: Int = 0
var type: Type = Type.UNKNOWN
var preview: Preview? = null
constructor(o: JSONObject) : this() {
id = o.optInt("id", -1)
ownerId = o.optInt("owner_id", -1)
title = o.optString("title")
size = o.optInt("size")
ext = o.optString("ext")
url = o.optString("url")
date = o.optInt("date")
type = Type.fromInt(o.optInt("type"))
o.optJSONObject("preview")?.let {
preview = Preview(it)
}
}
class Preview(o: JSONObject) : Serializable {
companion object {
const val serialVersionUID: Long = 1L
}
var photo: Photo? = null
var graffiti: Graffiti? = null
inner class Photo(o: JSONObject) : Serializable {
var sizes: ArrayList<oldVKPhotoSize>? = null
init {
o.optJSONArray("sizes")?.let {
val sizes = ArrayList<oldVKPhotoSize>()
for (i in 0 until it.length()) {
sizes.add(oldVKPhotoSize(it.optJSONObject(i)))
}
this.sizes = sizes
}
}
}
class Graffiti(o: JSONObject) : Serializable {
companion object {
const val serialVersionUID: Long = 1L
}
var src: String = o.optString("src")
var width: Int = o.optInt("width")
var height: Int = o.optInt("height")
}
init {
o.optJSONObject("photo")?.let {
photo = Photo(it)
}
o.optJSONObject("graffiti")?.let {
graffiti = Graffiti(it)
}
}
}
enum class Type(val value: Int) {
NONE(0),
TEXT(1),
ARCHIVE(2),
GIF(3),
IMAGE(4),
AUDIO(5),
VIDEO(6),
BOOK(7),
UNKNOWN(8);
companion object {
fun fromInt(value: Int) = values().first { it.value == value }
}
}
}
@@ -1,15 +0,0 @@
package com.meloda.fast.api.model.old
import org.json.JSONObject
class oldVKGeolocation() : VKModel() {
companion object {
const val serialVersionUID: Long = 1L
}
override val attachmentType = VKAttachments.Type.GEOLOCATION
constructor(o: JSONObject) : this() {}
}
@@ -1,25 +0,0 @@
package com.meloda.fast.api.model.old
import org.json.JSONObject
class oldVKGift() : VKModel() {
companion object {
const val serialVersionUID: Long = 1L
}
override val attachmentType = VKAttachments.Type.GIFT
var id: Int = 0
var thumb256: String = ""
var thumb96: String = ""
var thumb48: String = ""
constructor(o: JSONObject) : this() {
id = o.optInt("id", -1)
thumb256 = o.optString("thumb_256")
thumb96 = o.optString("thumb_96")
thumb48 = o.optString("thumb_48")
}
}
@@ -1,29 +0,0 @@
package com.meloda.fast.api.model.old
import org.json.JSONObject
class oldVKGraffiti() : VKModel() {
companion object {
const val serialVersionUID: Long = 1L
}
override val attachmentType = VKAttachments.Type.GRAFFITI
var id: Int = 0
var ownerId: Int = 0
var url: String = ""
var width: Int = 0
var height: Int = 0
var accessKey: String = ""
constructor(o: JSONObject) : this() {
id = o.optInt("id", -1)
ownerId = o.optInt("owner_id", -1)
url = o.optString("url")
width = o.optInt("width")
height = o.optInt("height")
accessKey = o.optString("access_key")
}
}
@@ -1,56 +0,0 @@
package com.meloda.fast.api.model.old
import org.json.JSONArray
import org.json.JSONObject
open class oldVKGroup() : VKModel() {
override val attachmentType = VKAttachments.Type.NONE
companion object {
const val serialVersionUID: Long = 1L
fun parse(array: JSONArray): ArrayList<oldVKGroup> {
val groups = ArrayList<oldVKGroup>()
for (i in 0 until array.length()) {
groups.add(oldVKGroup(array.optJSONObject(i)))
}
return groups
}
}
var id: Int = 0
var name: String = ""
var screenName: String = ""
var isClosed: Boolean = false
var deactivated: String = ""
var type: Type = Type.NULL
var photo50: String = ""
var photo100: String = ""
var photo200: String = ""
constructor(o: JSONObject) : this() {
id = o.optInt("id", -1)
name = o.optString("name")
screenName = o.optString("screen_name")
isClosed = o.optInt("is_closed") == 1
deactivated = o.optString("deactivated")
type = Type.fromString(o.optString("type"))
photo50 = o.optString("photo_50")
photo100 = o.optString("photo_100")
photo200 = o.optString("photo_200")
}
enum class Type(val value: String) {
NULL("null"),
GROUP("group"),
PAGE("page"),
EVENT("event");
companion object {
fun fromString(value: String) = values().first { it.value == value }
}
}
}
@@ -1,57 +0,0 @@
package com.meloda.fast.api.model.old
import org.json.JSONObject
import java.io.Serializable
class oldVKLink() : VKModel() {
companion object {
const val serialVersionUID: Long = 1L
}
override val attachmentType = VKAttachments.Type.LINK
var url: String = ""
var title: String = ""
var caption: String = ""
var description: String = ""
var previewPage: String = ""
var previewUrl: String = ""
var photo: oldVKPhoto? = null
var button: Button? = null
constructor(o: JSONObject): this() {
url = o.optString("url")
title = o.optString("title")
caption = o.optString("caption")
description = o.optString("description")
previewPage = o.optString("preview_page")
previewUrl = o.optString("preview_url")
o.optJSONObject("photo")?.let {
photo = oldVKPhoto(it)
}
o.optJSONObject("button")?.let {
button = Button(it)
}
}
class Button(o: JSONObject) : Serializable {
var title: String = o.optString("title")
var action: Action? = null
init {
o.optJSONObject("action")?.let {
action = Action(it)
}
}
class Action(o: JSONObject) : Serializable {
var type: String = o.optString("type")
var url: String = o.optString("url")
}
}
}
@@ -1,164 +0,0 @@
package com.meloda.fast.api.model.old
import android.util.ArrayMap
import com.meloda.fast.api.oldVKUtil
import org.json.JSONObject
open class oldVKMessage() : VKModel() {
override val attachmentType = VKAttachments.Type.NONE
companion object {
var profiles = arrayListOf<oldVKUser>()
var groups = arrayListOf<oldVKGroup>()
var conversations = arrayListOf<oldVKConversation>()
const val serialVersionUID: Long = 1L
var lastHistoryCount: Int = 0
const val UNREAD = 1 // Оно просто есть
const val OUTBOX = 1 shl 1 // Исходящее сообщение
const val REPLIED = 1 shl 2 // На сообщение был создан ответ
const val IMPORTANT = 1 shl 3 // Важное сообщение
const val FRIENDS = 1 shl 5 // Сообщение в чат друга
const val SPAM = 1 shl 6 // Сообщение помечено как спам
const val DELETED = 1 shl 7 // Удаление сообщения
const val AUDIO_LISTENED = 1 shl 12 // ГС прослушано
const val CHAT = 1 shl 13 // Сообщение отправлено в беседу
const val CANCEL_SPAM = 1 shl 15 // Отмена пометки спама
const val HIDDEN = 1 shl 16 // Приветственное сообщение сообщества
const val DELETE_FOR_ALL = 1 shl 17 // Сообщение удалено для всех
const val CHAT_IN = 1 shl 19 // Входящее сообщение в беседе
const val REPLY_MSG = 1 shl 21 // Ответ на сообщение
val flags = ArrayMap<String, Int>()
fun isOut(flags: Int): Boolean {
return OUTBOX and flags > 0
}
fun isDeleted(flags: Int): Boolean {
return DELETED and flags > 0
}
fun isUnread(flags: Int): Boolean {
return UNREAD and flags > 0
}
fun isSpam(flags: Int): Boolean {
return SPAM and flags > 0
}
fun isCanceledSpam(flags: Int): Boolean {
return CANCEL_SPAM and flags > 0
}
fun isImportant(flags: Int): Boolean {
return IMPORTANT and flags > 0
}
fun isDeletedForAll(flags: Int): Boolean {
return DELETE_FOR_ALL and flags > 0
}
init {
flags["unread"] = UNREAD
flags["outbox"] = OUTBOX
flags["replied"] = REPLIED
flags["important"] = IMPORTANT
flags["friends"] = FRIENDS
flags["spam"] = SPAM
flags["deleted"] = DELETED
flags["audio_listened"] = AUDIO_LISTENED
flags["chat"] = CHAT
flags["cancel_spam"] = CANCEL_SPAM
flags["hidden"] = HIDDEN
flags["delete_for_all"] = DELETE_FOR_ALL
flags["chat_in"] = CHAT_IN
flags["reply_msg"] = REPLY_MSG
}
}
var id: Int = 0
var date: Int = 0
var peerId: Int = 0
var fromId: Int = 0
var editTime: Int = 0
var isOut: Boolean = false
var text: String = ""
var randomId: Int = 0
var conversationMessageId: Int = 0
var hasEmoji: Boolean = false
var isImportant: Boolean = false
var isRead: Boolean = false
var attachments: ArrayList<VKModel> = arrayListOf()
var fwdMessages: ArrayList<oldVKMessage> = arrayListOf()
var replyMessage: oldVKMessage? = null
var action: oldVKMessageAction? = null
var fromUser: oldVKUser? = null
var fromGroup: oldVKGroup? = null
constructor(o: JSONObject) : this() {
id = o.optInt("id", -1)
date = o.optInt("date")
peerId = o.optInt("peer_id", -1)
fromId = o.optInt("from_id", -1)
editTime = o.optInt("edit_time", -1)
isOut = o.optInt("out") == 1
text = oldVKUtil.prepareMessageText(o.optString("text"))
randomId = o.optInt("random_id", -1)
conversationMessageId = o.optInt("conversation_message_id", -1)
isImportant = o.optBoolean("important")
o.optJSONArray("attachments")?.let {
attachments = VKAttachments.parse(it)
}
o.optJSONArray("fwd_messages")?.let {
val fwdMessages = ArrayList<oldVKMessage>(it.length())
for (i in 0 until it.length()) {
fwdMessages.add(oldVKMessage(it.optJSONObject(i)))
}
this.fwdMessages = fwdMessages
}
o.optJSONObject("reply_message")?.let {
replyMessage = oldVKMessage(it)
}
o.optJSONObject("action")?.let {
action = oldVKMessageAction(it)
}
}
fun getForwardedMessages() = ArrayList<oldVKMessage>().apply {
for (model in fwdMessages) add(model)
}
fun isFromUser() = fromId > 0
fun isFromGroup() = fromId < 0
fun isOutbox() = isOut
fun isInbox() = !isOutbox()
override fun toString(): String {
return if (text.isNotEmpty()) {
text
} else {
super.toString()
}
}
}
@@ -1,47 +0,0 @@
package com.meloda.fast.api.model.old
import org.json.JSONObject
class oldVKMessageAction() : VKModel() {
companion object {
const val serialVersionUID: Long = 1L
}
override val attachmentType = VKAttachments.Type.NONE
var type: Type = Type.NONE
var memberId = 0
var message: oldVKMessage? = null
var conversationMessageId: Int = 0
var text: String = ""
var oldText: String = ""
//TODO: add photo
constructor(o: JSONObject) : this() {
type = Type.fromString(o.optString("type"))
memberId = o.optInt("member_id", -1)
text = o.optString("text")
}
enum class Type(val value: String) {
NONE("none"),
CHAT_CREATE("chat_create"),
PHOTO_UPDATE("chat_photo_update"),
PHOTO_REMOVE("chat_photo_remove"),
TITLE_UPDATE("chat_title_update"),
PIN_MESSAGE("chat_pin_message"),
UNPIN_MESSAGE("chat_unpin_message"),
INVITE_USER("chat_invite_user"),
INVITE_USER_BY_LINK("chat_invite_user_by_link"),
KICK_USER("chat_kick_user"),
SCREENSHOT("chat_screenshot"),
INVITE_USER_BY_CALL("chat_invite_user_by_call"),
INVITE_USER_BY_CALL_LINK("chat_invite_user_by_call_link");
companion object {
fun fromString(value: String) = values().first { it.value == value }
}
}
}
@@ -1,40 +0,0 @@
package com.meloda.fast.api.model.old
import org.json.JSONObject
import java.util.*
class oldVKPhoto() : VKModel() {
companion object {
const val serialVersionUID: Long = 1L
}
override val attachmentType = VKAttachments.Type.PHOTO
var id: Int = 0
var albumId: Int = 0
var ownerId: Int = 0
var text: String = ""
var date: Int = 0
var width: Int = 0
var height: Int = 0
var sizes: ArrayList<oldVKPhotoSize>? = null
constructor(o: JSONObject) : this() {
id = o.optInt("id", -1)
albumId = o.optInt("album_id", -1)
ownerId = o.optInt("owner_id", -1)
text = o.optString("text")
date = o.optInt("date")
width = o.optInt("width")
height = o.optInt("height")
o.optJSONArray("sizes")?.let {
val sizes = ArrayList<oldVKPhotoSize>()
for (i in 0 until it.length()) {
sizes.add(oldVKPhotoSize(it.optJSONObject(i)))
}
this.sizes = sizes
}
}
}
@@ -1,18 +0,0 @@
package com.meloda.fast.api.model.old
import org.json.JSONObject
class oldVKPhotoSize(o: JSONObject) : VKModel() {
companion object {
const val serialVersionUID: Long = 1L
}
override val attachmentType = VKAttachments.Type.NONE
var type: String = o.optString("type")
var url: String = o.optString("url")
var height: Int = o.optInt("height")
var width: Int = o.optInt("width")
}
@@ -1,58 +0,0 @@
package com.meloda.fast.api.model.old
import org.json.JSONObject
class oldVKPoll() : VKModel() {
companion object {
const val serialVersionUID: Long = 1L
}
override val attachmentType = VKAttachments.Type.POLL
constructor(o: JSONObject): this() {}
// var id = o.optInt("id", -1)
// var ownerId = o.optInt("owner_id", -1)
// var created = o.optInt("created")
// var question: String = o.optString("question")
// var votes = o.optInt("votes")
// var answers = ArrayList<Answer>()
// var isAnonymous = o.optBoolean("anonymous")
// var isMultiple = o.optBoolean("multiple")
// var answerIds = ArrayList<Int>()
// var endDate = o.optInt("end_date")
// var isClosed = o.optBoolean("closed")
// var isBoard = o.optBoolean("is_board")
// var isCanEdit = o.optBoolean("can_edit")
// var isCanVote = false
// var isCanReport = false
// var isCanShare = false
// var authorId = 0
// var background = Color.WHITE
//TODO: private ArrayList friends
// init {
// o.optJSONArray("answers")?.let {
// val answers = ArrayList<Answer>()
// for (i in 0 until it.length()) {
// answers.add(Answer(it.optJSONObject(i)))
// }
// this.answers = answers
// }
// //setAnswerIds();
// // ...
// }
// class Answer(o: JSONObject) : Serializable {
// var id = o.optInt("id", -1)
// var text: String = o.optString("text")
// var votes = o.optInt("votes")
// var rate = o.optInt("rate")
// }
}
@@ -1,44 +0,0 @@
package com.meloda.fast.api.model.old
import org.json.JSONObject
import java.util.*
class oldVKSticker() : VKModel() {
companion object {
const val serialVersionUID: Long = 1L
}
override val attachmentType = VKAttachments.Type.STICKER
var productId: Int = 0
var stickerId: Int = 0
var images: ArrayList<Image>? = null
constructor(o: JSONObject) : this() {
productId = o.optInt("product_id", -1)
stickerId = o.optInt("sticker_id", -1)
o.optJSONArray("images")?.let {
val images = ArrayList<Image>()
for (i in 0 until it.length()) {
images.add(Image(it.optJSONObject(i)))
}
this.images = images
}
}
class Image(o: JSONObject) : VKModel() {
companion object {
const val serialVersionUID: Long = 1L
}
override val attachmentType = VKAttachments.Type.NONE
var url: String = o.optString("url")
var width = o.optInt("width")
var height = o.optInt("height")
}
}
@@ -1,80 +0,0 @@
package com.meloda.fast.api.model.old
import org.json.JSONArray
import org.json.JSONObject
open class oldVKUser() : VKModel() {
override val attachmentType = VKAttachments.Type.NONE
companion object {
const val serialVersionUID: Long = 1L
var friendsCount: Int = 0
fun parse(array: JSONArray): ArrayList<oldVKUser> {
val users = ArrayList<oldVKUser>()
for (i in 0 until array.length()) {
users.add(oldVKUser(array.optJSONObject(i)))
}
return users
}
}
var sortId: Int = 0
var userId: Int = 0
var firstName: String = ""
var lastName: String = ""
var deactivated: String = ""
var isClosed: Boolean = false
var isCanAccessClosed: Boolean = true
var sex: Int = 0
var screenName: String = ""
var photo50: String = ""
var photo100: String = ""
var photo200: String = ""
var isOnline: Boolean = false
var isOnlineMobile: Boolean = false
var status: String = ""
var lastSeen: Int = 0
var lastSeenPlatform: Int = 0
var isVerified: Boolean = false
constructor(o: JSONObject) : this() {
sortId = 0
userId = o.optInt("id", -1)
firstName = o.optString("first_name")
lastName = o.optString("last_name")
deactivated = o.optString("deactivated", "")
isClosed = o.optBoolean("is_closed")
isCanAccessClosed = o.optBoolean("can_access_closed")
sex = o.optInt("sex")
screenName = o.optString("screen_name")
photo50 = o.optString("photo_50")
photo100 = o.optString("photo_100")
photo200 = o.optString("photo_200")
isOnline = o.optInt("online") == 1
isOnlineMobile = isOnline && o.optInt("online_mobile") == 1
status = o.optString("status")
lastSeen = 0
lastSeenPlatform = 0
isVerified = o.optInt("verified") == 1
o.optJSONObject("last_seen")?.let {
lastSeen = it.optInt("time")
lastSeenPlatform = it.optInt("platform")
}
}
fun isDeactivated() = deactivated.isNotEmpty()
override fun toString(): String {
return "$firstName $lastName"
}
}
@@ -1,45 +0,0 @@
package com.meloda.fast.api.model.old
import com.meloda.fast.api.model.old.VKAttachments
import com.meloda.fast.api.model.old.VKModel
import org.json.JSONObject
class oldVKVideo() : VKModel() {
companion object {
const val serialVersionUID: Long = 1L
}
override val attachmentType = VKAttachments.Type.VIDEO
// var id = o.optInt("id", -1)
// var ownerId = o.optInt("owner_id", -1)
// var title: String = o.optString("title")
// var description: String = o.optString("description")
// var duration = o.optInt("duration", -1)
// var photo130: String = o.optString("photo_130")
// var photo320: String = o.optString("photo_320")
// var photo640: String = o.optString("photo_640")
// var photo800: String = o.optString("photo_800")
// var photo1280: String = o.optString("photo_1280")
// var firstFrame130: String = o.optString("first_frame_130")
// var firstFrame320: String = o.optString("first_frame_320")
// var firstFrame640: String = o.optString("first_frame_640")
// var firstFrame800: String = o.optString("first_frame_800")
// var firstFrame1280: String = o.optString("first_frame_1280")
// var date = o.optInt("date")
// var views = o.optInt("views")
// var comments = o.optInt("comments")
// var player: String = o.optString("player")
// var isCanEdit = o.optInt("can_edit", 0) == 1
// var isCanAdd = o.optInt("can_add") == 1
// var isPrivate = o.optInt("is_private", 0) == 1
// var accessKey: String = o.optString("access_key")
// var isProcessing = o.optInt("processing", 0) == 1
// var isLive = o.optInt("live", 0) == 1
// var isUpcoming = o.optInt("upcoming", 0) == 1
// var isFavorite = o.optBoolean("favorite")
constructor(o: JSONObject) : this() {}
}
@@ -1,15 +0,0 @@
package com.meloda.fast.api.model.old
import org.json.JSONObject
class oldVKWall() : VKModel() { //https://vk.com/dev/objects/post
companion object {
const val serialVersionUID: Long = 1L
}
override val attachmentType = VKAttachments.Type.WALL_POST
constructor(o: JSONObject) : this() {}
}
@@ -22,5 +22,5 @@ data class ConversationsGetResponse(
data class ConversationsResponseItems(
val conversation: BaseVkConversation,
@SerializedName("last_message")
val lastMessage: BaseVkMessage
val lastMessage: BaseVkMessage?
) : Parcelable
@@ -1,379 +0,0 @@
package com.meloda.fast.api
import androidx.annotation.WorkerThread
import com.meloda.fast.api.model.*
import com.meloda.fast.api.model.old.*
import com.meloda.fast.api.network.VKErrors
import org.json.JSONArray
import org.json.JSONObject
import java.text.SimpleDateFormat
import java.util.*
// TODO: 8/31/2021 review
object oldVKUtil {
private const val TAG = "VKUtil"
fun isValidationRequired(throwable: Throwable): Boolean {
if (throwable !is VKException) return false
return throwable.error == VKErrors.NEED_VALIDATION
}
fun isCaptchaRequired(throwable: Throwable): Boolean {
if (throwable !is VKException) return false
return throwable.error == VKErrors.NEED_CAPTCHA
}
fun sortMessagesByDate(
values: ArrayList<oldVKMessage>,
firstOnTop: Boolean
): ArrayList<oldVKMessage> {
values.sortWith { m1, m2 ->
val d1 = m1.date
val d2 = m2.date
if (firstOnTop) {
d2 - d1
} else {
d1 - d2
}
}
return values
}
fun sortConversationsByDate(
values: ArrayList<oldVKConversation>,
firstOnTop: Boolean
): ArrayList<oldVKConversation> {
values.sortWith { c1, c2 ->
val d1 = c1.lastMessage.date
val d2 = c2.lastMessage.date
return@sortWith if (firstOnTop) {
d2 - d1
} else {
d1 - d2
}
}
return values
}
fun prepareMessageText(message: String): String {
if (message.isEmpty()) return message
var newText = message
val mentions = hashMapOf<String, String>()
var startFrom = 0
while (true) {
val leftBracketIndex = newText.indexOf('[', startFrom)
val verticalLineIndex = newText.indexOf('|', startFrom)
val rightBracketIndex = newText.indexOf(']', startFrom)
if (leftBracketIndex == -1 ||
verticalLineIndex == -1 ||
rightBracketIndex == -1
) {
break
}
val id = newText.substring(leftBracketIndex + 1, verticalLineIndex)
if (!id.matches(Regex("^id(\\d+)\$")) || rightBracketIndex - verticalLineIndex < 2) {
break
}
val text = newText.substring(verticalLineIndex + 1, rightBracketIndex)
val str = "[$id|$text]"
mentions[str] = text
startFrom = rightBracketIndex + 1
}
mentions.forEach {
newText = newText.replace(it.key, it.value)
}
return newText
}
// fun removeTime(date: Date): Long {
// return Calendar.getInstance().apply {
// time = date
// this[Calendar.HOUR_OF_DAY] = 0
// this[Calendar.MINUTE] = 0
// this[Calendar.SECOND] = 0
// this[Calendar.MILLISECOND] = 0
// }.timeInMillis
// }
//TODO: нормальное время
fun getLastSeenTime(date: Long): String {
return SimpleDateFormat("HH:mm", Locale.getDefault()).format(date)
}
fun getTitle(
conversation: oldVKConversation,
peerUser: oldVKUser?,
peerGroup: oldVKGroup?
): String {
return when {
conversation.isUser() -> peerUser?.let { return it.toString() } ?: ""
conversation.isGroup() -> peerGroup?.let { return it.name } ?: ""
conversation.isChat() -> conversation.title ?: ""
else -> ""
}
}
fun getMessageTitle(
message: oldVKMessage,
fromUser: oldVKUser?,
fromGroup: oldVKGroup?
): String {
return when {
message.isFromUser() -> {
fromUser?.let { return it.toString() } ?: ""
}
message.isFromGroup() -> {
fromGroup?.let { return it.name } ?: ""
}
else -> ""
}
}
fun getAvatar(
conversation: oldVKConversation,
peerUser: oldVKUser?,
peerGroup: oldVKGroup?
): String {
return when {
conversation.isUser() -> {
peerUser?.let { return it.photo200 } ?: ""
}
conversation.isGroup() -> {
peerGroup?.let { return it.photo200 } ?: ""
}
conversation.isChat() -> {
conversation.photo200
}
else -> ""
}
}
fun getUserAvatar(
message: oldVKMessage,
fromUser: oldVKUser?,
fromGroup: oldVKGroup?
): String {
return when {
message.isFromUser() -> {
fromUser?.let { return it.photo100 } ?: ""
}
message.isFromGroup() -> {
fromGroup?.let { return it.photo100 } ?: ""
}
else -> ""
}
}
fun getUserPhoto(user: oldVKUser): String {
if (user.photo200.isEmpty()) {
if (user.photo100.isEmpty()) {
if (user.photo50.isEmpty()) {
return ""
}
} else {
return user.photo100
}
} else {
return user.photo200
}
return ""
}
fun getGroupPhoto(group: oldVKGroup): String {
if (group.photo200.isEmpty()) {
if (group.photo100.isEmpty()) {
if (group.photo50.isEmpty()) {
return ""
}
} else {
return group.photo100
}
} else {
return group.photo200
}
return ""
}
fun parseConversations(array: JSONArray): ArrayList<oldVKConversation> {
val conversations = arrayListOf<oldVKConversation>()
for (i in 0 until array.length()) {
conversations.add(oldVKConversation(array.optJSONObject(i)))
}
return conversations
}
fun parseMessages(array: JSONArray): ArrayList<oldVKMessage> {
val messages = arrayListOf<oldVKMessage>()
for (i in 0 until array.length()) {
messages.add(oldVKMessage(array.optJSONObject(i)))
}
return messages
}
fun isMessageHasFlag(mask: Int, flagName: String): Boolean {
val o: Any? = oldVKMessage.flags[flagName]
return if (o != null) { //has flag
val flag = o as Int
flag and mask > 0
} else false
}
//TODO: rewrite parsing
//fromUser and fromGroup are null
@Deprecated("need to rewrite")
@WorkerThread
fun parseLongPollMessage(array: JSONArray): oldVKMessage {
val message = oldVKMessage()
val id = array.optInt(1)
val flags = array.optInt(2)
val peerId = array.optInt(3)
val date = array.optInt(4)
val text = array.optString(5)
message.id = id
message.peerId = peerId
message.date = date
message.text = text
// val fromId =
// if (isMessageHasFlag(flags, "outbox")) com.meloda.fast.api.UserConfig.userId
// else peerId
message.fromId = peerId
array.optJSONObject(6)?.let {
if (it.has("emoji")) message.hasEmoji = true
if (it.has("from")) {
message.fromId = it.optInt("from", -1)
}
if (it.has("source_act")) {
message.action = oldVKMessageAction().also { action ->
action.type =
oldVKMessageAction.Type.fromString(it.optString("source_act"))
when (action.type) {
oldVKMessageAction.Type.CHAT_CREATE -> {
action.text = it.optString("source_text")
}
oldVKMessageAction.Type.TITLE_UPDATE -> {
action.oldText = it.optString("source_old_text")
action.text = it.optString("source_text")
}
oldVKMessageAction.Type.PIN_MESSAGE -> {
action.memberId = it.optInt("source_mid")
action.conversationMessageId = it.optInt("source_chat_local_id")
it.optJSONObject("source_message")?.let { message ->
action.message = oldVKMessage(message)
}
}
oldVKMessageAction.Type.UNPIN_MESSAGE -> {
action.memberId = it.optInt("source_mid")
action.conversationMessageId = it.optInt("source_chat_local_id")
}
oldVKMessageAction.Type.INVITE_USER,
oldVKMessageAction.Type.KICK_USER,
oldVKMessageAction.Type.SCREENSHOT,
oldVKMessageAction.Type.INVITE_USER_BY_CALL -> {
action.memberId = it.optInt("source_mid")
}
}
}
}
}
array.optJSONObject(7)?.let {
/**
*
* fwd? reply? attachments_count? attachments?
*
*/
}
val randomId = array.optInt(8)
message.randomId = randomId
val conversationMessageId = array.optInt(9)
message.conversationMessageId = conversationMessageId
val editTime = array.optInt(10)
message.editTime = editTime
// val out = fromId == com.meloda.fast.api.UserConfig.userId
// message.isOut = out
//
// if (message.isFromUser()) {
// message.fromUser = MemoryCache.getUserById(fromId)
// } else {
// message.fromGroup = MemoryCache.getGroupById(abs(fromId))
// }
return message
}
fun parseJsonPhotos(jsonPhotos: JSONObject): List<String> {
val photos = arrayListOf<String>()
for (key in jsonPhotos.keys()) {
photos.add(jsonPhotos.getString(key))
}
return photos
}
fun putPhotosToJson(photo50: String, photo100: String, photo200: String): JSONObject {
val json = JSONObject()
json.put("photo_50", photo50)
json.put("photo_100", photo100)
json.put("photo_200", photo200)
return json
}
fun isGroupId(id: Int) = id < 0
fun isUserId(id: Int) = id in 1..1999999999
fun isChatId(id: Int) = id > 2_000_000_000
}