call in attachments

This commit is contained in:
2021-10-11 00:06:36 +03:00
parent 147e6c5a33
commit ef7d1a6031
17 changed files with 251 additions and 21 deletions
+3 -1
View File
@@ -82,6 +82,8 @@ dependencies {
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:1.1.5") coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:1.1.5")
implementation("com.github.massoudss:waveformSeekBar:3.1.0")
implementation("androidx.core:core-splashscreen:1.0.0-alpha02") implementation("androidx.core:core-splashscreen:1.0.0-alpha02")
implementation("androidx.work:work-runtime-ktx:2.6.0") implementation("androidx.work:work-runtime-ktx:2.6.0")
@@ -100,7 +102,7 @@ dependencies {
implementation("androidx.fragment:fragment-ktx:1.3.6") implementation("androidx.fragment:fragment-ktx:1.3.6")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2") implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.2-native-mt") implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.2")
implementation("androidx.room:room-ktx:2.3.0") implementation("androidx.room:room-ktx:2.3.0")
implementation("androidx.room:room-runtime:2.3.0") implementation("androidx.room:room-runtime:2.3.0")
+1
View File
@@ -9,6 +9,7 @@
<application <application
android:name=".common.AppGlobal" android:name=".common.AppGlobal"
android:allowBackup="false" android:allowBackup="false"
android:extractNativeLibs="false"
android:icon="@mipmap/ic_launcher" android:icon="@mipmap/ic_launcher"
android:label="@string/app_name" android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round" android:roundIcon="@mipmap/ic_launcher_round"
@@ -142,9 +142,7 @@ object VkUtils {
} }
BaseVkAttachmentItem.AttachmentType.VOICE -> { BaseVkAttachmentItem.AttachmentType.VOICE -> {
val voiceMessage = baseAttachment.voiceMessage ?: continue val voiceMessage = baseAttachment.voiceMessage ?: continue
attachments += VkVoiceMessage( attachments += voiceMessage.asVkVoiceMessage()
link = voiceMessage.link_mp3
)
} }
BaseVkAttachmentItem.AttachmentType.STICKER -> { BaseVkAttachmentItem.AttachmentType.STICKER -> {
val sticker = baseAttachment.sticker ?: continue val sticker = baseAttachment.sticker ?: continue
@@ -180,9 +178,7 @@ object VkUtils {
} }
BaseVkAttachmentItem.AttachmentType.CALL -> { BaseVkAttachmentItem.AttachmentType.CALL -> {
val call = baseAttachment.call ?: continue val call = baseAttachment.call ?: continue
attachments += VkCall( attachments += call.asVkCall()
initiatorId = call.initiator_id
)
} }
BaseVkAttachmentItem.AttachmentType.GROUP_CALL_IN_PROGRESS -> { BaseVkAttachmentItem.AttachmentType.GROUP_CALL_IN_PROGRESS -> {
val groupCall = baseAttachment.groupCall ?: continue val groupCall = baseAttachment.groupCall ?: continue
@@ -5,7 +5,12 @@ import kotlinx.parcelize.Parcelize
@Parcelize @Parcelize
data class VkCall( data class VkCall(
val initiatorId: Int val initiatorId: Int,
val receiverId: Int,
val state: String,
val time: Int,
val duration: Int,
val isVideo: Boolean
) : VkAttachment() { ) : VkAttachment() {
@IgnoredOnParcel @IgnoredOnParcel
@@ -5,9 +5,18 @@ import kotlinx.parcelize.Parcelize
@Parcelize @Parcelize
data class VkVoiceMessage( data class VkVoiceMessage(
val link: String val id: Int,
val ownerId: Int,
val duration: Int,
val waveform: List<Int>,
val linkOgg: String,
val linkMp3: String,
val accessKey: String,
val transcriptState: String,
val transcript: String
) : VkAttachment() { ) : VkAttachment() {
@IgnoredOnParcel @IgnoredOnParcel
val className: String = this::class.java.name val className: String = this::class.java.name
} }
@@ -1,6 +1,7 @@
package com.meloda.fast.api.model.base.attachments package com.meloda.fast.api.model.base.attachments
import android.os.Parcelable import android.os.Parcelable
import com.meloda.fast.api.model.attachments.VkCall
import kotlinx.parcelize.Parcelize import kotlinx.parcelize.Parcelize
@Parcelize @Parcelize
@@ -11,4 +12,15 @@ data class BaseVkCall(
val time: Int, val time: Int,
val duration: Int, val duration: Int,
val video: Boolean val video: Boolean
) : Parcelable ) : Parcelable {
fun asVkCall() = VkCall(
initiatorId = initiator_id,
receiverId = receiver_id,
state = state,
time = time,
duration = duration,
isVideo = video
)
}
@@ -1,6 +1,7 @@
package com.meloda.fast.api.model.base.attachments package com.meloda.fast.api.model.base.attachments
import android.os.Parcelable import android.os.Parcelable
import com.meloda.fast.api.model.attachments.VkVoiceMessage
import kotlinx.parcelize.Parcelize import kotlinx.parcelize.Parcelize
@Parcelize @Parcelize
@@ -14,4 +15,18 @@ data class BaseVkVoiceMessage(
val access_key: String, val access_key: String,
val transcript_state: String, val transcript_state: String,
val transcript: String val transcript: String
) : Parcelable ) : Parcelable {
fun asVkVoiceMessage() = VkVoiceMessage(
id = id,
ownerId = owner_id,
duration = duration,
waveform = waveform,
linkOgg = link_ogg,
linkMp3 = link_mp3,
accessKey = access_key,
transcriptState = transcript_state,
transcript = transcript
)
}
@@ -15,9 +15,11 @@ import androidx.core.content.ContextCompat
import androidx.core.view.isNotEmpty import androidx.core.view.isNotEmpty
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.core.view.setPadding import androidx.core.view.setPadding
import androidx.core.view.updatePadding
import coil.load import coil.load
import com.google.android.material.imageview.ShapeableImageView import com.google.android.material.imageview.ShapeableImageView
import com.meloda.fast.R import com.meloda.fast.R
import com.meloda.fast.api.UserConfig
import com.meloda.fast.api.VkUtils import com.meloda.fast.api.VkUtils
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
@@ -34,6 +36,7 @@ import kotlin.math.roundToInt
class AttachmentInflater constructor( class AttachmentInflater constructor(
private val context: Context, private val context: Context,
private val container: LinearLayoutCompat, private val container: LinearLayoutCompat,
private val textContainer: LinearLayoutCompat,
private val message: VkMessage, private val message: VkMessage,
private val profiles: Map<Int, VkUser>, private val profiles: Map<Int, VkUser>,
private val groups: Map<Int, VkGroup> private val groups: Map<Int, VkGroup>
@@ -57,6 +60,7 @@ class AttachmentInflater constructor(
attachments = message.attachments!! attachments = message.attachments!!
container.removeAllViews() container.removeAllViews()
textContainer.removeAllViews()
if (attachments.size == 1) { if (attachments.size == 1) {
when (val attachment = attachments[0]) { when (val attachment = attachments[0]) {
@@ -90,7 +94,8 @@ class AttachmentInflater constructor(
is VkAudio -> audio(attachment) is VkAudio -> audio(attachment)
is VkFile -> file(attachment) is VkFile -> file(attachment)
is VkLink -> link(attachment) is VkLink -> link(attachment)
is VkStory -> story(attachment) is VkVoiceMessage -> voice(attachment)
is VkCall -> call(attachment)
else -> Log.e( else -> Log.e(
"Attachment inflater", "Attachment inflater",
@@ -312,8 +317,57 @@ class AttachmentInflater constructor(
).format(wall.date * 1000L) ).format(wall.date * 1000L)
} }
private fun story(story: VkStory) { private fun voice(voiceMessage: VkVoiceMessage) {
val binding = ItemMessageAttachmentVoiceBinding.inflate(inflater, textContainer, true)
if (message.isOut)
binding.root.updatePadding(
bottom = AndroidUtils.px(5).roundToInt(),
left = AndroidUtils.px(6).roundToInt()
)
val waveform = IntArray(voiceMessage.waveform.size)
voiceMessage.waveform.forEachIndexed { index, i -> waveform[index] = i }
binding.waveform.sample = waveform
binding.waveform.maxProgress = 100f
binding.waveform.progress = 100f
binding.duration.text = SimpleDateFormat(
"mm:ss",
Locale.getDefault()
).format(voiceMessage.duration * 1000L)
}
private fun call(call: VkCall) {
val binding = ItemMessageAttachmentCallBinding.inflate(inflater, textContainer, true)
if (message.isOut)
binding.root.updatePadding(
bottom = AndroidUtils.px(5).roundToInt(),
left = AndroidUtils.px(6).roundToInt()
)
val callType =
context.getString(
if (call.initiatorId == UserConfig.userId) R.string.message_call_type_outgoing
else R.string.message_call_type_incoming
)
binding.type.text = callType
var callState =
context.getString(
if (call.state == "reached") R.string.message_call_state_ended
else if (call.state == "canceled_by_initiator") {
if (call.initiatorId == UserConfig.userId) R.string.message_call_state_cancelled
else R.string.message_call_state_missed
} else R.string.message_call_unknown
)
if (callState == context.getString(R.string.message_call_unknown)) callState = call.state
binding.state.text = callState
} }
} }
@@ -136,6 +136,8 @@ class MessagesHistoryAdapter constructor(
text = binding.text, text = binding.text,
spacer = binding.spacer, spacer = binding.spacer,
unread = binding.unread, unread = binding.unread,
textContainer = binding.textContainer,
attachmentContainer = binding.attachmentContainer, attachmentContainer = binding.attachmentContainer,
attachmentSpacer = binding.attachmentSpacer, attachmentSpacer = binding.attachmentSpacer,
@@ -172,6 +174,8 @@ class MessagesHistoryAdapter constructor(
text = binding.text, text = binding.text,
spacer = binding.spacer, spacer = binding.spacer,
unread = binding.unread, unread = binding.unread,
textContainer = binding.textContainer,
attachmentContainer = binding.attachmentContainer, attachmentContainer = binding.attachmentContainer,
attachmentSpacer = binding.attachmentSpacer, attachmentSpacer = binding.attachmentSpacer,
@@ -42,6 +42,7 @@ class MessagesPreparator constructor(
private val spacer: Space? = null, private val spacer: Space? = null,
private val unread: ImageView? = null, private val unread: ImageView? = null,
private val time: TextView? = null, private val time: TextView? = null,
private val textContainer: LinearLayoutCompat? = null,
private val attachmentContainer: LinearLayoutCompat? = null, private val attachmentContainer: LinearLayoutCompat? = null,
private val attachmentSpacer: Space? = null, private val attachmentSpacer: Space? = null,
@@ -158,7 +159,7 @@ class MessagesPreparator constructor(
} }
private fun prepareAttachments() { private fun prepareAttachments() {
if (attachmentContainer != null) { if (attachmentContainer != null && textContainer != null) {
if (message.attachments.isNullOrEmpty()) { if (message.attachments.isNullOrEmpty()) {
attachmentContainer.isVisible = false attachmentContainer.isVisible = false
attachmentContainer.removeAllViews() attachmentContainer.removeAllViews()
@@ -168,6 +169,7 @@ class MessagesPreparator constructor(
AttachmentInflater( AttachmentInflater(
context = context, context = context,
container = attachmentContainer, container = attachmentContainer,
textContainer = textContainer,
message = message, message = message,
groups = groups, groups = groups,
profiles = profiles profiles = profiles
@@ -0,0 +1,59 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="4dp">
<FrameLayout
android:layout_width="42dp"
android:layout_height="42dp"
android:layout_gravity="top"
android:layout_marginTop="2dp"
android:background="@drawable/ic_play_button_circle_background"
android:backgroundTint="@color/a3_200">
<androidx.appcompat.widget.AppCompatImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="@drawable/ic_attachment_call"
app:tint="@color/a3_700" />
</FrameLayout>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="8dp"
android:orientation="vertical">
<com.google.android.material.textview.MaterialTextView
android:id="@+id/type"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:fontFamily="@font/google_sans_regular"
android:maxLines="1"
android:textColor="@color/n1_800"
android:textSize="18sp"
tools:text="Исходящий звонок" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/state"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:alpha="0.8"
android:fontFamily="@font/roboto_regular"
android:textColor="@color/n1_800"
tools:text="Отменён" />
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.appcompat.widget.LinearLayoutCompat>
</layout>
@@ -0,0 +1,56 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="4dp">
<FrameLayout
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_gravity="top"
android:layout_marginTop="2dp"
android:background="@drawable/ic_play_button_circle_background"
android:backgroundTint="@color/a3_200">
<androidx.appcompat.widget.AppCompatImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="@drawable/ic_round_play_arrow_24"
app:tint="@color/a3_700" />
</FrameLayout>
<com.masoudss.lib.WaveformSeekBar
android:id="@+id/waveform"
android:layout_width="100dp"
android:layout_height="20dp"
android:layout_gravity="center_vertical"
android:layout_marginStart="16dp"
app:wave_background_color="@color/a2_300"
app:wave_corner_radius="40dp"
app:wave_gap="2dp"
app:wave_gravity="center"
app:wave_min_height="5dp"
app:wave_progress_color="@color/n2_500"
app:wave_width="3dp" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/duration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginHorizontal="8dp"
android:alpha="0.8"
android:fontFamily="@font/roboto_regular"
android:textColor="@color/n1_800"
tools:text="0:36" />
</androidx.appcompat.widget.LinearLayoutCompat>
</layout>
+1 -1
View File
@@ -56,6 +56,7 @@
tools:ignore="UselessParent"> tools:ignore="UselessParent">
<androidx.appcompat.widget.LinearLayoutCompat <androidx.appcompat.widget.LinearLayoutCompat
android:id="@+id/textContainer"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical"> android:orientation="vertical">
@@ -71,7 +72,6 @@
tools:text="This" /> tools:text="This" />
</androidx.appcompat.widget.LinearLayoutCompat> </androidx.appcompat.widget.LinearLayoutCompat>
</com.meloda.fast.widget.BoundedLinearLayout> </com.meloda.fast.widget.BoundedLinearLayout>
<com.meloda.fast.widget.CircleImageView <com.meloda.fast.widget.CircleImageView
+13 -6
View File
@@ -38,15 +38,22 @@
android:background="@drawable/ic_message_out_background" android:background="@drawable/ic_message_out_background"
android:orientation="vertical"> android:orientation="vertical">
<com.google.android.material.textview.MaterialTextView <androidx.appcompat.widget.LinearLayoutCompat
android:id="@+id/text" android:id="@+id/textContainer"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_vertical|start" android:orientation="vertical">
android:padding="15dp"
android:textColor="@color/n1_900"
tools:text="This is test" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|start"
android:padding="15dp"
android:textColor="@color/n1_900"
tools:text="This is test" />
</androidx.appcompat.widget.LinearLayoutCompat>
</com.meloda.fast.widget.BoundedLinearLayout> </com.meloda.fast.widget.BoundedLinearLayout>
<Space <Space
+1
View File
@@ -9,6 +9,7 @@
<color name="a2_100">@android:color/system_accent2_100</color> <color name="a2_100">@android:color/system_accent2_100</color>
<color name="a2_200">@android:color/system_accent2_200</color> <color name="a2_200">@android:color/system_accent2_200</color>
<color name="a2_300">@android:color/system_accent2_300</color>
<color name="a2_700">@android:color/system_accent2_700</color> <color name="a2_700">@android:color/system_accent2_700</color>
<color name="a1_1000">@android:color/system_accent2_1000</color> <color name="a1_1000">@android:color/system_accent2_1000</color>
+1
View File
@@ -39,6 +39,7 @@
<color name="a2_100">#DCE1F7</color> <color name="a2_100">#DCE1F7</color>
<color name="a2_200">#C0C6DA</color> <color name="a2_200">#C0C6DA</color>
<color name="a2_300">#A4ABBF</color>
<color name="a2_700">#414757</color> <color name="a2_700">#414757</color>
<color name="a3_100">#F8D6FC</color> <color name="a3_100">#F8D6FC</color>
+6
View File
@@ -140,4 +140,10 @@
<string name="confirm_pin_conversation">Pin the conversation?</string> <string name="confirm_pin_conversation">Pin the conversation?</string>
<string name="action_pin">Pin</string> <string name="action_pin">Pin</string>
<string name="action_unpin">Unpin</string> <string name="action_unpin">Unpin</string>
<string name="message_call_type_outgoing">Outgoing call</string>
<string name="message_call_type_incoming">Incoming call</string>
<string name="message_call_state_ended">Ended</string>
<string name="message_call_state_cancelled">Cancelled</string>
<string name="message_call_state_missed">Missed</string>
<string name="message_call_unknown">Unknown</string>
</resources> </resources>