package org.schabi.newpipe.info_list.holder; import static org.schabi.newpipe.util.ServiceHelper.getServiceById; import android.text.method.LinkMovementMethod; import android.text.style.URLSpan; import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.ImageView; import android.widget.RelativeLayout; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.fragment.app.FragmentActivity; import org.schabi.newpipe.R; import org.schabi.newpipe.extractor.InfoItem; import org.schabi.newpipe.extractor.comments.CommentsInfoItem; import org.schabi.newpipe.info_list.InfoItemBuilder; import org.schabi.newpipe.local.history.HistoryRecordManager; import org.schabi.newpipe.util.DeviceUtils; import org.schabi.newpipe.util.Localization; import org.schabi.newpipe.util.NavigationHelper; import org.schabi.newpipe.util.external_communication.ShareUtils; import org.schabi.newpipe.util.image.ImageStrategy; import org.schabi.newpipe.util.image.PicassoHelper; import org.schabi.newpipe.util.text.CommentTextOnTouchListener; import org.schabi.newpipe.util.text.TextEllipsizer; public class CommentInfoItemHolder extends InfoItemHolder { private static final int COMMENT_DEFAULT_LINES = 2; private final int commentHorizontalPadding; private final int commentVerticalPadding; private final RelativeLayout itemRoot; private final ImageView itemThumbnailView; private final TextView itemContentView; private final ImageView itemThumbsUpView; private final TextView itemLikesCountView; private final TextView itemTitleView; private final ImageView itemHeartView; private final ImageView itemPinnedView; private final Button repliesButton; @NonNull private final TextEllipsizer textEllipsizer; public CommentInfoItemHolder(final InfoItemBuilder infoItemBuilder, final ViewGroup parent) { super(infoItemBuilder, R.layout.list_comment_item, parent); itemRoot = itemView.findViewById(R.id.itemRoot); itemThumbnailView = itemView.findViewById(R.id.itemThumbnailView); itemContentView = itemView.findViewById(R.id.itemCommentContentView); itemThumbsUpView = itemView.findViewById(R.id.detail_thumbs_up_img_view); itemLikesCountView = itemView.findViewById(R.id.detail_thumbs_up_count_view); itemTitleView = itemView.findViewById(R.id.itemTitleView); itemHeartView = itemView.findViewById(R.id.detail_heart_image_view); itemPinnedView = itemView.findViewById(R.id.detail_pinned_view); repliesButton = itemView.findViewById(R.id.replies_button); commentHorizontalPadding = (int) infoItemBuilder.getContext() .getResources().getDimension(R.dimen.comments_horizontal_padding); commentVerticalPadding = (int) infoItemBuilder.getContext() .getResources().getDimension(R.dimen.comments_vertical_padding); textEllipsizer = new TextEllipsizer(itemContentView, COMMENT_DEFAULT_LINES, null); textEllipsizer.setStateChangeListener(isEllipsized -> { if (Boolean.TRUE.equals(isEllipsized)) { denyLinkFocus(); } else { determineMovementMethod(); } }); } @Override public void updateFromItem(final InfoItem infoItem, final HistoryRecordManager historyRecordManager) { if (!(infoItem instanceof CommentsInfoItem)) { return; } final CommentsInfoItem item = (CommentsInfoItem) infoItem; // load the author avatar PicassoHelper.loadAvatar(item.getUploaderAvatars()).into(itemThumbnailView); if (ImageStrategy.shouldLoadImages()) { itemThumbnailView.setVisibility(View.VISIBLE); itemRoot.setPadding(commentVerticalPadding, commentVerticalPadding, commentVerticalPadding, commentVerticalPadding); } else { itemThumbnailView.setVisibility(View.GONE); itemRoot.setPadding(commentHorizontalPadding, commentVerticalPadding, commentHorizontalPadding, commentVerticalPadding); } itemThumbnailView.setOnClickListener(view -> openCommentAuthor(item)); // setup the top row, with pinned icon, author name and comment date itemPinnedView.setVisibility(item.isPinned() ? View.VISIBLE : View.GONE); itemTitleView.setText(Localization.concatenateStrings(item.getUploaderName(), Localization.relativeTimeOrTextual(itemBuilder.getContext(), item.getUploadDate(), item.getTextualUploadDate()))); // setup bottom row, with likes, heart and replies button itemLikesCountView.setText( Localization.likeCount(itemBuilder.getContext(), item.getLikeCount())); itemHeartView.setVisibility(item.isHeartedByUploader() ? View.VISIBLE : View.GONE); final boolean hasReplies = item.getReplies() != null; repliesButton.setOnClickListener(hasReplies ? v -> openCommentReplies(item) : null); repliesButton.setVisibility(hasReplies ? View.VISIBLE : View.GONE); repliesButton.setText(hasReplies ? Localization.replyCount(itemBuilder.getContext(), item.getReplyCount()) : ""); ((RelativeLayout.LayoutParams) itemThumbsUpView.getLayoutParams()).topMargin = hasReplies ? 0 : DeviceUtils.dpToPx(6, itemBuilder.getContext()); // setup comment content and click listeners to expand/ellipsize it textEllipsizer.setStreamingService(getServiceById(item.getServiceId())); textEllipsizer.setStreamUrl(item.getUrl()); textEllipsizer.setContent(item.getCommentText()); textEllipsizer.ellipsize(); //noinspection ClickableViewAccessibility itemContentView.setOnTouchListener(CommentTextOnTouchListener.INSTANCE); itemView.setOnClickListener(view -> { textEllipsizer.toggle(); if (itemBuilder.getOnCommentsSelectedListener() != null) { itemBuilder.getOnCommentsSelectedListener().selected(item); } }); itemView.setOnLongClickListener(view -> { if (DeviceUtils.isTv(itemBuilder.getContext())) { openCommentAuthor(item); } else { final CharSequence text = itemContentView.getText(); if (text != null) { ShareUtils.copyToClipboard(itemBuilder.getContext(), text.toString()); } } return true; }); } private void openCommentAuthor(@NonNull final CommentsInfoItem item) { NavigationHelper.openCommentAuthorIfPresent((FragmentActivity) itemBuilder.getContext(), item); } private void openCommentReplies(@NonNull final CommentsInfoItem item) { NavigationHelper.openCommentRepliesFragment((FragmentActivity) itemBuilder.getContext(), item); } private void allowLinkFocus() { itemContentView.setMovementMethod(LinkMovementMethod.getInstance()); } private void denyLinkFocus() { itemContentView.setMovementMethod(null); } private boolean shouldFocusLinks() { if (itemView.isInTouchMode()) { return false; } final URLSpan[] urls = itemContentView.getUrls(); return urls != null && urls.length != 0; } private void determineMovementMethod() { if (shouldFocusLinks()) { allowLinkFocus(); } else { denyLinkFocus(); } } }