Java tutorial
/* * This file is part of Butter. * * Butter 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. * * Butter 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. * * You should have received a copy of the GNU General Public License * along with Butter. If not, see <http://www.gnu.org/licenses/>. */ package butter.droid.fragments.dialog; import android.annotation.TargetApi; import android.app.Activity; import android.app.Dialog; import android.content.DialogInterface; import android.os.Build; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.v4.app.DialogFragment; import android.text.TextUtils; import android.view.ContextThemeWrapper; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageButton; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; import com.squareup.picasso.Picasso; import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Date; import java.util.Locale; import java.util.Map; import butterknife.ButterKnife; import butterknife.Bind; import butterknife.OnClick; import butter.droid.R; import butter.droid.activities.MediaDetailActivity; import butter.droid.base.content.preferences.DefaultQuality; import butter.droid.base.content.preferences.Prefs; import butter.droid.base.providers.media.models.Episode; import butter.droid.base.providers.media.models.Media; import butter.droid.base.providers.media.models.Show; import butter.droid.base.providers.meta.MetaProvider; import butter.droid.base.providers.subs.SubsProvider; import butter.droid.base.torrent.Magnet; import butter.droid.base.torrent.StreamInfo; import butter.droid.base.utils.FragmentUtil; import butter.droid.base.utils.LocaleUtils; import butter.droid.base.utils.PixelUtils; import butter.droid.base.utils.PrefUtils; import butter.droid.base.utils.SortUtils; import butter.droid.base.utils.StringUtils; import butter.droid.base.utils.ThreadUtils; import butter.droid.base.utils.VersionUtils; import butter.droid.widget.BottomSheetScrollView; import butter.droid.widget.OptionSelector; public class EpisodeDialogFragment extends DialogFragment { public static final String EXTRA_EPISODE = "episode"; public static final String EXTRA_SHOW = "show"; private static final int ANIM_SPEED = 200; private Integer mThreshold = 0, mBottom = 0; private Activity mActivity; private MetaProvider mMetaProvider; private SubsProvider mSubsProvider; private boolean mTouching = false, mOpened = false; private String mSelectedSubtitleLanguage, mSelectedQuality; private Episode mEpisode; private Show mShow; private Magnet mMagnet; @Bind(R.id.scrollview) BottomSheetScrollView mScrollView; @Bind(R.id.placeholder) View mPlaceholder; @Bind(R.id.play_button) ImageButton mPlayButton; @Bind(R.id.header_image) ImageView mHeaderImage; @Bind(R.id.info) TextView mInfo; @Bind(R.id.title) TextView mTitle; @Bind(R.id.aired) TextView mAired; @Bind(R.id.synopsis) TextView mSynopsis; @Bind(R.id.subtitles) OptionSelector mSubtitles; @Bind(R.id.quality) OptionSelector mQuality; @Bind(R.id.magnet) @Nullable ImageButton mOpenMagnet; public static EpisodeDialogFragment newInstance(Show show, Episode episode) { EpisodeDialogFragment frag = new EpisodeDialogFragment(); Bundle args = new Bundle(); args.putParcelable(EXTRA_SHOW, show); args.putParcelable(EXTRA_EPISODE, episode); frag.setArguments(args); return frag; } @TargetApi(Build.VERSION_CODES.JELLY_BEAN) @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View v = LayoutInflater.from(new ContextThemeWrapper(getActivity(), R.style.Theme_Butter)) .inflate(R.layout.fragment_dialog_episode, container, false); ButterKnife.bind(this, v); if (!VersionUtils.isJellyBean()) { mPlayButton.setBackgroundDrawable(PixelUtils.changeDrawableColor(mPlayButton.getContext(), R.drawable.play_button_circle, mShow.color)); } else { mPlayButton.setBackground(PixelUtils.changeDrawableColor(mPlayButton.getContext(), R.drawable.play_button_circle, mShow.color)); } LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) mPlaceholder.getLayoutParams(); layoutParams.height = PixelUtils.getScreenHeight(mActivity); mPlaceholder.setLayoutParams(layoutParams); return v; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setStyle(STYLE_NO_FRAME, R.style.Theme_Dialog_Episode); setCancelable(false); mActivity = getActivity(); mThreshold = PixelUtils.getPixelsFromDp(mActivity, 220); mBottom = PixelUtils.getPixelsFromDp(mActivity, 33); mShow = getArguments().getParcelable(EXTRA_SHOW); mEpisode = getArguments().getParcelable(EXTRA_EPISODE); mMetaProvider = mEpisode.getMetaProvider(); mSubsProvider = mEpisode.getSubsProvider(); } @NonNull @Override public Dialog onCreateDialog(Bundle savedInstanceState) { Dialog dialog = super.onCreateDialog(savedInstanceState); dialog.setOnKeyListener(new DialogInterface.OnKeyListener() { @Override public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { smoothDismiss(); } return true; } }); return dialog; } public void smoothDismiss() { mOpened = false; if (mScrollView.getScrollY() <= mBottom) { dismiss(); return; } mScrollView.animateScrollTo(0, ANIM_SPEED); mScrollView.postDelayed(new Runnable() { @Override public void run() { try { dismiss(); } catch (Exception e) { } } }, ANIM_SPEED); } @Override public void onDismiss(DialogInterface dialog) { super.onDismiss(dialog); if (null != mMetaProvider) mMetaProvider.cancel(); if (null != mSubsProvider) mSubsProvider.cancel(); } @Override public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); mScrollView.postDelayed(new Runnable() { @Override public void run() { //mMaxHeight = PixelUtils.getScreenHeight(mActivity) - PixelUtils.getPixelsFromDp(mActivity, 50); int screenHeight = PixelUtils.getScreenHeight(mActivity); int scroll = (screenHeight / 3) * 2; mScrollView.animateScrollTo(scroll, ANIM_SPEED); mScrollView.postDelayed(new Runnable() { @Override public void run() { mOpened = true; } }, ANIM_SPEED); } }, 250); } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); if (!TextUtils.isEmpty(mEpisode.title)) { mTitle.setText(mEpisode.title); mHeaderImage.setContentDescription(mEpisode.title); } else { mTitle.setText(R.string.no_title_available); mHeaderImage.setContentDescription(getString(R.string.no_title_available)); } mAired.setVisibility(mEpisode.aired > 0 ? View.VISIBLE : View.GONE); Date airedDate = new Date((long) mEpisode.aired * 1000); mAired.setText(String.format(getString(R.string.aired), new SimpleDateFormat("MMMM dd, yyyy", LocaleUtils.getCurrent()).format(airedDate))); if (!TextUtils.isEmpty(mEpisode.overview)) mSynopsis.setText(mEpisode.overview); else mSynopsis.setText(R.string.no_synopsis_available); String seasonStr = Integer.toString(mEpisode.season); if (seasonStr.length() < 2) seasonStr = "0" + seasonStr; String episodeStr = Integer.toString(mEpisode.episode); if (episodeStr.length() < 2) episodeStr = "0" + episodeStr; mInfo.setText("S" + seasonStr + "E" + episodeStr); mSubtitles.setFragmentManager(getFragmentManager()); mQuality.setFragmentManager(getFragmentManager()); mSubtitles.setTitle(R.string.subtitles); mQuality.setTitle(R.string.quality); final String[] qualities = mEpisode.torrents.keySet().toArray(new String[mEpisode.torrents.size()]); SortUtils.sortQualities(qualities); mQuality.setData(qualities); String quality = DefaultQuality.get(mActivity, Arrays.asList(qualities)); int qualityIndex = Arrays.asList(qualities).indexOf(quality); mSelectedQuality = quality; mQuality.setText(mSelectedQuality); mQuality.setDefault(qualityIndex); updateMagnet(); mQuality.setListener(new OptionSelector.SelectorListener() { @Override public void onSelectionChanged(int position, String value) { mSelectedQuality = value; updateMagnet(); } }); mSubtitles.setText(R.string.loading_subs); mSubtitles.setClickable(false); if (mSubsProvider != null) { mSubsProvider.getList(mEpisode, new SubsProvider.Callback() { @Override public void onSuccess(Map<String, String> subtitles) { if (!FragmentUtil.isAdded(EpisodeDialogFragment.this)) return; mEpisode.subtitles = subtitles; String[] languages = subtitles.keySet().toArray(new String[subtitles.size()]); Arrays.sort(languages); final String[] adapterLanguages = new String[languages.length + 1]; adapterLanguages[0] = "no-subs"; System.arraycopy(languages, 0, adapterLanguages, 1, languages.length); String[] readableNames = new String[adapterLanguages.length]; for (int i = 0; i < readableNames.length; i++) { String language = adapterLanguages[i]; if (language.equals("no-subs")) { readableNames[i] = getString(R.string.no_subs); } else { Locale locale = LocaleUtils.toLocale(language); readableNames[i] = locale.getDisplayName(locale); } } mSubtitles.setListener(new OptionSelector.SelectorListener() { @Override public void onSelectionChanged(int position, String value) { onSubtitleLanguageSelected(adapterLanguages[position]); } }); mSubtitles.setData(readableNames); ThreadUtils.runOnUiThread(new Runnable() { @Override public void run() { mSubtitles.setClickable(true); } }); String defaultSubtitle = PrefUtils.get(mSubtitles.getContext(), Prefs.SUBTITLE_DEFAULT, null); if (subtitles.containsKey(defaultSubtitle)) { onSubtitleLanguageSelected(defaultSubtitle); mSubtitles.setDefault(Arrays.asList(adapterLanguages).indexOf(defaultSubtitle)); } else { onSubtitleLanguageSelected("no-subs"); mSubtitles.setDefault(Arrays.asList(adapterLanguages).indexOf("no-subs")); } } @Override public void onFailure(Exception e) { mSubtitles.setData(new String[0]); mSubtitles.setClickable(true); } }); } else { mSubtitles.setText(R.string.no_subs_available); } mScrollView.setListener(new BottomSheetScrollView.Listener() { @Override public void onScroll(int scrollY, BottomSheetScrollView.Direction direction) { } @Override public void onTouch(boolean touching) { mTouching = touching; int scrollY = mScrollView.getScrollY(); if (!mTouching && mOpened && scrollY <= mThreshold) { smoothDismiss(); } } @Override public void onScrollStart() { } @Override public void onScrollEnd() { if (!mTouching && mOpened && mScrollView.getScrollY() <= mThreshold) { smoothDismiss(); } } }); if (mMetaProvider != null) { mMetaProvider.getEpisodeMeta(mEpisode.imdbId, mEpisode.season, mEpisode.episode, new MetaProvider.Callback() { @Override public void onResult(MetaProvider.MetaData metaData, Exception e) { String imageUrl = mEpisode.headerImage; if (e == null) { imageUrl = metaData.images.poster; } Picasso.with(mHeaderImage.getContext()).load(imageUrl).into(mHeaderImage); } }); } else { Picasso.with(mHeaderImage.getContext()).load(mEpisode.headerImage).into(mHeaderImage); } } @Override public void onAttach(Activity activity) { super.onAttach(activity); } private void updateMagnet() { if (mOpenMagnet == null) return; if (mMagnet == null) { mMagnet = new Magnet(mActivity, mEpisode.torrents.get(mSelectedQuality).url); } mMagnet.setUrl(mEpisode.torrents.get(mSelectedQuality).url); if (!mMagnet.canOpen()) { mOpenMagnet.setVisibility(View.GONE); } else { mOpenMagnet.setVisibility(View.VISIBLE); } } @OnClick(R.id.synopsis) public void readMoreClick(View v) { if (getFragmentManager().findFragmentByTag("overlay_fragment") != null) return; SynopsisDialogFragment synopsisDialogFragment = new SynopsisDialogFragment(); Bundle b = new Bundle(); b.putString("text", mEpisode.overview); synopsisDialogFragment.setArguments(b); synopsisDialogFragment.show(getFragmentManager(), "overlay_fragment"); } @OnClick(R.id.play_button) public void playClick() { smoothDismiss(); Media.Torrent torrent = mEpisode.torrents.get(mSelectedQuality); StreamInfo streamInfo = new StreamInfo(mEpisode, mShow, torrent.url, mSelectedSubtitleLanguage, mSelectedQuality); ((MediaDetailActivity) getActivity()).playStream(streamInfo); } @Nullable @OnClick(R.id.magnet) public void openMagnet() { mMagnet.open(mActivity); } @OnClick(R.id.placeholder) public void outsideClick() { smoothDismiss(); } private void onSubtitleLanguageSelected(String language) { mSelectedSubtitleLanguage = language; if (!language.equals("no-subs")) { final Locale locale = LocaleUtils.toLocale(language); ThreadUtils.runOnUiThread(new Runnable() { @Override public void run() { mSubtitles.setText(StringUtils.uppercaseFirst(locale.getDisplayName(locale))); } }); } else { ThreadUtils.runOnUiThread(new Runnable() { @Override public void run() { mSubtitles.setText(R.string.no_subs); } }); } } }