Extract some utility methods from CommentInfoItemHolder

This commit is contained in:
Stypox 2023-04-12 10:54:03 +02:00
parent 4b6392df54
commit ad68f784ae
No known key found for this signature in database
GPG Key ID: 4BDF1B40A49FDD23
5 changed files with 80 additions and 81 deletions

View File

@ -1,12 +1,12 @@
package org.schabi.newpipe.info_list.holder; package org.schabi.newpipe.info_list.holder;
import static android.text.TextUtils.isEmpty; import static android.text.TextUtils.isEmpty;
import static org.schabi.newpipe.util.ServiceHelper.getServiceById;
import android.graphics.Paint; import android.graphics.Paint;
import android.text.Layout; import android.text.Layout;
import android.text.method.LinkMovementMethod; import android.text.method.LinkMovementMethod;
import android.text.style.URLSpan; import android.text.style.URLSpan;
import android.util.Log;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.Button; import android.widget.Button;
@ -15,21 +15,15 @@ import android.widget.RelativeLayout;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.text.HtmlCompat; import androidx.core.text.HtmlCompat;
import androidx.fragment.app.FragmentActivity;
import org.schabi.newpipe.MainActivity;
import org.schabi.newpipe.R; import org.schabi.newpipe.R;
import org.schabi.newpipe.error.ErrorUtil;
import org.schabi.newpipe.extractor.InfoItem; import org.schabi.newpipe.extractor.InfoItem;
import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.ServiceList;
import org.schabi.newpipe.extractor.StreamingService; import org.schabi.newpipe.extractor.StreamingService;
import org.schabi.newpipe.extractor.comments.CommentsInfo; import org.schabi.newpipe.extractor.comments.CommentsInfo;
import org.schabi.newpipe.extractor.comments.CommentsInfoItem; import org.schabi.newpipe.extractor.comments.CommentsInfoItem;
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
import org.schabi.newpipe.extractor.stream.Description; import org.schabi.newpipe.extractor.stream.Description;
import org.schabi.newpipe.fragments.list.comments.CommentRepliesFragment;
import org.schabi.newpipe.info_list.InfoItemBuilder; import org.schabi.newpipe.info_list.InfoItemBuilder;
import org.schabi.newpipe.local.history.HistoryRecordManager; import org.schabi.newpipe.local.history.HistoryRecordManager;
import org.schabi.newpipe.util.DeviceUtils; import org.schabi.newpipe.util.DeviceUtils;
@ -46,7 +40,6 @@ import java.util.function.Consumer;
import io.reactivex.rxjava3.disposables.CompositeDisposable; import io.reactivex.rxjava3.disposables.CompositeDisposable;
public class CommentInfoItemHolder extends InfoItemHolder { public class CommentInfoItemHolder extends InfoItemHolder {
private static final String TAG = "CommentIIHolder";
private static final String ELLIPSIS = ""; private static final String ELLIPSIS = "";
private static final int COMMENT_DEFAULT_LINES = 2; private static final int COMMENT_DEFAULT_LINES = 2;
@ -125,30 +118,19 @@ public class CommentInfoItemHolder extends InfoItemHolder {
// setup the top row, with pinned icon, author name and comment date // setup the top row, with pinned icon, author name and comment date
itemPinnedView.setVisibility(item.isPinned() ? View.VISIBLE : View.GONE); itemPinnedView.setVisibility(item.isPinned() ? View.VISIBLE : View.GONE);
itemTitleView.setText(Localization.concatenateStrings(item.getUploaderName(),
final String uploadDate; Localization.relativeTimeOrTextual(item.getUploadDate(),
if (item.getUploadDate() != null) { item.getTextualUploadDate(), itemBuilder.getContext())));
uploadDate = Localization.relativeTime(item.getUploadDate().offsetDateTime());
} else {
uploadDate = item.getTextualUploadDate();
}
itemTitleView.setText(Localization.concatenateStrings(item.getUploaderName(), uploadDate));
// setup bottom row, with likes, heart and replies button // setup bottom row, with likes, heart and replies button
if (item.getLikeCount() >= 0) {
itemLikesCountView.setText( itemLikesCountView.setText(
Localization.shortCount( Localization.likeCount(itemBuilder.getContext(), item.getLikeCount()));
itemBuilder.getContext(),
item.getLikeCount()));
} else {
itemLikesCountView.setText("-");
}
itemHeartView.setVisibility(item.isHeartedByUploader() ? View.VISIBLE : View.GONE); itemHeartView.setVisibility(item.isHeartedByUploader() ? View.VISIBLE : View.GONE);
final boolean hasReplies = item.getReplies() != null; final boolean hasReplies = item.getReplies() != null;
repliesButton.setOnClickListener(hasReplies ? v -> openRepliesFragment(item) : null); repliesButton.setOnClickListener(hasReplies ? v -> openCommentReplies(item) : null);
repliesButton.setVisibility(hasReplies ? View.VISIBLE : View.GONE); repliesButton.setVisibility(hasReplies ? View.VISIBLE : View.GONE);
repliesButton.setText(hasReplies repliesButton.setText(hasReplies
? Localization.replyCount(itemBuilder.getContext(), item.getReplyCount()) : ""); ? Localization.replyCount(itemBuilder.getContext(), item.getReplyCount()) : "");
@ -157,14 +139,7 @@ public class CommentInfoItemHolder extends InfoItemHolder {
// setup comment content and click listeners to expand/ellipsize it // setup comment content and click listeners to expand/ellipsize it
try { streamService = getServiceById(item.getServiceId());
streamService = NewPipe.getService(item.getServiceId());
} catch (final ExtractionException e) {
// should never happen
ErrorUtil.showUiErrorSnackbar(itemBuilder.getContext(), "Getting StreamingService", e);
Log.w(TAG, "Cannot obtain service from comment service id, defaulting to YouTube", e);
streamService = ServiceList.YouTube;
}
streamUrl = item.getUrl(); streamUrl = item.getUrl();
commentText = item.getCommentText(); commentText = item.getCommentText();
ellipsize(); ellipsize();
@ -193,19 +168,13 @@ public class CommentInfoItemHolder extends InfoItemHolder {
} }
private void openCommentAuthor(final CommentsInfoItem item) { private void openCommentAuthor(final CommentsInfoItem item) {
if (isEmpty(item.getUploaderUrl())) { NavigationHelper.openCommentAuthorIfPresent((FragmentActivity) itemBuilder.getContext(),
return; item);
}
final AppCompatActivity activity = (AppCompatActivity) itemBuilder.getContext();
try {
NavigationHelper.openChannelFragment(
activity.getSupportFragmentManager(),
item.getServiceId(),
item.getUploaderUrl(),
item.getUploaderName());
} catch (final Exception e) {
ErrorUtil.showUiErrorSnackbar(activity, "Opening channel fragment", e);
} }
private void openCommentReplies(final CommentsInfoItem item) {
NavigationHelper.openCommentRepliesFragment((FragmentActivity) itemBuilder.getContext(),
(CommentsInfo) itemBuilder.getSourceListInfo(), item);
} }
private void allowLinkFocus() { private void allowLinkFocus() {
@ -305,17 +274,4 @@ public class CommentInfoItemHolder extends InfoItemHolder {
onCompletion); onCompletion);
} }
} }
private void openRepliesFragment(final CommentsInfoItem commentsInfoItem) {
((MainActivity) itemBuilder.getContext())
.getSupportFragmentManager()
.beginTransaction()
.setCustomAnimations(R.animator.custom_fade_in, R.animator.custom_fade_out,
R.animator.custom_fade_in, R.animator.custom_fade_out)
.replace(R.id.fragment_holder,
new CommentRepliesFragment((CommentsInfo) itemBuilder.getSourceListInfo(),
commentsInfoItem))
.addToBackStack(null)
.commit();
}
} }

