From 7204407690929666e066e8b6f509c43a205e6e17 Mon Sep 17 00:00:00 2001 From: Siddhesh Naik Date: Mon, 13 May 2024 02:22:13 +0530 Subject: [PATCH 1/7] Fix RSS button visibility - The `onPrepareMenu` callback is invoked after setting the visibility of the menu items. - Due to this, the menu item resets to it's default visibility. - Now updating the menu item within the callback. - Also migrated to the MenuHost framework to reduce dependency on deprecated APIs. --- .../list/channel/ChannelFragment.java | 131 +++++++++--------- 1 file changed, 68 insertions(+), 63 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java index 7e83d9958..fd382adbf 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java @@ -22,6 +22,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.content.ContextCompat; import androidx.core.graphics.ColorUtils; +import androidx.core.view.MenuProvider; import androidx.preference.PreferenceManager; import com.google.android.material.snackbar.Snackbar; @@ -99,6 +100,7 @@ public class ChannelFragment extends BaseStateFragment private MenuItem menuRssButton; private MenuItem menuNotifyButton; private SubscriptionEntity channelSubscription; + private MenuProvider menuProvider; public static ChannelFragment getInstance(final int serviceId, final String url, final String name) { @@ -121,7 +123,62 @@ public class ChannelFragment extends BaseStateFragment @Override public void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setHasOptionsMenu(true); + menuProvider = new MenuProvider() { + @Override + public void onCreateMenu(@NonNull final Menu menu, + @NonNull final MenuInflater inflater) { + inflater.inflate(R.menu.menu_channel, menu); + + if (DEBUG) { + Log.d(TAG, "onCreateOptionsMenu() called with: " + + "menu = [" + menu + "], inflater = [" + inflater + "]"); + } + + } + + @Override + public void onPrepareMenu(@NonNull final Menu menu) { + menuRssButton = menu.findItem(R.id.menu_item_rss); + menuNotifyButton = menu.findItem(R.id.menu_item_notify); + updateRssButton(); + updateNotifyButton(channelSubscription); + } + + @Override + public boolean onMenuItemSelected(@NonNull final MenuItem item) { + switch (item.getItemId()) { + case R.id.menu_item_notify: + final boolean value = !item.isChecked(); + item.setEnabled(false); + setNotify(value); + break; + case R.id.action_settings: + NavigationHelper.openSettings(requireContext()); + break; + case R.id.menu_item_rss: + if (currentInfo != null) { + ShareUtils.openUrlInApp(requireContext(), currentInfo.getFeedUrl()); + } + break; + case R.id.menu_item_openInBrowser: + if (currentInfo != null) { + ShareUtils.openUrlInBrowser(requireContext(), + currentInfo.getOriginalUrl()); + } + break; + case R.id.menu_item_share: + if (currentInfo != null) { + ShareUtils.shareText(requireContext(), name, + currentInfo.getOriginalUrl(), currentInfo.getAvatars()); + } + break; + default: + return false; + } + return true; + } + }; + activity.addMenuProvider(menuProvider); } @Override @@ -183,67 +240,10 @@ public class ChannelFragment extends BaseStateFragment } disposables.clear(); binding = null; + activity.removeMenuProvider(menuProvider); + menuProvider = null; } - - /*////////////////////////////////////////////////////////////////////////// - // Menu - //////////////////////////////////////////////////////////////////////////*/ - - @Override - public void onCreateOptionsMenu(@NonNull final Menu menu, - @NonNull final MenuInflater inflater) { - super.onCreateOptionsMenu(menu, inflater); - inflater.inflate(R.menu.menu_channel, menu); - - if (DEBUG) { - Log.d(TAG, "onCreateOptionsMenu() called with: " - + "menu = [" + menu + "], inflater = [" + inflater + "]"); - } - } - - @Override - public void onPrepareOptionsMenu(@NonNull final Menu menu) { - super.onPrepareOptionsMenu(menu); - menuRssButton = menu.findItem(R.id.menu_item_rss); - menuNotifyButton = menu.findItem(R.id.menu_item_notify); - updateNotifyButton(channelSubscription); - } - - @Override - public boolean onOptionsItemSelected(@NonNull final MenuItem item) { - switch (item.getItemId()) { - case R.id.menu_item_notify: - final boolean value = !item.isChecked(); - item.setEnabled(false); - setNotify(value); - break; - case R.id.action_settings: - NavigationHelper.openSettings(requireContext()); - break; - case R.id.menu_item_rss: - if (currentInfo != null) { - ShareUtils.openUrlInApp(requireContext(), currentInfo.getFeedUrl()); - } - break; - case R.id.menu_item_openInBrowser: - if (currentInfo != null) { - ShareUtils.openUrlInBrowser(requireContext(), currentInfo.getOriginalUrl()); - } - break; - case R.id.menu_item_share: - if (currentInfo != null) { - ShareUtils.shareText(requireContext(), name, currentInfo.getOriginalUrl(), - currentInfo.getAvatars()); - } - break; - default: - return super.onOptionsItemSelected(item); - } - return true; - } - - /*////////////////////////////////////////////////////////////////////////// // Channel Subscription //////////////////////////////////////////////////////////////////////////*/ @@ -408,6 +408,13 @@ public class ChannelFragment extends BaseStateFragment animate(binding.channelSubscribeButton, true, 100, AnimationType.LIGHT_SCALE_AND_ALPHA); } + private void updateRssButton() { + if (menuRssButton == null || currentInfo == null) { + return; + } + menuRssButton.setVisible(!TextUtils.isEmpty(currentInfo.getFeedUrl())); + } + private void updateNotifyButton(@Nullable final SubscriptionEntity subscription) { if (menuNotifyButton == null) { return; @@ -610,9 +617,7 @@ public class ChannelFragment extends BaseStateFragment binding.subChannelAvatarView.setVisibility(View.VISIBLE); } - if (menuRssButton != null) { - menuRssButton.setVisible(!TextUtils.isEmpty(result.getFeedUrl())); - } + updateRssButton(); channelContentNotSupported = false; for (final Throwable throwable : result.getErrors()) { From 46139340fed514498eb9fc97c88f61a836dc1d99 Mon Sep 17 00:00:00 2001 From: Isira Seneviratne Date: Wed, 15 May 2024 06:51:52 +0530 Subject: [PATCH 2/7] Convert comment touch listener to a lambda --- .../holder/CommentInfoItemHolder.java | 26 +++++++++++- .../util/text/CommentTextOnTouchListener.java | 42 ------------------- 2 files changed, 24 insertions(+), 44 deletions(-) delete mode 100644 app/src/main/java/org/schabi/newpipe/util/text/CommentTextOnTouchListener.java diff --git a/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentInfoItemHolder.java b/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentInfoItemHolder.java index a3f0384ad..839aa1813 100644 --- a/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentInfoItemHolder.java +++ b/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentInfoItemHolder.java @@ -1,9 +1,13 @@ package org.schabi.newpipe.info_list.holder; import static org.schabi.newpipe.util.ServiceHelper.getServiceById; +import static org.schabi.newpipe.util.text.TouchUtils.getOffsetForHorizontalLine; +import android.text.Spanned; import android.text.method.LinkMovementMethod; +import android.text.style.ClickableSpan; import android.text.style.URLSpan; +import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.widget.Button; @@ -25,7 +29,6 @@ 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 { @@ -128,7 +131,26 @@ public class CommentInfoItemHolder extends InfoItemHolder { textEllipsizer.ellipsize(); //noinspection ClickableViewAccessibility - itemContentView.setOnTouchListener(CommentTextOnTouchListener.INSTANCE); + itemContentView.setOnTouchListener((v, event) -> { + final CharSequence text = itemContentView.getText(); + if (text instanceof Spanned buffer) { + final int action = event.getAction(); + + if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_DOWN) { + final int offset = getOffsetForHorizontalLine(itemContentView, event); + final var links = buffer.getSpans(offset, offset, ClickableSpan.class); + + if (links.length != 0) { + if (action == MotionEvent.ACTION_UP) { + links[0].onClick(itemContentView); + } + // we handle events that intersect links, so return true + return true; + } + } + } + return false; + }); itemView.setOnClickListener(view -> { textEllipsizer.toggle(); diff --git a/app/src/main/java/org/schabi/newpipe/util/text/CommentTextOnTouchListener.java b/app/src/main/java/org/schabi/newpipe/util/text/CommentTextOnTouchListener.java deleted file mode 100644 index 5018a6120..000000000 --- a/app/src/main/java/org/schabi/newpipe/util/text/CommentTextOnTouchListener.java +++ /dev/null @@ -1,42 +0,0 @@ -package org.schabi.newpipe.util.text; - -import static org.schabi.newpipe.util.text.TouchUtils.getOffsetForHorizontalLine; - -import android.annotation.SuppressLint; -import android.text.Spanned; -import android.text.style.ClickableSpan; -import android.view.MotionEvent; -import android.view.View; -import android.widget.TextView; - -public class CommentTextOnTouchListener implements View.OnTouchListener { - public static final CommentTextOnTouchListener INSTANCE = new CommentTextOnTouchListener(); - - @SuppressLint("ClickableViewAccessibility") - @Override - public boolean onTouch(final View v, final MotionEvent event) { - if (!(v instanceof TextView)) { - return false; - } - final TextView widget = (TextView) v; - final CharSequence text = widget.getText(); - if (text instanceof Spanned) { - final Spanned buffer = (Spanned) text; - final int action = event.getAction(); - - if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_DOWN) { - final int offset = getOffsetForHorizontalLine(widget, event); - final ClickableSpan[] links = buffer.getSpans(offset, offset, ClickableSpan.class); - - if (links.length != 0) { - if (action == MotionEvent.ACTION_UP) { - links[0].onClick(widget); - } - // we handle events that intersect links, so return true - return true; - } - } - } - return false; - } -} From e48ce5a103112e97a3478d4656f41c8d03063281 Mon Sep 17 00:00:00 2001 From: moontoaster <74986506+moontoaster@users.noreply.github.com> Date: Thu, 23 May 2024 20:57:05 +0300 Subject: [PATCH 3/7] Update PrettyTime to 5.0.8 This version contains a fix for Ukrainian locale which fixes #11092. --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 28a208195..9aec02267 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -282,7 +282,7 @@ dependencies { implementation "com.jakewharton.rxbinding4:rxbinding:4.0.0" // Date and time formatting - implementation "org.ocpsoft.prettytime:prettytime:5.0.7.Final" + implementation "org.ocpsoft.prettytime:prettytime:5.0.8.Final" /** Debugging **/ // Memory leak detection From 2a3d133bcf74aeb6aff5a3e72c9d9955b08dc2e0 Mon Sep 17 00:00:00 2001 From: Neznak Date: Mon, 27 May 2024 14:08:18 +0300 Subject: [PATCH 4/7] Add missing Peertube instance subscribeto.me to the links Newpipe handles --- app/src/main/AndroidManifest.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 1127c55a4..d11de9f47 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -367,6 +367,7 @@ + From 8583c482640ccc7496b78ea97b8e50178af4142f Mon Sep 17 00:00:00 2001 From: Aryan Yadav <155174267+aryn-ydv@users.noreply.github.com> Date: Tue, 28 May 2024 10:14:46 +0530 Subject: [PATCH 5/7] fixes #11093 --- .../schabi/newpipe/fragments/list/playlist/PlaylistFragment.java | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java index 9afb06344..6410fb9ee 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java @@ -352,6 +352,7 @@ public class PlaylistFragment extends BaseListInfoFragment ellipsizer.toggle()); + headerBinding.playlistDescription.setOnClickListener(v -> ellipsizer.toggle()); } else { headerBinding.playlistDescription.setVisibility(View.GONE); headerBinding.playlistDescriptionReadMore.setVisibility(View.GONE); From e64c01d2daf35c33001dfd12f46f30df765dfc01 Mon Sep 17 00:00:00 2001 From: Eric Driussi Date: Mon, 24 Jun 2024 09:47:29 +0100 Subject: [PATCH 6/7] Remove kotlin restriction --- .github/CONTRIBUTING.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 088707b6e..70c81c7b1 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -42,10 +42,6 @@ You'll see *exactly* what is sent, be able to add **your comments**, and then se * Create PRs that cover only **one specific issue/solution/bug**. Do not create PRs that are huge monoliths and could have been split into multiple independent contributions. * NewPipe uses [NewPipeExtractor](https://github.com/TeamNewPipe/NewPipeExtractor) to fetch data from services. If you need to change something there, you must test your changes in NewPipe. Telling NewPipe to use your extractor version can be accomplished by editing the `app/build.gradle` file: the comments under the "NewPipe libraries" section of `dependencies` will help you out. -### Kotlin in NewPipe -* NewPipe will remain mostly Java for time being -* Contributions containing a simple conversion from Java to Kotlin should be avoided. Conversions to Kotlin should only be done if Kotlin actually brings improvements like bug fixes or better performance which are not, or only with much more effort, implementable in Java. The core team sees Java as an easier to learn and generally well adopted programming language. - ### Creating a Pull Request (PR) * Make changes on a **separate branch** with a meaningful name, not on the _master_ branch or the _dev_ branch. This is commonly known as *feature branch workflow*. You may then send your changes as a pull request (PR) on GitHub. From 1f309854bcf36db8cb60d7da08c1c117aea58bf3 Mon Sep 17 00:00:00 2001 From: Stypox Date: Tue, 2 Jul 2024 17:37:09 +0200 Subject: [PATCH 7/7] Run CI on pull requests to refactor branch, too --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0c750157c..9ae3a77c2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,6 +6,7 @@ on: branches: - dev - master + - refactor - release** paths-ignore: - 'README.md'