diff --git a/app/src/main/java/com/syncedsynapse/kore2/Settings.java b/app/src/main/java/com/syncedsynapse/kore2/Settings.java index d91d226..9aa8258 100644 --- a/app/src/main/java/com/syncedsynapse/kore2/Settings.java +++ b/app/src/main/java/com/syncedsynapse/kore2/Settings.java @@ -22,7 +22,7 @@ import android.text.format.DateUtils; import com.syncedsynapse.kore2.utils.LogUtils; /** - * Singleton that holds the settings of the app. + * Singleton that holds the settings of the app, that are not stored in the default shared preferences * * Interfaces with {@link android.content.SharedPreferences} to load/store these preferences. */ @@ -52,7 +52,22 @@ public class Settings { // Default values private static final int DEFAULT_MAX_CAST_PICTURES = 12; - // Singleton instance + /** + * Default Shared Preferences keys. + * These settings are automatically managed by the Preferences mechanism. + * Make sure these are the same as in preferences.xml + */ + public static final String KEY_PREF_THEME = "pref_theme"; + public static final String KEY_PREF_SWITCH_TO_REMOTE_AFTER_MEDIA_START = + "pref_switch_to_remote_after_media_start"; + public static final String KEY_PREF_ABOUT = "pref_about"; + public static final String KEY_PREF_COFFEE = "pref_coffee"; + + public static final String DEFAULT_PREF_THEME = "0"; + public static final boolean DEFAULT_PREF_SWITCH_TO_REMOTE_AFTER_MEDIA_START = true; + + + // Singleton instance private static Settings instance = null; private Context context; diff --git a/app/src/main/java/com/syncedsynapse/kore2/ui/AlbumDetailsFragment.java b/app/src/main/java/com/syncedsynapse/kore2/ui/AlbumDetailsFragment.java index 5c50b02..ceb4702 100644 --- a/app/src/main/java/com/syncedsynapse/kore2/ui/AlbumDetailsFragment.java +++ b/app/src/main/java/com/syncedsynapse/kore2/ui/AlbumDetailsFragment.java @@ -23,6 +23,7 @@ import android.content.res.TypedArray; import android.database.Cursor; import android.net.Uri; import android.os.*; +import android.preference.PreferenceManager; import android.provider.BaseColumns; import android.support.v4.app.Fragment; import android.support.v4.app.LoaderManager; @@ -46,6 +47,7 @@ import android.widget.Toast; import com.melnykov.fab.FloatingActionButton; import com.melnykov.fab.ObservableScrollView; import com.syncedsynapse.kore2.R; +import com.syncedsynapse.kore2.Settings; import com.syncedsynapse.kore2.host.HostInfo; import com.syncedsynapse.kore2.host.HostManager; import com.syncedsynapse.kore2.jsonrpc.ApiCallback; @@ -97,6 +99,7 @@ public class AlbumDetailsFragment extends Fragment private String albumTitle; private List songInfoList = null; + @InjectView(R.id.exit_transition_view) View exitTransitionView; // Buttons @InjectView(R.id.fab) ImageButton fabButton; @InjectView(R.id.add_to_playlist) ImageButton addToPlaylistButton; @@ -189,6 +192,8 @@ public class AlbumDetailsFragment extends Fragment @Override public void onResume() { + // Force the exit view to invisible + exitTransitionView.setVisibility(View.INVISIBLE); super.onResume(); } @@ -258,7 +263,16 @@ public class AlbumDetailsFragment extends Fragment action.execute(hostManager.getConnection(), new ApiCallback() { @Override public void onSucess(String result) { - // Do nothing, play should be starting + // Check whether we should switch to the remote + boolean switchToRemote = PreferenceManager + .getDefaultSharedPreferences(getActivity()) + .getBoolean(Settings.KEY_PREF_SWITCH_TO_REMOTE_AFTER_MEDIA_START, + Settings.DEFAULT_PREF_SWITCH_TO_REMOTE_AFTER_MEDIA_START); + if (switchToRemote) { + int cx = (fabButton.getLeft() + fabButton.getRight()) / 2; + int cy = (fabButton.getTop() + fabButton.getBottom()) / 2; + UIUtils.switchToRemoteWithAnimation(getActivity(), cx, cy, exitTransitionView); + } } @Override diff --git a/app/src/main/java/com/syncedsynapse/kore2/ui/BaseActivity.java b/app/src/main/java/com/syncedsynapse/kore2/ui/BaseActivity.java index 046e1ad..2d1056f 100644 --- a/app/src/main/java/com/syncedsynapse/kore2/ui/BaseActivity.java +++ b/app/src/main/java/com/syncedsynapse/kore2/ui/BaseActivity.java @@ -20,6 +20,7 @@ import android.os.Bundle; import android.preference.PreferenceManager; import android.support.v7.app.ActionBarActivity; +import com.syncedsynapse.kore2.Settings; import com.syncedsynapse.kore2.utils.UIUtils; /** @@ -31,8 +32,7 @@ public class BaseActivity extends ActionBarActivity { protected void onCreate(Bundle savedInstanceState) { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); setTheme(UIUtils.getThemeResourceId( - prefs.getString(SettingsFragment.KEY_PREF_THEME, - SettingsFragment.DEFAULT_PREF_THEME))); + prefs.getString(Settings.KEY_PREF_THEME, Settings.DEFAULT_PREF_THEME))); super.onCreate(savedInstanceState); } diff --git a/app/src/main/java/com/syncedsynapse/kore2/ui/MovieDetailsFragment.java b/app/src/main/java/com/syncedsynapse/kore2/ui/MovieDetailsFragment.java index d0b591b..7845949 100644 --- a/app/src/main/java/com/syncedsynapse/kore2/ui/MovieDetailsFragment.java +++ b/app/src/main/java/com/syncedsynapse/kore2/ui/MovieDetailsFragment.java @@ -24,6 +24,7 @@ import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.os.Handler; +import android.preference.PreferenceManager; import android.provider.BaseColumns; import android.support.v4.app.Fragment; import android.support.v4.app.LoaderManager; @@ -107,9 +108,9 @@ public class MovieDetailsFragment extends Fragment @InjectView(R.id.swipe_refresh_layout) SwipeRefreshLayout swipeRefreshLayout; + @InjectView(R.id.exit_transition_view) View exitTransitionView; // Buttons @InjectView(R.id.fab) ImageButton fabButton; - @InjectView(R.id.add_to_playlist) ImageButton addToPlaylistButton; @InjectView(R.id.go_to_imdb) ImageButton imdbButton; @InjectView(R.id.download) ImageButton downloadButton; @@ -210,6 +211,8 @@ public class MovieDetailsFragment extends Fragment @Override public void onResume() { bus.register(this); + // Force the exit view to invisible + exitTransitionView.setVisibility(View.INVISIBLE); super.onResume(); } @@ -338,7 +341,16 @@ public class MovieDetailsFragment extends Fragment action.execute(hostManager.getConnection(), new ApiCallback() { @Override public void onSucess(String result) { - // Do nothing, play should be starting + // Check whether we should switch to the remote + boolean switchToRemote = PreferenceManager + .getDefaultSharedPreferences(getActivity()) + .getBoolean(Settings.KEY_PREF_SWITCH_TO_REMOTE_AFTER_MEDIA_START, + Settings.DEFAULT_PREF_SWITCH_TO_REMOTE_AFTER_MEDIA_START); + if (switchToRemote) { + int cx = (fabButton.getLeft() + fabButton.getRight()) / 2; + int cy = (fabButton.getTop() + fabButton.getBottom()) / 2; + UIUtils.switchToRemoteWithAnimation(getActivity(), cx, cy, exitTransitionView); + } } @Override diff --git a/app/src/main/java/com/syncedsynapse/kore2/ui/MusicVideoDetailsFragment.java b/app/src/main/java/com/syncedsynapse/kore2/ui/MusicVideoDetailsFragment.java index 949defd..b48e82c 100644 --- a/app/src/main/java/com/syncedsynapse/kore2/ui/MusicVideoDetailsFragment.java +++ b/app/src/main/java/com/syncedsynapse/kore2/ui/MusicVideoDetailsFragment.java @@ -24,6 +24,7 @@ import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.os.Handler; +import android.preference.PreferenceManager; import android.provider.BaseColumns; import android.support.v4.app.Fragment; import android.support.v4.app.LoaderManager; @@ -45,6 +46,7 @@ import android.widget.Toast; import com.melnykov.fab.FloatingActionButton; import com.melnykov.fab.ObservableScrollView; import com.syncedsynapse.kore2.R; +import com.syncedsynapse.kore2.Settings; import com.syncedsynapse.kore2.host.HostInfo; import com.syncedsynapse.kore2.host.HostManager; import com.syncedsynapse.kore2.jsonrpc.ApiCallback; @@ -100,6 +102,7 @@ public class MusicVideoDetailsFragment extends Fragment @InjectView(R.id.swipe_refresh_layout) SwipeRefreshLayout swipeRefreshLayout; + @InjectView(R.id.exit_transition_view) View exitTransitionView; // Buttons @InjectView(R.id.fab) ImageButton fabButton; @InjectView(R.id.add_to_playlist) ImageButton addToPlaylistButton; @@ -190,6 +193,8 @@ public class MusicVideoDetailsFragment extends Fragment @Override public void onResume() { bus.register(this); + // Force the exit view to invisible + exitTransitionView.setVisibility(View.INVISIBLE); super.onResume(); } @@ -295,7 +300,16 @@ public class MusicVideoDetailsFragment extends Fragment action.execute(hostManager.getConnection(), new ApiCallback() { @Override public void onSucess(String result) { - // Do nothing + // Check whether we should switch to the remote + boolean switchToRemote = PreferenceManager + .getDefaultSharedPreferences(getActivity()) + .getBoolean(Settings.KEY_PREF_SWITCH_TO_REMOTE_AFTER_MEDIA_START, + Settings.DEFAULT_PREF_SWITCH_TO_REMOTE_AFTER_MEDIA_START); + if (switchToRemote) { + int cx = (fabButton.getLeft() + fabButton.getRight()) / 2; + int cy = (fabButton.getTop() + fabButton.getBottom()) / 2; + UIUtils.switchToRemoteWithAnimation(getActivity(), cx, cy, exitTransitionView); + } } @Override diff --git a/app/src/main/java/com/syncedsynapse/kore2/ui/SettingsActivity.java b/app/src/main/java/com/syncedsynapse/kore2/ui/SettingsActivity.java index 181732f..92b7bff 100644 --- a/app/src/main/java/com/syncedsynapse/kore2/ui/SettingsActivity.java +++ b/app/src/main/java/com/syncedsynapse/kore2/ui/SettingsActivity.java @@ -25,6 +25,7 @@ import android.support.v7.widget.Toolbar; import android.view.MenuItem; import com.syncedsynapse.kore2.R; +import com.syncedsynapse.kore2.Settings; import com.syncedsynapse.kore2.utils.LogUtils; import com.syncedsynapse.kore2.utils.UIUtils; @@ -40,8 +41,8 @@ public class SettingsActivity extends ActionBarActivity{ protected void onCreate(Bundle savedInstanceState) { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); setTheme(UIUtils.getThemeResourceId( - prefs.getString(SettingsFragment.KEY_PREF_THEME, - SettingsFragment.DEFAULT_PREF_THEME))); + prefs.getString(Settings.KEY_PREF_THEME, + Settings.DEFAULT_PREF_THEME))); super.onCreate(savedInstanceState); setContentView(R.layout.activity_settings); diff --git a/app/src/main/java/com/syncedsynapse/kore2/ui/SettingsFragment.java b/app/src/main/java/com/syncedsynapse/kore2/ui/SettingsFragment.java index 8b78719..adf1161 100644 --- a/app/src/main/java/com/syncedsynapse/kore2/ui/SettingsFragment.java +++ b/app/src/main/java/com/syncedsynapse/kore2/ui/SettingsFragment.java @@ -46,14 +46,6 @@ public class SettingsFragment extends PreferenceFragment public static final String COFFEE_SKU = "coffee"; public static final int COFFEE_RC = 1001; - /** - * Preferences keys. Make sure these are the same as in preferences.xml - */ - public static final String KEY_PREF_THEME = "pref_theme"; - public static final String KEY_PREF_ABOUT = "pref_about"; - public static final String KEY_PREF_COFFEE = "pref_coffee"; - public static final String DEFAULT_PREF_THEME = "0"; - // Billing helper private IabHelper mBillingHelper; @@ -97,7 +89,7 @@ public class SettingsFragment extends PreferenceFragment // Update summaries setupPreferences(mSettings.hasBoughtCoffee); - if (key.equals(KEY_PREF_THEME)) { + if (key.equals(Settings.KEY_PREF_THEME)) { //String newTheme = sharedPreferences.getString(key, DEFAULT_PREF_THEME); // restart to apply new theme (actually build an entirely new task stack) @@ -118,7 +110,7 @@ public class SettingsFragment extends PreferenceFragment LogUtils.LOGD(TAG, "Setting up preferences. Has bought coffee? " + hasBoughtCoffee); // Coffee upgrade - final Preference coffeePref = findPreference(KEY_PREF_COFFEE); + final Preference coffeePref = findPreference(Settings.KEY_PREF_COFFEE); if (coffeePref != null) { if (hasBoughtCoffee) { if (settings.showThanksForCofeeMessage) { @@ -150,7 +142,7 @@ public class SettingsFragment extends PreferenceFragment } // Theme preferences - ListPreference themePref = (ListPreference)findPreference(KEY_PREF_THEME); + ListPreference themePref = (ListPreference)findPreference(Settings.KEY_PREF_THEME); if (hasBoughtCoffee) { themePref.setEnabled(true); themePref.setSummary(themePref.getEntry()); @@ -166,7 +158,7 @@ public class SettingsFragment extends PreferenceFragment getActivity().getPackageManager().getPackageInfo(getActivity().getPackageName(), 0).versionName; } catch (PackageManager.NameNotFoundException exc) { } - Preference aboutPreference = findPreference(KEY_PREF_ABOUT); + Preference aboutPreference = findPreference(Settings.KEY_PREF_ABOUT); aboutPreference.setSummary(nameAndVersion); aboutPreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { @Override @@ -202,7 +194,7 @@ public class SettingsFragment extends PreferenceFragment mSettings.save(); // Lock upgrade preference - Preference coffeePreference = findPreference(KEY_PREF_COFFEE); + Preference coffeePreference = findPreference(Settings.KEY_PREF_COFFEE); coffeePreference.setEnabled(false); coffeePreference.setSummary(getResources().getString(R.string.error_setting_up_billing, result.getMessage())); diff --git a/app/src/main/java/com/syncedsynapse/kore2/ui/TVShowEpisodeDetailsFragment.java b/app/src/main/java/com/syncedsynapse/kore2/ui/TVShowEpisodeDetailsFragment.java index 59220fc..5243616 100644 --- a/app/src/main/java/com/syncedsynapse/kore2/ui/TVShowEpisodeDetailsFragment.java +++ b/app/src/main/java/com/syncedsynapse/kore2/ui/TVShowEpisodeDetailsFragment.java @@ -24,6 +24,7 @@ import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.os.Handler; +import android.preference.PreferenceManager; import android.provider.BaseColumns; import android.support.v4.app.Fragment; import android.support.v4.app.LoaderManager; @@ -44,6 +45,7 @@ import android.widget.Toast; import com.melnykov.fab.FloatingActionButton; import com.melnykov.fab.ObservableScrollView; import com.syncedsynapse.kore2.R; +import com.syncedsynapse.kore2.Settings; import com.syncedsynapse.kore2.host.HostInfo; import com.syncedsynapse.kore2.host.HostManager; import com.syncedsynapse.kore2.jsonrpc.ApiCallback; @@ -100,6 +102,7 @@ public class TVShowEpisodeDetailsFragment extends Fragment @InjectView(R.id.swipe_refresh_layout) SwipeRefreshLayout swipeRefreshLayout; + @InjectView(R.id.exit_transition_view) View exitTransitionView; // Buttons @InjectView(R.id.fab) ImageButton fabButton; @InjectView(R.id.add_to_playlist) ImageButton addToPlaylistButton; @@ -201,6 +204,8 @@ public class TVShowEpisodeDetailsFragment extends Fragment @Override public void onResume() { bus.register(this); + // Force the exit view to invisible + exitTransitionView.setVisibility(View.INVISIBLE); super.onResume(); } @@ -329,7 +334,16 @@ public class TVShowEpisodeDetailsFragment extends Fragment action.execute(hostManager.getConnection(), new ApiCallback() { @Override public void onSucess(String result) { - // Do nothing, playback should start + // Check whether we should switch to the remote + boolean switchToRemote = PreferenceManager + .getDefaultSharedPreferences(getActivity()) + .getBoolean(Settings.KEY_PREF_SWITCH_TO_REMOTE_AFTER_MEDIA_START, + Settings.DEFAULT_PREF_SWITCH_TO_REMOTE_AFTER_MEDIA_START); + if (switchToRemote) { + int cx = (fabButton.getLeft() + fabButton.getRight()) / 2; + int cy = (fabButton.getTop() + fabButton.getBottom()) / 2; + UIUtils.switchToRemoteWithAnimation(getActivity(), cx, cy, exitTransitionView); + } } @Override diff --git a/app/src/main/java/com/syncedsynapse/kore2/utils/UIUtils.java b/app/src/main/java/com/syncedsynapse/kore2/utils/UIUtils.java index f19e685..b3376cb 100644 --- a/app/src/main/java/com/syncedsynapse/kore2/utils/UIUtils.java +++ b/app/src/main/java/com/syncedsynapse/kore2/utils/UIUtils.java @@ -15,13 +15,18 @@ */ package com.syncedsynapse.kore2.utils; +import android.animation.Animator; +import android.annotation.TargetApi; +import android.app.Activity; import android.content.Context; +import android.content.Intent; import android.content.res.Resources; import android.content.res.TypedArray; import android.text.TextUtils; import android.util.DisplayMetrics; import android.view.LayoutInflater; import android.view.View; +import android.view.ViewAnimationUtils; import android.view.WindowManager; import android.widget.GridLayout; import android.widget.ImageView; @@ -34,6 +39,7 @@ import com.syncedsynapse.kore2.host.HostInfo; import com.syncedsynapse.kore2.host.HostManager; import com.syncedsynapse.kore2.jsonrpc.type.GlobalType; import com.syncedsynapse.kore2.jsonrpc.type.VideoType; +import com.syncedsynapse.kore2.ui.RemoteActivity; import java.util.ArrayList; import java.util.List; @@ -356,4 +362,49 @@ public class UIUtils { return R.style.NightTheme; } } + + /** + * Launches the remote activity, performing a circular reveal animation if + * Lollipop or later + * + * @param context Context + * @param centerX Center X of the animation + * @param centerY Center Y of the animation + * @param exitTransitionView View to reveal. Should occupy the whole screen and + * be invisible before calling this + */ + @TargetApi(21) + public static void switchToRemoteWithAnimation(final Context context, + int centerX, int centerY, + final View exitTransitionView) { + final Intent launchIntent = new Intent(context, RemoteActivity.class); + if (Utils.isLollipopOrLater()) { + // Show the animation + int endRadius = Math.max(exitTransitionView.getHeight(), exitTransitionView.getWidth()); + Animator exitAnim = ViewAnimationUtils.createCircularReveal(exitTransitionView, + centerX, centerY, 0, endRadius); + + exitAnim.setDuration(200); + exitAnim.addListener(new Animator.AnimatorListener() { + @Override + public void onAnimationStart(Animator animation) {} + + @Override + public void onAnimationEnd(Animator animation) { + // Launch remote activity + context.startActivity(launchIntent); + } + + @Override public void onAnimationCancel(Animator animation) {} + + @Override + public void onAnimationRepeat(Animator animation) {} + }); + exitTransitionView.setVisibility(View.VISIBLE); + exitAnim.start(); + } else { + // No animation show, just launch the remote + context.startActivity(launchIntent); + } + } } diff --git a/app/src/main/res/layout/fragment_album_details.xml b/app/src/main/res/layout/fragment_album_details.xml index 616f4dd..68bff97 100644 --- a/app/src/main/res/layout/fragment_album_details.xml +++ b/app/src/main/res/layout/fragment_album_details.xml @@ -221,4 +221,11 @@ app:fab_colorNormal="?attr/fabColorNormal" app:fab_colorPressed="?attr/fabColorPressed"/> + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_episode_details.xml b/app/src/main/res/layout/fragment_episode_details.xml index 45e578c..eef3280 100644 --- a/app/src/main/res/layout/fragment_episode_details.xml +++ b/app/src/main/res/layout/fragment_episode_details.xml @@ -255,4 +255,12 @@ android:src="@drawable/ic_play_arrow_white_24dp" app:fab_colorNormal="?attr/fabColorNormal" app:fab_colorPressed="?attr/fabColorPressed"/> + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_movie_details.xml b/app/src/main/res/layout/fragment_movie_details.xml index 20455e3..a027c78 100644 --- a/app/src/main/res/layout/fragment_movie_details.xml +++ b/app/src/main/res/layout/fragment_movie_details.xml @@ -285,4 +285,12 @@ android:src="@drawable/ic_play_arrow_white_24dp" app:fab_colorNormal="?attr/fabColorNormal" app:fab_colorPressed="?attr/fabColorPressed"/> + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_music_video_details.xml b/app/src/main/res/layout/fragment_music_video_details.xml index 9501447..1775204 100644 --- a/app/src/main/res/layout/fragment_music_video_details.xml +++ b/app/src/main/res/layout/fragment_music_video_details.xml @@ -178,4 +178,12 @@ android:src="@drawable/ic_play_arrow_white_24dp" app:fab_colorNormal="?attr/fabColorNormal" app:fab_colorPressed="?attr/fabColorPressed"/> + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 417a6a4..f7c82e8 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -257,6 +257,9 @@ Solarized Solarized Dark + Switch to remote after media start + + About
diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index 782cc61..168571e 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -29,6 +29,11 @@ android:entryValues="@array/themes_values_array" android:defaultValue="0"/> + +