From 69fc571b5618fd66e4d40b5420e49b1c6e6c5a3b Mon Sep 17 00:00:00 2001 From: Mauricio Colli Date: Tue, 21 Aug 2018 23:04:46 -0300 Subject: [PATCH 01/60] Add overlay to close popup --- .../newpipe/player/PopupVideoPlayer.java | 280 +++++++++++++----- app/src/main/res/layout/player_popup.xml | 8 +- .../res/layout/player_popup_close_overlay.xml | 18 ++ 3 files changed, 231 insertions(+), 75 deletions(-) create mode 100644 app/src/main/res/layout/player_popup_close_overlay.xml diff --git a/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java b/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java index 86998e0ea..37a9e917e 100644 --- a/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java +++ b/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java @@ -19,6 +19,8 @@ package org.schabi.newpipe.player; +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; import android.annotation.SuppressLint; import android.app.NotificationManager; import android.app.PendingIntent; @@ -34,6 +36,7 @@ import android.os.Build; import android.os.IBinder; import android.preference.PreferenceManager; import android.support.annotation.NonNull; +import android.support.design.widget.FloatingActionButton; import android.support.v4.app.NotificationCompat; import android.util.DisplayMetrics; import android.util.Log; @@ -41,7 +44,9 @@ import android.view.GestureDetector; import android.view.Gravity; import android.view.MotionEvent; import android.view.View; +import android.view.ViewGroup; import android.view.WindowManager; +import android.view.animation.AnticipateInterpolator; import android.widget.ImageButton; import android.widget.ImageView; import android.widget.PopupMenu; @@ -104,8 +109,12 @@ public final class PopupVideoPlayer extends Service { WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON; private WindowManager windowManager; - private WindowManager.LayoutParams windowLayoutParams; - private GestureDetector gestureDetector; + private WindowManager.LayoutParams popupLayoutParams; + private GestureDetector popupGestureDetector; + + private View closeOverlayView; + private FloatingActionButton closeOverlayButton; + private WindowManager.LayoutParams closeOverlayLayoutParams; private int shutdownFlingVelocity; private int tossFlingVelocity; @@ -122,6 +131,7 @@ public final class PopupVideoPlayer extends Service { private VideoPlayerImpl playerImpl; private LockManager lockManager; + private boolean isPopupClosing = false; /*////////////////////////////////////////////////////////////////////////// // Service-Activity Binder @@ -150,7 +160,10 @@ public final class PopupVideoPlayer extends Service { public int onStartCommand(final Intent intent, int flags, int startId) { if (DEBUG) Log.d(TAG, "onStartCommand() called with: intent = [" + intent + "], flags = [" + flags + "], startId = [" + startId + "]"); - if (playerImpl.getPlayer() == null) initPopup(); + if (playerImpl.getPlayer() == null) { + initPopup(); + initPopupCloseOverlay(); + } if (!playerImpl.isPlaying()) playerImpl.getPlayer().setPlayWhenReady(true); playerImpl.handleIntent(intent); @@ -160,15 +173,16 @@ public final class PopupVideoPlayer extends Service { @Override public void onConfigurationChanged(Configuration newConfig) { + if (DEBUG) Log.d(TAG, "onConfigurationChanged() called with: newConfig = [" + newConfig + "]"); updateScreenSize(); - updatePopupSize(windowLayoutParams.width, -1); + updatePopupSize(popupLayoutParams.width, -1); checkPositionBounds(); } @Override public void onDestroy() { if (DEBUG) Log.d(TAG, "onDestroy() called"); - onClose(); + closePopup(); } @Override @@ -200,27 +214,52 @@ public final class PopupVideoPlayer extends Service { WindowManager.LayoutParams.TYPE_PHONE : WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; - windowLayoutParams = new WindowManager.LayoutParams( + popupLayoutParams = new WindowManager.LayoutParams( (int) popupWidth, (int) getMinimumVideoHeight(popupWidth), layoutParamType, IDLE_WINDOW_FLAGS, PixelFormat.TRANSLUCENT); - windowLayoutParams.gravity = Gravity.LEFT | Gravity.TOP; - windowLayoutParams.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE; + popupLayoutParams.gravity = Gravity.LEFT | Gravity.TOP; + popupLayoutParams.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE; int centerX = (int) (screenWidth / 2f - popupWidth / 2f); int centerY = (int) (screenHeight / 2f - popupHeight / 2f); - windowLayoutParams.x = popupRememberSizeAndPos ? sharedPreferences.getInt(POPUP_SAVED_X, centerX) : centerX; - windowLayoutParams.y = popupRememberSizeAndPos ? sharedPreferences.getInt(POPUP_SAVED_Y, centerY) : centerY; + popupLayoutParams.x = popupRememberSizeAndPos ? sharedPreferences.getInt(POPUP_SAVED_X, centerX) : centerX; + popupLayoutParams.y = popupRememberSizeAndPos ? sharedPreferences.getInt(POPUP_SAVED_Y, centerY) : centerY; checkPositionBounds(); - MySimpleOnGestureListener listener = new MySimpleOnGestureListener(); - gestureDetector = new GestureDetector(this, listener); + PopupWindowGestureListener listener = new PopupWindowGestureListener(); + popupGestureDetector = new GestureDetector(this, listener); rootView.setOnTouchListener(listener); - playerImpl.getLoadingPanel().setMinimumWidth(windowLayoutParams.width); - playerImpl.getLoadingPanel().setMinimumHeight(windowLayoutParams.height); - windowManager.addView(rootView, windowLayoutParams); + + playerImpl.getLoadingPanel().setMinimumWidth(popupLayoutParams.width); + playerImpl.getLoadingPanel().setMinimumHeight(popupLayoutParams.height); + windowManager.addView(rootView, popupLayoutParams); + } + + @SuppressLint("RtlHardcoded") + private void initPopupCloseOverlay() { + if (DEBUG) Log.d(TAG, "initPopupCloseOverlay() called"); + closeOverlayView = View.inflate(this, R.layout.player_popup_close_overlay, null); + closeOverlayButton = closeOverlayView.findViewById(R.id.closeButton); + + final int layoutParamType = Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.O ? + WindowManager.LayoutParams.TYPE_PHONE : + WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; + final int flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE + | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; + + closeOverlayLayoutParams = new WindowManager.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, + layoutParamType, + flags, + PixelFormat.TRANSLUCENT); + closeOverlayLayoutParams.gravity = Gravity.LEFT | Gravity.TOP; + closeOverlayLayoutParams.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE; + + closeOverlayButton.setVisibility(View.GONE); + windowManager.addView(closeOverlayView, closeOverlayLayoutParams); } /*////////////////////////////////////////////////////////////////////////// @@ -280,24 +319,54 @@ public final class PopupVideoPlayer extends Service { // Misc //////////////////////////////////////////////////////////////////////////*/ - public void onClose() { - if (DEBUG) Log.d(TAG, "onClose() called"); + public void closePopup() { + if (DEBUG) Log.d(TAG, "closePopup() called, isPopupClosing = " + isPopupClosing); + if (isPopupClosing) return; + isPopupClosing = true; if (playerImpl != null) { if (playerImpl.getRootView() != null) { windowManager.removeView(playerImpl.getRootView()); - playerImpl.setRootView(null); } + playerImpl.setRootView(null); playerImpl.stopActivityBinding(); playerImpl.destroy(); + playerImpl = null; } + + mBinder = null; if (lockManager != null) lockManager.releaseWifiAndCpu(); if (notificationManager != null) notificationManager.cancel(NOTIFICATION_ID); - mBinder = null; - playerImpl = null; - stopForeground(true); - stopSelf(); + animateOverlayAndFinishService(); + } + + private void animateOverlayAndFinishService() { + final int targetTranslationY = (int) (closeOverlayButton.getRootView().getHeight() - closeOverlayButton.getY()); + + closeOverlayButton.animate().setListener(null).cancel(); + closeOverlayButton.animate() + .setInterpolator(new AnticipateInterpolator()) + .translationY(targetTranslationY) + .setDuration(400) + .setListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationCancel(Animator animation) { + end(); + } + + @Override + public void onAnimationEnd(Animator animation) { + end(); + } + + private void end() { + windowManager.removeView(closeOverlayView); + + stopForeground(true); + stopSelf(); + } + }).start(); } /*////////////////////////////////////////////////////////////////////////// @@ -305,19 +374,21 @@ public final class PopupVideoPlayer extends Service { //////////////////////////////////////////////////////////////////////////*/ private void checkPositionBounds() { - if (windowLayoutParams.x > screenWidth - windowLayoutParams.width) - windowLayoutParams.x = (int) (screenWidth - windowLayoutParams.width); - if (windowLayoutParams.x < 0) windowLayoutParams.x = 0; - if (windowLayoutParams.y > screenHeight - windowLayoutParams.height) - windowLayoutParams.y = (int) (screenHeight - windowLayoutParams.height); - if (windowLayoutParams.y < 0) windowLayoutParams.y = 0; + if (DEBUG) Log.d(TAG, "checkPositionBounds() called"); + if (popupLayoutParams.x > screenWidth - popupLayoutParams.width) + popupLayoutParams.x = (int) (screenWidth - popupLayoutParams.width); + if (popupLayoutParams.x < 0) popupLayoutParams.x = 0; + + if (popupLayoutParams.y > screenHeight - popupLayoutParams.height) + popupLayoutParams.y = (int) (screenHeight - popupLayoutParams.height); + if (popupLayoutParams.y < 0) popupLayoutParams.y = 0; } private void savePositionAndSize() { SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(PopupVideoPlayer.this); - sharedPreferences.edit().putInt(POPUP_SAVED_X, windowLayoutParams.x).apply(); - sharedPreferences.edit().putInt(POPUP_SAVED_Y, windowLayoutParams.y).apply(); - sharedPreferences.edit().putFloat(POPUP_SAVED_WIDTH, windowLayoutParams.width).apply(); + sharedPreferences.edit().putInt(POPUP_SAVED_X, popupLayoutParams.x).apply(); + sharedPreferences.edit().putInt(POPUP_SAVED_Y, popupLayoutParams.y).apply(); + sharedPreferences.edit().putFloat(POPUP_SAVED_WIDTH, popupLayoutParams.width).apply(); } private float getMinimumVideoHeight(float width) { @@ -352,13 +423,13 @@ public final class PopupVideoPlayer extends Service { if (height == -1) height = (int) getMinimumVideoHeight(width); else height = (int) (height > maximumHeight ? maximumHeight : height < minimumHeight ? minimumHeight : height); - windowLayoutParams.width = width; - windowLayoutParams.height = height; + popupLayoutParams.width = width; + popupLayoutParams.height = height; popupWidth = width; popupHeight = height; if (DEBUG) Log.d(TAG, "updatePopupSize() updated values: width = [" + width + "], height = [" + height + "]"); - windowManager.updateViewLayout(playerImpl.getRootView(), windowLayoutParams); + windowManager.updateViewLayout(playerImpl.getRootView(), popupLayoutParams); } protected void setRepeatModeRemote(final RemoteViews remoteViews, final int repeatMode) { @@ -380,10 +451,10 @@ public final class PopupVideoPlayer extends Service { } private void updateWindowFlags(final int flags) { - if (windowLayoutParams == null || windowManager == null || playerImpl == null) return; + if (popupLayoutParams == null || windowManager == null || playerImpl == null) return; - windowLayoutParams.flags = flags; - windowManager.updateViewLayout(playerImpl.getRootView(), windowLayoutParams); + popupLayoutParams.flags = flags; + windowManager.updateViewLayout(playerImpl.getRootView(), popupLayoutParams); } /////////////////////////////////////////////////////////////////////////// @@ -393,6 +464,7 @@ public final class PopupVideoPlayer extends Service { private ImageView videoPlayPause; private View extraOptionsView; + private View closingOverlayView; @Override public void handleIntent(Intent intent) { @@ -413,12 +485,18 @@ public final class PopupVideoPlayer extends Service { fullScreenButton = rootView.findViewById(R.id.fullScreenButton); fullScreenButton.setOnClickListener(v -> onFullScreenButtonClicked()); videoPlayPause = rootView.findViewById(R.id.videoPlayPause); - videoPlayPause.setOnClickListener(this::onPlayPauseButtonPressed); extraOptionsView = rootView.findViewById(R.id.extraOptionsView); + closingOverlayView = rootView.findViewById(R.id.closingOverlay); rootView.addOnLayoutChangeListener(this); } + @Override + public void initListeners() { + super.initListeners(); + videoPlayPause.setOnClickListener(v -> onPlayPause()); + } + @Override protected void setupSubtitleView(@NonNull SubtitleView view, final float captionScale, @@ -429,10 +507,6 @@ public final class PopupVideoPlayer extends Service { view.setStyle(captionStyle); } - private void onPlayPauseButtonPressed(View ib) { - onPlayPause(); - } - @Override public void onLayoutChange(final View view, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { @@ -476,7 +550,7 @@ public final class PopupVideoPlayer extends Service { intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); } context.startActivity(intent); - onClose(); + closePopup(); } @Override @@ -634,7 +708,7 @@ public final class PopupVideoPlayer extends Service { @Override public void onPlaybackShutdown() { super.onPlaybackShutdown(); - onClose(); + closePopup(); } /*////////////////////////////////////////////////////////////////////////// @@ -660,7 +734,7 @@ public final class PopupVideoPlayer extends Service { if (DEBUG) Log.d(TAG, "onBroadcastReceived() called with: intent = [" + intent + "]"); switch (intent.getAction()) { case ACTION_CLOSE: - onClose(); + closePopup(); break; case ACTION_PLAY_PAUSE: onPlayPause(); @@ -791,12 +865,15 @@ public final class PopupVideoPlayer extends Service { public TextView getResizingIndicator() { return resizingIndicator; } + + public View getClosingOverlayView() { + return closingOverlayView; + } } - private class MySimpleOnGestureListener extends GestureDetector.SimpleOnGestureListener implements View.OnTouchListener { + private class PopupWindowGestureListener extends GestureDetector.SimpleOnGestureListener implements View.OnTouchListener { private int initialPopupX, initialPopupY; private boolean isMoving; - private boolean isResizing; @Override @@ -832,10 +909,10 @@ public final class PopupVideoPlayer extends Service { @Override public boolean onDown(MotionEvent e) { if (DEBUG) Log.d(TAG, "onDown() called with: e = [" + e + "]"); - initialPopupX = windowLayoutParams.x; - initialPopupY = windowLayoutParams.y; - popupWidth = windowLayoutParams.width; - popupHeight = windowLayoutParams.height; + initialPopupX = popupLayoutParams.x; + initialPopupY = popupLayoutParams.y; + popupWidth = popupLayoutParams.width; + popupHeight = popupLayoutParams.height; return super.onDown(e); } @@ -848,15 +925,20 @@ public final class PopupVideoPlayer extends Service { } @Override - public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { - if (isResizing || playerImpl == null) return super.onScroll(e1, e2, distanceX, distanceY); + public boolean onScroll(MotionEvent initialEvent, MotionEvent movingEvent, float distanceX, float distanceY) { + if (isResizing || playerImpl == null) return super.onScroll(initialEvent, movingEvent, distanceX, distanceY); if (playerImpl.getCurrentState() != BasePlayer.STATE_BUFFERING && (!isMoving || playerImpl.getControlsRoot().getAlpha() != 1f)) playerImpl.showControls(0); + + if (!isMoving) { + animateView(closeOverlayButton, true, 200); + } + isMoving = true; - float diffX = (int) (e2.getRawX() - e1.getRawX()), posX = (int) (initialPopupX + diffX); - float diffY = (int) (e2.getRawY() - e1.getRawY()), posY = (int) (initialPopupY + diffY); + float diffX = (int) (movingEvent.getRawX() - initialEvent.getRawX()), posX = (int) (initialPopupX + diffX); + float diffY = (int) (movingEvent.getRawY() - initialEvent.getRawY()), posY = (int) (initialPopupY + diffY); if (posX > (screenWidth - popupWidth)) posX = (int) (screenWidth - popupWidth); else if (posX < 0) posX = 0; @@ -864,26 +946,49 @@ public final class PopupVideoPlayer extends Service { if (posY > (screenHeight - popupHeight)) posY = (int) (screenHeight - popupHeight); else if (posY < 0) posY = 0; - windowLayoutParams.x = (int) posX; - windowLayoutParams.y = (int) posY; + popupLayoutParams.x = (int) posX; + popupLayoutParams.y = (int) posY; + + final View closingOverlayView = playerImpl.getClosingOverlayView(); + if (isInsideClosingRadius(movingEvent)) { + if (closingOverlayView.getVisibility() == View.GONE) { + animateView(closingOverlayView, true, 250); + } + } else { + if (closingOverlayView.getVisibility() == View.VISIBLE) { + animateView(closingOverlayView, false, 0); + } + } //noinspection PointlessBooleanExpression - if (DEBUG && false) Log.d(TAG, "PopupVideoPlayer.onScroll = " + - ", e1.getRaw = [" + e1.getRawX() + ", " + e1.getRawY() + "]" + - ", e2.getRaw = [" + e2.getRawX() + ", " + e2.getRawY() + "]" + - ", distanceXy = [" + distanceX + ", " + distanceY + "]" + - ", posXy = [" + posX + ", " + posY + "]" + - ", popupWh = [" + popupWidth + " x " + popupHeight + "]"); - windowManager.updateViewLayout(playerImpl.getRootView(), windowLayoutParams); + if (DEBUG && false) { + Log.d(TAG, "PopupVideoPlayer.onScroll = " + + ", e1.getRaw = [" + initialEvent.getRawX() + ", " + initialEvent.getRawY() + "]" + ", e1.getX,Y = [" + initialEvent.getX() + ", " + initialEvent.getY() + "]" + + ", e2.getRaw = [" + movingEvent.getRawX() + ", " + movingEvent.getRawY() + "]" + ", e2.getX,Y = [" + movingEvent.getX() + ", " + movingEvent.getY() + "]" + + ", distanceX,Y = [" + distanceX + ", " + distanceY + "]" + + ", posX,Y = [" + posX + ", " + posY + "]" + + ", popupW,H = [" + popupWidth + " x " + popupHeight + "]"); + } + windowManager.updateViewLayout(playerImpl.getRootView(), popupLayoutParams); return true; } - private void onScrollEnd() { + private void onScrollEnd(MotionEvent event) { if (DEBUG) Log.d(TAG, "onScrollEnd() called"); if (playerImpl == null) return; if (playerImpl.isControlsVisible() && playerImpl.getCurrentState() == STATE_PLAYING) { playerImpl.hideControls(DEFAULT_CONTROLS_DURATION, DEFAULT_CONTROLS_HIDE_TIME); } + + if (isInsideClosingRadius(event)) { + closePopup(); + } else { + animateView(playerImpl.getClosingOverlayView(), false, 0); + + if (!isPopupClosing) { + animateView(closeOverlayButton, false, 200); + } + } } @Override @@ -894,13 +999,13 @@ public final class PopupVideoPlayer extends Service { final float absVelocityX = Math.abs(velocityX); final float absVelocityY = Math.abs(velocityY); if (absVelocityX > shutdownFlingVelocity) { - onClose(); + closePopup(); return true; } else if (Math.max(absVelocityX, absVelocityY) > tossFlingVelocity) { - if (absVelocityX > tossFlingVelocity) windowLayoutParams.x = (int) velocityX; - if (absVelocityY > tossFlingVelocity) windowLayoutParams.y = (int) velocityY; + if (absVelocityX > tossFlingVelocity) popupLayoutParams.x = (int) velocityX; + if (absVelocityY > tossFlingVelocity) popupLayoutParams.y = (int) velocityY; checkPositionBounds(); - windowManager.updateViewLayout(playerImpl.getRootView(), windowLayoutParams); + windowManager.updateViewLayout(playerImpl.getRootView(), popupLayoutParams); return true; } return false; @@ -908,7 +1013,7 @@ public final class PopupVideoPlayer extends Service { @Override public boolean onTouch(View v, MotionEvent event) { - gestureDetector.onTouchEvent(event); + popupGestureDetector.onTouchEvent(event); if (playerImpl == null) return false; if (event.getPointerCount() == 2 && !isResizing) { if (DEBUG) Log.d(TAG, "onTouch() 2 finger pointer detected, enabling resizing."); @@ -931,7 +1036,7 @@ public final class PopupVideoPlayer extends Service { Log.d(TAG, "onTouch() ACTION_UP > v = [" + v + "], e1.getRaw = [" + event.getRawX() + ", " + event.getRawY() + "]"); if (isMoving) { isMoving = false; - onScrollEnd(); + onScrollEnd(event); } if (isResizing) { @@ -939,7 +1044,10 @@ public final class PopupVideoPlayer extends Service { animateView(playerImpl.getResizingIndicator(), false, 100, 0); playerImpl.changeState(playerImpl.getCurrentState()); } - savePositionAndSize(); + + if (!isPopupClosing) { + savePositionAndSize(); + } } v.performClick(); @@ -955,10 +1063,10 @@ public final class PopupVideoPlayer extends Service { final float diff = Math.abs(firstPointerX - secondPointerX); if (firstPointerX > secondPointerX) { // second pointer is the anchor (the leftmost pointer) - windowLayoutParams.x = (int) (event.getRawX() - diff); + popupLayoutParams.x = (int) (event.getRawX() - diff); } else { // first pointer is the anchor - windowLayoutParams.x = (int) event.getRawX(); + popupLayoutParams.x = (int) event.getRawX(); } checkPositionBounds(); @@ -969,5 +1077,29 @@ public final class PopupVideoPlayer extends Service { return true; } + + /*////////////////////////////////////////////////////////////////////////// + // Utils + //////////////////////////////////////////////////////////////////////////*/ + + private int distanceFromCloseButton(MotionEvent popupMotionEvent) { + final int closeOverlayButtonX = closeOverlayButton.getLeft() + closeOverlayButton.getWidth() / 2; + final int closeOverlayButtonY = closeOverlayButton.getTop() + closeOverlayButton.getHeight() / 2; + + float fingerX = popupLayoutParams.x + popupMotionEvent.getX(); + float fingerY = popupLayoutParams.y + popupMotionEvent.getY(); + + return (int) Math.sqrt(Math.pow(closeOverlayButtonX - fingerX, 2) + Math.pow(closeOverlayButtonY - fingerY, 2)); + } + + private float getClosingRadius() { + final int buttonRadius = closeOverlayButton.getWidth() / 2; + // 20% wider than the button itself + return buttonRadius * 1.2f; + } + + private boolean isInsideClosingRadius(MotionEvent popupMotionEvent) { + return distanceFromCloseButton(popupMotionEvent) <= getClosingRadius(); + } } } \ No newline at end of file diff --git a/app/src/main/res/layout/player_popup.xml b/app/src/main/res/layout/player_popup.xml index 001d43bf6..7a92c6712 100644 --- a/app/src/main/res/layout/player_popup.xml +++ b/app/src/main/res/layout/player_popup.xml @@ -9,7 +9,6 @@ tools:layout_height="84dp" tools:layout_width="@dimen/popup_minimum_width"> - + + \ No newline at end of file diff --git a/app/src/main/res/layout/player_popup_close_overlay.xml b/app/src/main/res/layout/player_popup_close_overlay.xml new file mode 100644 index 000000000..f7aceadec --- /dev/null +++ b/app/src/main/res/layout/player_popup_close_overlay.xml @@ -0,0 +1,18 @@ + + + + + \ No newline at end of file From a01d6eaf72fd83b3320d6c6ab23d30550ad828d8 Mon Sep 17 00:00:00 2001 From: Mauricio Colli Date: Tue, 21 Aug 2018 23:04:52 -0300 Subject: [PATCH 02/60] Don't make controls visible when moving popup --- .../main/java/org/schabi/newpipe/player/PopupVideoPlayer.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java b/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java index 37a9e917e..2d943ea11 100644 --- a/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java +++ b/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java @@ -928,9 +928,6 @@ public final class PopupVideoPlayer extends Service { public boolean onScroll(MotionEvent initialEvent, MotionEvent movingEvent, float distanceX, float distanceY) { if (isResizing || playerImpl == null) return super.onScroll(initialEvent, movingEvent, distanceX, distanceY); - if (playerImpl.getCurrentState() != BasePlayer.STATE_BUFFERING - && (!isMoving || playerImpl.getControlsRoot().getAlpha() != 1f)) playerImpl.showControls(0); - if (!isMoving) { animateView(closeOverlayButton, true, 200); } From 8a29cfbb7e109a82ba48dc24deacb54729edb4c2 Mon Sep 17 00:00:00 2001 From: Mauricio Colli Date: Tue, 21 Aug 2018 23:04:52 -0300 Subject: [PATCH 03/60] Remove popup shutdown gesture in favor of the new close overlay --- .../java/org/schabi/newpipe/player/PopupVideoPlayer.java | 7 +------ .../org/schabi/newpipe/player/helper/PlayerHelper.java | 4 ---- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java b/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java index 2d943ea11..bf1669e6e 100644 --- a/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java +++ b/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java @@ -116,7 +116,6 @@ public final class PopupVideoPlayer extends Service { private FloatingActionButton closeOverlayButton; private WindowManager.LayoutParams closeOverlayLayoutParams; - private int shutdownFlingVelocity; private int tossFlingVelocity; private float screenWidth, screenHeight; @@ -200,7 +199,6 @@ public final class PopupVideoPlayer extends Service { View rootView = View.inflate(this, R.layout.player_popup, null); playerImpl.setup(rootView); - shutdownFlingVelocity = PlayerHelper.getShutdownFlingVelocity(this); tossFlingVelocity = PlayerHelper.getTossFlingVelocity(this); updateScreenSize(); @@ -995,10 +993,7 @@ public final class PopupVideoPlayer extends Service { final float absVelocityX = Math.abs(velocityX); final float absVelocityY = Math.abs(velocityY); - if (absVelocityX > shutdownFlingVelocity) { - closePopup(); - return true; - } else if (Math.max(absVelocityX, absVelocityY) > tossFlingVelocity) { + if (Math.max(absVelocityX, absVelocityY) > tossFlingVelocity) { if (absVelocityX > tossFlingVelocity) popupLayoutParams.x = (int) velocityX; if (absVelocityY > tossFlingVelocity) popupLayoutParams.y = (int) velocityY; checkPositionBounds(); diff --git a/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHelper.java b/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHelper.java index 275f488e3..ae187a834 100644 --- a/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHelper.java +++ b/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHelper.java @@ -251,10 +251,6 @@ public class PlayerHelper { return true; } - public static int getShutdownFlingVelocity(@NonNull final Context context) { - return 6000; - } - public static int getTossFlingVelocity(@NonNull final Context context) { return 2500; } From 3887231c73bb165790bc1929067743f7457834c1 Mon Sep 17 00:00:00 2001 From: Mauricio Colli Date: Wed, 22 Aug 2018 23:45:25 -0300 Subject: [PATCH 04/60] Fix popup position when draggable area is resized A common case where this happens is when the soft input is visible. --- .../newpipe/player/PopupVideoPlayer.java | 60 +++++++++++++++---- 1 file changed, 47 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java b/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java index bf1669e6e..0e7328020 100644 --- a/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java +++ b/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java @@ -175,7 +175,7 @@ public final class PopupVideoPlayer extends Service { if (DEBUG) Log.d(TAG, "onConfigurationChanged() called with: newConfig = [" + newConfig + "]"); updateScreenSize(); updatePopupSize(popupLayoutParams.width, -1); - checkPositionBounds(); + checkPopupPositionBounds(); } @Override @@ -225,7 +225,7 @@ public final class PopupVideoPlayer extends Service { popupLayoutParams.x = popupRememberSizeAndPos ? sharedPreferences.getInt(POPUP_SAVED_X, centerX) : centerX; popupLayoutParams.y = popupRememberSizeAndPos ? sharedPreferences.getInt(POPUP_SAVED_Y, centerY) : centerY; - checkPositionBounds(); + checkPopupPositionBounds(); PopupWindowGestureListener listener = new PopupWindowGestureListener(); popupGestureDetector = new GestureDetector(this, listener); @@ -371,15 +371,44 @@ public final class PopupVideoPlayer extends Service { // Utils //////////////////////////////////////////////////////////////////////////*/ - private void checkPositionBounds() { - if (DEBUG) Log.d(TAG, "checkPositionBounds() called"); - if (popupLayoutParams.x > screenWidth - popupLayoutParams.width) - popupLayoutParams.x = (int) (screenWidth - popupLayoutParams.width); - if (popupLayoutParams.x < 0) popupLayoutParams.x = 0; + /** + * @see #checkPopupPositionBounds(float, float) + */ + @SuppressWarnings("UnusedReturnValue") + private boolean checkPopupPositionBounds() { + return checkPopupPositionBounds(screenWidth, screenHeight); + } - if (popupLayoutParams.y > screenHeight - popupLayoutParams.height) - popupLayoutParams.y = (int) (screenHeight - popupLayoutParams.height); - if (popupLayoutParams.y < 0) popupLayoutParams.y = 0; + /** + * Check if {@link #popupLayoutParams}' position is within a arbitrary boundary that goes from (0,0) to (boundaryWidth,boundaryHeight). + *

+ * If it's out of these boundaries, {@link #popupLayoutParams}' position is changed and {@code true} is returned + * to represent this change. + * + * @return if the popup was out of bounds and have been moved back to it + */ + private boolean checkPopupPositionBounds(final float boundaryWidth, final float boundaryHeight) { + if (DEBUG) { + Log.d(TAG, "checkPopupPositionBounds() called with: boundaryWidth = [" + boundaryWidth + "], boundaryHeight = [" + boundaryHeight + "]"); + } + + if (popupLayoutParams.x < 0) { + popupLayoutParams.x = 0; + return true; + } else if (popupLayoutParams.x > boundaryWidth - popupLayoutParams.width) { + popupLayoutParams.x = (int) (boundaryWidth - popupLayoutParams.width); + return true; + } + + if (popupLayoutParams.y < 0) { + popupLayoutParams.y = 0; + return true; + } else if (popupLayoutParams.y > boundaryHeight - popupLayoutParams.height) { + popupLayoutParams.y = (int) (boundaryHeight - popupLayoutParams.height); + return true; + } + + return false; } private void savePositionAndSize() { @@ -907,6 +936,11 @@ public final class PopupVideoPlayer extends Service { @Override public boolean onDown(MotionEvent e) { if (DEBUG) Log.d(TAG, "onDown() called with: e = [" + e + "]"); + + // Fix popup position when the user touch it, it may have the wrong one + // because the soft input is visible (the draggable area is currently resized). + checkPopupPositionBounds(closeOverlayView.getWidth(), closeOverlayView.getHeight()); + initialPopupX = popupLayoutParams.x; initialPopupY = popupLayoutParams.y; popupWidth = popupLayoutParams.width; @@ -918,7 +952,7 @@ public final class PopupVideoPlayer extends Service { public void onLongPress(MotionEvent e) { if (DEBUG) Log.d(TAG, "onLongPress() called with: e = [" + e + "]"); updateScreenSize(); - checkPositionBounds(); + checkPopupPositionBounds(); updatePopupSize((int) screenWidth, -1); } @@ -996,7 +1030,7 @@ public final class PopupVideoPlayer extends Service { if (Math.max(absVelocityX, absVelocityY) > tossFlingVelocity) { if (absVelocityX > tossFlingVelocity) popupLayoutParams.x = (int) velocityX; if (absVelocityY > tossFlingVelocity) popupLayoutParams.y = (int) velocityY; - checkPositionBounds(); + checkPopupPositionBounds(); windowManager.updateViewLayout(playerImpl.getRootView(), popupLayoutParams); return true; } @@ -1061,7 +1095,7 @@ public final class PopupVideoPlayer extends Service { popupLayoutParams.x = (int) event.getRawX(); } - checkPositionBounds(); + checkPopupPositionBounds(); updateScreenSize(); final int width = (int) Math.min(screenWidth, diff); From 4704274b877017a72221a58f66152c07bdbe9576 Mon Sep 17 00:00:00 2001 From: Somethingweirdhere Date: Fri, 8 Jun 2018 16:11:59 +0200 Subject: [PATCH 05/60] New Branch --- app/src/main/java/org/schabi/newpipe/MainActivity.java | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/org/schabi/newpipe/MainActivity.java b/app/src/main/java/org/schabi/newpipe/MainActivity.java index 191332e19..c2eb069d6 100644 --- a/app/src/main/java/org/schabi/newpipe/MainActivity.java +++ b/app/src/main/java/org/schabi/newpipe/MainActivity.java @@ -106,6 +106,7 @@ public class MainActivity extends AppCompatActivity { item.setIcon(ServiceHelper.getIcon(s.getServiceId())); } + drawerItems.getMenu().getItem(ServiceHelper.getSelectedServiceId(this)).setChecked(true); toggle = new ActionBarDrawerToggle(this, drawer, toolbar, From 54b21c716a4025fce1f382bc0db5094e3b73813f Mon Sep 17 00:00:00 2001 From: Somethingweirdhere Date: Fri, 8 Jun 2018 21:07:25 +0200 Subject: [PATCH 06/60] Added drawer menu --- .../java/org/schabi/newpipe/MainActivity.java | 146 +++++++++++++++--- .../local/bookmark/BookmarkFragment.java | 6 +- .../schabi/newpipe/util/KioskTranslator.java | 15 +- .../schabi/newpipe/util/NavigationHelper.java | 16 ++ app/src/main/res/layout/drawer_layout.xml | 23 --- app/src/main/res/menu/drawer_items.xml | 14 +- 6 files changed, 163 insertions(+), 57 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/MainActivity.java b/app/src/main/java/org/schabi/newpipe/MainActivity.java index c2eb069d6..d5a4bffd2 100644 --- a/app/src/main/java/org/schabi/newpipe/MainActivity.java +++ b/app/src/main/java/org/schabi/newpipe/MainActivity.java @@ -49,12 +49,15 @@ import android.widget.TextView; import org.schabi.newpipe.extractor.NewPipe; import org.schabi.newpipe.extractor.StreamingService; +import org.schabi.newpipe.extractor.exceptions.ExtractionException; import org.schabi.newpipe.fragments.BackPressable; import org.schabi.newpipe.fragments.MainFragment; import org.schabi.newpipe.fragments.detail.VideoDetailFragment; import org.schabi.newpipe.fragments.list.search.SearchFragment; import org.schabi.newpipe.report.ErrorActivity; +import org.schabi.newpipe.report.UserAction; import org.schabi.newpipe.util.Constants; +import org.schabi.newpipe.util.KioskTranslator; import org.schabi.newpipe.util.NavigationHelper; import org.schabi.newpipe.util.PermissionHelper; import org.schabi.newpipe.util.ServiceHelper; @@ -90,24 +93,70 @@ public class MainActivity extends AppCompatActivity { } setSupportActionBar(findViewById(R.id.toolbar)); - setupDrawer(); + try { + setupDrawer(); + } catch (Exception e) { + ErrorActivity.reportUiError(this, e); + } } - private void setupDrawer() { + private void setupDrawer() throws Exception { final Toolbar toolbar = findViewById(R.id.toolbar); drawer = findViewById(R.id.drawer_layout); drawerItems = findViewById(R.id.navigation); + //Services + for(StreamingService s : NewPipe.getServices()) { final String title = s.getServiceInfo().getName() + (ServiceHelper.isBeta(s) ? " (beta)" : ""); - final MenuItem item = drawerItems.getMenu() - .add(R.id.menu_services_group, s.getServiceId(), 0, title); - item.setIcon(ServiceHelper.getIcon(s.getServiceId())); + + drawerItems.getMenu() + .add(R.id.menu_services_group, s.getServiceId(), 0, title) + .setIcon(ServiceHelper.getIcon(s.getServiceId())); } + //Tabs - drawerItems.getMenu().getItem(ServiceHelper.getSelectedServiceId(this)).setChecked(true); + int currentServiceId = ServiceHelper.getSelectedServiceId(this); + StreamingService service = NewPipe.getService(currentServiceId); + + int kioskId = 0; + + for (final String ks : service.getKioskList().getAvailableKiosks()) { + drawerItems.getMenu() + .add(R.id.menu_tabs_group, kioskId, 0, KioskTranslator.getTranslatedKioskName(ks, this)) + .setIcon(KioskTranslator.getKioskIcons(ks, this)); + kioskId ++; + } + + drawerItems.getMenu() + .add(R.id.menu_tabs_group, -1, 0, R.string.tab_subscriptions) + .setIcon(ThemeHelper.resolveResourceIdFromAttr(this, R.attr.ic_channel)); + drawerItems.getMenu() + .add(R.id.menu_tabs_group, -2, 0, R.string.fragment_whats_new) + .setIcon(ThemeHelper.resolveResourceIdFromAttr(this, R.attr.rss)); + drawerItems.getMenu() + .add(R.id.menu_tabs_group, -3, 0, R.string.tab_bookmarks) + .setIcon(ThemeHelper.resolveResourceIdFromAttr(this, R.attr.ic_bookmark)); + drawerItems.getMenu() + .add(R.id.menu_tabs_group, -4, 0, R.string.downloads) + .setIcon(ThemeHelper.resolveResourceIdFromAttr(this, R.attr.download)); + drawerItems.getMenu() + .add(R.id.menu_tabs_group, -5, 0, R.string.action_history) + .setIcon(ThemeHelper.resolveResourceIdFromAttr(this, R.attr.history)); + + //Settings and About + + drawerItems.getMenu() + .add(R.id.menu_options_about_group, 0, 0, R.string.settings) + .setIcon(ThemeHelper.resolveResourceIdFromAttr(this, R.attr.settings)); + drawerItems.getMenu() + .add(R.id.menu_options_about_group, 1, 0, R.string.tab_about) + .setIcon(ThemeHelper.resolveResourceIdFromAttr(this, R.attr.info)); + + + drawerItems.getMenu().getItem(ServiceHelper.getSelectedServiceId(this)).setChecked(true); toggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.drawer_open, R.string.drawer_close) { @@ -140,32 +189,83 @@ public class MainActivity extends AppCompatActivity { } }); - drawerItems.setNavigationItemSelectedListener(this::changeService); - - setupDrawerFooter(); + drawerItems.setNavigationItemSelectedListener(this::drawerItemSelected); setupDrawerHeader(); } + private boolean drawerItemSelected(MenuItem item) { + switch (item.getGroupId()) { + case R.id.menu_services_group: + changeService(item); + break; + case R.id.menu_tabs_group: + try { + tabSelected(item); + } catch (Exception e) { + ErrorActivity.reportUiError(this, e); + } + break; + case R.id.menu_options_about_group: + optionsAboutSelected(item); + break; + default: + return false; + } - private boolean changeService(MenuItem item) { - if (item.getGroupId() != R.id.menu_services_group) - return false; - drawerItems.getMenu().getItem(ServiceHelper.getSelectedServiceId(this)).setChecked(false); - ServiceHelper.setSelectedServiceId(this, item.getItemId()); - drawerItems.getMenu().getItem(ServiceHelper.getSelectedServiceId(this)).setChecked(true); drawer.closeDrawers(); return true; } - private void setupDrawerFooter() { - ImageButton settings = findViewById(R.id.drawer_settings); - ImageButton downloads = findViewById(R.id.drawer_downloads); - ImageButton history = findViewById(R.id.drawer_history); + private void changeService(MenuItem item) { + drawerItems.getMenu().getItem(ServiceHelper.getSelectedServiceId(this)).setChecked(false); + ServiceHelper.setSelectedServiceId(this, item.getItemId()); + drawerItems.getMenu().getItem(ServiceHelper.getSelectedServiceId(this)).setChecked(true); + } - settings.setOnClickListener(view -> NavigationHelper.openSettings(this)); - downloads.setOnClickListener(view ->NavigationHelper.openDownloads(this)); - history.setOnClickListener(view -> - NavigationHelper.openStatisticFragment(getSupportFragmentManager())); + private void tabSelected(MenuItem item) throws ExtractionException { + switch(item.getItemId()) { + case -1: + NavigationHelper.openSubscriptionFragment(getSupportFragmentManager()); + break; + case -2: + NavigationHelper.openWhatsNewFragment(getSupportFragmentManager()); + break; + case -3: + NavigationHelper.openBookmarksFragment(getSupportFragmentManager()); + break; + case -4: + NavigationHelper.openDownloads(this); + break; + case -5: + NavigationHelper.openStatisticFragment(getSupportFragmentManager()); + break; + default: + int currentServiceId = ServiceHelper.getSelectedServiceId(this); + StreamingService service = NewPipe.getService(currentServiceId); + String serviceName = ""; + + int kioskId = 0; + for (final String ks : service.getKioskList().getAvailableKiosks()) { + if(kioskId == item.getItemId()) { + serviceName = ks; + } + kioskId ++; + } + + NavigationHelper.openKioskFragment(getSupportFragmentManager(), currentServiceId, serviceName); + break; + } + } + + private void optionsAboutSelected(MenuItem item) { + switch(item.getItemId()) { + case 0: + NavigationHelper.openSettings(this); + break; + case 1: + NavigationHelper.openAbout(this); + break; + } } private void setupDrawerHeader() { diff --git a/app/src/main/java/org/schabi/newpipe/local/bookmark/BookmarkFragment.java b/app/src/main/java/org/schabi/newpipe/local/bookmark/BookmarkFragment.java index 02eabd9ef..975028d0d 100644 --- a/app/src/main/java/org/schabi/newpipe/local/bookmark/BookmarkFragment.java +++ b/app/src/main/java/org/schabi/newpipe/local/bookmark/BookmarkFragment.java @@ -104,8 +104,10 @@ public final class BookmarkFragment public void selected(LocalItem selectedItem) { try { // Requires the parent fragment to find holder for fragment replacement - if (getParentFragment() == null) return; - final FragmentManager fragmentManager = getParentFragment().getFragmentManager(); + final FragmentManager fragmentManager = + getParentFragment() == null + ? getFragmentManager() + : getParentFragment().getFragmentManager(); if (selectedItem instanceof PlaylistMetadataEntry) { final PlaylistMetadataEntry entry = ((PlaylistMetadataEntry) selectedItem); diff --git a/app/src/main/java/org/schabi/newpipe/util/KioskTranslator.java b/app/src/main/java/org/schabi/newpipe/util/KioskTranslator.java index 4740b82e0..392892cef 100644 --- a/app/src/main/java/org/schabi/newpipe/util/KioskTranslator.java +++ b/app/src/main/java/org/schabi/newpipe/util/KioskTranslator.java @@ -24,7 +24,7 @@ import org.schabi.newpipe.R; public class KioskTranslator { public static String getTranslatedKioskName(String kioskId, Context c) { - switch(kioskId) { + switch (kioskId) { case "Trending": return c.getString(R.string.trending); case "Top 50": @@ -35,4 +35,17 @@ public class KioskTranslator { return kioskId; } } + + public static int getKioskIcons(String kioskId, Context c) { + switch(kioskId) { + case "Trending": + return ThemeHelper.resolveResourceIdFromAttr(c, R.attr.ic_hot); + case "Top 50": + return ThemeHelper.resolveResourceIdFromAttr(c, R.attr.ic_hot); + case "New & hot": + return ThemeHelper.resolveResourceIdFromAttr(c, R.attr.ic_hot); + default: + return 0; + } + } } diff --git a/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java b/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java index 85367e2a5..4556cfd7d 100644 --- a/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java +++ b/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java @@ -36,12 +36,14 @@ import org.schabi.newpipe.extractor.linkhandler.SearchQueryHandler; import org.schabi.newpipe.fragments.MainFragment; import org.schabi.newpipe.fragments.detail.VideoDetailFragment; import org.schabi.newpipe.fragments.list.channel.ChannelFragment; +import org.schabi.newpipe.local.bookmark.BookmarkFragment; import org.schabi.newpipe.local.feed.FeedFragment; import org.schabi.newpipe.fragments.list.kiosk.KioskFragment; import org.schabi.newpipe.fragments.list.playlist.PlaylistFragment; import org.schabi.newpipe.fragments.list.search.SearchFragment; import org.schabi.newpipe.local.history.StatisticsPlaylistFragment; import org.schabi.newpipe.local.playlist.LocalPlaylistFragment; +import org.schabi.newpipe.local.subscription.SubscriptionFragment; import org.schabi.newpipe.local.subscription.SubscriptionsImportFragment; import org.schabi.newpipe.player.BackgroundPlayer; import org.schabi.newpipe.player.BackgroundPlayerActivity; @@ -349,6 +351,20 @@ public class NavigationHelper { .commit(); } + public static void openBookmarksFragment(FragmentManager fragmentManager) { + defaultTransaction(fragmentManager) + .replace(R.id.fragment_holder, new BookmarkFragment()) + .addToBackStack(null) + .commit(); + } + + public static void openSubscriptionFragment(FragmentManager fragmentManager) { + defaultTransaction(fragmentManager) + .replace(R.id.fragment_holder, new SubscriptionFragment()) + .addToBackStack(null) + .commit(); + } + public static void openKioskFragment(FragmentManager fragmentManager, int serviceId, String kioskId) throws ExtractionException { defaultTransaction(fragmentManager) .replace(R.id.fragment_holder, KioskFragment.getInstance(serviceId, kioskId)) diff --git a/app/src/main/res/layout/drawer_layout.xml b/app/src/main/res/layout/drawer_layout.xml index c0186a02c..2eb3abe26 100644 --- a/app/src/main/res/layout/drawer_layout.xml +++ b/app/src/main/res/layout/drawer_layout.xml @@ -89,29 +89,6 @@ android:layout_alignEnd="@id/navigation" android:layout_alignParentBottom="true"> - - - - - \ No newline at end of file diff --git a/app/src/main/res/menu/drawer_items.xml b/app/src/main/res/menu/drawer_items.xml index ae4598edd..9d5e67bb4 100644 --- a/app/src/main/res/menu/drawer_items.xml +++ b/app/src/main/res/menu/drawer_items.xml @@ -2,13 +2,11 @@

- - + + + + \ No newline at end of file From edb75c4bab85bbe914a5c22a2bef880820b752e1 Mon Sep 17 00:00:00 2001 From: Somethingweirdhere Date: Fri, 8 Jun 2018 21:27:50 +0200 Subject: [PATCH 07/60] Fixed crash in Subscriptions section --- .../subscription/SubscriptionFragment.java | 31 ++++++++++++++++--- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionFragment.java b/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionFragment.java index c194069fb..bbd1150c4 100644 --- a/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionFragment.java +++ b/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionFragment.java @@ -13,6 +13,7 @@ import android.os.Parcelable; import android.support.annotation.DrawableRes; import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import android.support.v4.app.FragmentManager; import android.support.v4.content.LocalBroadcastManager; import android.support.v7.app.ActionBar; import android.support.v7.app.AppCompatActivity; @@ -241,8 +242,15 @@ public class SubscriptionFragment extends BaseStateFragment - NavigationHelper.openWhatsNewFragment(getParentFragment().getFragmentManager())); + { + FragmentManager fragmentManager; + + if (getParentFragment() == null) + { + fragmentManager = getFragmentManager(); + } else { + fragmentManager = getParentFragment().getFragmentManager(); + } + NavigationHelper.openWhatsNewFragment(fragmentManager); + }); importExportListHeader.setOnClickListener(v -> importExportOptions.switchState()); } From 8ecbe4c8adb734c4c6875e5cc30b7b49baa24c5d Mon Sep 17 00:00:00 2001 From: Somethingweirdhere Date: Sat, 9 Jun 2018 11:33:03 +0200 Subject: [PATCH 08/60] Created a dialog for the main page content --- .../java/org/schabi/newpipe/MainActivity.java | 14 --- .../newpipe/fragments/MainFragment.java | 106 ++---------------- .../settings/ContentSettingsDialog.java | 98 ++++++++++++++++ .../settings/ContentSettingsFragment.java | 11 ++ app/src/main/res/drawable-hdpi/ic_add.png | Bin 0 -> 246 bytes app/src/main/res/drawable-mdpi/ic_add.png | Bin 0 -> 176 bytes app/src/main/res/drawable-xhdpi/ic_add.png | Bin 0 -> 220 bytes app/src/main/res/drawable-xxhdpi/ic_add.png | Bin 0 -> 371 bytes .../res/layout/dialog_contentsettings.xml | 60 ++++++++++ .../res/layout/dialog_contentsettingtab.xml | 43 +++++++ app/src/main/res/menu/main_menu.xml | 27 ----- app/src/main/res/values/strings.xml | 3 + app/src/main/res/xml/content_settings.xml | 9 +- 13 files changed, 225 insertions(+), 146 deletions(-) create mode 100644 app/src/main/java/org/schabi/newpipe/settings/ContentSettingsDialog.java create mode 100644 app/src/main/res/drawable-hdpi/ic_add.png create mode 100644 app/src/main/res/drawable-mdpi/ic_add.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_add.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_add.png create mode 100644 app/src/main/res/layout/dialog_contentsettings.xml create mode 100644 app/src/main/res/layout/dialog_contentsettingtab.xml delete mode 100644 app/src/main/res/menu/main_menu.xml diff --git a/app/src/main/java/org/schabi/newpipe/MainActivity.java b/app/src/main/java/org/schabi/newpipe/MainActivity.java index d5a4bffd2..159ba38d2 100644 --- a/app/src/main/java/org/schabi/newpipe/MainActivity.java +++ b/app/src/main/java/org/schabi/newpipe/MainActivity.java @@ -417,9 +417,6 @@ public class MainActivity extends AppCompatActivity { if (!(fragment instanceof SearchFragment)) { findViewById(R.id.toolbar).findViewById(R.id.toolbar_search_container).setVisibility(View.GONE); - - MenuInflater inflater = getMenuInflater(); - inflater.inflate(R.menu.main_menu, menu); } ActionBar actionBar = getSupportActionBar(); @@ -441,17 +438,6 @@ public class MainActivity extends AppCompatActivity { case android.R.id.home: onHomeButtonPressed(); return true; - case R.id.action_show_downloads: - return NavigationHelper.openDownloads(this); - case R.id.action_history: - NavigationHelper.openStatisticFragment(getSupportFragmentManager()); - return true; - case R.id.action_about: - NavigationHelper.openAbout(this); - return true; - case R.id.action_settings: - NavigationHelper.openSettings(this); - return true; default: return super.onOptionsItemSelected(item); } diff --git a/app/src/main/java/org/schabi/newpipe/fragments/MainFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/MainFragment.java index 0e3312403..1665f7c5f 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/MainFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/MainFragment.java @@ -88,6 +88,8 @@ public class MainFragment extends BaseFragment implements TabLayout.OnTabSelecte int whatsHotIcon = ThemeHelper.resolveResourceIdFromAttr(activity, R.attr.ic_hot); int bookmarkIcon = ThemeHelper.resolveResourceIdFromAttr(activity, R.attr.ic_bookmark); + //assign proper icons to tabs + /* if (isSubscriptionsPageOnlySelected()) { tabLayout.getTabAt(0).setIcon(channelIcon); tabLayout.getTabAt(1).setIcon(bookmarkIcon); @@ -96,6 +98,7 @@ public class MainFragment extends BaseFragment implements TabLayout.OnTabSelecte tabLayout.getTabAt(1).setIcon(channelIcon); tabLayout.getTabAt(2).setIcon(bookmarkIcon); } + */ } /*////////////////////////////////////////////////////////////////////////// @@ -107,16 +110,6 @@ public class MainFragment extends BaseFragment implements TabLayout.OnTabSelecte super.onCreateOptionsMenu(menu, inflater); if (DEBUG) Log.d(TAG, "onCreateOptionsMenu() called with: menu = [" + menu + "], inflater = [" + inflater + "]"); inflater.inflate(R.menu.main_fragment_menu, menu); - SubMenu kioskMenu = menu.addSubMenu(Menu.NONE, Menu.NONE, 200, getString(R.string.kiosk)); - try { - createKioskMenu(kioskMenu, inflater); - } catch (Exception e) { - ErrorActivity.reportError(activity, e, - activity.getClass(), - null, - ErrorActivity.ErrorInfo.make(UserAction.UI_ERROR, - "none", "", R.string.app_ui_crash)); - } ActionBar supportActionBar = activity.getSupportActionBar(); if (supportActionBar != null) { @@ -165,22 +158,8 @@ public class MainFragment extends BaseFragment implements TabLayout.OnTabSelecte @Override public Fragment getItem(int position) { - switch (position) { - case 0: - return isSubscriptionsPageOnlySelected() ? new SubscriptionFragment() : getMainPageFragment(); - case 1: - if(PreferenceManager.getDefaultSharedPreferences(getActivity()) - .getString(getString(R.string.main_page_content_key), getString(R.string.blank_page_key)) - .equals(getString(R.string.subscription_page_key))) { - return new BookmarkFragment(); - } else { - return new SubscriptionFragment(); - } - case 2: - return new BookmarkFragment(); - default: - return new BlankFragment(); - } + //return proper fragments + return new BlankFragment(); } @Override @@ -191,7 +170,8 @@ public class MainFragment extends BaseFragment implements TabLayout.OnTabSelecte @Override public int getCount() { - return isSubscriptionsPageOnlySelected() ? 2 : 3; + //return number of framgents + return 10; } } @@ -204,76 +184,4 @@ public class MainFragment extends BaseFragment implements TabLayout.OnTabSelecte .getString(getString(R.string.main_page_content_key), getString(R.string.blank_page_key)) .equals(getString(R.string.subscription_page_key)); } - - private Fragment getMainPageFragment() { - if (getActivity() == null) return new BlankFragment(); - - try { - SharedPreferences preferences = - PreferenceManager.getDefaultSharedPreferences(getActivity()); - final String setMainPage = preferences.getString(getString(R.string.main_page_content_key), - getString(R.string.main_page_selectd_kiosk_id)); - if (setMainPage.equals(getString(R.string.blank_page_key))) { - return new BlankFragment(); - } else if (setMainPage.equals(getString(R.string.kiosk_page_key))) { - int serviceId = preferences.getInt(getString(R.string.main_page_selected_service), - FALLBACK_SERVICE_ID); - String kioskId = preferences.getString(getString(R.string.main_page_selectd_kiosk_id), - FALLBACK_KIOSK_ID); - KioskFragment fragment = KioskFragment.getInstance(serviceId, kioskId); - fragment.useAsFrontPage(true); - return fragment; - } else if (setMainPage.equals(getString(R.string.feed_page_key))) { - FeedFragment fragment = new FeedFragment(); - fragment.useAsFrontPage(true); - return fragment; - } else if (setMainPage.equals(getString(R.string.channel_page_key))) { - int serviceId = preferences.getInt(getString(R.string.main_page_selected_service), - FALLBACK_SERVICE_ID); - String url = preferences.getString(getString(R.string.main_page_selected_channel_url), - FALLBACK_CHANNEL_URL); - String name = preferences.getString(getString(R.string.main_page_selected_channel_name), - FALLBACK_CHANNEL_NAME); - ChannelFragment fragment = ChannelFragment.getInstance(serviceId, - url, - name); - fragment.useAsFrontPage(true); - return fragment; - } else { - return new BlankFragment(); - } - - } catch (Exception e) { - ErrorActivity.reportError(activity, e, - activity.getClass(), - null, - ErrorActivity.ErrorInfo.make(UserAction.UI_ERROR, - "none", "", R.string.app_ui_crash)); - return new BlankFragment(); - } - } - - /*////////////////////////////////////////////////////////////////////////// - // Select Kiosk - //////////////////////////////////////////////////////////////////////////*/ - - private void createKioskMenu(Menu menu, MenuInflater menuInflater) - throws Exception { - StreamingService service = NewPipe.getService(currentServiceId); - KioskList kl = service.getKioskList(); - int i = 0; - for (final String ks : kl.getAvailableKiosks()) { - menu.add(0, KIOSK_MENU_OFFSET + i, Menu.NONE, - KioskTranslator.getTranslatedKioskName(ks, getContext())) - .setOnMenuItemClickListener(menuItem -> { - try { - NavigationHelper.openKioskFragment(getFragmentManager(), currentServiceId, ks); - } catch (Exception e) { - ErrorActivity.reportUiError((AppCompatActivity) getActivity(), e); - } - return true; - }); - i++; - } - } } diff --git a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsDialog.java b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsDialog.java new file mode 100644 index 000000000..6cc63dd5e --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsDialog.java @@ -0,0 +1,98 @@ +package org.schabi.newpipe.settings; + +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.v4.app.DialogFragment; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.TextView; + +import org.schabi.newpipe.R; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class ContentSettingsDialog extends DialogFragment { + + List usedTabs = new ArrayList<>(); + + @Override + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + return inflater.inflate(R.layout.dialog_contentsettings, container); + } + + @Override + public void onViewCreated(@NonNull View rootView, @Nullable Bundle savedInstanceState) { + super.onViewCreated(rootView, savedInstanceState); + RecyclerView allTabs = rootView.findViewById(R.id.tabs); + allTabs.setLayoutManager(new LinearLayoutManager(getContext())); + allTabs.setAdapter(new allAdapter()); + + RecyclerView usedTabs = rootView.findViewById(R.id.usedTabs); + usedTabs.setLayoutManager(new LinearLayoutManager(getContext())); + } + + public class allAdapter extends RecyclerView.Adapter{ + + @Override + public TabViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + + LayoutInflater inflater = LayoutInflater.from(getContext()); + View view = inflater.inflate(R.layout.dialog_contentsettingtab, parent, false); + return new TabViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull TabViewHolder holder, int position) { + holder.bind(position); + } + + + // Return the size of your dataset (invoked by the layout manager) + @Override + public int getItemCount() { + return 5; + } + + class TabViewHolder extends RecyclerView.ViewHolder { + + TextView text; + Button add; + + public TabViewHolder(View itemView) { + super(itemView); + + text = itemView.findViewById(R.id.tabName); + add = itemView.findViewById(R.id.buttonAddRemove); + } + + void bind(int position) { + add.setBackgroundResource(R.drawable.ic_add); + switch (position) { + case 0: + text.setText("Test"); + break; + case 1: + break; + case 2: + break; + case 3: + break; + case 4: + break; + case 5: + break; + case 6: + break; + } + } + } + } +} diff --git a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java index 8f4e6d471..cf535ed09 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java +++ b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java @@ -9,6 +9,7 @@ import android.os.Bundle; import android.preference.PreferenceManager; import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import android.support.v4.app.FragmentManager; import android.support.v7.preference.ListPreference; import android.support.v7.preference.Preference; import android.util.Log; @@ -98,6 +99,8 @@ public class ContentSettingsFragment extends BasePreferenceFragment { addPreferencesFromResource(R.xml.content_settings); + /* + final ListPreference mainPageContentPref = (ListPreference) findPreference(getString(R.string.main_page_content_key)); mainPageContentPref.setOnPreferenceChangeListener((Preference preference, Object newValueO) -> { final String newValue = newValueO.toString(); @@ -160,6 +163,14 @@ public class ContentSettingsFragment extends BasePreferenceFragment { return true; }); + */ + + Preference contentPreference = findPreference(getString(R.string.main_page_content_key)); + contentPreference.setOnPreferenceClickListener((Preference p) -> { + new ContentSettingsDialog().show(getFragmentManager(),""); + return true; + }); + Preference importDataPreference = findPreference(getString(R.string.import_data)); importDataPreference.setOnPreferenceClickListener((Preference p) -> { Intent i = new Intent(getActivity(), FilePickerActivityHelper.class) diff --git a/app/src/main/res/drawable-hdpi/ic_add.png b/app/src/main/res/drawable-hdpi/ic_add.png new file mode 100644 index 0000000000000000000000000000000000000000..85172125ec3e2d2b559c145390254b0752e832d2 GIT binary patch literal 246 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA1|-9oezpUty`CIR=C&P zpv&8*{GO5+E~F&jRIy}_ijrbH6C;a&0|Ss)QFvR&HM{mC>zb|4Fa3Izeti1vG{fT0 zLeK9M`{sVVttsDmZKYk&ekB7xp`|CKwbxB8T)X$nUXLki$12WFj}WUqEB(h!5Nwje pgZr$kcwN$2@knvzx5JD~4ImigP3~>Lt!FI>qb6h*~G7T zG^O=IgY|(+mx4}+@EaHzakWP>bn(?>IbO7!#SPNd@bEdqlcFZIpEV*qO@hn}Dnk8T U8}*yoflgrXboFyt=akR{03#GS3;+NC literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xhdpi/ic_add.png b/app/src/main/res/drawable-xhdpi/ic_add.png new file mode 100644 index 0000000000000000000000000000000000000000..cbe4b60000a1d1be03ca0f9b3896ef50fd594f57 GIT binary patch literal 220 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=i#=T&Ln>~)y>XDU*+8TrG2P3k zQNf~Px?j*6w!7D+&+eEW7SMd3|Gn0;V5N<(RXiuDcs>vDk}NuRxhlx(Z!$yD!SxP5 z)-6{88ifLS=RU8WY4Q8KHN*Sn>u>aHo5Ihp%oku_;AijPO<%+D-|xV6^gdaSW-r_4c-5_MrfghKm-r zcXd6Or#L~8^U3v{7CS;#+`UzQyIiq*LEr`V$yI!JJPl{?J5R|D1eyQ>1`$_E_pVv> z>g}Z?$sc8wYfj#zbN}|XyUTy>FxsuiWcj6b|Epc^jL)85+R5?JvtSvE00Se70|TRg z0|N%LVY&3(+m$7kIPWd7>}9c7=J7h_`20WjF3MJ0_n+ICIqQ8kk!+_;7x(zkADi*5P~S?)1Ks-TUVrAH?GacE+nN V&6NI_U0Mhd@O1TaS?83{1OP(sld}K- literal 0 HcmV?d00001 diff --git a/app/src/main/res/layout/dialog_contentsettings.xml b/app/src/main/res/layout/dialog_contentsettings.xml new file mode 100644 index 000000000..9303cb995 --- /dev/null +++ b/app/src/main/res/layout/dialog_contentsettings.xml @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/dialog_contentsettingtab.xml b/app/src/main/res/layout/dialog_contentsettingtab.xml new file mode 100644 index 000000000..baad35b7b --- /dev/null +++ b/app/src/main/res/layout/dialog_contentsettingtab.xml @@ -0,0 +1,43 @@ + + + + + +