View File

@ -12,10 +12,6 @@ import org.schabi.newpipe.info_list.InfoItemBuilder;
import org.schabi.newpipe.local.history.HistoryRecordManager; import org.schabi.newpipe.local.history.HistoryRecordManager;
import org.schabi.newpipe.util.Localization; import org.schabi.newpipe.util.Localization;
import androidx.preference.PreferenceManager;
import static org.schabi.newpipe.MainActivity.DEBUG;
/* /*
* Created by Christian Schabesberger on 01.08.16. * Created by Christian Schabesberger on 01.08.16.
* <p> * <p>
@ -81,7 +77,8 @@ public class StreamInfoItemHolder extends StreamMiniInfoItemHolder {
} }
} }
final String uploadDate = getFormattedRelativeUploadDate(infoItem); final String uploadDate = Localization.relativeTimeOrTextual(infoItem.getUploadDate(),
infoItem.getTextualUploadDate(), itemBuilder.getContext());
if (!TextUtils.isEmpty(uploadDate)) { if (!TextUtils.isEmpty(uploadDate)) {
if (viewsAndDate.isEmpty()) { if (viewsAndDate.isEmpty()) {
return uploadDate; return uploadDate;
@ -92,20 +89,4 @@ public class StreamInfoItemHolder extends StreamMiniInfoItemHolder {
return viewsAndDate; return viewsAndDate;
} }
private String getFormattedRelativeUploadDate(final StreamInfoItem infoItem) {
if (infoItem.getUploadDate() != null) {
String formattedRelativeTime = Localization
.relativeTime(infoItem.getUploadDate().offsetDateTime());
if (DEBUG && PreferenceManager.getDefaultSharedPreferences(itemBuilder.getContext())
.getBoolean(itemBuilder.getContext()
.getString(R.string.show_original_time_ago_key), false)) {
formattedRelativeTime += " (" + infoItem.getTextualUploadDate() + ")";
}
return formattedRelativeTime;
} else {
return infoItem.getTextualUploadDate();
}
}
} }

View File

@ -1,5 +1,7 @@
package org.schabi.newpipe.util; package org.schabi.newpipe.util;
import static org.schabi.newpipe.MainActivity.DEBUG;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
@ -22,6 +24,7 @@ import org.ocpsoft.prettytime.units.Decade;
import org.schabi.newpipe.R; import org.schabi.newpipe.R;
import org.schabi.newpipe.extractor.ListExtractor; import org.schabi.newpipe.extractor.ListExtractor;
import org.schabi.newpipe.extractor.localization.ContentCountry; import org.schabi.newpipe.extractor.localization.ContentCountry;
import org.schabi.newpipe.extractor.localization.DateWrapper;
import org.schabi.newpipe.extractor.stream.AudioStream; import org.schabi.newpipe.extractor.stream.AudioStream;
import org.schabi.newpipe.extractor.stream.AudioTrackType; import org.schabi.newpipe.extractor.stream.AudioTrackType;
@ -214,6 +217,14 @@ public final class Localization {
String.valueOf(replyCount)); String.valueOf(replyCount));
} }
public static String likeCount(final Context context, final int likeCount) {
if (likeCount < 0) {
return "-";
} else {
return shortCount(context, likeCount);
}
}
public static String getDurationString(final long duration) { public static String getDurationString(final long duration) {
final String output; final String output;
@ -333,6 +344,20 @@ public final class Localization {
return prettyTime.formatUnrounded(offsetDateTime); return prettyTime.formatUnrounded(offsetDateTime);
} }
public static String relativeTimeOrTextual(final DateWrapper parsed,
final String textual,
@Nullable final Context context) {
if (parsed == null) {
return textual;
} else if (DEBUG && context != null && PreferenceManager
.getDefaultSharedPreferences(context)
.getBoolean(context.getString(R.string.show_original_time_ago_key), false)) {
return relativeTime(parsed.offsetDateTime()) + " (" + textual + ")";
} else {
return relativeTime(parsed.offsetDateTime());
}
}
public static void assureCorrectAppLanguage(final Context c) { public static void assureCorrectAppLanguage(final Context c) {
final Resources res = c.getResources(); final Resources res = c.getResources();
final DisplayMetrics dm = res.getDisplayMetrics(); final DisplayMetrics dm = res.getDisplayMetrics();

View File

@ -1,5 +1,6 @@
package org.schabi.newpipe.util; package org.schabi.newpipe.util;
import static android.text.TextUtils.isEmpty;
import static org.schabi.newpipe.util.ListHelper.getUrlAndNonTorrentStreams; import static org.schabi.newpipe.util.ListHelper.getUrlAndNonTorrentStreams;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
@ -17,6 +18,7 @@ import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction; import androidx.fragment.app.FragmentTransaction;
@ -29,8 +31,11 @@ import org.schabi.newpipe.RouterActivity;
import org.schabi.newpipe.about.AboutActivity; import org.schabi.newpipe.about.AboutActivity;
import org.schabi.newpipe.database.feed.model.FeedGroupEntity; import org.schabi.newpipe.database.feed.model.FeedGroupEntity;
import org.schabi.newpipe.download.DownloadActivity; import org.schabi.newpipe.download.DownloadActivity;
import org.schabi.newpipe.error.ErrorUtil;
import org.schabi.newpipe.extractor.NewPipe; import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.StreamingService; import org.schabi.newpipe.extractor.StreamingService;
import org.schabi.newpipe.extractor.comments.CommentsInfo;
import org.schabi.newpipe.extractor.comments.CommentsInfoItem;
import org.schabi.newpipe.extractor.exceptions.ExtractionException; import org.schabi.newpipe.extractor.exceptions.ExtractionException;
import org.schabi.newpipe.extractor.stream.AudioStream; import org.schabi.newpipe.extractor.stream.AudioStream;
import org.schabi.newpipe.extractor.stream.DeliveryMethod; import org.schabi.newpipe.extractor.stream.DeliveryMethod;
@ -41,6 +46,7 @@ import org.schabi.newpipe.extractor.stream.VideoStream;
import org.schabi.newpipe.fragments.MainFragment; import org.schabi.newpipe.fragments.MainFragment;
import org.schabi.newpipe.fragments.detail.VideoDetailFragment; import org.schabi.newpipe.fragments.detail.VideoDetailFragment;
import org.schabi.newpipe.fragments.list.channel.ChannelFragment; import org.schabi.newpipe.fragments.list.channel.ChannelFragment;
import org.schabi.newpipe.fragments.list.comments.CommentRepliesFragment;
import org.schabi.newpipe.fragments.list.kiosk.KioskFragment; import org.schabi.newpipe.fragments.list.kiosk.KioskFragment;
import org.schabi.newpipe.fragments.list.playlist.PlaylistFragment; import org.schabi.newpipe.fragments.list.playlist.PlaylistFragment;
import org.schabi.newpipe.fragments.list.search.SearchFragment; import org.schabi.newpipe.fragments.list.search.SearchFragment;
@ -476,6 +482,29 @@ public final class NavigationHelper {
item.getServiceId(), uploaderUrl, item.getUploaderName()); item.getServiceId(), uploaderUrl, item.getUploaderName());
} }
public static void openCommentAuthorIfPresent(@NonNull final FragmentActivity activity,
final CommentsInfoItem comment) {
if (isEmpty(comment.getUploaderUrl())) {
return;
}
try {
openChannelFragment(activity.getSupportFragmentManager(), comment.getServiceId(),
comment.getUploaderUrl(), comment.getUploaderName());
} catch (final Exception e) {
ErrorUtil.showUiErrorSnackbar(activity, "Opening channel fragment", e);
}
}
public static void openCommentRepliesFragment(@NonNull final FragmentActivity activity,
final CommentsInfo commentsInfo,
final CommentsInfoItem commentsInfoItem) {
defaultTransaction(activity.getSupportFragmentManager())
.replace(R.id.fragment_holder,
new CommentRepliesFragment(commentsInfo, commentsInfoItem))
.addToBackStack(null)
.commit();
}
public static void openPlaylistFragment(final FragmentManager fragmentManager, public static void openPlaylistFragment(final FragmentManager fragmentManager,
final int serviceId, final String url, final int serviceId, final String url,
@NonNull final String name) { @NonNull final String name) {

View File

@ -144,6 +144,14 @@ public final class ServiceHelper {
.orElse("<unknown>"); .orElse("<unknown>");
} }
@NonNull
public static StreamingService getServiceById(final int serviceId) {
return ServiceList.all().stream()
.filter(s -> s.getServiceId() == serviceId)
.findFirst()
.orElseThrow();
}
public static void setSelectedServiceId(final Context context, final int serviceId) { public static void setSelectedServiceId(final Context context, final int serviceId) {
String serviceName; String serviceName;
try { try {