diff --git a/core/common/src/main/kotlin/dev/meloda/fast/common/util/Utils.kt b/core/common/src/main/kotlin/dev/meloda/fast/common/util/Utils.kt
new file mode 100644
index 00000000..93d7caac
--- /dev/null
+++ b/core/common/src/main/kotlin/dev/meloda/fast/common/util/Utils.kt
@@ -0,0 +1,7 @@
+package dev.meloda.fast.common.util
+
+import java.net.URLEncoder
+
+fun String.urlEncode(encoding: String = "utf-8"): String {
+ return URLEncoder.encode(this, encoding)
+}
diff --git a/core/ui/src/main/res/drawable/round_reply_24px.xml b/core/ui/src/main/res/drawable/round_reply_24px.xml
new file mode 100644
index 00000000..380df664
--- /dev/null
+++ b/core/ui/src/main/res/drawable/round_reply_24px.xml
@@ -0,0 +1,11 @@
+
+
+
+
diff --git a/feature/messageshistory/src/main/kotlin/dev/meloda/fast/messageshistory/MessagesHistoryViewModel.kt b/feature/messageshistory/src/main/kotlin/dev/meloda/fast/messageshistory/MessagesHistoryViewModel.kt
new file mode 100644
index 00000000..4f08f01f
--- /dev/null
+++ b/feature/messageshistory/src/main/kotlin/dev/meloda/fast/messageshistory/MessagesHistoryViewModel.kt
@@ -0,0 +1,66 @@
+package dev.meloda.fast.messageshistory
+
+import android.os.Bundle
+import androidx.compose.ui.text.input.TextFieldValue
+import dev.meloda.fast.messageshistory.model.MessageDialog
+import dev.meloda.fast.messageshistory.model.MessageNavigation
+import dev.meloda.fast.messageshistory.model.MessagesHistoryScreenState
+import dev.meloda.fast.messageshistory.model.UiItem
+import dev.meloda.fast.model.BaseError
+import dev.meloda.fast.model.api.domain.VkMessage
+import kotlinx.coroutines.flow.StateFlow
+
+interface MessagesHistoryViewModel {
+
+ val screenState: StateFlow
+ val navigation: StateFlow
+ val messages: StateFlow>
+ val uiMessages: StateFlow>
+ val dialog: StateFlow
+ val selectedMessages: StateFlow>
+
+ val inputFieldFocusRequester: StateFlow
+
+ val isNeedToScrollToIndex: StateFlow
+
+ val baseError: StateFlow
+ val imagesToPreload: StateFlow>
+
+ val currentOffset: StateFlow
+ val canPaginate: StateFlow
+
+ fun onNavigationConsumed()
+
+ fun onTopBarClicked()
+
+ fun onDialogConfirmed(dialog: MessageDialog, bundle: Bundle)
+ fun onDialogDismissed(dialog: MessageDialog)
+ fun onDialogItemPicked(dialog: MessageDialog, bundle: Bundle)
+
+ fun onScrolledToIndex()
+
+ fun onCloseButtonClicked()
+ fun onRefresh()
+ fun onAttachmentButtonClicked()
+ fun onMessageInputChanged(newText: TextFieldValue)
+ fun onEmojiButtonLongClicked()
+ fun onActionButtonClicked()
+
+ fun onPaginationConditionsMet()
+
+ fun onMessageClicked(messageId: Long)
+ fun onMessageLongClicked(messageId: Long)
+
+ fun onPinnedMessageClicked(messageId: Long)
+ fun onUnpinMessageClicked()
+
+ fun onDeleteSelectedMessagesClicked()
+
+ fun onBoldClicked()
+ fun onItalicClicked()
+ fun onUnderlineClicked()
+ fun onLinkClicked()
+ fun onRegularClicked()
+
+ fun onReplyCloseClicked()
+}
diff --git a/feature/messageshistory/src/main/kotlin/dev/meloda/fast/messageshistory/presentation/ReplyContainer.kt b/feature/messageshistory/src/main/kotlin/dev/meloda/fast/messageshistory/presentation/ReplyContainer.kt
new file mode 100644
index 00000000..159a9a14
--- /dev/null
+++ b/feature/messageshistory/src/main/kotlin/dev/meloda/fast/messageshistory/presentation/ReplyContainer.kt
@@ -0,0 +1,132 @@
+package dev.meloda.fast.messageshistory.presentation
+
+import androidx.compose.animation.AnimatedVisibility
+import androidx.compose.foundation.background
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.heightIn
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.shape.CircleShape
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material3.Icon
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Text
+import androidx.compose.material3.ripple
+import androidx.compose.material3.surfaceColorAtElevation
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.clip
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.Shape
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import dev.meloda.fast.ui.R
+
+@Composable
+fun ReplyContainer(
+ onCloseClicked: () -> Unit = {},
+ title: String,
+ text: String?,
+ modifier: Modifier = Modifier,
+ backgroundColor: Color = MaterialTheme.colorScheme.surfaceColorAtElevation(5.dp)
+) {
+ Row(
+ modifier = modifier
+ .padding(horizontal = 8.dp)
+ .fillMaxWidth()
+ .heightIn(min = 48.dp)
+ .clip(
+ RoundedCornerShape(
+ topStart = 24.dp,
+ topEnd = 24.dp,
+ bottomStart = 0.dp,
+ bottomEnd = 0.dp
+ )
+ )
+ .background(backgroundColor)
+ .padding(horizontal = 8.dp),
+ horizontalArrangement = Arrangement.spacedBy(8.dp),
+ verticalAlignment = Alignment.CenterVertically
+ ) {
+ Icon(
+ painter = painterResource(R.drawable.round_reply_24px),
+ contentDescription = null,
+ tint = MaterialTheme.colorScheme.primary
+ )
+
+ Column(
+ modifier = Modifier.weight(1f),
+ verticalArrangement = Arrangement.spacedBy(0.dp)
+ ) {
+ Text(
+ text = title,
+ style = MaterialTheme.typography.labelLarge,
+ color = MaterialTheme.colorScheme.primary
+ )
+
+ AnimatedVisibility(text != null) {
+ Text(
+ text = text.orEmpty(),
+ style = MaterialTheme.typography.bodySmall,
+ )
+ }
+ }
+
+ RippledClickContainer(
+ modifier = Modifier.size(36.dp),
+ shape = CircleShape,
+ onClick = onCloseClicked
+ ) {
+ Icon(
+ painter = painterResource(R.drawable.round_close_24px),
+ contentDescription = null,
+ )
+ }
+ }
+}
+
+@Composable
+fun RippledClickContainer(
+ modifier: Modifier = Modifier,
+ shape: Shape = RoundedCornerShape(4.dp),
+ onClick: () -> Unit,
+ content: @Composable () -> Unit
+) {
+ Box(
+ modifier = modifier
+ .clip(shape)
+ .clickable(
+ interactionSource = null,
+ indication = ripple(),
+ onClick = onClick
+ ),
+ contentAlignment = Alignment.Center
+ ) {
+ content()
+ }
+}
+
+@Preview
+@Composable
+private fun ReplyContainerPreview() {
+ Box(
+ modifier = Modifier
+ .fillMaxSize()
+ .background(Color.White),
+ contentAlignment = Alignment.Center
+ ) {
+ ReplyContainer(
+ onCloseClicked = {},
+ title = "В ответ Ишак",
+ text = "Приветствую тебя, Ишак!",
+ )
+ }
+}