Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import org.monogram.domain.models.MessageModel
import org.monogram.domain.models.MessageSendOptions
import org.monogram.domain.models.MessageUploadProgressEvent
import org.monogram.domain.models.MessageViewerModel
import org.monogram.domain.models.PollDraft
import org.monogram.domain.models.UserModel
import org.monogram.domain.models.webapp.ThemeParams
import org.monogram.domain.models.webapp.WebAppInfoModel
Expand Down Expand Up @@ -82,6 +83,13 @@ interface MessageRemoteDataSource {
threadId: Long?,
sendOptions: MessageSendOptions
): TdApi.Message?
suspend fun sendPoll(
chatId: Long,
poll: PollDraft,
replyToMsgId: Long?,
threadId: Long?,
sendOptions: MessageSendOptions
): TdApi.Message?

suspend fun sendSticker(chatId: Long, stickerPath: String, replyToMsgId: Long?, threadId: Long?): TdApi.Message?
suspend fun sendGif(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import org.monogram.domain.models.MessageModel
import org.monogram.domain.models.MessageSendOptions
import org.monogram.domain.models.MessageUploadProgressEvent
import org.monogram.domain.models.MessageViewerModel
import org.monogram.domain.models.PollDraft
import org.monogram.domain.models.UserModel
import org.monogram.domain.models.webapp.ThemeParams
import org.monogram.domain.models.webapp.WebAppInfoModel
Expand Down Expand Up @@ -616,6 +617,63 @@ class TdMessageRemoteDataSource(
return response
}

override suspend fun sendPoll(
chatId: Long,
poll: PollDraft,
replyToMsgId: Long?,
threadId: Long?,
sendOptions: MessageSendOptions
): TdApi.Message? {
val formattedQuestion = TdApi.FormattedText(poll.question, emptyArray())
val pollOptions = poll.options.map { option ->
TdApi.InputPollOption(TdApi.FormattedText(option, emptyArray()))
}.toTypedArray()
val type = if (poll.isQuiz) {
val correctOptionIds = poll.correctOptionIds
.map { it.coerceAtLeast(0) }
.distinct()
.toIntArray()
TdApi.InputPollTypeQuiz(
if (correctOptionIds.isNotEmpty()) correctOptionIds else intArrayOf(0),
TdApi.FormattedText(poll.explanation.orEmpty(), emptyArray())
)
} else {
TdApi.InputPollTypeRegular()
}
val content = TdApi.InputMessagePoll().apply {
this.question = formattedQuestion
this.options = pollOptions
this.description = poll.description
?.takeIf { it.isNotBlank() }
?.let { TdApi.FormattedText(it, emptyArray()) }
this.isAnonymous = poll.isAnonymous
this.allowsMultipleAnswers = poll.allowsMultipleAnswers
this.allowsRevoting = poll.allowsRevoting
this.shuffleOptions = poll.shuffleOptions
this.hideResultsUntilCloses = poll.hideResultsUntilCloses
this.type = type
this.openPeriod = poll.openPeriod.coerceAtLeast(0)
this.closeDate = poll.closeDate.coerceAtLeast(0)
this.isClosed = poll.isClosed
}
val replyTo =
if (replyToMsgId != null && replyToMsgId != 0L) TdApi.InputMessageReplyToMessage(
replyToMsgId,
null,
0,
""
) else null
val topicId = resolveTopicId(chatId, threadId)
val req = TdApi.SendMessage().apply {
this.chatId = chatId
this.topicId = topicId
this.replyTo = replyTo
this.inputMessageContent = content
this.options = sendOptions.toTdMessageSendOptions()
}
return safeExecute(req)
}

override suspend fun sendSticker(chatId: Long, stickerPath: String, replyToMsgId: Long?, threadId: Long?): TdApi.Message? {
val content = TdApi.InputMessageSticker().apply {
this.sticker = TdApi.InputFileLocal(stickerPath)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@ import org.monogram.data.mapper.CustomEmojiLoader
import org.monogram.data.mapper.TdFileHelper
import org.monogram.data.mapper.WebPageMapper
import org.monogram.data.mapper.toMessageEntityOrNull
import org.monogram.domain.models.*
import org.monogram.domain.models.MessageContent
import org.monogram.domain.models.MessageEntity
import org.monogram.domain.models.PollOption
import org.monogram.domain.models.PollType
import org.monogram.domain.models.StickerFormat
import org.monogram.domain.repository.AppPreferencesProvider

internal data class ContentMappingContext(
Expand Down Expand Up @@ -494,7 +498,7 @@ internal class MessageContentMapper(
val pollType = when (val type = poll.type) {
is TdApi.PollTypeRegular -> PollType.Regular(poll.allowsMultipleAnswers)
is TdApi.PollTypeQuiz -> {
PollType.Quiz(type.correctOptionIds.firstOrNull() ?: -1, type.explanation?.text)
PollType.Quiz(type.correctOptionIds.toList(), type.explanation?.text)
}

else -> PollType.Regular(poll.allowsMultipleAnswers)
Expand All @@ -503,6 +507,7 @@ internal class MessageContentMapper(
MessageContent.Poll(
id = poll.id,
question = poll.question.text,
description = null,
options = poll.options.map { option ->
PollOption(
text = option.text.text,
Expand All @@ -515,6 +520,9 @@ internal class MessageContentMapper(
totalVoterCount = poll.totalVoterCount,
isClosed = poll.isClosed,
isAnonymous = poll.isAnonymous,
allowsRevoting = true,
shuffleOptions = false,
hideResultsUntilCloses = false,
type = pollType,
openPeriod = poll.openPeriod,
closeDate = poll.closeDate
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,14 @@ import org.monogram.domain.models.ChatEventModel
import org.monogram.domain.models.ChatPermissionsModel
import org.monogram.domain.models.FileModel
import org.monogram.domain.models.InlineQueryResultModel
import org.monogram.domain.models.MessageDownloadEvent
import org.monogram.domain.models.MessageEntity
import org.monogram.domain.models.MessageEntityType
import org.monogram.domain.models.MessageDownloadEvent
import org.monogram.domain.models.MessageModel
import org.monogram.domain.models.MessageSendOptions
import org.monogram.domain.models.MessageSenderModel
import org.monogram.domain.models.MessageViewerModel
import org.monogram.domain.models.PollDraft
import org.monogram.domain.models.UserModel
import org.monogram.domain.models.webapp.InstantViewModel
import org.monogram.domain.models.webapp.InvoiceModel
Expand Down Expand Up @@ -340,6 +341,22 @@ class MessageRepositoryImpl(
)
}

override suspend fun sendPoll(
chatId: Long,
poll: PollDraft,
replyToMsgId: Long?,
threadId: Long?,
sendOptions: MessageSendOptions
) {
messageRemoteDataSource.sendPoll(
chatId = chatId,
poll = poll,
replyToMsgId = replyToMsgId,
threadId = threadId,
sendOptions = sendOptions
)
}

override suspend fun sendGif(
chatId: Long,
gifId: String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -367,10 +367,14 @@ sealed interface MessageContent {
data class Poll(
val id: Long,
val question: String,
val description: String? = null,
val options: List<PollOption>,
val totalVoterCount: Int,
val isClosed: Boolean,
val isAnonymous: Boolean,
val allowsRevoting: Boolean = true,
val shuffleOptions: Boolean = false,
val hideResultsUntilCloses: Boolean = false,
val type: PollType,
val openPeriod: Int,
val closeDate: Int
Expand Down Expand Up @@ -544,7 +548,7 @@ data class PollOption(

sealed interface PollType {
data class Regular(val allowMultipleAnswers: Boolean) : PollType
data class Quiz(val correctOptionId: Int, val explanation: String?) : PollType
data class Quiz(val correctOptionIds: List<Int>, val explanation: String?) : PollType
}

@Serializable
Expand Down
18 changes: 18 additions & 0 deletions domain/src/main/java/org/monogram/domain/models/PollDraft.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package org.monogram.domain.models

data class PollDraft(
val question: String,
val options: List<String>,
val description: String? = null,
val isAnonymous: Boolean = true,
val allowsMultipleAnswers: Boolean = false,
val allowsRevoting: Boolean = true,
val shuffleOptions: Boolean = false,
val hideResultsUntilCloses: Boolean = false,
val openPeriod: Int = 0,
val closeDate: Int = 0,
val isClosed: Boolean = false,
val isQuiz: Boolean = false,
val correctOptionIds: List<Int> = emptyList(),
val explanation: String? = null
)
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import org.monogram.domain.models.MessageModel
import org.monogram.domain.models.MessageSendOptions
import org.monogram.domain.models.MessageUploadProgressEvent
import org.monogram.domain.models.MessageViewerModel
import org.monogram.domain.models.PollDraft
import org.monogram.domain.models.UserModel
import org.monogram.domain.models.webapp.InstantViewModel

Expand Down Expand Up @@ -128,6 +129,14 @@ interface MessageRepository :
sendOptions: MessageSendOptions = MessageSendOptions()
)

suspend fun sendPoll(
chatId: Long,
poll: PollDraft,
replyToMsgId: Long? = null,
threadId: Long? = null,
sendOptions: MessageSendOptions = MessageSendOptions()
)

suspend fun sendGif(
chatId: Long,
gifId: String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalHapticFeedback
import androidx.compose.ui.res.pluralStringResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.semantics
Expand Down Expand Up @@ -518,8 +519,9 @@ fun ChatListContent(component: ChatListComponent) {
)
if (selectionState.selectedChatIds.isNotEmpty()) {
Text(
text = stringResource(
R.string.chats_selected_format,
text = pluralStringResource(
R.plurals.chats_selected_format,
selectionState.selectedChatIds.size,
selectionState.selectedChatIds.size
),
style = MaterialTheme.typography.bodySmall,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,30 @@
package org.monogram.presentation.features.chats.chatList.components

import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.Check
import androidx.compose.material3.*
import androidx.compose.material3.BottomSheetDefaults
import androidx.compose.material3.Button
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.ModalBottomSheet
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.material3.TextFieldDefaults
import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
Expand All @@ -17,6 +33,7 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import org.monogram.presentation.R
Expand Down Expand Up @@ -47,6 +64,7 @@ fun SettingsTextField(
singleLine: Boolean = false,
minLines: Int = 1,
maxLines: Int = Int.MAX_VALUE,
itemSpacing: Dp = 2.dp,
keyboardOptions: KeyboardOptions = KeyboardOptions.Default,
keyboardActions: KeyboardActions = KeyboardActions.Default,
trailingIcon: @Composable (() -> Unit)? = null
Expand Down Expand Up @@ -109,8 +127,8 @@ fun SettingsTextField(
)
)
}
if (position != ItemPosition.BOTTOM && position != ItemPosition.STANDALONE) {
Spacer(Modifier.height(2.dp))
if (position != ItemPosition.BOTTOM && position != ItemPosition.STANDALONE && itemSpacing > 0.dp) {
Spacer(Modifier.height(itemSpacing))
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import org.monogram.domain.models.MessageEntity
import org.monogram.domain.models.MessageModel
import org.monogram.domain.models.MessageSendOptions
import org.monogram.domain.models.MessageViewerModel
import org.monogram.domain.models.PollDraft
import org.monogram.domain.models.StickerSetModel
import org.monogram.domain.models.TopicModel
import org.monogram.domain.models.UserModel
Expand Down Expand Up @@ -56,6 +57,18 @@ interface ChatComponent {
)

fun onSendGif(gif: GifModel)
fun onSendDocument(
documentPath: String,
caption: String = "",
captionEntities: List<MessageEntity> = emptyList(),
sendOptions: MessageSendOptions = MessageSendOptions()
)

fun onSendPoll(
poll: PollDraft,
sendOptions: MessageSendOptions = MessageSendOptions()
)

fun onSendGifFile(
path: String,
caption: String = "",
Expand Down
Loading