Skip to content

Commit f279d18

Browse files
committed
Disable storing/resolving local media paths
1 parent 9de8bce commit f279d18

4 files changed

Lines changed: 64 additions & 87 deletions

File tree

data/src/main/java/org/monogram/data/datasource/cache/RoomChatLocalDataSource.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,13 +88,13 @@ class RoomChatLocalDataSource(
8888
content,
8989
contentType,
9090
contentMeta,
91-
mediaFileId,
92-
mediaPath,
91+
0,
92+
null,
9393
editDate
9494
)
9595

9696
override suspend fun updateMediaPath(chatId: Long, messageId: Long, fileId: Int, path: String) {
97-
messageDao.updateMediaPathForMessage(chatId = chatId, messageId = messageId, fileId = fileId, path = path)
97+
// TDLib file ids and local paths are session-local
9898
}
9999

100100
override suspend fun clearCachedMediaPaths() = messageDao.clearCachedMediaPaths()

data/src/main/java/org/monogram/data/mapper/message/MessagePersistenceMapper.kt

Lines changed: 41 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,9 @@ internal class MessagePersistenceMapper(
6969
content = content.text,
7070
contentType = content.type,
7171
contentMeta = content.meta,
72-
mediaFileId = content.fileId,
73-
mediaPath = content.path,
74-
mediaThumbnailPath = content.thumbnailPath,
72+
mediaFileId = 0,
73+
mediaPath = null,
74+
mediaThumbnailPath = null,
7575
minithumbnail = content.minithumbnail,
7676
date = resolveMessageDate(msg),
7777
isOutgoing = msg.isOutgoing,
@@ -109,39 +109,32 @@ internal class MessagePersistenceMapper(
109109
?: original
110110
val thumbnail = sizes.find { it.type == "m" }
111111
?: sizes.find { it.type == "s" }
112-
val fileId = best?.photo?.id ?: 0
113-
val originalFileId = original?.photo?.id ?: fileId
114-
val path = best?.photo?.local?.path?.takeIf { fileHelper.isValidPath(it) }
115-
val thumbnailPath = thumbnail?.photo?.local?.path?.takeIf { fileHelper.isValidPath(it) }
112+
best?.photo?.local?.path?.takeIf { fileHelper.isValidPath(it) }
113+
thumbnail?.photo?.local?.path?.takeIf { fileHelper.isValidPath(it) }
116114
CachedMessageContent(
117115
"photo",
118116
content.caption.text,
119-
encodeMeta(best?.width ?: 0, best?.height ?: 0, originalFileId),
120-
fileId = fileId,
121-
path = path,
122-
thumbnailPath = thumbnailPath,
117+
encodeMeta(best?.width ?: 0, best?.height ?: 0),
118+
fileId = 0,
119+
path = null,
120+
thumbnailPath = null,
123121
minithumbnail = content.photo.minithumbnail?.data
124122
)
125123
}
126124

127125
is TdApi.MessageVideo -> {
128-
val fileId = content.video.video.id
129-
val path = content.video.video.local.path.takeIf { fileHelper.isValidPath(it) }
130126
CachedMessageContent(
131127
"video",
132128
content.caption.text,
133129
encodeMeta(
134130
content.video.width,
135131
content.video.height,
136132
content.video.duration,
137-
content.video.thumbnail?.file?.local?.path
138-
?.takeIf { fileHelper.isValidPath(it) }
139-
.orEmpty(),
140133
if (content.video.supportsStreaming) 1 else 0
141134
),
142-
fileId = fileId,
143-
path = path,
144-
thumbnailPath = content.video.thumbnail?.file?.local?.path?.takeIf { fileHelper.isValidPath(it) },
135+
fileId = 0,
136+
path = null,
137+
thumbnailPath = null,
145138
minithumbnail = content.video.minithumbnail?.data
146139
)
147140
}
@@ -150,22 +143,19 @@ internal class MessagePersistenceMapper(
150143
"voice",
151144
content.caption.text,
152145
encodeMeta(content.voiceNote.duration),
153-
fileId = content.voiceNote.voice.id,
154-
path = content.voiceNote.voice.local.path.takeIf { fileHelper.isValidPath(it) }
146+
fileId = 0,
147+
path = null
155148
)
156149

157150
is TdApi.MessageVideoNote -> CachedMessageContent(
158151
"video_note",
159152
"",
160153
encodeMeta(
161154
content.videoNote.duration,
162-
content.videoNote.length,
163-
content.videoNote.thumbnail?.file?.local?.path
164-
?.takeIf { fileHelper.isValidPath(it) }
165-
.orEmpty()
155+
content.videoNote.length
166156
),
167-
fileId = content.videoNote.video.id,
168-
path = content.videoNote.video.local.path.takeIf { fileHelper.isValidPath(it) }
157+
fileId = 0,
158+
path = null
169159
)
170160

171161
is TdApi.MessageSticker -> {
@@ -185,17 +175,17 @@ internal class MessagePersistenceMapper(
185175
content.sticker.height,
186176
format
187177
),
188-
fileId = content.sticker.sticker.id,
189-
path = content.sticker.sticker.local.path.takeIf { fileHelper.isValidPath(it) }
178+
fileId = 0,
179+
path = null
190180
)
191181
}
192182

