diff --git a/app/src/main/kotlin/org/fossify/gallery/activities/VideoPlayerActivity.kt b/app/src/main/kotlin/org/fossify/gallery/activities/VideoPlayerActivity.kt
index f0750cbcd..40332906a 100644
--- a/app/src/main/kotlin/org/fossify/gallery/activities/VideoPlayerActivity.kt
+++ b/app/src/main/kotlin/org/fossify/gallery/activities/VideoPlayerActivity.kt
@@ -309,6 +309,18 @@ open class VideoPlayerActivity : SimpleActivity(), SeekBar.OnSeekBarChangeListen
mVideoSize.y = videoSize.height
setVideoSize()
}
+
+ override fun onPlayerErrorChanged(error: PlaybackException?) {
+ binding.errorMessageHolder.errorMessage.apply {
+ if (error != null) {
+ text = error.localizedMessage ?: getString(R.string.failed_to_load_media)
+ setTextColor(if (context.config.blackBackground) Color.WHITE else context.getProperTextColor())
+ fadeIn()
+ } else {
+ beGone()
+ }
+ }
+ }
})
}
diff --git a/app/src/main/kotlin/org/fossify/gallery/adapters/DirectoryAdapter.kt b/app/src/main/kotlin/org/fossify/gallery/adapters/DirectoryAdapter.kt
index 3810c0e28..b21841f9a 100644
--- a/app/src/main/kotlin/org/fossify/gallery/adapters/DirectoryAdapter.kt
+++ b/app/src/main/kotlin/org/fossify/gallery/adapters/DirectoryAdapter.kt
@@ -11,8 +11,10 @@ import android.view.Menu
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
+import android.widget.ImageView
import android.widget.RelativeLayout
import androidx.annotation.RequiresApi
+import androidx.appcompat.content.res.AppCompatResources
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.RecyclerView
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
@@ -820,14 +822,18 @@ class DirectoryAdapter(
}
activity.loadImage(
- thumbnailType,
- directory.tmb,
- dirThumbnail,
- scrollHorizontally,
- animateGifs,
- cropThumbnails,
- roundedCorners,
- directory.getKey()
+ type = thumbnailType,
+ path = directory.tmb,
+ target = dirThumbnail,
+ horizontalScroll = scrollHorizontally,
+ animateGifs = animateGifs,
+ cropThumbnails = cropThumbnails,
+ roundCorners = roundedCorners,
+ signature = directory.getKey(),
+ onError = {
+ dirThumbnail.scaleType = ImageView.ScaleType.CENTER
+ dirThumbnail.setImageDrawable(AppCompatResources.getDrawable(activity, R.drawable.ic_vector_warning_colored))
+ }
)
}
diff --git a/app/src/main/kotlin/org/fossify/gallery/adapters/MediaAdapter.kt b/app/src/main/kotlin/org/fossify/gallery/adapters/MediaAdapter.kt
index 5f681344f..06e132793 100644
--- a/app/src/main/kotlin/org/fossify/gallery/adapters/MediaAdapter.kt
+++ b/app/src/main/kotlin/org/fossify/gallery/adapters/MediaAdapter.kt
@@ -9,7 +9,9 @@ import android.os.Looper
import android.view.Menu
import android.view.View
import android.view.ViewGroup
+import android.widget.ImageView
import android.widget.Toast
+import androidx.appcompat.content.res.AppCompatResources
import androidx.core.view.allViews
import com.bumptech.glide.Glide
import com.qtalk.recyclerviewfastscroller.RecyclerViewFastScroller
@@ -681,7 +683,19 @@ class MediaAdapter(
if (loadImageInstantly) {
activity.loadImage(
- medium.type, path, mediumThumbnail, scrollHorizontally, animateGifs, cropThumbnails, roundedCorners, medium.getKey(), rotatedImagePaths
+ type = medium.type,
+ path = path,
+ target = mediumThumbnail,
+ horizontalScroll = scrollHorizontally,
+ animateGifs = animateGifs,
+ cropThumbnails = cropThumbnails,
+ roundCorners = roundedCorners,
+ signature = medium.getKey(),
+ skipMemoryCacheAtPaths = rotatedImagePaths,
+ onError = {
+ mediumThumbnail.scaleType = ImageView.ScaleType.CENTER
+ mediumThumbnail.setImageDrawable(AppCompatResources.getDrawable(activity, R.drawable.ic_vector_warning_colored))
+ }
)
} else {
mediumThumbnail.setImageDrawable(null)
@@ -690,8 +704,19 @@ class MediaAdapter(
val isVisible = visibleItemPaths.contains(medium.path)
if (isVisible) {
activity.loadImage(
- medium.type, path, mediumThumbnail, scrollHorizontally, animateGifs, cropThumbnails, roundedCorners,
- medium.getKey(), rotatedImagePaths
+ type = medium.type,
+ path = path,
+ target = mediumThumbnail,
+ horizontalScroll = scrollHorizontally,
+ animateGifs = animateGifs,
+ cropThumbnails = cropThumbnails,
+ roundCorners = roundedCorners,
+ signature = medium.getKey(),
+ skipMemoryCacheAtPaths = rotatedImagePaths,
+ onError = {
+ mediumThumbnail.scaleType = ImageView.ScaleType.CENTER
+ mediumThumbnail.setImageDrawable(AppCompatResources.getDrawable(activity, R.drawable.ic_vector_warning_colored))
+ }
)
}
}, IMAGE_LOAD_DELAY)
diff --git a/app/src/main/kotlin/org/fossify/gallery/extensions/Context.kt b/app/src/main/kotlin/org/fossify/gallery/extensions/Context.kt
index edac79d3e..335f28912 100644
--- a/app/src/main/kotlin/org/fossify/gallery/extensions/Context.kt
+++ b/app/src/main/kotlin/org/fossify/gallery/extensions/Context.kt
@@ -482,13 +482,29 @@ fun Context.loadImage(
roundCorners: Int,
signature: ObjectKey,
skipMemoryCacheAtPaths: ArrayList? = null,
+ onError: (() -> Unit)? = null
) {
target.isHorizontalScrolling = horizontalScroll
if (type == TYPE_SVGS) {
- loadSVG(path, target, cropThumbnails, roundCorners, signature)
+ loadSVG(
+ path = path,
+ target = target,
+ cropThumbnails = cropThumbnails,
+ roundCorners = roundCorners,
+ signature = signature
+ )
} else {
- val tryLoadingWithPicasso = type == TYPE_IMAGES && path.isPng()
- loadImageBase(path, target, cropThumbnails, roundCorners, signature, skipMemoryCacheAtPaths, animateGifs, tryLoadingWithPicasso)
+ loadImageBase(
+ path = path,
+ target = target,
+ cropThumbnails = cropThumbnails,
+ roundCorners = roundCorners,
+ signature = signature,
+ skipMemoryCacheAtPaths = skipMemoryCacheAtPaths,
+ animate = animateGifs,
+ tryLoadingWithPicasso = type == TYPE_IMAGES && path.isPng(),
+ onError = onError
+ )
}
}
@@ -524,6 +540,7 @@ fun Context.loadImageBase(
animate: Boolean = false,
tryLoadingWithPicasso: Boolean = false,
crossFadeDuration: Int = THUMBNAIL_FADE_DURATION_MS,
+ onError: (() -> Unit)? = null
) {
val options = RequestOptions()
.signature(signature)
@@ -571,24 +588,25 @@ fun Context.loadImageBase(
.set(WebpDownsampler.USE_SYSTEM_DECODER, false) // CVE-2023-4863
.transition(DrawableTransitionOptions.withCrossFade(crossFadeDuration))
- if (tryLoadingWithPicasso) {
- builder = builder.listener(object : RequestListener {
- override fun onLoadFailed(e: GlideException?, model: Any?, targetBitmap: Target, isFirstResource: Boolean): Boolean {
+ builder = builder.listener(object : RequestListener {
+ override fun onLoadFailed(e: GlideException?, model: Any?, targetBitmap: Target, isFirstResource: Boolean): Boolean {
+ if (tryLoadingWithPicasso) {
tryLoadingWithPicasso(path, target, cropThumbnails, roundCorners, signature)
- return true
+ } else {
+ onError?.invoke()
}
- override fun onResourceReady(
- resource: Drawable,
- model: Any,
- targetBitmap: Target,
- dataSource: DataSource,
- isFirstResource: Boolean,
- ): Boolean {
- return false
- }
- })
- }
+ return true
+ }
+
+ override fun onResourceReady(
+ resource: Drawable,
+ model: Any,
+ targetBitmap: Target,
+ dataSource: DataSource,
+ isFirstResource: Boolean,
+ ) = false
+ })
builder.into(target)
}
diff --git a/app/src/main/kotlin/org/fossify/gallery/fragments/PhotoFragment.kt b/app/src/main/kotlin/org/fossify/gallery/fragments/PhotoFragment.kt
index 8b483099f..c97d56290 100644
--- a/app/src/main/kotlin/org/fossify/gallery/fragments/PhotoFragment.kt
+++ b/app/src/main/kotlin/org/fossify/gallery/fragments/PhotoFragment.kt
@@ -518,6 +518,11 @@ class PhotoFragment : ViewPagerFragment() {
loadImage()
// TODO: Implement panorama using a FOSS library
// checkIfPanorama()
+ } else {
+ binding.errorMessageHolder.errorMessage.apply {
+ setTextColor(if (context.config.blackBackground) Color.WHITE else context.getProperTextColor())
+ fadeIn()
+ }
}
}
})
diff --git a/app/src/main/kotlin/org/fossify/gallery/fragments/VideoFragment.kt b/app/src/main/kotlin/org/fossify/gallery/fragments/VideoFragment.kt
index ab1c2452a..d224f9f80 100644
--- a/app/src/main/kotlin/org/fossify/gallery/fragments/VideoFragment.kt
+++ b/app/src/main/kotlin/org/fossify/gallery/fragments/VideoFragment.kt
@@ -2,6 +2,7 @@ package org.fossify.gallery.fragments
import android.annotation.SuppressLint
import android.content.res.Configuration
+import android.graphics.Color
import android.graphics.Point
import android.graphics.SurfaceTexture
import android.net.Uri
@@ -449,6 +450,20 @@ class VideoFragment : ViewPagerFragment(), TextureView.SurfaceTextureListener, S
mVideoSize.y = (videoSize.height / videoSize.pixelWidthHeightRatio).toInt()
setVideoSize()
}
+
+ override fun onPlayerErrorChanged(error: PlaybackException?) {
+ binding.errorMessageHolder.errorMessage.apply {
+ if (error != null) {
+ binding.videoPlayOutline.beGone()
+ text = error.localizedMessage ?: getString(R.string.failed_to_load_media)
+ setTextColor(if (context.config.blackBackground) Color.WHITE else context.getProperTextColor())
+ fadeIn()
+ } else {
+ beGone()
+ binding.videoPlayOutline.beVisible()
+ }
+ }
+ }
})
}
diff --git a/app/src/main/kotlin/org/fossify/gallery/helpers/MyGlideImageDecoder.kt b/app/src/main/kotlin/org/fossify/gallery/helpers/MyGlideImageDecoder.kt
index a5da7b2c1..84e6f445c 100644
--- a/app/src/main/kotlin/org/fossify/gallery/helpers/MyGlideImageDecoder.kt
+++ b/app/src/main/kotlin/org/fossify/gallery/helpers/MyGlideImageDecoder.kt
@@ -23,7 +23,7 @@ class MyGlideImageDecoder(val degrees: Int, val signature: ObjectKey) : ImageDec
.load(uri.toString().substringAfter("file://"))
.apply(options)
.transform(RotateTransformation(-degrees))
- .into(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL)
+ .submit(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL)
return builder.get()
}
diff --git a/app/src/main/res/drawable/ic_vector_warning_colored.xml b/app/src/main/res/drawable/ic_vector_warning_colored.xml
new file mode 100644
index 000000000..a83af2669
--- /dev/null
+++ b/app/src/main/res/drawable/ic_vector_warning_colored.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/activity_video_player.xml b/app/src/main/res/layout/activity_video_player.xml
index b57b0841f..4734329d4 100644
--- a/app/src/main/res/layout/activity_video_player.xml
+++ b/app/src/main/res/layout/activity_video_player.xml
@@ -50,6 +50,10 @@
android:id="@+id/bottom_video_time_holder"
layout="@layout/bottom_video_time_holder" />
+
+
+
diff --git a/app/src/main/res/layout/pager_photo_item.xml b/app/src/main/res/layout/pager_photo_item.xml
index 22f9f5da4..b4d908804 100644
--- a/app/src/main/res/layout/pager_photo_item.xml
+++ b/app/src/main/res/layout/pager_photo_item.xml
@@ -32,6 +32,10 @@
android:layout_height="match_parent"
android:visibility="gone" />
+
+
+
+
+ android:layout_height="match_parent"
+ tools:src="@mipmap/ic_launcher" />
+ android:layout_height="@dimen/list_view_folder_thumbnail_size"
+ tools:src="@mipmap/ic_launcher" />
Reorder folders by dragging (Pro)
Restoring to \'%s\'
Fossify Gallery needs full access to display all your photos and videos. Go to Settings > Permissions > Photos and videos > Allow all.
+ Failed to load media.
Filter media