Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
85 commits
Select commit Hold shift + click to select a range
e6daf45
[DescriptionFragment] Fix thumbnail size: width x height
TobiGr Feb 6, 2026
e358867
Use dedicated constants for unknown image dimensions in ImageStrategy
TobiGr Feb 7, 2026
9a292e3
Translated using Weblate (Albanian)
weblate Feb 22, 2026
06e4548
Add warning banner about ongoing google certification for android apps
Feb 22, 2026
195a76b
Correctly retrieve menu item inside download dialog
Feb 25, 2026
dd65db5
Merge pull request #13290 from dustdfg/correct_download_fragment
TobiGr Feb 25, 2026
66237ab
KeepAndroidOpen: Choose website language from list of supported langu…
TobiGr Feb 26, 2026
9f1e2c6
Merge pull request #13282 from dustdfg/keep_android_open
TobiGr Feb 26, 2026
042f946
Don't show Keep Android Open popup on debug builds
Feb 26, 2026
56fb31d
Merge pull request #13292 from dustdfg/kao_release_only
Stypox Feb 26, 2026
e22b046
Fix inconsistency in getQuantity and add docs
Stypox Feb 26, 2026
bf16332
Merge pull request #13293 from TeamNewPipe/getQuantity-inconsistency
TobiGr Feb 26, 2026
6dddcf3
Translated using Weblate (French)
weblate Feb 28, 2026
98a883d
Update NewPipe Extractor to 0.26.0
TobiGr Feb 22, 2026
8b500c7
Add changelog for NewPipe 0.28.4 (1009)
TobiGr Feb 22, 2026
1fbf9fc
Bump version to 0.28.4 (1009)
TobiGr Feb 22, 2026
0020a02
Apply suggestion
Mar 2, 2026
0cdf40c
Merge pull request #13298 from dustdfg/shareutils_kao
Stypox Mar 2, 2026
8fa6f96
Apply suggestion
Mar 2, 2026
e6e5fc7
Merge pull request #13299 from TeamNewPipe/backport-13298-to-release-…
Stypox Mar 2, 2026
9f45aa5
Remove freedroidwarn license
Mar 4, 2026
e173bf4
Add Sign in confirm not a bot issue URL to the exception error message
absurdlylongusername Mar 6, 2026
b8ec9bf
Maybe this fix ktlint errors?
absurdlylongusername Mar 6, 2026
dda219a
Translated using Weblate (Latvian)
weblate Mar 6, 2026
d497f1d
Translated using Weblate (Latvian)
weblate Mar 6, 2026
521f60a
Change URL to FAQ
absurdlylongusername Mar 7, 2026
3b3348e
Change to FAQ entry instead
absurdlylongusername Mar 7, 2026
47624a5
Complete sentence.
TobiGr Mar 8, 2026
816f5f9
Translated using Weblate (Vietnamese)
weblate Mar 8, 2026
05f09c9
Merge pull request #13310 from absurdlylongusername/add-issue-url-sig…
TobiGr Mar 8, 2026
d5f941f
Translated using Weblate (Vietnamese)
weblate Mar 8, 2026
dc2e4aa
Add Sign in confirm not a bot issue URL to the exception error message
absurdlylongusername Mar 6, 2026
d9fd1bf
Maybe this fix ktlint errors?
absurdlylongusername Mar 6, 2026
93f9a52
Change URL to FAQ
absurdlylongusername Mar 7, 2026
7c88f06
Change to FAQ entry instead
absurdlylongusername Mar 7, 2026
54021a9
Complete sentence.
TobiGr Mar 8, 2026
675d156
Merge pull request #13324 from TeamNewPipe/backport-13310-to-release-…
TobiGr Mar 8, 2026
21b37b5
Merge pull request #13296 from TeamNewPipe/release-0.28.4
TobiGr Mar 8, 2026
79767f9
Merge branch 'master' into dev
TobiGr Mar 8, 2026
9cc6f9f
Merge pull request #13305 from dustdfg/remove_freedroid_license
theimpulson Mar 15, 2026
0d65733
Merge pull request #13207 from TobiGr/small-fixes
theimpulson Mar 15, 2026
6fa97e1
subscription: Port subscription import-export to workers from refactor
theimpulson Mar 15, 2026
bfcc31e
BackupRestoreSettingsFragment: add UI options to import/export subscr…
evermind-zz Feb 13, 2026
668af4f
Merge pull request #13347 from theimpulson/subscriptions
theimpulson Mar 16, 2026
223b240
Refactor zip import/export using Path
Isira-Seneviratne Jul 7, 2025
ebb9379
Fix DB import/export issue
Isira-Seneviratne Jul 7, 2025
71a3bf2
Use InputStream#transferTo()
Isira-Seneviratne Jul 7, 2025
aba2a38
Inline variable
Isira-Seneviratne Jul 8, 2025
5f1a270
Fix database import
Isira-Seneviratne Aug 25, 2025
f1c608b
Merge pull request #13352 from theimpulson/path
theimpulson Mar 18, 2026
3490008
Update dependencies and Gradle to latest stable release
theimpulson Mar 18, 2026
515bb6e
Merge pull request #13363 from theimpulson/depUpdate
TobiGr Mar 18, 2026
fbf3b7a
Translated using Weblate (Galician)
weblate Mar 27, 2026
831425a
Deleted translation using Weblate (Arabic (Najdi))
TobiGr Mar 27, 2026
08326c6
Deleted translation using Weblate (English (Middle))
TobiGr Mar 27, 2026
2fec3a3
Deleted translation using Weblate (English (Old))
TobiGr Mar 27, 2026
3f8d26d
Deleted translation using Weblate (German (Low))
TobiGr Mar 27, 2026
fa6412a
Deleted translation using Weblate (French (Louisiana))
TobiGr Mar 27, 2026
179a713
Deleted translation using Weblate (Arabic (Tunisian))
TobiGr Mar 27, 2026
80a47be
Deleted translation using Weblate (Gaelic)
TobiGr Mar 27, 2026
db61af1
Deleted translation using Weblate (Corsican)
TobiGr Mar 27, 2026
b0f2d50
Deleted translation using Weblate (Romany)
TobiGr Mar 27, 2026
cf0d701
Deleted translation using Weblate (Yiddish)
TobiGr Mar 27, 2026
3112eef
Deleted translation using Weblate (Luri (Bakhtiari))
TobiGr Mar 27, 2026
2dda392
Deleted translation using Weblate (Aymara)
TobiGr Mar 27, 2026
09c9615
Deleted translation using Weblate (Sicilian)
TobiGr Mar 27, 2026
af08ddc
Deleted translation using Weblate (Kashmiri)
TobiGr Mar 27, 2026
949f0f3
Deleted translation using Weblate (Azerbaijani (Southern))
TobiGr Mar 27, 2026
f8c9ab8
Deleted translation using Weblate (Azerbaijani (Southern))
TobiGr Mar 27, 2026
6d50fe7
Deleted translation using Weblate (Mainfränkisch)
TobiGr Mar 27, 2026
75ba70a
Deleted translation using Weblate (Aymara (Southern))
TobiGr Mar 27, 2026
da76ddb
Remove French (Lousiana) frc from app locales
TobiGr Mar 27, 2026
07a2ab2
Fix NullPointerException in enqueue actions by using Application Context
arjun1194 Mar 28, 2026
b7c339c
Merge pull request #13382 from TeamNewPipe/weblate
theimpulson Mar 29, 2026
50e8189
Merge pull request #13385 from arjun1194/fix/use-application-context-…
TobiGr Mar 29, 2026
db8edd3
Fix SecurityException when opening downloaded files in other app
TobiGr Mar 29, 2026
3aa74f1
Update extractor to latest commit
litetex Apr 8, 2026
2f14473
Merge pull request #13403 from litetex/update-extractor
TobiGr Apr 8, 2026
df6ec44
Translated using Weblate (Polish)
weblate Apr 10, 2026
0ce141f
Add changelog for NewPipe 0.28.5 (1010)
TobiGr Apr 10, 2026
148b6f7
Update NewPipe Extractor to v0.26.1
TobiGr Apr 10, 2026
24abbb8
Translated using Weblate (Chinese (Simplified Han script))
weblate Apr 10, 2026
1ce1dbe
Bump NewPipe version to 0.28.5 (1010)
TobiGr Apr 10, 2026
3e297fd
Merge pull request #13391 from TobiGr/fix/downloaderPermission
TobiGr Apr 14, 2026
53d8d4d
Merge branch 'dev' into refactor
theimpulson Apr 14, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,9 @@ configure<ApplicationExtension> {
minSdk = 23
targetSdk = 35

versionCode = System.getProperty("versionCodeOverride")?.toInt() ?: 1008
versionCode = System.getProperty("versionCodeOverride")?.toInt() ?: 1010

versionName = "0.28.3"
versionName = "0.28.5"
System.getProperty("versionNameSuffix")?.let { versionNameSuffix = it }

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
Expand Down
15 changes: 15 additions & 0 deletions app/proguard-rules.pro
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,18 @@
-keepclassmembers class * extends com.google.protobuf.GeneratedMessageLite {
<fields>;
}

## Keep Kotlinx Serialization classes
-keepclassmembers class kotlinx.serialization.json.** {
*** Companion;
}
-keepclasseswithmembers class kotlinx.serialization.json.** {
kotlinx.serialization.KSerializer serializer(...);
}
-keep,includedescriptorclasses class org.schabi.newpipe.**$$serializer { *; }
-keepclassmembers class org.schabi.newpipe.** {
*** Companion;
}
-keepclasseswithmembers class org.schabi.newpipe.** {
kotlinx.serialization.KSerializer serializer(...);
}
62 changes: 62 additions & 0 deletions app/src/main/java/org/schabi/newpipe/MainActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

package org.schabi.newpipe;

import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
Expand Down Expand Up @@ -92,6 +93,8 @@
import org.schabi.newpipe.util.external_communication.ShareUtils;
import org.schabi.newpipe.views.FocusOverlayView;

import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
Expand Down Expand Up @@ -192,6 +195,12 @@ protected void onCreate(final Bundle savedInstanceState) {
UpdateSettingsFragment.askForConsentToUpdateChecks(this);
}

// ReleaseVersionUtil.INSTANCE.isReleaseApk() will be true only for main official build
// We want every release build (nightly, nightly-refactor) to show the popup
if (!DEBUG) {
showKeepAndroidDialog();
}

MigrationManager.showUserInfoIfPresent(this);
}

