mirror of
				https://github.com/TeamNewPipe/NewPipe
				synced 2025-10-31 15:23:00 +00:00 
			
		
		
		
	| @@ -20,7 +20,10 @@ | ||||
|  | ||||
| package org.schabi.newpipe; | ||||
|  | ||||
| import android.content.BroadcastReceiver; | ||||
| import android.content.Context; | ||||
| import android.content.Intent; | ||||
| import android.content.IntentFilter; | ||||
| import android.content.SharedPreferences; | ||||
| import android.content.pm.PackageManager; | ||||
| import android.os.Build; | ||||
| @@ -101,6 +104,8 @@ public class MainActivity extends AppCompatActivity { | ||||
|     private boolean servicesShown = false; | ||||
|     private ImageView serviceArrow; | ||||
|  | ||||
|     private BroadcastReceiver broadcastReceiver; | ||||
|  | ||||
|     private static final int ITEM_ID_SUBSCRIPTIONS = -1; | ||||
|     private static final int ITEM_ID_FEED = -2; | ||||
|     private static final int ITEM_ID_BOOKMARKS = -3; | ||||
| @@ -147,6 +152,7 @@ public class MainActivity extends AppCompatActivity { | ||||
|         if (DeviceUtils.isTv(this)) { | ||||
|             FocusOverlayView.setupFocusObserver(this); | ||||
|         } | ||||
|         setupBroadcastReceiver(); | ||||
|     } | ||||
|  | ||||
|     private void setupDrawer() throws Exception { | ||||
| @@ -454,6 +460,9 @@ public class MainActivity extends AppCompatActivity { | ||||
|         if (!isChangingConfigurations()) { | ||||
|             StateSaver.clearStateFiles(); | ||||
|         } | ||||
|         if (broadcastReceiver != null) { | ||||
|             unregisterReceiver(broadcastReceiver); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
| @@ -795,9 +804,36 @@ public class MainActivity extends AppCompatActivity { | ||||
|             ErrorActivity.reportUiError(this, e); | ||||
|         } | ||||
|     } | ||||
|     /* | ||||
|      * Utils | ||||
|      * */ | ||||
|  | ||||
|     private void setupBroadcastReceiver() { | ||||
|         broadcastReceiver = new BroadcastReceiver() { | ||||
|             @Override | ||||
|             public void onReceive(final Context context, final Intent intent) { | ||||
|                 if (intent.getAction().equals(VideoDetailFragment.ACTION_PLAYER_STARTED)) { | ||||
|                     final Fragment fragmentPlayer = getSupportFragmentManager() | ||||
|                             .findFragmentById(R.id.fragment_player_holder); | ||||
|                     if (fragmentPlayer == null) { | ||||
|                         /* | ||||
|                          * We still don't have a fragment attached to the activity. | ||||
|                          * It can happen when a user started popup or background players | ||||
|                          * without opening a stream inside the fragment. | ||||
|                          * Adding it in a collapsed state (only mini player will be visible) | ||||
|                          * */ | ||||
|                         NavigationHelper.showMiniPlayer(getSupportFragmentManager()); | ||||
|                     } | ||||
|                     /* | ||||
|                     * At this point the player is added 100%, we can unregister. | ||||
|                     * Other actions are useless since the fragment will not be removed after that | ||||
|                      * */ | ||||
|                     unregisterReceiver(broadcastReceiver); | ||||
|                     broadcastReceiver = null; | ||||
|                 } | ||||
|             } | ||||
|         }; | ||||
|         final IntentFilter intentFilter = new IntentFilter(); | ||||
|         intentFilter.addAction(VideoDetailFragment.ACTION_PLAYER_STARTED); | ||||
|         registerReceiver(broadcastReceiver, intentFilter); | ||||
|     } | ||||
|  | ||||
|     private boolean bottomSheetHiddenOrCollapsed() { | ||||
|         final FrameLayout bottomSheetLayout = findViewById(R.id.fragment_player_holder); | ||||
|   | ||||
| @@ -146,6 +146,8 @@ public class VideoDetailFragment | ||||
|             "org.schabi.newpipe.VideoDetailFragment.ACTION_SHOW_MAIN_PLAYER"; | ||||
|     public static final String ACTION_HIDE_MAIN_PLAYER = | ||||
|             "org.schabi.newpipe.VideoDetailFragment.ACTION_HIDE_MAIN_PLAYER"; | ||||
|     public static final String ACTION_PLAYER_STARTED = | ||||
|             "org.schabi.newpipe.VideoDetailFragment.ACTION_PLAYER_STARTED"; | ||||
|     public static final String ACTION_VIDEO_FRAGMENT_RESUMED = | ||||
|             "org.schabi.newpipe.VideoDetailFragment.ACTION_VIDEO_FRAGMENT_RESUMED"; | ||||
|     public static final String ACTION_VIDEO_FRAGMENT_STOPPED = | ||||
| @@ -302,6 +304,12 @@ public class VideoDetailFragment | ||||
|         return instance; | ||||
|     } | ||||
|  | ||||
|     public static VideoDetailFragment getInstanceInCollapsedState() { | ||||
|         final VideoDetailFragment instance = new VideoDetailFragment(); | ||||
|         instance.bottomSheetState = BottomSheetBehavior.STATE_COLLAPSED; | ||||
|         return instance; | ||||
|     } | ||||
|  | ||||
|  | ||||
|     /*////////////////////////////////////////////////////////////////////////// | ||||
|     // Fragment's Lifecycle | ||||
| @@ -518,7 +526,7 @@ public class VideoDetailFragment | ||||
|                     openVideoPlayer(); | ||||
|                 } | ||||
|  | ||||
|                 setOverlayPlayPauseImage(); | ||||
|                 setOverlayPlayPauseImage(player != null && player.isPlaying()); | ||||
|                 break; | ||||
|             case R.id.overlay_close_button: | ||||
|                 bottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN); | ||||
| @@ -1325,12 +1333,22 @@ public class VideoDetailFragment | ||||
|                     bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED); | ||||
|                 } else if (intent.getAction().equals(ACTION_HIDE_MAIN_PLAYER)) { | ||||
|                     bottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN); | ||||
|                 } else if (intent.getAction().equals(ACTION_PLAYER_STARTED)) { | ||||
|                     // If the state is not hidden we don't need to show the mini player | ||||
|                     if (bottomSheetBehavior.getState() == BottomSheetBehavior.STATE_HIDDEN) { | ||||
|                         bottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED); | ||||
|                     } | ||||
|                     // Rebound to the service if it was closed via notification or mini player | ||||
|                     if (!PlayerHolder.bound) { | ||||
|                         PlayerHolder.startService(App.getApp(), false, VideoDetailFragment.this); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         }; | ||||
|         final IntentFilter intentFilter = new IntentFilter(); | ||||
|         intentFilter.addAction(ACTION_SHOW_MAIN_PLAYER); | ||||
|         intentFilter.addAction(ACTION_HIDE_MAIN_PLAYER); | ||||
|         intentFilter.addAction(ACTION_PLAYER_STARTED); | ||||
|         activity.registerReceiver(broadcastReceiver, intentFilter); | ||||
|     } | ||||
|  | ||||
| @@ -1719,8 +1737,12 @@ public class VideoDetailFragment | ||||
|         // It will allow to have live instance of PlayQueue with actual information about | ||||
|         // deleted/added items inside Channel/Playlist queue and makes possible to have | ||||
|         // a history of played items | ||||
|         if (stack.isEmpty() || !stack.peek().getPlayQueue().equals(queue)) { | ||||
|             stack.push(new StackItem(serviceId, url, name, playQueue)); | ||||
|         if ((stack.isEmpty() || !stack.peek().getPlayQueue().equals(queue) | ||||
|                 && queue.getItem() != null)) { | ||||
|             stack.push(new StackItem(queue.getItem().getServiceId(), | ||||
|                     queue.getItem().getUrl(), | ||||
|                     queue.getItem().getTitle(), | ||||
|                     queue)); | ||||
|         } else { | ||||
|             final StackItem stackWithQueue = findQueueInStack(queue); | ||||
|             if (stackWithQueue != null) { | ||||
| @@ -1744,7 +1766,7 @@ public class VideoDetailFragment | ||||
|                                  final int repeatMode, | ||||
|                                  final boolean shuffled, | ||||
|                                  final PlaybackParameters parameters) { | ||||
|         setOverlayPlayPauseImage(); | ||||
|         setOverlayPlayPauseImage(player != null && player.isPlaying()); | ||||
|  | ||||
|         switch (state) { | ||||
|             case BasePlayer.STATE_PLAYING: | ||||
| @@ -1818,7 +1840,7 @@ public class VideoDetailFragment | ||||
|  | ||||
|     @Override | ||||
|     public void onServiceStopped() { | ||||
|         setOverlayPlayPauseImage(); | ||||
|         setOverlayPlayPauseImage(false); | ||||
|         if (currentInfo != null) { | ||||
|             updateOverlayData(currentInfo.getName(), | ||||
|                     currentInfo.getUploaderName(), | ||||
| @@ -2224,6 +2246,9 @@ public class VideoDetailFragment | ||||
|                         break; | ||||
|                     case BottomSheetBehavior.STATE_COLLAPSED: | ||||
|                         moveFocusToMainFragment(true); | ||||
|                         manageSpaceAtTheBottom(false); | ||||
|  | ||||
|                         bottomSheetBehavior.setPeekHeight(peekHeight); | ||||
|  | ||||
|                         // Re-enable clicks | ||||
|                         setOverlayElementsClickable(true); | ||||
| @@ -2270,8 +2295,8 @@ public class VideoDetailFragment | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private void setOverlayPlayPauseImage() { | ||||
|         final int attr = player != null && player.isPlaying() | ||||
|     private void setOverlayPlayPauseImage(final boolean playerIsPlaying) { | ||||
|         final int attr = playerIsPlaying | ||||
|                 ? R.attr.ic_pause | ||||
|                 : R.attr.ic_play_arrow; | ||||
|         overlayPlayPauseButton.setImageResource( | ||||
|   | ||||
| @@ -255,9 +255,9 @@ public class VideoPlayerImpl extends VideoPlayer | ||||
|             onQueueClosed(); | ||||
|             // Android TV: without it focus will frame the whole player | ||||
|             playPauseButton.requestFocus(); | ||||
|             onPlay(); | ||||
|         } | ||||
|  | ||||
|         onPlay(); | ||||
|         NavigationHelper.sendPlayerStartedEvent(service); | ||||
|     } | ||||
|  | ||||
|     VideoPlayerImpl(final MainPlayer service) { | ||||
| @@ -662,6 +662,7 @@ public class VideoPlayerImpl extends VideoPlayer | ||||
|     @Override | ||||
|     public void onPlayQueueEdited() { | ||||
|         updatePlayback(); | ||||
|         showOrHideButtons(); | ||||
|         NotificationUtil.getInstance().createNotificationIfNeededAndUpdate(this, false); | ||||
|     } | ||||
|  | ||||
| @@ -1455,15 +1456,16 @@ public class VideoPlayerImpl extends VideoPlayer | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         playPreviousButton.setVisibility(playQueue.getIndex() == 0 | ||||
|                 ? View.INVISIBLE | ||||
|                 : View.VISIBLE); | ||||
|         playNextButton.setVisibility(playQueue.getIndex() + 1 == playQueue.getStreams().size() | ||||
|                 ? View.INVISIBLE | ||||
|                 : View.VISIBLE); | ||||
|         queueButton.setVisibility(playQueue.getStreams().size() <= 1 || popupPlayerSelected() | ||||
|                 ? View.GONE | ||||
|                 : View.VISIBLE); | ||||
|         final boolean showPrev = playQueue.getIndex() != 0; | ||||
|         final boolean showNext = playQueue.getIndex() + 1 != playQueue.getStreams().size(); | ||||
|         final boolean showQueue = playQueue.getStreams().size() > 1 && !popupPlayerSelected(); | ||||
|  | ||||
|         playPreviousButton.setVisibility(showPrev ? View.VISIBLE : View.INVISIBLE); | ||||
|         playPreviousButton.setAlpha(showPrev ? 1.0f : 0.0f); | ||||
|         playNextButton.setVisibility(showNext ? View.VISIBLE : View.INVISIBLE); | ||||
|         playNextButton.setAlpha(showNext ? 1.0f : 0.0f); | ||||
|         queueButton.setVisibility(showQueue ? View.VISIBLE : View.GONE); | ||||
|         queueButton.setAlpha(showQueue ? 1.0f : 0.0f); | ||||
|     } | ||||
|  | ||||
|     private void showSystemUIPartially() { | ||||
| @@ -1936,6 +1938,7 @@ public class VideoPlayerImpl extends VideoPlayer | ||||
|             getControlsRoot().setPadding(0, 0, 0, 0); | ||||
|         } | ||||
|         queueLayout.setPadding(0, 0, 0, 0); | ||||
|         updateQueue(); | ||||
|         updateMetadata(); | ||||
|         updatePlayback(); | ||||
|         triggerProgressUpdate(); | ||||
|   | ||||
| @@ -384,8 +384,19 @@ public final class NavigationHelper { | ||||
|     } | ||||
|  | ||||
|     public static void expandMainPlayer(final Context context) { | ||||
|         final Intent intent = new Intent(VideoDetailFragment.ACTION_SHOW_MAIN_PLAYER); | ||||
|         context.sendBroadcast(intent); | ||||
|         context.sendBroadcast(new Intent(VideoDetailFragment.ACTION_SHOW_MAIN_PLAYER)); | ||||
|     } | ||||
|  | ||||
|     public static void sendPlayerStartedEvent(final Context context) { | ||||
|         context.sendBroadcast(new Intent(VideoDetailFragment.ACTION_PLAYER_STARTED)); | ||||
|     } | ||||
|  | ||||
|     public static void showMiniPlayer(final FragmentManager fragmentManager) { | ||||
|         final VideoDetailFragment instance = VideoDetailFragment.getInstanceInCollapsedState(); | ||||
|         defaultTransaction(fragmentManager) | ||||
|                 .replace(R.id.fragment_player_holder, instance) | ||||
|                 .runOnCommit(() -> sendPlayerStartedEvent(instance.requireActivity())) | ||||
|                 .commit(); | ||||
|     } | ||||
|  | ||||
|     public static void openChannelFragment(final FragmentManager fragmentManager, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Tobias Groza
					Tobias Groza