193183
is TdApi.MessageDocument -> CachedMessageContent(
194184
"document",
195185
content.caption.text,
196186
encodeMeta(content.document.fileName, content.document.mimeType, content.document.document.size),
197-
fileId = content.document.document.id,
198-
path = content.document.document.local.path.takeIf { fileHelper.isValidPath(it) }
187+
fileId = 0,
188+
path = null
199189
)
200190

201191
is TdApi.MessageAudio -> CachedMessageContent(
@@ -207,8 +197,8 @@ internal class MessagePersistenceMapper(
207197
content.audio.performer.orEmpty(),
208198
content.audio.fileName.orEmpty()
209199
),
210-
fileId = content.audio.audio.id,
211-
path = content.audio.audio.local.path.takeIf { fileHelper.isValidPath(it) }
200+
fileId = 0,
201+
path = null
212202
)
213203

214204
is TdApi.MessageAnimation -> CachedMessageContent(
@@ -217,13 +207,10 @@ internal class MessagePersistenceMapper(
217207
encodeMeta(
218208
content.animation.width,
219209
content.animation.height,
220-
content.animation.duration,
221-
content.animation.thumbnail?.file?.local?.path
222-
?.takeIf { fileHelper.isValidPath(it) }
223-
.orEmpty()
210+
content.animation.duration
224211
),
225-
fileId = content.animation.animation.id,
226-
path = content.animation.animation.local.path.takeIf { fileHelper.isValidPath(it) }
212+
fileId = 0,
213+
path = null
227214
)
228215

229216
is TdApi.MessagePoll -> CachedMessageContent(
@@ -263,14 +250,8 @@ internal class MessagePersistenceMapper(
263250

264251
fun mapEntityToModel(entity: MessageDbEntity): MessageModel {
265252
val meta = decodeMeta(entity.contentMeta)
266-
val usesLegacyEmbeddedMedia = entity.mediaFileId == 0 && entity.mediaPath.isNullOrBlank()
267-
val (legacyFileId, legacyPath) = if (usesLegacyEmbeddedMedia) {
268-
resolveLegacyMediaFromMeta(entity.contentType, meta)
269-
} else {
270-
0 to null
271-
}
272-
val mediaFileId = entity.mediaFileId.takeIf { it != 0 } ?: legacyFileId
273-
val mediaPath = entity.mediaPath?.takeIf { it.isNotBlank() } ?: legacyPath
253+
val mediaFileId = entity.mediaFileId.takeIf { it != 0 } ?: 0
254+
entity.mediaPath?.takeIf { it.isNotBlank() }
274255
val replyToMsgId = entity.replyToMessageId.takeIf { it != 0L }
275256
val replyPreview = resolveReplyPreview(entity)
276257
val replyPreviewModel =
@@ -361,12 +342,12 @@ internal class MessagePersistenceMapper(
361342

362343
"photo" -> {
363344
val fileId = mediaFileId
364-
val originalFileId = meta.getOrNull(2)?.toIntOrNull() ?: fileId
345+
val originalFileId = fileId
365346
fileHelper.registerCachedFile(fileId, entity.chatId, entity.id)
366347
fileHelper.registerCachedFile(originalFileId, entity.chatId, entity.id)
367348
MessageContent.Photo(
368-
path = fileHelper.resolveCachedPath(fileId, mediaPath),
369-
thumbnailPath = entity.mediaThumbnailPath?.takeIf { fileHelper.isValidPath(it) },
349+
path = null,
350+
thumbnailPath = null,
370351
width = meta.getOrNull(0)?.toIntOrNull() ?: 0,
371352
height = meta.getOrNull(1)?.toIntOrNull() ?: 0,
372353
caption = entity.content,
@@ -379,18 +360,11 @@ internal class MessagePersistenceMapper(
379360

380361
"video" -> {
381362
val fileId = mediaFileId
382-
val supportsStreaming = if (usesLegacyEmbeddedMedia) {
383-
(meta.getOrNull(6)?.toIntOrNull() ?: 0) == 1
384-
} else {
385-
(meta.getOrNull(4)?.toIntOrNull() ?: 0) == 1
386-
}
363+
val supportsStreaming = (meta.getOrNull(3)?.toIntOrNull() ?: 0) == 1
387364
fileHelper.registerCachedFile(fileId, entity.chatId, entity.id)
388365
MessageContent.Video(
389-
path = fileHelper.resolveCachedPath(fileId, mediaPath),
390-
thumbnailPath = (
391-
entity.mediaThumbnailPath?.takeIf { fileHelper.isValidPath(it) }
392-
?: meta.getOrNull(3)
393-
)?.takeIf { fileHelper.isValidPath(it) },
366+
path = null,
367+
thumbnailPath = null,
394368
width = meta.getOrNull(0)?.toIntOrNull() ?: 0,
395369
height = meta.getOrNull(1)?.toIntOrNull() ?: 0,
396370
duration = meta.getOrNull(2)?.toIntOrNull() ?: 0,
@@ -406,19 +380,18 @@ internal class MessagePersistenceMapper(
406380
val fileId = mediaFileId
407381
fileHelper.registerCachedFile(fileId, entity.chatId, entity.id)
408382
MessageContent.Voice(
409-
path = fileHelper.resolveCachedPath(fileId, mediaPath),
383+
path = null,
410384
duration = meta.getOrNull(0)?.toIntOrNull() ?: 0,
411385
fileId = fileId
412386
)
413387
}
414388

415389
"video_note" -> {
416390
val fileId = mediaFileId
417-
val storedThumbPath = if (usesLegacyEmbeddedMedia) meta.getOrNull(4) else meta.getOrNull(2)
418391
fileHelper.registerCachedFile(fileId, entity.chatId, entity.id)
419392
MessageContent.VideoNote(
420-
path = fileHelper.resolveCachedPath(fileId, mediaPath),
421-
thumbnail = storedThumbPath?.takeIf { fileHelper.isValidPath(it) },
393+
path = null,
394+
thumbnail = null,
422395
duration = meta.getOrNull(0)?.toIntOrNull() ?: 0,
423396
length = meta.getOrNull(1)?.toIntOrNull() ?: 0,
424397
fileId = fileId
@@ -431,7 +404,7 @@ internal class MessagePersistenceMapper(
431404
MessageContent.Sticker(
432405
id = 0L,
433406
setId = meta.getOrNull(0)?.toLongOrNull() ?: 0L,
434-
path = fileHelper.resolveCachedPath(fileId, mediaPath),
407+
path = null,
435408
width = meta.getOrNull(2)?.toIntOrNull() ?: 0,
436409
height = meta.getOrNull(3)?.toIntOrNull() ?: 0,
437410
emoji = entity.content,
@@ -443,7 +416,7 @@ internal class MessagePersistenceMapper(
443416
val fileId = mediaFileId
444417
fileHelper.registerCachedFile(fileId, entity.chatId, entity.id)
445418
MessageContent.Document(
446-
path = fileHelper.resolveCachedPath(fileId, mediaPath),
419+
path = null,
447420
fileName = meta.getOrNull(0).orEmpty(),
448421
mimeType = meta.getOrNull(1).orEmpty(),
449422
size = meta.getOrNull(2)?.toLongOrNull() ?: 0L,
@@ -457,7 +430,7 @@ internal class MessagePersistenceMapper(
457430
val fileId = mediaFileId
458431
fileHelper.registerCachedFile(fileId, entity.chatId, entity.id)
459432
MessageContent.Audio(
460-
path = fileHelper.resolveCachedPath(fileId, mediaPath),
433+
path = null,
461434
duration = meta.getOrNull(0)?.toIntOrNull() ?: 0,
462435
title = meta.getOrNull(1).orEmpty(),
463436
performer = meta.getOrNull(2).orEmpty(),
@@ -474,7 +447,7 @@ internal class MessagePersistenceMapper(
474447
val fileId = mediaFileId
475448
fileHelper.registerCachedFile(fileId, entity.chatId, entity.id)
476449
MessageContent.Gif(
477-
path = fileHelper.resolveCachedPath(fileId, mediaPath),
450+
path = null,
478451
width = meta.getOrNull(0)?.toIntOrNull() ?: 0,
479452
height = meta.getOrNull(1)?.toIntOrNull() ?: 0,
480453
caption = entity.content,
@@ -831,20 +804,6 @@ internal class MessagePersistenceMapper(
831804
return if (raw.contains(META_SEPARATOR)) raw.split(META_SEPARATOR) else raw.split('|')
832805
}
833806

834-
private fun resolveLegacyMediaFromMeta(contentType: String, meta: List<String>): Pair<Int, String?> {
835-
return when (contentType) {
836-
"photo" -> (meta.getOrNull(2)?.toIntOrNull() ?: 0) to meta.getOrNull(3)
837-
"video" -> (meta.getOrNull(3)?.toIntOrNull() ?: 0) to meta.getOrNull(4)
838-
"voice" -> (meta.getOrNull(1)?.toIntOrNull() ?: 0) to meta.getOrNull(2)
839-
"video_note" -> (meta.getOrNull(2)?.toIntOrNull() ?: 0) to meta.getOrNull(3)
840-
"sticker" -> (meta.getOrNull(4)?.toIntOrNull() ?: 0) to meta.getOrNull(6)
841-
"document" -> (meta.getOrNull(3)?.toIntOrNull() ?: 0) to meta.getOrNull(4)
842-
"audio" -> (meta.getOrNull(4)?.toIntOrNull() ?: 0) to meta.getOrNull(5)
843-
"gif" -> (meta.getOrNull(3)?.toIntOrNull() ?: 0) to meta.getOrNull(4)
844-
else -> 0 to null
845-
}
846-
}
847-
848807
private fun resolveMessageDate(msg: TdApi.Message): Int {
849808
return when (val schedulingState = msg.schedulingState) {
850809
is TdApi.MessageSchedulingStateSendAtDate -> schedulingState.sendDate

data/src/main/java/org/monogram/data/stickers/StickerFileManager.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ class StickerFileManager(
175175
}
176176
val liveKnownPath = authoritativeFile?.local?.path?.takeUnless { it.isNullOrBlank() }
177177
val memoryPath = filePathsCache[fileId]
178-
val dbPath = localDataSource.getPath(fileId)
178+
val dbPath = null
179179
val completedPath = fileUpdateHandler.fileDownloadCompleted
180180
.replayCache
181181
.firstOrNull { it.first == fileId && isValidFilePath(it.second) }

presentation/src/main/java/org/monogram/presentation/features/chats/conversation/logic/message-loading/MessageLoading.kt

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,22 @@ private fun MessageModel.deliverySignature(): String? {
265265
}
266266
}
267267

268+
private fun MessageModel.hasUnresolvableCachedMedia(): Boolean {
269+
return when (val c = content) {
270+
is MessageContent.Photo -> c.path.isNullOrBlank() && c.thumbnailPath.isNullOrBlank() &&
271+
c.fileId == 0 && c.originalFileId == 0
272+
273+
is MessageContent.Video -> c.path.isNullOrBlank() && c.thumbnailPath.isNullOrBlank() && c.fileId == 0
274+
is MessageContent.Voice -> c.path.isNullOrBlank() && c.fileId == 0
275+
is MessageContent.VideoNote -> c.path.isNullOrBlank() && c.thumbnail.isNullOrBlank() && c.fileId == 0
276+
is MessageContent.Sticker -> c.path.isNullOrBlank() && c.fileId == 0
277+
is MessageContent.Document -> c.path.isNullOrBlank() && c.fileId == 0
278+
is MessageContent.Audio -> c.path.isNullOrBlank() && c.fileId == 0
279+
is MessageContent.Gif -> c.path.isNullOrBlank() && c.fileId == 0
280+
else -> false
281+
}
282+
}
283+
268284
internal fun DefaultChatComponent.loadMessages(force: Boolean = false) {
269285
val state = _state.value
270286
if (state.isLoading) return
@@ -445,7 +461,9 @@ private suspend fun DefaultChatComponent.loadBottomMessages(
445461
val messages = olderPage.messages
446462
val isRemoteSameAsCachedPreview = hasCachedPreview && cachedMessages.isNotEmpty() &&
447463
messages.size == cachedMessages.size &&
448-
messages.zip(cachedMessages).all { (remote, cached) -> remote.id == cached.id }
464+
messages.zip(cachedMessages).all { (remote, cached) ->
465+
remote.id == cached.id && !cached.hasUnresolvableCachedMedia()
466+
}
449467

450468
val isOldestLoaded = if (isRemoteSameAsCachedPreview) {
451469
false

0 commit comments

Comments
 (0)