From 2773f5fbc8318e37c6753a659d0a10ecb14b38a8 Mon Sep 17 00:00:00 2001
From: Christian Schabesberger <chris.schabesberger@mailbox.org>
Date: Sun, 11 Feb 2018 21:34:32 +0100
Subject: [PATCH] move download menu item into detail controls menu

---
 .../fragments/detail/ActionBarHandler.java    |  15 +-
 .../fragments/detail/VideoDetailFragment.java | 162 +++++++-----------
 .../main/res/layout/fragment_video_detail.xml |  18 ++
 app/src/main/res/menu/video_detail_menu.xml   |   6 -
 app/src/main/res/values/strings.xml           |   1 +
 5 files changed, 86 insertions(+), 116 deletions(-)

diff --git a/app/src/main/java/org/schabi/newpipe/fragments/detail/ActionBarHandler.java b/app/src/main/java/org/schabi/newpipe/fragments/detail/ActionBarHandler.java
index 27bffca2d..d928166ab 100644
--- a/app/src/main/java/org/schabi/newpipe/fragments/detail/ActionBarHandler.java
+++ b/app/src/main/java/org/schabi/newpipe/fragments/detail/ActionBarHandler.java
@@ -53,7 +53,6 @@ class ActionBarHandler {
     // those are edited directly. Typically VideoDetailFragment will implement those callbacks.
     private OnActionListener onShareListener;
     private OnActionListener onOpenInBrowserListener;
-    private OnActionListener onDownloadListener;
     private OnActionListener onPlayWithKodiListener;
 
     // Triggered when a stream related action is triggered.
@@ -117,11 +116,6 @@ class ActionBarHandler {
                 }
                 return true;
             }
-            case R.id.menu_item_download:
-                if (onDownloadListener != null) {
-                    onDownloadListener.onActionSelected(selectedVideoStream);
-                }
-                return true;
             case R.id.action_play_with_kodi:
                 if (onPlayWithKodiListener != null) {
                     onPlayWithKodiListener.onActionSelected(selectedVideoStream);
@@ -145,19 +139,12 @@ class ActionBarHandler {
         onOpenInBrowserListener = listener;
     }
 
-    public void setOnDownloadListener(OnActionListener listener) {
-        onDownloadListener = listener;
-    }
-
     public void setOnPlayWithKodiListener(OnActionListener listener) {
         onPlayWithKodiListener = listener;
     }
 
-    public void showDownloadAction(boolean visible) {
-        menu.findItem(R.id.menu_item_download).setVisible(visible);
-    }
-
     public void showPlayWithKodiAction(boolean visible) {
         menu.findItem(R.id.action_play_with_kodi).setVisible(visible);
     }
+
 }
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 89f35c306..daf422516 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
@@ -147,6 +147,7 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement
     private TextView detailControlsBackground;
     private TextView detailControlsPopup;
     private TextView detailControlsAddToPlaylist;
+    private TextView detailControlsDownload;
     private TextView appendControlsDetail;
 
     private LinearLayout videoDescriptionRootLayout;
@@ -335,6 +336,24 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement
                             .show(getFragmentManager(), TAG);
                 }
                 break;
