Basic conversations screen
attachment types action types forwards
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
package com.meloda.fast.api
|
||||
|
||||
import com.meloda.fast.api.model.VkUser
|
||||
import com.meloda.fast.common.AppGlobal
|
||||
|
||||
object UserConfig {
|
||||
@@ -30,4 +31,6 @@ object UserConfig {
|
||||
|
||||
fun isLoggedIn() = userId > 0 && accessToken.isNotBlank()
|
||||
|
||||
var vkUser: VkUser? = null
|
||||
|
||||
}
|
||||
@@ -0,0 +1,357 @@
|
||||
package com.meloda.fast.api
|
||||
|
||||
import android.content.Context
|
||||
import com.meloda.fast.R
|
||||
import com.meloda.fast.api.model.VkGroup
|
||||
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
|
||||
|
||||
object VkUtils {
|
||||
|
||||
fun parseForwards(baseForwards: List<BaseVkMessage>?): List<VkMessage>? {
|
||||
if (baseForwards.isNullOrEmpty()) return null
|
||||
|
||||
val forwards = mutableListOf<VkMessage>()
|
||||
|
||||
for (baseForward in baseForwards) {
|
||||
forwards += baseForward.asVkMessage()
|
||||
}
|
||||
|
||||
return forwards
|
||||
}
|
||||
|
||||
fun parseAttachments(baseAttachments: List<BaseVkAttachmentItem>?): List<VkAttachment>? {
|
||||
if (baseAttachments.isNullOrEmpty()) return null
|
||||
|
||||
val attachments = mutableListOf<VkAttachment>()
|
||||
|
||||
for (baseAttachment in baseAttachments) {
|
||||
when (baseAttachment.getPreparedType()) {
|
||||
BaseVkAttachmentItem.AttachmentType.PHOTO -> {
|
||||
val photo = baseAttachment.photo ?: continue
|
||||
attachments += VkPhoto(
|
||||
link = photo.sizes[0].url
|
||||
)
|
||||
}
|
||||
BaseVkAttachmentItem.AttachmentType.VIDEO -> {
|
||||
val video = baseAttachment.video ?: continue
|
||||
attachments += VkVideo(
|
||||
link = video.player
|
||||
)
|
||||
}
|
||||
BaseVkAttachmentItem.AttachmentType.AUDIO -> {
|
||||
val audio = baseAttachment.audio ?: continue
|
||||
attachments += VkAudio(
|
||||
link = audio.url
|
||||
)
|
||||
}
|
||||
BaseVkAttachmentItem.AttachmentType.FILE -> {
|
||||
val file = baseAttachment.file ?: continue
|
||||
attachments += VkFile(
|
||||
link = file.url
|
||||
)
|
||||
}
|
||||
BaseVkAttachmentItem.AttachmentType.LINK -> {
|
||||
val link = baseAttachment.link ?: continue
|
||||
attachments += VkLink(
|
||||
link = link.url
|
||||
)
|
||||
}
|
||||
BaseVkAttachmentItem.AttachmentType.MINI_APP -> {
|
||||
val miniApp = baseAttachment.miniApp ?: continue
|
||||
attachments += VkMiniApp(
|
||||
link = miniApp.app.shareUrl
|
||||
)
|
||||
}
|
||||
BaseVkAttachmentItem.AttachmentType.VOICE -> {
|
||||
val voiceMessage = baseAttachment.voiceMessage ?: continue
|
||||
attachments += VkVoiceMessage(
|
||||
link = voiceMessage.linkMp3
|
||||
)
|
||||
}
|
||||
BaseVkAttachmentItem.AttachmentType.STICKER -> {
|
||||
val sticker = baseAttachment.sticker ?: continue
|
||||
attachments += VkSticker(
|
||||
link = sticker.images[0].url
|
||||
)
|
||||
}
|
||||
BaseVkAttachmentItem.AttachmentType.GIFT -> {
|
||||
val gift = baseAttachment.gift ?: continue
|
||||
attachments += VkGift(
|
||||
link = gift.thumb48
|
||||
)
|
||||
}
|
||||
BaseVkAttachmentItem.AttachmentType.WALL -> {
|
||||
val wall = baseAttachment.wall ?: continue
|
||||
attachments += VkWall(
|
||||
id = wall.id
|
||||
)
|
||||
}
|
||||
BaseVkAttachmentItem.AttachmentType.GRAFFITI -> {
|
||||
val graffiti = baseAttachment.graffiti ?: continue
|
||||
attachments += VkGraffiti(
|
||||
link = graffiti.url
|
||||
)
|
||||
}
|
||||
BaseVkAttachmentItem.AttachmentType.POLL -> {
|
||||
val poll = baseAttachment.poll ?: continue
|
||||
attachments += VkPoll(
|
||||
id = poll.id
|
||||
)
|
||||
}
|
||||
BaseVkAttachmentItem.AttachmentType.WALL_REPLY -> {
|
||||
val wallReply = baseAttachment.wallReply ?: continue
|
||||
attachments += VkWallReply(
|
||||
id = wallReply.id
|
||||
)
|
||||
}
|
||||
BaseVkAttachmentItem.AttachmentType.CALL -> {
|
||||
val call = baseAttachment.call ?: continue
|
||||
attachments += VkCall(
|
||||
initiatorId = call.initiatorId
|
||||
)
|
||||
}
|
||||
else -> continue
|
||||
}
|
||||
}
|
||||
|
||||
return attachments
|
||||
}
|
||||
|
||||
fun getActionConversationText(
|
||||
message: VkMessage,
|
||||
youPrefix: String,
|
||||
profiles: HashMap<Int, VkUser>? = null,
|
||||
groups: HashMap<Int, VkGroup>? = null,
|
||||
messageUser: VkUser? = null,
|
||||
messageGroup: VkGroup? = null
|
||||
): String? {
|
||||
return when (message.getPreparedAction()) {
|
||||
VkMessage.Action.CHAT_CREATE -> {
|
||||
val text = message.actionText ?: return null
|
||||
|
||||
val prefix = when {
|
||||
message.fromId == UserConfig.userId -> youPrefix
|
||||
message.isGroup() -> messageGroup?.name
|
||||
message.isUser() -> messageUser?.toString()
|
||||
else -> return null
|
||||
} ?: return null
|
||||
|
||||
"$prefix created «$text»"
|
||||
}
|
||||
VkMessage.Action.CHAT_TITLE_UPDATE -> {
|
||||
val text = message.actionText ?: return null
|
||||
|
||||
val prefix = when {
|
||||
message.fromId == UserConfig.userId -> youPrefix
|
||||
message.isGroup() -> messageGroup?.name
|
||||
message.isUser() -> messageUser?.toString()
|
||||
else -> return null
|
||||
} ?: return null
|
||||
|
||||
"$prefix renamed chat to «$text»"
|
||||
}
|
||||
VkMessage.Action.CHAT_PHOTO_UPDATE -> {
|
||||
val prefix = when {
|
||||
message.fromId == UserConfig.userId -> youPrefix
|
||||
message.isGroup() -> messageGroup?.name
|
||||
message.isUser() -> messageUser?.toString()
|
||||
else -> return null
|
||||
} ?: return null
|
||||
|
||||
"$prefix updated the chat photo"
|
||||
}
|
||||
VkMessage.Action.CHAT_PHOTO_REMOVE -> {
|
||||
val prefix = when {
|
||||
message.fromId == UserConfig.userId -> youPrefix
|
||||
message.isGroup() -> messageGroup?.name
|
||||
message.isUser() -> messageUser?.toString()
|
||||
else -> return null
|
||||
} ?: return null
|
||||
|
||||
"$prefix deleted the chat photo"
|
||||
}
|
||||
VkMessage.Action.CHAT_KICK_USER -> {
|
||||
val memberId = message.actionMemberId ?: return null
|
||||
val isUser = memberId > 0
|
||||
val isGroup = memberId < 0
|
||||
|
||||
val actionUser = profiles?.get(memberId)
|
||||
val actionGroup = groups?.get(memberId)
|
||||
// val actionUser = profiles?.find { it.id == memberId }
|
||||
// val actionGroup = groups?.find { it.id == memberId }
|
||||
|
||||
if (isUser && actionUser == null) return null
|
||||
if (isGroup && actionGroup == null) return null
|
||||
|
||||
if (memberId == message.fromId) {
|
||||
val prefix = if (memberId == UserConfig.userId) youPrefix
|
||||
else actionUser.toString()
|
||||
"$prefix left the chat"
|
||||
} else {
|
||||
val prefix =
|
||||
if (message.fromId == UserConfig.userId) youPrefix
|
||||
else messageUser?.toString() ?: messageGroup?.toString() ?: "..."
|
||||
val postfix =
|
||||
if (memberId == UserConfig.userId) youPrefix.lowercase()
|
||||
else actionUser.toString()
|
||||
"$prefix kicked $postfix"
|
||||
}
|
||||
}
|
||||
VkMessage.Action.CHAT_INVITE_USER -> {
|
||||
val memberId = message.actionMemberId ?: 0
|
||||
val isUser = memberId > 0
|
||||
val isGroup = memberId < 0
|
||||
|
||||
val actionUser = profiles?.get(memberId)
|
||||
val actionGroup = groups?.get(memberId)
|
||||
// val actionUser = profiles?.find { it.id == memberId }
|
||||
// val actionGroup = groups?.find { it.id == memberId }
|
||||
|
||||
if (isUser && actionUser == null) return null
|
||||
if (isGroup && actionGroup == null) return null
|
||||
|
||||
if (memberId == message.fromId) {
|
||||
val prefix = if (memberId == UserConfig.userId) youPrefix
|
||||
else actionUser.toString()
|
||||
"$prefix returned the chat"
|
||||
} else {
|
||||
val prefix = if (message.fromId == UserConfig.userId) youPrefix
|
||||
else messageUser?.toString() ?: messageGroup?.toString() ?: "..."
|
||||
val postfix =
|
||||
if (memberId == UserConfig.userId) youPrefix.lowercase()
|
||||
else actionUser.toString()
|
||||
"$prefix invited $postfix"
|
||||
}
|
||||
}
|
||||
VkMessage.Action.CHAT_INVITE_USER_BY_LINK -> {
|
||||
val prefix = when {
|
||||
message.fromId == UserConfig.userId -> youPrefix
|
||||
message.isUser() -> messageUser?.toString()
|
||||
else -> return null
|
||||
} ?: return null
|
||||
|
||||
"$prefix joined the chat via link"
|
||||
}
|
||||
VkMessage.Action.CHAT_INVITE_USER_BY_CALL_LINK -> {
|
||||
val prefix = when {
|
||||
message.fromId == UserConfig.userId -> youPrefix
|
||||
message.isUser() -> messageUser?.toString()
|
||||
else -> return null
|
||||
} ?: return null
|
||||
|
||||
"$prefix joined the call via link"
|
||||
}
|
||||
VkMessage.Action.CHAT_PIN_MESSAGE -> {
|
||||
val prefix = when {
|
||||
message.fromId == UserConfig.userId -> youPrefix
|
||||
message.isGroup() -> messageGroup?.name
|
||||
message.isUser() -> messageUser?.toString()
|
||||
else -> return null
|
||||
} ?: return null
|
||||
|
||||
val actionMessage = message.actionMessage ?: return null
|
||||
|
||||
"$prefix pinned message «$actionMessage»"
|
||||
}
|
||||
VkMessage.Action.CHAT_UNPIN_MESSAGE -> {
|
||||
val prefix = when {
|
||||
message.fromId == UserConfig.userId -> youPrefix
|
||||
message.isGroup() -> messageGroup?.name
|
||||
message.isUser() -> messageUser?.toString()
|
||||
else -> return null
|
||||
} ?: return null
|
||||
|
||||
"$prefix unpinned message"
|
||||
}
|
||||
VkMessage.Action.CHAT_SCREENSHOT -> {
|
||||
val prefix = when {
|
||||
message.fromId == UserConfig.userId -> youPrefix
|
||||
message.isGroup() -> messageGroup?.name
|
||||
message.isUser() -> messageUser?.toString()
|
||||
else -> return null
|
||||
} ?: return null
|
||||
|
||||
"$prefix took a screenshot"
|
||||
}
|
||||
null -> null
|
||||
else -> "[${message.action}]"
|
||||
}
|
||||
}
|
||||
|
||||
fun getForwardsConversationText(context: Context, message: VkMessage): String? {
|
||||
if (message.forwards.isNullOrEmpty()) return null
|
||||
|
||||
return message.forwards?.let { forwards ->
|
||||
context.getString(
|
||||
if (forwards.size == 1) R.string.forwarded_message
|
||||
else R.string.forwarded_messages
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun getAttachmentConversationText(context: Context, message: VkMessage): String? {
|
||||
message.geoType?.let {
|
||||
return when (it) {
|
||||
"point" -> context.getString(R.string.message_geo_point)
|
||||
else -> context.getString(R.string.message_geo)
|
||||
}
|
||||
}
|
||||
if (message.attachments.isNullOrEmpty()) return null
|
||||
|
||||
return message.attachments?.let { attachments ->
|
||||
if (attachments.size == 1) {
|
||||
getAttachmentTypeByClass(attachments[0])?.let { getAttachmentTextByType(it) }
|
||||
} else {
|
||||
if (isAttachmentsHaveOneType(attachments)) {
|
||||
getAttachmentTypeByClass(attachments[0])?.let { getAttachmentTextByType(it) }
|
||||
} else {
|
||||
context.getString(R.string.message_attachments_many)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun isAttachmentsHaveOneType(attachments: List<VkAttachment>): Boolean {
|
||||
if (attachments.isEmpty()) return true
|
||||
if (attachments.size == 1) return true
|
||||
|
||||
val firstType = getAttachmentTypeByClass(attachments[0])
|
||||
for (i in 1 until attachments.size) {
|
||||
val type = getAttachmentTypeByClass(attachments[i])
|
||||
if (type != firstType) return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
fun getAttachmentTypeByClass(attachment: VkAttachment): BaseVkAttachmentItem.AttachmentType? {
|
||||
return when (attachment) {
|
||||
is VkPhoto -> BaseVkAttachmentItem.AttachmentType.PHOTO
|
||||
is VkVideo -> BaseVkAttachmentItem.AttachmentType.VIDEO
|
||||
is VkAudio -> BaseVkAttachmentItem.AttachmentType.AUDIO
|
||||
is VkFile -> BaseVkAttachmentItem.AttachmentType.FILE
|
||||
is VkLink -> BaseVkAttachmentItem.AttachmentType.LINK
|
||||
is VkMiniApp -> BaseVkAttachmentItem.AttachmentType.MINI_APP
|
||||
is VkVoiceMessage -> BaseVkAttachmentItem.AttachmentType.VOICE
|
||||
is VkSticker -> BaseVkAttachmentItem.AttachmentType.STICKER
|
||||
is VkGift -> BaseVkAttachmentItem.AttachmentType.GIFT
|
||||
is VkWall -> BaseVkAttachmentItem.AttachmentType.WALL
|
||||
is VkGraffiti -> BaseVkAttachmentItem.AttachmentType.GRAFFITI
|
||||
is VkPoll -> BaseVkAttachmentItem.AttachmentType.POLL
|
||||
is VkWallReply -> BaseVkAttachmentItem.AttachmentType.WALL_REPLY
|
||||
is VkCall -> BaseVkAttachmentItem.AttachmentType.CALL
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
fun getAttachmentTextByType(attachmentType: BaseVkAttachmentItem.AttachmentType): String? {
|
||||
return when (attachmentType) {
|
||||
else -> attachmentType.value
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -11,7 +11,7 @@ class ConversationsDataSource @Inject constructor(
|
||||
private val dao: ConversationsDao
|
||||
) {
|
||||
|
||||
suspend fun getAllChats(params: ConversationsGetRequest) = repo.getAllChats(params)
|
||||
suspend fun getAllChats(params: ConversationsGetRequest) = repo.getAllChats(params.map)
|
||||
|
||||
suspend fun storeConversations(conversations: List<VkConversation>) = dao.insert(conversations)
|
||||
|
||||
|
||||
@@ -9,7 +9,15 @@ data class VkConversation(
|
||||
@PrimaryKey(autoGenerate = false)
|
||||
val id: Int,
|
||||
val title: String?,
|
||||
val photo200: String?,
|
||||
val type: String,
|
||||
val callInProgress: Boolean
|
||||
) {
|
||||
@Ignore
|
||||
var lastMessage: VkMessage? = null
|
||||
|
||||
fun isChat() = type == "chat"
|
||||
fun isUser() = type == "user"
|
||||
fun isGroup() = type == "group"
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.meloda.fast.api.model
|
||||
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
|
||||
@Entity(tableName = "groups")
|
||||
data class VkGroup(
|
||||
@PrimaryKey(autoGenerate = false)
|
||||
val id: Int,
|
||||
val name: String,
|
||||
val screenName: String,
|
||||
val photo200: String?
|
||||
) {
|
||||
|
||||
override fun toString() = name.trim()
|
||||
|
||||
}
|
||||
@@ -1,7 +1,9 @@
|
||||
package com.meloda.fast.api.model
|
||||
|
||||
import androidx.room.Entity
|
||||
import androidx.room.Ignore
|
||||
import androidx.room.PrimaryKey
|
||||
import com.meloda.fast.api.model.attachments.VkAttachment
|
||||
|
||||
@Entity(tableName = "messages")
|
||||
data class VkMessage(
|
||||
@@ -11,9 +13,48 @@ data class VkMessage(
|
||||
val isOut: Boolean,
|
||||
val peerId: Int,
|
||||
val fromId: Int,
|
||||
val date: Int
|
||||
val date: Int,
|
||||
val action: String?,
|
||||
val actionMemberId: Int?,
|
||||
val actionText: String?,
|
||||
val actionConversationMessageId: Int?,
|
||||
val actionMessage: String?,
|
||||
val geoType: String?
|
||||
) {
|
||||
@Ignore
|
||||
var forwards: List<VkMessage>? = null
|
||||
|
||||
@Ignore
|
||||
var attachments: List<VkAttachment>? = null
|
||||
|
||||
fun isUser() = id > 0
|
||||
|
||||
fun isGroup() = id < 0
|
||||
|
||||
fun getPreparedAction(): Action? {
|
||||
if (action == null) return null
|
||||
return Action.parse(action)
|
||||
}
|
||||
|
||||
enum class Action(val value: String) {
|
||||
CHAT_CREATE("chat_create"),
|
||||
CHAT_PHOTO_UPDATE("chat_photo_update"),
|
||||
CHAT_PHOTO_REMOVE("chat_photo_remove"),
|
||||
CHAT_TITLE_UPDATE("chat_title_update"),
|
||||
CHAT_PIN_MESSAGE("chat_pin_message"),
|
||||
CHAT_UNPIN_MESSAGE("chat_unpin_message"),
|
||||
CHAT_INVITE_USER("chat_invite_user"),
|
||||
CHAT_INVITE_USER_BY_LINK("chat_invite_user_by_link"),
|
||||
CHAT_KICK_USER("chat_kick_user"),
|
||||
CHAT_SCREENSHOT("chat_screenshot"),
|
||||
|
||||
// TODO: 9/11/2021 catch this shit
|
||||
CHAT_INVITE_USER_BY_CALL("chat_invite_user_by_call"),
|
||||
CHAT_INVITE_USER_BY_CALL_LINK("chat_invite_user_by_call_join_link");
|
||||
|
||||
companion object {
|
||||
fun parse(value: String) = values().first { it.value == value }
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -8,5 +8,11 @@ data class VkUser(
|
||||
@PrimaryKey(autoGenerate = false)
|
||||
val id: Int,
|
||||
val firstName: String,
|
||||
val lastName: String
|
||||
)
|
||||
val lastName: String,
|
||||
val online: Boolean,
|
||||
val photo200: String?
|
||||
) {
|
||||
|
||||
override fun toString() = "$firstName $lastName".trim()
|
||||
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
package com.meloda.fast.api.model.attachments
|
||||
|
||||
import android.os.Parcelable
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
@Parcelize
|
||||
data class BaseVKAttachmentItem(
|
||||
val type: String,
|
||||
val photo: VKPhotoAttachment?,
|
||||
val video: VKVideoAttachment?,
|
||||
val audio: VKAudioAttachment?,
|
||||
val doc: VKFileAttachment?,
|
||||
val link: VKLinkAttachment?
|
||||
) : Parcelable
|
||||
|
||||
abstract class BaseVKAttachment : Parcelable
|
||||
@@ -0,0 +1,3 @@
|
||||
package com.meloda.fast.api.model.attachments
|
||||
|
||||
abstract class VkAttachment
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.meloda.fast.api.model.attachments
|
||||
|
||||
data class VkAudio(
|
||||
val link: String
|
||||
) : VkAttachment()
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.meloda.fast.api.model.attachments
|
||||
|
||||
data class VkCall(
|
||||
val initiatorId: Int
|
||||
) : VkAttachment()
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.meloda.fast.api.model.attachments
|
||||
|
||||
data class VkFile(
|
||||
val link: String
|
||||
) : VkAttachment()
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.meloda.fast.api.model.attachments
|
||||
|
||||
data class VkGift(
|
||||
val link: String
|
||||
) : VkAttachment()
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.meloda.fast.api.model.attachments
|
||||
|
||||
data class VkGraffiti(
|
||||
val link: String
|
||||
) : VkAttachment()
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.meloda.fast.api.model.attachments
|
||||
|
||||
data class VkLink(
|
||||
val link: String
|
||||
) : VkAttachment()
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.meloda.fast.api.model.attachments
|
||||
|
||||
data class VkMiniApp(
|
||||
val link: String
|
||||
) : VkAttachment()
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.meloda.fast.api.model.attachments
|
||||
|
||||
data class VkPhoto(
|
||||
val link: String
|
||||
) : VkAttachment()
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.meloda.fast.api.model.attachments
|
||||
|
||||
data class VkPoll(
|
||||
val id: Int
|
||||
) : VkAttachment()
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.meloda.fast.api.model.attachments
|
||||
|
||||
data class VkSticker(
|
||||
val link: String
|
||||
) : VkAttachment()
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.meloda.fast.api.model.attachments
|
||||
|
||||
data class VkVideo(
|
||||
val link: String
|
||||
) : VkAttachment()
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.meloda.fast.api.model.attachments
|
||||
|
||||
data class VkVoiceMessage(
|
||||
val link: String
|
||||
) : VkAttachment()
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.meloda.fast.api.model.attachments
|
||||
|
||||
data class VkWall(
|
||||
val id: Int
|
||||
) : VkAttachment()
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.meloda.fast.api.model.attachments
|
||||
|
||||
data class VkWallReply(
|
||||
val id: Int
|
||||
) : VkAttachment()
|
||||
@@ -31,12 +31,17 @@ data class BaseVkConversation(
|
||||
@SerializedName("can_receive_money")
|
||||
val canReceiveMoney: Boolean,
|
||||
@SerializedName("chat_settings")
|
||||
val chatSettings: ChatSettings?
|
||||
val chatSettings: ChatSettings?,
|
||||
@SerializedName("call_in_progress")
|
||||
val callInProgress: CallInProgress?
|
||||
) : Parcelable {
|
||||
|
||||
fun asVkConversation(lastMessage: VkMessage? = null) = VkConversation(
|
||||
id = peer.id,
|
||||
title = chatSettings?.title,
|
||||
photo200 = chatSettings?.photo?.photo200,
|
||||
type = peer.type,
|
||||
callInProgress = callInProgress != null
|
||||
).apply { this.lastMessage = lastMessage }
|
||||
|
||||
@Parcelize
|
||||
@@ -83,7 +88,7 @@ data class BaseVkConversation(
|
||||
val membersCount: Int,
|
||||
@SerializedName("friends_count")
|
||||
val friendsCount: Int,
|
||||
val photo: Photo,
|
||||
val photo: Photo?,
|
||||
@SerializedName("admin_ids")
|
||||
val adminsIds: List<Int>,
|
||||
@SerializedName("active_ids")
|
||||
@@ -93,7 +98,8 @@ data class BaseVkConversation(
|
||||
@SerializedName("is_disappearing")
|
||||
val isDisappearing: Boolean,
|
||||
@SerializedName("is_service")
|
||||
val isService: Boolean
|
||||
val isService: Boolean,
|
||||
val theme: String
|
||||
) : Parcelable {
|
||||
|
||||
@Parcelize
|
||||
@@ -125,13 +131,28 @@ data class BaseVkConversation(
|
||||
@Parcelize
|
||||
data class Photo(
|
||||
@SerializedName("photo_50")
|
||||
val photo50: String,
|
||||
val photo50: String?,
|
||||
@SerializedName("photo_100")
|
||||
val photo100: String,
|
||||
val photo100: String?,
|
||||
@SerializedName("photo_200")
|
||||
val photo200: String,
|
||||
val photo200: String?,
|
||||
@SerializedName("is_default_photo")
|
||||
val isDefaultPhoto: Boolean
|
||||
) : Parcelable
|
||||
}
|
||||
|
||||
@Parcelize
|
||||
data class CallInProgress(
|
||||
val participants: Participants,
|
||||
@SerializedName("join_link")
|
||||
val joinLink: String
|
||||
) : Parcelable {
|
||||
|
||||
@Parcelize
|
||||
data class Participants(
|
||||
val list: List<Int>,
|
||||
val count: Int
|
||||
) : Parcelable
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.meloda.fast.api.model.base
|
||||
|
||||
import android.os.Parcelable
|
||||
import com.google.gson.annotations.SerializedName
|
||||
import com.meloda.fast.api.model.VkGroup
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
@Parcelize
|
||||
data class BaseVkGroup(
|
||||
val id: Int,
|
||||
val name: String,
|
||||
@SerializedName("screen_name")
|
||||
val screenName: String,
|
||||
@SerializedName("is_closed")
|
||||
val isClosed: Int,
|
||||
val type: String,
|
||||
@SerializedName("is_admin")
|
||||
val isAdmin: Int,
|
||||
@SerializedName("is_member")
|
||||
val isMember: Int,
|
||||
@SerializedName("is_advertiser")
|
||||
val isAdvertiser: Int,
|
||||
@SerializedName("photo_50")
|
||||
val photo50: String?,
|
||||
@SerializedName("photo_100")
|
||||
val photo100: String?,
|
||||
@SerializedName("photo_200")
|
||||
val photo200: String?
|
||||
) : Parcelable {
|
||||
|
||||
fun asVkGroup() = VkGroup(
|
||||
id = -id,
|
||||
name = name,
|
||||
screenName = screenName,
|
||||
photo200 = photo200
|
||||
)
|
||||
|
||||
}
|
||||
@@ -2,9 +2,10 @@ package com.meloda.fast.api.model.base
|
||||
|
||||
import android.os.Parcelable
|
||||
import com.google.gson.annotations.SerializedName
|
||||
import com.meloda.fast.api.VkUtils
|
||||
import com.meloda.fast.api.model.VkMessage
|
||||
import com.meloda.fast.api.model.base.attachments.BaseVkAttachmentItem
|
||||
import kotlinx.parcelize.Parcelize
|
||||
import kotlinx.parcelize.RawValue
|
||||
|
||||
@Parcelize
|
||||
data class BaseVkMessage(
|
||||
@@ -19,25 +20,36 @@ data class BaseVkMessage(
|
||||
@SerializedName("conversation_message_id")
|
||||
val conversationMessageId: Int,
|
||||
@SerializedName("fwd_messages")
|
||||
val fwdMessages: List<BaseVkMessage> = listOf(),
|
||||
val fwdMessages: List<BaseVkMessage>? = listOf(),
|
||||
val important: Boolean,
|
||||
@SerializedName("random_id")
|
||||
val randomId: Int,
|
||||
val attachments: @RawValue List<Any> = listOf(),
|
||||
val attachments: List<BaseVkAttachmentItem> = listOf(),
|
||||
@SerializedName("is_hidden")
|
||||
val isHidden: Boolean,
|
||||
val payload: String,
|
||||
val geo: Geo?
|
||||
val geo: Geo?,
|
||||
val action: Action?,
|
||||
val ttl: Int
|
||||
) : Parcelable {
|
||||
|
||||
fun asVkMessage() = VkMessage(
|
||||
id = id,
|
||||
text = text,
|
||||
text = if (text.isBlank()) null else text,
|
||||
isOut = out == 1,
|
||||
peerId = peerId,
|
||||
fromId = fromId,
|
||||
date = date
|
||||
)
|
||||
date = date,
|
||||
action = action?.type,
|
||||
actionMemberId = action?.memberId,
|
||||
actionText = action?.text,
|
||||
actionConversationMessageId = action?.conversationMessageId,
|
||||
actionMessage = action?.message,
|
||||
geoType = geo?.type
|
||||
).also {
|
||||
it.attachments = VkUtils.parseAttachments(attachments)
|
||||
it.forwards = VkUtils.parseForwards(fwdMessages)
|
||||
}
|
||||
|
||||
@Parcelize
|
||||
data class Geo(
|
||||
@@ -54,4 +66,15 @@ data class BaseVkMessage(
|
||||
data class Place(val country: String, val city: String, val title: String) : Parcelable
|
||||
}
|
||||
|
||||
@Parcelize
|
||||
data class Action(
|
||||
val type: String,
|
||||
@SerializedName("member_id")
|
||||
val memberId: Int?,
|
||||
val text: String?,
|
||||
@SerializedName("conversation_message_id")
|
||||
val conversationMessageId: Int?,
|
||||
val message: String?
|
||||
) : Parcelable
|
||||
|
||||
}
|
||||
|
||||
@@ -50,7 +50,9 @@ data class BaseVkUser(
|
||||
fun asVkUser() = VkUser(
|
||||
id = id,
|
||||
firstName = firstName,
|
||||
lastName = lastName
|
||||
lastName = lastName,
|
||||
online = online == 1,
|
||||
photo200 = photo200
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
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 BaseVkAttachmentItem(
|
||||
val type: String,
|
||||
val photo: BaseVkPhoto?,
|
||||
val video: BaseVkVideo?,
|
||||
val audio: BaseVkAudio?,
|
||||
@SerializedName("doc")
|
||||
val file: BaseVkFile?,
|
||||
val link: BaseVkLink?,
|
||||
@SerializedName("mini_app")
|
||||
val miniApp: BaseVkMiniApp?,
|
||||
@SerializedName("audio_message")
|
||||
val voiceMessage: BaseVkVoiceMessage?,
|
||||
val sticker: BaseVkSticker?,
|
||||
val gift: BaseVkGift?,
|
||||
val wall: BaseVkWall?,
|
||||
val graffiti: BaseVkGraffiti?,
|
||||
val poll: BaseVkPoll?,
|
||||
@SerializedName("wall_reply")
|
||||
val wallReply: BaseVkWallReply?,
|
||||
val call: BaseVkCall?
|
||||
) : Parcelable {
|
||||
|
||||
fun getPreparedType() = AttachmentType.parse(type)
|
||||
|
||||
enum class AttachmentType(val value: String) {
|
||||
PHOTO("photo"),
|
||||
VIDEO("video"),
|
||||
AUDIO("audio"),
|
||||
FILE("doc"),
|
||||
LINK("link"),
|
||||
VOICE("audio_message"),
|
||||
MINI_APP("mini_app"),
|
||||
STICKER("sticker"),
|
||||
GIFT("gift"),
|
||||
WALL("wall"),
|
||||
GRAFFITI("graffiti"),
|
||||
POLL("poll"),
|
||||
WALL_REPLY("wall_reply"),
|
||||
CALL("call")
|
||||
;
|
||||
|
||||
companion object {
|
||||
fun parse(value: String) = values().firstOrNull { it.value == value }
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
abstract class BaseVkAttachment : Parcelable
|
||||
+3
-3
@@ -1,11 +1,11 @@
|
||||
package com.meloda.fast.api.model.attachments
|
||||
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 VKAudioAttachment(
|
||||
data class BaseVkAudio(
|
||||
val id: Int,
|
||||
val title: String,
|
||||
val artist: String,
|
||||
@@ -33,7 +33,7 @@ data class VKAudioAttachment(
|
||||
val storiesAllowed: Boolean,
|
||||
@SerializedName("stories_cover_allowed")
|
||||
val storiesCoverAllowed: Boolean
|
||||
) : BaseVKAttachment() {
|
||||
) : BaseVkAttachment() {
|
||||
|
||||
@Parcelize
|
||||
data class Album(
|
||||
@@ -0,0 +1,17 @@
|
||||
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 BaseVkCall(
|
||||
@SerializedName("initiator_id")
|
||||
val initiatorId: Int,
|
||||
@SerializedName("receiver_id")
|
||||
val receiverId: Int,
|
||||
val state: String,
|
||||
val time: Int,
|
||||
val duration: Int,
|
||||
val video: Boolean
|
||||
) : Parcelable
|
||||
+3
-3
@@ -1,11 +1,11 @@
|
||||
package com.meloda.fast.api.model.attachments
|
||||
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 VKFileAttachment(
|
||||
data class BaseVkFile(
|
||||
val id: Int,
|
||||
@SerializedName("owner_id")
|
||||
val ownerId: Int,
|
||||
@@ -22,7 +22,7 @@ data class VKFileAttachment(
|
||||
val accessKey: String,
|
||||
@SerializedName("web_preview_url")
|
||||
val webPreviewUrl: String?
|
||||
) : BaseVKAttachment() {
|
||||
) : BaseVkAttachment() {
|
||||
|
||||
@Parcelize
|
||||
data class Preview(
|
||||
@@ -0,0 +1,16 @@
|
||||
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 BaseVkGift(
|
||||
val id: Int,
|
||||
@SerializedName("thumb_256")
|
||||
val thumb256: String?,
|
||||
@SerializedName("thumb_96")
|
||||
val thumb96: String?,
|
||||
@SerializedName("thumb_48")
|
||||
val thumb48: String
|
||||
) : Parcelable
|
||||
@@ -0,0 +1,17 @@
|
||||
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 BaseVkGraffiti(
|
||||
val id: Int,
|
||||
@SerializedName("owner_id")
|
||||
val ownerId: Int,
|
||||
val url: String,
|
||||
val width: Int,
|
||||
val height: Int,
|
||||
@SerializedName("access_key")
|
||||
val accessKey: String
|
||||
) : Parcelable
|
||||
+4
-4
@@ -1,15 +1,15 @@
|
||||
package com.meloda.fast.api.model.attachments
|
||||
package com.meloda.fast.api.model.base.attachments
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
@Parcelize
|
||||
data class VKLinkAttachment(
|
||||
data class BaseVkLink(
|
||||
val url: String,
|
||||
val title: String,
|
||||
val caption: String,
|
||||
val photo: VKPhotoAttachment,
|
||||
val photo: BaseVkPhoto,
|
||||
val target: String,
|
||||
@SerializedName("is_favorite")
|
||||
val isFavorite: Boolean
|
||||
) : BaseVKAttachment()
|
||||
) : BaseVkAttachment()
|
||||
@@ -0,0 +1,67 @@
|
||||
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 BaseVkMiniApp(
|
||||
val title: String,
|
||||
val description: String,
|
||||
val app: App,
|
||||
val images: List<Image>?,
|
||||
@SerializedName("button_text")
|
||||
val buttonText: String
|
||||
) : Parcelable {
|
||||
|
||||
@Parcelize
|
||||
data class App(
|
||||
val type: String,
|
||||
val id: Int,
|
||||
val title: String,
|
||||
@SerializedName("author_owner_id")
|
||||
val authorOwnerId: Int,
|
||||
@SerializedName("are_notifications_enabled")
|
||||
val areNotificationsEnabled: Boolean,
|
||||
@SerializedName("is_favorite")
|
||||
val isFavorite: Boolean,
|
||||
@SerializedName("is_installed")
|
||||
val isInstalled: Boolean,
|
||||
@SerializedName("track_code")
|
||||
val trackCode: String,
|
||||
@SerializedName("share_url")
|
||||
val shareUrl: String,
|
||||
@SerializedName("webview_url")
|
||||
val webViewUrl: String,
|
||||
@SerializedName("hide_tabbar")
|
||||
val hideTabBar: Int,
|
||||
@SerializedName("icon_75")
|
||||
val icon75: String?,
|
||||
@SerializedName("icon_139")
|
||||
val icon139: String?,
|
||||
@SerializedName("icon_150")
|
||||
val icon150: String?,
|
||||
@SerializedName("icon_278")
|
||||
val icon278: String?,
|
||||
@SerializedName("icon_576")
|
||||
val icon576: String?,
|
||||
@SerializedName("open_in_external_browser")
|
||||
val openInExternalBrowser: Boolean,
|
||||
@SerializedName("need_policy_confirmation")
|
||||
val needPolicyConfirmation: Boolean,
|
||||
@SerializedName("is_vkui_internal")
|
||||
val isVkUiInternal: Boolean,
|
||||
@SerializedName("has_vk_connect")
|
||||
val hasVkConnect: Boolean,
|
||||
@SerializedName("need_show_bottom_menu_tooltip_on_close")
|
||||
val needShowBottomMenuTooltipOnClose: Boolean
|
||||
) : Parcelable
|
||||
|
||||
@Parcelize
|
||||
data class Image(
|
||||
val height: Int,
|
||||
val width: Int,
|
||||
val url: String
|
||||
) : Parcelable
|
||||
|
||||
}
|
||||
+3
-3
@@ -1,11 +1,11 @@
|
||||
package com.meloda.fast.api.model.attachments
|
||||
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 VKPhotoAttachment(
|
||||
data class BaseVkPhoto(
|
||||
@SerializedName("album_id")
|
||||
val albumId: Int,
|
||||
val date: Int,
|
||||
@@ -20,7 +20,7 @@ data class VKPhotoAttachment(
|
||||
val text: String,
|
||||
@SerializedName("user_id")
|
||||
val userId: Int?
|
||||
) : BaseVKAttachment()
|
||||
) : BaseVkAttachment()
|
||||
|
||||
@Parcelize
|
||||
data class Size(
|
||||
@@ -0,0 +1,72 @@
|
||||
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 BaseVkPoll(
|
||||
val multiple: Boolean,
|
||||
val id: Int,
|
||||
val votes: Int,
|
||||
val anonymous: Boolean,
|
||||
val closed: Boolean,
|
||||
@SerializedName("end_date")
|
||||
val endDate: Int,
|
||||
@SerializedName("is_board")
|
||||
val isBoard: Boolean,
|
||||
@SerializedName("can_vote")
|
||||
val canVote: Boolean,
|
||||
@SerializedName("can_edit")
|
||||
val canEdit: Boolean,
|
||||
@SerializedName("can_report")
|
||||
val canReport: Boolean,
|
||||
@SerializedName("can_share")
|
||||
val canShare: Boolean,
|
||||
val created: Int,
|
||||
@SerializedName("owner_id")
|
||||
val ownerId: Int,
|
||||
val question: String,
|
||||
@SerializedName("disable_unvote")
|
||||
val disableUnVote: Boolean,
|
||||
val friends: List<Friend>?,
|
||||
@SerializedName("embed_hash")
|
||||
val embedHash: String,
|
||||
val answers: List<Answer>,
|
||||
@SerializedName("author_id")
|
||||
val authorId: Int,
|
||||
val background: Background?
|
||||
) : Parcelable {
|
||||
|
||||
@Parcelize
|
||||
data class Friend(
|
||||
val id: Int
|
||||
) : Parcelable
|
||||
|
||||
@Parcelize
|
||||
data class Answer(
|
||||
val id: Int,
|
||||
val rate: Double,
|
||||
val text: String,
|
||||
val votes: Int
|
||||
) : Parcelable
|
||||
|
||||
@Parcelize
|
||||
data class Background(
|
||||
val angle: Int,
|
||||
val color: String,
|
||||
val id: Int,
|
||||
val name: String,
|
||||
val type: String,
|
||||
val points: List<Point>
|
||||
) : Parcelable {
|
||||
|
||||
@Parcelize
|
||||
data class Point(
|
||||
val color: String,
|
||||
val position: Double
|
||||
) : Parcelable
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
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 BaseVkSticker(
|
||||
@SerializedName("product_id")
|
||||
val productId: Int,
|
||||
@SerializedName("sticker_id")
|
||||
val stickerId: Int,
|
||||
val images: List<Image>,
|
||||
@SerializedName("images_with_background")
|
||||
val imagesWithBackground: List<Image>,
|
||||
@SerializedName("animation_url")
|
||||
val animationUrl: String?,
|
||||
val animations: List<Animation>?
|
||||
) : Parcelable {
|
||||
|
||||
@Parcelize
|
||||
data class Image(
|
||||
val width: Int,
|
||||
val height: Int,
|
||||
val url: String
|
||||
) : Parcelable
|
||||
|
||||
@Parcelize
|
||||
data class Animation(
|
||||
val type: String,
|
||||
val url: String
|
||||
) : Parcelable
|
||||
|
||||
|
||||
}
|
||||
+10
-10
@@ -1,11 +1,11 @@
|
||||
package com.meloda.fast.api.model.attachments
|
||||
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 VKVideoAttachment(
|
||||
data class BaseVkVideo(
|
||||
val id: Int,
|
||||
val title: String,
|
||||
val width: Int,
|
||||
@@ -47,11 +47,11 @@ data class VKVideoAttachment(
|
||||
val image: List<Image>,
|
||||
@SerializedName("first_frame")
|
||||
val firstFrame: List<FirstFrame>,
|
||||
val files: List<File>,
|
||||
val files: File,
|
||||
@SerializedName("timeline_thumbs")
|
||||
val timelineThumbs: TimelineThumbs
|
||||
//ads
|
||||
) : BaseVKAttachment() {
|
||||
) : BaseVkAttachment() {
|
||||
|
||||
@Parcelize
|
||||
data class Image(
|
||||
@@ -71,12 +71,12 @@ data class VKVideoAttachment(
|
||||
|
||||
@Parcelize
|
||||
data class File(
|
||||
val mp4_240: String,
|
||||
val mp4_360: String,
|
||||
val mp4_480: String,
|
||||
val mp4_720: String,
|
||||
val mp4_1080: String,
|
||||
val mp4_1440: String,
|
||||
val mp4_240: String?,
|
||||
val mp4_360: String?,
|
||||
val mp4_480: String?,
|
||||
val mp4_720: String?,
|
||||
val mp4_1080: String?,
|
||||
val mp4_1440: String?,
|
||||
val hls: String,
|
||||
@SerializedName("dash_uni")
|
||||
val dashUni: String,
|
||||
@@ -0,0 +1,23 @@
|
||||
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 BaseVkVoiceMessage(
|
||||
val id: Int,
|
||||
@SerializedName("owner_id")
|
||||
val ownerId: Int,
|
||||
val duration: Int,
|
||||
val waveform: List<Int>,
|
||||
@SerializedName("link_ogg")
|
||||
val linkOgg: String,
|
||||
@SerializedName("link_mp3")
|
||||
val linkMp3: String,
|
||||
@SerializedName("access_key")
|
||||
val accessKey: String,
|
||||
@SerializedName("transcript_state")
|
||||
val transcriptState: String,
|
||||
val transcript: String
|
||||
) : Parcelable
|
||||
@@ -0,0 +1,76 @@
|
||||
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 BaseVkWall(
|
||||
val id: Int,
|
||||
@SerializedName("from_id")
|
||||
val fromId: Int,
|
||||
@SerializedName("to_id")
|
||||
val toId: Int,
|
||||
val date: Int,
|
||||
val text: String,
|
||||
val attachments: List<BaseVkAttachmentItem>?,
|
||||
@SerializedName("post_source")
|
||||
val postSource: PostSource,
|
||||
val comments: Comments,
|
||||
val likes: Likes,
|
||||
val reposts: Reposts,
|
||||
val views: Views,
|
||||
@SerializedName("is_favorite")
|
||||
val isFavorite: Boolean,
|
||||
val donut: Donut,
|
||||
@SerializedName("access_key")
|
||||
val accessKey: String,
|
||||
@SerializedName("short_text_rate")
|
||||
val shortTextRate: Double
|
||||
) : Parcelable {
|
||||
|
||||
@Parcelize
|
||||
data class PostSource(
|
||||
val type: String,
|
||||
val platform: String
|
||||
) : Parcelable
|
||||
|
||||
@Parcelize
|
||||
data class Comments(
|
||||
val count: Int,
|
||||
@SerializedName("can_post")
|
||||
val canPost: Int,
|
||||
@SerializedName("groups_can_post")
|
||||
val groupsCanPost: Boolean
|
||||
) : Parcelable
|
||||
|
||||
@Parcelize
|
||||
data class Likes(
|
||||
val count: Int,
|
||||
@SerializedName("user_likes")
|
||||
val userLikes: Int,
|
||||
@SerializedName("can_like")
|
||||
val canLike: Int,
|
||||
@SerializedName("can_publish")
|
||||
val canPublish: Int,
|
||||
) : Parcelable
|
||||
|
||||
@Parcelize
|
||||
data class Reposts(
|
||||
val count: Int,
|
||||
@SerializedName("user_reposted")
|
||||
val userReposted: Int
|
||||
) : Parcelable
|
||||
|
||||
@Parcelize
|
||||
data class Views(
|
||||
val count: Int
|
||||
) : Parcelable
|
||||
|
||||
@Parcelize
|
||||
data class Donut(
|
||||
@SerializedName("is_donut")
|
||||
val isDonut: Boolean
|
||||
) : Parcelable
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
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 BaseVkWallReply(
|
||||
val id: Int,
|
||||
@SerializedName("from_id")
|
||||
val fromId: Int,
|
||||
val date: Int,
|
||||
val text: String,
|
||||
@SerializedName("post_id")
|
||||
val postId: Int,
|
||||
@SerializedName("owner_id")
|
||||
val ownerId: Int,
|
||||
@SerializedName("parents_stack")
|
||||
val parentsStack: List<Int>,
|
||||
val likes: Likes,
|
||||
@SerializedName("reply_to_user")
|
||||
val replyToUser: Int?,
|
||||
@SerializedName("reply_to_comment")
|
||||
val replyToComment: Int?
|
||||
) : Parcelable {
|
||||
|
||||
|
||||
@Parcelize
|
||||
data class Likes(
|
||||
val count: Int,
|
||||
@SerializedName("can_like")
|
||||
val canLike: Int,
|
||||
@SerializedName("user_likes")
|
||||
val userLikes: Int,
|
||||
@SerializedName("can_publish")
|
||||
val canPublish: Int
|
||||
) : Parcelable
|
||||
|
||||
}
|
||||
@@ -18,20 +18,20 @@ object VKAttachments {
|
||||
val jsonObject = attachment.optJSONObject(type.value) ?: continue
|
||||
|
||||
when (type) {
|
||||
Type.PHOTO -> attachments.add(VKPhoto(jsonObject))
|
||||
Type.AUDIO -> attachments.add(VKAudio(jsonObject))
|
||||
Type.VIDEO -> attachments.add(VKVideo(jsonObject))
|
||||
Type.DOCUMENT -> attachments.add(VKDocument(jsonObject))
|
||||
Type.STICKER -> attachments.add(VKSticker(jsonObject))
|
||||
Type.LINK -> attachments.add(VKLink(jsonObject))
|
||||
Type.GIFT -> attachments.add(VKGift(jsonObject))
|
||||
Type.VOICE_MESSAGE -> attachments.add(VKAudioMessage(jsonObject))
|
||||
Type.GRAFFITI -> attachments.add(VKGraffiti(jsonObject))
|
||||
Type.POLL -> attachments.add(VKPoll(jsonObject))
|
||||
// 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(VKComment(jsonObject))
|
||||
Type.GEOLOCATION -> attachments.add(VKGeolocation(jsonObject))
|
||||
// Type.WALL_POST -> attachments.add(VKWall(jsonObject))
|
||||
Type.WALL_REPLY -> attachments.add(oldVKComment(jsonObject))
|
||||
// Type.GEOLOCATION -> attachments.add(oldVKGeolocation(jsonObject))
|
||||
else -> continue
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,6 @@ class VKLongPollHistory : VKModel() {
|
||||
private val lpMessages: ArrayList<oldVKMessage>? = null
|
||||
private val messages: ArrayList<oldVKMessage>? = null
|
||||
private val profiles: ArrayList<oldVKUser>? = null
|
||||
private val groups: ArrayList<VKGroup>? = null //TODO: использовать
|
||||
private val groups: ArrayList<oldVKGroup>? = null //TODO: использовать
|
||||
|
||||
}
|
||||
+1
-1
@@ -2,7 +2,7 @@ package com.meloda.fast.api.model.old
|
||||
|
||||
import org.json.JSONObject
|
||||
|
||||
class VKAudio() : VKModel() {
|
||||
class oldVKAudio() : VKModel() {
|
||||
|
||||
companion object {
|
||||
const val serialVersionUID: Long = 1L
|
||||
+1
-1
@@ -2,7 +2,7 @@ package com.meloda.fast.api.model.old
|
||||
|
||||
import org.json.JSONObject
|
||||
|
||||
class VKAudioMessage() : VKModel() {
|
||||
class oldVKAudioMessage() : VKModel() {
|
||||
|
||||
companion object {
|
||||
const val serialVersionUID: Long = 1L
|
||||
+1
-1
@@ -2,7 +2,7 @@ package com.meloda.fast.api.model.old
|
||||
|
||||
import org.json.JSONObject
|
||||
|
||||
class VKComment() : VKModel() { //https://vk.com/dev/objects/comment
|
||||
class oldVKComment() : VKModel() { //https://vk.com/dev/objects/comment
|
||||
|
||||
companion object {
|
||||
const val serialVersionUID: Long = 1L
|
||||
@@ -10,7 +10,7 @@ class oldVKConversation() : VKModel(), Cloneable {
|
||||
const val serialVersionUID: Long = 1L
|
||||
|
||||
var profiles = arrayListOf<oldVKUser>()
|
||||
var groups = arrayListOf<VKGroup>()
|
||||
var groups = arrayListOf<oldVKGroup>()
|
||||
|
||||
var conversationsCount: Int = 0
|
||||
|
||||
@@ -56,7 +56,7 @@ class oldVKConversation() : VKModel(), Cloneable {
|
||||
|
||||
var peerUser: oldVKUser? = null
|
||||
|
||||
var peerGroup: VKGroup? = null
|
||||
var peerGroup: oldVKGroup? = null
|
||||
|
||||
constructor(o: JSONObject) : this() {
|
||||
inReadMessageId = o.optInt("in_read")
|
||||
|
||||
+4
-4
@@ -4,7 +4,7 @@ import org.json.JSONObject
|
||||
import java.io.Serializable
|
||||
import java.util.*
|
||||
|
||||
class VKDocument() : VKModel() {
|
||||
class oldVKDocument() : VKModel() {
|
||||
|
||||
override val attachmentType = VKAttachments.Type.DOCUMENT
|
||||
|
||||
@@ -47,13 +47,13 @@ class VKDocument() : VKModel() {
|
||||
|
||||
inner class Photo(o: JSONObject) : Serializable {
|
||||
|
||||
var sizes: ArrayList<VKPhotoSize>? = null
|
||||
var sizes: ArrayList<oldVKPhotoSize>? = null
|
||||
|
||||
init {
|
||||
o.optJSONArray("sizes")?.let {
|
||||
val sizes = ArrayList<VKPhotoSize>()
|
||||
val sizes = ArrayList<oldVKPhotoSize>()
|
||||
for (i in 0 until it.length()) {
|
||||
sizes.add(VKPhotoSize(it.optJSONObject(i)))
|
||||
sizes.add(oldVKPhotoSize(it.optJSONObject(i)))
|
||||
}
|
||||
this.sizes = sizes
|
||||
}
|
||||
+1
-1
@@ -2,7 +2,7 @@ package com.meloda.fast.api.model.old
|
||||
|
||||
import org.json.JSONObject
|
||||
|
||||
class VKGeolocation() : VKModel() {
|
||||
class oldVKGeolocation() : VKModel() {
|
||||
|
||||
companion object {
|
||||
const val serialVersionUID: Long = 1L
|
||||
+1
-1
@@ -2,7 +2,7 @@ package com.meloda.fast.api.model.old
|
||||
|
||||
import org.json.JSONObject
|
||||
|
||||
class VKGift() : VKModel() {
|
||||
class oldVKGift() : VKModel() {
|
||||
|
||||
companion object {
|
||||
const val serialVersionUID: Long = 1L
|
||||
+1
-1
@@ -2,7 +2,7 @@ package com.meloda.fast.api.model.old
|
||||
|
||||
import org.json.JSONObject
|
||||
|
||||
class VKGraffiti() : VKModel() {
|
||||
class oldVKGraffiti() : VKModel() {
|
||||
|
||||
companion object {
|
||||
const val serialVersionUID: Long = 1L
|
||||
+4
-4
@@ -3,7 +3,7 @@ package com.meloda.fast.api.model.old
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONObject
|
||||
|
||||
open class VKGroup() : VKModel() {
|
||||
open class oldVKGroup() : VKModel() {
|
||||
|
||||
override val attachmentType = VKAttachments.Type.NONE
|
||||
|
||||
@@ -11,11 +11,11 @@ open class VKGroup() : VKModel() {
|
||||
|
||||
const val serialVersionUID: Long = 1L
|
||||
|
||||
fun parse(array: JSONArray): ArrayList<VKGroup> {
|
||||
val groups = ArrayList<VKGroup>()
|
||||
fun parse(array: JSONArray): ArrayList<oldVKGroup> {
|
||||
val groups = ArrayList<oldVKGroup>()
|
||||
|
||||
for (i in 0 until array.length()) {
|
||||
groups.add(VKGroup(array.optJSONObject(i)))
|
||||
groups.add(oldVKGroup(array.optJSONObject(i)))
|
||||
}
|
||||
return groups
|
||||
}
|
||||
+3
-3
@@ -3,7 +3,7 @@ package com.meloda.fast.api.model.old
|
||||
import org.json.JSONObject
|
||||
import java.io.Serializable
|
||||
|
||||
class VKLink() : VKModel() {
|
||||
class oldVKLink() : VKModel() {
|
||||
|
||||
companion object {
|
||||
const val serialVersionUID: Long = 1L
|
||||
@@ -17,7 +17,7 @@ class VKLink() : VKModel() {
|
||||
var description: String = ""
|
||||
var previewPage: String = ""
|
||||
var previewUrl: String = ""
|
||||
var photo: VKPhoto? = null
|
||||
var photo: oldVKPhoto? = null
|
||||
var button: Button? = null
|
||||
|
||||
constructor(o: JSONObject): this() {
|
||||
@@ -29,7 +29,7 @@ class VKLink() : VKModel() {
|
||||
previewUrl = o.optString("preview_url")
|
||||
|
||||
o.optJSONObject("photo")?.let {
|
||||
photo = VKPhoto(it)
|
||||
photo = oldVKPhoto(it)
|
||||
}
|
||||
|
||||
o.optJSONObject("button")?.let {
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.meloda.fast.api.model.old
|
||||
|
||||
import android.util.ArrayMap
|
||||
import com.meloda.fast.api.VKUtil
|
||||
import com.meloda.fast.api.oldVKUtil
|
||||
import org.json.JSONObject
|
||||
|
||||
open class oldVKMessage() : VKModel() {
|
||||
@@ -11,7 +11,7 @@ open class oldVKMessage() : VKModel() {
|
||||
companion object {
|
||||
|
||||
var profiles = arrayListOf<oldVKUser>()
|
||||
var groups = arrayListOf<VKGroup>()
|
||||
var groups = arrayListOf<oldVKGroup>()
|
||||
var conversations = arrayListOf<oldVKConversation>()
|
||||
|
||||
const val serialVersionUID: Long = 1L
|
||||
@@ -101,11 +101,11 @@ open class oldVKMessage() : VKModel() {
|
||||
|
||||
var replyMessage: oldVKMessage? = null
|
||||
|
||||
var action: VKMessageAction? = null
|
||||
var action: oldVKMessageAction? = null
|
||||
|
||||
var fromUser: oldVKUser? = null
|
||||
|
||||
var fromGroup: VKGroup? = null
|
||||
var fromGroup: oldVKGroup? = null
|
||||
|
||||
constructor(o: JSONObject) : this() {
|
||||
id = o.optInt("id", -1)
|
||||
@@ -115,7 +115,7 @@ open class oldVKMessage() : VKModel() {
|
||||
editTime = o.optInt("edit_time", -1)
|
||||
isOut = o.optInt("out") == 1
|
||||
|
||||
text = VKUtil.prepareMessageText(o.optString("text"))
|
||||
text = oldVKUtil.prepareMessageText(o.optString("text"))
|
||||
|
||||
randomId = o.optInt("random_id", -1)
|
||||
conversationMessageId = o.optInt("conversation_message_id", -1)
|
||||
@@ -138,7 +138,7 @@ open class oldVKMessage() : VKModel() {
|
||||
}
|
||||
|
||||
o.optJSONObject("action")?.let {
|
||||
action = VKMessageAction(it)
|
||||
action = oldVKMessageAction(it)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@ package com.meloda.fast.api.model.old
|
||||
|
||||
import org.json.JSONObject
|
||||
|
||||
class VKMessageAction() : VKModel() {
|
||||
class oldVKMessageAction() : VKModel() {
|
||||
|
||||
companion object {
|
||||
const val serialVersionUID: Long = 1L
|
||||
+4
-4
@@ -3,7 +3,7 @@ package com.meloda.fast.api.model.old
|
||||
import org.json.JSONObject
|
||||
import java.util.*
|
||||
|
||||
class VKPhoto() : VKModel() {
|
||||
class oldVKPhoto() : VKModel() {
|
||||
|
||||
companion object {
|
||||
const val serialVersionUID: Long = 1L
|
||||
@@ -18,7 +18,7 @@ class VKPhoto() : VKModel() {
|
||||
var date: Int = 0
|
||||
var width: Int = 0
|
||||
var height: Int = 0
|
||||
var sizes: ArrayList<VKPhotoSize>? = null
|
||||
var sizes: ArrayList<oldVKPhotoSize>? = null
|
||||
|
||||
constructor(o: JSONObject) : this() {
|
||||
id = o.optInt("id", -1)
|
||||
@@ -30,9 +30,9 @@ class VKPhoto() : VKModel() {
|
||||
height = o.optInt("height")
|
||||
|
||||
o.optJSONArray("sizes")?.let {
|
||||
val sizes = ArrayList<VKPhotoSize>()
|
||||
val sizes = ArrayList<oldVKPhotoSize>()
|
||||
for (i in 0 until it.length()) {
|
||||
sizes.add(VKPhotoSize(it.optJSONObject(i)))
|
||||
sizes.add(oldVKPhotoSize(it.optJSONObject(i)))
|
||||
}
|
||||
this.sizes = sizes
|
||||
}
|
||||
+1
-1
@@ -2,7 +2,7 @@ package com.meloda.fast.api.model.old
|
||||
|
||||
import org.json.JSONObject
|
||||
|
||||
class VKPhotoSize(o: JSONObject) : VKModel() {
|
||||
class oldVKPhotoSize(o: JSONObject) : VKModel() {
|
||||
|
||||
companion object {
|
||||
const val serialVersionUID: Long = 1L
|
||||
+1
-1
@@ -2,7 +2,7 @@ package com.meloda.fast.api.model.old
|
||||
|
||||
import org.json.JSONObject
|
||||
|
||||
class VKPoll() : VKModel() {
|
||||
class oldVKPoll() : VKModel() {
|
||||
|
||||
companion object {
|
||||
const val serialVersionUID: Long = 1L
|
||||
+1
-1
@@ -3,7 +3,7 @@ package com.meloda.fast.api.model.old
|
||||
import org.json.JSONObject
|
||||
import java.util.*
|
||||
|
||||
class VKSticker() : VKModel() {
|
||||
class oldVKSticker() : VKModel() {
|
||||
|
||||
companion object {
|
||||
const val serialVersionUID: Long = 1L
|
||||
+1
-1
@@ -4,7 +4,7 @@ import com.meloda.fast.api.model.old.VKAttachments
|
||||
import com.meloda.fast.api.model.old.VKModel
|
||||
import org.json.JSONObject
|
||||
|
||||
class VKVideo() : VKModel() {
|
||||
class oldVKVideo() : VKModel() {
|
||||
|
||||
companion object {
|
||||
const val serialVersionUID: Long = 1L
|
||||
+1
-1
@@ -2,7 +2,7 @@ package com.meloda.fast.api.model.old
|
||||
|
||||
import org.json.JSONObject
|
||||
|
||||
class VKWall() : VKModel() { //https://vk.com/dev/objects/post
|
||||
class oldVKWall() : VKModel() { //https://vk.com/dev/objects/post
|
||||
|
||||
companion object {
|
||||
const val serialVersionUID: Long = 1L
|
||||
@@ -3,14 +3,15 @@ package com.meloda.fast.api.network.repo
|
||||
import com.meloda.fast.api.base.ApiResponse
|
||||
import com.meloda.fast.api.network.Answer
|
||||
import com.meloda.fast.api.network.VKUrls
|
||||
import com.meloda.fast.api.network.request.ConversationsGetRequest
|
||||
import com.meloda.fast.api.network.response.ConversationsGetResponse
|
||||
import retrofit2.http.Body
|
||||
import retrofit2.http.FieldMap
|
||||
import retrofit2.http.FormUrlEncoded
|
||||
import retrofit2.http.POST
|
||||
|
||||
interface ConversationsRepo {
|
||||
|
||||
@FormUrlEncoded
|
||||
@POST(VKUrls.Conversations.get)
|
||||
suspend fun getAllChats(@Body params: ConversationsGetRequest): Answer<ApiResponse<ConversationsGetResponse>>
|
||||
suspend fun getAllChats(@FieldMap params: Map<String, String>): Answer<ApiResponse<ConversationsGetResponse>>
|
||||
|
||||
}
|
||||
@@ -4,12 +4,16 @@ import com.meloda.fast.api.base.ApiResponse
|
||||
import com.meloda.fast.api.model.base.BaseVkUser
|
||||
import com.meloda.fast.api.network.Answer
|
||||
import com.meloda.fast.api.network.VKUrls
|
||||
import retrofit2.http.GET
|
||||
import retrofit2.http.QueryMap
|
||||
import retrofit2.http.FieldMap
|
||||
import retrofit2.http.FormUrlEncoded
|
||||
import retrofit2.http.POST
|
||||
|
||||
interface UsersRepo {
|
||||
|
||||
@GET(VKUrls.Users.getById)
|
||||
suspend fun getById(@QueryMap params: Map<String, String>): Answer<ApiResponse<List<BaseVkUser>>>
|
||||
@FormUrlEncoded
|
||||
@POST(VKUrls.Users.getById)
|
||||
suspend fun getById(
|
||||
@FieldMap params: Map<String, String>?
|
||||
): Answer<ApiResponse<List<BaseVkUser>>>
|
||||
|
||||
}
|
||||
@@ -13,4 +13,16 @@ data class ConversationsGetRequest(
|
||||
val extended: Boolean? = true,
|
||||
@SerializedName("start_message_id")
|
||||
val startMessageId: Int? = null
|
||||
) : Parcelable
|
||||
) : Parcelable {
|
||||
|
||||
val map
|
||||
get() = mutableMapOf(
|
||||
"fields" to fields,
|
||||
"filter" to filter
|
||||
).apply {
|
||||
count?.let { this["count"] = it.toString() }
|
||||
offset?.let { this["offset"] = it.toString() }
|
||||
extended?.let { this["extended"] = it.toString() }
|
||||
startMessageId?.let { this["start_message_id"] = it.toString() }
|
||||
}
|
||||
}
|
||||
@@ -5,17 +5,17 @@ import kotlinx.parcelize.Parcelize
|
||||
|
||||
@Parcelize
|
||||
data class UsersGetRequest(
|
||||
val usersIds: List<Int>,
|
||||
val usersIds: List<Int>? = null,
|
||||
val fields: String? = null,
|
||||
val nomCase: String? = null
|
||||
) : Parcelable {
|
||||
|
||||
val map
|
||||
get() = mutableMapOf(
|
||||
"user_ids" to usersIds.joinToString { it.toString() }
|
||||
).apply {
|
||||
fields?.let { this["fields"] = it }
|
||||
nomCase?.let { this["nom_case"] = it }
|
||||
}
|
||||
get() = mutableMapOf<String, String>()
|
||||
.apply {
|
||||
usersIds?.let { this["user_ids"] = it.joinToString { id -> id.toString() } }
|
||||
fields?.let { this["fields"] = it }
|
||||
nomCase?.let { this["nom_case"] = it }
|
||||
}
|
||||
|
||||
}
|
||||
@@ -3,7 +3,9 @@ package com.meloda.fast.api.network.response
|
||||
import android.os.Parcelable
|
||||
import com.google.gson.annotations.SerializedName
|
||||
import com.meloda.fast.api.model.base.BaseVkConversation
|
||||
import com.meloda.fast.api.model.base.BaseVkGroup
|
||||
import com.meloda.fast.api.model.base.BaseVkMessage
|
||||
import com.meloda.fast.api.model.base.BaseVkUser
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
@Parcelize
|
||||
@@ -11,7 +13,9 @@ data class ConversationsGetResponse(
|
||||
val count: Int,
|
||||
val items: List<ConversationsResponseItems>,
|
||||
@SerializedName("unread_count")
|
||||
val unreadCount: Int?
|
||||
val unreadCount: Int?,
|
||||
val profiles: List<BaseVkUser>?,
|
||||
val groups: List<BaseVkGroup>?
|
||||
) : Parcelable
|
||||
|
||||
@Parcelize
|
||||
|
||||
+16
-16
@@ -10,7 +10,7 @@ import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
|
||||
// TODO: 8/31/2021 review
|
||||
object VKUtil {
|
||||
object oldVKUtil {
|
||||
|
||||
private const val TAG = "VKUtil"
|
||||
|
||||
@@ -122,7 +122,7 @@ object VKUtil {
|
||||
fun getTitle(
|
||||
conversation: oldVKConversation,
|
||||
peerUser: oldVKUser?,
|
||||
peerGroup: VKGroup?
|
||||
peerGroup: oldVKGroup?
|
||||
): String {
|
||||
return when {
|
||||
conversation.isUser() -> peerUser?.let { return it.toString() } ?: ""
|
||||
@@ -140,7 +140,7 @@ object VKUtil {
|
||||
fun getMessageTitle(
|
||||
message: oldVKMessage,
|
||||
fromUser: oldVKUser?,
|
||||
fromGroup: VKGroup?
|
||||
fromGroup: oldVKGroup?
|
||||
): String {
|
||||
return when {
|
||||
message.isFromUser() -> {
|
||||
@@ -158,7 +158,7 @@ object VKUtil {
|
||||
fun getAvatar(
|
||||
conversation: oldVKConversation,
|
||||
peerUser: oldVKUser?,
|
||||
peerGroup: VKGroup?
|
||||
peerGroup: oldVKGroup?
|
||||
): String {
|
||||
return when {
|
||||
conversation.isUser() -> {
|
||||
@@ -180,7 +180,7 @@ object VKUtil {
|
||||
fun getUserAvatar(
|
||||
message: oldVKMessage,
|
||||
fromUser: oldVKUser?,
|
||||
fromGroup: VKGroup?
|
||||
fromGroup: oldVKGroup?
|
||||
): String {
|
||||
return when {
|
||||
message.isFromUser() -> {
|
||||
@@ -211,7 +211,7 @@ object VKUtil {
|
||||
return ""
|
||||
}
|
||||
|
||||
fun getGroupPhoto(group: VKGroup): String {
|
||||
fun getGroupPhoto(group: oldVKGroup): String {
|
||||
if (group.photo200.isEmpty()) {
|
||||
if (group.photo100.isEmpty()) {
|
||||
if (group.photo50.isEmpty()) {
|
||||
@@ -286,19 +286,19 @@ object VKUtil {
|
||||
}
|
||||
|
||||
if (it.has("source_act")) {
|
||||
message.action = VKMessageAction().also { action ->
|
||||
message.action = oldVKMessageAction().also { action ->
|
||||
action.type =
|
||||
VKMessageAction.Type.fromString(it.optString("source_act"))
|
||||
oldVKMessageAction.Type.fromString(it.optString("source_act"))
|
||||
|
||||
when (action.type) {
|
||||
VKMessageAction.Type.CHAT_CREATE -> {
|
||||
oldVKMessageAction.Type.CHAT_CREATE -> {
|
||||
action.text = it.optString("source_text")
|
||||
}
|
||||
VKMessageAction.Type.TITLE_UPDATE -> {
|
||||
oldVKMessageAction.Type.TITLE_UPDATE -> {
|
||||
action.oldText = it.optString("source_old_text")
|
||||
action.text = it.optString("source_text")
|
||||
}
|
||||
VKMessageAction.Type.PIN_MESSAGE -> {
|
||||
oldVKMessageAction.Type.PIN_MESSAGE -> {
|
||||
action.memberId = it.optInt("source_mid")
|
||||
action.conversationMessageId = it.optInt("source_chat_local_id")
|
||||
|
||||
@@ -306,14 +306,14 @@ object VKUtil {
|
||||
action.message = oldVKMessage(message)
|
||||
}
|
||||
}
|
||||
VKMessageAction.Type.UNPIN_MESSAGE -> {
|
||||
oldVKMessageAction.Type.UNPIN_MESSAGE -> {
|
||||
action.memberId = it.optInt("source_mid")
|
||||
action.conversationMessageId = it.optInt("source_chat_local_id")
|
||||
}
|
||||
VKMessageAction.Type.INVITE_USER,
|
||||
VKMessageAction.Type.KICK_USER,
|
||||
VKMessageAction.Type.SCREENSHOT,
|
||||
VKMessageAction.Type.INVITE_USER_BY_CALL -> {
|
||||
oldVKMessageAction.Type.INVITE_USER,
|
||||
oldVKMessageAction.Type.KICK_USER,
|
||||
oldVKMessageAction.Type.SCREENSHOT,
|
||||
oldVKMessageAction.Type.INVITE_USER_BY_CALL -> {
|
||||
action.memberId = it.optInt("source_mid")
|
||||
}
|
||||
}
|
||||
@@ -3,9 +3,11 @@ package com.meloda.fast.database
|
||||
import androidx.room.Database
|
||||
import androidx.room.RoomDatabase
|
||||
import com.meloda.fast.api.model.VkConversation
|
||||
import com.meloda.fast.api.model.VkGroup
|
||||
import com.meloda.fast.api.model.VkMessage
|
||||
import com.meloda.fast.api.model.VkUser
|
||||
import com.meloda.fast.database.dao.ConversationsDao
|
||||
import com.meloda.fast.database.dao.GroupsDao
|
||||
import com.meloda.fast.database.dao.MessagesDao
|
||||
import com.meloda.fast.database.dao.UsersDao
|
||||
|
||||
@@ -13,9 +15,10 @@ import com.meloda.fast.database.dao.UsersDao
|
||||
entities = [
|
||||
VkConversation::class,
|
||||
VkMessage::class,
|
||||
VkUser::class
|
||||
VkUser::class,
|
||||
VkGroup::class
|
||||
],
|
||||
version = 1,
|
||||
version = 8,
|
||||
exportSchema = false
|
||||
)
|
||||
abstract class AppDatabase : RoomDatabase() {
|
||||
@@ -23,5 +26,6 @@ abstract class AppDatabase : RoomDatabase() {
|
||||
abstract fun conversationsDao(): ConversationsDao
|
||||
abstract fun messagesDao(): MessagesDao
|
||||
abstract fun usersDao(): UsersDao
|
||||
abstract fun groupsDao(): GroupsDao
|
||||
|
||||
}
|
||||
@@ -1,8 +1,20 @@
|
||||
package com.meloda.fast.database.dao
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import com.meloda.fast.api.model.VkConversation
|
||||
|
||||
@Dao
|
||||
interface ConversationsDao : KindaDao<VkConversation> {
|
||||
interface ConversationsDao {
|
||||
|
||||
@Query("SELECT * FROM conversations")
|
||||
suspend fun getAll(): List<VkConversation>
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
suspend fun insert(values: List<VkConversation>)
|
||||
|
||||
suspend fun insert(values: Array<out VkConversation>) = insert(values.toList())
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.meloda.fast.database.dao
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import com.meloda.fast.api.model.VkGroup
|
||||
|
||||
@Dao
|
||||
interface GroupsDao {
|
||||
|
||||
@Query("SELECT * FROM groups")
|
||||
suspend fun getAll(): List<VkGroup>
|
||||
|
||||
@Query("SELECT * FROM groups WHERE id = :id")
|
||||
suspend fun getById(id: Int): VkGroup?
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
suspend fun insert(values: List<VkGroup>)
|
||||
|
||||
suspend fun insert(values: Array<out VkGroup>) = insert(values.toList())
|
||||
|
||||
}
|
||||
@@ -9,12 +9,15 @@ import com.meloda.fast.api.model.VkUser
|
||||
@Dao
|
||||
interface UsersDao {
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
suspend fun insert(values: List<VkUser>)
|
||||
|
||||
@Query("SELECT * FROM users")
|
||||
suspend fun getAll(): List<VkUser>
|
||||
|
||||
@Query("SELECT * FROM users WHERE id = :id")
|
||||
suspend fun getById(id: Int): VkUser?
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
suspend fun insert(values: List<VkUser>)
|
||||
|
||||
suspend fun insert(values: Array<out VkUser>) = insert(values.toList())
|
||||
|
||||
}
|
||||
@@ -26,7 +26,7 @@ import com.meloda.fast.database.old.DatabaseKeys.UNREAD_COUNT
|
||||
import com.meloda.fast.database.old.DatabaseUtils.TABLE_CHATS
|
||||
import com.meloda.fast.database.old.base.Storage
|
||||
import com.meloda.fast.api.model.old.oldVKConversation
|
||||
import com.meloda.fast.api.VKUtil
|
||||
import com.meloda.fast.api.oldVKUtil
|
||||
import org.json.JSONObject
|
||||
|
||||
@WorkerThread
|
||||
@@ -86,7 +86,7 @@ class ChatsStorage : Storage<oldVKConversation>() {
|
||||
|
||||
values.put(
|
||||
PHOTOS,
|
||||
VKUtil.putPhotosToJson(
|
||||
oldVKUtil.putPhotosToJson(
|
||||
value.photo50,
|
||||
value.photo100,
|
||||
value.photo200
|
||||
@@ -130,7 +130,7 @@ class ChatsStorage : Storage<oldVKConversation>() {
|
||||
val lastMessage = messagesStorage.getMessageById(conversation.lastMessageId)
|
||||
if (lastMessage != null) conversation.lastMessage = lastMessage
|
||||
|
||||
val photos = VKUtil.parseJsonPhotos(JSONObject(CacheStorage.getString(cursor, PHOTOS)))
|
||||
val photos = oldVKUtil.parseJsonPhotos(JSONObject(CacheStorage.getString(cursor, PHOTOS)))
|
||||
conversation.photo50 = photos[0]
|
||||
conversation.photo100 = photos[1]
|
||||
conversation.photo200 = photos[2]
|
||||
|
||||
@@ -17,19 +17,19 @@ import com.meloda.fast.database.old.DatabaseKeys.SCREEN_NAME
|
||||
import com.meloda.fast.database.old.DatabaseKeys.TYPE
|
||||
import com.meloda.fast.database.old.DatabaseUtils.TABLE_GROUPS
|
||||
import com.meloda.fast.database.old.base.Storage
|
||||
import com.meloda.fast.api.model.old.VKGroup
|
||||
import com.meloda.fast.api.VKUtil
|
||||
import com.meloda.fast.api.model.old.oldVKGroup
|
||||
import com.meloda.fast.api.oldVKUtil
|
||||
import org.json.JSONObject
|
||||
|
||||
class GroupsStorage : Storage<VKGroup>() {
|
||||
class GroupsStorage : Storage<oldVKGroup>() {
|
||||
|
||||
override val tag = "GroupsStorage"
|
||||
|
||||
@WorkerThread
|
||||
fun getGroups(ids: IntArray): ArrayList<VKGroup> {
|
||||
fun getGroups(ids: IntArray): ArrayList<oldVKGroup> {
|
||||
val cursor = CacheStorage.selectCursor(TABLE_GROUPS, GROUP_ID, ids)
|
||||
|
||||
val groups = ArrayList<VKGroup>(cursor.count)
|
||||
val groups = ArrayList<oldVKGroup>(cursor.count)
|
||||
while (cursor.moveToNext()) groups.add(parseValue(cursor))
|
||||
|
||||
cursor.close()
|
||||
@@ -37,15 +37,15 @@ class GroupsStorage : Storage<VKGroup>() {
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
fun getGroup(userId: Int): VKGroup? {
|
||||
fun getGroup(userId: Int): oldVKGroup? {
|
||||
val group = getGroups(intArrayOf(userId))
|
||||
|
||||
return if (group.isNotEmpty()) group[0] else null
|
||||
}
|
||||
|
||||
override fun getAllValues(): ArrayList<VKGroup> {
|
||||
override fun getAllValues(): ArrayList<oldVKGroup> {
|
||||
val cursor = CacheStorage.selectCursor(TABLE_GROUPS)
|
||||
val groups = ArrayList<VKGroup>()
|
||||
val groups = ArrayList<oldVKGroup>()
|
||||
|
||||
while (cursor.moveToNext()) groups.add(parseValue(cursor))
|
||||
|
||||
@@ -54,7 +54,7 @@ class GroupsStorage : Storage<VKGroup>() {
|
||||
return groups
|
||||
}
|
||||
|
||||
override fun insertValues(values: ArrayList<VKGroup>, params: Bundle?) {
|
||||
override fun insertValues(values: ArrayList<oldVKGroup>, params: Bundle?) {
|
||||
if (values.isEmpty()) return
|
||||
|
||||
database.beginTransaction()
|
||||
@@ -75,7 +75,7 @@ class GroupsStorage : Storage<VKGroup>() {
|
||||
Log.d(tag, "Successful cached groups")
|
||||
}
|
||||
|
||||
override fun cacheValue(values: ContentValues, value: VKGroup, params: Bundle?) {
|
||||
override fun cacheValue(values: ContentValues, value: oldVKGroup, params: Bundle?) {
|
||||
values.put(GROUP_ID, value.id)
|
||||
values.put(NAME, value.name)
|
||||
values.put(SCREEN_NAME, value.screenName)
|
||||
@@ -84,22 +84,22 @@ class GroupsStorage : Storage<VKGroup>() {
|
||||
values.put(TYPE, value.type.value)
|
||||
|
||||
val photos =
|
||||
VKUtil.putPhotosToJson(value.photo50, value.photo100, value.photo200).toString()
|
||||
oldVKUtil.putPhotosToJson(value.photo50, value.photo100, value.photo200).toString()
|
||||
|
||||
values.put(PHOTOS, photos)
|
||||
}
|
||||
|
||||
override fun parseValue(cursor: Cursor): VKGroup {
|
||||
val group = VKGroup()
|
||||
override fun parseValue(cursor: Cursor): oldVKGroup {
|
||||
val group = oldVKGroup()
|
||||
|
||||
group.id = getInt(cursor, GROUP_ID)
|
||||
group.name = getString(cursor, NAME)
|
||||
group.screenName = getString(cursor, SCREEN_NAME)
|
||||
group.isClosed = getInt(cursor, IS_CLOSED) == 1
|
||||
group.deactivated = getString(cursor, DEACTIVATED)
|
||||
group.type = VKGroup.Type.fromString(getString(cursor, TYPE))
|
||||
group.type = oldVKGroup.Type.fromString(getString(cursor, TYPE))
|
||||
|
||||
val photos = VKUtil.parseJsonPhotos(JSONObject(getString(cursor, PHOTOS)))
|
||||
val photos = oldVKUtil.parseJsonPhotos(JSONObject(getString(cursor, PHOTOS)))
|
||||
|
||||
group.photo50 = photos[0]
|
||||
group.photo100 = photos[1]
|
||||
|
||||
@@ -24,7 +24,7 @@ import com.meloda.fast.database.old.DatabaseUtils.TABLE_MESSAGES
|
||||
import com.meloda.fast.database.old.base.Storage
|
||||
import com.meloda.fast.util.Utils
|
||||
import com.meloda.fast.api.model.old.oldVKMessage
|
||||
import com.meloda.fast.api.model.old.VKMessageAction
|
||||
import com.meloda.fast.api.model.old.oldVKMessageAction
|
||||
import com.meloda.fast.api.model.old.VKModel
|
||||
import java.util.stream.Collectors
|
||||
|
||||
@@ -153,7 +153,7 @@ class MessagesStorage : Storage<oldVKMessage>() {
|
||||
if (replyMessage != null) message.replyMessage = replyMessage
|
||||
|
||||
val blobAction = Utils.deserialize(CacheStorage.getBlob(cursor, ACTION))
|
||||
if (blobAction != null) message.action = blobAction as VKMessageAction
|
||||
if (blobAction != null) message.action = blobAction as oldVKMessageAction
|
||||
|
||||
val stringFwdMessages = CacheStorage.getString(cursor, FWD_MESSAGES)
|
||||
if (stringFwdMessages != null) {
|
||||
|
||||
@@ -6,7 +6,7 @@ import android.os.Bundle
|
||||
import android.util.Log
|
||||
import androidx.annotation.WorkerThread
|
||||
import com.meloda.fast.api.UserConfig
|
||||
import com.meloda.fast.api.VKUtil
|
||||
import com.meloda.fast.api.oldVKUtil
|
||||
import com.meloda.fast.api.model.old.oldVKUser
|
||||
import com.meloda.fast.database.old.CacheStorage
|
||||
import com.meloda.fast.database.old.DatabaseKeys.DEACTIVATED
|
||||
@@ -135,7 +135,7 @@ class UsersStorage : Storage<oldVKUser>() {
|
||||
|
||||
values.put(
|
||||
PHOTOS,
|
||||
VKUtil.putPhotosToJson(
|
||||
oldVKUtil.putPhotosToJson(
|
||||
value.photo50,
|
||||
value.photo100,
|
||||
value.photo200
|
||||
@@ -159,7 +159,7 @@ class UsersStorage : Storage<oldVKUser>() {
|
||||
user.lastSeen = CacheStorage.getInt(cursor, LAST_SEEN)
|
||||
|
||||
val photos =
|
||||
VKUtil.parseJsonPhotos(JSONObject(CacheStorage.getString(cursor, PHOTOS)))
|
||||
oldVKUtil.parseJsonPhotos(JSONObject(CacheStorage.getString(cursor, PHOTOS)))
|
||||
|
||||
user.photo50 = photos[0]
|
||||
user.photo100 = photos[1]
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.meloda.fast.di
|
||||
import com.meloda.fast.common.AppGlobal
|
||||
import com.meloda.fast.database.AppDatabase
|
||||
import com.meloda.fast.database.dao.ConversationsDao
|
||||
import com.meloda.fast.database.dao.GroupsDao
|
||||
import com.meloda.fast.database.dao.MessagesDao
|
||||
import com.meloda.fast.database.dao.UsersDao
|
||||
import dagger.Module
|
||||
@@ -35,4 +36,9 @@ object DatabaseModule {
|
||||
fun provideMessagesDao(appDatabase: AppDatabase): MessagesDao =
|
||||
appDatabase.messagesDao()
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideGroupsDao(appDatabase: AppDatabase): GroupsDao =
|
||||
appDatabase.groupsDao()
|
||||
|
||||
}
|
||||
@@ -1,3 +1 @@
|
||||
package com.meloda.fast.extensions
|
||||
|
||||
fun Boolean.toApiStyle() = (if (this) 1 else 0).toString()
|
||||
@@ -5,7 +5,7 @@ import androidx.lifecycle.viewModelScope
|
||||
import com.meloda.fast.api.UserConfig
|
||||
import com.meloda.fast.api.VKConstants
|
||||
import com.meloda.fast.api.VKException
|
||||
import com.meloda.fast.api.VKUtil
|
||||
import com.meloda.fast.api.oldVKUtil
|
||||
import com.meloda.fast.api.datasource.AuthDataSource
|
||||
import com.meloda.fast.api.network.request.RequestAuthDirect
|
||||
import com.meloda.fast.base.viewmodel.BaseViewModel
|
||||
@@ -61,13 +61,13 @@ class LoginViewModel @Inject constructor(
|
||||
|
||||
twoFaCode?.let { sendEvent(CodeSent) }
|
||||
|
||||
if (VKUtil.isValidationRequired(it)) {
|
||||
if (oldVKUtil.isValidationRequired(it)) {
|
||||
it.validationSid?.let { sid ->
|
||||
sendEvent(ValidationRequired(validationSid = sid))
|
||||
|
||||
sendSms(sid)
|
||||
}
|
||||
} else if (VKUtil.isCaptchaRequired(it)) {
|
||||
} else if (oldVKUtil.isCaptchaRequired(it)) {
|
||||
it.captcha?.let { captcha ->
|
||||
sendEvent(CaptchaRequired(captcha.first to captcha.second))
|
||||
}
|
||||
|
||||
@@ -1,17 +1,142 @@
|
||||
package com.meloda.fast.screens.messages
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Color
|
||||
import android.graphics.drawable.ColorDrawable
|
||||
import android.text.SpannableString
|
||||
import android.text.style.ForegroundColorSpan
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.recyclerview.widget.DiffUtil
|
||||
import coil.load
|
||||
import com.meloda.fast.R
|
||||
import com.meloda.fast.api.UserConfig
|
||||
import com.meloda.fast.api.VkUtils
|
||||
import com.meloda.fast.api.model.VkConversation
|
||||
import com.meloda.fast.api.model.VkGroup
|
||||
import com.meloda.fast.api.model.VkUser
|
||||
import com.meloda.fast.base.adapter.BaseAdapter
|
||||
import com.meloda.fast.base.adapter.BindingHolder
|
||||
import com.meloda.fast.databinding.ItemConversationBinding
|
||||
import java.text.SimpleDateFormat
|
||||
|
||||
class ConversationsAdapter(context: Context, values: MutableList<VkConversation>) :
|
||||
BaseAdapter<VkConversation, ConversationsAdapter.ItemHolder>(
|
||||
context, values, COMPARATOR
|
||||
) {
|
||||
class ConversationsAdapter constructor(
|
||||
context: Context,
|
||||
values: MutableList<VkConversation>,
|
||||
val profiles: HashMap<Int, VkUser> = hashMapOf(),
|
||||
val groups: HashMap<Int, VkGroup> = hashMapOf()
|
||||
) : BaseAdapter<VkConversation, ConversationsAdapter.ItemHolder>(
|
||||
context, values, COMPARATOR
|
||||
) {
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
|
||||
ItemHolder(ItemConversationBinding.inflate(inflater, parent, false))
|
||||
|
||||
inner class ItemHolder(binding: ItemConversationBinding) :
|
||||
BindingHolder<ItemConversationBinding>(binding) {
|
||||
|
||||
private val dateColor = ContextCompat.getColor(context, R.color.date)
|
||||
private val youPrefix = context.getString(R.string.you_message_prefix)
|
||||
|
||||
override fun bind(position: Int) {
|
||||
val conversation = getItem(position)
|
||||
val message = conversation.lastMessage ?: return
|
||||
|
||||
val chatUser: VkUser? = if (conversation.isUser()) {
|
||||
profiles[conversation.id]
|
||||
// profiles.find { it.id == conversation.id }
|
||||
} else null
|
||||
|
||||
val messageUser: VkUser? = if (message.isUser()) {
|
||||
profiles[message.fromId]
|
||||
// profiles.find { it.id == message.fromId }
|
||||
} else null
|
||||
|
||||
val chatGroup: VkGroup? = if (conversation.isGroup()) {
|
||||
groups[conversation.id]
|
||||
// groups.find { it.id == conversation.id }
|
||||
} else null
|
||||
|
||||
val messageGroup: VkGroup? = if (message.isGroup()) {
|
||||
groups[message.fromId]
|
||||
// groups.find { it.id == message.fromId }
|
||||
} else null
|
||||
|
||||
val avatar = when {
|
||||
chatUser != null && !chatUser.photo200.isNullOrBlank() -> chatUser.photo200
|
||||
chatGroup != null && !chatGroup.photo200.isNullOrBlank() -> chatGroup.photo200
|
||||
!conversation.photo200.isNullOrBlank() -> conversation.photo200
|
||||
else -> null
|
||||
}
|
||||
|
||||
if (avatar == null) {
|
||||
binding.avatar.setImageDrawable(ColorDrawable(Color.RED))
|
||||
} else {
|
||||
binding.avatar.load(avatar) { crossfade(200) }
|
||||
}
|
||||
|
||||
binding.online.isVisible = chatUser?.online == true
|
||||
|
||||
val actionMessage = VkUtils.getActionConversationText(
|
||||
message = message,
|
||||
youPrefix = youPrefix,
|
||||
profiles = profiles,
|
||||
groups = groups,
|
||||
messageUser = messageUser,
|
||||
messageGroup = messageGroup
|
||||
)
|
||||
|
||||
val attachmentsMessage = VkUtils.getAttachmentConversationText(
|
||||
context = context,
|
||||
message = message
|
||||
)
|
||||
|
||||
val forwardsMessage = VkUtils.getForwardsConversationText(
|
||||
context = context,
|
||||
message = message
|
||||
)
|
||||
|
||||
val messageText = if (actionMessage != null ||
|
||||
attachmentsMessage != null ||
|
||||
forwardsMessage != null
|
||||
) ""
|
||||
else message.text ?: "no_message"
|
||||
|
||||
val coloredMessage = actionMessage ?: attachmentsMessage ?: forwardsMessage ?: ""
|
||||
|
||||
var prefix = when {
|
||||
actionMessage != null -> ""
|
||||
message.isOut -> "$youPrefix: "
|
||||
messageUser != null && messageUser.firstName.isNotBlank() -> "${messageUser.firstName}: "
|
||||
messageGroup != null && messageGroup.toString()
|
||||
.isNotBlank() -> "${messageGroup.name}: "
|
||||
else -> ""
|
||||
}
|
||||
|
||||
if (!conversation.isChat() && !message.isOut || conversation.id == UserConfig.userId) prefix =
|
||||
""
|
||||
|
||||
// if (conversation.isChat() || message.isOut) {
|
||||
val spanText = "$prefix$coloredMessage $messageText".trim()
|
||||
|
||||
val spanMessage = SpannableString(spanText)
|
||||
spanMessage.setSpan(
|
||||
ForegroundColorSpan(dateColor), 0,
|
||||
prefix.length + coloredMessage.length,
|
||||
0
|
||||
)
|
||||
binding.message.text = spanMessage
|
||||
// } else {
|
||||
// binding.message.text = messageText
|
||||
// }
|
||||
|
||||
binding.title.text =
|
||||
getItem(position).title ?: chatUser?.toString() ?: chatGroup?.name ?: "..."
|
||||
|
||||
binding.date.text = SimpleDateFormat("HH:mm").format(message.date * 1000)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val COMPARATOR = object : DiffUtil.ItemCallback<VkConversation>() {
|
||||
@@ -27,15 +152,4 @@ class ConversationsAdapter(context: Context, values: MutableList<VkConversation>
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
|
||||
ItemHolder(ItemConversationBinding.inflate(inflater, parent, false))
|
||||
|
||||
inner class ItemHolder(binding: ItemConversationBinding) :
|
||||
BindingHolder<ItemConversationBinding>(binding) {
|
||||
|
||||
override fun bind(position: Int) {
|
||||
binding.title.text = getItem(position).title ?: "HUI"
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -32,6 +32,8 @@ class ConversationsFragment :
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
viewModel.loadProfileUser()
|
||||
|
||||
prepareViews()
|
||||
|
||||
adapter = ConversationsAdapter(requireContext(), mutableListOf())
|
||||
@@ -43,7 +45,7 @@ class ConversationsFragment :
|
||||
override fun onEvent(event: VKEvent) {
|
||||
super.onEvent(event)
|
||||
when (event) {
|
||||
is ConversationsLoaded -> refreshConversations(event.conversations)
|
||||
is ConversationsLoaded -> refreshConversations(event)
|
||||
is StartProgressEvent -> onProgressStarted()
|
||||
is StopProgressEvent -> onProgressStopped()
|
||||
}
|
||||
@@ -91,10 +93,14 @@ class ConversationsFragment :
|
||||
}
|
||||
}
|
||||
|
||||
private fun refreshConversations(conversations: List<VkConversation>) {
|
||||
fillRecyclerView(conversations)
|
||||
private fun refreshConversations(event: ConversationsLoaded) {
|
||||
// adapter.profiles.clear()
|
||||
adapter.profiles += event.profiles
|
||||
|
||||
viewModel.loadSomeUsers(listOf(1, 2, 3, 362877006))
|
||||
// adapter.groups.clear()
|
||||
adapter.groups += event.groups
|
||||
|
||||
fillRecyclerView(event.conversations)
|
||||
}
|
||||
|
||||
private fun fillRecyclerView(values: List<VkConversation>) {
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
package com.meloda.fast.screens.messages
|
||||
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.meloda.fast.api.UserConfig
|
||||
import com.meloda.fast.api.VKConstants
|
||||
import com.meloda.fast.api.datasource.ConversationsDataSource
|
||||
import com.meloda.fast.api.datasource.UsersDataSource
|
||||
import com.meloda.fast.api.model.VkConversation
|
||||
import com.meloda.fast.api.model.VkGroup
|
||||
import com.meloda.fast.api.model.VkUser
|
||||
import com.meloda.fast.api.network.request.ConversationsGetRequest
|
||||
import com.meloda.fast.api.network.request.UsersGetRequest
|
||||
import com.meloda.fast.base.viewmodel.BaseViewModel
|
||||
@@ -14,6 +17,7 @@ import com.meloda.fast.base.viewmodel.VKEvent
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import java.util.*
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
@@ -27,12 +31,27 @@ class ConversationsViewModel @Inject constructor(
|
||||
dataSource.getAllChats(
|
||||
ConversationsGetRequest(
|
||||
count = 30,
|
||||
// offset = 37,
|
||||
extended = true,
|
||||
fields = "${VKConstants.USER_FIELDS},${VKConstants.GROUP_FIELDS}"
|
||||
)
|
||||
)
|
||||
},
|
||||
onAnswer = {
|
||||
it.response?.let { response ->
|
||||
val profiles = hashMapOf<Int, VkUser>()
|
||||
response.profiles?.forEach { baseUser ->
|
||||
baseUser.asVkUser().let { user -> profiles[user.id] = user }
|
||||
}
|
||||
|
||||
val groups = hashMapOf<Int, VkGroup>()
|
||||
response.groups?.forEach { baseGroup ->
|
||||
baseGroup.asVkGroup().let { group -> groups[group.id] = group }
|
||||
}
|
||||
|
||||
// val profiles = response.profiles?.map { profile -> profile.asVkUser() } ?: listOf()
|
||||
// val groups = response.groups?.map { group -> group.asVkGroup() } ?: listOf()
|
||||
|
||||
sendEvent(
|
||||
ConversationsLoaded(
|
||||
count = response.count,
|
||||
@@ -41,14 +60,16 @@ class ConversationsViewModel @Inject constructor(
|
||||
items.conversation.asVkConversation(
|
||||
items.lastMessage.asVkMessage()
|
||||
)
|
||||
}
|
||||
},
|
||||
profiles = profiles,
|
||||
groups = groups
|
||||
)
|
||||
)
|
||||
}
|
||||
},
|
||||
onError = {
|
||||
val er = it
|
||||
val i = 0
|
||||
throw it
|
||||
},
|
||||
onStart = {
|
||||
sendEvent(StartProgressEvent)
|
||||
@@ -58,34 +79,25 @@ class ConversationsViewModel @Inject constructor(
|
||||
})
|
||||
}
|
||||
|
||||
fun loadSomeUsers(usersIds: List<Int>) = viewModelScope.launch {
|
||||
fun loadProfileUser() = viewModelScope.launch {
|
||||
makeJob({
|
||||
usersDataSource.getById(
|
||||
UsersGetRequest(
|
||||
usersIds = usersIds,
|
||||
fields = "sex"
|
||||
)
|
||||
)
|
||||
usersDataSource.getById(UsersGetRequest(fields = "online,photo_200"))
|
||||
},
|
||||
onAnswer = {
|
||||
val argh = it
|
||||
val i = 0
|
||||
it.response?.let { r ->
|
||||
val users = r.map { user -> user.asVkUser() }
|
||||
|
||||
val users = r.map { u -> u.asVkUser() }
|
||||
usersDataSource.storeUsers(users)
|
||||
}
|
||||
},
|
||||
onError = {
|
||||
val e = it
|
||||
val i = 0
|
||||
})
|
||||
|
||||
UserConfig.vkUser = users[0]
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
data class ConversationsLoaded(
|
||||
val count: Int,
|
||||
val unreadCount: Int,
|
||||
val conversations: List<VkConversation>
|
||||
val conversations: List<VkConversation>,
|
||||
val profiles: HashMap<Int, VkUser>,
|
||||
val groups: HashMap<Int, VkGroup>
|
||||
) : VKEvent()
|
||||
@@ -4,7 +4,7 @@ import android.content.Context
|
||||
import android.graphics.drawable.Drawable
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.meloda.fast.R
|
||||
import com.meloda.fast.api.VKUtil
|
||||
import com.meloda.fast.api.oldVKUtil
|
||||
import com.meloda.fast.api.model.old.*
|
||||
import com.meloda.fast.common.AppGlobal
|
||||
import com.meloda.fast.extensions.ContextExtensions.color
|
||||
@@ -31,7 +31,7 @@ object VKUtils {
|
||||
} else {
|
||||
r.getString(
|
||||
R.string.user_last_seen_at,
|
||||
VKUtil.getLastSeenTime(user.lastSeen * 1000L)
|
||||
oldVKUtil.getLastSeenTime(user.lastSeen * 1000L)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -195,11 +195,11 @@ object VKUtils {
|
||||
var result = ""
|
||||
|
||||
when (it.type) {
|
||||
VKMessageAction.Type.CHAT_CREATE -> result = context.getString(
|
||||
oldVKMessageAction.Type.CHAT_CREATE -> result = context.getString(
|
||||
R.string.message_action_created_chat,
|
||||
""
|
||||
)
|
||||
VKMessageAction.Type.INVITE_USER -> result =
|
||||
oldVKMessageAction.Type.INVITE_USER -> result =
|
||||
if (lastMessage.fromId == lastMessage.action!!.memberId) {
|
||||
context.getString(R.string.message_action_returned_to_chat, "")
|
||||
} else {
|
||||
@@ -207,11 +207,11 @@ object VKUtils {
|
||||
// val invited = MemoryCache.getUserById(lastMessage.action!!.memberId)
|
||||
// context.getString(R.string.message_action_invited_user, invited)
|
||||
}
|
||||
VKMessageAction.Type.INVITE_USER_BY_LINK -> result = context.getString(
|
||||
oldVKMessageAction.Type.INVITE_USER_BY_LINK -> result = context.getString(
|
||||
R.string.message_action_invited_by_link,
|
||||
""
|
||||
)
|
||||
VKMessageAction.Type.KICK_USER -> result =
|
||||
oldVKMessageAction.Type.KICK_USER -> result =
|
||||
if (lastMessage.fromId == lastMessage.action!!.memberId) {
|
||||
context.getString(R.string.message_action_left_from_chat, "")
|
||||
} else {
|
||||
@@ -219,23 +219,23 @@ object VKUtils {
|
||||
// val kicked = MemoryCache.getUserById(lastMessage.action!!.memberId)
|
||||
// context.getString(R.string.message_action_kicked_user, kicked)
|
||||
}
|
||||
VKMessageAction.Type.PHOTO_REMOVE -> result = context.getString(
|
||||
oldVKMessageAction.Type.PHOTO_REMOVE -> result = context.getString(
|
||||
R.string.message_action_removed_photo,
|
||||
""
|
||||
)
|
||||
VKMessageAction.Type.PHOTO_UPDATE -> result = context.getString(
|
||||
oldVKMessageAction.Type.PHOTO_UPDATE -> result = context.getString(
|
||||
R.string.message_action_updated_photo,
|
||||
""
|
||||
)
|
||||
VKMessageAction.Type.PIN_MESSAGE -> result = context.getString(
|
||||
oldVKMessageAction.Type.PIN_MESSAGE -> result = context.getString(
|
||||
R.string.message_action_pinned_message,
|
||||
""
|
||||
)
|
||||
VKMessageAction.Type.UNPIN_MESSAGE -> result = context.getString(
|
||||
oldVKMessageAction.Type.UNPIN_MESSAGE -> result = context.getString(
|
||||
R.string.message_action_unpinned_message,
|
||||
""
|
||||
)
|
||||
VKMessageAction.Type.TITLE_UPDATE -> result = context.getString(
|
||||
oldVKMessageAction.Type.TITLE_UPDATE -> result = context.getString(
|
||||
R.string.message_action_updated_title,
|
||||
""
|
||||
)
|
||||
|
||||
Binary file not shown.
@@ -8,8 +8,7 @@
|
||||
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||
android:id="@+id/refreshLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recyclerView"
|
||||
@@ -18,23 +17,10 @@
|
||||
android:orientation="vertical"
|
||||
android:scrollbars="vertical"
|
||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||
tools:listitem="@layout/item_conversation" />
|
||||
tools:listitem="@layout/item_conversation_old" />
|
||||
|
||||
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
||||
|
||||
<com.google.android.material.appbar.MaterialToolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="52dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:background="@drawable/toolbar_background"
|
||||
android:elevation="3dp"
|
||||
app:title="@string/conversations"
|
||||
app:titleCentered="true" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progressBar"
|
||||
android:layout_width="wrap_content"
|
||||
@@ -43,22 +29,4 @@
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<include
|
||||
layout="@layout/no_items_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:visibility="gone" />
|
||||
|
||||
<include
|
||||
layout="@layout/no_internet_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:visibility="gone" />
|
||||
|
||||
<include
|
||||
layout="@layout/error_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:visibility="gone" />
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
@@ -9,14 +9,14 @@
|
||||
<androidx.fragment.app.FragmentContainerView
|
||||
android:id="@+id/fragmentContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginBottom="48dp" />
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
<com.google.android.material.bottomnavigation.BottomNavigationView
|
||||
android:id="@+id/bottomBar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:layout_gravity="bottom"
|
||||
android:visibility="gone"
|
||||
app:backgroundTint="?colorSurface"
|
||||
app:elevation="0.5dp"
|
||||
app:itemIconTint="@drawable/navigation_view_items_colors"
|
||||
|
||||
@@ -1,186 +1,103 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/root"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?selectableItemBackground"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:paddingTop="2dp"
|
||||
android:paddingBottom="2dp">
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/container"
|
||||
<androidx.appcompat.widget.LinearLayoutCompat
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_margin="6dp"
|
||||
android:baselineAligned="false"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:padding="6dp">
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="24dp"
|
||||
android:layout_marginVertical="10dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="0">
|
||||
android:layout_width="56dp"
|
||||
android:layout_height="56dp">
|
||||
|
||||
<com.google.android.material.imageview.ShapeableImageView
|
||||
android:id="@+id/peerAvatar"
|
||||
android:layout_width="56dp"
|
||||
android:layout_height="56dp"
|
||||
android:layout_gravity="bottom|end"
|
||||
app:shapeAppearanceOverlay="@style/CircleImageView.56"
|
||||
tools:src="?colorAccent" />
|
||||
<com.meloda.fast.widget.CircleImageView
|
||||
android:id="@+id/avatar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:src="#ff0000" />
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/online"
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:layout_gravity="end|bottom">
|
||||
|
||||
<com.meloda.fast.widget.CircleImageView
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:layout_gravity="center"
|
||||
android:src="@color/background" />
|
||||
|
||||
<com.meloda.fast.widget.CircleImageView
|
||||
android:layout_width="14dp"
|
||||
android:layout_height="14dp"
|
||||
android:layout_gravity="center"
|
||||
android:src="@drawable/ic_online_pc"
|
||||
app:tint="@color/online" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/peerOnline"
|
||||
android:layout_width="14dp"
|
||||
android:layout_height="14dp"
|
||||
android:layout_gravity="bottom|end"
|
||||
tools:src="@drawable/ic_online_pc" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
<androidx.appcompat.widget.LinearLayoutCompat
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="6dp"
|
||||
android:layout_marginEnd="6dp"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center"
|
||||
android:layout_marginStart="24dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
<androidx.appcompat.widget.LinearLayoutCompat
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:baselineAligned="false"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/type"
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginStart="4dp"
|
||||
android:paddingStart="2dp"
|
||||
android:paddingEnd="0dp"
|
||||
android:tint="@color/conversationTitle"
|
||||
android:visibility="gone"
|
||||
tools:src="@drawable/ic_dialog_type_conversation" />
|
||||
|
||||
<TextView
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:fontFamily="@font/tt_commons_medium"
|
||||
android:singleLine="true"
|
||||
android:textColor="#ff0000"
|
||||
android:textSize="20sp"
|
||||
tools:text="Title" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="2dp"
|
||||
android:layout_marginTop="2dp"
|
||||
android:gravity="center_vertical"
|
||||
android:minHeight="26dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<com.google.android.material.imageview.ShapeableImageView
|
||||
android:id="@+id/fromAvatar"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginStart="6dp"
|
||||
app:shapeAppearanceOverlay="@style/CircleImageView.24"
|
||||
tools:src="?colorAccent"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/textAttachment"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="4dp"
|
||||
android:layout_marginTop="1.5dp"
|
||||
android:tint="?colorAccent"
|
||||
android:visibility="gone"
|
||||
tools:src="@drawable/ic_message_attachment_camera"
|
||||
tools:visibility="visible" />
|
||||
android:layout_weight="1"
|
||||
android:fontFamily="@font/google_sans_regular"
|
||||
android:maxLines="2"
|
||||
android:textColor="#201A1A"
|
||||
android:textSize="22sp"
|
||||
tools:text="Title" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text"
|
||||
android:layout_width="match_parent"
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/date"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="4dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:baselineAligned="false"
|
||||
android:gravity="center_vertical"
|
||||
android:singleLine="true"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textSize="14sp"
|
||||
android:layout_marginTop="-4dp"
|
||||
android:alpha="0.5"
|
||||
android:fontFamily="@font/roboto_regular"
|
||||
android:textColor="@color/date"
|
||||
tools:text="20:00" />
|
||||
|
||||
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||
|
||||
<androidx.appcompat.widget.LinearLayoutCompat
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/message"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:alpha="0.7"
|
||||
android:fontFamily="@font/roboto_regular"
|
||||
android:maxLines="2"
|
||||
android:textColor="@color/message"
|
||||
android:textSize="16sp"
|
||||
tools:text="Message" />
|
||||
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:minHeight="50dp"
|
||||
android:paddingStart="6dp"
|
||||
android:paddingEnd="6dp">
|
||||
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||
|
||||
<com.google.android.material.imageview.ShapeableImageView
|
||||
android:id="@+id/out"
|
||||
android:layout_width="10dp"
|
||||
android:layout_height="10dp"
|
||||
android:layout_gravity="bottom"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:src="?colorAccent"
|
||||
android:visibility="gone"
|
||||
tools:visibility="gone" />
|
||||
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||
|
||||
</FrameLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/date"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end|top"
|
||||
android:layout_margin="8dp"
|
||||
android:gravity="center"
|
||||
android:maxLines="1"
|
||||
android:minWidth="30dp"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
android:textSize="12sp"
|
||||
tools:text="now" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/counter"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end"
|
||||
android:layout_marginTop="36dp"
|
||||
android:layout_marginEnd="14dp"
|
||||
android:background="@drawable/ic_conversations_counter_background"
|
||||
android:backgroundTint="?colorAccent"
|
||||
android:backgroundTintMode="multiply"
|
||||
android:fontFamily="@font/google_sans_medium"
|
||||
android:gravity="center"
|
||||
android:minWidth="28dp"
|
||||
android:minHeight="28dp"
|
||||
android:padding="6dp"
|
||||
android:textColor="?android:textColorPrimaryInverse"
|
||||
android:textSize="12sp"
|
||||
tools:text="12"
|
||||
tools:visibility="visible" />
|
||||
|
||||
</FrameLayout>
|
||||
</layout>
|
||||
@@ -0,0 +1,186 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/root"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?selectableItemBackground"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:paddingTop="2dp"
|
||||
android:paddingBottom="2dp">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_margin="6dp"
|
||||
android:baselineAligned="false"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:padding="6dp">
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="0">
|
||||
|
||||
<com.google.android.material.imageview.ShapeableImageView
|
||||
android:id="@+id/peerAvatar"
|
||||
android:layout_width="56dp"
|
||||
android:layout_height="56dp"
|
||||
android:layout_gravity="bottom|end"
|
||||
app:shapeAppearanceOverlay="@style/CircleImageView.56"
|
||||
tools:src="?colorAccent" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/peerOnline"
|
||||
android:layout_width="14dp"
|
||||
android:layout_height="14dp"
|
||||
android:layout_gravity="bottom|end"
|
||||
tools:src="@drawable/ic_online_pc" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="6dp"
|
||||
android:layout_marginEnd="6dp"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:baselineAligned="false"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/type"
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginStart="4dp"
|
||||
android:paddingStart="2dp"
|
||||
android:paddingEnd="0dp"
|
||||
android:tint="@color/conversationTitle"
|
||||
android:visibility="gone"
|
||||
tools:src="@drawable/ic_dialog_type_conversation" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:fontFamily="@font/tt_commons_medium"
|
||||
android:singleLine="true"
|
||||
android:textColor="#ff0000"
|
||||
android:textSize="20sp"
|
||||
tools:text="Title" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="2dp"
|
||||
android:layout_marginTop="2dp"
|
||||
android:gravity="center_vertical"
|
||||
android:minHeight="26dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<com.google.android.material.imageview.ShapeableImageView
|
||||
android:id="@+id/fromAvatar"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginStart="6dp"
|
||||
app:shapeAppearanceOverlay="@style/CircleImageView.24"
|
||||
tools:src="?colorAccent"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/textAttachment"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="4dp"
|
||||
android:layout_marginTop="1.5dp"
|
||||
android:tint="?colorAccent"
|
||||
android:visibility="gone"
|
||||
tools:src="@drawable/ic_message_attachment_camera"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="4dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:baselineAligned="false"
|
||||
android:gravity="center_vertical"
|
||||
android:singleLine="true"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textSize="14sp"
|
||||
tools:text="Message" />
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:minHeight="50dp"
|
||||
android:paddingStart="6dp"
|
||||
android:paddingEnd="6dp">
|
||||
|
||||
<com.google.android.material.imageview.ShapeableImageView
|
||||
android:id="@+id/out"
|
||||
android:layout_width="10dp"
|
||||
android:layout_height="10dp"
|
||||
android:layout_gravity="bottom"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:src="?colorAccent"
|
||||
android:visibility="gone"
|
||||
tools:visibility="gone" />
|
||||
|
||||
</FrameLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/date"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end|top"
|
||||
android:layout_margin="8dp"
|
||||
android:gravity="center"
|
||||
android:maxLines="1"
|
||||
android:minWidth="30dp"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
android:textSize="12sp"
|
||||
tools:text="now" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/counter"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end"
|
||||
android:layout_marginTop="36dp"
|
||||
android:layout_marginEnd="14dp"
|
||||
android:background="@drawable/ic_conversations_counter_background"
|
||||
android:backgroundTint="?colorAccent"
|
||||
android:backgroundTintMode="multiply"
|
||||
android:fontFamily="@font/google_sans_medium"
|
||||
android:gravity="center"
|
||||
android:minWidth="28dp"
|
||||
android:minHeight="28dp"
|
||||
android:padding="6dp"
|
||||
android:textColor="?android:textColorPrimaryInverse"
|
||||
android:textSize="12sp"
|
||||
tools:text="12"
|
||||
tools:visibility="visible" />
|
||||
|
||||
</FrameLayout>
|
||||
@@ -1,16 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<color name="statusBar">@android:color/system_accent1_10</color>
|
||||
<color name="navigationBar">@android:color/system_accent1_10</color>
|
||||
<color name="background">@android:color/system_accent1_10</color>
|
||||
<color name="statusBar">@android:color/system_neutral1_50</color>
|
||||
<color name="navigationBar">@android:color/system_neutral1_50</color>
|
||||
<color name="background">@android:color/system_neutral1_50</color>
|
||||
<color name="accent">@android:color/system_accent1_500</color>
|
||||
<color name="action">@android:color/system_accent3_500</color>
|
||||
<color name="actionRipple">@android:color/system_accent3_200</color>
|
||||
<color name="actionContentPrimary">@android:color/system_accent1_10</color>
|
||||
|
||||
<color name="online">@android:color/system_accent3_200</color>
|
||||
<color name="date">@android:color/system_neutral2_500</color>
|
||||
<color name="message">@android:color/system_neutral1_900</color>
|
||||
|
||||
<color name="primary">@android:color/system_accent1_10</color>
|
||||
<color name="primary">@android:color/system_neutral1_50</color>
|
||||
|
||||
<color name="divider">#E0E0E0</color>
|
||||
|
||||
|
||||
@@ -15,6 +15,10 @@
|
||||
|
||||
<color name="textSecondary">#99000000</color>
|
||||
|
||||
<color name="online">#00ff00</color>
|
||||
<color name="date">#212121</color>
|
||||
<color name="message">#000000</color>
|
||||
|
||||
|
||||
<color name="text_secondary_100_alpha">#ff000000</color>
|
||||
<color name="text_secondary_87_alpha">#DE000000</color>
|
||||
|
||||
@@ -158,5 +158,10 @@
|
||||
<string name="conversations">Conversations</string>
|
||||
<string name="code_hint">Code</string>
|
||||
<string name="input_validation_code">Input code from sms</string>
|
||||
<string name="you_message_prefix">You</string>
|
||||
<string name="message_geo">Geolocation</string>
|
||||
<string name="message_geo_point">Point</string>
|
||||
<string name="forwarded_message">Message</string>
|
||||
<string name="forwarded_messages">Messages</string>
|
||||
|
||||
</resources>
|
||||
|
||||
Reference in New Issue
Block a user