Skip to content

Commit 4ec7532

Browse files
Addressed code review comments
1 parent da83646 commit 4ec7532

File tree

6 files changed

+60
-35
lines changed

6 files changed

+60
-35
lines changed

app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1473,6 +1473,7 @@ public void showLoading() {
14731473
CoilUtils.dispose(binding.detailThumbnailImageView);
14741474
CoilUtils.dispose(binding.detailSubChannelThumbnailView);
14751475
CoilUtils.dispose(binding.overlayThumbnail);
1476+
CoilUtils.dispose(binding.detailUploaderThumbnailView);
14761477

14771478
binding.detailThumbnailImageView.setImageBitmap(null);
14781479
binding.detailSubChannelThumbnailView.setImageBitmap(null);

app/src/main/java/org/schabi/newpipe/local/feed/notifications/NotificationHelper.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,7 @@ class NotificationHelper(val context: Context) {
7676

7777
summaryBuilder.setLargeIcon(avatarIcon)
7878

79-
// Show individual stream notifications, set channel icon only if there is actually
80-
// one
79+
// Show individual stream notifications, set channel icon only if there is actually one
8180
showStreamNotifications(newStreams, data.serviceId, avatarIcon)
8281
// Show summary notification
8382
manager.notify(data.pseudoId, summaryBuilder.build())

app/src/main/java/org/schabi/newpipe/player/Player.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,8 @@ public final class Player implements PlaybackListener, Listener {
192192
private MediaItemTag currentMetadata;
193193
@Nullable
194194
private Bitmap currentThumbnail;
195+
@Nullable
196+
private coil.request.Disposable thumbnailDisposable;
195197

196198
/*//////////////////////////////////////////////////////////////////////////
197199
// Player
@@ -772,6 +774,11 @@ private void loadCurrentThumbnail(final List<Image> thumbnails) {
772774
+ thumbnails.size() + "]");
773775
}
774776

777+
// Cancel any ongoing image loading
778+
if (thumbnailDisposable != null) {
779+
thumbnailDisposable.dispose();
780+
}
781+
775782
// Unset currentThumbnail, since it is now outdated. This ensures it is not used in media
776783
// session metadata while the new thumbnail is being loaded by Coil.
777784
onThumbnailLoaded(null);
@@ -780,7 +787,7 @@ private void loadCurrentThumbnail(final List<Image> thumbnails) {
780787
}
781788

782789
// scale down the notification thumbnail for performance
783-
final var target = new Target() {
790+
final var thumbnailTarget = new Target() {
784791
@Override
785792
public void onError(@Nullable final Drawable error) {
786793
Log.e(TAG, "Thumbnail - onError() called");
@@ -805,7 +812,8 @@ public void onSuccess(@NonNull final Drawable result) {
805812
result.getIntrinsicHeight(), null));
806813
}
807814
};
808-
CoilHelper.INSTANCE.loadScaledDownThumbnail(context, thumbnails, target);
815+
thumbnailDisposable = CoilHelper.INSTANCE
816+
.loadScaledDownThumbnail(context, thumbnails, thumbnailTarget);
809817
}
810818

811819
private void onThumbnailLoaded(@Nullable final Bitmap bitmap) {

app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,8 @@ public void onCreatePreferences(final Bundle savedInstanceState, final String ro
4242
ImageStrategy.setPreferredImageQuality(PreferredImageQuality
4343
.fromPreferenceKey(requireContext(), (String) newValue));
4444
final var loader = Coil.imageLoader(preference.getContext());
45-
if (loader.getMemoryCache() != null) {
46-
loader.getMemoryCache().clear();
47-
}
48-
if (loader.getDiskCache() != null) {
49-
loader.getDiskCache().clear();
50-
}
45+
loader.getMemoryCache().clear();
46+
loader.getDiskCache().clear();
5147
Toast.makeText(preference.getContext(),
5248
R.string.thumbnail_cache_wipe_complete_notice, Toast.LENGTH_SHORT)
5349
.show();

app/src/main/java/org/schabi/newpipe/util/external_communication/ShareUtils.java

Lines changed: 41 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import android.content.pm.PackageManager;
1111
import android.content.pm.ResolveInfo;
1212
import android.graphics.Bitmap;
13+
import android.graphics.BitmapFactory;
1314
import android.net.Uri;
1415
import android.os.Build;
1516
import android.text.TextUtils;
@@ -24,13 +25,16 @@
2425
import org.schabi.newpipe.BuildConfig;
2526
import org.schabi.newpipe.R;
2627
import org.schabi.newpipe.extractor.Image;
27-
import org.schabi.newpipe.util.image.CoilHelper;
2828
import org.schabi.newpipe.util.image.ImageStrategy;
2929

30-
import java.io.File;
31-
import java.io.FileOutputStream;
30+
import java.nio.file.Files;
31+
import java.util.Collections;
3232
import java.util.List;
3333

34+
import coil.Coil;
35+
import coil.disk.DiskCache;
36+
import coil.memory.MemoryCache;
37+
3438
public final class ShareUtils {
3539
private static final String TAG = ShareUtils.class.getSimpleName();
3640

@@ -335,7 +339,13 @@ public static void copyToClipboard(@NonNull final Context context, final String
335339
}
336340

337341
/**
338-
* Generate a {@link ClipData} with the image of the content shared.
342+
* Generate a {@link ClipData} with the image of the content shared, if it's in the app cache.
343+
*
344+
* <p>
345+
* In order not to worry about network issues (timeouts, DNS issues, low connection speed, ...)
346+
* when sharing a content, only images in the {@link MemoryCache} or {@link DiskCache}
347+
* used by the Coil library are used as preview images. If the thumbnail image is not in the
348+
* cache, no {@link ClipData} will be generated and {@code null} will be returned.
339349
*
340350
* <p>
341351
* In order to display the image in the content preview of the Android share sheet, an URI of
@@ -351,11 +361,6 @@ public static void copyToClipboard(@NonNull final Context context, final String
351361
* </p>
352362
*
353363
* <p>
354-
* This method will call {@link CoilHelper#loadBitmapBlocking(Context, String)} to get the
355-
* thumbnail of the content.
356-
* </p>
357-
*
358-
* <p>
359364
* Using the result of this method when sharing has only an effect on the system share sheet (if
360365
* OEMs didn't change Android system standard behavior) on Android API 29 and higher.
361366
* </p>
@@ -369,33 +374,46 @@ private static ClipData generateClipDataForImagePreview(
369374
@NonNull final Context context,
370375
@NonNull final String thumbnailUrl) {
371376
try {
372-
final var bitmap = CoilHelper.INSTANCE.loadBitmapBlocking(context, thumbnailUrl);
373-
if (bitmap == null) {
374-
return null;
375-
}
376-
377377
// Save the image in memory to the application's cache because we need a URI to the
378378
// image to generate a ClipData which will show the share sheet, and so an image file
379379
final Context applicationContext = context.getApplicationContext();
380-
final String appFolder = applicationContext.getCacheDir().getAbsolutePath();
381-
final File thumbnailPreviewFile = new File(appFolder
382-
+ "/android_share_sheet_image_preview.jpg");
380+
final var loader = Coil.imageLoader(context);
381+
final var value = loader.getMemoryCache()
382+
.get(new MemoryCache.Key(thumbnailUrl, Collections.emptyMap()));
383+
384+
final Bitmap cachedBitmap;
385+
if (value != null) {
386+
cachedBitmap = value.getBitmap();
387+
} else {
388+
try (var snapshot = loader.getDiskCache().openSnapshot(thumbnailUrl)) {
389+
if (snapshot != null) {
390+
cachedBitmap = BitmapFactory.decodeFile(snapshot.getData().toString());
391+
} else {
392+
cachedBitmap = null;
393+
}
394+
}
395+
}
396+
397+
if (cachedBitmap == null) {
398+
return null;
399+
}
383400

384-
// Any existing file will be overwritten with FileOutputStream
385-
final FileOutputStream fileOutputStream = new FileOutputStream(thumbnailPreviewFile);
386-
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fileOutputStream);
387-
fileOutputStream.close();
401+
final var path = applicationContext.getCacheDir().toPath()
402+
.resolve("android_share_sheet_image_preview.jpg");
403+
// Any existing file will be overwritten
404+
try (var outputStream = Files.newOutputStream(path)) {
405+
cachedBitmap.compress(Bitmap.CompressFormat.JPEG, 90, outputStream);
406+
}
388407

389408
final ClipData clipData = ClipData.newUri(applicationContext.getContentResolver(), "",
390409
FileProvider.getUriForFile(applicationContext,
391410
BuildConfig.APPLICATION_ID + ".provider",
392-
thumbnailPreviewFile));
411+
path.toFile()));
393412

394413
if (DEBUG) {
395414
Log.d(TAG, "ClipData successfully generated for Android share sheet: " + clipData);
396415
}
397416
return clipData;
398-
399417
} catch (final Exception e) {
400418
Log.w(TAG, "Error when setting preview image for share sheet", e);
401419
return null;

app/src/main/java/org/schabi/newpipe/util/image/CoilHelper.kt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import androidx.annotation.DrawableRes
88
import androidx.core.graphics.drawable.toBitmapOrNull
99
import coil.executeBlocking
1010
import coil.imageLoader
11+
import coil.request.Disposable
1112
import coil.request.ImageRequest
1213
import coil.size.Size
1314
import coil.target.Target
@@ -47,7 +48,7 @@ object CoilHelper {
4748
loadImageDefault(target, url, R.drawable.placeholder_thumbnail_video)
4849
}
4950

50-
fun loadScaledDownThumbnail(context: Context, images: List<Image>, target: Target) {
51+
fun loadScaledDownThumbnail(context: Context, images: List<Image>, target: Target): Disposable {
5152
val url = ImageStrategy.choosePreferredImage(images)
5253
val request = getImageRequest(context, url, R.drawable.placeholder_thumbnail_video)
5354
.target(target)
@@ -79,7 +80,7 @@ object CoilHelper {
7980
})
8081
.build()
8182

82-
context.imageLoader.enqueue(request)
83+
return context.imageLoader.enqueue(request)
8384
}
8485

8586
fun loadDetailsThumbnail(target: ImageView, images: List<Image>) {
@@ -133,6 +134,8 @@ object CoilHelper {
133134
return ImageRequest.Builder(context)
134135
.data(takenUrl)
135136
.error(placeholderResId)
137+
.memoryCacheKey(takenUrl)
138+
.diskCacheKey(takenUrl)
136139
.apply {
137140
if (takenUrl != null || showPlaceholderWhileLoading) {
138141
placeholder(placeholderResId)

0 commit comments

Comments
 (0)