Skip to content

Commit 3a99558

Browse files
committed
fix placeholder icon inset
Signed-off-by: alperozturk96 <alper_ozturk@proton.me>
1 parent 94e38e2 commit 3a99558

11 files changed

Lines changed: 146 additions & 159 deletions

File tree

app/src/main/java/com/nextcloud/client/jobs/gallery/GalleryImageGenerationJob.kt

Lines changed: 20 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,21 @@
88
package com.nextcloud.client.jobs.gallery
99

1010
import android.graphics.Bitmap
11+
import android.graphics.Point
1112
import android.media.ThumbnailUtils
1213
import android.os.Build
1314
import android.provider.MediaStore
1415
import android.util.Size
16+
import android.view.WindowManager
1517
import android.widget.ImageView
16-
import androidx.core.content.ContextCompat
1718
import com.nextcloud.client.account.User
1819
import com.nextcloud.utils.extensions.getBigThumbnail
1920
import com.nextcloud.utils.extensions.getBigThumbnailKey
2021
import com.nextcloud.utils.extensions.getSmallThumbnail
21-
import com.nextcloud.utils.extensions.getSmallThumbnailKey
2222
import com.nextcloud.utils.extensions.isPNG
23+
import com.nextcloud.utils.extensions.setMediaThumbnail
2324
import com.nextcloud.utils.extensions.toFile
24-
import com.nextcloud.utils.extensions.videoOverlayKey
25-
import com.nextcloud.utils.thumbnail.ThumbnailMemoryCache
2625
import com.owncloud.android.MainApp
27-
import com.owncloud.android.R
2826
import com.owncloud.android.datamodel.FileDataStorageManager
2927
import com.owncloud.android.datamodel.OCFile
3028
import com.owncloud.android.datamodel.ThumbnailsCacheManager
@@ -115,24 +113,24 @@ class GalleryImageGenerationJob(private val user: User, private val storageManag
115113
private suspend fun getBitmap(file: OCFile): Bitmap? = withContext(Dispatchers.IO) {
116114
val cached = file.getBigThumbnail()
117115
if (cached != null && !file.isUpdateThumbnailNeeded) {
118-
return@withContext withCachedVideoOverlay(file, cached, file.getBigThumbnailKey())
116+
return@withContext cached
119117
}
120118

121119
if (file.isDown) {
122120
val local = decodeLocalThumbnail(file)
123121
if (local != null) {
124122
ThumbnailsCacheManager.addBitmapToCache(file.getBigThumbnailKey(), local)
125-
return@withContext withCachedVideoOverlay(file, local, file.getBigThumbnailKey())
123+
return@withContext local
126124
}
127125
}
128126

129127
val remote = semaphore.withPermit { fetchFromServer(file) }
130128
if (remote != null) {
131-
return@withContext withCachedVideoOverlay(file, remote, file.getBigThumbnailKey())
129+
return@withContext remote
132130
}
133131

134132
file.getSmallThumbnail()?.let { small ->
135-
return@withContext withCachedVideoOverlay(file, small, file.getSmallThumbnailKey())
133+
return@withContext small
136134
}
137135

138136
null
@@ -145,21 +143,22 @@ class GalleryImageGenerationJob(private val user: User, private val storageManag
145143
}
146144

147145
private fun createImageThumbnail(file: OCFile): Bitmap? {
148-
val box = ThumbnailsCacheManager.getResizedImageDimension()
146+
val wm = MainApp.getAppContext().getSystemService(android.content.Context.WINDOW_SERVICE) as WindowManager
147+
val p = Point()
148+
wm.defaultDisplay.getSize(p)
149149

150-
var bitmap = BitmapUtils.decodeSampledBitmapFromFile(file.storagePath, box.x, box.y) ?: return null
150+
val pxW = p.x
151+
val pxH = p.y
152+
153+
val cacheKey = file.getBigThumbnailKey()
154+
155+
var bitmap = BitmapUtils.decodeSampledBitmapFromFile(file.storagePath, pxW, pxH) ?: return null
151156

152157
if (file.isPNG()) {
153-
bitmap = ThumbnailsCacheManager.handlePNG(bitmap, bitmap.width, bitmap.height)
158+
bitmap = ThumbnailsCacheManager.handlePNG(bitmap, pxW, pxH)
154159
}
155160

156-
val thumbnail = ThumbnailsCacheManager.addThumbnailToCache(
157-
file.getBigThumbnailKey(),
158-
bitmap,
159-
file.storagePath,
160-
bitmap.width,
161-
bitmap.height
162-
)
161+
val thumbnail = ThumbnailsCacheManager.addThumbnailToCache(cacheKey, bitmap, file.storagePath, pxW, pxH)
163162
file.isUpdateThumbnailNeeded = false
164163

165164
return thumbnail
@@ -193,19 +192,6 @@ class GalleryImageGenerationJob(private val user: User, private val storageManag
193192
null
194193
}
195194

196-
private fun withCachedVideoOverlay(file: OCFile, bitmap: Bitmap, sourceKey: String): Bitmap {
197-
if (!MimeTypeUtil.isVideo(file)) {
198-
return bitmap
199-
}
200-
201-
val overlayKey = videoOverlayKey(sourceKey)
202-
ThumbnailMemoryCache.get(overlayKey)?.let { return it }
203-
204-
return ThumbnailsCacheManager.addVideoOverlay(bitmap, MainApp.getAppContext()).also {
205-
ThumbnailMemoryCache.put(overlayKey, it)
206-
}
207-
}
208-
209195
private suspend fun setThumbnail(
210196
bitmap: Bitmap,
211197
file: OCFile,
@@ -214,17 +200,8 @@ class GalleryImageGenerationJob(private val user: User, private val storageManag
214200
) = withContext(Dispatchers.Main) {
215201
val tagId = file.fileId.toString()
216202

217-
if (imageView.tag.toString() == tagId) {
218-
if (file.isPNG()) {
219-
imageView.setBackgroundColor(
220-
ContextCompat.getColor(MainApp.getAppContext(), R.color.bg_default)
221-
)
222-
}
223-
224-
if (imageView.isAttachedToWindow) {
225-
imageView.scaleType = ImageView.ScaleType.CENTER_CROP
226-
imageView.setImageBitmap(bitmap)
227-
}
203+
if (imageView.tag.toString() == tagId && imageView.isAttachedToWindow) {
204+
imageView.setMediaThumbnail(file, bitmap)
228205
}
229206

230207
listener.onSuccess()

app/src/main/java/com/nextcloud/utils/OCFileUtils.kt

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,29 +6,23 @@
66
*/
77
package com.nextcloud.utils
88

9-
import android.graphics.Bitmap
10-
import android.graphics.Color
119
import android.graphics.drawable.Drawable
1210
import android.util.LruCache
1311
import androidx.core.content.ContextCompat
14-
import androidx.core.graphics.drawable.toDrawable
1512
import com.nextcloud.utils.extensions.getBitmapSize
1613
import com.nextcloud.utils.extensions.getExifSize
1714
import com.owncloud.android.MainApp
1815
import com.owncloud.android.R
1916
import com.owncloud.android.datamodel.OCFile
2017
import com.owncloud.android.lib.common.utils.Log_OC
21-
import com.owncloud.android.utils.BitmapUtils
2218
import com.owncloud.android.utils.MimeTypeUtil
2319

2420
@Suppress("TooGenericExceptionCaught", "ReturnCount")
2521
object OCFileUtils {
2622
private const val TAG = "OCFileUtils"
2723
private const val IMAGE_SIZE_CACHE_ENTRIES = 2048
28-
private const val PLACEHOLDER_SIZE_PX = 256
2924

3025
private val imageSizes = LruCache<Long, Pair<Int, Int>>(IMAGE_SIZE_CACHE_ENTRIES)
31-
private val placeholders = mutableMapOf<Int, Bitmap>()
3226

3327
fun getImageSize(ocFile: OCFile, defaultThumbnailSize: Float): Pair<Int, Int> {
3428
val fallback = defaultThumbnailSize.toInt().coerceAtLeast(1)
@@ -59,7 +53,7 @@ object OCFileUtils {
5953
return fallbackPair
6054
}
6155

62-
fun getMediaPlaceholder(file: OCFile): Drawable {
56+
fun getMediaPlaceholder(file: OCFile): Drawable? {
6357
val context = MainApp.getAppContext()
6458

6559
val drawableId = if (MimeTypeUtil.isImage(file)) {
@@ -70,13 +64,6 @@ object OCFileUtils {
7064
R.drawable.file
7165
}
7266

73-
val bitmap = synchronized(placeholders) {
74-
placeholders.getOrPut(drawableId) {
75-
val drawable = ContextCompat.getDrawable(context, drawableId) ?: Color.GRAY.toDrawable()
76-
BitmapUtils.drawableToBitmap(drawable, PLACEHOLDER_SIZE_PX, PLACEHOLDER_SIZE_PX)
77-
}
78-
}
79-
80-
return bitmap.toDrawable(context.resources)
67+
return ContextCompat.getDrawable(context, drawableId)
8168
}
8269
}

app/src/main/java/com/nextcloud/utils/extensions/ImageViewExtensions.kt

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
package com.nextcloud.utils.extensions
99

1010
import android.content.Context
11+
import android.graphics.Bitmap
1112
import android.graphics.drawable.GradientDrawable
1213
import android.util.TypedValue
1314
import android.view.View
@@ -17,7 +18,10 @@ import androidx.annotation.ColorInt
1718
import androidx.annotation.DrawableRes
1819
import androidx.core.content.ContextCompat
1920
import com.elyeproj.loaderviewlibrary.LoaderImageView
21+
import com.nextcloud.utils.OCFileUtils
2022
import com.owncloud.android.R
23+
import com.owncloud.android.datamodel.OCFile
24+
import com.owncloud.android.utils.MimeTypeUtil
2125

2226
fun ImageView.startShimmer(shimmer: LoaderImageView) {
2327
shimmer.setImageResource(R.drawable.background)
@@ -33,6 +37,37 @@ fun ImageView.stopShimmer(shimmer: LoaderImageView?) {
3337
setVisibility(View.VISIBLE)
3438
}
3539

40+
fun ImageView.setMediaPlaceholder(file: OCFile, iconInset: Int) {
41+
scaleType = ImageView.ScaleType.FIT_CENTER
42+
setPadding(iconInset, iconInset, iconInset, iconInset)
43+
setBackgroundResource(R.color.media_placeholder_background)
44+
foreground = null
45+
setImageDrawable(OCFileUtils.getMediaPlaceholder(file))
46+
setTag(R.id.media_thumbnail_file_id, null)
47+
}
48+
49+
fun ImageView.setMediaThumbnail(file: OCFile, bitmap: Bitmap) {
50+
scaleType = ImageView.ScaleType.CENTER_CROP
51+
setPadding(0, 0, 0, 0)
52+
53+
if (file.isPNG()) {
54+
setBackgroundResource(R.color.bg_default)
55+
} else {
56+
background = null
57+
}
58+
59+
foreground = if (MimeTypeUtil.isVideo(file)) {
60+
ContextCompat.getDrawable(context, R.drawable.video_white)
61+
} else {
62+
null
63+
}
64+
65+
setImageBitmap(bitmap)
66+
setTag(R.id.media_thumbnail_file_id, file.fileId)
67+
}
68+
69+
fun ImageView.showsMediaThumbnailOf(file: OCFile): Boolean = getTag(R.id.media_thumbnail_file_id) == file.fileId
70+
3671
@JvmOverloads
3772
fun ImageView.makeRoundedWithIcon(
3873
context: Context,

app/src/main/java/com/nextcloud/utils/thumbnail/FileThumbnailGenerator.kt

Lines changed: 20 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ import com.nextcloud.utils.extensions.getSmallThumbnailKey
2525
import com.nextcloud.utils.extensions.startShimmer
2626
import com.nextcloud.utils.extensions.stopShimmer
2727
import com.nextcloud.utils.extensions.toFile
28-
import com.nextcloud.utils.extensions.videoOverlayKey
2928
import com.owncloud.android.R
3029
import com.owncloud.android.datamodel.FileDataStorageManager
3130
import com.owncloud.android.datamodel.OCFile
@@ -69,19 +68,15 @@ class FileThumbnailGenerator @Inject constructor(
6968
)
7069

7170
private val tasks = CopyOnWriteArrayList<ThumbnailGenerationTask>()
71+
private val placeholders = mutableMapOf<String, Bitmap>()
7272

7373
fun setThumbnail(file: OCFile, view: ImageView, arguments: ThumbnailArguments) {
7474
if (file.remoteId == null) {
7575
setLocalThumbnail(file, view, arguments)
7676
return
7777
}
7878

79-
if (!file.isPreviewAvailable) {
80-
generate(file, view, arguments)
81-
return
82-
}
83-
84-
val cached = ThumbnailMemoryCache.get(file.getSmallThumbnailKey())
79+
val cached = ThumbnailsCacheManager.getBitmapFromDiskCache(file.getSmallThumbnailKey())
8580
if (cached == null || file.isUpdateThumbnailNeeded) {
8681
generate(file, view, arguments)
8782
} else {
@@ -91,6 +86,16 @@ class FileThumbnailGenerator @Inject constructor(
9186
applyPngBackground(file, view)
9287
}
9388

89+
private fun show(bitmap: Bitmap, file: OCFile, view: ImageView, arguments: ThumbnailArguments) {
90+
view.stopShimmer(arguments.shimmer)
91+
92+
if (MimeTypeUtil.isVideo(file) && !arguments.hideVideoOverlay) {
93+
view.setImageBitmap(ThumbnailsCacheManager.addVideoOverlay(bitmap, context))
94+
} else {
95+
BitmapUtils.setRoundedBitmapAccordingToListType(arguments.isGrid, bitmap, view)
96+
}
97+
}
98+
9499
fun setOfflineOperationThumbnail(file: OCFile, view: ImageView) {
95100
if (file.isFolder) {
96101
view.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_folder_offline))
@@ -117,25 +122,6 @@ class FileThumbnailGenerator @Inject constructor(
117122
tasks.clear()
118123
}
119124

120-
private fun show(bitmap: Bitmap, file: OCFile, view: ImageView, arguments: ThumbnailArguments) {
121-
view.stopShimmer(arguments.shimmer)
122-
123-
if (MimeTypeUtil.isVideo(file) && !arguments.hideVideoOverlay) {
124-
view.setImageBitmap(file.withVideoOverlay(bitmap))
125-
} else {
126-
BitmapUtils.setRoundedBitmapAccordingToListType(arguments.isGrid, bitmap, view)
127-
}
128-
}
129-
130-
private fun OCFile.withVideoOverlay(thumbnail: Bitmap): Bitmap {
131-
val overlayKey = videoOverlayKey(getSmallThumbnailKey())
132-
ThumbnailMemoryCache.get(overlayKey)?.let { return it }
133-
134-
return ThumbnailsCacheManager.addVideoOverlay(thumbnail, context).also {
135-
ThumbnailMemoryCache.put(overlayKey, it)
136-
}
137-
}
138-
139125
private fun setLocalThumbnail(file: OCFile, view: ImageView, arguments: ThumbnailArguments) {
140126
val localFile = file.storagePath.toFile()
141127

@@ -159,12 +145,6 @@ class FileThumbnailGenerator @Inject constructor(
159145
return
160146
}
161147

162-
val cached = ThumbnailMemoryCache.get(file.getSmallThumbnailKey())
163-
if (cached != null) {
164-
show(cached, file, view, arguments)
165-
return
166-
}
167-
168148
tasks.removeIf { it.isCancelled || it.status == AsyncTask.Status.FINISHED }
169149

170150
startTask(
@@ -244,13 +224,15 @@ class FileThumbnailGenerator @Inject constructor(
244224

245225
private fun OCFile.mimeIcon(): Drawable? = MimeTypeUtil.getFileTypeIcon(mimeType, fileName, context, viewThemeUtils)
246226

247-
private fun OCFile.placeholder(): Bitmap {
248-
val drawable = mimeIcon()
249-
?: ResourcesCompat.getDrawable(context.resources, R.drawable.file_image, null)
250-
?: Color.GRAY.toDrawable()
251-
val size = ThumbnailsCacheManager.getThumbnailDimension()
227+
private fun OCFile.placeholder(): Bitmap = synchronized(placeholders) {
228+
placeholders.getOrPut(mimeType.orEmpty()) {
229+
val drawable = mimeIcon()
230+
?: ResourcesCompat.getDrawable(context.resources, R.drawable.file_image, null)
231+
?: Color.GRAY.toDrawable()
232+
val size = ThumbnailsCacheManager.getThumbnailDimension()
252233

253-
return BitmapUtils.drawableToBitmap(drawable, size, size)
234+
BitmapUtils.drawableToBitmap(drawable, size, size)
235+
}
254236
}
255237

256238
private fun applyPngBackground(file: ServerFileInterface, view: ImageView) {

0 commit comments

Comments
 (0)