@@ -30,7 +30,6 @@ import com.nextcloud.talk.shareditems.repositories.SharedItemsRepository
3030import com.nextcloud.talk.utils.CapabilitiesUtil
3131import com.nextcloud.talk.utils.FileUtils
3232import io.reactivex.Observable
33- import kotlinx.coroutines.flow.MutableSharedFlow
3433import kotlinx.coroutines.flow.MutableStateFlow
3534import kotlinx.coroutines.flow.StateFlow
3635import kotlinx.coroutines.flow.collect
@@ -52,13 +51,16 @@ import kotlin.coroutines.resumeWithException
5251class MediaViewerViewModel @Inject constructor(private val sharedItemsRepository : SharedItemsRepository ) :
5352 ViewModel () {
5453
54+ data class PendingShift (val id : Long , val amount : Int )
55+
5556 data class UiState (
5657 val groups : List <MediaViewerGroup > = emptyList(),
5758 val currentGlobalIndex : Int = 0 ,
5859 val loadingOlder : Boolean = false ,
5960 val canLoadOlder : Boolean = true ,
6061 val cachedFilePaths : Map <Long , String > = emptyMap(),
61- val downloadingMessageIds : Set <Long > = emptySet()
62+ val downloadingMessageIds : Set <Long > = emptySet(),
63+ val pendingShift : PendingShift ? = null
6264 ) {
6365 val flattenedItems: List <MediaViewerItem > get() = groups.flatMap { it.items }
6466 val currentItem: MediaViewerItem ? get() = flattenedItems.getOrNull(currentGlobalIndex)
@@ -71,14 +73,7 @@ class MediaViewerViewModel @Inject constructor(private val sharedItemsRepository
7173
7274 private val _uiState = MutableStateFlow (UiState ())
7375 val uiState: StateFlow <UiState > = _uiState
74-
75- // HorizontalPager indexes into the flattened item list; prepending older groups shifts every
76- // existing index by the number of items prepended. This is a one-shot event (not part of
77- // UiState) so the pager can silently jump to the shifted position - via
78- // pagerState.scrollToPage(pagerState.currentPage + shift) - the moment it fires, keeping the
79- // same item on screen instead of visually jumping to whatever is now at the old index.
80- private val _indexShiftEvents = MutableSharedFlow <Int >(extraBufferCapacity = 1 )
81- val indexShiftEvents = _indexShiftEvents
76+ private var nextShiftId = 0L
8277
8378 private lateinit var user: User
8479 private lateinit var repositoryParameters: SharedItemsRepository .Parameters
@@ -112,6 +107,10 @@ class MediaViewerViewModel @Inject constructor(private val sharedItemsRepository
112107 onPageSettled(globalIndex)
113108 }
114109
110+ fun consumePendingShift (id : Long ) {
111+ _uiState .update { if (it.pendingShift?.id == id) it.copy(pendingShift = null ) else it }
112+ }
113+
115114 private fun ensureCachedAround (globalIndex : Int ) {
116115 val items = _uiState .value.flattenedItems
117116 for (index in (globalIndex - PREFETCH_RADIUS ).. (globalIndex + PREFETCH_RADIUS )) {
@@ -127,7 +126,7 @@ class MediaViewerViewModel @Inject constructor(private val sharedItemsRepository
127126 }
128127
129128 val context = NextcloudTalkApplication .sharedApplication!!
130- val existing = FileUtils .resolveSharedAttachmentFile(context.cacheDir, item.fileName)
129+ val existing = FileUtils .resolveSharedAttachmentFile(context.cacheDir, item.fileId, item. fileName)
131130 if (existing != null && existing.exists()) {
132131 _uiState .update {
133132 it.copy(cachedFilePaths = it.cachedFilePaths + (item.messageId to existing.absolutePath))
@@ -144,6 +143,7 @@ class MediaViewerViewModel @Inject constructor(private val sharedItemsRepository
144143 DownloadFileToCacheWorker .KEY_ATTACHMENT_FOLDER ,
145144 CapabilitiesUtil .getAttachmentFolder(user.capabilities!! .spreedCapability!! )
146145 )
146+ .putString(DownloadFileToCacheWorker .KEY_FILE_ID , item.fileId)
147147 .putString(DownloadFileToCacheWorker .KEY_FILE_NAME , item.fileName)
148148 .putString(DownloadFileToCacheWorker .KEY_FILE_PATH , item.path)
149149 .putLong(DownloadFileToCacheWorker .KEY_FILE_SIZE , item.fileSize)
@@ -161,7 +161,11 @@ class MediaViewerViewModel @Inject constructor(private val sharedItemsRepository
161161 if (workInfo == null ) return @collect
162162 when (workInfo.state) {
163163 WorkInfo .State .SUCCEEDED -> {
164- val downloaded = FileUtils .resolveSharedAttachmentFile(context.cacheDir, item.fileName)
164+ val downloaded = FileUtils .resolveSharedAttachmentFile(
165+ context.cacheDir,
166+ item.fileId,
167+ item.fileName
168+ )
165169 _uiState .update {
166170 it.copy(
167171 downloadingMessageIds = it.downloadingMessageIds - item.messageId,
@@ -210,17 +214,16 @@ class MediaViewerViewModel @Inject constructor(private val sharedItemsRepository
210214 }
211215
212216 oldestKnownMessageId = olderItems.first().messageId
213- val previousCount = _uiState .value.flattenedItems.size
214217 _uiState .update { current ->
215218 val combined = (olderItems + current.flattenedItems).toMediaViewerGroups()
216219 current.copy(
217220 groups = combined,
218221 currentGlobalIndex = current.currentGlobalIndex + olderItems.size,
219222 loadingOlder = false ,
220- canLoadOlder = sharedItems?.moreItemsExisting == true
223+ canLoadOlder = sharedItems?.moreItemsExisting == true ,
224+ pendingShift = PendingShift (id = nextShiftId++ , amount = olderItems.size)
221225 )
222226 }
223- _indexShiftEvents .tryEmit(_uiState .value.flattenedItems.size - previousCount)
224227 }
225228 }
226229
0 commit comments