Skip to content

Commit 6cb8767

Browse files
committed
Uniform localizing view counts
1 parent 2de8b09 commit 6cb8767

9 files changed

Lines changed: 80 additions & 71 deletions

File tree

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

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1379,14 +1379,9 @@ class VideoDetailFragment :
13791379
}
13801380

13811381
if (info.viewCount >= 0) {
1382-
binding.detailViewCountView.text =
1383-
if (info.streamType == StreamType.AUDIO_LIVE_STREAM) {
1384-
Localization.listeningCount(activity, info.viewCount)
1385-
} else if (info.streamType == StreamType.LIVE_STREAM) {
1386-
Localization.localizeWatchingCount(activity, info.viewCount)
1387-
} else {
1388-
Localization.localizeViewCount(activity, info.viewCount)
1389-
}
1382+
binding.detailViewCountView.text = Localization.localizeViewCount(
1383+
activity, false, info.streamType, info.viewCount
1384+
)
13901385
binding.detailViewCountView.visibility = View.VISIBLE
13911386
} else {
13921387
binding.detailViewCountView.visibility = View.GONE

app/src/main/java/org/schabi/newpipe/info_list/holder/StreamInfoItemHolder.java

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
import org.schabi.newpipe.R;
88
import org.schabi.newpipe.extractor.InfoItem;
99
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
10-
import org.schabi.newpipe.extractor.stream.StreamType;
1110
import org.schabi.newpipe.info_list.InfoItemBuilder;
1211
import org.schabi.newpipe.local.history.HistoryRecordManager;
1312
import org.schabi.newpipe.util.Localization;
@@ -65,16 +64,8 @@ public void updateFromItem(final InfoItem infoItem,
6564
private String getStreamInfoDetailLine(final StreamInfoItem infoItem) {
6665
String viewsAndDate = "";
6766
if (infoItem.getViewCount() >= 0) {
68-
if (infoItem.getStreamType().equals(StreamType.AUDIO_LIVE_STREAM)) {
69-
viewsAndDate = Localization
70-
.listeningCount(itemBuilder.getContext(), infoItem.getViewCount());
71-
} else if (infoItem.getStreamType().equals(StreamType.LIVE_STREAM)) {
72-
viewsAndDate = Localization
73-
.shortWatchingCount(itemBuilder.getContext(), infoItem.getViewCount());
74-
} else {
75-
viewsAndDate = Localization
76-
.shortViewCount(itemBuilder.getContext(), infoItem.getViewCount());
77-
}
67+
viewsAndDate = Localization.localizeViewCount(itemBuilder.getContext(), true,
68+
infoItem.getStreamType(), infoItem.getViewCount());
7869
}
7970

8071
final String uploadDate = Localization.relativeTimeOrTextual(itemBuilder.getContext(),

app/src/main/java/org/schabi/newpipe/local/feed/item/StreamItem.kt

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package org.schabi.newpipe.local.feed.item
22

33
import android.content.Context
4-
import android.text.TextUtils
54
import android.view.View
65
import androidx.core.content.ContextCompat
76
import androidx.preference.PreferenceManager
@@ -117,22 +116,16 @@ data class StreamItem(
117116
}
118117

119118
private fun getStreamInfoDetailLine(context: Context): String {
120-
var viewsAndDate = ""
121-
val viewCount = stream.viewCount
122-
if (viewCount != null && viewCount >= 0) {
123-
viewsAndDate = when (stream.streamType) {
124-
AUDIO_LIVE_STREAM -> Localization.listeningCount(context, viewCount)
125-
LIVE_STREAM -> Localization.shortWatchingCount(context, viewCount)
126-
else -> Localization.shortViewCount(context, viewCount)
127-
}
128-
}
119+
val views = stream.viewCount
120+
?.takeIf { it >= 0 }
121+
?.let { Localization.localizeViewCount(context, true, stream.streamType, it) }
122+
?: ""
123+
129124
val uploadDate = getFormattedRelativeUploadDate(context)
130125
return when {
131-
!TextUtils.isEmpty(uploadDate) -> when {
132-
viewsAndDate.isEmpty() -> uploadDate!!
133-
else -> Localization.concatenateStrings(viewsAndDate, uploadDate)
134-
}
135-
else -> viewsAndDate
126+
uploadDate.isNullOrEmpty() -> views
127+
views.isEmpty() -> uploadDate
128+
else -> Localization.concatenateStrings(views, uploadDate)
136129
}
137130
}
138131

app/src/main/java/org/schabi/newpipe/local/history/HistoryEntryAdapter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ protected String getFormattedDate(final Date date) {
5555
}
5656

5757
protected String getFormattedViewString(final long viewCount) {
58-
return Localization.shortViewCount(mContext, viewCount);
58+
return Localization.localizeWatchCount(mContext, viewCount);
5959
}
6060

6161
@Override

app/src/main/java/org/schabi/newpipe/local/holder/LocalStatisticStreamItemHolder.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ private String getStreamInfoDetailLine(final StreamStatisticsEntry entry,
7373
final DateTimeFormatter dateTimeFormatter) {
7474
return Localization.concatenateStrings(
7575
// watchCount
76-
Localization.shortViewCount(itemBuilder.getContext(), entry.getWatchCount()),
76+
Localization.localizeWatchCount(itemBuilder.getContext(), entry.getWatchCount()),
7777
dateTimeFormatter.format(entry.getLatestAccessDate()),
7878
// serviceName
7979
ServiceHelper.getNameOfServiceById(entry.getStreamEntity().getServiceId()));

app/src/main/java/org/schabi/newpipe/ui/components/items/stream/StreamUtils.kt

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -36,16 +36,10 @@ internal fun getStreamInfoDetail(stream: StreamInfoItem): String {
3636
val context = LocalContext.current
3737

3838
return rememberSaveable(stream) {
39-
val count = stream.viewCount
40-
val views = if (count >= 0) {
41-
when (stream.streamType) {
42-
StreamType.AUDIO_LIVE_STREAM -> Localization.listeningCount(context, count)
43-
StreamType.LIVE_STREAM -> Localization.shortWatchingCount(context, count)
44-
else -> Localization.shortViewCount(context, count)
45-
}
46-
} else {
47-
""
48-
}
39+
val views = stream.viewCount
40+
.takeIf { it >= 0 }
41+
?.let { Localization.localizeViewCount(context, true, stream.streamType, it) }
42+
?: ""
4943
val date =
5044
Localization.relativeTimeOrTextual(context, stream.uploadDate, stream.textualUploadDate)
5145

app/src/main/java/org/schabi/newpipe/ui/components/menu/LongPressMenu.kt

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ import androidx.compose.ui.tooling.preview.datasource.LoremIpsum
7272
import androidx.compose.ui.unit.dp
7373
import coil3.compose.AsyncImage
7474
import org.schabi.newpipe.R
75+
import org.schabi.newpipe.extractor.stream.StreamType
7576
import org.schabi.newpipe.ktx.popFirst
7677
import org.schabi.newpipe.ui.components.menu.LongPressAction.Type.EnqueueNext
7778
import org.schabi.newpipe.ui.components.menu.LongPressAction.Type.ShowChannelDetails
@@ -441,7 +442,9 @@ fun getSubtitleAnnotatedString(
441442
append(uploadDate)
442443
}
443444

444-
val viewCount = item.viewCount?.let { Localization.localizeViewCount(ctx, it) }
445+
val viewCount = item.viewCount?.let {
446+
Localization.localizeViewCount(ctx, true, item.streamType, it)
447+
}
445448
if (!viewCount.isNullOrBlank()) {
446449
if (shouldAddSeparator) {
447450
append(Localization.DOT_SEPARATOR)
@@ -545,6 +548,7 @@ private class LongPressablePreviews : CollectionPreviewParameterProvider<LongPre
545548
uploader = "Blender",
546549
uploaderUrl = "https://www.youtube.com/@BlenderOfficial",
547550
viewCount = 8765432,
551+
streamType = null,
548552
uploadDate = Either.left("16 years ago"),
549553
decoration = LongPressable.Decoration.Playlist(12),
550554
),
@@ -555,6 +559,7 @@ private class LongPressablePreviews : CollectionPreviewParameterProvider<LongPre
555559
uploader = "Blender",
556560
uploaderUrl = "https://www.youtube.com/@BlenderOfficial",
557561
viewCount = 8765432,
562+
streamType = StreamType.VIDEO_STREAM,
558563
uploadDate = Either.left("16 years ago"),
559564
decoration = LongPressable.Decoration.Duration(500),
560565
),
@@ -565,6 +570,7 @@ private class LongPressablePreviews : CollectionPreviewParameterProvider<LongPre
565570
uploader = null,
566571
uploaderUrl = "https://www.youtube.com/@BlenderOfficial",
567572
viewCount = null,
573+
streamType = null,
568574
uploadDate = null,
569575
decoration = null,
570576
),
@@ -575,6 +581,7 @@ private class LongPressablePreviews : CollectionPreviewParameterProvider<LongPre
575581
uploader = null,
576582
uploaderUrl = null,
577583
viewCount = null,
584+
streamType = StreamType.AUDIO_STREAM,
578585
uploadDate = null,
579586
decoration = LongPressable.Decoration.Duration(500),
580587
),
@@ -585,6 +592,7 @@ private class LongPressablePreviews : CollectionPreviewParameterProvider<LongPre
585592
uploader = null,
586593
uploaderUrl = null,
587594
viewCount = null,
595+
streamType = StreamType.LIVE_STREAM,
588596
uploadDate = null,
589597
decoration = LongPressable.Decoration.Live,
590598
),
@@ -595,6 +603,7 @@ private class LongPressablePreviews : CollectionPreviewParameterProvider<LongPre
595603
uploader = null,
596604
uploaderUrl = null,
597605
viewCount = null,
606+
streamType = StreamType.AUDIO_LIVE_STREAM,
598607
uploadDate = Either.right(OffsetDateTime.now().minusSeconds(12)),
599608
decoration = LongPressable.Decoration.Playlist(1500),
600609
),

app/src/main/java/org/schabi/newpipe/ui/components/menu/LongPressable.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ data class LongPressable(
2222
val uploader: String?,
2323
val uploaderUrl: String?,
2424
val viewCount: Long?,
25+
val streamType: StreamType?, // only used to format the view count properly
2526
val uploadDate: Either<String, OffsetDateTime>?,
2627
val decoration: Decoration?,
2728
) {
@@ -49,6 +50,7 @@ data class LongPressable(
4950
uploader = item.uploaderName?.takeIf { it.isNotBlank() },
5051
uploaderUrl = item.uploaderUrl?.takeIf { it.isNotBlank() },
5152
viewCount = item.viewCount.takeIf { it >= 0 },
53+
streamType = item.streamType,
5254
uploadDate = item.uploadDate?.let { Either.right(it.offsetDateTime()) }
5355
?: item.textualUploadDate?.let { Either.left(it) },
5456
decoration = Decoration.from(item.streamType, item.duration),
@@ -62,6 +64,7 @@ data class LongPressable(
6264
uploader = item.uploader.takeIf { it.isNotBlank() },
6365
uploaderUrl = item.uploaderUrl?.takeIf { it.isNotBlank() },
6466
viewCount = item.viewCount?.takeIf { it >= 0 },
67+
streamType = item.streamType,
6568
uploadDate = item.uploadDate?.let { Either.right(it) }
6669
?: item.textualUploadDate?.let { Either.left(it) },
6770
decoration = Decoration.from(item.streamType, item.duration),
@@ -76,6 +79,7 @@ data class LongPressable(
7679
uploader = null,
7780
uploaderUrl = null,
7881
viewCount = null,
82+
streamType = null,
7983
uploadDate = null,
8084
decoration = Decoration.Playlist(item.streamCount),
8185
)
@@ -88,6 +92,7 @@ data class LongPressable(
8892
uploader = item.uploader,
8993
uploaderUrl = null,
9094
viewCount = null,
95+
streamType = null,
9196
uploadDate = null,
9297
decoration = Decoration.Playlist(item.streamCount),
9398
)
@@ -100,6 +105,7 @@ data class LongPressable(
100105
uploader = null,
101106
uploaderUrl = item.url?.takeIf { it.isNotBlank() },
102107
viewCount = null,
108+
streamType = null,
103109
uploadDate = null,
104110
decoration = null,
105111
)
@@ -112,6 +118,7 @@ data class LongPressable(
112118
uploader = item.uploaderName.takeIf { it.isNotBlank() },
113119
uploaderUrl = item.uploaderUrl?.takeIf { it.isNotBlank() },
114120
viewCount = null,
121+
streamType = null,
115122
uploadDate = null,
116123
decoration = Decoration.Playlist(item.streamCount),
117124
)

app/src/main/java/org/schabi/newpipe/util/Localization.java

Lines changed: 44 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import org.schabi.newpipe.extractor.localization.DateWrapper;
3232
import org.schabi.newpipe.extractor.stream.AudioStream;
3333
import org.schabi.newpipe.extractor.stream.AudioTrackType;
34+
import org.schabi.newpipe.extractor.stream.StreamType;
3435

3536
import java.math.BigDecimal;
3637
import java.math.RoundingMode;
@@ -183,9 +184,50 @@ public static String localizeUploadDate(@NonNull final Context context,
183184
return context.getString(R.string.upload_date_text, formatDate(offsetDateTime));
184185
}
185186

186-
public static String localizeViewCount(@NonNull final Context context, final long viewCount) {
187+
/**
188+
* Localizes the number of views of a stream reported by the service,
189+
* with different words based on the stream type.
190+
*
191+
* @param context the Android context
192+
* @param shortForm whether the number of views should be formatted in a short approximated form
193+
* @param streamType influences the accompanying text, i.e. views/watching/listening
194+
* @param viewCount the number of views reported by the service to localize
195+
* @return the formatted and localized view count
196+
*/
197+
public static String localizeViewCount(@NonNull final Context context,
198+
final boolean shortForm,
199+
@Nullable final StreamType streamType,
200+
final long viewCount) {
201+
final String localizedNumber;
202+
if (shortForm) {
203+
localizedNumber = shortCount(context, viewCount);
204+
} else {
205+
localizedNumber = localizeNumber(viewCount);
206+
}
207+
208+
if (streamType == StreamType.AUDIO_LIVE_STREAM) {
209+
return getQuantity(context, R.plurals.listening, R.string.no_one_listening, viewCount,
210+
localizedNumber);
211+
} else if (streamType == StreamType.LIVE_STREAM) {
212+
return getQuantity(context, R.plurals.watching, R.string.no_one_watching, viewCount,
213+
localizedNumber);
214+
} else {
215+
return getQuantity(context, R.plurals.views, R.string.no_views, viewCount,
216+
localizedNumber);
217+
}
218+
}
219+
220+
/**
221+
* Localizes the number of times the user watched a video that they have in the history.
222+
*
223+
* @param context the Android context
224+
* @param viewCount the number of times (stored in the database) the user watched a video
225+
* @return the formatted and localized watch count
226+
*/
227+
public static String localizeWatchCount(@NonNull final Context context,
228+
final long viewCount) {
187229
return getQuantity(context, R.plurals.views, R.string.no_views, viewCount,
188-
localizeNumber(viewCount));
230+
shortCount(context, viewCount));
189231
}
190232

191233
public static String localizeStreamCount(@NonNull final Context context,
@@ -217,12 +259,6 @@ public static String localizeStreamCountMini(@NonNull final Context context,
217259
}
218260
}
219261

220-
public static String localizeWatchingCount(@NonNull final Context context,
221-
final long watchingCount) {
222-
return getQuantity(context, R.plurals.watching, R.string.no_one_watching, watchingCount,
223-
localizeNumber(watchingCount));
224-
}
225-
226262
public static String shortCount(@NonNull final Context context, final long count) {
227263
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
228264
return CompactDecimalFormat.getInstance(getAppLocale(),
@@ -250,22 +286,6 @@ public static String shortCount(@NonNull final Context context, final long count
250286
}
251287
}
252288

253-
public static String listeningCount(@NonNull final Context context, final long listeningCount) {
254-
return getQuantity(context, R.plurals.listening, R.string.no_one_listening, listeningCount,
255-
shortCount(context, listeningCount));
256-
}
257-
258-
public static String shortWatchingCount(@NonNull final Context context,
259-
final long watchingCount) {
260-
return getQuantity(context, R.plurals.watching, R.string.no_one_watching, watchingCount,
261-
shortCount(context, watchingCount));
262-
}
263-
264-
public static String shortViewCount(@NonNull final Context context, final long viewCount) {
265-
return getQuantity(context, R.plurals.views, R.string.no_views, viewCount,
266-
shortCount(context, viewCount));
267-
}
268-
269289
public static String shortSubscriberCount(@NonNull final Context context,
270290
final long subscriberCount) {
271291
return getQuantity(context, R.plurals.subscribers, R.string.no_subscribers, subscriberCount,

0 commit comments

Comments
 (0)