Skip to content

Commit 109d06b

Browse files
TobiGrStypox
authored andcommitted
Deduplicate code to initialize ClickListeners on playlist controls
Add the separate utility class PlayButtonHelper to handle the initialization of the listeners. The ClickListeners on playlist controls had different behaviours. This commit fixes that. The commit also refactors the way how the app determines whether it is started for the first time. The previous version was not clean and recent in this PR caused it to fail.
1 parent 0d9910c commit 109d06b

8 files changed

Lines changed: 147 additions & 117 deletions

File tree

app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@
112112
import org.schabi.newpipe.util.ThemeHelper;
113113
import org.schabi.newpipe.util.external_communication.KoreUtils;
114114
import org.schabi.newpipe.util.external_communication.ShareUtils;
115+
import org.schabi.newpipe.util.PlayButtonHelper;
115116

116117
import java.util.ArrayList;
117118
import java.util.Iterator;
@@ -535,9 +536,11 @@ private void setOnLongClickListeners() {
535536
}));
536537

537538
binding.detailControlsBackground.setOnLongClickListener(makeOnLongClickListener(info ->
538-
openBackgroundPlayer(true)));
539+
openBackgroundPlayer(true)
540+
));
539541
binding.detailControlsPopup.setOnLongClickListener(makeOnLongClickListener(info ->
540-
openPopupPlayer(true)));
542+
openPopupPlayer(true)
543+
));
541544
binding.detailControlsDownload.setOnLongClickListener(makeOnLongClickListener(info ->
542545
NavigationHelper.openDownloads(activity)));
543546

