diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 4f97a7201..dab6fb2ec 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -185,7 +185,7 @@ android:name=".RouterPopupActivity" android:label="@string/popup_mode_share_menu_title" android:taskAffinity="" - android:theme="@android:style/Theme.NoDisplay"> + android:theme="@style/PopupPermissionsTheme"> diff --git a/app/src/main/java/org/schabi/newpipe/RouterPopupActivity.java b/app/src/main/java/org/schabi/newpipe/RouterPopupActivity.java index 1cff0ca76..2e7089300 100644 --- a/app/src/main/java/org/schabi/newpipe/RouterPopupActivity.java +++ b/app/src/main/java/org/schabi/newpipe/RouterPopupActivity.java @@ -21,6 +21,7 @@ public class RouterPopupActivity extends RouterActivity { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !PermissionHelper.checkSystemAlertWindowPermission(this)) { Toast.makeText(this, R.string.msg_popup_permission, Toast.LENGTH_LONG).show(); + finish(); return; } StreamingService service; diff --git a/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java index a4ee01ccc..d0460c347 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java @@ -485,6 +485,8 @@ public class VideoDetailFragment extends BaseStateFragment implement private void showStreamDialog(final StreamInfoItem item) { final Context context = getContext(); + if (context == null || context.getResources() == null || getActivity() == null) return; + final String[] commands = new String[]{ context.getResources().getString(R.string.enqueue_on_background), context.getResources().getString(R.string.enqueue_on_popup) diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListFragment.java index fd1e9ea63..ae17dafff 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListFragment.java @@ -192,6 +192,8 @@ public abstract class BaseListFragment extends BaseStateFragment implem protected void showStreamDialog(final StreamInfoItem item) { final Context context = getContext(); + if (context == null || context.getResources() == null || getActivity() == null) return; + final String[] commands = new String[]{ context.getResources().getString(R.string.enqueue_on_background), context.getResources().getString(R.string.enqueue_on_popup) diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java index 348495079..857fb81e0 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java @@ -154,6 +154,8 @@ public class ChannelFragment extends BaseListInfoFragment { @Override protected void showStreamDialog(final StreamInfoItem item) { final Context context = getContext(); + if (context == null || context.getResources() == null || getActivity() == null) return; + final String[] commands = new String[]{ context.getResources().getString(R.string.enqueue_on_background), context.getResources().getString(R.string.enqueue_on_popup), diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java index 878dbf385..e7f7e9968 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java @@ -15,7 +15,6 @@ import android.view.MenuInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; -import android.widget.LinearLayout; import android.widget.TextView; import android.widget.Toast; @@ -109,6 +108,8 @@ public class PlaylistFragment extends BaseListInfoFragment { @Override protected void showStreamDialog(final StreamInfoItem item) { final Context context = getContext(); + if (context == null || context.getResources() == null || getActivity() == null) return; + final String[] commands = new String[]{ context.getResources().getString(R.string.enqueue_on_background), context.getResources().getString(R.string.enqueue_on_popup), diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/search/SearchFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/search/SearchFragment.java index fae97bb7b..fb54a15c3 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/search/SearchFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/search/SearchFragment.java @@ -165,7 +165,7 @@ public class SearchFragment extends BaseListFragment items = new ArrayList<>(); private final Context context; private OnSuggestionItemSelected listener; - private boolean showSugestinHistory = true; + private boolean showSuggestionHistory = true; public interface OnSuggestionItemSelected { void onSuggestionItemSelected(SuggestionItem item); + void onSuggestionItemInserted(SuggestionItem item); void onSuggestionItemLongClick(SuggestionItem item); } @@ -32,7 +33,7 @@ public class SuggestionListAdapter extends RecyclerView.Adapter items) { this.items.clear(); - if (showSugestinHistory) { + if (showSuggestionHistory) { this.items.addAll(items); } else { // remove history items if history is disabled @@ -49,8 +50,8 @@ public class SuggestionListAdapter extends RecyclerView.Adapter
+ * In the event that this error is produced during a valid stream playback, we save the + * current position so the playback may be recovered and resumed manually by the user. This + * happens only if the playback is {@link #RECOVERY_SKIP_THRESHOLD} milliseconds until complete. + *

* * {@link ExoPlaybackException#TYPE_UNEXPECTED TYPE_UNEXPECTED}:

* If a runtime error occurred, then we can try to recover it by restarting the playback - * after setting the timestamp recovery. + * after setting the timestamp recovery.

* * {@link ExoPlaybackException#TYPE_RENDERER TYPE_RENDERER}:

* If the renderer failed, treat the error as unrecoverable. @@ -568,6 +577,10 @@ public abstract class BasePlayer implements Player.EventListener, PlaybackListen switch (error.type) { case ExoPlaybackException.TYPE_SOURCE: + if (simpleExoPlayer.getCurrentPosition() < + simpleExoPlayer.getDuration() - RECOVERY_SKIP_THRESHOLD) { + setRecovery(); + } playQueue.error(isCurrentWindowValid()); showStreamError(error); break; diff --git a/app/src/main/java/org/schabi/newpipe/player/MainVideoPlayer.java b/app/src/main/java/org/schabi/newpipe/player/MainVideoPlayer.java index b91a0814b..73e4d87ac 100644 --- a/app/src/main/java/org/schabi/newpipe/player/MainVideoPlayer.java +++ b/app/src/main/java/org/schabi/newpipe/player/MainVideoPlayer.java @@ -23,6 +23,7 @@ import android.app.Activity; import android.content.Context; import android.content.Intent; import android.content.pm.ActivityInfo; +import android.content.res.Configuration; import android.graphics.Color; import android.media.AudioManager; import android.os.Build; @@ -33,6 +34,7 @@ import android.support.v7.widget.RecyclerView; import android.support.v7.widget.helper.ItemTouchHelper; import android.util.Log; import android.view.GestureDetector; +import android.view.MenuItem; import android.view.MotionEvent; import android.view.View; import android.view.WindowManager; @@ -59,6 +61,8 @@ import org.schabi.newpipe.util.NavigationHelper; import org.schabi.newpipe.util.PermissionHelper; import org.schabi.newpipe.util.ThemeHelper; +import java.lang.reflect.Field; +import java.lang.reflect.Method; import java.util.List; import static org.schabi.newpipe.util.AnimationUtils.animateView; @@ -151,6 +155,17 @@ public final class MainVideoPlayer extends Activity { if (playerImpl != null) playerImpl.destroy(); } + @Override + public void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + + if (playerImpl.isSomePopupMenuVisible()) { + playerImpl.moreOptionsPopupMenu.dismiss(); + playerImpl.getQualityPopupMenu().dismiss(); + playerImpl.getPlaybackSpeedPopupMenu().dismiss(); + } + } + /*////////////////////////////////////////////////////////////////////////// // Utils //////////////////////////////////////////////////////////////////////////*/ @@ -223,7 +238,6 @@ public final class MainVideoPlayer extends Activity { private ImageButton repeatButton; private ImageButton shuffleButton; - private ImageButton screenRotationButton; private ImageButton playPauseButton; private ImageButton playPreviousButton; private ImageButton playNextButton; @@ -235,6 +249,10 @@ public final class MainVideoPlayer extends Activity { private boolean queueVisible; + private ImageButton moreOptionsButton; + public int moreOptionsPopupMenuGroupId = 89; + public PopupMenu moreOptionsPopupMenu; + VideoPlayerImpl(final Context context) { super("VideoPlayerImpl" + MainVideoPlayer.TAG, context); } @@ -250,10 +268,12 @@ public final class MainVideoPlayer extends Activity { this.repeatButton = rootView.findViewById(R.id.repeatButton); this.shuffleButton = rootView.findViewById(R.id.shuffleButton); - this.screenRotationButton = rootView.findViewById(R.id.screenRotationButton); this.playPauseButton = rootView.findViewById(R.id.playPauseButton); this.playPreviousButton = rootView.findViewById(R.id.playPreviousButton); this.playNextButton = rootView.findViewById(R.id.playNextButton); + this.moreOptionsButton = rootView.findViewById(R.id.moreOptionsButton); + this.moreOptionsPopupMenu = new PopupMenu(context, moreOptionsButton); + this.moreOptionsPopupMenu.getMenuInflater().inflate(R.menu.menu_videooptions, moreOptionsPopupMenu.getMenu()); titleTextView.setSelected(true); channelTextView.setSelected(true); @@ -277,7 +297,7 @@ public final class MainVideoPlayer extends Activity { playPauseButton.setOnClickListener(this); playPreviousButton.setOnClickListener(this); playNextButton.setOnClickListener(this); - screenRotationButton.setOnClickListener(this); + moreOptionsButton.setOnClickListener(this); } /*////////////////////////////////////////////////////////////////////////// @@ -349,6 +369,28 @@ public final class MainVideoPlayer extends Activity { finish(); } + public void onPlayBackgroundButtonClicked() { + if (DEBUG) Log.d(TAG, "onPlayBackgroundButtonClicked() called"); + if (playerImpl.getPlayer() == null) return; + + setRecovery(); + final Intent intent = NavigationHelper.getPlayerIntent( + context, + BackgroundPlayer.class, + this.getPlayQueue(), + this.getRepeatMode(), + this.getPlaybackSpeed(), + this.getPlaybackPitch(), + this.getPlaybackQuality() + ); + context.startService(intent); + + ((View) getControlAnimationView().getParent()).setVisibility(View.GONE); + destroy(); + finish(); + } + + @Override public void onClick(View v) { super.onClick(v); @@ -361,9 +403,6 @@ public final class MainVideoPlayer extends Activity { } else if (v.getId() == playNextButton.getId()) { onPlayNext(); - } else if (v.getId() == screenRotationButton.getId()) { - onScreenRotationClicked(); - } else if (v.getId() == queueButton.getId()) { onQueueClicked(); return; @@ -373,6 +412,8 @@ public final class MainVideoPlayer extends Activity { } else if (v.getId() == shuffleButton.getId()) { onShuffleClicked(); return; + } else if (v.getId() == moreOptionsButton.getId()) { + onMoreOptionsClicked(); } if (getCurrentState() != STATE_COMPLETED) { @@ -406,6 +447,32 @@ public final class MainVideoPlayer extends Activity { queueVisible = false; } + private void onMoreOptionsClicked() { + if (DEBUG) Log.d(TAG, "onMoreOptionsClicked() called"); + buildMoreOptionsMenu(); + + try { + Field[] fields = moreOptionsPopupMenu.getClass().getDeclaredFields(); + for (Field field : fields) { + if ("mPopup".equals(field.getName())) { + field.setAccessible(true); + Object menuPopupHelper = field.get(moreOptionsPopupMenu); + Class classPopupHelper = Class.forName(menuPopupHelper + .getClass().getName()); + Method setForceIcons = classPopupHelper.getMethod( + "setForceShowIcon", boolean.class); + setForceIcons.invoke(menuPopupHelper, true); + break; + } + } + } catch (Exception e) { + e.printStackTrace(); + } + moreOptionsPopupMenu.show(); + isSomePopupMenuVisible = true; + showControls(300); + } + private void onScreenRotationClicked() { if (DEBUG) Log.d(TAG, "onScreenRotationClicked() called"); toggleOrientation(); @@ -556,6 +623,27 @@ public final class MainVideoPlayer extends Activity { setShuffleButton(shuffleButton, playQueue.isShuffled()); } + private void buildMoreOptionsMenu() { + if (moreOptionsPopupMenu == null) return; + moreOptionsPopupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { + @Override + public boolean onMenuItemClick(MenuItem menuItem) { + switch (menuItem.getItemId()) { + case R.id.toggleOrientation: + onScreenRotationClicked(); + break; + case R.id.switchPopup: + onFullScreenButtonClicked(); + break; + case R.id.switchBackground: + onPlayBackgroundButtonClicked(); + break; + } + return false; + } + }); + } + private void buildQueue() { queueLayout = findViewById(R.id.playQueuePanel); @@ -802,4 +890,4 @@ public final class MainVideoPlayer extends Activity { } } -} \ No newline at end of file +} 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 a3fd0f7a7..5f8b36449 100644 --- a/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java +++ b/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java @@ -842,6 +842,8 @@ public final class PopupVideoPlayer extends Service { } savePositionAndSize(); } + + v.performClick(); return true; } @@ -880,23 +882,25 @@ public final class PopupVideoPlayer extends Service { private final Context context; private final Handler mainHandler; - FetcherHandler(Context context, int serviceId, String url) { + private FetcherHandler(Context context, int serviceId, String url) { this.mainHandler = new Handler(PopupVideoPlayer.this.getMainLooper()); this.context = context; this.url = url; this.serviceId = serviceId; } - /*package-private*/ void onReceive(final StreamInfo info) { + private void onReceive(final StreamInfo info) { mainHandler.post(new Runnable() { @Override public void run() { - playerImpl.initPlayback(new SinglePlayQueue(info)); + final Intent intent = NavigationHelper.getPlayerIntent(getApplicationContext(), + PopupVideoPlayer.class, new SinglePlayQueue(info)); + playerImpl.handleIntent(intent); } }); } - protected void onError(final Throwable exception) { + private void onError(final Throwable exception) { if (DEBUG) Log.d(TAG, "onError() called with: exception = [" + exception + "]"); exception.printStackTrace(); mainHandler.post(new Runnable() { @@ -922,7 +926,7 @@ public final class PopupVideoPlayer extends Service { stopSelf(); } - /*package-private*/ void onReCaptchaException() { + private void onReCaptchaException() { Toast.makeText(context, R.string.recaptcha_request_toast, Toast.LENGTH_LONG).show(); // Starting ReCaptcha Challenge Activity Intent intent = new Intent(context, ReCaptchaActivity.class); diff --git a/app/src/main/java/org/schabi/newpipe/player/VideoPlayer.java b/app/src/main/java/org/schabi/newpipe/player/VideoPlayer.java index 07ead4f0e..60f15372a 100644 --- a/app/src/main/java/org/schabi/newpipe/player/VideoPlayer.java +++ b/app/src/main/java/org/schabi/newpipe/player/VideoPlayer.java @@ -124,12 +124,11 @@ public abstract class VideoPlayer extends BasePlayer implements SimpleExoPlayer. private View topControlsRoot; private TextView qualityTextView; - private ImageButton fullScreenButton; private ValueAnimator controlViewAnimator; private Handler controlsVisibilityHandler = new Handler(); - private boolean isSomePopupMenuVisible = false; + boolean isSomePopupMenuVisible = false; private int qualityPopupMenuGroupId = 69; private PopupMenu qualityPopupMenu; @@ -166,7 +165,6 @@ public abstract class VideoPlayer extends BasePlayer implements SimpleExoPlayer. this.bottomControlsRoot = rootView.findViewById(R.id.bottomControls); this.topControlsRoot = rootView.findViewById(R.id.topControls); this.qualityTextView = rootView.findViewById(R.id.qualityTextView); - this.fullScreenButton = rootView.findViewById(R.id.fullScreenButton); //this.aspectRatioFrameLayout.setAspectRatio(16.0f / 9.0f); @@ -186,7 +184,6 @@ public abstract class VideoPlayer extends BasePlayer implements SimpleExoPlayer. super.initListeners(); playbackSeekBar.setOnSeekBarChangeListener(this); playbackSpeedTextView.setOnClickListener(this); - fullScreenButton.setOnClickListener(this); qualityTextView.setOnClickListener(this); } @@ -454,9 +451,7 @@ public abstract class VideoPlayer extends BasePlayer implements SimpleExoPlayer. @Override public void onClick(View v) { if (DEBUG) Log.d(TAG, "onClick() called with: v = [" + v + "]"); - if (v.getId() == fullScreenButton.getId()) { - onFullScreenButtonClicked(); - } else if (v.getId() == qualityTextView.getId()) { + if (v.getId() == qualityTextView.getId()) { onQualitySelectorClicked(); } else if (v.getId() == playbackSpeedTextView.getId()) { onPlaybackSpeedClicked(); @@ -754,14 +749,14 @@ public abstract class VideoPlayer extends BasePlayer implements SimpleExoPlayer. return qualityTextView; } - public ImageButton getFullScreenButton() { - return fullScreenButton; - } - public PopupMenu getQualityPopupMenu() { return qualityPopupMenu; } + public PopupMenu getPlaybackSpeedPopupMenu() { + return playbackSpeedPopupMenu; + } + public View getSurfaceForeground() { return surfaceForeground; } diff --git a/app/src/main/java/org/schabi/newpipe/util/InfoCache.java b/app/src/main/java/org/schabi/newpipe/util/InfoCache.java index 5b22af86a..794c3dd78 100644 --- a/app/src/main/java/org/schabi/newpipe/util/InfoCache.java +++ b/app/src/main/java/org/schabi/newpipe/util/InfoCache.java @@ -26,6 +26,9 @@ import android.util.Log; import org.schabi.newpipe.MainActivity; import org.schabi.newpipe.extractor.Info; +import java.util.Map; +import java.util.concurrent.TimeUnit; + public final class InfoCache { private static final boolean DEBUG = MainActivity.DEBUG; @@ -37,9 +40,9 @@ public final class InfoCache { * Trim the cache to this size */ private static final int TRIM_CACHE_TO = 30; + private static final int DEFAULT_TIMEOUT_HOURS = 4; - // TODO: Replace to one with timeout (like the one from guava) - private static final LruCache lruCache = new LruCache<>(MAX_ITEMS_ON_CACHE); + private static final LruCache lruCache = new LruCache<>(MAX_ITEMS_ON_CACHE); private InfoCache() { //no instance @@ -52,28 +55,29 @@ public final class InfoCache { public Info getFromKey(int serviceId, @NonNull String url) { if (DEBUG) Log.d(TAG, "getFromKey() called with: serviceId = [" + serviceId + "], url = [" + url + "]"); synchronized (lruCache) { - return lruCache.get(serviceId + url); + return getInfo(lruCache, keyOf(serviceId, url)); } } public void putInfo(@NonNull Info info) { if (DEBUG) Log.d(TAG, "putInfo() called with: info = [" + info + "]"); synchronized (lruCache) { - lruCache.put(info.service_id + info.url, info); + final CacheData data = new CacheData(info, DEFAULT_TIMEOUT_HOURS, TimeUnit.HOURS); + lruCache.put(keyOf(info), data); } } public void removeInfo(@NonNull Info info) { if (DEBUG) Log.d(TAG, "removeInfo() called with: info = [" + info + "]"); synchronized (lruCache) { - lruCache.remove(info.service_id + info.url); + lruCache.remove(keyOf(info)); } } public void removeInfo(int serviceId, @NonNull String url) { if (DEBUG) Log.d(TAG, "removeInfo() called with: serviceId = [" + serviceId + "], url = [" + url + "]"); synchronized (lruCache) { - lruCache.remove(serviceId + url); + lruCache.remove(keyOf(serviceId, url)); } } @@ -87,6 +91,7 @@ public final class InfoCache { public void trimCache() { if (DEBUG) Log.d(TAG, "trimCache() called"); synchronized (lruCache) { + removeStaleCache(lruCache); lruCache.trimToSize(TRIM_CACHE_TO); } } @@ -97,4 +102,51 @@ public final class InfoCache { } } + private static String keyOf(@NonNull final Info info) { + return keyOf(info.service_id, info.url); + } + + private static String keyOf(final int serviceId, @NonNull final String url) { + return serviceId + url; + } + + private static void removeStaleCache(@NonNull final LruCache cache) { + for (Map.Entry entry : cache.snapshot().entrySet()) { + final CacheData data = entry.getValue(); + if (data != null && data.isExpired()) { + cache.remove(entry.getKey()); + } + } + } + + private static Info getInfo(@NonNull final LruCache cache, + @NonNull final String key) { + final CacheData data = cache.get(key); + if (data == null) return null; + + if (data.isExpired()) { + cache.remove(key); + return null; + } + + return data.info; + } + + final private static class CacheData { + final private long expireTimestamp; + final private Info info; + + private CacheData(@NonNull final Info info, + final long timeout, + @NonNull final TimeUnit timeUnit) { + this.expireTimestamp = System.currentTimeMillis() + + TimeUnit.MILLISECONDS.convert(timeout, timeUnit); + + this.info = info; + } + + private boolean isExpired() { + return System.currentTimeMillis() > expireTimestamp; + } + } } diff --git a/app/src/main/res/drawable-hdpi/ic_arrow_top_left_black_24dp.png b/app/src/main/res/drawable-hdpi/ic_arrow_top_left_black_24dp.png new file mode 100644 index 000000000..da5605741 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_arrow_top_left_black_24dp.png differ diff --git a/app/src/main/res/drawable-hdpi/ic_arrow_top_left_white_24dp.png b/app/src/main/res/drawable-hdpi/ic_arrow_top_left_white_24dp.png new file mode 100644 index 000000000..24376b637 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_arrow_top_left_white_24dp.png differ diff --git a/app/src/main/res/drawable-hdpi/ic_more_vert_black_24dp.png b/app/src/main/res/drawable-hdpi/ic_more_vert_black_24dp.png new file mode 100644 index 000000000..22acc5500 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_more_vert_black_24dp.png differ diff --git a/app/src/main/res/drawable-hdpi/ic_more_vert_white_24dp.png b/app/src/main/res/drawable-hdpi/ic_more_vert_white_24dp.png new file mode 100644 index 000000000..67f07e473 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_more_vert_white_24dp.png differ diff --git a/app/src/main/res/drawable-mdpi/ic_arrow_top_left_black_24dp.png b/app/src/main/res/drawable-mdpi/ic_arrow_top_left_black_24dp.png new file mode 100644 index 000000000..056a0ff28 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_arrow_top_left_black_24dp.png differ diff --git a/app/src/main/res/drawable-mdpi/ic_arrow_top_left_white_24dp.png b/app/src/main/res/drawable-mdpi/ic_arrow_top_left_white_24dp.png new file mode 100644 index 000000000..a2e73369c Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_arrow_top_left_white_24dp.png differ diff --git a/app/src/main/res/drawable-mdpi/ic_more_vert_black_24dp.png b/app/src/main/res/drawable-mdpi/ic_more_vert_black_24dp.png new file mode 100644 index 000000000..0e4f2f6ea Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_more_vert_black_24dp.png differ diff --git a/app/src/main/res/drawable-mdpi/ic_more_vert_white_24dp.png b/app/src/main/res/drawable-mdpi/ic_more_vert_white_24dp.png new file mode 100644 index 000000000..017e45ede Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_more_vert_white_24dp.png differ diff --git a/app/src/main/res/drawable-xhdpi/ic_arrow_top_left_black_24dp.png b/app/src/main/res/drawable-xhdpi/ic_arrow_top_left_black_24dp.png new file mode 100644 index 000000000..e4255a18a Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_arrow_top_left_black_24dp.png differ diff --git a/app/src/main/res/drawable-xhdpi/ic_arrow_top_left_white_24dp.png b/app/src/main/res/drawable-xhdpi/ic_arrow_top_left_white_24dp.png new file mode 100644 index 000000000..db578cab9 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_arrow_top_left_white_24dp.png differ diff --git a/app/src/main/res/drawable-xhdpi/ic_more_vert_black_24dp.png b/app/src/main/res/drawable-xhdpi/ic_more_vert_black_24dp.png new file mode 100644 index 000000000..9f10aa275 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_more_vert_black_24dp.png differ diff --git a/app/src/main/res/drawable-xhdpi/ic_more_vert_white_24dp.png b/app/src/main/res/drawable-xhdpi/ic_more_vert_white_24dp.png new file mode 100644 index 000000000..efab8a74f Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_more_vert_white_24dp.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_arrow_top_left_black_24dp.png b/app/src/main/res/drawable-xxhdpi/ic_arrow_top_left_black_24dp.png new file mode 100644 index 000000000..566b5c5d3 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_arrow_top_left_black_24dp.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_arrow_top_left_white_24dp.png b/app/src/main/res/drawable-xxhdpi/ic_arrow_top_left_white_24dp.png new file mode 100644 index 000000000..89d726f6c Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_arrow_top_left_white_24dp.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_more_vert_black_24dp.png b/app/src/main/res/drawable-xxhdpi/ic_more_vert_black_24dp.png new file mode 100644 index 000000000..94d5ab98c Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_more_vert_black_24dp.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_more_vert_white_24dp.png b/app/src/main/res/drawable-xxhdpi/ic_more_vert_white_24dp.png new file mode 100644 index 000000000..d32281307 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_more_vert_white_24dp.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_arrow_top_left_black_24dp.png b/app/src/main/res/drawable-xxxhdpi/ic_arrow_top_left_black_24dp.png new file mode 100644 index 000000000..d536127b5 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_arrow_top_left_black_24dp.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_arrow_top_left_white_24dp.png b/app/src/main/res/drawable-xxxhdpi/ic_arrow_top_left_white_24dp.png new file mode 100644 index 000000000..0ddd5a8fa Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_arrow_top_left_white_24dp.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_more_vert_black_24dp.png b/app/src/main/res/drawable-xxxhdpi/ic_more_vert_black_24dp.png new file mode 100644 index 000000000..4642a3b66 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_more_vert_black_24dp.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_more_vert_white_24dp.png b/app/src/main/res/drawable-xxxhdpi/ic_more_vert_white_24dp.png new file mode 100644 index 000000000..2f2cb3d00 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_more_vert_white_24dp.png differ diff --git a/app/src/main/res/layout/activity_main_player.xml b/app/src/main/res/layout/activity_main_player.xml index 5c6349c35..6086dd5cb 100644 --- a/app/src/main/res/layout/activity_main_player.xml +++ b/app/src/main/res/layout/activity_main_player.xml @@ -209,7 +209,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginRight="2dp" - android:layout_toLeftOf="@+id/screenRotationButton" + android:layout_toLeftOf="@+id/queueButton" android:gravity="center" android:minHeight="35dp" android:minWidth="40dp" @@ -218,28 +218,13 @@ tools:ignore="RtlHardcoded,RtlSymmetry" tools:text="1x" /> - - @@ -454,4 +440,4 @@ tools:visibility="visible"/> - \ No newline at end of file + diff --git a/app/src/main/res/layout/dialog_title.xml b/app/src/main/res/layout/dialog_title.xml index dc76a4f20..fa7e155d2 100644 --- a/app/src/main/res/layout/dialog_title.xml +++ b/app/src/main/res/layout/dialog_title.xml @@ -6,7 +6,9 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:clickable="false" - android:padding="@dimen/video_item_search_padding"> + android:paddingLeft="@dimen/video_item_search_padding" + android:paddingRight="@dimen/video_item_search_padding" + android:paddingTop="@dimen/video_item_search_padding"> \ No newline at end of file diff --git a/app/src/main/res/layout/item_search_suggestion.xml b/app/src/main/res/layout/item_search_suggestion.xml index b230f6da0..bffc3ce89 100644 --- a/app/src/main/res/layout/item_search_suggestion.xml +++ b/app/src/main/res/layout/item_search_suggestion.xml @@ -1,36 +1,71 @@ - + android:orientation="horizontal"> - - - - \ No newline at end of file + android:background="?attr/selectableItemBackground" + android:clickable="true" + android:focusable="true" + android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" + android:layout_toLeftOf="@id/suggestion_insert" + android:layout_toStartOf="@id/suggestion_insert" + android:layout_centerVertical="true" + android:paddingBottom="8dp" + android:paddingTop="8dp"> + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/player_notification.xml b/app/src/main/res/layout/player_notification.xml index 157615bb7..2a3e7aff3 100644 --- a/app/src/main/res/layout/player_notification.xml +++ b/app/src/main/res/layout/player_notification.xml @@ -34,22 +34,22 @@ diff --git a/app/src/main/res/layout/player_notification_expanded.xml b/app/src/main/res/layout/player_notification_expanded.xml index d37087312..7d59720e0 100644 --- a/app/src/main/res/layout/player_notification_expanded.xml +++ b/app/src/main/res/layout/player_notification_expanded.xml @@ -46,22 +46,22 @@ @@ -80,7 +80,6 @@ diff --git a/app/src/main/res/menu/menu_videooptions.xml b/app/src/main/res/menu/menu_videooptions.xml new file mode 100644 index 000000000..2fbde0412 --- /dev/null +++ b/app/src/main/res/menu/menu_videooptions.xml @@ -0,0 +1,21 @@ + + + + + + + diff --git a/app/src/main/res/values/attrs.xml b/app/src/main/res/values/attrs.xml index abf7c7b09..86b9644ae 100644 --- a/app/src/main/res/values/attrs.xml +++ b/app/src/main/res/values/attrs.xml @@ -20,6 +20,8 @@ + + diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 3750bdb78..b77a2d229 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -39,7 +39,10 @@ #EEFFFFFF #ffffff #66000000 + #323232 + #ffffff + #999999 #e53935 #fff diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 8f0bb02cd..c0c16e30f 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -27,6 +27,8 @@ @drawable/ic_history_black_24dp @drawable/ic_drag_handle_black_24dp @drawable/ic_fiber_manual_record_black_24dp + @drawable/ic_arrow_top_left_black_24dp + @drawable/ic_more_vert_black_24dp @color/light_separator_color @color/light_contrast_background_color @@ -65,6 +67,8 @@ @drawable/ic_history_white_24dp @drawable/ic_drag_handle_white_24dp @drawable/ic_fiber_manual_record_white_24dp + @drawable/ic_arrow_top_left_white_24dp + @drawable/ic_more_vert_white_24dp @color/dark_separator_color @color/dark_contrast_background_color @@ -160,4 +164,12 @@ @color/dark_youtube_primary_color +