11/*
22 * Nextcloud - Android Client
33 *
4+ * SPDX-FileCopyrightText: 2025 Alper Ozturk <alper.ozturk@nextcloud.com>
45 * SPDX-FileCopyrightText: 2022 Tobias Kaminsky <tobias@kaminsky.me>
56 * SPDX-FileCopyrightText: 2022 Nextcloud GmbH
67 * SPDX-License-Identifier: AGPL-3.0-or-later OR GPL-2.0-only
@@ -17,6 +18,7 @@ import androidx.core.view.get
1718import com.afollestad.sectionedrecyclerview.SectionedViewHolder
1819import com.elyeproj.loaderviewlibrary.LoaderImageView
1920import com.nextcloud.android.common.ui.theme.utils.ColorRole
21+ import com.nextcloud.utils.OCFileUtils
2022import com.nextcloud.utils.extensions.makeRounded
2123import com.nextcloud.utils.extensions.setVisibleIf
2224import com.owncloud.android.R
@@ -58,7 +60,7 @@ class GalleryRowHolder(
5860 }
5961
6062 if (binding.rowLayout.childCount > row.files.size) {
61- binding.rowLayout.removeViewsInLayout (row.files.size - 1 , ( binding.rowLayout.childCount - row.files.size) )
63+ binding.rowLayout.removeViews (row.files.size, binding.rowLayout.childCount - row.files.size)
6264 }
6365
6466 val shrinkRatio = computeShrinkRatio(row)
@@ -110,76 +112,57 @@ class GalleryRowHolder(
110112 bind(currentRow)
111113 }
112114
113- @SuppressWarnings(" MagicNumber" , " ComplexMethod " )
115+ @SuppressWarnings(" MagicNumber" )
114116 private fun computeShrinkRatio (row : GalleryRow ): Float {
115- val screenWidth =
116- DisplayUtils .convertDpToPixel(context.resources.configuration.screenWidthDp.toFloat(), context)
117- .toFloat()
117+ val screenWidth = DisplayUtils .convertDpToPixel(
118+ context.resources.configuration.screenWidthDp.toFloat(),
119+ context
120+ ).toFloat()
118121
119- if (row.files.size > 1 ) {
120- var newSummedWidth = 0f
121- for (file in row.files) {
122- // first adjust all thumbnails to max height
123- val thumbnail1 = file.imageDimension ? : ImageDimension (defaultThumbnailSize, defaultThumbnailSize)
124-
125- val height1 = thumbnail1.height
126- val width1 = thumbnail1.width
127-
128- val scaleFactor1 = row.getMaxHeight() / height1
129- val newHeight1 = height1 * scaleFactor1
130- val newWidth1 = width1 * scaleFactor1
122+ return if (row.files.size > 1 ) {
123+ computeMultiFileShrinkRatio(row, screenWidth)
124+ } else {
125+ computeSingleFileShrinkRatio(row, screenWidth)
126+ }
127+ }
131128
132- file.imageDimension = ImageDimension (newWidth1, newHeight1)
129+ private fun computeMultiFileShrinkRatio (row : GalleryRow , screenWidth : Float ): Float {
130+ val targetHeight = row.getMaxHeight()
131+ var totalUnscaledWidth = 0f
133132
134- newSummedWidth + = newWidth1
135- }
133+ for (file in row.files) {
134+ val (originalWidth, originalHeight) = OCFileUtils .getImageSize(file, defaultThumbnailSize)
136135
137- var c = 1f
138- // this ensures that files in last row are better visible,
139- // e.g. when 2 images are there, it uses 2/5 of screen
140- if (galleryAdapter.columns == 5 ) {
141- when (row.files.size) {
142- 2 -> {
143- c = 5 / 2f
144- }
136+ val scaledWidth = targetHeight * (originalWidth.toFloat() / originalHeight)
137+ file.imageDimension = ImageDimension (scaledWidth, targetHeight)
145138
146- 3 -> {
147- c = 4 / 3f
148- }
149-
150- 4 -> {
151- c = 4 / 5f
152- }
139+ totalUnscaledWidth + = scaledWidth
140+ }
153141
154- 5 -> {
155- c = 1f
156- }
157- }
158- }
142+ val totalAvailableWidth = screenWidth - ((row.files.size - 1 ) * smallMargin)
143+ return totalAvailableWidth / totalUnscaledWidth
144+ }
159145
160- return (screenWidth / c) / newSummedWidth
161- } else {
162- val thumbnail1 = row.files[0 ].imageDimension ? : ImageDimension (defaultThumbnailSize, defaultThumbnailSize)
163- return (screenWidth / galleryAdapter.columns) / thumbnail1.width
164- }
146+ private fun computeSingleFileShrinkRatio (row : GalleryRow , screenWidth : Float ): Float {
147+ val width = OCFileUtils .getImageSize(row.files[0 ], defaultThumbnailSize).first
148+ return (screenWidth / galleryAdapter.columns) / width
165149 }
166150
167151 private fun adjustFile (indexedFile : IndexedValue <OCFile >, shrinkRatio : Float , row : GalleryRow ) {
168152 val file = indexedFile.value
169153 val index = indexedFile.index
170- val fileWidth = file.imageDimension?.width
171- val fileHeight = file.imageDimension?.height
172154
173- val width = ((fileWidth ? : defaultThumbnailSize) * shrinkRatio).toInt()
174- val height = ((fileHeight ? : defaultThumbnailSize) * shrinkRatio).toInt()
155+ val width = file.imageDimension?.width?.times( shrinkRatio)? .toInt() ? : 0
156+ val height = file.imageDimension?.height?.times( shrinkRatio)? .toInt() ? : 0
175157
176158 val frameLayout = binding.rowLayout[index] as FrameLayout
177159 val checkBoxImageView = frameLayout[2 ] as ImageView
178160 val shimmer = frameLayout[0 ] as LoaderImageView
179161 val thumbnail = (frameLayout[1 ] as ImageView ).apply {
180162 adjustViewBounds = true
181- scaleType = ImageView .ScaleType .FIT_CENTER
163+ scaleType = ImageView .ScaleType .FIT_XY
182164 }
165+
183166 val isChecked = ocFileListDelegate.isCheckedFile(file)
184167
185168 adjustRowCell(thumbnail, isChecked)
@@ -193,25 +176,15 @@ class GalleryRowHolder(
193176 width
194177 )
195178
196- val params = FrameLayout .LayoutParams (width, height)
197-
198- if (index < (row.files.size - 1 )) {
199- params.setMargins(zero, zero, smallMargin, smallMargin)
200- } else {
201- params.setMargins(zero, zero, zero, smallMargin)
202- }
179+ // Force layout update
180+ frameLayout.requestLayout()
203181
204- thumbnail.run {
205- layoutParams = params
206- layoutParams.height = height
207- layoutParams.width = width
208- }
182+ val params = FrameLayout .LayoutParams (width, height)
183+ val endMargin = if (index < row.files.size - 1 ) smallMargin else zero
184+ params.setMargins(zero, zero, endMargin, smallMargin)
209185
210- shimmer.run {
211- layoutParams = params
212- layoutParams.height = height
213- layoutParams.width = width
214- }
186+ thumbnail.layoutParams = params
187+ shimmer.layoutParams = FrameLayout .LayoutParams (params)
215188 }
216189
217190 @Suppress(" MagicNumber" )
0 commit comments