+            case R.id.detail_controls_download:
+                if (!PermissionHelper.checkStoragePermissions(activity)) {
+                    return;
+                }
+
+                try {
+                    DownloadDialog downloadDialog =
+                            DownloadDialog.newInstance(currentInfo,
+                                    sortedStreamVideosList,
+                                    actionBarHandler.getSelectedVideoStream());
+                    downloadDialog.show(activity.getSupportFragmentManager(), "downloadDialog");
+                } catch (Exception e) {
+                    Toast.makeText(activity,
+                            R.string.could_not_setup_download_menu,
+                            Toast.LENGTH_LONG).show();
+                    e.printStackTrace();
+                }
+                break;
             case R.id.detail_uploader_root_layout:
                 if (TextUtils.isEmpty(currentInfo.getUploaderUrl())) {
                     Log.w(TAG, "Can't open channel because we got no channel URL");
@@ -438,6 +457,7 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement
         detailControlsBackground = rootView.findViewById(R.id.detail_controls_background);
         detailControlsPopup = rootView.findViewById(R.id.detail_controls_popup);
         detailControlsAddToPlaylist = rootView.findViewById(R.id.detail_controls_playlist_append);
+        detailControlsDownload = rootView.findViewById(R.id.detail_controls_download);
         appendControlsDetail = rootView.findViewById(R.id.touch_append_detail);
 
         videoDescriptionRootLayout = rootView.findViewById(R.id.detail_description_root_layout);
@@ -489,6 +509,7 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement
         detailControlsBackground.setOnClickListener(this);
         detailControlsPopup.setOnClickListener(this);
         detailControlsAddToPlaylist.setOnClickListener(this);
+        detailControlsDownload.setOnClickListener(this);
         relatedStreamExpandButton.setOnClickListener(this);
 
         detailControlsBackground.setLongClickable(true);
@@ -508,19 +529,16 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement
                 context.getResources().getString(R.string.enqueue_on_popup)
         };
 
-        final DialogInterface.OnClickListener actions = new DialogInterface.OnClickListener() {
-            @Override
-            public void onClick(DialogInterface dialogInterface, int i) {
-                switch (i) {
-                    case 0:
-                        NavigationHelper.enqueueOnBackgroundPlayer(context, new SinglePlayQueue(item));
-                        break;
-                    case 1:
-                        NavigationHelper.enqueueOnPopupPlayer(getActivity(), new SinglePlayQueue(item));
-                        break;
-                    default:
-                        break;
-                }
+        final DialogInterface.OnClickListener actions = (DialogInterface dialogInterface, int i) -> {
+            switch (i) {
+                case 0:
+                    NavigationHelper.enqueueOnBackgroundPlayer(context, new SinglePlayQueue(item));
+                    break;
+                case 1:
+                    NavigationHelper.enqueueOnPopupPlayer(getActivity(), new SinglePlayQueue(item));
+                    break;
+                default:
+                    break;
             }
         };
 
@@ -528,21 +546,19 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement
     }
 
     private View.OnTouchListener getOnControlsTouchListener() {
-        return new View.OnTouchListener() {
-            @Override
-            public boolean onTouch(View view, MotionEvent motionEvent) {
-                if (!PreferenceManager.getDefaultSharedPreferences(activity).getBoolean(getString(R.string.show_hold_to_append_key), true)) return false;
+        return (View view, MotionEvent motionEvent) -> {
+            view.performClick();
+            if (!PreferenceManager.getDefaultSharedPreferences(activity).getBoolean(getString(R.string.show_hold_to_append_key), true)) return false;
 
-                if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
-                    animateView(appendControlsDetail, true, 250, 0, new Runnable() {
-                        @Override
-                        public void run() {
-                            animateView(appendControlsDetail, false, 1500, 1000);
-                        }
-                    });
-                }
-                return false;
+            if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
+                animateView(appendControlsDetail, true, 250, 0, new Runnable() {
+                    @Override
+                    public void run() {
+                        animateView(appendControlsDetail, false, 1500, 1000);
+                    }
+                });
             }
+            return false;
         };
     }
 
@@ -615,18 +631,9 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement
     private static void showInstallKoreDialog(final Context context) {
         final AlertDialog.Builder builder = new AlertDialog.Builder(context);
         builder.setMessage(R.string.kore_not_found)
-                .setPositiveButton(R.string.install, new DialogInterface.OnClickListener() {
-                    @Override
-                    public void onClick(DialogInterface dialog, int which) {
-                        NavigationHelper.installKore(context);
-                    }
-                })
-                .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
-                    @Override
-                    public void onClick(DialogInterface dialog, int which) {
-
-                    }
-                });
+                .setPositiveButton(R.string.install, (DialogInterface dialog, int which) ->
+                        NavigationHelper.installKore(context))
+                .setNegativeButton(R.string.cancel, (DialogInterface dialog, int which) -> {});
         builder.create().show();
     }
 
