chat theme change event
mark messages as important refactoring
This commit is contained in:
@@ -1,7 +1,10 @@
|
|||||||
package com.meloda.fast.api
|
package com.meloda.fast.api
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.graphics.Typeface
|
||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
|
import android.text.SpannableString
|
||||||
|
import android.text.style.StyleSpan
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import com.meloda.fast.R
|
import com.meloda.fast.R
|
||||||
import com.meloda.fast.api.model.VkGroup
|
import com.meloda.fast.api.model.VkGroup
|
||||||
@@ -51,9 +54,7 @@ object VkUtils {
|
|||||||
when (baseAttachment.getPreparedType()) {
|
when (baseAttachment.getPreparedType()) {
|
||||||
BaseVkAttachmentItem.AttachmentType.PHOTO -> {
|
BaseVkAttachmentItem.AttachmentType.PHOTO -> {
|
||||||
val photo = baseAttachment.photo ?: continue
|
val photo = baseAttachment.photo ?: continue
|
||||||
attachments += VkPhoto(
|
attachments += photo.asVkPhoto()
|
||||||
link = photo.sizes[0].url
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
BaseVkAttachmentItem.AttachmentType.VIDEO -> {
|
BaseVkAttachmentItem.AttachmentType.VIDEO -> {
|
||||||
val video = baseAttachment.video ?: continue
|
val video = baseAttachment.video ?: continue
|
||||||
@@ -206,8 +207,6 @@ object VkUtils {
|
|||||||
|
|
||||||
val actionUser = profiles?.get(memberId)
|
val actionUser = profiles?.get(memberId)
|
||||||
val actionGroup = groups?.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 (isUser && actionUser == null) return null
|
||||||
if (isGroup && actionGroup == null) return null
|
if (isGroup && actionGroup == null) return null
|
||||||
@@ -233,8 +232,6 @@ object VkUtils {
|
|||||||
|
|
||||||
val actionUser = profiles?.get(memberId)
|
val actionUser = profiles?.get(memberId)
|
||||||
val actionGroup = groups?.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 (isUser && actionUser == null) return null
|
||||||
if (isGroup && actionGroup == null) return null
|
if (isGroup && actionGroup == null) return null
|
||||||
@@ -302,11 +299,257 @@ object VkUtils {
|
|||||||
|
|
||||||
"$prefix took a screenshot"
|
"$prefix took a screenshot"
|
||||||
}
|
}
|
||||||
|
VkMessage.Action.CHAT_STYLE_UPDATE -> {
|
||||||
|
val prefix = when {
|
||||||
|
message.fromId == UserConfig.userId -> youPrefix
|
||||||
|
message.isUser() -> messageUser?.toString()
|
||||||
|
else -> return null
|
||||||
|
} ?: return null
|
||||||
|
|
||||||
|
"$prefix changed chat theme"
|
||||||
|
}
|
||||||
null -> null
|
null -> null
|
||||||
else -> "[${message.action}]"
|
else -> "[${message.action}]"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getActionMessageText(
|
||||||
|
message: VkMessage,
|
||||||
|
youPrefix: String,
|
||||||
|
profiles: HashMap<Int, VkUser>? = null,
|
||||||
|
groups: HashMap<Int, VkGroup>? = null,
|
||||||
|
messageUser: VkUser? = null,
|
||||||
|
messageGroup: VkGroup? = null
|
||||||
|
): SpannableString? {
|
||||||
|
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
|
||||||
|
|
||||||
|
val spanText = "$prefix created «$text»"
|
||||||
|
|
||||||
|
SpannableString(spanText).also {
|
||||||
|
it.setSpan(StyleSpan(Typeface.BOLD), 0, prefix.length, 0)
|
||||||
|
it.setSpan(
|
||||||
|
StyleSpan(Typeface.BOLD),
|
||||||
|
spanText.indexOf(text, startIndex = prefix.length),
|
||||||
|
text.length, 0
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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
|
||||||
|
|
||||||
|
val spanText = "$prefix renamed chat to «$text»"
|
||||||
|
|
||||||
|
val startIndex = spanText.indexOf(text)
|
||||||
|
|
||||||
|
SpannableString(spanText).also {
|
||||||
|
it.setSpan(StyleSpan(Typeface.BOLD), 0, prefix.length, 0)
|
||||||
|
it.setSpan(
|
||||||
|
StyleSpan(Typeface.BOLD), startIndex, startIndex + text.length, 0
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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
|
||||||
|
|
||||||
|
val spanText = "$prefix updated the chat photo"
|
||||||
|
SpannableString(spanText).also {
|
||||||
|
it.setSpan(StyleSpan(Typeface.BOLD), 0, prefix.length, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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
|
||||||
|
|
||||||
|
val spanText = "$prefix deleted the chat photo"
|
||||||
|
SpannableString(spanText).also {
|
||||||
|
it.setSpan(StyleSpan(Typeface.BOLD), 0, prefix.length, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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)
|
||||||
|
|
||||||
|
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()
|
||||||
|
val spanText = "$prefix left the chat"
|
||||||
|
SpannableString(spanText).also {
|
||||||
|
it.setSpan(StyleSpan(Typeface.BOLD), 0, prefix.length, 0)
|
||||||
|
}
|
||||||
|
} 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()
|
||||||
|
|
||||||
|
val spanText = "$prefix kicked $postfix"
|
||||||
|
val startIndex = spanText.indexOf(postfix)
|
||||||
|
|
||||||
|
SpannableString(spanText).also {
|
||||||
|
it.setSpan(StyleSpan(Typeface.BOLD), 0, prefix.length, 0)
|
||||||
|
it.setSpan(
|
||||||
|
StyleSpan(Typeface.BOLD), startIndex, startIndex + postfix.length, 0
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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)
|
||||||
|
|
||||||
|
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()
|
||||||
|
val spanText = "$prefix returned the chat"
|
||||||
|
SpannableString(spanText).also {
|
||||||
|
it.setSpan(StyleSpan(Typeface.BOLD), 0, prefix.length, 0)
|
||||||
|
}
|
||||||
|
} 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()
|
||||||
|
|
||||||
|
val spanText = "$prefix invited $postfix"
|
||||||
|
val startIndex = spanText.indexOf(postfix)
|
||||||
|
|
||||||
|
SpannableString(spanText).also {
|
||||||
|
it.setSpan(StyleSpan(Typeface.BOLD), 0, prefix.length, 0)
|
||||||
|
it.setSpan(
|
||||||
|
StyleSpan(Typeface.BOLD), startIndex, startIndex + postfix.length, 0
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
VkMessage.Action.CHAT_INVITE_USER_BY_LINK -> {
|
||||||
|
val prefix = when {
|
||||||
|
message.fromId == UserConfig.userId -> youPrefix
|
||||||
|
message.isUser() -> messageUser?.toString()
|
||||||
|
else -> return null
|
||||||
|
} ?: return null
|
||||||
|
|
||||||
|
val spanText = "$prefix joined the chat via link"
|
||||||
|
SpannableString(spanText).also {
|
||||||
|
it.setSpan(StyleSpan(Typeface.BOLD), 0, prefix.length, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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
|
||||||
|
|
||||||
|
val spanText = "$prefix joined the call via link"
|
||||||
|
SpannableString(spanText).also {
|
||||||
|
it.setSpan(StyleSpan(Typeface.BOLD), 0, prefix.length, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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
|
||||||
|
|
||||||
|
val spanText = "$prefix pinned message «$actionMessage»"
|
||||||
|
val startIndex = spanText.indexOf(actionMessage)
|
||||||
|
|
||||||
|
SpannableString(spanText).also {
|
||||||
|
it.setSpan(StyleSpan(Typeface.BOLD), 0, prefix.length, 0)
|
||||||
|
it.setSpan(
|
||||||
|
StyleSpan(Typeface.BOLD), startIndex, startIndex + actionMessage.length, 0
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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
|
||||||
|
|
||||||
|
val spanText = "$prefix unpinned message"
|
||||||
|
SpannableString(spanText).also {
|
||||||
|
it.setSpan(StyleSpan(Typeface.BOLD), 0, prefix.length, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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
|
||||||
|
|
||||||
|
val spanText = "$prefix took a screenshot"
|
||||||
|
SpannableString(spanText).also {
|
||||||
|
it.setSpan(StyleSpan(Typeface.BOLD), 0, prefix.length, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
VkMessage.Action.CHAT_STYLE_UPDATE -> {
|
||||||
|
val prefix = when {
|
||||||
|
message.fromId == UserConfig.userId -> youPrefix
|
||||||
|
message.isUser() -> messageUser?.toString()
|
||||||
|
else -> return null
|
||||||
|
} ?: return null
|
||||||
|
|
||||||
|
val spanText = "$prefix changed chat theme"
|
||||||
|
SpannableString(spanText).also {
|
||||||
|
it.setSpan(StyleSpan(Typeface.BOLD), 0, prefix.length, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
null -> null
|
||||||
|
else -> SpannableString("[${message.action}]")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun getForwardsConversationText(context: Context, message: VkMessage): String? {
|
fun getForwardsConversationText(context: Context, message: VkMessage): String? {
|
||||||
if (message.forwards.isNullOrEmpty()) return null
|
if (message.forwards.isNullOrEmpty()) return null
|
||||||
|
|
||||||
|
|||||||
@@ -1,18 +0,0 @@
|
|||||||
package com.meloda.fast.api.datasource
|
|
||||||
|
|
||||||
import com.meloda.fast.api.network.repo.MessagesRepo
|
|
||||||
import com.meloda.fast.api.network.request.MessagesGetHistoryRequest
|
|
||||||
import com.meloda.fast.api.network.request.MessagesSendRequest
|
|
||||||
import com.meloda.fast.database.dao.MessagesDao
|
|
||||||
import javax.inject.Inject
|
|
||||||
|
|
||||||
class MessagesDataSource @Inject constructor(
|
|
||||||
private val repo: MessagesRepo,
|
|
||||||
private val dao: MessagesDao
|
|
||||||
) {
|
|
||||||
|
|
||||||
suspend fun getHistory(params: MessagesGetHistoryRequest) = repo.getHistory(params.map)
|
|
||||||
|
|
||||||
suspend fun send(params: MessagesSendRequest) = repo.send(params.map)
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -24,7 +24,8 @@ data class VkMessage(
|
|||||||
val actionText: String? = null,
|
val actionText: String? = null,
|
||||||
val actionConversationMessageId: Int? = null,
|
val actionConversationMessageId: Int? = null,
|
||||||
val actionMessage: String? = null,
|
val actionMessage: String? = null,
|
||||||
val geoType: String? = null
|
val geoType: String? = null,
|
||||||
|
val important: Boolean = false
|
||||||
) : Parcelable {
|
) : Parcelable {
|
||||||
|
|
||||||
@IgnoredOnParcel
|
@IgnoredOnParcel
|
||||||
@@ -61,7 +62,8 @@ data class VkMessage(
|
|||||||
actionText = actionText,
|
actionText = actionText,
|
||||||
actionConversationMessageId = actionConversationMessageId,
|
actionConversationMessageId = actionConversationMessageId,
|
||||||
actionMessage = actionMessage,
|
actionMessage = actionMessage,
|
||||||
geoType = geoType
|
geoType = geoType,
|
||||||
|
important = important
|
||||||
)
|
)
|
||||||
|
|
||||||
enum class Action(val value: String) {
|
enum class Action(val value: String) {
|
||||||
@@ -78,7 +80,8 @@ data class VkMessage(
|
|||||||
|
|
||||||
// TODO: 9/11/2021 catch this shit
|
// TODO: 9/11/2021 catch this shit
|
||||||
CHAT_INVITE_USER_BY_CALL("chat_invite_user_by_call"),
|
CHAT_INVITE_USER_BY_CALL("chat_invite_user_by_call"),
|
||||||
CHAT_INVITE_USER_BY_CALL_LINK("chat_invite_user_by_call_join_link");
|
CHAT_INVITE_USER_BY_CALL_LINK("chat_invite_user_by_call_join_link"),
|
||||||
|
CHAT_STYLE_UPDATE("conversation_style_update");
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun parse(value: String) = values().first { it.value == value }
|
fun parse(value: String) = values().first { it.value == value }
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
package com.meloda.fast.api.model.attachments
|
package com.meloda.fast.api.model.attachments
|
||||||
|
|
||||||
abstract class VkAttachment
|
import android.os.Parcelable
|
||||||
|
|
||||||
|
abstract class VkAttachment : Parcelable
|
||||||
@@ -1,5 +1,8 @@
|
|||||||
package com.meloda.fast.api.model.attachments
|
package com.meloda.fast.api.model.attachments
|
||||||
|
|
||||||
|
import kotlinx.parcelize.Parcelize
|
||||||
|
|
||||||
|
@Parcelize
|
||||||
data class VkAudio(
|
data class VkAudio(
|
||||||
val link: String
|
val link: String
|
||||||
) : VkAttachment()
|
) : VkAttachment()
|
||||||
@@ -1,5 +1,8 @@
|
|||||||
package com.meloda.fast.api.model.attachments
|
package com.meloda.fast.api.model.attachments
|
||||||
|
|
||||||
|
import kotlinx.parcelize.Parcelize
|
||||||
|
|
||||||
|
@Parcelize
|
||||||
data class VkCall(
|
data class VkCall(
|
||||||
val initiatorId: Int
|
val initiatorId: Int
|
||||||
) : VkAttachment()
|
) : VkAttachment()
|
||||||
@@ -1,5 +1,8 @@
|
|||||||
package com.meloda.fast.api.model.attachments
|
package com.meloda.fast.api.model.attachments
|
||||||
|
|
||||||
|
import kotlinx.parcelize.Parcelize
|
||||||
|
|
||||||
|
@Parcelize
|
||||||
data class VkFile(
|
data class VkFile(
|
||||||
val link: String
|
val link: String
|
||||||
) : VkAttachment()
|
) : VkAttachment()
|
||||||
@@ -1,5 +1,8 @@
|
|||||||
package com.meloda.fast.api.model.attachments
|
package com.meloda.fast.api.model.attachments
|
||||||
|
|
||||||
|
import kotlinx.parcelize.Parcelize
|
||||||
|
|
||||||
|
@Parcelize
|
||||||
data class VkGift(
|
data class VkGift(
|
||||||
val link: String
|
val link: String
|
||||||
) : VkAttachment()
|
) : VkAttachment()
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
package com.meloda.fast.api.model.attachments
|
package com.meloda.fast.api.model.attachments
|
||||||
|
|
||||||
|
import kotlinx.parcelize.Parcelize
|
||||||
|
|
||||||
|
@Parcelize
|
||||||
data class VkGraffiti(
|
data class VkGraffiti(
|
||||||
val link: String
|
val link: String
|
||||||
) : VkAttachment()
|
) : VkAttachment()
|
||||||
@@ -1,5 +1,8 @@
|
|||||||
package com.meloda.fast.api.model.attachments
|
package com.meloda.fast.api.model.attachments
|
||||||
|
|
||||||
|
import kotlinx.parcelize.Parcelize
|
||||||
|
|
||||||
|
@Parcelize
|
||||||
data class VkGroupCall(
|
data class VkGroupCall(
|
||||||
val initiatorId: Int
|
val initiatorId: Int
|
||||||
) : VkAttachment()
|
) : VkAttachment()
|
||||||
@@ -1,5 +1,8 @@
|
|||||||
package com.meloda.fast.api.model.attachments
|
package com.meloda.fast.api.model.attachments
|
||||||
|
|
||||||
|
import kotlinx.parcelize.Parcelize
|
||||||
|
|
||||||
|
@Parcelize
|
||||||
data class VkLink(
|
data class VkLink(
|
||||||
val link: String
|
val link: String
|
||||||
) : VkAttachment()
|
) : VkAttachment()
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
package com.meloda.fast.api.model.attachments
|
package com.meloda.fast.api.model.attachments
|
||||||
|
|
||||||
|
import kotlinx.parcelize.Parcelize
|
||||||
|
|
||||||
|
@Parcelize
|
||||||
data class VkMiniApp(
|
data class VkMiniApp(
|
||||||
val link: String
|
val link: String
|
||||||
) : VkAttachment()
|
) : VkAttachment()
|
||||||
|
|||||||
@@ -1,5 +1,28 @@
|
|||||||
package com.meloda.fast.api.model.attachments
|
package com.meloda.fast.api.model.attachments
|
||||||
|
|
||||||
|
import com.meloda.fast.api.model.base.attachments.Size
|
||||||
|
import kotlinx.parcelize.Parcelize
|
||||||
|
|
||||||
|
@Parcelize
|
||||||
data class VkPhoto(
|
data class VkPhoto(
|
||||||
val link: String
|
val albumId: Int,
|
||||||
) : VkAttachment()
|
val date: Int,
|
||||||
|
val id: Int,
|
||||||
|
val ownerId: Int,
|
||||||
|
val hasTags: Boolean,
|
||||||
|
val accessKey: String?,
|
||||||
|
val sizes: List<Size>,
|
||||||
|
val text: String,
|
||||||
|
val userId: Int?
|
||||||
|
) : VkAttachment() {
|
||||||
|
|
||||||
|
fun sizeOfType(type: Char): Size? {
|
||||||
|
for (size in sizes) {
|
||||||
|
if (size.type == type.toString())
|
||||||
|
return size
|
||||||
|
}
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,5 +1,8 @@
|
|||||||
package com.meloda.fast.api.model.attachments
|
package com.meloda.fast.api.model.attachments
|
||||||
|
|
||||||
|
import kotlinx.parcelize.Parcelize
|
||||||
|
|
||||||
|
@Parcelize
|
||||||
data class VkPoll(
|
data class VkPoll(
|
||||||
val id: Int
|
val id: Int
|
||||||
) : VkAttachment()
|
) : VkAttachment()
|
||||||
@@ -1,5 +1,8 @@
|
|||||||
package com.meloda.fast.api.model.attachments
|
package com.meloda.fast.api.model.attachments
|
||||||
|
|
||||||
|
import kotlinx.parcelize.Parcelize
|
||||||
|
|
||||||
|
@Parcelize
|
||||||
data class VkSticker(
|
data class VkSticker(
|
||||||
val link: String
|
val link: String
|
||||||
) : VkAttachment()
|
) : VkAttachment()
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
package com.meloda.fast.api.model.attachments
|
package com.meloda.fast.api.model.attachments
|
||||||
|
|
||||||
|
import kotlinx.parcelize.Parcelize
|
||||||
|
|
||||||
|
@Parcelize
|
||||||
data class VkVideo(
|
data class VkVideo(
|
||||||
val link: String
|
val link: String
|
||||||
) : VkAttachment()
|
) : VkAttachment()
|
||||||
@@ -1,5 +1,8 @@
|
|||||||
package com.meloda.fast.api.model.attachments
|
package com.meloda.fast.api.model.attachments
|
||||||
|
|
||||||
|
import kotlinx.parcelize.Parcelize
|
||||||
|
|
||||||
|
@Parcelize
|
||||||
data class VkVoiceMessage(
|
data class VkVoiceMessage(
|
||||||
val link: String
|
val link: String
|
||||||
) : VkAttachment()
|
) : VkAttachment()
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
package com.meloda.fast.api.model.attachments
|
package com.meloda.fast.api.model.attachments
|
||||||
|
|
||||||
|
import kotlinx.parcelize.Parcelize
|
||||||
|
|
||||||
|
@Parcelize
|
||||||
data class VkWall(
|
data class VkWall(
|
||||||
val id: Int
|
val id: Int
|
||||||
) : VkAttachment()
|
) : VkAttachment()
|
||||||
@@ -1,5 +1,8 @@
|
|||||||
package com.meloda.fast.api.model.attachments
|
package com.meloda.fast.api.model.attachments
|
||||||
|
|
||||||
|
import kotlinx.parcelize.Parcelize
|
||||||
|
|
||||||
|
@Parcelize
|
||||||
data class VkWallReply(
|
data class VkWallReply(
|
||||||
val id: Int
|
val id: Int
|
||||||
) : VkAttachment()
|
) : VkAttachment()
|
||||||
@@ -46,7 +46,8 @@ data class BaseVkMessage(
|
|||||||
actionText = action?.text,
|
actionText = action?.text,
|
||||||
actionConversationMessageId = action?.conversationMessageId,
|
actionConversationMessageId = action?.conversationMessageId,
|
||||||
actionMessage = action?.message,
|
actionMessage = action?.message,
|
||||||
geoType = geo?.type
|
geoType = geo?.type,
|
||||||
|
important = important
|
||||||
).also {
|
).also {
|
||||||
it.attachments = VkUtils.parseAttachments(attachments)
|
it.attachments = VkUtils.parseAttachments(attachments)
|
||||||
it.forwards = VkUtils.parseForwards(fwdMessages)
|
it.forwards = VkUtils.parseForwards(fwdMessages)
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package com.meloda.fast.api.model.base.attachments
|
|||||||
|
|
||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
||||||
import com.google.gson.annotations.SerializedName
|
import com.google.gson.annotations.SerializedName
|
||||||
|
import com.meloda.fast.api.model.attachments.VkPhoto
|
||||||
import kotlinx.parcelize.Parcelize
|
import kotlinx.parcelize.Parcelize
|
||||||
|
|
||||||
@Parcelize
|
@Parcelize
|
||||||
@@ -15,12 +16,26 @@ data class BaseVkPhoto(
|
|||||||
@SerializedName("has_tags")
|
@SerializedName("has_tags")
|
||||||
val hasTags: Boolean,
|
val hasTags: Boolean,
|
||||||
@SerializedName("access_key")
|
@SerializedName("access_key")
|
||||||
val accessKey: String,
|
val accessKey: String?,
|
||||||
val sizes: List<Size>,
|
val sizes: List<Size>,
|
||||||
val text: String,
|
val text: String,
|
||||||
@SerializedName("user_id")
|
@SerializedName("user_id")
|
||||||
val userId: Int?
|
val userId: Int?
|
||||||
) : BaseVkAttachment()
|
) : BaseVkAttachment() {
|
||||||
|
|
||||||
|
fun asVkPhoto() = VkPhoto(
|
||||||
|
albumId = albumId,
|
||||||
|
date = date,
|
||||||
|
id = id,
|
||||||
|
ownerId = ownerId,
|
||||||
|
hasTags = hasTags,
|
||||||
|
accessKey = accessKey,
|
||||||
|
sizes = sizes,
|
||||||
|
text = text,
|
||||||
|
userId = userId
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Parcelize
|
@Parcelize
|
||||||
data class Size(
|
data class Size(
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package com.meloda.fast.api.network.request
|
package com.meloda.fast.api.model.request
|
||||||
|
|
||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
||||||
import com.google.gson.annotations.SerializedName
|
import com.google.gson.annotations.SerializedName
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package com.meloda.fast.api.network.request
|
package com.meloda.fast.api.model.request
|
||||||
|
|
||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
||||||
import kotlinx.parcelize.Parcelize
|
import kotlinx.parcelize.Parcelize
|
||||||
+16
-1
@@ -1,6 +1,7 @@
|
|||||||
package com.meloda.fast.api.network.request
|
package com.meloda.fast.api.model.request
|
||||||
|
|
||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
||||||
|
import com.google.gson.annotations.SerializedName
|
||||||
import kotlinx.parcelize.Parcelize
|
import kotlinx.parcelize.Parcelize
|
||||||
|
|
||||||
@Parcelize
|
@Parcelize
|
||||||
@@ -54,5 +55,19 @@ data class MessagesSendRequest(
|
|||||||
disableMentions?.let { this["disable_mentions"] = (if (it) 1 else 0).toString() }
|
disableMentions?.let { this["disable_mentions"] = (if (it) 1 else 0).toString() }
|
||||||
dontParseLinks?.let { this["dont_parse_links"] = (if (it) 1 else 0).toString() }
|
dontParseLinks?.let { this["dont_parse_links"] = (if (it) 1 else 0).toString() }
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Parcelize
|
||||||
|
data class MessagesMarkAsImportantRequest(
|
||||||
|
@SerializedName("message_ids")
|
||||||
|
val messagesIds: List<Int>,
|
||||||
|
val important: Boolean
|
||||||
|
) : Parcelable {
|
||||||
|
|
||||||
|
val map
|
||||||
|
get() = mutableMapOf(
|
||||||
|
"message_ids" to messagesIds.joinToString { it.toString() },
|
||||||
|
"important" to (if (important) 1 else 0).toString()
|
||||||
|
)
|
||||||
|
|
||||||
}
|
}
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package com.meloda.fast.api.network.request
|
package com.meloda.fast.api.model.request
|
||||||
|
|
||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
||||||
import kotlinx.parcelize.Parcelize
|
import kotlinx.parcelize.Parcelize
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package com.meloda.fast.api.network.response
|
package com.meloda.fast.api.model.response
|
||||||
|
|
||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
||||||
import com.google.gson.annotations.SerializedName
|
import com.google.gson.annotations.SerializedName
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package com.meloda.fast.api.network.response
|
package com.meloda.fast.api.model.response
|
||||||
|
|
||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
||||||
import com.google.gson.annotations.SerializedName
|
import com.google.gson.annotations.SerializedName
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package com.meloda.fast.api.network.response
|
package com.meloda.fast.api.model.response
|
||||||
|
|
||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
||||||
import com.meloda.fast.api.model.base.BaseVkConversation
|
import com.meloda.fast.api.model.base.BaseVkConversation
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
package com.meloda.fast.api.model.response
|
||||||
|
|
||||||
@@ -21,6 +21,7 @@ object VKUrls {
|
|||||||
object Messages {
|
object Messages {
|
||||||
const val GetHistory = "$API/messages.getHistory"
|
const val GetHistory = "$API/messages.getHistory"
|
||||||
const val Send = "$API/messages.send"
|
const val Send = "$API/messages.send"
|
||||||
|
const val MarkAsImportant = "$API/messages.markAsImportant"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -1,7 +1,7 @@
|
|||||||
package com.meloda.fast.api.datasource
|
package com.meloda.fast.api.network.datasource
|
||||||
|
|
||||||
import com.meloda.fast.api.network.repo.AuthRepo
|
import com.meloda.fast.api.network.repo.AuthRepo
|
||||||
import com.meloda.fast.api.network.request.RequestAuthDirect
|
import com.meloda.fast.api.model.request.RequestAuthDirect
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class AuthDataSource @Inject constructor(
|
class AuthDataSource @Inject constructor(
|
||||||
+2
-2
@@ -1,8 +1,8 @@
|
|||||||
package com.meloda.fast.api.datasource
|
package com.meloda.fast.api.network.datasource
|
||||||
|
|
||||||
import com.meloda.fast.api.model.VkConversation
|
import com.meloda.fast.api.model.VkConversation
|
||||||
import com.meloda.fast.api.network.repo.ConversationsRepo
|
import com.meloda.fast.api.network.repo.ConversationsRepo
|
||||||
import com.meloda.fast.api.network.request.ConversationsGetRequest
|
import com.meloda.fast.api.model.request.ConversationsGetRequest
|
||||||
import com.meloda.fast.database.dao.ConversationsDao
|
import com.meloda.fast.database.dao.ConversationsDao
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package com.meloda.fast.api.network.datasource
|
||||||
|
|
||||||
|
import com.meloda.fast.api.model.request.MessagesGetHistoryRequest
|
||||||
|
import com.meloda.fast.api.model.request.MessagesMarkAsImportantRequest
|
||||||
|
import com.meloda.fast.api.model.request.MessagesSendRequest
|
||||||
|
import com.meloda.fast.api.network.repo.MessagesRepo
|
||||||
|
import com.meloda.fast.database.dao.MessagesDao
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class MessagesDataSource @Inject constructor(
|
||||||
|
private val repo: MessagesRepo,
|
||||||
|
private val dao: MessagesDao
|
||||||
|
) {
|
||||||
|
|
||||||
|
suspend fun getHistory(params: MessagesGetHistoryRequest) =
|
||||||
|
repo.getHistory(params.map)
|
||||||
|
|
||||||
|
suspend fun send(params: MessagesSendRequest) =
|
||||||
|
repo.send(params.map)
|
||||||
|
|
||||||
|
suspend fun markAsImportant(params: MessagesMarkAsImportantRequest) =
|
||||||
|
repo.markAsImportant(params.map)
|
||||||
|
|
||||||
|
}
|
||||||
+2
-2
@@ -1,8 +1,8 @@
|
|||||||
package com.meloda.fast.api.datasource
|
package com.meloda.fast.api.network.datasource
|
||||||
|
|
||||||
import com.meloda.fast.api.model.VkUser
|
import com.meloda.fast.api.model.VkUser
|
||||||
import com.meloda.fast.api.network.repo.UsersRepo
|
import com.meloda.fast.api.network.repo.UsersRepo
|
||||||
import com.meloda.fast.api.network.request.UsersGetRequest
|
import com.meloda.fast.api.model.request.UsersGetRequest
|
||||||
import com.meloda.fast.database.dao.UsersDao
|
import com.meloda.fast.database.dao.UsersDao
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
package com.meloda.fast.api.network.repo
|
package com.meloda.fast.api.network.repo
|
||||||
|
|
||||||
import com.meloda.fast.api.network.VKUrls
|
import com.meloda.fast.api.network.VKUrls
|
||||||
import com.meloda.fast.api.network.response.ResponseAuthDirect
|
import com.meloda.fast.api.model.response.ResponseAuthDirect
|
||||||
import com.meloda.fast.api.network.Answer
|
import com.meloda.fast.api.network.Answer
|
||||||
import com.meloda.fast.api.network.response.ResponseSendSms
|
import com.meloda.fast.api.model.response.ResponseSendSms
|
||||||
import retrofit2.http.*
|
import retrofit2.http.*
|
||||||
|
|
||||||
interface AuthRepo {
|
interface AuthRepo {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package com.meloda.fast.api.network.repo
|
|||||||
import com.meloda.fast.api.base.ApiResponse
|
import com.meloda.fast.api.base.ApiResponse
|
||||||
import com.meloda.fast.api.network.Answer
|
import com.meloda.fast.api.network.Answer
|
||||||
import com.meloda.fast.api.network.VKUrls
|
import com.meloda.fast.api.network.VKUrls
|
||||||
import com.meloda.fast.api.network.response.ConversationsGetResponse
|
import com.meloda.fast.api.model.response.ConversationsGetResponse
|
||||||
import retrofit2.http.FieldMap
|
import retrofit2.http.FieldMap
|
||||||
import retrofit2.http.FormUrlEncoded
|
import retrofit2.http.FormUrlEncoded
|
||||||
import retrofit2.http.POST
|
import retrofit2.http.POST
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
package com.meloda.fast.api.network.repo
|
package com.meloda.fast.api.network.repo
|
||||||
|
|
||||||
import com.meloda.fast.api.base.ApiResponse
|
import com.meloda.fast.api.base.ApiResponse
|
||||||
|
import com.meloda.fast.api.model.response.MessagesGetHistoryResponse
|
||||||
import com.meloda.fast.api.network.Answer
|
import com.meloda.fast.api.network.Answer
|
||||||
import com.meloda.fast.api.network.VKUrls
|
import com.meloda.fast.api.network.VKUrls
|
||||||
import com.meloda.fast.api.network.response.MessagesGetHistoryResponse
|
|
||||||
import retrofit2.http.FieldMap
|
import retrofit2.http.FieldMap
|
||||||
import retrofit2.http.FormUrlEncoded
|
import retrofit2.http.FormUrlEncoded
|
||||||
import retrofit2.http.POST
|
import retrofit2.http.POST
|
||||||
@@ -18,4 +18,8 @@ interface MessagesRepo {
|
|||||||
@POST(VKUrls.Messages.Send)
|
@POST(VKUrls.Messages.Send)
|
||||||
suspend fun send(@FieldMap params: Map<String, String>): Answer<ApiResponse<Int>>
|
suspend fun send(@FieldMap params: Map<String, String>): Answer<ApiResponse<Int>>
|
||||||
|
|
||||||
|
@FormUrlEncoded
|
||||||
|
@POST(VKUrls.Messages.MarkAsImportant)
|
||||||
|
suspend fun markAsImportant(@FieldMap params: Map<String, String>): Answer<ApiResponse<List<Int>>>
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
package com.meloda.fast.api.network.response
|
|
||||||
|
|
||||||
import android.os.Parcelable
|
|
||||||
import kotlinx.parcelize.Parcelize
|
|
||||||
|
|
||||||
@@ -18,7 +18,7 @@ import com.meloda.fast.database.dao.UsersDao
|
|||||||
VkUser::class,
|
VkUser::class,
|
||||||
VkGroup::class
|
VkGroup::class
|
||||||
],
|
],
|
||||||
version = 15,
|
version = 16,
|
||||||
exportSchema = false
|
exportSchema = false
|
||||||
)
|
)
|
||||||
abstract class AppDatabase : RoomDatabase() {
|
abstract class AppDatabase : RoomDatabase() {
|
||||||
|
|||||||
@@ -2,10 +2,10 @@ package com.meloda.fast.di
|
|||||||
|
|
||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
import com.google.gson.GsonBuilder
|
import com.google.gson.GsonBuilder
|
||||||
import com.meloda.fast.api.datasource.AuthDataSource
|
import com.meloda.fast.api.network.datasource.AuthDataSource
|
||||||
import com.meloda.fast.api.datasource.ConversationsDataSource
|
import com.meloda.fast.api.network.datasource.ConversationsDataSource
|
||||||
import com.meloda.fast.api.datasource.MessagesDataSource
|
import com.meloda.fast.api.network.datasource.MessagesDataSource
|
||||||
import com.meloda.fast.api.datasource.UsersDataSource
|
import com.meloda.fast.api.network.datasource.UsersDataSource
|
||||||
import com.meloda.fast.api.network.AuthInterceptor
|
import com.meloda.fast.api.network.AuthInterceptor
|
||||||
import com.meloda.fast.api.network.ResultCallFactory
|
import com.meloda.fast.api.network.ResultCallFactory
|
||||||
import com.meloda.fast.api.network.repo.AuthRepo
|
import com.meloda.fast.api.network.repo.AuthRepo
|
||||||
|
|||||||
+30
-21
@@ -9,7 +9,6 @@ import androidx.fragment.app.viewModels
|
|||||||
import androidx.navigation.fragment.findNavController
|
import androidx.navigation.fragment.findNavController
|
||||||
import coil.load
|
import coil.load
|
||||||
import com.google.android.material.appbar.AppBarLayout
|
import com.google.android.material.appbar.AppBarLayout
|
||||||
import com.google.android.material.snackbar.Snackbar
|
|
||||||
import com.meloda.fast.R
|
import com.meloda.fast.R
|
||||||
import com.meloda.fast.api.UserConfig
|
import com.meloda.fast.api.UserConfig
|
||||||
import com.meloda.fast.api.model.VkConversation
|
import com.meloda.fast.api.model.VkConversation
|
||||||
@@ -27,34 +26,38 @@ class ConversationsFragment :
|
|||||||
BaseViewModelFragment<ConversationsViewModel>(R.layout.fragment_conversations) {
|
BaseViewModelFragment<ConversationsViewModel>(R.layout.fragment_conversations) {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val TAG: String = ConversationsFragment::class.java.name
|
const val TAG = "ConversationsFragment"
|
||||||
}
|
}
|
||||||
|
|
||||||
override val viewModel: ConversationsViewModel by viewModels()
|
override val viewModel: ConversationsViewModel by viewModels()
|
||||||
private val binding: FragmentConversationsBinding by viewBinding()
|
private val binding: FragmentConversationsBinding by viewBinding()
|
||||||
|
|
||||||
private lateinit var adapter: ConversationsAdapter
|
private val adapter: ConversationsAdapter by lazy {
|
||||||
|
ConversationsAdapter(
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
requireContext(),
|
||||||
super.onViewCreated(view, savedInstanceState)
|
mutableListOf(),
|
||||||
|
hashMapOf(),
|
||||||
viewModel.loadProfileUser()
|
hashMapOf()
|
||||||
|
).also {
|
||||||
prepareViews()
|
|
||||||
|
|
||||||
adapter = ConversationsAdapter(requireContext(), mutableListOf()).also {
|
|
||||||
it.itemClickListener = this::onItemClick
|
it.itemClickListener = this::onItemClick
|
||||||
it.itemLongClickListener = this::onItemLongClick
|
it.itemLongClickListener = this::onItemLongClick
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private var isPaused = false
|
||||||
|
|
||||||
|
override fun onPause() {
|
||||||
|
super.onPause()
|
||||||
|
isPaused = true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
prepareViews()
|
||||||
|
|
||||||
binding.recyclerView.adapter = adapter
|
binding.recyclerView.adapter = adapter
|
||||||
|
|
||||||
viewModel.loadConversations()
|
binding.createChat.setOnClickListener {}
|
||||||
|
|
||||||
binding.createChat.setOnClickListener {
|
|
||||||
Snackbar.make(it, "Test Snackbar with action", Snackbar.LENGTH_LONG)
|
|
||||||
.setAction("Action") {}.show()
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
UserConfig.vkUser.observe(viewLifecycleOwner) {
|
UserConfig.vkUser.observe(viewLifecycleOwner) {
|
||||||
it?.let { user -> binding.avatar.load(user.photo200) { crossfade(100) } }
|
it?.let { user -> binding.avatar.load(user.photo200) { crossfade(100) } }
|
||||||
@@ -68,10 +71,16 @@ class ConversationsFragment :
|
|||||||
|
|
||||||
val alpha = 1 - abs(verticalOffset * 0.01).toFloat()
|
val alpha = 1 - abs(verticalOffset * 0.01).toFloat()
|
||||||
|
|
||||||
// println("offset: $verticalOffset; alpha: $alpha")
|
|
||||||
|
|
||||||
binding.avatarContainer.alpha = alpha
|
binding.avatarContainer.alpha = alpha
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if (isPaused) {
|
||||||
|
isPaused = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.loadProfileUser()
|
||||||
|
viewModel.loadConversations()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onEvent(event: VKEvent) {
|
override fun onEvent(event: VKEvent) {
|
||||||
|
|||||||
@@ -3,13 +3,13 @@ package com.meloda.fast.screens.conversations
|
|||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import com.meloda.fast.api.UserConfig
|
import com.meloda.fast.api.UserConfig
|
||||||
import com.meloda.fast.api.VKConstants
|
import com.meloda.fast.api.VKConstants
|
||||||
import com.meloda.fast.api.datasource.ConversationsDataSource
|
import com.meloda.fast.api.network.datasource.ConversationsDataSource
|
||||||
import com.meloda.fast.api.datasource.UsersDataSource
|
import com.meloda.fast.api.network.datasource.UsersDataSource
|
||||||
import com.meloda.fast.api.model.VkConversation
|
import com.meloda.fast.api.model.VkConversation
|
||||||
import com.meloda.fast.api.model.VkGroup
|
import com.meloda.fast.api.model.VkGroup
|
||||||
import com.meloda.fast.api.model.VkUser
|
import com.meloda.fast.api.model.VkUser
|
||||||
import com.meloda.fast.api.network.request.ConversationsGetRequest
|
import com.meloda.fast.api.model.request.ConversationsGetRequest
|
||||||
import com.meloda.fast.api.network.request.UsersGetRequest
|
import com.meloda.fast.api.model.request.UsersGetRequest
|
||||||
import com.meloda.fast.base.viewmodel.BaseViewModel
|
import com.meloda.fast.base.viewmodel.BaseViewModel
|
||||||
import com.meloda.fast.base.viewmodel.StartProgressEvent
|
import com.meloda.fast.base.viewmodel.StartProgressEvent
|
||||||
import com.meloda.fast.base.viewmodel.StopProgressEvent
|
import com.meloda.fast.base.viewmodel.StopProgressEvent
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ import com.meloda.fast.api.UserConfig
|
|||||||
import com.meloda.fast.api.VKConstants
|
import com.meloda.fast.api.VKConstants
|
||||||
import com.meloda.fast.api.VKException
|
import com.meloda.fast.api.VKException
|
||||||
import com.meloda.fast.api.VkUtils
|
import com.meloda.fast.api.VkUtils
|
||||||
import com.meloda.fast.api.datasource.AuthDataSource
|
import com.meloda.fast.api.network.datasource.AuthDataSource
|
||||||
import com.meloda.fast.api.network.request.RequestAuthDirect
|
import com.meloda.fast.api.model.request.RequestAuthDirect
|
||||||
import com.meloda.fast.base.viewmodel.BaseViewModel
|
import com.meloda.fast.base.viewmodel.BaseViewModel
|
||||||
import com.meloda.fast.base.viewmodel.StartProgressEvent
|
import com.meloda.fast.base.viewmodel.StartProgressEvent
|
||||||
import com.meloda.fast.base.viewmodel.StopProgressEvent
|
import com.meloda.fast.base.viewmodel.StopProgressEvent
|
||||||
|
|||||||
@@ -3,19 +3,22 @@ package com.meloda.fast.screens.messages
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
import android.widget.FrameLayout
|
||||||
|
import androidx.appcompat.widget.LinearLayoutCompat
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import androidx.recyclerview.widget.DiffUtil
|
import androidx.recyclerview.widget.DiffUtil
|
||||||
import coil.load
|
import coil.load
|
||||||
|
import com.meloda.fast.R
|
||||||
|
import com.meloda.fast.api.VkUtils
|
||||||
import com.meloda.fast.api.model.VkConversation
|
import com.meloda.fast.api.model.VkConversation
|
||||||
import com.meloda.fast.api.model.VkGroup
|
import com.meloda.fast.api.model.VkGroup
|
||||||
import com.meloda.fast.api.model.VkMessage
|
import com.meloda.fast.api.model.VkMessage
|
||||||
import com.meloda.fast.api.model.VkUser
|
import com.meloda.fast.api.model.VkUser
|
||||||
|
import com.meloda.fast.api.model.attachments.VkPhoto
|
||||||
import com.meloda.fast.base.adapter.BaseAdapter
|
import com.meloda.fast.base.adapter.BaseAdapter
|
||||||
import com.meloda.fast.base.adapter.BaseHolder
|
import com.meloda.fast.base.adapter.BaseHolder
|
||||||
import com.meloda.fast.common.AppGlobal
|
import com.meloda.fast.common.AppGlobal
|
||||||
import com.meloda.fast.databinding.ItemMessageInBinding
|
import com.meloda.fast.databinding.*
|
||||||
import com.meloda.fast.databinding.ItemMessageOutBinding
|
|
||||||
import com.meloda.fast.databinding.ItemMessageServiceBinding
|
|
||||||
import com.meloda.fast.util.AndroidUtils
|
import com.meloda.fast.util.AndroidUtils
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
@@ -37,6 +40,15 @@ class MessagesHistoryAdapter constructor(
|
|||||||
if (viewType == -1) {
|
if (viewType == -1) {
|
||||||
getItem(position).let {
|
getItem(position).let {
|
||||||
if (it.action != null) viewType = SERVICE
|
if (it.action != null) viewType = SERVICE
|
||||||
|
|
||||||
|
val attachments = it.attachments ?: return@let
|
||||||
|
if (attachments.isEmpty()) return@let
|
||||||
|
if (VkUtils.isAttachmentsHaveOneType(attachments) &&
|
||||||
|
attachments[0] is VkPhoto
|
||||||
|
) {
|
||||||
|
return if (it.isOut) ATTACHMENT_PHOTOS_OUT else ATTACHMENT_PHOTOS_IN
|
||||||
|
}
|
||||||
|
|
||||||
if (it.isOut) viewType = OUTGOING
|
if (it.isOut) viewType = OUTGOING
|
||||||
if (!it.isOut) viewType = INCOMING
|
if (!it.isOut) viewType = INCOMING
|
||||||
}
|
}
|
||||||
@@ -52,9 +64,21 @@ class MessagesHistoryAdapter constructor(
|
|||||||
return when (viewType) {
|
return when (viewType) {
|
||||||
HEADER -> Header(createEmptyView(60))
|
HEADER -> Header(createEmptyView(60))
|
||||||
FOOTER -> Footer(createEmptyView(36))
|
FOOTER -> Footer(createEmptyView(36))
|
||||||
SERVICE -> ServiceMessage(ItemMessageServiceBinding.inflate(inflater, parent, false))
|
SERVICE -> ServiceMessage(
|
||||||
OUTGOING -> OutgoingMessage(ItemMessageOutBinding.inflate(inflater, parent, false))
|
ItemMessageServiceBinding.inflate(inflater, parent, false)
|
||||||
INCOMING -> IncomingMessage(ItemMessageInBinding.inflate(inflater, parent, false))
|
)
|
||||||
|
ATTACHMENT_PHOTOS_IN -> AttachmentPhotosIncoming(
|
||||||
|
ItemMessageAttachmentPhotoInBinding.inflate(inflater, parent, false)
|
||||||
|
)
|
||||||
|
ATTACHMENT_PHOTOS_OUT -> AttachmentPhotosOutgoing(
|
||||||
|
ItemMessageAttachmentPhotoOutBinding.inflate(inflater, parent, false)
|
||||||
|
)
|
||||||
|
OUTGOING -> OutgoingMessage(
|
||||||
|
ItemMessageOutBinding.inflate(inflater, parent, false)
|
||||||
|
)
|
||||||
|
INCOMING -> IncomingMessage(
|
||||||
|
ItemMessageInBinding.inflate(inflater, parent, false)
|
||||||
|
)
|
||||||
else -> Holder()
|
else -> Holder()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -83,12 +107,87 @@ class MessagesHistoryAdapter constructor(
|
|||||||
|
|
||||||
inner class Footer(v: View) : Holder(v)
|
inner class Footer(v: View) : Holder(v)
|
||||||
|
|
||||||
|
inner class AttachmentPhotosIncoming(
|
||||||
|
private val binding: ItemMessageAttachmentPhotoInBinding
|
||||||
|
) : Holder(binding.root) {
|
||||||
|
|
||||||
|
init {
|
||||||
|
binding.photo.shapeAppearanceModel = binding.photo.shapeAppearanceModel.withCornerSize {
|
||||||
|
AndroidUtils.px(12)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun bind(position: Int) {
|
||||||
|
val message = getItem(position)
|
||||||
|
|
||||||
|
val photo = message.attachments?.get(0) as? VkPhoto ?: return
|
||||||
|
|
||||||
|
val size = photo.sizeOfType('m') ?: return
|
||||||
|
|
||||||
|
binding.photo.layoutParams = FrameLayout.LayoutParams(
|
||||||
|
AndroidUtils.px(size.width).roundToInt(),
|
||||||
|
AndroidUtils.px(size.height).roundToInt()
|
||||||
|
)
|
||||||
|
|
||||||
|
binding.photo.load(size.url)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
inner class AttachmentPhotosOutgoing(
|
||||||
|
private val binding: ItemMessageAttachmentPhotoOutBinding
|
||||||
|
) : Holder(binding.root) {
|
||||||
|
|
||||||
|
init {
|
||||||
|
binding.photo.shapeAppearanceModel = binding.photo.shapeAppearanceModel.withCornerSize {
|
||||||
|
AndroidUtils.px(12)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun bind(position: Int) {
|
||||||
|
val message = getItem(position)
|
||||||
|
|
||||||
|
val photo = message.attachments?.get(0) as? VkPhoto ?: return
|
||||||
|
|
||||||
|
val size = photo.sizeOfType('m') ?: return
|
||||||
|
|
||||||
|
binding.photo.layoutParams = LinearLayoutCompat.LayoutParams(
|
||||||
|
AndroidUtils.px(size.width).roundToInt(),
|
||||||
|
AndroidUtils.px(size.height).roundToInt()
|
||||||
|
)
|
||||||
|
|
||||||
|
binding.photo.load(size.url)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
inner class ServiceMessage(
|
inner class ServiceMessage(
|
||||||
private val binding: ItemMessageServiceBinding
|
private val binding: ItemMessageServiceBinding
|
||||||
) : Holder(binding.root) {
|
) : Holder(binding.root) {
|
||||||
|
|
||||||
override fun bind(position: Int) {
|
private val youPrefix = context.getString(R.string.you_message_prefix)
|
||||||
|
|
||||||
|
override fun bind(position: Int) {
|
||||||
|
val message = getItem(position)
|
||||||
|
|
||||||
|
val messageUser =
|
||||||
|
if (message.isUser()) profiles[message.fromId]
|
||||||
|
else null
|
||||||
|
|
||||||
|
val messageGroup =
|
||||||
|
if (message.isGroup()) groups[message.fromId]
|
||||||
|
else null
|
||||||
|
|
||||||
|
message.action ?: return
|
||||||
|
|
||||||
|
binding.message.text = VkUtils.getActionMessageText(
|
||||||
|
message = message,
|
||||||
|
youPrefix = youPrefix,
|
||||||
|
profiles = profiles,
|
||||||
|
groups = groups,
|
||||||
|
messageUser = messageUser,
|
||||||
|
messageGroup = messageGroup
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -176,11 +275,14 @@ class MessagesHistoryAdapter constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val INCOMING = 1001
|
private const val SERVICE = 1
|
||||||
private const val OUTGOING = 1002
|
|
||||||
private const val SERVICE = 1003
|
|
||||||
private const val HEADER = 0
|
private const val HEADER = 0
|
||||||
private const val FOOTER = 2
|
private const val FOOTER = 2
|
||||||
|
private const val INCOMING = 3
|
||||||
|
private const val OUTGOING = 4
|
||||||
|
|
||||||
|
private const val ATTACHMENT_PHOTOS_IN = 101
|
||||||
|
private const val ATTACHMENT_PHOTOS_OUT = 1011
|
||||||
|
|
||||||
private val COMPARATOR = object : DiffUtil.ItemCallback<VkMessage>() {
|
private val COMPARATOR = object : DiffUtil.ItemCallback<VkMessage>() {
|
||||||
override fun areItemsTheSame(
|
override fun areItemsTheSame(
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import androidx.lifecycle.MutableLiveData
|
|||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import coil.load
|
import coil.load
|
||||||
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import com.meloda.fast.R
|
import com.meloda.fast.R
|
||||||
import com.meloda.fast.api.UserConfig
|
import com.meloda.fast.api.UserConfig
|
||||||
import com.meloda.fast.api.model.VkConversation
|
import com.meloda.fast.api.model.VkConversation
|
||||||
@@ -57,7 +58,10 @@ class MessagesHistoryFragment :
|
|||||||
}
|
}
|
||||||
|
|
||||||
private val adapter: MessagesHistoryAdapter by lazy {
|
private val adapter: MessagesHistoryAdapter by lazy {
|
||||||
MessagesHistoryAdapter(requireContext(), mutableListOf(), conversation)
|
MessagesHistoryAdapter(requireContext(), mutableListOf(), conversation).also {
|
||||||
|
it.itemClickListener = this::onItemClick
|
||||||
|
it.itemLongClickListener = this::onItemLongClick
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private var timestampTimer: Timer? = null
|
private var timestampTimer: Timer? = null
|
||||||
@@ -183,6 +187,7 @@ class MessagesHistoryFragment :
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun performAction() {
|
private fun performAction() {
|
||||||
if (action.value == Action.RECORD) {
|
if (action.value == Action.RECORD) {
|
||||||
|
|
||||||
@@ -203,7 +208,7 @@ class MessagesHistoryFragment :
|
|||||||
)
|
)
|
||||||
|
|
||||||
adapter.add(message)
|
adapter.add(message)
|
||||||
adapter.notifyItemRangeInserted(adapter.lastPosition - 1, 1)
|
adapter.notifyDataSetChanged()
|
||||||
binding.recyclerView.smoothScrollToPosition(adapter.lastPosition)
|
binding.recyclerView.smoothScrollToPosition(adapter.lastPosition)
|
||||||
binding.message.clear()
|
binding.message.clear()
|
||||||
|
|
||||||
@@ -217,6 +222,7 @@ class MessagesHistoryFragment :
|
|||||||
|
|
||||||
override fun onEvent(event: VKEvent) {
|
override fun onEvent(event: VKEvent) {
|
||||||
when (event) {
|
when (event) {
|
||||||
|
is MessagesMarkAsImportant -> markMessagesAsImportant(event)
|
||||||
is MessagesLoaded -> refreshMessages(event)
|
is MessagesLoaded -> refreshMessages(event)
|
||||||
is StartProgressEvent -> onProgressStarted()
|
is StartProgressEvent -> onProgressStarted()
|
||||||
is StopProgressEvent -> onProgressStopped()
|
is StopProgressEvent -> onProgressStopped()
|
||||||
@@ -264,6 +270,19 @@ class MessagesHistoryFragment :
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun markMessagesAsImportant(event: MessagesMarkAsImportant) {
|
||||||
|
var changed = false
|
||||||
|
for (i in adapter.values.indices) {
|
||||||
|
val message = adapter.values[i]
|
||||||
|
if (event.messagesIds.contains(message.id)) {
|
||||||
|
if (!changed) changed = true
|
||||||
|
adapter.values[i] = message.copy(important = event.important)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changed) adapter.notifyDataSetChanged()
|
||||||
|
}
|
||||||
|
|
||||||
private fun refreshMessages(event: MessagesLoaded) {
|
private fun refreshMessages(event: MessagesLoaded) {
|
||||||
adapter.profiles += event.profiles
|
adapter.profiles += event.profiles
|
||||||
adapter.groups += event.groups
|
adapter.groups += event.groups
|
||||||
@@ -282,4 +301,30 @@ class MessagesHistoryFragment :
|
|||||||
else binding.recyclerView.scrollToPosition(adapter.lastPosition)
|
else binding.recyclerView.scrollToPosition(adapter.lastPosition)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun onItemClick(position: Int) {
|
||||||
|
val message = adapter.values[position]
|
||||||
|
|
||||||
|
val important = if (message.important) "Unmark as important" else "Mark as important"
|
||||||
|
|
||||||
|
val params = arrayOf(important)
|
||||||
|
|
||||||
|
val dialog = MaterialAlertDialogBuilder(requireContext())
|
||||||
|
.setItems(params) { _, which ->
|
||||||
|
if (which == 0) {
|
||||||
|
viewModel.markAsImportant(
|
||||||
|
messagesIds = listOf(message.id),
|
||||||
|
important = !message.important
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dialog.show()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun onItemLongClick(position: Int): Boolean {
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,13 +1,14 @@
|
|||||||
package com.meloda.fast.screens.messages
|
package com.meloda.fast.screens.messages
|
||||||
|
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import com.meloda.fast.api.datasource.MessagesDataSource
|
|
||||||
import com.meloda.fast.api.model.VkConversation
|
import com.meloda.fast.api.model.VkConversation
|
||||||
import com.meloda.fast.api.model.VkGroup
|
import com.meloda.fast.api.model.VkGroup
|
||||||
import com.meloda.fast.api.model.VkMessage
|
import com.meloda.fast.api.model.VkMessage
|
||||||
import com.meloda.fast.api.model.VkUser
|
import com.meloda.fast.api.model.VkUser
|
||||||
import com.meloda.fast.api.network.request.MessagesGetHistoryRequest
|
import com.meloda.fast.api.model.request.MessagesGetHistoryRequest
|
||||||
import com.meloda.fast.api.network.request.MessagesSendRequest
|
import com.meloda.fast.api.model.request.MessagesMarkAsImportantRequest
|
||||||
|
import com.meloda.fast.api.model.request.MessagesSendRequest
|
||||||
|
import com.meloda.fast.api.network.datasource.MessagesDataSource
|
||||||
import com.meloda.fast.base.viewmodel.BaseViewModel
|
import com.meloda.fast.base.viewmodel.BaseViewModel
|
||||||
import com.meloda.fast.base.viewmodel.StartProgressEvent
|
import com.meloda.fast.base.viewmodel.StartProgressEvent
|
||||||
import com.meloda.fast.base.viewmodel.StopProgressEvent
|
import com.meloda.fast.base.viewmodel.StopProgressEvent
|
||||||
@@ -109,6 +110,33 @@ class MessagesHistoryViewModel @Inject constructor(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun markAsImportant(
|
||||||
|
messagesIds: List<Int>,
|
||||||
|
important: Boolean
|
||||||
|
) = viewModelScope.launch {
|
||||||
|
makeJob({
|
||||||
|
dataSource.markAsImportant(
|
||||||
|
MessagesMarkAsImportantRequest(
|
||||||
|
messagesIds = messagesIds,
|
||||||
|
important = important
|
||||||
|
)
|
||||||
|
)
|
||||||
|
},
|
||||||
|
onAnswer = {
|
||||||
|
val response = it.response ?: return@makeJob
|
||||||
|
sendEvent(
|
||||||
|
MessagesMarkAsImportant(
|
||||||
|
messagesIds = response,
|
||||||
|
important = important
|
||||||
|
)
|
||||||
|
)
|
||||||
|
},
|
||||||
|
onError = {
|
||||||
|
val throwable = it
|
||||||
|
val i = 0
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
data class MessagesLoaded(
|
data class MessagesLoaded(
|
||||||
@@ -117,4 +145,9 @@ data class MessagesLoaded(
|
|||||||
val messages: List<VkMessage>,
|
val messages: List<VkMessage>,
|
||||||
val profiles: HashMap<Int, VkUser>,
|
val profiles: HashMap<Int, VkUser>,
|
||||||
val groups: HashMap<Int, VkGroup>
|
val groups: HashMap<Int, VkGroup>
|
||||||
|
) : VKEvent()
|
||||||
|
|
||||||
|
data class MessagesMarkAsImportant(
|
||||||
|
val messagesIds: List<Int>,
|
||||||
|
val important: Boolean
|
||||||
) : VKEvent()
|
) : VKEvent()
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools">
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:padding="12dp">
|
||||||
|
|
||||||
|
<com.google.android.material.imageview.ShapeableImageView
|
||||||
|
android:id="@+id/photo"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:scaleType="centerCrop"
|
||||||
|
tools:src="@tools:sample/backgrounds/scenic" />
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
</layout>
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools">
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.LinearLayoutCompat
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="end"
|
||||||
|
android:padding="12dp">
|
||||||
|
|
||||||
|
<com.google.android.material.imageview.ShapeableImageView
|
||||||
|
android:id="@+id/photo"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:scaleType="centerCrop"
|
||||||
|
tools:src="@tools:sample/backgrounds/scenic" />
|
||||||
|
|
||||||
|
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||||
|
|
||||||
|
</layout>
|
||||||
@@ -3,15 +3,19 @@
|
|||||||
xmlns:tools="http://schemas.android.com/tools">
|
xmlns:tools="http://schemas.android.com/tools">
|
||||||
|
|
||||||
<androidx.appcompat.widget.LinearLayoutCompat
|
<androidx.appcompat.widget.LinearLayoutCompat
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical">
|
android:gravity="center"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:paddingHorizontal="12dp"
|
||||||
|
android:paddingVertical="2.5dp">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/message"
|
android:id="@+id/message"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="Service" />
|
android:textColor="?textColorService"
|
||||||
|
tools:text="Service" />
|
||||||
|
|
||||||
</androidx.appcompat.widget.LinearLayoutCompat>
|
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:id="@+id/nav_graph"
|
||||||
|
app:startDestination="@id/conversationsFragment">
|
||||||
|
|
||||||
|
<include app:graph="@navigation/messages" />
|
||||||
|
|
||||||
|
</navigation>
|
||||||
@@ -10,6 +10,10 @@
|
|||||||
@android:color/transparent
|
@android:color/transparent
|
||||||
</item>
|
</item>
|
||||||
|
|
||||||
|
<item name="android:windowLightStatusBar">true</item>
|
||||||
|
|
||||||
|
<item name="preferenceTheme">@style/PreferenceThemeOverlay</item>
|
||||||
|
|
||||||
<item name="colorPrimary">@color/colorPrimary</item>
|
<item name="colorPrimary">@color/colorPrimary</item>
|
||||||
<item name="colorPrimaryVariant">@color/colorPrimaryVariant</item>
|
<item name="colorPrimaryVariant">@color/colorPrimaryVariant</item>
|
||||||
<item name="colorOnPrimary">@color/colorOnPrimary</item>
|
<item name="colorOnPrimary">@color/colorOnPrimary</item>
|
||||||
@@ -18,9 +22,18 @@
|
|||||||
<item name="colorSecondaryVariant">@color/colorSecondaryVariant</item>
|
<item name="colorSecondaryVariant">@color/colorSecondaryVariant</item>
|
||||||
<item name="colorOnSecondary">@color/colorOnSecondary</item>
|
<item name="colorOnSecondary">@color/colorOnSecondary</item>
|
||||||
|
|
||||||
<item name="android:windowLightStatusBar">true</item>
|
<item name="colorSecondary2">@color/colorSecondary2</item>
|
||||||
|
<item name="colorSecondary2Variant">@color/colorSecondary2Variant</item>
|
||||||
|
<item name="colorOnSecondary2">@color/colorOnSecondary2</item>
|
||||||
|
|
||||||
<item name="preferenceTheme">@style/PreferenceThemeOverlay</item>
|
<item name="colorSecondary3">@color/colorSecondary3</item>
|
||||||
|
<item name="colorSecondary3Variant">@color/colorSecondary3Variant</item>
|
||||||
|
<item name="colorOnSecondary3">@color/colorOnSecondary3</item>
|
||||||
|
|
||||||
|
<item name="textColorPrimary">@color/textColorPrimary</item>
|
||||||
|
<item name="textColorSecondary">@color/textColorSecondary</item>
|
||||||
|
<item name="textColorSecondaryVariant">@color/textColorSecondaryVariant</item>
|
||||||
|
<item name="textColorService">@color/textColorService</item>
|
||||||
|
|
||||||
<item name="dialogCornerRadius">12dp</item>
|
<item name="dialogCornerRadius">12dp</item>
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -25,5 +25,6 @@
|
|||||||
<color name="n2_10">@android:color/system_neutral2_10</color>
|
<color name="n2_10">@android:color/system_neutral2_10</color>
|
||||||
<color name="n2_100">@android:color/system_neutral2_100</color>
|
<color name="n2_100">@android:color/system_neutral2_100</color>
|
||||||
<color name="n2_500">@android:color/system_neutral2_500</color>
|
<color name="n2_500">@android:color/system_neutral2_500</color>
|
||||||
|
<color name="n2_600">@android:color/system_neutral2_600</color>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
@@ -1,9 +1,10 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
|
|
||||||
<attr name="textColorPrimary" format="color"/>
|
<attr name="textColorPrimary" format="color" />
|
||||||
<attr name="textColorSecondary" format="color"/>
|
<attr name="textColorSecondary" format="color" />
|
||||||
<attr name="textColorSecondaryVariant" format="color"/>
|
<attr name="textColorSecondaryVariant" format="color" />
|
||||||
|
<attr name="textColorService" format="color" />
|
||||||
|
|
||||||
<attr name="colorSecondary2" format="color" />
|
<attr name="colorSecondary2" format="color" />
|
||||||
<attr name="colorSecondary2Variant" format="color" />
|
<attr name="colorSecondary2Variant" format="color" />
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
<color name="textColorPrimary">@color/n1_900</color>
|
<color name="textColorPrimary">@color/n1_900</color>
|
||||||
<color name="textColorSecondary">@color/n1_900</color>
|
<color name="textColorSecondary">@color/n1_900</color>
|
||||||
<color name="textColorSecondaryVariant">@color/n2_500</color>
|
<color name="textColorSecondaryVariant">@color/n2_500</color>
|
||||||
|
<color name="textColorService">@color/n2_600</color>
|
||||||
|
|
||||||
<color name="colorSurface">@color/a1_0</color>
|
<color name="colorSurface">@color/a1_0</color>
|
||||||
|
|
||||||
@@ -50,5 +51,6 @@
|
|||||||
<color name="n2_10">#FDFBFE</color>
|
<color name="n2_10">#FDFBFE</color>
|
||||||
<color name="n2_100">#E0E2EB</color>
|
<color name="n2_100">#E0E2EB</color>
|
||||||
<color name="n2_500">#74767D</color>
|
<color name="n2_500">#74767D</color>
|
||||||
|
<color name="n2_600">#5C5E65</color>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
<item name="textColorPrimary">@color/textColorPrimary</item>
|
<item name="textColorPrimary">@color/textColorPrimary</item>
|
||||||
<item name="textColorSecondary">@color/textColorSecondary</item>
|
<item name="textColorSecondary">@color/textColorSecondary</item>
|
||||||
<item name="textColorSecondaryVariant">@color/textColorSecondaryVariant</item>
|
<item name="textColorSecondaryVariant">@color/textColorSecondaryVariant</item>
|
||||||
|
<item name="textColorService">@color/textColorService</item>
|
||||||
|
|
||||||
<item name="colorSurface">@color/colorSurface</item>
|
<item name="colorSurface">@color/colorSurface</item>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user