Expand Down Expand Up @@ -889,4 +898,57 @@ private boolean bottomSheetHiddenOrCollapsed() {
|| sheetState == BottomSheetBehavior.STATE_COLLAPSED;
}

private void showKeepAndroidDialog() {
final var prefs = PreferenceManager.getDefaultSharedPreferences(this);

final var now = Instant.now();
final var kaoLastCheck = Instant.ofEpochMilli(prefs.getLong(
getString(R.string.kao_last_checked_key),
0
));

final var supportedLannguages = List.of("fr", "de", "ca", "es", "id", "it", "pl",
"pt", "cs", "sk", "fa", "ar", "tr", "el", "th", "ru", "uk", "ko", "zh", "ja");
final var locale = Localization.getAppLocale();
final String kaoBaseUrl = "https://keepandroidopen.org/";
final String kaoURI;
if (supportedLannguages.contains(locale.getLanguage())) {
if ("zh".equals(locale.getLanguage())) {
kaoURI = kaoBaseUrl + ("TW".equals(locale.getCountry()) ? "zh-TW" : "zh-CN");
} else {
kaoURI = kaoBaseUrl + locale.getLanguage();
}
} else {
kaoURI = kaoBaseUrl;
}
final var solutionURI =
"https://github.com/woheller69/FreeDroidWarn?tab=readme-ov-file#solutions";

if (kaoLastCheck.plus(30, ChronoUnit.DAYS).isBefore(now)) {
final var dialog = new AlertDialog.Builder(this)
.setTitle("Keep Android Open")
.setCancelable(false)
.setMessage(this.getString(R.string.kao_dialog_warning))
.setPositiveButton(this.getString(android.R.string.ok), (d, w) -> {
prefs.edit()
.putLong(
getString(R.string.kao_last_checked_key),
now.toEpochMilli()
)
.apply();
})
.setNeutralButton(this.getString(R.string.kao_solution), null)
.setNegativeButton(this.getString(R.string.kao_dialog_more_info), null)
.show();

// If we use setNeutralButton and etc. dialog will close after pressing the buttons,
// but we want it to close only when positive button is pressed
dialog.getButton(AlertDialog.BUTTON_NEGATIVE).setOnClickListener(v ->
ShareUtils.openUrlInBrowser(this, kaoURI)
);
dialog.getButton(AlertDialog.BUTTON_NEUTRAL).setOnClickListener(v ->
ShareUtils.openUrlInBrowser(this, solutionURI)
);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ private void initToolbar(final Toolbar toolbar) {
toolbar.setNavigationOnClickListener(v -> dismiss());
toolbar.setNavigationContentDescription(R.string.cancel);

okButton = toolbar.findViewById(R.id.okay);
okButton = toolbar.getMenu().findItem(R.id.okay);
okButton.setEnabled(false); // disable until the download service connection is done

toolbar.setOnMenuItemClickListener(item -> {
Expand Down
3 changes: 2 additions & 1 deletion app/src/main/java/org/schabi/newpipe/error/ErrorActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import org.schabi.newpipe.databinding.ActivityErrorBinding
import org.schabi.newpipe.util.Localization
import org.schabi.newpipe.util.ThemeHelper
import org.schabi.newpipe.util.external_communication.ShareUtils
import org.schabi.newpipe.util.text.setTextWithLinks

/**
* This activity is used to show error details and allow reporting them in various ways.
Expand Down Expand Up @@ -100,7 +101,7 @@ class ErrorActivity : AppCompatActivity() {

// normal bugreport
buildInfo(errorInfo)
binding.errorMessageView.text = errorInfo.getMessage(this)
binding.errorMessageView.setTextWithLinks(errorInfo.getMessage(this))
binding.errorView.text = formErrorText(errorInfo.stackTraces)

// print stack trace once again for debugging:
Expand Down
26 changes: 18 additions & 8 deletions app/src/main/java/org/schabi/newpipe/error/ErrorInfo.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package org.schabi.newpipe.error
import android.content.Context
import android.os.Parcelable
import androidx.annotation.StringRes
import androidx.core.content.ContextCompat
import com.google.android.exoplayer2.ExoPlaybackException
import com.google.android.exoplayer2.upstream.HttpDataSource
import com.google.android.exoplayer2.upstream.Loader
Expand All @@ -28,7 +29,7 @@ import org.schabi.newpipe.extractor.exceptions.YoutubeMusicPremiumContentExcepti
import org.schabi.newpipe.ktx.isNetworkRelated
import org.schabi.newpipe.player.mediasource.FailedMediaSource
import org.schabi.newpipe.player.resolver.PlaybackResolver
import org.schabi.newpipe.util.Localization
import org.schabi.newpipe.util.text.getText

/**
* An error has occurred in the app. This class contains plain old parcelable data that can be used
Expand Down Expand Up @@ -135,8 +136,8 @@ class ErrorInfo private constructor(
return getServiceName(serviceId)
}

fun getMessage(context: Context): String {
return message.getString(context)
fun getMessage(context: Context): CharSequence {
return message.getText(context)
}

companion object {
Expand All @@ -146,18 +147,23 @@ class ErrorInfo private constructor(
private val stringRes: Int,
private vararg val formatArgs: String
) : Parcelable {
fun getString(context: Context): String {
// use Localization.compatGetString() just in case context is not AppCompatActivity
fun getText(context: Context): CharSequence {
// Ensure locale aware context via ContextCompat.getContextForLanguage() (just in case context is not AppCompatActivity)
val ctx = ContextCompat.getContextForLanguage(context)
return if (formatArgs.isEmpty()) {
Localization.compatGetString(context, stringRes)
ctx.getText(stringRes)
} else {
Localization.compatGetString(context, stringRes, *formatArgs)
// ContextCompat.getString() with formatArgs does not exist, so we just
// replicate its source code but with formatArgs
ctx.resources.getText(stringRes, *formatArgs)
}
}
}

const val SERVICE_NONE = "<unknown_service>"

const val YOUTUBE_IP_BAN_FAQ_URL = "https://newpipe.net/FAQ/#ip-banned-youtube"

private fun getServiceName(serviceId: Int?) = // not using getNameOfServiceById since we want to accept a nullable serviceId and we
// want to default to SERVICE_NONE
ServiceList.all()?.firstOrNull { it.serviceId == serviceId }?.serviceInfo?.name
Expand Down Expand Up @@ -245,7 +251,11 @@ class ErrorInfo private constructor(
ErrorMessage(R.string.youtube_music_premium_content)

throwable is SignInConfirmNotBotException ->
ErrorMessage(R.string.sign_in_confirm_not_bot_error, getServiceName(serviceId))
ErrorMessage(
R.string.sign_in_confirm_not_bot_error,
getServiceName(serviceId),
YOUTUBE_IP_BAN_FAQ_URL
)

throwable is ContentNotAvailableException ->
ErrorMessage(R.string.content_not_available)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import org.schabi.newpipe.MainActivity
import org.schabi.newpipe.R
import org.schabi.newpipe.ktx.animate
import org.schabi.newpipe.util.external_communication.ShareUtils
import org.schabi.newpipe.util.text.setTextWithLinks

class ErrorPanelHelper(
private val fragment: Fragment,
Expand Down Expand Up @@ -64,7 +65,7 @@ class ErrorPanelHelper(

fun showError(errorInfo: ErrorInfo) {
ensureDefaultVisibility()
errorTextView.text = errorInfo.getMessage(context)
errorTextView.setTextWithLinks(errorInfo.getMessage(context))

if (errorInfo.recaptchaUrl != null) {
showAndSetErrorButtonAction(R.string.recaptcha_solve) {
Expand Down Expand Up @@ -109,7 +110,7 @@ class ErrorPanelHelper(
fun showTextError(errorString: String) {
ensureDefaultVisibility()

errorTextView.text = errorString
errorTextView.setTextWithLinks(errorString)

setRootVisible()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -216,9 +216,9 @@ protected void addImagesMetadataItem(final LayoutInflater inflater,
|| image.getWidth() != Image.WIDTH_UNKNOWN
// if even the resolution level is unknown, ?x? will be shown
|| image.getEstimatedResolutionLevel() == Image.ResolutionLevel.UNKNOWN) {
urls.append(imageSizeToText(image.getHeight()));
urls.append('x');
urls.append(imageSizeToText(image.getWidth()));
urls.append('x');
urls.append(imageSizeToText(image.getHeight()));
} else {
switch (image.getEstimatedResolutionLevel()) {
case LOW -> urls.append(getString(R.string.image_quality_low));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import static org.schabi.newpipe.util.SparseItemUtil.fetchStreamInfoAndSaveToDatabase;
import static org.schabi.newpipe.util.SparseItemUtil.fetchUploaderUrlIfSparse;

import android.content.Context;
import android.net.Uri;

import androidx.annotation.NonNull;
Expand Down Expand Up @@ -53,28 +54,33 @@ public enum StreamDialogDefaultEntry {
/**
* Enqueues the stream automatically to the current PlayerType.
*/
ENQUEUE(R.string.enqueue_stream, (fragment, item) ->
fetchItemInfoIfSparse(fragment.requireContext(), item, singlePlayQueue ->
NavigationHelper.enqueueOnPlayer(fragment.getContext(), singlePlayQueue))
),
ENQUEUE(R.string.enqueue_stream, (fragment, item) -> {
final Context ctx = fragment.requireContext().getApplicationContext();
fetchItemInfoIfSparse(ctx, item, singlePlayQueue ->
NavigationHelper.enqueueOnPlayer(ctx, singlePlayQueue));
}),

/**
* Enqueues the stream automatically to the current PlayerType
* after the currently playing stream.
*/
ENQUEUE_NEXT(R.string.enqueue_next_stream, (fragment, item) ->
fetchItemInfoIfSparse(fragment.requireContext(), item, singlePlayQueue ->
NavigationHelper.enqueueNextOnPlayer(fragment.getContext(), singlePlayQueue))
),
ENQUEUE_NEXT(R.string.enqueue_next_stream, (fragment, item) -> {
final Context ctx = fragment.requireContext().getApplicationContext();
fetchItemInfoIfSparse(ctx, item, singlePlayQueue ->
NavigationHelper.enqueueNextOnPlayer(ctx, singlePlayQueue));
}),

START_HERE_ON_BACKGROUND(R.string.start_here_on_background, (fragment, item) ->
fetchItemInfoIfSparse(fragment.requireContext(), item, singlePlayQueue ->
NavigationHelper.playOnBackgroundPlayer(
fragment.getContext(), singlePlayQueue, true))),
START_HERE_ON_BACKGROUND(R.string.start_here_on_background, (fragment, item) -> {
final Context ctx = fragment.requireContext().getApplicationContext();
fetchItemInfoIfSparse(ctx, item, singlePlayQueue ->
NavigationHelper.playOnBackgroundPlayer(ctx, singlePlayQueue, true));
}),

START_HERE_ON_POPUP(R.string.start_here_on_popup, (fragment, item) ->
fetchItemInfoIfSparse(fragment.requireContext(), item, singlePlayQueue ->
NavigationHelper.playOnPopupPlayer(fragment.getContext(), singlePlayQueue, true))),
START_HERE_ON_POPUP(R.string.start_here_on_popup, (fragment, item) -> {
final Context ctx = fragment.requireContext().getApplicationContext();
fetchItemInfoIfSparse(ctx, item, singlePlayQueue ->
NavigationHelper.playOnPopupPlayer(ctx, singlePlayQueue, true));
}),

SET_AS_PLAYLIST_THUMBNAIL(R.string.set_as_playlist_thumbnail, (fragment, item) -> {
throw new UnsupportedOperationException("This needs to be implemented manually "
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ import org.schabi.newpipe.util.NavigationHelper
*/
class MediaBrowserPlaybackPreparer(
private val context: Context,
private val setMediaSessionError: BiConsumer<String, Int>, // error string, error code
private val setMediaSessionError: BiConsumer<CharSequence, Int>, // error string, error code
private val clearMediaSessionError: Runnable,
private val onPrepare: Consumer<Boolean>
) : PlaybackPreparer {
Expand Down Expand Up @@ -118,7 +118,7 @@ class MediaBrowserPlaybackPreparer(

private fun onPrepareError(throwable: Throwable) {
setMediaSessionError.accept(
ErrorInfo.getMessage(throwable, null, null).getString(context),
ErrorInfo.getMessage(throwable, null, null).getText(context),
PlaybackStateCompat.ERROR_CODE_APP_ERROR
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ fun ErrorPanel(
modifier = modifier
) {
Text(
text = messageText,
text = messageText.toString(),
style = MaterialTheme.typography.titleMedium.copy(fontWeight = FontWeight.Bold),
textAlign = TextAlign.Center
)
Expand Down
14 changes: 13 additions & 1 deletion app/src/main/java/org/schabi/newpipe/util/Localization.java
Original file line number Diff line number Diff line change
Expand Up @@ -462,12 +462,24 @@ private static double round(final double value, final int scale) {
return new BigDecimal(value).setScale(scale, RoundingMode.HALF_UP).doubleValue();
}

/**
* A wrapper around {@code context.getResources().getQuantityString()} with some safeguard.
*
* @param context the Android context
* @param pluralId the ID of the plural resource
* @param zeroCaseStringId the resource ID of the string to use in case {@code count=0},
* or 0 if the plural resource should be used in the zero case too
* @param count the number that should be used to pick the correct plural form
* @param formattedCount the formatting parameter to substitute inside the plural resource,
* ideally just {@code count} converted to string
* @return the formatted string with the correct pluralization
*/
private static String getQuantity(@NonNull final Context context,
@PluralsRes final int pluralId,
@StringRes final int zeroCaseStringId,
final long count,
final String formattedCount) {
if (count == 0) {
if (count == 0 && zeroCaseStringId != 0) {
return context.getString(zeroCaseStringId);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,15 @@ object ImageStrategy {
fun dbUrlToImageList(url: String?): List<Image> {
return when (url) {
null -> listOf()
else -> listOf(Image(url, -1, -1, ResolutionLevel.UNKNOWN))

else -> listOf(
Image(
url,
Image.HEIGHT_UNKNOWN,
Image.WIDTH_UNKNOWN,
ResolutionLevel.UNKNOWN
)
)
}
}
}
Loading
Loading