Skip to content

Commit bca8900

Browse files
authored
Enhance chat features and core improvements (#345)
1 parent a475d7e commit bca8900

108 files changed

Lines changed: 5647 additions & 1287 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

data/src/firebase/java/org/monogram/data/service/FcmPushService.kt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,23 @@ package org.monogram.data.service
33
import com.google.firebase.messaging.FirebaseMessagingService
44
import com.google.firebase.messaging.RemoteMessage
55
import org.koin.android.ext.android.inject
6+
import org.monogram.data.di.TdNotificationManager
67
import org.monogram.data.gateway.TelegramGateway
8+
import org.monogram.data.push.PushSyncTrigger
79
import org.monogram.domain.repository.AppPreferencesProvider
810

911
class FcmPushService : FirebaseMessagingService() {
1012
private val gateway: TelegramGateway by inject()
1113
private val appPreferences: AppPreferencesProvider by inject()
14+
private val notificationManager: TdNotificationManager by inject()
15+
private val pushSyncTrigger: PushSyncTrigger by inject()
1216
private val delegate by lazy {
1317
BaseFcmPushService(
1418
context = this,
1519
gateway = gateway,
16-
appPreferences = appPreferences
20+
appPreferences = appPreferences,
21+
notificationManager = notificationManager,
22+
pushSyncTrigger = pushSyncTrigger
1723
)
1824
}
1925

data/src/main/java/org/monogram/data/chats/ChatCache.kt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -562,7 +562,14 @@ class ChatCache : ChatsCacheDataSource, UserCacheDataSource {
562562
TdApi.ChatPosition(TdApi.ChatListArchive(), order, pinned, null)
563563
}
564564

565-
"f" -> null
565+
"f" -> {
566+
if (parts.size < 4) return@mapNotNull null
567+
val folderId = parts[1].toIntOrNull() ?: return@mapNotNull null
568+
val order = parts[2].toLongOrNull() ?: return@mapNotNull null
569+
if (order == 0L) return@mapNotNull null
570+
val pinned = parts[3] == "1"
571+
TdApi.ChatPosition(TdApi.ChatListFolder(folderId), order, pinned, null)
572+
}
566573

567574
else -> null
568575
}

data/src/main/java/org/monogram/data/chats/ChatModelFactory.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ class ChatModelFactory(
8383
var personalAvatarPath: String? = null
8484
var signMessages = false
8585
var joinToSendMessages = false
86+
var joinByRequest = false
8687

8788
val isArchived = chat.positions.any { it.list is TdApi.ChatListArchive }
8889

@@ -143,6 +144,7 @@ class ChatModelFactory(
143144
hasAutomaticTranslation = it.hasAutomaticTranslation
144145
signMessages = it.signMessages
145146
joinToSendMessages = it.joinToSendMessages
147+
joinByRequest = it.joinByRequest
146148
}
147149
?: if (allowRemoteLookups && !cache.isSupergroupTemporarilyMissing(type.supergroupId)) lazyLoad(
148150
cache.pendingSupergroups,
@@ -383,7 +385,9 @@ class ChatModelFactory(
383385
hasAutomaticTranslation = hasAutomaticTranslation,
384386
personalAvatarPath = personalAvatarPath,
385387
signMessages = signMessages,
386-
joinToSendMessages = joinToSendMessages
388+
joinToSendMessages = joinToSendMessages,
389+
pendingJoinRequestCount = chat.pendingJoinRequests?.totalCount ?: 0,
390+
joinByRequest = joinByRequest
387391
)
388392
}
389393

data/src/main/java/org/monogram/data/chats/ChatPersistenceManager.kt

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ class ChatPersistenceManager(
2424
) {
2525
private val lastSavedEntities = ConcurrentHashMap<Long, ChatEntity>()
2626
private val pendingSaveJobs = ConcurrentHashMap<Long, Job>()
27-
private val mainChatList = TdApi.ChatListMain()
2827

2928
fun rememberSavedEntity(entity: ChatEntity) {
3029
lastSavedEntities[entity.id] = entity
@@ -38,7 +37,7 @@ class ChatPersistenceManager(
3837
try {
3938
delay(SINGLE_CHAT_SAVE_DEBOUNCE_MS)
4039
val activeChatList = activeChatListProvider()
41-
val position = resolvePersistPosition(chat, activeChatList)
40+
val position = resolvePersistPosition(chat, activeChatList, listManager)
4241
val model = modelFactory.mapChatToModel(
4342
chat = chat,
4443
order = position?.order ?: 0L,
@@ -149,7 +148,7 @@ class ChatPersistenceManager(
149148
return chatMapper.mapToEntity(model)
150149
}
151150

152-
val persistPosition = resolvePersistPosition(chat, activeChatList)
151+
val persistPosition = resolvePersistPosition(chat, activeChatList, listManager)
153152
val mapped = chatMapper.mapToEntity(chat, model)
154153
return if (persistPosition != null &&
155154
(persistPosition.order != mapped.order || persistPosition.isPinned != mapped.isPinned)
@@ -160,16 +159,6 @@ class ChatPersistenceManager(
160159
}
161160
}
162161

163-
private fun resolvePersistPosition(chat: TdApi.Chat, activeChatList: TdApi.ChatList): TdApi.ChatPosition? {
164-
return chat.positions.find { pos ->
165-
pos.order != 0L && listManager.isSameChatList(pos.list, mainChatList)
166-
}
167-
?: chat.positions.find { pos ->
168-
pos.order != 0L && listManager.isSameChatList(pos.list, activeChatList)
169-
}
170-
?: chat.positions.firstOrNull { it.order != 0L }
171-
}
172-
173162
private fun isEntityChanged(old: ChatEntity, new: ChatEntity): Boolean {
174163
return old.withoutCreatedAt() != new.withoutCreatedAt()
175164
}
@@ -181,4 +170,18 @@ class ChatPersistenceManager(
181170
private const val SINGLE_CHAT_SAVE_DEBOUNCE_MS = 2000L
182171
private const val SNAPSHOT_PERSIST_LIMIT = 1000
183172
}
184-
}
173+
}
174+
175+
internal fun resolvePersistPosition(
176+
chat: TdApi.Chat,
177+
activeChatList: TdApi.ChatList,
178+
listManager: ChatListManager
179+
): TdApi.ChatPosition? {
180+
return chat.positions.find { pos ->
181+
pos.order != 0L && listManager.isSameChatList(pos.list, activeChatList)
182+
}
183+
?: chat.positions.find { pos ->
184+
pos.order != 0L && listManager.isSameChatList(pos.list, TdApi.ChatListMain())
185+
}
186+
?: chat.positions.firstOrNull { it.order != 0L }
187+
}

data/src/main/java/org/monogram/data/chats/ChatUpdateHandler.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,9 @@ class ChatUpdateHandler(
164164
is TdApi.UpdateFile -> {
165165
if (fileManager.handleFileUpdate(update.file)) {
166166
val chatId = fileManager.getChatIdByPhotoId(update.file.id)
167+
if (chatId != null) {
168+
onSaveChat(chatId)
169+
}
167170
onScheduleUpdate(chatId)
168171
onRefreshForumTopics()
169172
}
@@ -192,6 +195,7 @@ class ChatUpdateHandler(
192195
cache.putUser(update.user)
193196
val privateChatId = cache.userIdToChatId[update.user.id]
194197
if (privateChatId != null) {
198+
onSaveChat(privateChatId)
195199
onTriggerUpdate(privateChatId)
196200
}
197201
onRefreshForumTopics()

data/src/main/java/org/monogram/data/datasource/remote/ChatRemoteSource.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,10 @@ interface ChatRemoteSource {
2020
suspend fun setChatPermissions(chatId: Long, permissions: ChatPermissionsModel)
2121
suspend fun setChatHasProtectedContent(chatId: Long, hasProtectedContent: Boolean)
2222
suspend fun setChatSignMessages(chatId: Long, signMessages: Boolean)
23+
suspend fun setChatHasHiddenMembers(chatId: Long, hasHiddenMembers: Boolean)
24+
suspend fun setChatHasAggressiveAntiSpamEnabled(chatId: Long, enabled: Boolean)
2325
suspend fun setChatJoinToSendMessages(chatId: Long, joinToSendMessages: Boolean)
26+
suspend fun setChatJoinByRequest(chatId: Long, joinByRequest: Boolean)
2427
suspend fun setChatAvailableReactions(chatId: Long, availableReactions: List<String>)
2528
suspend fun setChatSlowModeDelay(chatId: Long, slowModeDelay: Int)
2629
suspend fun toggleChatIsForum(chatId: Long, isForum: Boolean)

data/src/main/java/org/monogram/data/datasource/remote/MessageRemoteDataSource.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ interface MessageRemoteDataSource : DraftLinkPreviewRemoteDataSource {
9393
photoPath: String,
9494
caption: String,
9595
captionEntities: List<MessageEntity>,
96+
showCaptionAboveMedia: Boolean,
9697
replyToMsgId: Long?,
9798
threadId: Long?,
9899
sendOptions: MessageSendOptions
@@ -103,6 +104,7 @@ interface MessageRemoteDataSource : DraftLinkPreviewRemoteDataSource {
103104
videoPath: String,
104105
caption: String,
105106
captionEntities: List<MessageEntity>,
107+
showCaptionAboveMedia: Boolean,
106108
replyToMsgId: Long?,
107109
threadId: Long?,
108110
sendOptions: MessageSendOptions
@@ -147,6 +149,7 @@ interface MessageRemoteDataSource : DraftLinkPreviewRemoteDataSource {
147149
gifPath: String,
148150
caption: String,
149151
captionEntities: List<MessageEntity>,
152+
showCaptionAboveMedia: Boolean,
150153
replyToMsgId: Long?,
151154
threadId: Long?,
152155
sendOptions: MessageSendOptions
@@ -157,6 +160,7 @@ interface MessageRemoteDataSource : DraftLinkPreviewRemoteDataSource {
157160
paths: List<String>,
158161
caption: String,
159162
captionEntities: List<MessageEntity>,
163+
showCaptionAboveMedia: Boolean,
160164
replyToMsgId: Long?,
161165
threadId: Long?,
162166
sendOptions: MessageSendOptions
@@ -289,6 +293,7 @@ interface MessageRemoteDataSource : DraftLinkPreviewRemoteDataSource {
289293
limit: Int,
290294
threadId: Long? = null
291295
): List<MessageModel>
296+
suspend fun getChatMessageByDate(chatId: Long, dateEpochSeconds: Int): MessageModel?
292297

293298
suspend fun getRemoteMessagesAround(
294299
chatId: Long,

data/src/main/java/org/monogram/data/datasource/remote/SettingsRemoteDataSource.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ interface SettingsRemoteDataSource {
88
suspend fun getActiveSessions(): TdApi.Sessions?
99
suspend fun getInstalledBackgrounds(forDarkTheme: Boolean): TdApi.Backgrounds?
1010
suspend fun getStorageStatistics(chatLimit: Int): TdApi.StorageStatistics?
11+
suspend fun getStorageStatisticsFast(): TdApi.StorageStatisticsFast?
1112
suspend fun getNetworkStatistics(): TdApi.NetworkStatistics?
1213
suspend fun getOption(name: String): TdApi.OptionValue?
1314
suspend fun getChatNotificationSettingsExceptions(
@@ -44,7 +45,7 @@ interface SettingsRemoteDataSource {
4445
chatIds: LongArray?,
4546
returnDeletedFileStatistics: Boolean,
4647
chatLimit: Int
47-
): Boolean
48+
): TdApi.StorageStatistics?
4849
suspend fun resetNetworkStatistics(): Boolean
4950

5051
// Files

data/src/main/java/org/monogram/data/datasource/remote/TdChatRemoteDataSource.kt

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ import org.monogram.data.compat.buildSearchPublicChats
99
import org.monogram.data.compat.buildTdChatPermissions
1010
import org.monogram.data.core.coRunCatching
1111
import org.monogram.data.gateway.TelegramGateway
12-
import org.monogram.domain.repository.TelegramLinkRepository
1312
import org.monogram.domain.models.ChatPermissionsModel
13+
import org.monogram.domain.repository.TelegramLinkRepository
1414

1515
class TdChatRemoteSource(
1616
private val gateway: TelegramGateway,
@@ -118,6 +118,27 @@ class TdChatRemoteSource(
118118
}
119119
}
120120

121+
override suspend fun setChatHasHiddenMembers(chatId: Long, hasHiddenMembers: Boolean) {
122+
coRunCatching {
123+
val chat = gateway.execute(TdApi.GetChat(chatId))
124+
val supergroupId = (chat.type as? TdApi.ChatTypeSupergroup)?.supergroupId ?: return
125+
gateway.execute(TdApi.ToggleSupergroupHasHiddenMembers(supergroupId, hasHiddenMembers))
126+
}
127+
}
128+
129+
override suspend fun setChatHasAggressiveAntiSpamEnabled(chatId: Long, enabled: Boolean) {
130+
coRunCatching {
131+
val chat = gateway.execute(TdApi.GetChat(chatId))
132+
val supergroupId = (chat.type as? TdApi.ChatTypeSupergroup)?.supergroupId ?: return
133+
gateway.execute(
134+
TdApi.ToggleSupergroupHasAggressiveAntiSpamEnabled(
135+
supergroupId,
136+
enabled
137+
)
138+
)
139+
}
140+
}
141+
121142
override suspend fun setChatJoinToSendMessages(chatId: Long, joinToSendMessages: Boolean) {
122143
coRunCatching {
123144
val chat = gateway.execute(TdApi.GetChat(chatId))
@@ -131,6 +152,22 @@ class TdChatRemoteSource(
131152
}
132153
}
133154

155+
override suspend fun setChatJoinByRequest(chatId: Long, joinByRequest: Boolean) {
156+
coRunCatching {
157+
val chat = gateway.execute(TdApi.GetChat(chatId))
158+
val supergroupId = (chat.type as? TdApi.ChatTypeSupergroup)?.supergroupId ?: return
159+
val fullInfo = gateway.execute(TdApi.GetSupergroupFullInfo(supergroupId))
160+
gateway.execute(
161+
TdApi.ToggleSupergroupJoinByRequest(
162+
supergroupId,
163+
joinByRequest,
164+
fullInfo.guardBotUserId,
165+
true
166+
)
167+
)
168+
}
169+
}
170+
134171
override suspend fun setChatAvailableReactions(chatId: Long, availableReactions: List<String>) {
135172
coRunCatching {
136173
val chat = gateway.execute(TdApi.GetChat(chatId))

0 commit comments

Comments
 (0)