Update API version (#147)

* Bump VK Api version to 5.238
* Implemented new authorization flow (at the moment, without auto re-requesting token)
* Add support for sticker pack preview attachments
* Bump LongPoll to version 19
* Improved messages handling
* Fixed coloring issues
* Cache improvements
* Archive screen with full functionality
* Recomposition fixes
* Markdown support for messages bubbles
* Adjust app name font size based on screen width
* Navigation related improvements
* Add logout functionality
This commit is contained in:
2025-04-04 20:43:59 +03:00
committed by GitHub
parent add67b6f8d
commit 89748b72ed
237 changed files with 4896 additions and 3289 deletions
@@ -1,15 +1,17 @@
package dev.meloda.fast.model
enum class ApiEvent(val value: Int) {
MESSAGE_SET_FLAGS(2),
MESSAGE_CLEAR_FLAGS(3),
MESSAGE_NEW(4),
MESSAGE_EDIT(5),
MESSAGE_READ_INCOMING(6),
MESSAGE_READ_OUTGOING(7),
MESSAGE_SET_FLAGS(10002),
MESSAGE_CLEAR_FLAGS(10003),
MESSAGE_NEW(10004),
MESSAGE_EDIT(10005),
MESSAGE_READ_INCOMING(10006),
MESSAGE_READ_OUTGOING(10007),
CHAT_CLEAR_FLAGS(10),
CHAT_SET_FLAGS(12),
MESSAGES_DELETED(13),
MESSAGES_DELETED(10013),
MESSAGE_UPDATED(10018),
MESSAGE_CACHE_CLEAR(10019),
CHAT_MAJOR_CHANGED(20),
CHAT_MINOR_CHANGED(21),
TYPING(63),
@@ -1,7 +1,7 @@
package dev.meloda.fast.model
data class AuthInfo(
val userId: Int?,
val accessToken: String?,
val validationHash: String?
val userId: Long,
val accessToken: String,
val validationHash: String
)
@@ -6,6 +6,10 @@ import androidx.compose.runtime.Immutable
sealed class BaseError {
data object SessionExpired : BaseError()
data object AccountBlocked : BaseError()
data object ConnectionError : BaseError()
data object InternalError : BaseError()
data object UnknownError : BaseError()
data class SimpleError(val message: String) : BaseError()
}
@@ -13,5 +13,20 @@ enum class ConversationFlags(val value: Int) {
DO_NOT_NOTIFY_ALL_MENTIONS(524288),
MARKED_AS_UNREAD(1048576),
ARCHIVED(8388608),
CALL_IN_PROGRESS(16777216),
CALL_IN_PROGRESS(16777216);
companion object {
fun parse(mask: Int): List<ConversationFlags> {
val flags = mutableListOf<ConversationFlags>()
ConversationFlags.entries.forEach { flag ->
if (mask and flag.value > 0) {
flags.add(flag)
}
}
return flags
}
}
}
@@ -0,0 +1,5 @@
package dev.meloda.fast.model
enum class ConversationsFilter {
ALL, UNREAD, ARCHIVE, BUSINESS_NOTIFY
}
@@ -4,5 +4,5 @@ import dev.meloda.fast.model.api.domain.VkUser
data class FriendsInfo(
val friends: List<VkUser>,
val onlineFriendsIds: List<Int>
val onlineFriendsIds: List<Long>
)
@@ -21,7 +21,10 @@ enum class LongPollEvent {
MARKED_AS_SPAM,
MARKED_AS_NOT_SPAM,
MESSAGE_DELETED,
MESSAGE_UPDATED,
MESSAGE_CACHE_CLEAR,
MESSAGE_RESTORED,
AUDIO_MESSAGE_LISTENED,
CHAT_CLEARED
CHAT_CLEARED,
CHAT_ARCHIVED
}
@@ -1,39 +1,47 @@
package dev.meloda.fast.model
import dev.meloda.fast.model.api.domain.VkConversation
import dev.meloda.fast.model.api.domain.VkMessage
sealed interface LongPollParsedEvent {
data class NewMessage(val message: VkMessage) : LongPollParsedEvent
data class NewMessage(
val message: VkMessage,
val inArchive: Boolean
) : LongPollParsedEvent
data class MessageEdited(val message: VkMessage) : LongPollParsedEvent
data class MessageUpdated(val message: VkMessage) : LongPollParsedEvent
data class MessageCacheClear(val message: VkMessage) : LongPollParsedEvent
data class IncomingMessageRead(
val peerId: Int,
val messageId: Int,
val peerId: Long,
val cmId: Long,
val unreadCount: Int,
) : LongPollParsedEvent
data class OutgoingMessageRead(
val peerId: Int,
val messageId: Int,
val peerId: Long,
val cmId: Long,
val unreadCount: Int,
) : LongPollParsedEvent
data class ChatMajorChanged(
val peerId: Int,
val peerId: Long,
val majorId: Int,
) : LongPollParsedEvent
data class ChatMinorChanged(
val peerId: Int,
val peerId: Long,
val minorId: Int
) : LongPollParsedEvent
data class Interaction(
val interactionType: InteractionType,
val peerId: Int,
val userIds: List<Int>,
val peerId: Long,
val userIds: List<Long>,
val totalCount: Int,
val timestamp: Int
) : LongPollParsedEvent
@@ -49,14 +57,14 @@ sealed interface LongPollParsedEvent {
) : LongPollParsedEvent
data class MessageMarkedAsImportant(
val peerId: Int,
val messageId: Int,
val peerId: Long,
val cmId: Long,
val marked: Boolean
) : LongPollParsedEvent
data class MessageMarkedAsSpam(
val peerId: Int,
val messageId: Int
val peerId: Long,
val cmId: Long
) : LongPollParsedEvent
data class MessageMarkedAsNotSpam(
@@ -64,8 +72,8 @@ sealed interface LongPollParsedEvent {
) : LongPollParsedEvent
data class MessageDeleted(
val peerId: Int,
val messageId: Int,
val peerId: Long,
val cmId: Long,
val forAll: Boolean
) : LongPollParsedEvent
@@ -74,12 +82,17 @@ sealed interface LongPollParsedEvent {
) : LongPollParsedEvent
data class AudioMessageListened(
val peerId: Int,
val messageId: Int
val peerId: Long,
val cmId: Long
) : LongPollParsedEvent
data class ChatCleared(
val peerId: Int,
val toMessageId: Int
): LongPollParsedEvent
val peerId: Long,
val toCmId: Long
) : LongPollParsedEvent
data class ChatArchived(
val conversation: VkConversation,
val archived: Boolean
) : LongPollParsedEvent
}
@@ -27,7 +27,11 @@ enum class AttachmentType(var value: String) {
AUDIO_PLAYLIST("audio_playlist"),
PODCAST("podcast"),
NARRATIVE("narrative"),
ARTICLE("article");
ARTICLE("article"),
VIDEO_MESSAGE("video_message"),
GROUP_CHAT_STICKER("ugc_sticker"),
STICKER_PACK_PREVIEW("sticker_pack_preview")
;
fun isMultiple(): Boolean = this in listOf(PHOTO, VIDEO, AUDIO, FILE)
@@ -6,7 +6,7 @@ import com.squareup.moshi.JsonClass
@JsonClass(generateAdapter = true)
data class VkArticleData(
@Json(name = "id") val id: Int
@Json(name = "id") val id: Long
) : VkAttachmentData {
fun toDomain(): VkArticleDomain = VkArticleDomain(
@@ -1,15 +1,15 @@
package dev.meloda.fast.model.api.data
import dev.meloda.fast.model.api.domain.VkAttachmentHistoryMessage
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import dev.meloda.fast.model.api.domain.VkAttachmentHistoryMessage
@JsonClass(generateAdapter = true)
data class VkAttachmentHistoryMessageData(
@Json(name = "message_id") val messageId: Int,
@Json(name = "message_id") val messageId: Long,
@Json(name = "date") val date: Int,
@Json(name = "cmid") val conversationMessageId: Int,
@Json(name = "from_id") val fromId: Int,
@Json(name = "cmid") val conversationMessageId: Long,
@Json(name = "from_id") val fromId: Long,
@Json(name = "position") val position: Int,
@Json(name = "attachment") val attachment: VkAttachmentItemData
) {
@@ -1,9 +1,9 @@
package dev.meloda.fast.model.api.data
import dev.meloda.fast.model.api.domain.VkAttachment
import dev.meloda.fast.model.api.domain.VkUnknownAttachment
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import dev.meloda.fast.model.api.domain.VkAttachment
import dev.meloda.fast.model.api.domain.VkUnknownAttachment
@JsonClass(generateAdapter = true)
data class VkAttachmentItemData(
@@ -32,7 +32,10 @@ data class VkAttachmentItemData(
@Json(name = "audio_playlist") val audioPlaylist: VkAudioPlaylistData?,
@Json(name = "podcast") val podcast: VkPodcastData?,
@Json(name = "narrative") val narrative: VkNarrativeData?,
@Json(name = "article") val article: VkArticleData?
@Json(name = "article") val article: VkArticleData?,
@Json(name = "video_message") val videoMessage: VkVideoMessageData?,
@Json(name = "ugc_sticker") val groupSticker: VkGroupStickerData?,
@Json(name = "sticker_pack_preview") val stickerPackPreview: VkStickerPackPreviewData?
) {
fun toDomain(): VkAttachment = when (AttachmentType.parse(type)) {
AttachmentType.UNKNOWN -> VkUnknownAttachment
@@ -60,5 +63,8 @@ data class VkAttachmentItemData(
AttachmentType.PODCAST -> podcast?.toDomain()
AttachmentType.NARRATIVE -> narrative?.toDomain()
AttachmentType.ARTICLE -> article?.toDomain()
AttachmentType.VIDEO_MESSAGE -> videoMessage?.toDomain()
AttachmentType.GROUP_CHAT_STICKER -> groupSticker?.toDomain()
AttachmentType.STICKER_PACK_PREVIEW -> stickerPackPreview?.toDomain()
} ?: VkUnknownAttachment
}
@@ -1,31 +1,31 @@
package dev.meloda.fast.model.api.data
import dev.meloda.fast.model.api.domain.VkAudioDomain
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import dev.meloda.fast.model.api.domain.VkAudioDomain
@JsonClass(generateAdapter = true)
data class VkAudioData(
@Json(name = "id") val id: Int,
@Json(name = "id") val id: Long,
@Json(name = "title") val title: String,
@Json(name = "artist") val artist: String,
@Json(name = "duration") val duration: Int,
@Json(name = "url") val url: String,
@Json(name = "date") val date: Int,
@Json(name = "owner_id") val ownerId: Int,
@Json(name = "owner_id") val ownerId: Long,
@Json(name = "access_key") val accessKey: String?,
@Json(name = "is_explicit") val isExplicit: Boolean,
@Json(name = "is_focus_track") val isFocusTrack: Boolean,
@Json(name = "is_licensed") val isLicensed: Boolean?,
@Json(name = "genre_id") val genreId: Int?,
@Json(name = "genre_id") val genreId: Long?,
@Json(name = "album") val album: Album?,
) : VkAttachmentData {
@JsonClass(generateAdapter = true)
data class Album(
@Json(name = "id") val id: Int,
@Json(name = "id") val id: Long,
@Json(name = "title") val title: String,
@Json(name = "owner_id") val ownerId: Int,
@Json(name = "owner_id") val ownerId: Long,
@Json(name = "access_key") val accessKey: String,
@Json(name = "thumb") val thumb: Thumb?
) {
@@ -6,8 +6,8 @@ import com.squareup.moshi.JsonClass
@JsonClass(generateAdapter = true)
data class VkAudioMessageData(
@Json(name = "id") val id: Int,
@Json(name = "owner_id") val ownerId: Int,
@Json(name = "id") val id: Long,
@Json(name = "owner_id") val ownerId: Long,
@Json(name = "duration") val duration: Int,
@Json(name = "waveform") val waveform: List<Int>,
@Json(name = "link_ogg") val linkOgg: String,
@@ -6,8 +6,8 @@ import com.squareup.moshi.JsonClass
@JsonClass(generateAdapter = true)
data class VkAudioPlaylistData(
@Json(name = "id") val id: Int,
@Json(name = "owner_id") val ownerId: Int,
@Json(name = "id") val id: Long,
@Json(name = "owner_id") val ownerId: Long,
@Json(name = "type") val type: Int,
@Json(name = "title") val title: String,
@Json(name = "description") val description: String,
@@ -6,8 +6,8 @@ import com.squareup.moshi.JsonClass
@JsonClass(generateAdapter = true)
data class VkCallData(
@Json(name = "initiator_id") val initiatorId: Int,
@Json(name = "receiver_id") val receiverId: Int,
@Json(name = "initiator_id") val initiatorId: Long,
@Json(name = "receiver_id") val receiverId: Long,
@Json(name = "state") val state: String,
@Json(name = "time") val time: Int,
@Json(name = "duration") val duration: Int,
@@ -8,9 +8,9 @@ import com.squareup.moshi.JsonClass
data class VkChatData(
@Json(name = "type") val type: String,
@Json(name = "val title") val title: String,
@Json(name = "admin_id") val adminId: Int,
@Json(name = "admin_id") val adminId: Long,
@Json(name = "members_count") val membersCount: Int,
@Json(name = "id") val id: Int,
@Json(name = "id") val id: Long,
@Json(name = "photo_50") val photo50: String,
@Json(name = "photo_100") val photo100: String,
@Json(name = "photo_200") val photo200: String,
@@ -6,7 +6,7 @@ import com.squareup.moshi.JsonClass
@JsonClass(generateAdapter = true)
data class VkChatMemberData(
@Json(name = "member_id") val memberId: Int,
@Json(name = "member_id") val memberId: Long,
@Json(name = "invited_by") val invitedBy: Int,
@Json(name = "join_date") val joinDate: Int,
@Json(name = "is_admin") val isAdmin: Boolean?,
@@ -6,10 +6,10 @@ import com.squareup.moshi.JsonClass
@JsonClass(generateAdapter = true)
data class VkContactData(
@Json(name = "id") val id: Int,
@Json(name = "id") val id: Long,
@Json(name = "name") val name: String,
@Json(name = "can_write") val canWrite: Boolean,
@Json(name = "user_id") val userId: Int,
@Json(name = "user_id") val userId: Long,
@Json(name = "last_seen_status") val lastSeenStatus: String?,
@Json(name = "photo_50") val photo50: String?,
@Json(name = "calls_id") val callsId: String
@@ -1,21 +1,21 @@
package dev.meloda.fast.model.api.data
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import dev.meloda.fast.model.api.PeerType
import dev.meloda.fast.model.api.domain.VkConversation
import dev.meloda.fast.model.api.domain.VkMessage
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
@JsonClass(generateAdapter = true)
data class VkConversationData(
@Json(name = "peer") val peer: Peer,
@Json(name = "last_message_id") val lastMessageId: Int?,
@Json(name = "in_read") val inRead: Int,
@Json(name = "out_read") val outRead: Int,
@Json(name = "in_read_cmid") val inReadConversationMessageId: Int,
@Json(name = "out_read_cmid") val outReadConversationMessageId: Int,
@Json(name = "last_message_id") val lastMessageId: Long?,
@Json(name = "in_read") val inRead: Long,
@Json(name = "out_read") val outRead: Long,
@Json(name = "in_read_cmid") val inReadConversationMessageId: Long,
@Json(name = "out_read_cmid") val outReadConversationMessageId: Long,
@Json(name = "sort_id") val sortId: SortId,
@Json(name = "last_conversation_message_id") val lastConversationMessageId: Int,
@Json(name = "last_conversation_message_id") val lastConversationMessageId: Long,
@Json(name = "is_marked_unread") val isMarkedUnread: Boolean,
@Json(name = "important") val important: Boolean,
@Json(name = "push_settings") val pushSettings: PushSettings?,
@@ -25,13 +25,14 @@ data class VkConversationData(
@Json(name = "chat_settings") val chatSettings: ChatSettings?,
@Json(name = "call_in_progress") val callInProgress: CallInProgress?,
@Json(name = "unread_count") val unreadCount: Int?,
@Json(name = "is_archived") val isArchived: Boolean?
) {
@JsonClass(generateAdapter = true)
data class Peer(
@Json(name = "id") val id: Int,
@Json(name = "id") val id: Long,
@Json(name = "type") val type: String,
@Json(name = "local_id") val localId: Int,
@Json(name = "local_id") val localId: Long,
)
@JsonClass(generateAdapter = true)
@@ -55,7 +56,7 @@ data class VkConversationData(
@JsonClass(generateAdapter = true)
data class ChatSettings(
@Json(name = "owner_id") val ownerId: Int,
@Json(name = "owner_id") val ownerId: Long,
@Json(name = "title") val title: String,
@Json(name = "state") val state: String,
@Json(name = "acl") val acl: Acl,
@@ -119,7 +120,7 @@ data class VkConversationData(
photo200 = chatSettings?.photo?.photo200,
isCallInProgress = callInProgress != null,
isPhantom = chatSettings?.isDisappearing == true,
lastConversationMessageId = lastConversationMessageId,
lastCmId = lastConversationMessageId,
inRead = inRead,
outRead = outRead,
lastMessageId = lastMessageId,
@@ -140,5 +141,6 @@ data class VkConversationData(
pinnedMessage = chatSettings?.pinnedMessage?.mapToDomain(),
user = null,
group = null,
isArchived = isArchived == true
)
}
@@ -5,7 +5,7 @@ import com.squareup.moshi.JsonClass
@JsonClass(generateAdapter = true)
data class VkCuratorData(
val id: Int,
val id: Long,
val name: String,
val description: String,
val url: String,
@@ -7,7 +7,7 @@ import com.squareup.moshi.JsonClass
@JsonClass(generateAdapter = true)
data class VkEventData(
@Json(name = "button_text") val buttonText: String,
@Json(name = "id") val id: Int,
@Json(name = "id") val id: Long,
@Json(name = "is_favorite") val isFavorite: Boolean,
@Json(name = "text") val text: String,
@Json(name = "address") val address: String,
@@ -1,13 +1,13 @@
package dev.meloda.fast.model.api.data
import dev.meloda.fast.model.api.domain.VkFileDomain
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import dev.meloda.fast.model.api.domain.VkFileDomain
@JsonClass(generateAdapter = true)
data class VkFileData(
@Json(name = "id") val id: Int,
@Json(name = "owner_id") val ownerId: Int,
@Json(name = "id") val id: Long,
@Json(name = "owner_id") val ownerId: Long,
@Json(name = "title") val title: String,
@Json(name = "size") val size: Int,
@Json(name = "ext") val extension: String,
@@ -6,7 +6,7 @@ import com.squareup.moshi.JsonClass
@JsonClass(generateAdapter = true)
data class VkGiftData(
@Json(name = "id") val id: Int,
@Json(name = "id") val id: Long,
@Json(name = "thumb_256") val thumb256: String?,
@Json(name = "thumb_96") val thumb96: String?,
@Json(name = "thumb_48") val thumb48: String
@@ -1,13 +1,13 @@
package dev.meloda.fast.model.api.data
import dev.meloda.fast.model.api.domain.VkGraffitiDomain
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import dev.meloda.fast.model.api.domain.VkGraffitiDomain
@JsonClass(generateAdapter = true)
data class VkGraffitiData(
@Json(name = "id") val id: Int,
@Json(name = "owner_id") val ownerId: Int,
@Json(name = "id") val id: Long,
@Json(name = "owner_id") val ownerId: Long,
@Json(name = "url") val url: String,
@Json(name = "width") val width: Int,
@Json(name = "height") val height: Int,
@@ -1,12 +1,12 @@
package dev.meloda.fast.model.api.data
import dev.meloda.fast.model.api.domain.VkGroupCallDomain
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import dev.meloda.fast.model.api.domain.VkGroupCallDomain
@JsonClass(generateAdapter = true)
data class VkGroupCallData(
@Json(name = "initiator_id") val initiatorId: Int,
@Json(name = "initiator_id") val initiatorId: Long,
@Json(name = "join_link") val joinLink: String,
@Json(name = "participants") val participants: Participants
) {
@@ -7,7 +7,7 @@ import kotlin.math.abs
@JsonClass(generateAdapter = true)
data class VkGroupData(
@Json(name = "id") val id: Int,
@Json(name = "id") val id: Long,
@Json(name = "name") val name: String,
@Json(name = "screen_name") val screenName: String,
@Json(name = "is_closed") val isClosed: Int?,
@@ -0,0 +1,27 @@
package dev.meloda.fast.model.api.data
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import dev.meloda.fast.model.api.domain.VkGroupStickerDomain
@JsonClass(generateAdapter = true)
data class VkGroupStickerData(
val id: Long,
val owner_id: Long,
val pack_id: Long?,
val status: String?,
val is_deleted: Boolean?,
val images: List<Image>?
): VkAttachmentData {
@JsonClass(generateAdapter = true)
data class Image(
@Json(name = "width") val width: Int,
@Json(name = "height") val height: Int,
@Json(name = "url") val url: String
)
fun toDomain(): VkGroupStickerDomain = VkGroupStickerDomain(
id = id
)
}
@@ -2,22 +2,23 @@ package dev.meloda.fast.model.api.data
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import dev.meloda.fast.model.api.domain.FormatDataType
import dev.meloda.fast.model.api.domain.VkMessage
@JsonClass(generateAdapter = true)
data class VkMessageData(
@Json(name = "id") val id: Int?,
@Json(name = "peer_id") val peerId: Int?,
@Json(name = "id") val id: Long?,
@Json(name = "peer_id") val peerId: Long?,
@Json(name = "date") val date: Int,
@Json(name = "from_id") val fromId: Int,
@Json(name = "from_id") val fromId: Long,
@Json(name = "out") val out: Int?,
@Json(name = "text") val text: String,
@Json(name = "conversation_message_id") val conversationMessageId: Int,
@Json(name = "conversation_message_id") val cmId: Long,
@Json(name = "fwd_messages") val fwdMessages: List<VkMessageData>? = emptyList(),
@Json(name = "important") val important: Boolean = false,
@Json(name = "random_id") val randomId: Int = 0,
@Json(name = "important") val important: Boolean?,
@Json(name = "random_id") val randomId: Long?,
@Json(name = "attachments") val attachments: List<VkAttachmentItemData> = emptyList(),
@Json(name = "is_hidden") val isHidden: Boolean = false,
@Json(name = "is_hidden") val isHidden: Boolean?,
@Json(name = "payload") val payload: String?,
@Json(name = "geo") val geo: Geo?,
@Json(name = "action") val action: Action?,
@@ -25,7 +26,8 @@ data class VkMessageData(
@Json(name = "reply_message") val replyMessage: VkMessageData?,
@Json(name = "update_time") val updateTime: Int?,
@Json(name = "is_pinned") val isPinned: Boolean?,
@Json(name = "pinned_at") val pinnedAt: Int?
@Json(name = "pinned_at") val pinnedAt: Int?,
@Json(name = "format_data") val formatData: FormatData?
) {
@JsonClass(generateAdapter = true)
@@ -52,29 +54,58 @@ data class VkMessageData(
@JsonClass(generateAdapter = true)
data class Action(
@Json(name = "type") val type: String,
@Json(name = "member_id") val memberId: Int?,
@Json(name = "member_id") val memberId: Long?,
@Json(name = "text") val text: String?,
@Json(name = "conversation_message_id") val conversationMessageId: Int?,
@Json(name = "conversation_message_id") val conversationMessageId: Long?,
@Json(name = "message") val message: String?
)
@JsonClass(generateAdapter = true)
data class FormatData(
@Json(name = "version") val version: String,
@Json(name = "items") val items: List<Item>
) {
@JsonClass(generateAdapter = true)
data class Item(
@Json(name = "offset") val offset: Int,
@Json(name = "length") val length: Int,
@Json(name = "type") val type: String,
@Json(name = "url") val url: String?
)
fun asDomain(): VkMessage.FormatData = VkMessage.FormatData(
version = version,
items = items.mapNotNull { item ->
FormatDataType.parse(item.type)?.let { type ->
VkMessage.FormatData.Item(
offset = item.offset,
length = item.length,
type = type,
url = item.url
)
}
}
)
}
}
fun VkMessageData.asDomain(): VkMessage = VkMessage(
id = id ?: -1,
conversationMessageId = conversationMessageId,
cmId = cmId,
text = text.ifBlank { null },
isOut = out == 1,
peerId = peerId ?: -1,
fromId = fromId,
date = date,
randomId = randomId,
randomId = randomId ?: 0,
action = VkMessage.Action.parse(action?.type),
actionMemberId = action?.memberId,
actionText = action?.text,
actionConversationMessageId = action?.conversationMessageId,
actionMessage = action?.message,
geoType = geo?.type,
isImportant = important,
isImportant = important ?: false,
updateTime = updateTime,
forwards = fwdMessages.orEmpty().map(VkMessageData::asDomain),
attachments = attachments.map(VkAttachmentItemData::toDomain),
@@ -84,5 +115,7 @@ fun VkMessageData.asDomain(): VkMessage = VkMessage(
actionUser = null,
actionGroup = null,
pinnedAt = pinnedAt,
isPinned = isPinned == true
isPinned = isPinned == true,
formatData = formatData?.asDomain(),
isSpam = false
)
@@ -16,9 +16,9 @@ data class VkMiniAppData(
@JsonClass(generateAdapter = true)
data class App(
@Json(name = "type") val type: String,
@Json(name = "id") val id: Int,
@Json(name = "id") val id: Long,
@Json(name = "title") val title: String,
@Json(name = "author_owner_id") val authorOwnerId: Int,
@Json(name = "author_owner_id") val authorOwnerid: Long,
@Json(name = "is_favorite") val isFavorite: Boolean,
@Json(name = "share_url") val shareUrl: String,
@Json(name = "webview_url") val webViewUrl: String,
@@ -6,7 +6,7 @@ import com.squareup.moshi.JsonClass
@JsonClass(generateAdapter = true)
data class VkNarrativeData(
@Json(name = "id") val id: Int,
@Json(name = "id") val id: Long,
@Json(name = "title") val title: String?
) : VkAttachmentData {
@@ -6,18 +6,18 @@ import dev.meloda.fast.model.api.domain.VkPhotoDomain
@JsonClass(generateAdapter = true)
data class VkPhotoData(
@Json(name = "album_id") val albumId: Int,
@Json(name = "album_id") val albumId: Long,
@Json(name = "date") val date: Int?,
@Json(name = "id") val id: Int,
@Json(name = "owner_id") val ownerId: Int,
@Json(name = "id") val id: Long,
@Json(name = "owner_id") val ownerId: Long,
@Json(name = "has_tags") val hasTags: Boolean?,
@Json(name = "access_key") val accessKey: String?,
@Json(name = "sizes") val sizes: List<Size>,
@Json(name = "text") val text: String?,
@Json(name = "user_id") val userId: Int?,
@Json(name = "user_id") val userId: Long?,
@Json(name = "lat") val lat: Double?,
@Json(name = "long") val long: Double?,
@Json(name = "post_id") val postId: Int?
@Json(name = "post_id") val postId: Long?
) : VkAttachmentData {
@JsonClass(generateAdapter = true)
@@ -1,21 +1,21 @@
package dev.meloda.fast.model.api.data
import dev.meloda.fast.model.api.domain.VkMessage
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import dev.meloda.fast.model.api.domain.VkMessage
@JsonClass(generateAdapter = true)
data class VkPinnedMessageData(
@Json(name = "id") val id: Int?,
@Json(name = "peer_id") val peerId: Int?,
@Json(name = "id") val id: Long?,
@Json(name = "peer_id") val peerId: Long?,
@Json(name = "date") val date: Int,
@Json(name = "from_id") val fromId: Int,
@Json(name = "from_id") val fromId: Long,
@Json(name = "out") val out: Boolean?,
@Json(name = "text") val text: String,
@Json(name = "conversation_message_id") val conversationMessageId: Int,
@Json(name = "conversation_message_id") val conversationMessageId: Long,
@Json(name = "fwd_messages") val forwards: List<VkMessageData>?,
@Json(name = "important") val important: Boolean = false,
@Json(name = "random_id") val randomId: Int = 0,
@Json(name = "random_id") val randomId: Long = 0,
@Json(name = "attachments") val attachments: List<VkAttachmentItemData>?,
@Json(name = "is_hidden") val isHidden: Boolean = false,
@Json(name = "payload") val payload: String?,
@@ -28,7 +28,7 @@ data class VkPinnedMessageData(
fun mapToDomain(): VkMessage = VkMessage(
id = id ?: -1,
conversationMessageId = conversationMessageId,
cmId = conversationMessageId,
text = text.ifBlank { null },
isOut = out == true,
peerId = peerId ?: -1,
@@ -54,5 +54,7 @@ data class VkPinnedMessageData(
actionGroup = null,
pinnedAt = null,
isPinned = true,
isSpam = false,
formatData = null,
)
}
@@ -6,7 +6,7 @@ import com.squareup.moshi.JsonClass
@JsonClass(generateAdapter = true)
data class VkPodcastData(
@Json(name = "id") val id: Int,
@Json(name = "id") val id: Long,
@Json(name = "title") val title: String,
@Json(name = "artist") val artist: String,
// ... other fields
@@ -1,13 +1,13 @@
package dev.meloda.fast.model.api.data
import dev.meloda.fast.model.api.domain.VkPollDomain
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import dev.meloda.fast.model.api.domain.VkPollDomain
@JsonClass(generateAdapter = true)
data class VkPollData(
val multiple: Boolean,
val id: Int,
val id: Long,
val votes: Int,
val anonymous: Boolean?,
val closed: Boolean,
@@ -18,24 +18,24 @@ data class VkPollData(
@Json(name = "can_report") val canReport: Boolean,
@Json(name = "can_share") val canShare: Boolean,
val created: Int,
@Json(name = "owner_id") val ownerId: Int,
@Json(name = "owner_id") val ownerId: Long,
val question: String,
@Json(name = "disable_unvote") val disableUnvote: Boolean,
val friends: List<Friend>?,
@Json(name = "embed_hash") val embedHash: String,
val answers: List<Answer>,
@Json(name = "author_id") val authorId: Int?,
@Json(name = "author_id") val authorId: Long?,
val background: Background?
) {
@JsonClass(generateAdapter = true)
data class Friend(
val id: Int
val id: Long
)
@JsonClass(generateAdapter = true)
data class Answer(
val id: Int,
val id: Long,
val rate: Double,
val text: String,
val votes: Int
@@ -45,7 +45,7 @@ data class VkPollData(
data class Background(
val angle: Int,
val color: String,
val id: Int,
val id: Long,
val name: String,
val type: String,
val points: List<Point>
@@ -1,15 +1,15 @@
package dev.meloda.fast.model.api.data
import dev.meloda.fast.model.api.domain.VkStickerDomain
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import dev.meloda.fast.model.api.domain.VkStickerDomain
@JsonClass(generateAdapter = true)
data class VkStickerData(
@Json(name = "product_id") val productId: Int,
@Json(name = "sticker_id") val stickerId: Int,
@Json(name = "images") val images: List<Image>,
@Json(name = "images_with_background") val imagesWithBackground: List<Image>,
@Json(name = "product_id") val productId: Long,
@Json(name = "sticker_id") val stickerId: Long,
@Json(name = "images") val images: List<Image>?,
@Json(name = "images_with_background") val imagesWithBackground: List<Image>?,
@Json(name = "animation_url") val animationUrl: String?,
@Json(name = "animations") val animations: List<Animation>?
) {
@@ -0,0 +1,33 @@
package dev.meloda.fast.model.api.data
import com.squareup.moshi.JsonClass
import dev.meloda.fast.model.api.domain.VkStickerPackPreviewDomain
@JsonClass(generateAdapter = true)
data class VkStickerPackPreviewData(
val id: Long,
val title: String,
val description: String?,
val author: String?,
val icon: Icon?,
val price: Price?,
val can_purchase: Boolean,
val url: String
) : VkAttachmentData {
@JsonClass(generateAdapter = true)
data class Icon(
val base_url: String
)
@JsonClass(generateAdapter = true)
data class Price(
val current: Long,
val regular: Long
)
fun toDomain(): VkStickerPackPreviewDomain = VkStickerPackPreviewDomain(
id = id
)
}
@@ -5,8 +5,8 @@ import com.squareup.moshi.JsonClass
@JsonClass(generateAdapter = true)
data class VkStoryData(
val id: Int,
val owner_id: Int,
val id: Long,
val owner_id: Long,
val access_key: String?,
val can_comment: Int?,
val can_reply: Int?,
@@ -7,7 +7,7 @@ import dev.meloda.fast.model.api.domain.VkUser
@JsonClass(generateAdapter = true)
data class VkUserData(
@Json(name = "id") val id: Int,
@Json(name = "id") val id: Long,
@Json(name = "first_name") val firstName: String,
@Json(name = "last_name") val lastName: String,
@Json(name = "can_access_closed") val canAccessClosed: Boolean,
@@ -18,8 +18,8 @@ data class VkUserData(
@Json(name = "photo_100") val photo100: String?,
@Json(name = "photo_200") val photo200: String?,
@Json(name = "photo_400_orig") val photo400Orig: String?,
@Json(name = "online") val online: Int?,
@Json(name = "online_info") val onlineInfo: OnlineInfo?,
@Json(name = "last_seen") val lastSeen: LastSeen?,
@Json(name = "screen_name") val screenName: String,
@Json(name = "bdate") val birthday: String?
//...other fields
@@ -31,25 +31,26 @@ data class VkUserData(
@Json(name = "status") val status: String?,
@Json(name = "last_seen") val lastSeen: Int?,
@Json(name = "is_online") val isOnline: Boolean?,
@Json(name = "online_mobile") val onlineMobile: Boolean?,
@Json(name = "app_id") val appId: Int?
@Json(name = "online_mobile") val isOnlineMobile: Boolean?,
@Json(name = "app_id") val appId: Long?
)
@JsonClass(generateAdapter = true)
data class LastSeen(
@Json(name = "platform") val platform: Int,
@Json(name = "time") val time: Int
)
fun mapToDomain() = VkUser(
id = id,
firstName = firstName,
lastName = lastName,
// TODO: 05/05/2024, Danil Nikolaev: improve
onlineStatus = when {
online != 1 -> OnlineStatus.Offline
onlineInfo?.onlineMobile == true -> {
OnlineStatus.OnlineMobile(appId = onlineInfo.appId)
}
else -> {
OnlineStatus.Online(appId = onlineInfo?.appId)
}
},
onlineStatus = parseUserOnlineState(
isOnline = onlineInfo?.isOnline,
isOnlineMobile = onlineInfo?.isOnlineMobile,
status = onlineInfo?.status,
appId = onlineInfo?.appId
),
photo50 = photo50,
photo100 = photo100,
photo200 = photo200,
@@ -59,3 +60,26 @@ data class VkUserData(
birthday = birthday
)
}
fun parseUserOnlineState(
isOnline: Boolean?,
isOnlineMobile: Boolean?,
status: String?,
appId: Long?
): OnlineStatus {
return when {
isOnlineMobile == true -> OnlineStatus.OnlineMobile(appId)
isOnline == true -> OnlineStatus.Online(appId)
status != null -> {
when (status) {
"last_week" -> OnlineStatus.LastWeek
"last_month" -> OnlineStatus.LastMonth
else -> OnlineStatus.Recently
}
}
else -> OnlineStatus.Offline
}
}
@@ -6,7 +6,7 @@ import dev.meloda.fast.model.api.domain.VkVideoDomain
@JsonClass(generateAdapter = true)
data class VkVideoData(
@Json(name = "id") val id: Int,
@Json(name = "id") val id: Long,
@Json(name = "title") val title: String,
@Json(name = "width") val width: Int?,
@Json(name = "height") val height: Int?,
@@ -19,7 +19,7 @@ data class VkVideoData(
@Json(name = "type") val type: String,
@Json(name = "views") val views: Int,
@Json(name = "access_key") val accessKey: String?,
@Json(name = "owner_id") val ownerId: Int,
@Json(name = "owner_id") val ownerId: Long,
@Json(name = "is_favorite") val isFavorite: Boolean?,
@Json(name = "image") val image: List<Image>?,
@Json(name = "first_frame") val firstFrame: List<FirstFrame>?,
@@ -0,0 +1,78 @@
package dev.meloda.fast.model.api.data
import com.squareup.moshi.JsonClass
import dev.meloda.fast.model.api.domain.VkVideoMessageDomain
@JsonClass(generateAdapter = true)
data class VkVideoMessageData(
val id: Long,
val access_key: String?,
val can_add: Int?,
val can_dislike: Int?,
val can_download: Int?,
val can_play_in_background: Int?,
val date: Int?,
val description: String?,
val duration: Int?,
val files: Files?,
val first_frame: List<FirstFrame>?,
val height: Int?,
val image: List<Image>?,
val is_author: Boolean?,
val is_favorite: Boolean?,
val is_from_message: Int?,
val need_mediascope_stat: Boolean?,
val ov_id: String?,
val owner_id: Long?,
val player: String?,
val processing: Int?,
val repeat: Int?,
val response_type: String?,
val shape_id: Long?,
val timeline_thumbs: TimelineThumbs?,
val title: String?,
val track_code: String?,
val transcript_state: String?,
val type: String?,
val views: Int?,
val width: Int?,
) : VkAttachmentData {
@JsonClass(generateAdapter = true)
data class Files(
val failover_host: String?,
val mp4_240: String?,
val mp4_480: String?,
)
@JsonClass(generateAdapter = true)
data class FirstFrame(
val height: Int?,
val url: String?,
val width: Int?,
)
@JsonClass(generateAdapter = true)
data class Image(
val height: Int?,
val url: String?,
val width: Int?,
val with_padding: Int?,
)
@JsonClass(generateAdapter = true)
data class TimelineThumbs(
val count_per_image: Int?,
val count_per_row: Int?,
val count_total: Int?,
val frame_height: Int?,
val frame_width: Double?,
val frequency: Int?,
val is_uv: Boolean?,
val links: List<String>?,
)
fun toDomain(): VkVideoMessageDomain = VkVideoMessageDomain(
id = id
)
}
@@ -6,9 +6,9 @@ import com.squareup.moshi.JsonClass
@JsonClass(generateAdapter = true)
data class VkWallData(
@Json(name = "id") val id: Int,
@Json(name = "from_id") val from_id: Int,
@Json(name = "to_id") val to_id: Int,
@Json(name = "id") val id: Long,
@Json(name = "from_id") val from_id: Long,
@Json(name = "to_id") val to_id: Long,
@Json(name = "date") val date: Int,
@Json(name = "text") val text: String,
@Json(name = "attachments") val attachments: List<VkAttachmentItemData>?,
@@ -5,12 +5,12 @@ import com.squareup.moshi.JsonClass
@JsonClass(generateAdapter = true)
data class VkWallReplyData(
val id: Int,
val from_id: Int,
val id: Long,
val from_id: Long,
val date: Int,
val text: String,
val post_id: Int,
val owner_id: Int,
val post_id: Long,
val owner_id: Long,
val parents_stack: List<Int>,
val likes: Likes,
val reply_to_user: Int?,
@@ -5,7 +5,7 @@ import com.squareup.moshi.JsonClass
@JsonClass(generateAdapter = true)
data class VkWidgetData(
val id: Int
val id: Long
) : VkAttachmentData {
fun toDomain() = VkWidgetDomain(id)
@@ -0,0 +1,10 @@
package dev.meloda.fast.model.api.domain
enum class FormatDataType {
BOLD, ITALIC, UNDERLINE, URL;
companion object {
fun parse(value: String): FormatDataType? =
entries.firstOrNull { it.name.lowercase() == value }
}
}
@@ -3,7 +3,7 @@ package dev.meloda.fast.model.api.domain
import dev.meloda.fast.model.api.data.AttachmentType
data class VkArticleDomain(
val id: Int
val id: Long
) : VkAttachment {
override val type: AttachmentType = AttachmentType.ARTICLE
@@ -1,10 +1,10 @@
package dev.meloda.fast.model.api.domain
data class VkAttachmentHistoryMessage(
val messageId: Int,
val conversationMessageId: Int,
val messageId: Long,
val conversationMessageId: Long,
val date: Int,
val fromId: Int,
val fromId: Long,
val position: Int,
val attachment: VkAttachment
)
@@ -3,8 +3,8 @@ package dev.meloda.fast.model.api.domain
import dev.meloda.fast.model.api.data.AttachmentType
data class VkAudioDomain(
val id: Int,
val ownerId: Int,
val id: Long,
val ownerId: Long,
val title: String,
val artist: String,
val url: String,
@@ -3,8 +3,8 @@ package dev.meloda.fast.model.api.domain
import dev.meloda.fast.model.api.data.AttachmentType
data class VkAudioMessageDomain(
val id: Int,
val ownerId: Int,
val id: Long,
val ownerId: Long,
val duration: Int,
val waveform: List<Int>,
val linkOgg: String,
@@ -3,8 +3,8 @@ package dev.meloda.fast.model.api.domain
import dev.meloda.fast.model.api.data.AttachmentType
data class VkAudioPlaylistDomain(
val id: Int,
val ownerId: Int,
val id: Long,
val ownerId: Long,
val title: String,
val description: String,
) : VkAttachment {
@@ -3,8 +3,8 @@ package dev.meloda.fast.model.api.domain
import dev.meloda.fast.model.api.data.AttachmentType
data class VkCallDomain(
val initiatorId: Int,
val receiverId: Int,
val initiatorId: Long,
val receiverId: Long,
val state: String,
val time: Int,
val duration: Int,
@@ -3,9 +3,9 @@ package dev.meloda.fast.model.api.domain
data class VkChatDomain(
val type: String,
val title: String,
val adminId: Int,
val adminId: Long,
val membersCount: Int,
val id: Int,
val id: Long,
val members: List<ChatMember> = emptyList(),
val photo50: String,
val photo100: String,
@@ -13,7 +13,7 @@ data class VkChatDomain(
val isDefaultPhoto: Boolean
) {
data class ChatMember(
val id: Int,
val id: Long,
val type: ChatMemberType,
val isOnline: Boolean?,
val lastSeen: Int?,
@@ -1,7 +1,7 @@
package dev.meloda.fast.model.api.domain
data class VkChatMemberDomain(
val memberId: Int,
val memberId: Long,
val invitedBy: Int,
val joinDate: Int,
val isAdmin: Boolean,
@@ -2,5 +2,5 @@ package dev.meloda.fast.model.api.domain
data class VkContactDomain(
val name: String,
val userId: Int
val userId: Long
)
@@ -4,31 +4,33 @@ import dev.meloda.fast.model.api.PeerType
import dev.meloda.fast.model.database.VkConversationEntity
data class VkConversation(
val id: Int,
val localId: Int,
val ownerId: Int?,
val id: Long,
val localId: Long,
val ownerId: Long?,
val title: String?,
val photo50: String?,
val photo100: String?,
val photo200: String?,
val isCallInProgress: Boolean,
val isPhantom: Boolean,
val lastConversationMessageId: Int,
val inReadCmId: Int,
val outReadCmId: Int,
val inRead: Int,
val outRead: Int,
val lastMessageId: Int?,
val lastCmId: Long,
val inReadCmId: Long,
val outReadCmId: Long,
val inRead: Long,
val outRead: Long,
val lastMessageId: Long?,
val unreadCount: Int,
val membersCount: Int?,
val canChangePin: Boolean,
val canChangeInfo: Boolean,
val majorId: Int,
val minorId: Int,
val pinnedMessageId: Int?,
val pinnedMessageId: Long?,
val interactionType: Int,
val interactionIds: List<Int>,
val interactionIds: List<Long>,
val peerType: PeerType,
val isArchived: Boolean,
val lastMessage: VkMessage?,
val pinnedMessage: VkMessage?,
val user: VkUser?,
@@ -36,8 +38,20 @@ data class VkConversation(
) {
fun isPinned(): Boolean = majorId > 0
fun isInUnread() = inRead - (lastMessageId ?: 0) < 0
fun isOutUnread() = outRead - (lastMessageId ?: 0) < 0
fun isInRead(cmId: Long? = null) = inReadCmId - (cmId ?: lastCmId) >= 0
fun isOutRead(cmId: Long? = null) = outReadCmId - (cmId ?: lastCmId) >= 0
fun isRead(lastMessage: VkMessage? = null): Boolean {
val message = lastMessage ?: this.lastMessage
return when {
message == null -> true
message.isOut -> isOutRead(message.cmId)
else -> isInRead(message.cmId)
}
}
companion object {
val EMPTY: VkConversation = VkConversation(
@@ -50,7 +64,7 @@ data class VkConversation(
photo200 = null,
isCallInProgress = false,
isPhantom = false,
lastConversationMessageId = -1,
lastCmId = -1,
inReadCmId = -1,
outReadCmId = -1,
inRead = -1,
@@ -66,11 +80,12 @@ data class VkConversation(
interactionType = -1,
interactionIds = emptyList(),
peerType = PeerType.USER,
isArchived = false,
lastMessage = null,
pinnedMessage = null,
user = null,
group = null
)
}
}
@@ -84,7 +99,7 @@ fun VkConversation.asEntity(): VkConversationEntity = VkConversationEntity(
photo100 = photo100,
photo200 = photo200,
isPhantom = isPhantom,
lastConversationMessageId = lastConversationMessageId,
lastConversationMessageId = lastCmId,
inReadCmId = inReadCmId,
outReadCmId = outReadCmId,
inRead = inRead,
@@ -98,4 +113,5 @@ fun VkConversation.asEntity(): VkConversationEntity = VkConversationEntity(
minorId = minorId,
pinnedMessageId = pinnedMessageId,
peerType = peerType.value,
isArchived = isArchived
)
@@ -3,7 +3,7 @@ package dev.meloda.fast.model.api.domain
import dev.meloda.fast.model.api.data.AttachmentType
data class VkCuratorDomain(
val id: Int,
val id: Long,
) : VkAttachment {
override val type: AttachmentType = AttachmentType.CURATOR
@@ -3,7 +3,7 @@ package dev.meloda.fast.model.api.domain
import dev.meloda.fast.model.api.data.AttachmentType
data class VkEventDomain(
val id: Int
val id: Long
) : VkAttachment {
override val type: AttachmentType = AttachmentType.EVENT
@@ -1,13 +1,13 @@
package dev.meloda.fast.model.api.domain
import com.squareup.moshi.JsonClass
import dev.meloda.fast.model.api.data.AttachmentType
import dev.meloda.fast.model.api.data.VkFileData
import com.squareup.moshi.JsonClass
@JsonClass(generateAdapter = true)
data class VkFileDomain(
val id: Int,
val ownerId: Int,
val id: Long,
val ownerId: Long,
val title: String,
val ext: String,
val size: Int,
@@ -3,7 +3,7 @@ package dev.meloda.fast.model.api.domain
import dev.meloda.fast.model.api.data.AttachmentType
data class VkGiftDomain(
val id: Int,
val id: Long,
val thumb256: String?,
val thumb96: String?,
val thumb48: String
@@ -3,8 +3,8 @@ package dev.meloda.fast.model.api.domain
import dev.meloda.fast.model.api.data.AttachmentType
data class VkGraffitiDomain(
val id: Int,
val ownerId: Int,
val id: Long,
val ownerId: Long,
val url: String,
val width: Int,
val height: Int,
@@ -3,7 +3,7 @@ package dev.meloda.fast.model.api.domain
import dev.meloda.fast.model.api.data.AttachmentType
data class VkGroupCallDomain(
val initiatorId: Int
val initiatorId: Long
) : VkAttachment {
override val type: AttachmentType = AttachmentType.GROUP_CALL_IN_PROGRESS
@@ -3,7 +3,7 @@ package dev.meloda.fast.model.api.domain
import dev.meloda.fast.model.database.VkGroupEntity
data class VkGroupDomain(
val id: Int,
val id: Long,
val name: String,
val screenName: String,
val photo50: String?,
@@ -13,14 +13,14 @@ data class VkGroupDomain(
) {
override fun toString() = name.trim()
fun mapToDB(): VkGroupEntity = VkGroupEntity(
id = id,
name = name,
screenName = screenName,
photo50 = photo50,
photo100 = photo100,
photo200 = photo200,
membersCount = membersCount
)
}
fun VkGroupDomain.asEntity(): VkGroupEntity = VkGroupEntity(
id = id,
name = name,
screenName = screenName,
photo50 = photo50,
photo100 = photo100,
photo200 = photo200,
membersCount = membersCount
)
@@ -0,0 +1,10 @@
package dev.meloda.fast.model.api.domain
import dev.meloda.fast.model.api.data.AttachmentType
data class VkGroupStickerDomain(
val id: Long
) : VkAttachment {
override val type: AttachmentType = AttachmentType.GROUP_CHAT_STICKER
}
@@ -5,30 +5,32 @@ import dev.meloda.fast.model.database.VkMessageEntity
@Immutable
data class VkMessage(
val id: Int,
val conversationMessageId: Int,
val id: Long,
val cmId: Long,
val text: String?,
val isOut: Boolean,
val peerId: Int,
val fromId: Int,
val peerId: Long,
val fromId: Long,
val date: Int,
val randomId: Int,
val randomId: Long,
val action: Action?,
val actionMemberId: Int?,
val actionMemberId: Long?,
val actionText: String?,
val actionConversationMessageId: Int?,
val actionConversationMessageId: Long?,
val actionMessage: String?,
val updateTime: Int?,
val pinnedAt: Int?,
val isPinned: Boolean,
val isImportant: Boolean = false,
val isSpam: Boolean = false,
val isImportant: Boolean,
val isSpam: Boolean,
val forwards: List<VkMessage>?,
val attachments: List<VkAttachment>?,
val replyMessage: VkMessage?,
val formatData: FormatData?,
val geoType: String?,
val user: VkUser?,
val group: VkGroupDomain?,
@@ -44,8 +46,7 @@ data class VkMessage(
fun isRead(conversation: VkConversation): Boolean = when {
id <= 0 -> false
isOut -> conversation.outRead - id >= 0
else -> conversation.inRead - id >= 0
else -> conversation.isRead(this)
}
fun hasAttachments(): Boolean = attachments.orEmpty().isNotEmpty()
@@ -80,11 +81,24 @@ data class VkMessage(
fun parse(value: String?): Action? = entries.firstOrNull { it.value == value }
}
}
data class FormatData(
val version: String,
val items: List<Item>
) {
data class Item(
val offset: Int,
val length: Int,
val type: FormatDataType,
val url: String?
)
}
}
fun VkMessage.asEntity(): VkMessageEntity = VkMessageEntity(
id = id,
conversationMessageId = conversationMessageId,
conversationMessageId = cmId,
text = text,
isOut = isOut,
peerId = peerId,
@@ -3,7 +3,7 @@ package dev.meloda.fast.model.api.domain
import dev.meloda.fast.model.api.data.AttachmentType
data class VkNarrativeDomain(
val id: Int,
val id: Long,
val title: String?
) : VkAttachment {
@@ -7,15 +7,15 @@ import java.util.Stack
// TODO: 11/04/2024, Danil Nikolaev: review
data class VkPhotoDomain(
val albumId: Int,
val albumId: Long,
val date: Int?,
val id: Int,
val ownerId: Int,
val id: Long,
val ownerId: Long,
val hasTags: Boolean,
val accessKey: String?,
val sizes: List<VkPhotoData.Size>,
val text: String?,
val userId: Int?
val userId: Long?
) : VkAttachment {
override val type: AttachmentType = AttachmentType.PHOTO
@@ -3,7 +3,7 @@ package dev.meloda.fast.model.api.domain
import dev.meloda.fast.model.api.data.AttachmentType
data class VkPodcastDomain(
val id: Int,
val id: Long,
val title: String,
val artist: String
) : VkAttachment {
@@ -3,7 +3,7 @@ package dev.meloda.fast.model.api.domain
import dev.meloda.fast.model.api.data.AttachmentType
data class VkPollDomain(
val id: Int
val id: Long
) : VkAttachment {
override val type: AttachmentType = AttachmentType.POLL
@@ -4,10 +4,10 @@ import dev.meloda.fast.model.api.data.AttachmentType
import dev.meloda.fast.model.api.data.VkStickerData
data class VkStickerDomain(
val id: Int,
val productId: Int,
val images: List<VkStickerData.Image>,
val backgroundImages: List<VkStickerData.Image>
val id: Long,
val productId: Long,
val images: List<VkStickerData.Image>?,
val backgroundImages: List<VkStickerData.Image>?
) : VkAttachment {
override val type: AttachmentType = AttachmentType.STICKER
@@ -15,7 +15,7 @@ data class VkStickerDomain(
val className: String = this::class.java.name
fun urlForSize(size: Int): String? {
for (image in images) {
for (image in images.orEmpty()) {
if (image.width == size) return image.url
}
@@ -0,0 +1,10 @@
package dev.meloda.fast.model.api.domain
import dev.meloda.fast.model.api.data.AttachmentType
data class VkStickerPackPreviewDomain(
val id: Long
): VkAttachment {
override val type: AttachmentType = AttachmentType.STICKER_PACK_PREVIEW
}
@@ -3,8 +3,8 @@ package dev.meloda.fast.model.api.domain
import dev.meloda.fast.model.api.data.AttachmentType
data class VkStoryDomain(
val id: Int,
val ownerId: Int,
val id: Long,
val ownerId: Long,
val date: Int,
val photo: VkPhotoDomain?
) : VkAttachment {
@@ -3,7 +3,7 @@ package dev.meloda.fast.model.api.domain
import dev.meloda.fast.model.database.VkUserEntity
data class VkUser(
val id: Int,
val id: Long,
val firstName: String,
val lastName: String,
val onlineStatus: OnlineStatus,
@@ -20,9 +20,12 @@ data class VkUser(
val fullName get() = "$firstName $lastName".trim()
}
sealed class OnlineStatus(open val appId: Int?) {
data class Online(override val appId: Int?) : OnlineStatus(appId)
data class OnlineMobile(override val appId: Int?) : OnlineStatus(appId)
sealed class OnlineStatus(open val appId: Long?) {
data class Online(override val appId: Long? = null) : OnlineStatus(appId)
data class OnlineMobile(override val appId: Long? = null) : OnlineStatus(appId)
data object Recently : OnlineStatus(null)
data object LastWeek : OnlineStatus(null)
data object LastMonth : OnlineStatus(null)
data object Offline : OnlineStatus(null)
fun isOnline(): Boolean = this is Online || this is OnlineMobile
@@ -1,13 +1,13 @@
package dev.meloda.fast.model.api.domain
import com.squareup.moshi.JsonClass
import dev.meloda.fast.model.api.data.AttachmentType
import dev.meloda.fast.model.api.data.VkVideoData
import com.squareup.moshi.JsonClass
@JsonClass(generateAdapter = true)
data class VkVideoDomain(
val id: Int,
val ownerId: Int,
val id: Long,
val ownerId: Long,
val images: List<VideoImage>,
val firstFrames: List<VkVideoData.FirstFrame>?,
val accessKey: String?,
@@ -0,0 +1,10 @@
package dev.meloda.fast.model.api.domain
import dev.meloda.fast.model.api.data.AttachmentType
data class VkVideoMessageDomain(
val id: Long
) : VkAttachment {
override val type: AttachmentType = AttachmentType.VIDEO_MESSAGE
}
@@ -4,9 +4,9 @@ import dev.meloda.fast.model.api.data.AttachmentType
import dev.meloda.fast.model.api.data.VkAttachmentItemData
data class VkWallDomain(
val id: Int,
val fromId: Int,
val toId: Int,
val id: Long,
val fromId: Long,
val toId: Long,
val date: Int,
val text: String,
val attachments: List<VkAttachmentItemData>?,
@@ -3,7 +3,7 @@ package dev.meloda.fast.model.api.domain
import dev.meloda.fast.model.api.data.AttachmentType
data class VkWallReplyDomain(
val id: Int
val id: Long
) : VkAttachment {
override val type: AttachmentType = AttachmentType.WALL_REPLY
@@ -3,7 +3,7 @@ package dev.meloda.fast.model.api.domain
import dev.meloda.fast.model.api.data.AttachmentType
data class VkWidgetDomain(
val id: Int
val id: Long
) : VkAttachment {
override val type: AttachmentType = AttachmentType.WIDGET
@@ -1,18 +1,20 @@
package dev.meloda.fast.model.api.requests
import dev.meloda.fast.model.ConversationsFilter
data class ConversationsGetRequest(
val count: Int? = null,
val offset: Int? = null,
val fields: String = "",
val filter: String = "all",
val filter: ConversationsFilter = ConversationsFilter.ALL,
val extended: Boolean? = true,
val startMessageId: Int? = null
val startMessageId: Long? = null
) {
val map
get() = mutableMapOf(
"fields" to fields,
"filter" to filter
"filter" to filter.toString().lowercase()
).apply {
count?.let { this["count"] = it.toString() }
offset?.let { this["offset"] = it.toString() }
@@ -20,15 +22,3 @@ data class ConversationsGetRequest(
startMessageId?.let { this["start_message_id"] = it.toString() }
}
}
data class ConversationsDeleteRequest(val peerId: Int) {
val map get() = mapOf("peer_id" to peerId.toString())
}
data class ConversationsPinRequest(val peerId: Int) {
val map get() = mapOf("peer_id" to peerId.toString())
}
data class ConversationsUnpinRequest(val peerId: Int) {
val map get() = mapOf("peer_id" to peerId.toString())
}
@@ -6,9 +6,9 @@ import dev.meloda.fast.model.api.domain.VkAttachment
data class MessagesGetHistoryRequest(
val count: Int? = null,
val offset: Int? = null,
val peerId: Int,
val peerId: Long,
val extended: Boolean? = null,
val startMessageId: Int? = null,
val startMessageId: Long? = null,
val rev: Boolean? = null,
val fields: String? = null,
) {
@@ -28,13 +28,13 @@ data class MessagesGetHistoryRequest(
}
data class MessagesSendRequest(
val peerId: Int,
val randomId: Int = 0,
val peerId: Long,
val randomId: Long = 0,
val message: String?,
val lat: Int? = null,
val lon: Int? = null,
val replyTo: Int? = null,
val stickerId: Int? = null,
val replyTo: Long? = null,
val stickerId: Long? = null,
val disableMentions: Boolean? = null,
val doNotParseLinks: Boolean? = null,
val silent: Boolean? = null,
@@ -65,8 +65,8 @@ data class MessagesSendRequest(
}
data class MessagesMarkAsReadRequest(
val peerId: Int,
val startMessageId: Int?
val peerId: Long,
val startMessageId: Long?
) {
val map: Map<String, String>
@@ -78,7 +78,7 @@ data class MessagesMarkAsReadRequest(
}
data class MessagesMarkAsImportantRequest(
val messagesIds: List<Int>,
val messagesIds: List<Long>,
val important: Boolean
) {
@@ -104,9 +104,9 @@ data class MessagesGetLongPollServerRequest(
data class MessagesPinMessageRequest(
val peerId: Int,
val messageId: Int? = null,
val conversationMessageId: Int? = null
val peerId: Long,
val messageId: Long? = null,
val conversationMessageId: Long? = null
) {
val map: Map<String, String>
@@ -119,15 +119,15 @@ data class MessagesPinMessageRequest(
}
data class MessagesUnpinMessageRequest(val peerId: Int) {
data class MessagesUnpinMessageRequest(val peerId: Long) {
val map: Map<String, String>
get() = mapOf("peer_id" to peerId.toString())
}
data class MessagesDeleteRequest(
val peerId: Int,
val messagesIds: List<Int>? = null,
val conversationsMessagesIds: List<Int>? = null,
val peerId: Long,
val messagesIds: List<Long>? = null,
val conversationsMessagesIds: List<Long>? = null,
val isSpam: Boolean? = null,
val deleteForAll: Boolean? = null
) {
@@ -147,25 +147,27 @@ data class MessagesDeleteRequest(
}
data class MessagesEditRequest(
val peerId: Int,
val messageId: Int,
val message: String? = null,
val lat: Float? = null,
val long: Float? = null,
val attachments: List<VkAttachment>? = null,
val notParseLinks: Boolean = false,
val keepSnippets: Boolean = true,
val keepForwardedMessages: Boolean = true
val peerId: Long,
val cmId: Long?,
val messageId: Long?,
val message: String?,
val lat: Float?,
val long: Float?,
val attachments: List<VkAttachment>?,
val notParseLinks: Boolean,
val keepSnippets: Boolean,
val keepForwardedMessages: Boolean
) {
val map: Map<String, String>
get() = mutableMapOf(
"peer_id" to peerId.toString(),
"message_id" to messageId.toString(),
"dont_parse_links" to notParseLinks.asInt().toString(),
"keep_snippets" to keepSnippets.asInt().toString(),
"keep_forward_messages" to keepForwardedMessages.asInt().toString()
).apply {
messageId?.let { this["message_id"] = it.toString() }
cmId?.let { this["cmid"] = it.toString() }
message?.let { this["message"] = it }
lat?.let { this["lat"] = it.toString() }
long?.let { this["long"] = it.toString() }
@@ -183,15 +185,20 @@ data class MessagesEditRequest(
data class MessagesGetByIdRequest(
val messagesIds: List<Int>,
val peerCmIds: List<Long>?,
val peerId: Long?,
val messagesIds: List<Long>?,
val cmIds: List<Long>?,
val extended: Boolean? = null,
val fields: String? = null
) {
val map: Map<String, String>
get() = mutableMapOf(
"message_ids" to messagesIds.joinToString(),
).apply {
get() = mutableMapOf<String, String>().apply {
peerCmIds?.let { this["peer_cmids"] = it.joinToString() }
peerId?.let { this["peer_id"] = it.toString() }
messagesIds?.let { this["message_ids"] = it.joinToString() }
cmIds?.let { this["cmids"] = it.joinToString() }
extended?.let { this["extended"] = it.asInt().toString() }
fields?.let { this["fields"] = it }
}
@@ -199,7 +206,7 @@ data class MessagesGetByIdRequest(
data class MessagesGetChatRequest(
val chatId: Int,
val chatId: Long,
val fields: String? = null
) {
@@ -213,7 +220,7 @@ data class MessagesGetChatRequest(
data class MessagesGetConversationMembersRequest(
val peerId: Int,
val peerId: Long,
val offset: Int? = null,
val count: Int? = null,
val extended: Boolean? = null,
@@ -234,8 +241,8 @@ data class MessagesGetConversationMembersRequest(
data class MessagesRemoveChatUserRequest(
val chatId: Int,
val memberId: Int
val chatId: Long,
val memberId: Long
) {
val map: Map<String, String>
get() = mapOf(
@@ -245,13 +252,13 @@ data class MessagesRemoveChatUserRequest(
}
data class MessagesGetHistoryAttachmentsRequest(
val peerId: Int,
val peerId: Long,
val extended: Boolean?,
val count: Int?,
val offset: Int?,
val preserveOrder: Boolean?,
val attachmentTypes: List<String>,
val conversationMessageId: Int,
val conversationMessageId: Long,
val fields: String?
) {
@@ -269,7 +276,7 @@ data class MessagesGetHistoryAttachmentsRequest(
}
data class MessagesCreateChatRequest(
val userIds: List<Int>?,
val userIds: List<Long>?,
val title: String?
) {
@@ -59,3 +59,33 @@ data class AuthWithAppRequest(
"sdk_fingerprint" to sdkFingerprint
)
}
data class GetAnonymTokenRequest(
val clientId: String,
val clientSecret: String
) {
val map
get() = mapOf(
"client_id" to clientId,
"client_secret" to clientSecret
)
}
data class ExchangeSilentTokenRequest(
val anonymToken: String,
val silentToken: String,
val silentUuid: String
) {
val map
get() = mapOf(
"access_token" to anonymToken,
"token" to silentToken,
"uuid" to silentUuid
)
}
data class GetExchangeTokenRequest(val accessToken: String) {
val map get() = mapOf("access_token" to accessToken)
}
@@ -1,7 +1,7 @@
package dev.meloda.fast.model.api.requests
data class UsersGetRequest(
val userIds: List<Int>? = null,
val userIds: List<Long>? = null,
val fields: String? = null,
val nomCase: String? = null
) {
@@ -35,5 +35,5 @@ data class ConversationsResponseItem(
@JsonClass(generateAdapter = true)
data class ConversationsDeleteResponse(
@Json(name = "last_deleted_id") val lastDeletedId: Int
@Json(name = "last_deleted_id") val lastDeletedId: Long
)
@@ -25,7 +25,8 @@ data class MessagesGetByIdResponse(
val count: Int,
val items: List<VkMessageData> = emptyList(),
val profiles: List<VkUserData>?,
val groups: List<VkGroupData>?
val groups: List<VkGroupData>?,
val contacts: List<VkContactData>?
)
@JsonClass(generateAdapter = true)
@@ -33,7 +34,8 @@ data class MessagesGetConversationMembersResponse(
val count: Int,
val items: List<VkChatMemberData>?,
val profiles: List<VkUserData>?,
val groups: List<VkGroupData>?
val groups: List<VkGroupData>?,
val contacts: List<VkContactData>?
)
@JsonClass(generateAdapter = true)
@@ -47,6 +49,12 @@ data class MessagesGetHistoryAttachmentsResponse(
@JsonClass(generateAdapter = true)
data class MessagesCreateChatResponse(
@Json(name = "chat_id") val chatId: Int,
@Json(name = "chat_id") val chatId: Long,
@Json(name = "peer_ids") val peerIds: List<Int>
)
@JsonClass(generateAdapter = true)
data class MessagesSendResponse(
@Json(name = "message_id") val messageId: Long,
@Json(name = "cmid") val cmId: Long
)
@@ -2,18 +2,29 @@ package dev.meloda.fast.model.api.responses
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import dev.meloda.fast.model.api.responses.AuthDirectResponse.BanInfo
@JsonClass(generateAdapter = true)
data class AuthDirectErrorOnlyResponse(
@Json(name = "error") val error: String,
@Json(name = "cant_get_code_open_restore") val restoreIfCannotGetCode: Boolean?,
@Json(name = "error") val error: String?,
@Json(name = "error_description") val errorDescription: String?,
@Json(name = "error_type") val errorType: String?
@Json(name = "error_type") val errorType: String?,
@Json(name = "ban_info") val banInfo: BanInfo?,
@Json(name = "captcha_sid") val captchaSid: String?,
@Json(name = "captcha_img") val captchaImage: String?,
@Json(name = "captcha_ts") val captchaTs: Double?,
@Json(name = "validation_sid") val validationSid: String?,
@Json(name = "validation_type") val validationType: String?,
@Json(name = "phone_mask") val phoneMask: String?,
@Json(name = "redirect_uri") val redirectUri: String?,
@Json(name = "validation_resend") val validationResend: String?,
)
@JsonClass(generateAdapter = true)
data class AuthDirectResponse(
@Json(name = "access_token") val accessToken: String?,
@Json(name = "user_id") val userId: Int?,
@Json(name = "user_id") val userId: Long?,
@Json(name = "trusted_hash") val validationHash: String?,
@Json(name = "validation_sid") val validationSid: String?,
@Json(name = "validation_type") val validationType: String?,
@@ -44,7 +55,45 @@ data class AuthDirectResponse(
}
@JsonClass(generateAdapter = true)
data class GetAnonymousTokenResponse(
@Json(name = "token") val token: String,
@Json(name = "expired_at") val expiredAt: Int
data class GetSilentTokenResponse(
@Json(name = "silent_token") val silentToken: String,
@Json(name = "silent_token_uuid") val silentTokenUuid: String,
@Json(name = "silent_token_ttl") val silentTokenTtl: Int,
@Json(name = "trusted_hash") val trustedHash: String?, // Приходит при наличии 2fa,
@Json(name = "error") val error: Error?
)
@JsonClass(generateAdapter = true)
data class Error(
@Json(name = "error_code") val errorCode: Int,
@Json(name = "error_msg") val errorMessage: Int,
@Json(name = "redirect_uri") val redirectUri: String?
)
@JsonClass(generateAdapter = true)
data class GetAnonymTokenResponse(
@Json(name = "token") val token: String
)
@JsonClass(generateAdapter = true)
data class ExchangeSilentTokenResponse(
@Json(name = "access_token") val accessToken: String,
@Json(name = "is_partial") val isPartial: Boolean,
@Json(name = "is_service") val isService: Boolean,
@Json(name = "additional_signup_required") val additionalSignupRequired: Boolean,
@Json(name = "user_id") val userId: Long,
@Json(name = "expires_in") val expiresIn: Long
)
@JsonClass(generateAdapter = true)
data class GetExchangeTokenResponse(
@Json(name = "users_exchange_tokens") val usersTokens: List<UserTokenInfo>
) {
@JsonClass(generateAdapter = true)
data class UserTokenInfo(
@Json(name = "user_id") val userId: Long,
@Json(name = "profile_type") val profileType: Int,
@Json(name = "common_token") val commonToken: String
)
}
@@ -4,7 +4,7 @@ import com.squareup.moshi.Json
data class PhotosGetMessagesUploadServerResponse(
@Json(name = "album_id")
val albumId: Int,
val albumid: Long,
@Json(name = "upload_url")
val uploadUrl: String
)
@@ -5,17 +5,17 @@ import com.squareup.moshi.Json
data class VideosSaveResponse(
@Json(name = "access_key") val accessKey: String,
val description: String,
@Json(name = "owner_id") val ownerId: Int,
@Json(name = "owner_id") val ownerid: Long,
val title: String,
@Json(name = "upload_url") val uploadUrl: String,
@Json(name = "video_id") val videoId: Int
@Json(name = "video_id") val videoid: Long
)
data class VideosUploadResponse(
@Json(name = "video_hash") val hash: String?,
val size: Int,
@Json(name = "direct_link") val directLink: String,
@Json(name = "owner_id") val ownerId: Int,
@Json(name = "video_id") val videoId: Int,
@Json(name = "owner_id") val ownerid: Long,
@Json(name = "video_id") val videoid: Long,
val error: String?
)
@@ -6,8 +6,9 @@ import androidx.room.PrimaryKey
@Entity(tableName = "accounts")
data class AccountEntity(
@PrimaryKey(autoGenerate = false)
val userId: Int,
val userId: Long,
val accessToken: String,
val fastToken: String?,
val trustedHash: String?
val trustedHash: String?,
val exchangeToken: String?
)
@@ -7,28 +7,29 @@ import dev.meloda.fast.model.api.domain.VkConversation
@Entity(tableName = "conversations")
data class VkConversationEntity(
@PrimaryKey val id: Int,
val localId: Int,
val ownerId: Int?,
@PrimaryKey val id: Long,
val localId: Long,
val ownerId: Long?,
val title: String?,
val photo50: String?,
val photo100: String?,
val photo200: String?,
val isPhantom: Boolean,
val lastConversationMessageId: Int,
val inReadCmId: Int,
val outReadCmId: Int,
val inRead: Int,
val outRead: Int,
val lastMessageId: Int?,
val lastConversationMessageId: Long,
val inReadCmId: Long,
val outReadCmId: Long,
val inRead: Long,
val outRead: Long,
val lastMessageId: Long?,
val unreadCount: Int,
val membersCount: Int?,
val canChangePin: Boolean,
val canChangeInfo: Boolean,
val majorId: Int,
val minorId: Int,
val pinnedMessageId: Int?,
val pinnedMessageId: Long?,
val peerType: String,
val isArchived: Boolean
)
fun VkConversationEntity.asExternalModel(): VkConversation = VkConversation(
@@ -41,7 +42,7 @@ fun VkConversationEntity.asExternalModel(): VkConversation = VkConversation(
photo200 = photo200,
isCallInProgress = false,
isPhantom = isPhantom,
lastConversationMessageId = lastConversationMessageId,
lastCmId = lastConversationMessageId,
inReadCmId = inReadCmId,
outReadCmId = outReadCmId,
inRead = inRead,
@@ -57,6 +58,8 @@ fun VkConversationEntity.asExternalModel(): VkConversation = VkConversation(
interactionType = -1,
interactionIds = emptyList(),
peerType = PeerType.parse(peerType),
isArchived = isArchived,
lastMessage = null,//lastMessage?.asExternalModel(),
pinnedMessage = null,//pinnedMessage?.asExternalModel(),
user = null,
@@ -2,10 +2,11 @@ package dev.meloda.fast.model.database
import androidx.room.Entity
import androidx.room.PrimaryKey
import dev.meloda.fast.model.api.domain.VkGroupDomain
@Entity(tableName = "groups")
data class VkGroupEntity(
@PrimaryKey val id: Int,
@PrimaryKey val id: Long,
val name: String,
val screenName: String,
val photo50: String?,
@@ -13,3 +14,13 @@ data class VkGroupEntity(
val photo200: String?,
val membersCount: Int?
)
fun VkGroupEntity.asDomain(): VkGroupDomain = VkGroupDomain(
id = id,
name = name,
screenName = screenName,
photo50 = photo50,
photo100 = photo100,
photo200 = photo200,
membersCount = membersCount
)
@@ -7,24 +7,24 @@ import dev.meloda.fast.model.api.domain.VkUnknownAttachment
@Entity(tableName = "messages")
data class VkMessageEntity(
@PrimaryKey val id: Int,
val conversationMessageId: Int,
@PrimaryKey val id: Long,
val conversationMessageId: Long,
val text: String?,
val isOut: Boolean,
val peerId: Int,
val fromId: Int,
val peerId: Long,
val fromId: Long,
val date: Int,
val randomId: Int,
val randomId: Long,
val action: String?,
val actionMemberId: Int?,
val actionMemberId: Long?,
val actionText: String?,
val actionConversationMessageId: Int?,
val actionConversationMessageId: Long?,
val actionMessage: String?,
val updateTime: Int?,
val important: Boolean,
val forwardIds: List<Int>?,
val forwardIds: List<Long>?,
val attachments: List<String>?, // TODO: 01/05/2024, Danil Nikolaev: how to store???
val replyMessageId: Int?,
val replyMessageId: Long?,
val geoType: String?,
val pinnedAt: Int?,
val isPinned: Boolean
@@ -32,7 +32,7 @@ data class VkMessageEntity(
fun VkMessageEntity.asExternalModel(): VkMessage = VkMessage(
id = id,
conversationMessageId = conversationMessageId,
cmId = conversationMessageId,
text = text,
isOut = isOut,
peerId = peerId,
@@ -56,5 +56,7 @@ fun VkMessageEntity.asExternalModel(): VkMessage = VkMessage(
actionUser = null,
actionGroup = null,
pinnedAt = pinnedAt,
isPinned = isPinned
isPinned = isPinned,
isSpam = false,
formatData = null,
)
@@ -2,17 +2,17 @@ package dev.meloda.fast.model.database
import androidx.room.Entity
import androidx.room.PrimaryKey
import dev.meloda.fast.model.api.domain.OnlineStatus
import dev.meloda.fast.model.api.data.parseUserOnlineState
import dev.meloda.fast.model.api.domain.VkUser
@Entity(tableName = "users")
data class VkUserEntity(
@PrimaryKey val id: Int,
@PrimaryKey val id: Long,
val firstName: String,
val lastName: String,
val isOnline: Boolean,
val isOnlineMobile: Boolean,
val onlineAppId: Int?,
val onlineAppId: Long?,
val lastSeen: Int?,
val lastSeenStatus: String?,
val birthday: String?,
@@ -26,11 +26,12 @@ fun VkUserEntity.asExternalModel(): VkUser = VkUser(
id = id,
firstName = firstName,
lastName = lastName,
onlineStatus = when {
!isOnline -> OnlineStatus.Offline
!isOnlineMobile -> OnlineStatus.Online(onlineAppId)
else -> OnlineStatus.OnlineMobile(onlineAppId)
},
onlineStatus = parseUserOnlineState(
isOnline = isOnline,
isOnlineMobile = isOnlineMobile,
status = lastSeenStatus,
appId = onlineAppId
),
photo50 = photo50,
photo100 = photo100,
photo200 = photo200,