@@ -636,41 +643,19 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement
         actionBarHandler.setupStreamList(sortedStreamVideosList, spinnerToolbar);
         actionBarHandler.setOnShareListener(selectedStreamId -> shareUrl(info.name, info.url));
 
-        actionBarHandler.setOnOpenInBrowserListener(new ActionBarHandler.OnActionListener() {
-            @Override
-            public void onActionSelected(int selectedStreamId) {
-                openUrlInBrowser(info.getUrl());
+        actionBarHandler.setOnOpenInBrowserListener((int selectedStreamId)->
+                openUrlInBrowser(info.getUrl()));
+
+        actionBarHandler.setOnPlayWithKodiListener((int selectedStreamId) -> {
+            try {
+                NavigationHelper.playWithKore(activity, Uri.parse(
+                        info.getUrl().replace("https", "http")));
+            } catch (Exception e) {
+                if(DEBUG) Log.i(TAG, "Failed to start kore", e);
+                showInstallKoreDialog(activity);
             }
         });
 
-        actionBarHandler.setOnPlayWithKodiListener(new ActionBarHandler.OnActionListener() {
-            @Override
-            public void onActionSelected(int selectedStreamId) {
-                try {
-                    NavigationHelper.playWithKore(activity, Uri.parse(info.getUrl().replace("https", "http")));
-                } catch (Exception e) {
-                    if(DEBUG) Log.i(TAG, "Failed to start kore", e);
-                    showInstallKoreDialog(activity);
-                }
-            }
-        });
-
-        actionBarHandler.setOnDownloadListener(new ActionBarHandler.OnActionListener() {
-            @Override
-            public void onActionSelected(int selectedStreamId) {
-                if (!PermissionHelper.checkStoragePermissions(activity)) {
-                    return;
-                }
-
-                try {
-                    DownloadDialog downloadDialog = DownloadDialog.newInstance(info, sortedStreamVideosList, selectedStreamId);
-                    downloadDialog.show(activity.getSupportFragmentManager(), "downloadDialog");
-                } catch (Exception e) {
-                    Toast.makeText(activity, R.string.could_not_setup_download_menu, Toast.LENGTH_LONG).show();
-                    e.printStackTrace();
-                }
-            }
-        });
     }
 
     /*//////////////////////////////////////////////////////////////////////////
@@ -777,20 +762,14 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement
         currentWorker = ExtractorHelper.getStreamInfo(serviceId, url, forceLoad)
                 .subscribeOn(Schedulers.io())
                 .observeOn(AndroidSchedulers.mainThread())
-                .subscribe(new Consumer<StreamInfo>() {
-                    @Override
-                    public void accept(@NonNull StreamInfo result) throws Exception {
-                        isLoading.set(false);
-                        currentInfo = result;
-                        showContentWithAnimation(120, 0, 0);
-                        handleResult(result);
-                    }
-                }, new Consumer<Throwable>() {
-                    @Override
-                    public void accept(@NonNull Throwable throwable) throws Exception {
-                        isLoading.set(false);
-                        onError(throwable);
-                    }
+                .subscribe((@NonNull StreamInfo result) -> {
+                    isLoading.set(false);
+                    currentInfo = result;
+                    showContentWithAnimation(120, 0, 0);
+                    handleResult(result);
+                }, (@NonNull Throwable throwable) -> {
+                    isLoading.set(false);
+                    onError(throwable);
                 });
     }
 
@@ -884,9 +863,7 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement
         }
 
         disposables.add(Single.just(descriptionHtml)
-                .map(new Function<String, Spanned>() {
-                    @Override
-                    public Spanned apply(@io.reactivex.annotations.NonNull String description) throws Exception {
+                .map((@io.reactivex.annotations.NonNull String description) -> {
                         Spanned parsedDescription;
                         if (Build.VERSION.SDK_INT >= 24) {
                             parsedDescription = Html.fromHtml(description, 0);
@@ -895,16 +872,12 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement
                             parsedDescription = Html.fromHtml(description);
                         }
                         return parsedDescription;
-                    }
                 })
                 .subscribeOn(Schedulers.computation())
                 .observeOn(AndroidSchedulers.mainThread())
-                .subscribe(new Consumer<Spanned>() {
-                    @Override
-                    public void accept(@io.reactivex.annotations.NonNull Spanned spanned) throws Exception {
+                .subscribe((@io.reactivex.annotations.NonNull Spanned spanned) -> {
                         videoDescriptionView.setText(spanned);
                         videoDescriptionView.setVisibility(View.VISIBLE);
-                    }
                 }));
     }
 
@@ -1131,14 +1104,11 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement
     }
 
     public void onBlockedByGemaError() {
-        thumbnailBackgroundButton.setOnClickListener(new View.OnClickListener() {
-            @Override
-            public void onClick(View v) {
+        thumbnailBackgroundButton.setOnClickListener((View v) -> {
                 Intent intent = new Intent();
                 intent.setAction(Intent.ACTION_VIEW);
                 intent.setData(Uri.parse(getString(R.string.c3s_url)));
                 startActivity(intent);
-            }
         });
 
         showError(getString(R.string.blocked_by_gema), false, R.drawable.gruese_die_gema);
diff --git a/app/src/main/res/layout/fragment_video_detail.xml b/app/src/main/res/layout/fragment_video_detail.xml
index 2d39d3d70..d47a2215b 100644
--- a/app/src/main/res/layout/fragment_video_detail.xml
+++ b/app/src/main/res/layout/fragment_video_detail.xml
@@ -354,6 +354,24 @@
                             android:paddingTop="6dp"
                             android:text="@string/controls_popup_title"
                             android:textSize="12sp"/>
+
+                        <TextView
+                            android:id="@+id/detail_controls_download"
+                            android:layout_width="80dp"
+                            android:layout_height="55dp"
+                            android:layout_gravity="center_vertical"
+                            android:layout_weight="1"
+                            android:background="?attr/selectableItemBackground"
+                            android:clickable="true"
+                            android:focusable="true"
+                            android:contentDescription="@string/controls_download_desg"
+                            android:drawableTop="?attr/download"
+                            android:gravity="center"
+                            android:paddingBottom="6dp"
+                            android:paddingTop="6dp"
+                            android:text="@string/download"
+                            android:textSize="12sp"/>
+
                     </LinearLayout>
 
                     <View
diff --git a/app/src/main/res/menu/video_detail_menu.xml b/app/src/main/res/menu/video_detail_menu.xml
index 10580a098..fd44c7860 100644
--- a/app/src/main/res/menu/video_detail_menu.xml
+++ b/app/src/main/res/menu/video_detail_menu.xml
@@ -2,12 +2,6 @@
 <menu xmlns:android="http://schemas.android.com/apk/res/android"
       xmlns:app="http://schemas.android.com/apk/res-auto">
 
-    <item
-        android:id="@+id/menu_item_download"
-        android:icon="?attr/download"
-        android:title="@string/download"
-        app:showAsAction="always"/>
-
     <item
         android:id="@+id/action_play_with_kodi"
         android:icon="?attr/cast"
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 767bffa10..7c04cb802 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -13,6 +13,7 @@
     <string name="open_in_popup_mode">Open in popup mode</string>
     <string name="share">Share</string>
     <string name="download">Download</string>
+    <string name="controls_download_desg">Download stream file.</string>
     <string name="search">Search</string>
     <string name="settings">Settings</string>
     <string name="did_you_mean">Did you mean: %1$s ?</string>