@@ -620,8 +623,7 @@ protected void initListeners() {
620623

621624
final View.OnTouchListener controlsTouchListener = (view, motionEvent) -> {
622625
if (motionEvent.getAction() == MotionEvent.ACTION_DOWN
623-
&& PreferenceManager.getDefaultSharedPreferences(activity)
624-
.getBoolean(getString(R.string.show_hold_to_append_key), true)) {
626+
&& PlayButtonHelper.shouldShowHoldToAppendTip(activity)) {
625627

626628
animate(binding.touchAppendDetail, true, 250, AnimationType.ALPHA, 0, () ->
627629
animate(binding.touchAppendDetail, false, 1500, AnimationType.ALPHA, 1000));

app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelTabFragment.java

Lines changed: 9 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,12 @@
1717
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler;
1818
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
1919
import org.schabi.newpipe.fragments.list.BaseListInfoFragment;
20-
import org.schabi.newpipe.player.PlayerType;
20+
import org.schabi.newpipe.fragments.list.playlist.PlaylistControlViewHolder;
2121
import org.schabi.newpipe.player.playqueue.ChannelTabPlayQueue;
2222
import org.schabi.newpipe.player.playqueue.PlayQueue;
2323
import org.schabi.newpipe.util.ChannelTabHelper;
2424
import org.schabi.newpipe.util.ExtractorHelper;
25-
import org.schabi.newpipe.util.NavigationHelper;
25+
import org.schabi.newpipe.util.PlayButtonHelper;
2626

2727
import java.util.List;
2828
import java.util.function.Supplier;
@@ -31,15 +31,15 @@
3131
import icepick.State;
3232
import io.reactivex.rxjava3.core.Single;
3333

34-
public class ChannelTabFragment extends BaseListInfoFragment<InfoItem, ChannelTabInfo> {
34+
public class ChannelTabFragment extends BaseListInfoFragment<InfoItem, ChannelTabInfo>
35+
implements PlaylistControlViewHolder {
3536

3637
@State
3738
protected ListLinkHandler tabHandler;
3839
@State
3940
protected String channelName;
4041

4142
private PlaylistControlBinding playlistControlBinding;
42-
4343
public static ChannelTabFragment getInstance(final int serviceId,
4444
final ListLinkHandler tabHandler,
4545
final String channelName) {
@@ -72,8 +72,8 @@ public View onCreateView(@NonNull final LayoutInflater inflater,
7272
}
7373

7474
@Override
75-
public void onDestroy() {
76-
super.onDestroy();
75+
public void onDestroyView() {
76+
super.onDestroyView();
7777
playlistControlBinding = null;
7878
}
7979

@@ -115,27 +115,12 @@ public void handleResult(final @NonNull ChannelTabInfo result) {
115115
playlistControlBinding.getRoot().setVisibility(View.GONE);
116116
}
117117

118-
playlistControlBinding.playlistCtrlPlayAllButton.setOnClickListener(
119-
view -> NavigationHelper.playOnMainPlayer(activity, getPlayQueue()));
120-
playlistControlBinding.playlistCtrlPlayPopupButton.setOnClickListener(
121-
view -> NavigationHelper.playOnPopupPlayer(activity, getPlayQueue(), false));
122-
playlistControlBinding.playlistCtrlPlayBgButton.setOnClickListener(
123-
view -> NavigationHelper.playOnBackgroundPlayer(activity, getPlayQueue(),
124-
false));
125-
126-
playlistControlBinding.playlistCtrlPlayPopupButton.setOnLongClickListener(view -> {
127-
NavigationHelper.enqueueOnPlayer(activity, getPlayQueue(), PlayerType.POPUP);
128-
return true;
129-
});
130-
131-
playlistControlBinding.playlistCtrlPlayBgButton.setOnLongClickListener(view -> {
132-
NavigationHelper.enqueueOnPlayer(activity, getPlayQueue(), PlayerType.AUDIO);
133-
return true;
134-
});
118+
PlayButtonHelper.initPlaylistControlClickListener(
119+
activity, playlistControlBinding, this);
135120
}
136121
}
137122

138-
private PlayQueue getPlayQueue() {
123+
public PlayQueue getPlayQueue() {
139124
final List<StreamInfoItem> streamItems = infoListAdapter.getItemsList().stream()
140125
.filter(StreamInfoItem.class::isInstance)
141126
.map(StreamInfoItem.class::cast)
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package org.schabi.newpipe.fragments.list.playlist;
2+
3+
import org.schabi.newpipe.player.playqueue.PlayQueue;
4+
5+
/**
6+
* Interface for {@code R.layout.playlist_control} view holders
7+
* to give access to the play queue.
8+
*/
9+
public interface PlaylistControlViewHolder {
10+
11+
PlayQueue getPlayQueue();
12+
13+
}

app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,14 @@
4343
import org.schabi.newpipe.info_list.dialog.StreamDialogDefaultEntry;
4444
import org.schabi.newpipe.local.dialog.PlaylistDialog;
4545
import org.schabi.newpipe.local.playlist.RemotePlaylistManager;
46-
import org.schabi.newpipe.player.PlayerType;
4746
import org.schabi.newpipe.player.playqueue.PlayQueue;
4847
import org.schabi.newpipe.player.playqueue.PlaylistPlayQueue;
4948
import org.schabi.newpipe.util.ExtractorHelper;
5049
import org.schabi.newpipe.util.Localization;
5150
import org.schabi.newpipe.util.NavigationHelper;
5251
import org.schabi.newpipe.util.PicassoHelper;
5352
import org.schabi.newpipe.util.external_communication.ShareUtils;
53+
import org.schabi.newpipe.util.PlayButtonHelper;
5454

5555
import java.util.ArrayList;
5656
import java.util.List;
@@ -64,7 +64,8 @@
6464
import io.reactivex.rxjava3.disposables.CompositeDisposable;
6565
import io.reactivex.rxjava3.disposables.Disposable;
6666

67-
public class PlaylistFragment extends BaseListInfoFragment<StreamInfoItem, PlaylistInfo> {
67+
public class PlaylistFragment extends BaseListInfoFragment<StreamInfoItem, PlaylistInfo>
68+
implements PlaylistControlViewHolder {
6869

6970
private static final String PICASSO_PLAYLIST_TAG = "PICASSO_PLAYLIST_TAG";
7071

@@ -332,25 +333,10 @@ public void handleResult(@NonNull final PlaylistInfo result) {
332333
.observeOn(AndroidSchedulers.mainThread())
333334
.subscribe(getPlaylistBookmarkSubscriber());
334335

335-
playlistControlBinding.playlistCtrlPlayAllButton.setOnClickListener(view ->
336-
NavigationHelper.playOnMainPlayer(activity, getPlayQueue()));
337-
playlistControlBinding.playlistCtrlPlayPopupButton.setOnClickListener(view ->
338-
NavigationHelper.playOnPopupPlayer(activity, getPlayQueue(), false));
339-
playlistControlBinding.playlistCtrlPlayBgButton.setOnClickListener(view ->
340-
NavigationHelper.playOnBackgroundPlayer(activity, getPlayQueue(), false));
341-
342-
playlistControlBinding.playlistCtrlPlayPopupButton.setOnLongClickListener(view -> {
343-
NavigationHelper.enqueueOnPlayer(activity, getPlayQueue(), PlayerType.POPUP);
344-
return true;
345-
});
346-
347-
playlistControlBinding.playlistCtrlPlayBgButton.setOnLongClickListener(view -> {
348-
NavigationHelper.enqueueOnPlayer(activity, getPlayQueue(), PlayerType.AUDIO);
349-
return true;
350-
});
336+
PlayButtonHelper.initPlaylistControlClickListener(activity, playlistControlBinding, this);
351337
}
352338

353-
private PlayQueue getPlayQueue() {
339+
public PlayQueue getPlayQueue() {
354340
return getPlayQueue(0);
355341
}
356342

app/src/main/java/org/schabi/newpipe/local/history/StatisticsPlaylistFragment.java

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,16 @@
2828
import org.schabi.newpipe.error.ErrorInfo;
2929
import org.schabi.newpipe.error.UserAction;
3030
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
31+
import org.schabi.newpipe.fragments.list.playlist.PlaylistControlViewHolder;
3132
import org.schabi.newpipe.info_list.dialog.InfoItemDialog;
33+
import org.schabi.newpipe.info_list.dialog.StreamDialogDefaultEntry;
3234
import org.schabi.newpipe.local.BaseLocalListFragment;
3335
import org.schabi.newpipe.player.playqueue.PlayQueue;
3436
import org.schabi.newpipe.player.playqueue.SinglePlayQueue;
3537
import org.schabi.newpipe.settings.HistorySettingsFragment;
3638
import org.schabi.newpipe.util.NavigationHelper;
3739
import org.schabi.newpipe.util.OnClickGesture;
38-
import org.schabi.newpipe.info_list.dialog.StreamDialogDefaultEntry;
40+
import org.schabi.newpipe.util.PlayButtonHelper;
3941

4042
import java.util.ArrayList;
4143
import java.util.Collections;
@@ -49,7 +51,8 @@
4951
import io.reactivex.rxjava3.disposables.Disposable;
5052

5153
public class StatisticsPlaylistFragment
52-
extends BaseLocalListFragment<List<StreamStatisticsEntry>, Void> {
54+
extends BaseLocalListFragment<List<StreamStatisticsEntry>, Void>
55+
implements PlaylistControlViewHolder {
5356
private final CompositeDisposable disposables = new CompositeDisposable();
5457
@State
5558
Parcelable itemsListState;
@@ -195,14 +198,9 @@ public void onDestroyView() {
195198
if (itemListAdapter != null) {
196199
itemListAdapter.unsetSelectedListener();
197200
}
198-
if (playlistControlBinding != null) {
199-
playlistControlBinding.playlistCtrlPlayBgButton.setOnClickListener(null);
200-
playlistControlBinding.playlistCtrlPlayAllButton.setOnClickListener(null);
201-
playlistControlBinding.playlistCtrlPlayPopupButton.setOnClickListener(null);
202201

203-
headerBinding = null;
204-
playlistControlBinding = null;
205-
}
202+
headerBinding = null;
203+
playlistControlBinding = null;
206204

207205
if (databaseSubscription != null) {
208206
databaseSubscription.cancel();
@@ -276,12 +274,8 @@ public void handleResult(@NonNull final List<StreamStatisticsEntry> result) {
276274
itemsListState = null;
277275
}
278276

279-
playlistControlBinding.playlistCtrlPlayAllButton.setOnClickListener(view ->
280-
NavigationHelper.playOnMainPlayer(activity, getPlayQueue()));
281-
playlistControlBinding.playlistCtrlPlayPopupButton.setOnClickListener(view ->
282-
NavigationHelper.playOnPopupPlayer(activity, getPlayQueue(), false));
283-
playlistControlBinding.playlistCtrlPlayBgButton.setOnClickListener(view ->
284-
NavigationHelper.playOnBackgroundPlayer(activity, getPlayQueue(), false));
277+
PlayButtonHelper.initPlaylistControlClickListener(activity, playlistControlBinding, this);
278+
285279
headerBinding.sortButton.setOnClickListener(view -> toggleSortMode());
286280

287281
hideLoading();
@@ -374,7 +368,7 @@ private void deleteEntry(final int index) {
374368
}
375369
}
376370

377-
private PlayQueue getPlayQueue() {
371+
public PlayQueue getPlayQueue() {
378372
return getPlayQueue(0);
379373
}
380374

app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java

Lines changed: 9 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
import androidx.annotation.NonNull;
2323
import androidx.annotation.Nullable;
2424
import androidx.appcompat.app.AlertDialog;
25-
import androidx.preference.PreferenceManager;
2625
import androidx.recyclerview.widget.ItemTouchHelper;
2726
import androidx.recyclerview.widget.RecyclerView;
2827
import androidx.viewbinding.ViewBinding;
@@ -42,17 +41,18 @@
4241
import org.schabi.newpipe.error.ErrorInfo;
4342
import org.schabi.newpipe.error.UserAction;
4443
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
44+
import org.schabi.newpipe.fragments.list.playlist.PlaylistControlViewHolder;
4545
import org.schabi.newpipe.info_list.dialog.InfoItemDialog;
4646
import org.schabi.newpipe.info_list.dialog.StreamDialogDefaultEntry;
4747
import org.schabi.newpipe.local.BaseLocalListFragment;
4848
import org.schabi.newpipe.local.history.HistoryRecordManager;
49-
import org.schabi.newpipe.player.PlayerType;
5049
import org.schabi.newpipe.player.playqueue.PlayQueue;
5150
import org.schabi.newpipe.player.playqueue.SinglePlayQueue;
5251
import org.schabi.newpipe.util.Localization;
5352
import org.schabi.newpipe.util.NavigationHelper;
5453
import org.schabi.newpipe.util.OnClickGesture;
5554
import org.schabi.newpipe.util.external_communication.ShareUtils;
55+
import org.schabi.newpipe.util.PlayButtonHelper;
5656

5757
import java.util.ArrayList;
5858
import java.util.Collections;
@@ -69,7 +69,8 @@
6969
import io.reactivex.rxjava3.schedulers.Schedulers;
7070
import io.reactivex.rxjava3.subjects.PublishSubject;
7171

72-
public class LocalPlaylistFragment extends BaseLocalListFragment<List<PlaylistStreamEntry>, Void> {
72+
public class LocalPlaylistFragment extends BaseLocalListFragment<List<PlaylistStreamEntry>, Void>
73+
implements PlaylistControlViewHolder {
7374
// Save the list 10 seconds after the last change occurred
7475
private static final long SAVE_DEBOUNCE_MILLIS = 10000;
7576
private static final int MINIMUM_INITIAL_DRAG_VELOCITY = 12;
@@ -265,14 +266,10 @@ public void onDestroyView() {
265266
if (itemListAdapter != null) {
266267
itemListAdapter.unsetSelectedListener();
267268
}
268-
if (playlistControlBinding != null) {
269-
playlistControlBinding.playlistCtrlPlayBgButton.setOnClickListener(null);
270-
playlistControlBinding.playlistCtrlPlayAllButton.setOnClickListener(null);
271-
playlistControlBinding.playlistCtrlPlayPopupButton.setOnClickListener(null);
272269

273-
headerBinding = null;
274-
playlistControlBinding = null;
275-
}
270+
headerBinding = null;
271+
playlistControlBinding = null;
272+
276273

277274
if (databaseSubscription != null) {
278275
databaseSubscription.cancel();
@@ -498,38 +495,11 @@ public void handleResult(@NonNull final List<PlaylistStreamEntry> result) {
498495
}
499496
setVideoCount(itemListAdapter.getItemsList().size());
500497

501-
playlistControlBinding.playlistCtrlPlayAllButton.setOnClickListener(view -> {
502-
NavigationHelper.playOnMainPlayer(activity, getPlayQueue());
503-
showHoldToAppendTipIfNeeded();
504-
});
505-
playlistControlBinding.playlistCtrlPlayPopupButton.setOnClickListener(view -> {
506-
NavigationHelper.playOnPopupPlayer(activity, getPlayQueue(), false);
507-
showHoldToAppendTipIfNeeded();
508-
});
509-
playlistControlBinding.playlistCtrlPlayBgButton.setOnClickListener(view -> {
510-
NavigationHelper.playOnBackgroundPlayer(activity, getPlayQueue(), false);
511-
showHoldToAppendTipIfNeeded();
512-
});
513-
playlistControlBinding.playlistCtrlPlayPopupButton.setOnLongClickListener(view -> {
514-
NavigationHelper.enqueueOnPlayer(activity, getPlayQueue(), PlayerType.POPUP);
515-
return true;
516-
});
517-
518-
playlistControlBinding.playlistCtrlPlayBgButton.setOnLongClickListener(view -> {
519-
NavigationHelper.enqueueOnPlayer(activity, getPlayQueue(), PlayerType.AUDIO);
520-
return true;
521-
});
498+
PlayButtonHelper.initPlaylistControlClickListener(activity, playlistControlBinding, this);
522499

523500
hideLoading();
524501
}
525502

526-
private void showHoldToAppendTipIfNeeded() {
527-
if (PreferenceManager.getDefaultSharedPreferences(activity)
528-
.getBoolean(getString(R.string.show_hold_to_append_key), true)) {
529-
Toast.makeText(activity, R.string.hold_to_append, Toast.LENGTH_SHORT).show();
530-
}
531-
}
532-
533503
///////////////////////////////////////////////////////////////////////////
534504
// Fragment Error Handling
535505
///////////////////////////////////////////////////////////////////////////
@@ -853,7 +823,7 @@ private void setVideoCount(final long count) {
853823
}
854824
}
855825

856-
private PlayQueue getPlayQueue() {
826+
public PlayQueue getPlayQueue() {
857827
return getPlayQueue(0);
858828
}
859829

app/src/main/java/org/schabi/newpipe/settings/NewPipeSettings.java

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -44,21 +44,11 @@ public final class NewPipeSettings {
4444
private NewPipeSettings() { }
4545

4646
public static void initSettings(final Context context) {
47-
// check if there are entries in the prefs to determine whether this is the first app run
48-
Boolean isFirstRun = null;
49-
final Set<String> prefsKeys = PreferenceManager.getDefaultSharedPreferences(context)
50-
.getAll().keySet();
51-
for (final String key: prefsKeys) {
52-
// ACRA stores some info in the prefs during app initialization
53-
// which happens before this method is called. Therefore ignore ACRA-related keys.
54-
if (!key.toLowerCase().startsWith("acra")) {
55-
isFirstRun = false;
56-
break;
57-
}
58-
}
59-
if (isFirstRun == null) {
60-
isFirstRun = true;
61-
}
47+
// check if the last used preference version is set
48+
// to determine whether this is the first app run
49+
final int lastUsedPrefVersion = PreferenceManager.getDefaultSharedPreferences(context)
50+
.getInt(context.getString(R.string.last_used_preferences_version), -1);
51+
final boolean isFirstRun = lastUsedPrefVersion == -1;
6252

6353
// first run migrations, then setDefaultValues, since the latter requires the correct types
6454
SettingMigrations.runMigrationsIfNeeded(context, isFirstRun);

0 commit comments

Comments
 (0)