diff --git a/app/src/main/java/org/schabi/newpipe/MainActivity.java b/app/src/main/java/org/schabi/newpipe/MainActivity.java index 175694125..43b01c70d 100644 --- a/app/src/main/java/org/schabi/newpipe/MainActivity.java +++ b/app/src/main/java/org/schabi/newpipe/MainActivity.java @@ -871,7 +871,7 @@ public class MainActivity extends AppCompatActivity { @Nullable final CommentRepliesFragment repliesFragment = (CommentRepliesFragment) fm.findFragmentByTag(CommentRepliesFragment.TAG); @Nullable final CommentsInfoItem rootComment = - repliesFragment == null ? null : repliesFragment.getCommentsInfoItem(); + repliesFragment == null ? null : repliesFragment.commentsInfoItem; // sometimes this function pops the backstack, other times it's handled by the system if (popBackStack) { diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/comments/CommentRepliesFragment.kt b/app/src/main/java/org/schabi/newpipe/fragments/list/comments/CommentRepliesFragment.kt index 4eb73520f..4bfb04d6e 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/comments/CommentRepliesFragment.kt +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/comments/CommentRepliesFragment.kt @@ -1,170 +1,104 @@ -package org.schabi.newpipe.fragments.list.comments; +package org.schabi.newpipe.fragments.list.comments -import static org.schabi.newpipe.util.ServiceHelper.getServiceById; - -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.constraintlayout.widget.ConstraintLayout; -import androidx.core.text.HtmlCompat; - -import org.schabi.newpipe.R; -import org.schabi.newpipe.databinding.CommentRepliesHeaderBinding; -import org.schabi.newpipe.error.UserAction; -import org.schabi.newpipe.extractor.ListExtractor; -import org.schabi.newpipe.extractor.comments.CommentsInfoItem; -import org.schabi.newpipe.fragments.list.BaseListInfoFragment; -import org.schabi.newpipe.info_list.ItemViewMode; -import org.schabi.newpipe.util.DeviceUtils; -import org.schabi.newpipe.util.ExtractorHelper; -import org.schabi.newpipe.util.Localization; -import org.schabi.newpipe.util.NavigationHelper; -import org.schabi.newpipe.util.image.CoilHelper; -import org.schabi.newpipe.util.image.ImageStrategy; -import org.schabi.newpipe.util.text.TextLinkifier; - -import java.util.Queue; -import java.util.function.Supplier; - -import icepick.State; -import io.reactivex.rxjava3.core.Single; -import io.reactivex.rxjava3.disposables.CompositeDisposable; - -public final class CommentRepliesFragment - extends BaseListInfoFragment { - - public static final String TAG = CommentRepliesFragment.class.getSimpleName(); - - @State - CommentsInfoItem commentsInfoItem; // the comment to show replies of - private final CompositeDisposable disposables = new CompositeDisposable(); - - - /*////////////////////////////////////////////////////////////////////////// - // Constructors and lifecycle - //////////////////////////////////////////////////////////////////////////*/ - - // only called by the Android framework, after which readFrom is called and restores all data - public CommentRepliesFragment() { - super(UserAction.REQUESTED_COMMENT_REPLIES); - } - - public CommentRepliesFragment(@NonNull final CommentsInfoItem commentsInfoItem) { - this(); - this.commentsInfoItem = commentsInfoItem; - // setting "" as title since the title will be properly set right after - setInitialData(commentsInfoItem.getServiceId(), commentsInfoItem.getUrl(), ""); - } - - @Nullable - @Override - public View onCreateView(@NonNull final LayoutInflater inflater, - @Nullable final ViewGroup container, - @Nullable final Bundle savedInstanceState) { - return inflater.inflate(R.layout.fragment_comments, container, false); - } - - @Override - public void onDestroyView() { - disposables.clear(); - super.onDestroyView(); - } - - @Override - protected Supplier getListHeaderSupplier() { - return () -> { - final CommentRepliesHeaderBinding binding = CommentRepliesHeaderBinding - .inflate(activity.getLayoutInflater(), itemsList, false); - final CommentsInfoItem item = commentsInfoItem; - - // load the author avatar - CoilHelper.INSTANCE.loadAvatar(binding.authorAvatar, item.getUploaderAvatars()); - binding.authorAvatar.setVisibility(ImageStrategy.shouldLoadImages() - ? View.VISIBLE : View.GONE); - - // setup author name and comment date - binding.authorName.setText(item.getUploaderName()); - binding.uploadDate.setText(Localization.relativeTimeOrTextual( - getContext(), item.getUploadDate(), item.getTextualUploadDate())); - binding.authorTouchArea.setOnClickListener( - v -> NavigationHelper.openCommentAuthorIfPresent(requireActivity(), item)); - - // setup like count, hearted and pinned - binding.thumbsUpCount.setText( - Localization.likeCount(requireContext(), item.getLikeCount())); - // for heartImage goneMarginEnd was used, but there is no way to tell ConstraintLayout - // not to use a different margin only when both the next two views are gone - ((ConstraintLayout.LayoutParams) binding.thumbsUpCount.getLayoutParams()) - .setMarginEnd(DeviceUtils.dpToPx( - (item.isHeartedByUploader() || item.isPinned() ? 8 : 16), - requireContext())); - binding.heartImage.setVisibility(item.isHeartedByUploader() ? View.VISIBLE : View.GONE); - binding.pinnedImage.setVisibility(item.isPinned() ? View.VISIBLE : View.GONE); - - // setup comment content - TextLinkifier.fromDescription(binding.commentContent, item.getCommentText(), - HtmlCompat.FROM_HTML_MODE_LEGACY, getServiceById(item.getServiceId()), - item.getUrl(), disposables, null); - - return binding.getRoot(); - }; - } - - - /*////////////////////////////////////////////////////////////////////////// - // State saving - //////////////////////////////////////////////////////////////////////////*/ - - @Override - public void writeTo(final Queue objectsToSave) { - super.writeTo(objectsToSave); - objectsToSave.add(commentsInfoItem); - } - - @Override - public void readFrom(@NonNull final Queue savedObjects) throws Exception { - super.readFrom(savedObjects); - commentsInfoItem = (CommentsInfoItem) savedObjects.poll(); - } - - - /*////////////////////////////////////////////////////////////////////////// - // Data loading - //////////////////////////////////////////////////////////////////////////*/ - - @Override - protected Single loadResult(final boolean forceLoad) { - return Single.fromCallable(() -> new CommentRepliesInfo(commentsInfoItem, - // the reply count string will be shown as the activity title - Localization.replyCount(requireContext(), commentsInfoItem.getReplyCount()))); - } - - @Override - protected Single> loadMoreItemsLogic() { - // commentsInfoItem.getUrl() should contain the url of the original - // ListInfo, which should be the stream url - return ExtractorHelper.getMoreCommentItems( - serviceId, commentsInfoItem.getUrl(), currentNextPage); - } - - - /*////////////////////////////////////////////////////////////////////////// - // Utils - //////////////////////////////////////////////////////////////////////////*/ - - @Override - protected ItemViewMode getItemViewMode() { - return ItemViewMode.LIST; - } +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.compose.ui.platform.ComposeView +import icepick.State +import io.reactivex.rxjava3.core.Single +import io.reactivex.rxjava3.disposables.CompositeDisposable +import org.schabi.newpipe.R +import org.schabi.newpipe.error.UserAction +import org.schabi.newpipe.extractor.ListExtractor.InfoItemsPage +import org.schabi.newpipe.extractor.comments.CommentsInfoItem +import org.schabi.newpipe.fragments.list.BaseListInfoFragment +import org.schabi.newpipe.info_list.ItemViewMode +import org.schabi.newpipe.util.ExtractorHelper +import org.schabi.newpipe.util.Localization +import java.util.Queue +import java.util.function.Supplier +class CommentRepliesFragment() : BaseListInfoFragment(UserAction.REQUESTED_COMMENT_REPLIES) { /** * @return the comment to which the replies are shown */ - public CommentsInfoItem getCommentsInfoItem() { - return commentsInfoItem; + @State + lateinit var commentsInfoItem: CommentsInfoItem // the comment to show replies of + private val disposables = CompositeDisposable() + + constructor(commentsInfoItem: CommentsInfoItem) : this() { + this.commentsInfoItem = commentsInfoItem + // setting "" as title since the title will be properly set right after + setInitialData(commentsInfoItem.serviceId, commentsInfoItem.url, "") + } + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + return inflater.inflate(R.layout.fragment_comments, container, false) + } + + override fun onDestroyView() { + disposables.clear() + super.onDestroyView() + } + + override fun getListHeaderSupplier(): Supplier { + return Supplier { + ComposeView(requireContext()).apply { + setContent { + CommentRepliesHeader(commentsInfoItem, disposables) + } + } + } + } + + /*////////////////////////////////////////////////////////////////////////// + // State saving + ////////////////////////////////////////////////////////////////////////// */ + override fun writeTo(objectsToSave: Queue) { + super.writeTo(objectsToSave) + objectsToSave.add(commentsInfoItem) + } + + @Throws(Exception::class) + override fun readFrom(savedObjects: Queue) { + super.readFrom(savedObjects) + commentsInfoItem = savedObjects.poll() as CommentsInfoItem + } + + /*////////////////////////////////////////////////////////////////////////// + // Data loading + ////////////////////////////////////////////////////////////////////////// */ + override fun loadResult(forceLoad: Boolean): Single { + return Single.fromCallable { + CommentRepliesInfo( + commentsInfoItem, // the reply count string will be shown as the activity title + Localization.replyCount(requireContext(), commentsInfoItem.replyCount) + ) + } + } + + override fun loadMoreItemsLogic(): Single>? { + // commentsInfoItem.getUrl() should contain the url of the original + // ListInfo, which should be the stream url + return ExtractorHelper.getMoreCommentItems( + serviceId, commentsInfoItem.url, currentNextPage + ) + } + + /*////////////////////////////////////////////////////////////////////////// + // Utils + ////////////////////////////////////////////////////////////////////////// */ + override fun getItemViewMode(): ItemViewMode { + return ItemViewMode.LIST + } + + companion object { + @JvmField + val TAG: String = CommentRepliesFragment::class.java.simpleName } } diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/comments/CommentRepliesHeader.kt b/app/src/main/java/org/schabi/newpipe/fragments/list/comments/CommentRepliesHeader.kt index 243d887cd..89f6985a3 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/comments/CommentRepliesHeader.kt +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/comments/CommentRepliesHeader.kt @@ -98,8 +98,8 @@ fun CommentRepliesHeader(comment: CommentsInfoItem, disposables: CompositeDispos }, update = { view -> // setup comment content - TextLinkifier.fromDescription(view, comment.commentText, - HtmlCompat.FROM_HTML_MODE_LEGACY, + TextLinkifier.fromDescription( + view, comment.commentText, HtmlCompat.FROM_HTML_MODE_LEGACY, ServiceHelper.getServiceById(comment.serviceId), comment.url, disposables, null ) diff --git a/app/src/main/res/layout/comment_replies_header.xml b/app/src/main/res/layout/comment_replies_header.xml deleted file mode 100644 index ed5ba1a10..000000000 --- a/app/src/main/res/layout/comment_replies_header.xml +++ /dev/null @@ -1,137 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file