mirror of
				https://github.com/TeamNewPipe/NewPipe
				synced 2025-10-30 23:03:00 +00:00 
			
		
		
		
	Merge pull request #1106 from TeamNewPipe/upenuns
Remove actionBarHandler
This commit is contained in:
		| @@ -1,150 +0,0 @@ | ||||
| package org.schabi.newpipe.fragments.detail; | ||||
|  | ||||
| import android.content.SharedPreferences; | ||||
| import android.preference.PreferenceManager; | ||||
| import android.support.v7.app.AppCompatActivity; | ||||
| import android.util.Log; | ||||
| import android.view.Menu; | ||||
| import android.view.MenuInflater; | ||||
| import android.view.MenuItem; | ||||
| import android.view.View; | ||||
| import android.widget.AdapterView; | ||||
| import android.widget.Spinner; | ||||
|  | ||||
| import org.schabi.newpipe.R; | ||||
| import org.schabi.newpipe.extractor.stream.VideoStream; | ||||
| import org.schabi.newpipe.util.ListHelper; | ||||
|  | ||||
| import java.util.List; | ||||
|  | ||||
| /* | ||||
|  * Created by Christian Schabesberger on 18.08.15. | ||||
|  * <p> | ||||
|  * Copyright (C) Christian Schabesberger 2015 <chris.schabesberger@mailbox.org> | ||||
|  * DetailsMenuHandler.java is part of NewPipe. | ||||
|  * <p> | ||||
|  * NewPipe is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * <p> | ||||
|  * NewPipe is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * <p> | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with NewPipe.  If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
|  | ||||
| @SuppressWarnings("WeakerAccess") | ||||
| class ActionBarHandler { | ||||
|     private static final String TAG = "ActionBarHandler"; | ||||
|  | ||||
|     private AppCompatActivity activity; | ||||
|     private int selectedVideoStream = -1; | ||||
|  | ||||
|     private SharedPreferences defaultPreferences; | ||||
|  | ||||
|     private Menu menu; | ||||
|  | ||||
|     // Only callbacks are listed here, there are more actions which don't need a callback. | ||||
|     // those are edited directly. Typically VideoDetailFragment will implement those callbacks. | ||||
|     private OnActionListener onShareListener; | ||||
|     private OnActionListener onOpenInBrowserListener; | ||||
|     private OnActionListener onPlayWithKodiListener; | ||||
|  | ||||
|     // Triggered when a stream related action is triggered. | ||||
|     public interface OnActionListener { | ||||
|         void onActionSelected(int selectedStreamId); | ||||
|     } | ||||
|  | ||||
|     public ActionBarHandler(AppCompatActivity activity) { | ||||
|         this.activity = activity; | ||||
|     } | ||||
|  | ||||
|     public void setupStreamList(final List<VideoStream> videoStreams, Spinner toolbarSpinner) { | ||||
|         if (activity == null) return; | ||||
|  | ||||
|         selectedVideoStream = ListHelper.getDefaultResolutionIndex(activity, videoStreams); | ||||
|  | ||||
|         boolean isExternalPlayerEnabled = PreferenceManager.getDefaultSharedPreferences(activity).getBoolean(activity.getString(R.string.use_external_video_player_key), false); | ||||
|         toolbarSpinner.setAdapter(new SpinnerToolbarAdapter(activity, videoStreams, isExternalPlayerEnabled)); | ||||
|         toolbarSpinner.setSelection(selectedVideoStream); | ||||
|         toolbarSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { | ||||
|             @Override | ||||
|             public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { | ||||
|                 selectedVideoStream = position; | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public void onNothingSelected(AdapterView<?> parent) { | ||||
|             } | ||||
|         }); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     public void setupMenu(Menu menu, MenuInflater inflater) { | ||||
|         this.menu = menu; | ||||
|  | ||||
|         // CAUTION set item properties programmatically otherwise it would not be accepted by | ||||
|         // appcompat itemsinflater.inflate(R.menu.videoitem_detail, menu); | ||||
|  | ||||
|         defaultPreferences = PreferenceManager.getDefaultSharedPreferences(activity); | ||||
|         inflater.inflate(R.menu.video_detail_menu, menu); | ||||
|  | ||||
|         updateItemsVisibility(); | ||||
|     } | ||||
|  | ||||
|     public void updateItemsVisibility(){ | ||||
|         showPlayWithKodiAction(defaultPreferences.getBoolean(activity.getString(R.string.show_play_with_kodi_key), false)); | ||||
|     } | ||||
|  | ||||
|     public boolean onItemSelected(MenuItem item) { | ||||
|         int id = item.getItemId(); | ||||
|         switch (id) { | ||||
|             case R.id.menu_item_share: { | ||||
|                 if (onShareListener != null) { | ||||
|                     onShareListener.onActionSelected(selectedVideoStream); | ||||
|                 } | ||||
|                 return true; | ||||
|             } | ||||
|             case R.id.menu_item_openInBrowser: { | ||||
|                 if (onOpenInBrowserListener != null) { | ||||
|                     onOpenInBrowserListener.onActionSelected(selectedVideoStream); | ||||
|                 } | ||||
|                 return true; | ||||
|             } | ||||
|             case R.id.action_play_with_kodi: | ||||
|                 if (onPlayWithKodiListener != null) { | ||||
|                     onPlayWithKodiListener.onActionSelected(selectedVideoStream); | ||||
|                 } | ||||
|                 return true; | ||||
|             default: | ||||
|                 Log.e(TAG, "Menu Item not known"); | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     public int getSelectedVideoStream() { | ||||
|         return selectedVideoStream; | ||||
|     } | ||||
|  | ||||
|     public void setOnShareListener(OnActionListener listener) { | ||||
|         onShareListener = listener; | ||||
|     } | ||||
|  | ||||
|     public void setOnOpenInBrowserListener(OnActionListener listener) { | ||||
|         onOpenInBrowserListener = listener; | ||||
|     } | ||||
|  | ||||
|     public void setOnPlayWithKodiListener(OnActionListener listener) { | ||||
|         onPlayWithKodiListener = listener; | ||||
|     } | ||||
|  | ||||
|     public void showPlayWithKodiAction(boolean visible) { | ||||
|         menu.findItem(R.id.action_play_with_kodi).setVisible(visible); | ||||
|     } | ||||
|  | ||||
| } | ||||
| @@ -31,6 +31,7 @@ import android.view.MenuItem; | ||||
| import android.view.MotionEvent; | ||||
| import android.view.View; | ||||
| import android.view.ViewGroup; | ||||
| import android.widget.AdapterView; | ||||
| import android.widget.FrameLayout; | ||||
| import android.widget.ImageButton; | ||||
| import android.widget.ImageView; | ||||
| @@ -95,13 +96,17 @@ import io.reactivex.schedulers.Schedulers; | ||||
|  | ||||
| import static org.schabi.newpipe.util.AnimationUtils.animateView; | ||||
|  | ||||
| public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implements BackPressable, SharedPreferences.OnSharedPreferenceChangeListener, View.OnClickListener, View.OnLongClickListener { | ||||
| public class VideoDetailFragment | ||||
|         extends BaseStateFragment<StreamInfo> | ||||
|         implements BackPressable, | ||||
|         SharedPreferences.OnSharedPreferenceChangeListener, | ||||
|         View.OnClickListener, | ||||
|         View.OnLongClickListener { | ||||
|     public static final String AUTO_PLAY = "auto_play"; | ||||
|  | ||||
|     // Amount of videos to show on start | ||||
|     private static final int INITIAL_RELATED_VIDEOS = 8; | ||||
|  | ||||
|     private ActionBarHandler actionBarHandler; | ||||
|     private ArrayList<VideoStream> sortedStreamVideosList; | ||||
|  | ||||
|     private InfoItemBuilder infoItemBuilder = null; | ||||
| @@ -126,9 +131,12 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement | ||||
|     private Disposable currentWorker; | ||||
|     private CompositeDisposable disposables = new CompositeDisposable(); | ||||
|  | ||||
|     private int selectedVideoStream = -1; | ||||
|  | ||||
|     /*////////////////////////////////////////////////////////////////////////// | ||||
|     // Views | ||||
|     //////////////////////////////////////////////////////////////////////////*/ | ||||
|     private Menu menu; | ||||
|  | ||||
|     private Spinner spinnerToolbar; | ||||
|  | ||||
| @@ -169,6 +177,7 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement | ||||
|     private LinearLayout relatedStreamsView; | ||||
|     private ImageButton relatedStreamExpandButton; | ||||
|  | ||||
|  | ||||
|     /*////////////////////////////////////////////////////////////////////////*/ | ||||
|  | ||||
|     public static VideoDetailFragment getInstance(int serviceId, String videoUrl, String name) { | ||||
| @@ -186,8 +195,10 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement | ||||
|         super.onCreate(savedInstanceState); | ||||
|         setHasOptionsMenu(true); | ||||
|  | ||||
|         showRelatedStreams = PreferenceManager.getDefaultSharedPreferences(activity).getBoolean(getString(R.string.show_next_video_key), true); | ||||
|         PreferenceManager.getDefaultSharedPreferences(activity).registerOnSharedPreferenceChangeListener(this); | ||||
|         showRelatedStreams = PreferenceManager.getDefaultSharedPreferences(activity) | ||||
|                 .getBoolean(getString(R.string.show_next_video_key), true); | ||||
|         PreferenceManager.getDefaultSharedPreferences(activity) | ||||
|                 .registerOnSharedPreferenceChangeListener(this); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
| @@ -208,10 +219,13 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement | ||||
|         if (updateFlags != 0) { | ||||
|             if (!isLoading.get() && currentInfo != null) { | ||||
|                 if ((updateFlags & RELATED_STREAMS_UPDATE_FLAG) != 0) initRelatedVideos(currentInfo); | ||||
|                 if ((updateFlags & RESOLUTIONS_MENU_UPDATE_FLAG) != 0) setupActionBarHandler(currentInfo); | ||||
|                 if ((updateFlags & RESOLUTIONS_MENU_UPDATE_FLAG) != 0) setupActionBar(currentInfo); | ||||
|             } | ||||
|  | ||||
|             if ((updateFlags & TOOLBAR_ITEMS_UPDATE_FLAG) != 0 && actionBarHandler != null) actionBarHandler.updateItemsVisibility(); | ||||
|             if ((updateFlags & TOOLBAR_ITEMS_UPDATE_FLAG) != 0 | ||||
|                     && menu != null) { | ||||
|                 updateMenuItemVisibility(); | ||||
|             } | ||||
|             updateFlags = 0; | ||||
|         } | ||||
|  | ||||
| @@ -224,7 +238,8 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement | ||||
|     @Override | ||||
|     public void onDestroy() { | ||||
|         super.onDestroy(); | ||||
|         PreferenceManager.getDefaultSharedPreferences(activity).unregisterOnSharedPreferenceChangeListener(this); | ||||
|         PreferenceManager.getDefaultSharedPreferences(activity) | ||||
|                 .unregisterOnSharedPreferenceChangeListener(this); | ||||
|  | ||||
|         if (currentWorker != null) currentWorker.dispose(); | ||||
|         if (disposables != null) disposables.clear(); | ||||
| @@ -285,7 +300,8 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement | ||||
|         // Check if the next video label and video is visible, | ||||
|         // if it is, include the two elements in the next check | ||||
|         int nextCount = currentInfo != null && currentInfo.getNextVideo() != null ? 2 : 0; | ||||
|         if (relatedStreamsView != null && relatedStreamsView.getChildCount() > INITIAL_RELATED_VIDEOS + nextCount) { | ||||
|         if (relatedStreamsView != null | ||||
|                 && relatedStreamsView.getChildCount() > INITIAL_RELATED_VIDEOS + nextCount) { | ||||
|             outState.putSerializable(WAS_RELATED_EXPANDED_KEY, true); | ||||
|         } | ||||
|  | ||||
| @@ -345,7 +361,7 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement | ||||
|                     DownloadDialog downloadDialog = | ||||
|                             DownloadDialog.newInstance(currentInfo, | ||||
|                                     sortedStreamVideosList, | ||||
|                                     actionBarHandler.getSelectedVideoStream()); | ||||
|                                     selectedVideoStream); | ||||
|                     downloadDialog.show(activity.getSupportFragmentManager(), "downloadDialog"); | ||||
|                 } catch (Exception e) { | ||||
|                     Toast.makeText(activity, | ||||
| @@ -417,8 +433,10 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement | ||||
|         int initialCount = INITIAL_RELATED_VIDEOS + nextCount; | ||||
|  | ||||
|         if (relatedStreamsView.getChildCount() > initialCount) { | ||||
|             relatedStreamsView.removeViews(initialCount, relatedStreamsView.getChildCount() - (initialCount)); | ||||
|             relatedStreamExpandButton.setImageDrawable(ContextCompat.getDrawable(activity, ThemeHelper.resolveResourceIdFromAttr(activity, R.attr.expand))); | ||||
|             relatedStreamsView.removeViews(initialCount, | ||||
|                     relatedStreamsView.getChildCount() - (initialCount)); | ||||
|             relatedStreamExpandButton.setImageDrawable(ContextCompat.getDrawable( | ||||
|                     activity, ThemeHelper.resolveResourceIdFromAttr(activity, R.attr.expand))); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
| @@ -428,7 +446,9 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement | ||||
|             //Log.d(TAG, "i = " + i); | ||||
|             relatedStreamsView.addView(infoItemBuilder.buildView(relatedStreamsView, item)); | ||||
|         } | ||||
|         relatedStreamExpandButton.setImageDrawable(ContextCompat.getDrawable(activity, ThemeHelper.resolveResourceIdFromAttr(activity, R.attr.collapse))); | ||||
|         relatedStreamExpandButton.setImageDrawable( | ||||
|                 ContextCompat.getDrawable(activity, | ||||
|                         ThemeHelper.resolveResourceIdFromAttr(activity, R.attr.collapse))); | ||||
|     } | ||||
|  | ||||
|     /*////////////////////////////////////////////////////////////////////////// | ||||
| @@ -483,7 +503,6 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement | ||||
|  | ||||
|         relatedStreamExpandButton = rootView.findViewById(R.id.detail_related_streams_expand); | ||||
|  | ||||
|         actionBarHandler = new ActionBarHandler(activity); | ||||
|         infoItemBuilder = new InfoItemBuilder(activity); | ||||
|         setHeightThumbnail(); | ||||
|     } | ||||
| @@ -547,7 +566,10 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement | ||||
|  | ||||
|     private View.OnTouchListener getOnControlsTouchListener() { | ||||
|         return (View view, MotionEvent motionEvent) -> { | ||||
|             if (!PreferenceManager.getDefaultSharedPreferences(activity).getBoolean(getString(R.string.show_hold_to_append_key), true)) return false; | ||||
|             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, () -> | ||||
| @@ -560,10 +582,21 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement | ||||
|     private void initThumbnailViews(StreamInfo info) { | ||||
|         thumbnailImageView.setImageResource(R.drawable.dummy_thumbnail_dark); | ||||
|         if (!TextUtils.isEmpty(info.getThumbnailUrl())) { | ||||
|             imageLoader.displayImage(info.getThumbnailUrl(), thumbnailImageView, DISPLAY_THUMBNAIL_OPTIONS, new SimpleImageLoadingListener() { | ||||
|             imageLoader.displayImage( | ||||
|                     info.getThumbnailUrl(), | ||||
|                     thumbnailImageView, | ||||
|                     DISPLAY_THUMBNAIL_OPTIONS, new SimpleImageLoadingListener() { | ||||
|                 @Override | ||||
|                 public void onLoadingFailed(String imageUri, View view, FailReason failReason) { | ||||
|                     ErrorActivity.reportError(activity, failReason.getCause(), null, activity.findViewById(android.R.id.content), ErrorActivity.ErrorInfo.make(UserAction.LOAD_IMAGE, NewPipe.getNameOfService(currentInfo.getServiceId()), imageUri, R.string.could_not_load_thumbnails)); | ||||
|                     ErrorActivity.reportError( | ||||
|                             activity, | ||||
|                             failReason.getCause(), | ||||
|                             null, | ||||
|                             activity.findViewById(android.R.id.content), | ||||
|                             ErrorActivity.ErrorInfo.make(UserAction.LOAD_IMAGE, | ||||
|                                     NewPipe.getNameOfService(currentInfo.getServiceId()), | ||||
|                                     imageUri, | ||||
|                                     R.string.could_not_load_thumbnails)); | ||||
|                 } | ||||
|             }); | ||||
|         } | ||||
| @@ -578,14 +611,17 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement | ||||
|  | ||||
|         if (info.getNextVideo() != null && showRelatedStreams) { | ||||
|             nextStreamTitle.setVisibility(View.VISIBLE); | ||||
|             relatedStreamsView.addView(infoItemBuilder.buildView(relatedStreamsView, info.getNextVideo())); | ||||
|             relatedStreamsView.addView( | ||||
|                     infoItemBuilder.buildView(relatedStreamsView, info.getNextVideo())); | ||||
|             relatedStreamsView.addView(getSeparatorView()); | ||||
|             relatedStreamRootLayout.setVisibility(View.VISIBLE); | ||||
|         } else nextStreamTitle.setVisibility(View.GONE); | ||||
|  | ||||
|         if (info.related_streams != null && !info.related_streams.isEmpty() && showRelatedStreams) { | ||||
|             //long first = System.nanoTime(), each; | ||||
|             int to = info.getRelatedStreams().size() >= INITIAL_RELATED_VIDEOS ? INITIAL_RELATED_VIDEOS : info.getRelatedStreams().size(); | ||||
|             int to = info.getRelatedStreams().size() >= INITIAL_RELATED_VIDEOS | ||||
|                     ? INITIAL_RELATED_VIDEOS | ||||
|                     : info.getRelatedStreams().size(); | ||||
|             for (int i = 0; i < to; i++) { | ||||
|                 InfoItem item = info.getRelatedStreams().get(i); | ||||
|                 //each = System.nanoTime(); | ||||
| @@ -597,7 +633,8 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement | ||||
|             relatedStreamRootLayout.setVisibility(View.VISIBLE); | ||||
|             relatedStreamExpandButton.setVisibility(View.VISIBLE); | ||||
|  | ||||
|             relatedStreamExpandButton.setImageDrawable(ContextCompat.getDrawable(activity, ThemeHelper.resolveResourceIdFromAttr(activity, R.attr.expand))); | ||||
|             relatedStreamExpandButton.setImageDrawable(ContextCompat.getDrawable( | ||||
|                     activity, ThemeHelper.resolveResourceIdFromAttr(activity, R.attr.expand))); | ||||
|         } else { | ||||
|             if (info.getNextVideo() == null) relatedStreamRootLayout.setVisibility(View.GONE); | ||||
|             relatedStreamExpandButton.setVisibility(View.GONE); | ||||
| @@ -610,7 +647,15 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement | ||||
|  | ||||
|     @Override | ||||
|     public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { | ||||
|         actionBarHandler.setupMenu(menu, inflater); | ||||
|         this.menu = menu; | ||||
|  | ||||
|         // CAUTION set item properties programmatically otherwise it would not be accepted by | ||||
|         // appcompat itemsinflater.inflate(R.menu.videoitem_detail, menu); | ||||
|  | ||||
|         inflater.inflate(R.menu.video_detail_menu, menu); | ||||
|  | ||||
|         updateMenuItemVisibility(); | ||||
|  | ||||
|         ActionBar supportActionBar = activity.getSupportActionBar(); | ||||
|         if (supportActionBar != null) { | ||||
|             supportActionBar.setDisplayHomeAsUpEnabled(true); | ||||
| @@ -618,9 +663,47 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private void updateMenuItemVisibility() { | ||||
|  | ||||
|         // show kodi if set in settings | ||||
|         menu.findItem(R.id.action_play_with_kodi).setVisible( | ||||
|                 PreferenceManager.getDefaultSharedPreferences(activity).getBoolean( | ||||
|                         activity.getString(R.string.show_play_with_kodi_key), false)); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public boolean onOptionsItemSelected(MenuItem item) { | ||||
|         return (!isLoading.get() && actionBarHandler.onItemSelected(item)) || super.onOptionsItemSelected(item); | ||||
|         if(isLoading.get()) { | ||||
|             // if is still loading block menu | ||||
|             return true; | ||||
|         } | ||||
|  | ||||
|         int id = item.getItemId(); | ||||
|         switch (id) { | ||||
|             case R.id.menu_item_share: { | ||||
|                 if(currentInfo != null) { | ||||
|                     shareUrl(currentInfo.name, url); | ||||
|                 } else { | ||||
|                     shareUrl(url, url); | ||||
|                 } | ||||
|                 return true; | ||||
|             } | ||||
|             case R.id.menu_item_openInBrowser: { | ||||
|                 openUrlInBrowser(url); | ||||
|                 return true; | ||||
|             } | ||||
|             case R.id.action_play_with_kodi: | ||||
|                 try { | ||||
|                     NavigationHelper.playWithKore(activity, Uri.parse( | ||||
|                             url.replace("https", "http"))); | ||||
|                 } catch (Exception e) { | ||||
|                     if(DEBUG) Log.i(TAG, "Failed to start kore", e); | ||||
|                     showInstallKoreDialog(activity); | ||||
|                 } | ||||
|                 return true; | ||||
|             default: | ||||
|                 return super.onOptionsItemSelected(item); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private static void showInstallKoreDialog(final Context context) { | ||||
| @@ -632,22 +715,31 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement | ||||
|         builder.create().show(); | ||||
|     } | ||||
|  | ||||
|     private void setupActionBarHandler(final StreamInfo info) { | ||||
|     private void setupActionBarOnError(final String url) { | ||||
|         if (DEBUG) Log.d(TAG, "setupActionBarHandlerOnError() called with: url = [" + url + "]"); | ||||
|         Log.e("-----", "missing code"); | ||||
|     } | ||||
|  | ||||
|     private void setupActionBar(final StreamInfo info) { | ||||
|         if (DEBUG) Log.d(TAG, "setupActionBarHandler() called with: info = [" + info + "]"); | ||||
|         sortedStreamVideosList = new ArrayList<>(ListHelper.getSortedStreamVideosList(activity, info.getVideoStreams(), info.getVideoOnlyStreams(), false)); | ||||
|         actionBarHandler.setupStreamList(sortedStreamVideosList, spinnerToolbar); | ||||
|         actionBarHandler.setOnShareListener(selectedStreamId -> shareUrl(info.name, info.url)); | ||||
|         sortedStreamVideosList = new ArrayList<>(ListHelper.getSortedStreamVideosList( | ||||
|                 activity, info.getVideoStreams(), info.getVideoOnlyStreams(), false)); | ||||
|  | ||||
|         actionBarHandler.setOnOpenInBrowserListener((int selectedStreamId)-> | ||||
|                 openUrlInBrowser(info.getUrl())); | ||||
|         selectedVideoStream = ListHelper.getDefaultResolutionIndex(activity, sortedStreamVideosList); | ||||
|  | ||||
|         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); | ||||
|         boolean isExternalPlayerEnabled = PreferenceManager.getDefaultSharedPreferences(activity) | ||||
|                 .getBoolean(activity.getString(R.string.use_external_video_player_key), false); | ||||
|         spinnerToolbar.setAdapter(new SpinnerToolbarAdapter(activity, sortedStreamVideosList, | ||||
|                 isExternalPlayerEnabled)); | ||||
|         spinnerToolbar.setSelection(selectedVideoStream); | ||||
|         spinnerToolbar.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { | ||||
|             @Override | ||||
|             public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { | ||||
|                 selectedVideoStream = position; | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public void onNothingSelected(AdapterView<?> parent) { | ||||
|             } | ||||
|         }); | ||||
|  | ||||
| @@ -685,7 +777,10 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement | ||||
|     public void setTitleToUrl(int serviceId, String videoUrl, String name) { | ||||
|         if (name != null && !name.isEmpty()) { | ||||
|             for (StackItem stackItem : stack) { | ||||
|                 if (stack.peek().getServiceId() == serviceId && stackItem.getUrl().equals(videoUrl)) stackItem.setTitle(name); | ||||
|                 if (stack.peek().getServiceId() == serviceId | ||||
|                         && stackItem.getUrl().equals(videoUrl)) { | ||||
|                     stackItem.setTitle(name); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| @@ -727,18 +822,18 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement | ||||
|         pushToStack(serviceId, url, name); | ||||
|         showLoading(); | ||||
|  | ||||
|         Log.d(TAG, "prepareAndHandleInfo() called parallaxScrollRootView.getScrollY(): " + parallaxScrollRootView.getScrollY()); | ||||
|         Log.d(TAG, "prepareAndHandleInfo() called parallaxScrollRootView.getScrollY(): " | ||||
|                 + parallaxScrollRootView.getScrollY()); | ||||
|         final boolean greaterThanThreshold = parallaxScrollRootView.getScrollY() > (int) | ||||
|                 (getResources().getDisplayMetrics().heightPixels * .1f); | ||||
|  | ||||
|         if (scrollToTop) parallaxScrollRootView.smoothScrollTo(0, 0); | ||||
|         animateView(contentRootLayoutHiding, false, greaterThanThreshold ? 250 : 0, 0, new Runnable() { | ||||
|             @Override | ||||
|             public void run() { | ||||
|                 handleResult(info); | ||||
|                 showContentWithAnimation(120, 0, .01f); | ||||
|             } | ||||
|         }); | ||||
|         animateView(contentRootLayoutHiding, | ||||
|                 false, | ||||
|                 greaterThanThreshold ? 250 : 0, 0, () -> { | ||||
|                     handleResult(info); | ||||
|                     showContentWithAnimation(120, 0, .01f); | ||||
|                 }); | ||||
|     } | ||||
|  | ||||
|     protected void prepareAndLoadInfo() { | ||||
| @@ -773,7 +868,8 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement | ||||
|     //////////////////////////////////////////////////////////////////////////*/ | ||||
|  | ||||
|     private void openBackgroundPlayer(final boolean append) { | ||||
|         AudioStream audioStream = currentInfo.getAudioStreams().get(ListHelper.getDefaultAudioFormat(activity, currentInfo.getAudioStreams())); | ||||
|         AudioStream audioStream = currentInfo.getAudioStreams() | ||||
|                 .get(ListHelper.getDefaultAudioFormat(activity, currentInfo.getAudioStreams())); | ||||
|  | ||||
|         boolean useExternalAudioPlayer = PreferenceManager.getDefaultSharedPreferences(activity) | ||||
|                 .getBoolean(activity.getString(R.string.use_external_audio_player_key), false); | ||||
| @@ -781,7 +877,10 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement | ||||
|         if (!useExternalAudioPlayer && android.os.Build.VERSION.SDK_INT >= 16) { | ||||
|             openNormalBackgroundPlayer(append); | ||||
|         } else { | ||||
|             NavigationHelper.playOnExternalPlayer(activity, currentInfo.getName(), currentInfo.getUploaderName(), audioStream); | ||||
|             NavigationHelper.playOnExternalPlayer(activity, | ||||
|                     currentInfo.getName(), | ||||
|                     currentInfo.getUploaderName(), | ||||
|                     audioStream); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -806,8 +905,12 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement | ||||
|     private void openVideoPlayer() { | ||||
|         VideoStream selectedVideoStream = getSelectedVideoStream(); | ||||
|  | ||||
|         if (PreferenceManager.getDefaultSharedPreferences(activity).getBoolean(this.getString(R.string.use_external_video_player_key), false)) { | ||||
|             NavigationHelper.playOnExternalPlayer(activity, currentInfo.getName(), currentInfo.getUploaderName(), selectedVideoStream); | ||||
|         if (PreferenceManager.getDefaultSharedPreferences(activity) | ||||
|                 .getBoolean(this.getString(R.string.use_external_video_player_key), false)) { | ||||
|             NavigationHelper.playOnExternalPlayer(activity, | ||||
|                     currentInfo.getName(), | ||||
|                     currentInfo.getUploaderName(), | ||||
|                     selectedVideoStream); | ||||
|         } else { | ||||
|             openNormalPlayer(selectedVideoStream); | ||||
|         } | ||||
| @@ -828,7 +931,10 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement | ||||
|         if (!useOldPlayer) { | ||||
|             // ExoPlayer | ||||
|             final PlayQueue playQueue = new SinglePlayQueue(currentInfo); | ||||
|             mIntent = NavigationHelper.getPlayerIntent(activity, MainVideoPlayer.class, playQueue, getSelectedVideoStream().getResolution()); | ||||
|             mIntent = NavigationHelper.getPlayerIntent(activity, | ||||
|                     MainVideoPlayer.class, | ||||
|                     playQueue, | ||||
|                     getSelectedVideoStream().getResolution()); | ||||
|         } else { | ||||
|             // Internal Player | ||||
|             mIntent = new Intent(activity, PlayVideoActivity.class) | ||||
| @@ -849,7 +955,7 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement | ||||
|     } | ||||
|  | ||||
|     private VideoStream getSelectedVideoStream() { | ||||
|         return sortedStreamVideosList.get(actionBarHandler.getSelectedVideoStream()); | ||||
|         return sortedStreamVideosList.get(selectedVideoStream); | ||||
|     } | ||||
|  | ||||
|     private void prepareDescription(final String descriptionHtml) { | ||||
| @@ -859,28 +965,31 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement | ||||
|  | ||||
|         disposables.add(Single.just(descriptionHtml) | ||||
|                 .map((@io.reactivex.annotations.NonNull String description) -> { | ||||
|                         Spanned parsedDescription; | ||||
|                         if (Build.VERSION.SDK_INT >= 24) { | ||||
|                             parsedDescription = Html.fromHtml(description, 0); | ||||
|                         } else { | ||||
|                             //noinspection deprecation | ||||
|                             parsedDescription = Html.fromHtml(description); | ||||
|                         } | ||||
|                         return parsedDescription; | ||||
|                     Spanned parsedDescription; | ||||
|                     if (Build.VERSION.SDK_INT >= 24) { | ||||
|                         parsedDescription = Html.fromHtml(description, 0); | ||||
|                     } else { | ||||
|                         //noinspection deprecation | ||||
|                         parsedDescription = Html.fromHtml(description); | ||||
|                     } | ||||
|                     return parsedDescription; | ||||
|                 }) | ||||
|                 .subscribeOn(Schedulers.computation()) | ||||
|                 .observeOn(AndroidSchedulers.mainThread()) | ||||
|                 .subscribe((@io.reactivex.annotations.NonNull Spanned spanned) -> { | ||||
|                         videoDescriptionView.setText(spanned); | ||||
|                         videoDescriptionView.setVisibility(View.VISIBLE); | ||||
|                     videoDescriptionView.setText(spanned); | ||||
|                     videoDescriptionView.setVisibility(View.VISIBLE); | ||||
|                 })); | ||||
|     } | ||||
|  | ||||
|     private View getSeparatorView() { | ||||
|         View separator = new View(activity); | ||||
|         LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 1); | ||||
|         int m8 = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 8, getResources().getDisplayMetrics()); | ||||
|         int m5 = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 5, getResources().getDisplayMetrics()); | ||||
|         LinearLayout.LayoutParams params = | ||||
|                 new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 1); | ||||
|         int m8 = (int) TypedValue.applyDimension( | ||||
|                 TypedValue.COMPLEX_UNIT_DIP, 8, getResources().getDisplayMetrics()); | ||||
|         int m5 = (int) TypedValue.applyDimension( | ||||
|                 TypedValue.COMPLEX_UNIT_DIP, 5, getResources().getDisplayMetrics()); | ||||
|         params.setMargins(m8, m5, m8, m5); | ||||
|         separator.setLayoutParams(params); | ||||
|  | ||||
| @@ -894,13 +1003,20 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement | ||||
|     private void setHeightThumbnail() { | ||||
|         final DisplayMetrics metrics = getResources().getDisplayMetrics(); | ||||
|         boolean isPortrait = metrics.heightPixels > metrics.widthPixels; | ||||
|         int height = isPortrait ? (int) (metrics.widthPixels / (16.0f / 9.0f)) : (int) (metrics.heightPixels / 2f); | ||||
|         thumbnailImageView.setScaleType(isPortrait ? ImageView.ScaleType.CENTER_CROP : ImageView.ScaleType.FIT_CENTER); | ||||
|         thumbnailImageView.setLayoutParams(new FrameLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, height)); | ||||
|         int height = isPortrait | ||||
|                 ? (int) (metrics.widthPixels / (16.0f / 9.0f)) | ||||
|                 : (int) (metrics.heightPixels / 2f); | ||||
|         thumbnailImageView.setScaleType(isPortrait | ||||
|                 ? ImageView.ScaleType.CENTER_CROP | ||||
|                 : ImageView.ScaleType.FIT_CENTER); | ||||
|         thumbnailImageView.setLayoutParams( | ||||
|                 new FrameLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, height)); | ||||
|         thumbnailImageView.setMinimumHeight(height); | ||||
|     } | ||||
|  | ||||
|     private void showContentWithAnimation(long duration, long delay, @FloatRange(from = 0.0f, to = 1.0f) float translationPercent) { | ||||
|     private void showContentWithAnimation(long duration, | ||||
|                                           long delay, | ||||
|                                           @FloatRange(from = 0.0f, to = 1.0f) float translationPercent) { | ||||
|         int translationY = (int) (getResources().getDisplayMetrics().heightPixels * | ||||
|                 (translationPercent > 0.0f ? translationPercent : .06f)); | ||||
|  | ||||
| @@ -908,23 +1024,38 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement | ||||
|         contentRootLayoutHiding.setAlpha(0f); | ||||
|         contentRootLayoutHiding.setTranslationY(translationY); | ||||
|         contentRootLayoutHiding.setVisibility(View.VISIBLE); | ||||
|         contentRootLayoutHiding.animate().alpha(1f).translationY(0) | ||||
|                 .setStartDelay(delay).setDuration(duration).setInterpolator(new FastOutSlowInInterpolator()).start(); | ||||
|         contentRootLayoutHiding.animate() | ||||
|                 .alpha(1f) | ||||
|                 .translationY(0) | ||||
|                 .setStartDelay(delay) | ||||
|                 .setDuration(duration) | ||||
|                 .setInterpolator(new FastOutSlowInInterpolator()) | ||||
|                 .start(); | ||||
|  | ||||
|         uploaderRootLayout.animate().setListener(null).cancel(); | ||||
|         uploaderRootLayout.setAlpha(0f); | ||||
|         uploaderRootLayout.setTranslationY(translationY); | ||||
|         uploaderRootLayout.setVisibility(View.VISIBLE); | ||||
|         uploaderRootLayout.animate().alpha(1f).translationY(0) | ||||
|                 .setStartDelay((long) (duration * .5f) + delay).setDuration(duration).setInterpolator(new FastOutSlowInInterpolator()).start(); | ||||
|         uploaderRootLayout.animate() | ||||
|                 .alpha(1f) | ||||
|                 .translationY(0) | ||||
|                 .setStartDelay((long) (duration * .5f) + delay) | ||||
|                 .setDuration(duration) | ||||
|                 .setInterpolator(new FastOutSlowInInterpolator()) | ||||
|                 .start(); | ||||
|  | ||||
|         if (showRelatedStreams) { | ||||
|             relatedStreamRootLayout.animate().setListener(null).cancel(); | ||||
|             relatedStreamRootLayout.setAlpha(0f); | ||||
|             relatedStreamRootLayout.setTranslationY(translationY); | ||||
|             relatedStreamRootLayout.setVisibility(View.VISIBLE); | ||||
|             relatedStreamRootLayout.animate().alpha(1f).translationY(0) | ||||
|                     .setStartDelay((long) (duration * .8f) + delay).setDuration(duration).setInterpolator(new FastOutSlowInInterpolator()).start(); | ||||
|             relatedStreamRootLayout.animate() | ||||
|                     .alpha(1f) | ||||
|                     .translationY(0) | ||||
|                     .setStartDelay((long) (duration * .8f) + delay) | ||||
|                     .setDuration(duration) | ||||
|                     .setInterpolator(new FastOutSlowInInterpolator()) | ||||
|                     .start(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -938,12 +1069,8 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement | ||||
|         if (thumbnailImageView == null || activity == null) return; | ||||
|  | ||||
|         thumbnailImageView.setImageDrawable(ContextCompat.getDrawable(activity, imageResource)); | ||||
|         animateView(thumbnailImageView, false, 0, 0, new Runnable() { | ||||
|             @Override | ||||
|             public void run() { | ||||
|                 animateView(thumbnailImageView, true, 500); | ||||
|             } | ||||
|         }); | ||||
|         animateView(thumbnailImageView, false, 0, 0, | ||||
|                 () -> animateView(thumbnailImageView, true, 500)); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
| @@ -1048,7 +1175,7 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement | ||||
|         prepareDescription(info.getDescription()); | ||||
|  | ||||
|         animateView(spinnerToolbar, true, 500); | ||||
|         setupActionBarHandler(info); | ||||
|         setupActionBar(info); | ||||
|         initThumbnailViews(info); | ||||
|         initRelatedVideos(info); | ||||
|         if (wasRelatedStreamsExpanded) { | ||||
| @@ -1058,7 +1185,11 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement | ||||
|         setTitleToUrl(info.getServiceId(), info.getUrl(), info.getName()); | ||||
|  | ||||
|         if (!info.getErrors().isEmpty()) { | ||||
|             showSnackBarError(info.getErrors(), UserAction.REQUESTED_STREAM, NewPipe.getNameOfService(info.getServiceId()), info.getUrl(), 0); | ||||
|             showSnackBarError(info.getErrors(), | ||||
|                     UserAction.REQUESTED_STREAM, | ||||
|                     NewPipe.getNameOfService(info.getServiceId()), | ||||
|                     info.getUrl(), | ||||
|                     0); | ||||
|         } | ||||
|  | ||||
|         if (info.video_streams.isEmpty() && info.video_only_streams.isEmpty()) { | ||||
| @@ -1090,9 +1221,16 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement | ||||
|         } else if (exception instanceof ContentNotAvailableException) { | ||||
|             showError(getString(R.string.content_not_available), false); | ||||
|         } else { | ||||
|             int errorId = exception instanceof YoutubeStreamExtractor.DecryptException ? R.string.youtube_signature_decryption_error : | ||||
|                     exception instanceof ParsingException ? R.string.parsing_error : R.string.general_error; | ||||
|             onUnrecoverableError(exception, UserAction.REQUESTED_STREAM, NewPipe.getNameOfService(serviceId), url, errorId); | ||||
|             int errorId = exception instanceof YoutubeStreamExtractor.DecryptException | ||||
|                     ? R.string.youtube_signature_decryption_error | ||||
|                     : exception instanceof ParsingException | ||||
|                     ? R.string.parsing_error | ||||
|                     : R.string.general_error; | ||||
|             onUnrecoverableError(exception, | ||||
|                     UserAction.REQUESTED_STREAM, | ||||
|                     NewPipe.getNameOfService(serviceId), | ||||
|                     url, | ||||
|                     errorId); | ||||
|         } | ||||
|  | ||||
|         return true; | ||||
| @@ -1100,10 +1238,10 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement | ||||
|  | ||||
|     public void onBlockedByGemaError() { | ||||
|         thumbnailBackgroundButton.setOnClickListener((View v) -> { | ||||
|                 Intent intent = new Intent(); | ||||
|                 intent.setAction(Intent.ACTION_VIEW); | ||||
|                 intent.setData(Uri.parse(getString(R.string.c3s_url))); | ||||
|                 startActivity(intent); | ||||
|             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); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Christian Schabesberger
					Christian Schabesberger