Skip to content

Commit d820a8f

Browse files
committed
Uniform localizing view counts
1 parent c73d178 commit d820a8f

File tree

9 files changed

+80
-71
lines changed

9 files changed

+80
-71
lines changed

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
@@ -1377,14 +1377,9 @@ class VideoDetailFragment :
13771377
}
13781378

13791379
if (info.viewCount >= 0) {
1380-
binding.detailViewCountView.text =
1381-
if (info.streamType == StreamType.AUDIO_LIVE_STREAM) {
1382-
Localization.listeningCount(activity, info.viewCount)
1383-
} else if (info.streamType == StreamType.LIVE_STREAM) {
1384-
Localization.localizeWatchingCount(activity, info.viewCount)
1385-
} else {
1386-
Localization.localizeViewCount(activity, info.viewCount)
1387-
}
1380+
binding.detailViewCountView.text = Localization.localizeViewCount(
1381+
activity, false, info.streamType, info.viewCount
1382+
)
13881383
binding.detailViewCountView.visibility = View.VISIBLE
13891384
} else {
13901385
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
@@ -30,6 +30,7 @@
3030
import org.schabi.newpipe.extractor.localization.DateWrapper;
3131
import org.schabi.newpipe.extractor.stream.AudioStream;
3232
import org.schabi.newpipe.extractor.stream.AudioTrackType;
33+
import org.schabi.newpipe.extractor.stream.StreamType;
3334

3435
import java.math.BigDecimal;
3536
import java.math.RoundingMode;
@@ -142,9 +143,50 @@ public static String localizeUploadDate(@NonNull final Context context,
142143
return context.getString(R.string.upload_date_text, formatDate(offsetDateTime));
143144
}
144145

145-
public static String localizeViewCount(@NonNull final Context context, final long viewCount) {
146+
/**
147+
* Localizes the number of views of a stream reported by the service,
148+
* with different words based on the stream type.
149+
*
150+
* @param context the Android context
151+
* @param shortForm whether the number of views should be formatted in a short approximated form
152+
* @param streamType influences the accompanying text, i.e. views/watching/listening
153+
* @param viewCount the number of views reported by the service to localize
154+
* @return the formatted and localized view count
155+
*/
156+
public static String localizeViewCount(@NonNull final Context context,
157+
final boolean shortForm,
158+
@Nullable final StreamType streamType,
159+
final long viewCount) {
160+
final String localizedNumber;
161+
if (shortForm) {
162+
localizedNumber = shortCount(context, viewCount);
163+
} else {
164+
localizedNumber = localizeNumber(viewCount);
165+
}
166+
167+
if (streamType == StreamType.AUDIO_LIVE_STREAM) {
168+
return getQuantity(context, R.plurals.listening, R.string.no_one_listening, viewCount,
169+
localizedNumber);
170+
} else if (streamType == StreamType.LIVE_STREAM) {
171+
return getQuantity(context, R.plurals.watching, R.string.no_one_watching, viewCount,
172+
localizedNumber);
173+
} else {
174+
return getQuantity(context, R.plurals.views, R.string.no_views, viewCount,
175+
localizedNumber);
176+
}
177+
}
178+
179+
/**
180+
* Localizes the number of times the user watched a video that they have in the history.
181+
*
182+
* @param context the Android context
183+
* @param viewCount the number of times (stored in the database) the user watched a video
184+
* @return the formatted and localized watch count
185+
*/
186+
public static String localizeWatchCount(@NonNull final Context context,
187+
final long viewCount) {
146188
return getQuantity(context, R.plurals.views, R.string.no_views, viewCount,
147-
localizeNumber(viewCount));
189+
shortCount(context, viewCount));
148190
}
149191

150192
public static String localizeStreamCount(@NonNull final Context context,
@@ -176,12 +218,6 @@ public static String localizeStreamCountMini(@NonNull final Context context,
176218
}
177219
}
178220

179-
public static String localizeWatchingCount(@NonNull final Context context,
180-
final long watchingCount) {
181-
return getQuantity(context, R.plurals.watching, R.string.no_one_watching, watchingCount,
182-
localizeNumber(watchingCount));
183-
}
184-
185221
public static String shortCount(@NonNull final Context context, final long count) {
186222
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
187223
return CompactDecimalFormat.getInstance(getAppLocale(),
@@ -209,22 +245,6 @@ public static String shortCount(@NonNull final Context context, final long count
209245
}
210246
}
211247

212-
public static String listeningCount(@NonNull final Context context, final long listeningCount) {
213-
return getQuantity(context, R.plurals.listening, R.string.no_one_listening, listeningCount,
214-
shortCount(context, listeningCount));
215-
}
216-
217-
public static String shortWatchingCount(@NonNull final Context context,
218-
final long watchingCount) {
219-
return getQuantity(context, R.plurals.watching, R.string.no_one_watching, watchingCount,
220-
shortCount(context, watchingCount));
221-
}
222-
223-
public static String shortViewCount(@NonNull final Context context, final long viewCount) {
224-
return getQuantity(context, R.plurals.views, R.string.no_views, viewCount,
225-
shortCount(context, viewCount));
226-
}
227-
228248
public static String shortSubscriberCount(@NonNull final Context context,
229249
final long subscriberCount) {
230250
return getQuantity(context, R.plurals.subscribers, R.string.no_subscribers, subscriberCount,

0 commit comments

Comments
 (0)