diff options
Diffstat (limited to 'app')
4 files changed, 173 insertions, 66 deletions
diff --git a/app/src/androidTest/java/de/test/antennapod/ui/PreferencesTest.java b/app/src/androidTest/java/de/test/antennapod/ui/PreferencesTest.java index 040f4150b..91928f01e 100644 --- a/app/src/androidTest/java/de/test/antennapod/ui/PreferencesTest.java +++ b/app/src/androidTest/java/de/test/antennapod/ui/PreferencesTest.java @@ -3,10 +3,12 @@ package de.test.antennapod.ui; import android.content.Context; import android.content.res.Resources; import android.test.ActivityInstrumentationTestCase2; +import android.util.Log; import com.robotium.solo.Solo; import com.robotium.solo.Timeout; +import java.util.Arrays; import java.util.concurrent.TimeUnit; import de.danoeh.antennapod.R; @@ -362,4 +364,48 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference Timeout.getLargeTimeout())); } + + public void testRewindChange() { + int seconds = UserPreferences.getRewindSecs(); + int deltas[] = res.getIntArray(R.array.seek_delta_values); + + solo.clickOnText(solo.getString(R.string.pref_rewind)); + solo.waitForDialogToOpen(); + + int currentIndex = Arrays.binarySearch(deltas, seconds); + assertTrue(currentIndex >= 0 && currentIndex < deltas.length); // found? + + // Find next value (wrapping around to next) + int newIndex = (currentIndex + 1) % deltas.length; + + solo.clickOnText(String.valueOf(deltas[newIndex]) + " seconds"); + solo.clickOnButton("Confirm"); + + solo.waitForDialogToClose(); + assertTrue(solo.waitForCondition(() -> UserPreferences.getRewindSecs() == deltas[newIndex], + Timeout.getLargeTimeout())); + } + + public void testFastForwardChange() { + for (int i = 2; i > 0; i--) { // repeat twice to catch any error where fastforward is tracking rewind + int seconds = UserPreferences.getFastForwardSecs(); + int deltas[] = res.getIntArray(R.array.seek_delta_values); + + solo.clickOnText(solo.getString(R.string.pref_fast_forward)); + solo.waitForDialogToOpen(); + + int currentIndex = Arrays.binarySearch(deltas, seconds); + assertTrue(currentIndex >= 0 && currentIndex < deltas.length); // found? + + // Find next value (wrapping around to next) + int newIndex = (currentIndex + 1) % deltas.length; + + solo.clickOnText(String.valueOf(deltas[newIndex]) + " seconds"); + solo.clickOnButton("Confirm"); + + solo.waitForDialogToClose(); + assertTrue(solo.waitForCondition(() -> UserPreferences.getFastForwardSecs() == deltas[newIndex], + Timeout.getLargeTimeout())); + } + } } diff --git a/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java index 48b578be7..818864f79 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java @@ -1,6 +1,7 @@ package de.danoeh.antennapod.activity; import android.annotation.TargetApi; +import android.app.Activity; import android.content.Intent; import android.content.SharedPreferences; import android.content.res.TypedArray; @@ -9,6 +10,7 @@ import android.graphics.PixelFormat; import android.net.Uri; import android.os.Build; import android.os.Bundle; +import android.support.annotation.Nullable; import android.support.v7.app.AlertDialog; import android.util.Log; import android.view.Menu; @@ -42,6 +44,7 @@ import de.danoeh.antennapod.core.util.Converter; import de.danoeh.antennapod.core.util.Flavors; import de.danoeh.antennapod.core.util.ShareUtils; import de.danoeh.antennapod.core.util.StorageUtils; +import de.danoeh.antennapod.core.util.Supplier; import de.danoeh.antennapod.core.util.playback.MediaPlayerError; import de.danoeh.antennapod.core.util.playback.Playable; import de.danoeh.antennapod.core.util.playback.PlaybackController; @@ -49,6 +52,8 @@ import de.danoeh.antennapod.dialog.SleepTimerDialog; import de.danoeh.antennapod.dialog.VariableSpeedDialog; import rx.Observable; import rx.android.schedulers.AndroidSchedulers; +import rx.functions.Action1; +import rx.functions.Func1; import rx.schedulers.Schedulers; @@ -178,6 +183,13 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements }; } + protected static TextView getTxtvFFFromActivity(MediaplayerActivity activity) { + return activity.txtvFF; + } + protected static TextView getTxtvRevFromActivity(MediaplayerActivity activity) { + return activity.txtvRev; + } + protected void onSetSpeedAbilityChanged() { Log.d(TAG, "onSetSpeedAbilityChanged()"); updatePlaybackSpeedButton(); @@ -650,6 +662,91 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements // Only meaningful on AudioplayerActivity, where it is overridden. } + /** + * Abstract directions to skip forward or back (rewind) and encapsulates behavior to get or set preference (including update of UI on the skip buttons). + */ + static public enum SkipDirection { + SKIP_FORWARD( + UserPreferences::getFastForwardSecs, + MediaplayerActivity::getTxtvFFFromActivity, + UserPreferences::setFastForwardSecs, + R.string.pref_fast_forward), + SKIP_REWIND(UserPreferences::getRewindSecs, + MediaplayerActivity::getTxtvRevFromActivity, + UserPreferences::setRewindSecs, + R.string.pref_rewind); + + private final Supplier<Integer> getPrefSecsFn; + private final Func1<MediaplayerActivity, TextView> getTextViewFn; + private final Action1<Integer> setPrefSecsFn; + private final int titleResourceID; + + /** + * Constructor for skip direction enum. Stores references to utility functions and resource + * id's that vary dependending on the direction. + * + * @param getPrefSecsFn Handle to function that retrieves current seconds of the skip delta + * @param getTextViewFn Handle to function that gets the TextView which displays the current skip delta value + * @param setPrefSecsFn Handle to function that sets the preference (setting) for the skip delta value (and optionally updates the button label with the current values) + * @param titleResourceID ID of the resource string with the title for a view + */ + SkipDirection(Supplier<Integer> getPrefSecsFn, Func1<MediaplayerActivity, TextView> getTextViewFn, Action1<Integer> setPrefSecsFn, int titleResourceID) { + this.getPrefSecsFn = getPrefSecsFn; + this.getTextViewFn = getTextViewFn; + this.setPrefSecsFn = setPrefSecsFn; + this.titleResourceID = titleResourceID; + } + + + public int getPrefSkipSeconds() { + return(getPrefSecsFn.get()); + } + + /** + * Updates preferences for a forward or backward skip depending on the direction of the instance, optionally updating the UI. + * + * @param seconds Number of seconds to set the preference associated with the direction of the instance. + * @param activity MediaplyerActivity that contains textview to update the display of the skip delta setting (or null if nothing to update) + */ + public void setPrefSkipSeconds(int seconds, @Nullable Activity activity) { + setPrefSecsFn.call(seconds); + + if (activity != null && activity instanceof MediaplayerActivity) { + TextView tv = getTextViewFn.call((MediaplayerActivity)activity); + if (tv != null) tv.setText(String.valueOf(seconds)); + } + } + public int getTitleResourceID() { + return titleResourceID; + } + } + + static public void showSkipPreference(Activity activity, SkipDirection direction) { + int checked = 0; + int skipSecs = direction.getPrefSkipSeconds(); + final int[] values = activity.getResources().getIntArray(R.array.seek_delta_values); + final String[] choices = new String[values.length]; + for (int i = 0; i < values.length; i++) { + if (skipSecs == values[i]) { + checked = i; + } + choices[i] = String.valueOf(values[i]) + " " + activity.getString(R.string.time_seconds); + } + + AlertDialog.Builder builder = new AlertDialog.Builder(activity); + builder.setTitle(direction.getTitleResourceID()); + builder.setSingleChoiceItems(choices, checked, null); + builder.setNegativeButton(R.string.cancel_label, null); + builder.setPositiveButton(R.string.confirm_label, (dialog, which) -> { + int choice = ((AlertDialog)dialog).getListView().getCheckedItemPosition(); + if (choice < 0 || choice >= values.length) { + System.err.printf("Choice in showSkipPreference is out of bounds %d", choice); + } else { + direction.setPrefSkipSeconds(values[choice], activity); + } + }); + builder.create().show(); + } protected void setupGUI() { setContentView(getContentViewResourceId()); @@ -692,7 +789,7 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements butFF = (ImageButton) findViewById(R.id.butFF); txtvFF = (TextView) findViewById(R.id.txtvFF); if (txtvFF != null) { - txtvFF.setText(String.valueOf(UserPreferences.getFastFowardSecs())); + txtvFF.setText(String.valueOf(UserPreferences.getFastForwardSecs())); } butSkip = (ImageButton) findViewById(R.id.butSkip); @@ -704,37 +801,9 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements if (butRev != null) { butRev.setOnClickListener(v -> onRewind()); - butRev.setOnLongClickListener(new View.OnLongClickListener() { - - int choice; - - @Override - public boolean onLongClick(View v) { - int checked = 0; - int rewindSecs = UserPreferences.getRewindSecs(); - final int[] values = getResources().getIntArray(R.array.seek_delta_values); - final String[] choices = new String[values.length]; - for (int i = 0; i < values.length; i++) { - if (rewindSecs == values[i]) { - checked = i; - } - choices[i] = String.valueOf(values[i]) + " " + getString(R.string.time_seconds); - } - choice = values[checked]; - AlertDialog.Builder builder = new AlertDialog.Builder(MediaplayerActivity.this); - builder.setTitle(R.string.pref_rewind); - builder.setSingleChoiceItems(choices, checked, - (dialog, which) -> choice = values[which]); - builder.setNegativeButton(R.string.cancel_label, null); - builder.setPositiveButton(R.string.confirm_label, (dialog, which) -> { - UserPreferences.setPrefRewindSecs(choice); - if(txtvRev != null){ - txtvRev.setText(String.valueOf(choice)); - } - }); - builder.create().show(); - return true; - } + butRev.setOnLongClickListener(v -> { + showSkipPreference(MediaplayerActivity.this, SkipDirection.SKIP_REWIND); + return true; }); } @@ -742,37 +811,9 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements if (butFF != null) { butFF.setOnClickListener(v -> onFastForward()); - butFF.setOnLongClickListener(new View.OnLongClickListener() { - - int choice; - - @Override - public boolean onLongClick(View v) { - int checked = 0; - int rewindSecs = UserPreferences.getFastFowardSecs(); - final int[] values = getResources().getIntArray(R.array.seek_delta_values); - final String[] choices = new String[values.length]; - for (int i = 0; i < values.length; i++) { - if (rewindSecs == values[i]) { - checked = i; - } - choices[i] = String.valueOf(values[i]) + " " + getString(R.string.time_seconds); - } - choice = values[checked]; - AlertDialog.Builder builder = new AlertDialog.Builder(MediaplayerActivity.this); - builder.setTitle(R.string.pref_fast_forward); - builder.setSingleChoiceItems(choices, checked, - (dialog, which) -> choice = values[which]); - builder.setNegativeButton(R.string.cancel_label, null); - builder.setPositiveButton(R.string.confirm_label, (dialog, which) -> { - UserPreferences.setPrefFastForwardSecs(choice); - if(txtvFF != null) { - txtvFF.setText(String.valueOf(choice)); - } - }); - builder.create().show(); - return true; - } + butFF.setOnLongClickListener(v -> { + showSkipPreference(MediaplayerActivity.this, SkipDirection.SKIP_FORWARD); + return false; }); } @@ -801,7 +842,7 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements return; } int curr = controller.getPosition(); - controller.seekTo(curr + UserPreferences.getFastFowardSecs() * 1000); + controller.seekTo(curr + UserPreferences.getFastForwardSecs() * 1000); } protected abstract int getContentViewResourceId(); diff --git a/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceController.java b/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceController.java index 7f1d3075f..7777af450 100644 --- a/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceController.java +++ b/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceController.java @@ -54,6 +54,7 @@ import de.danoeh.antennapod.R; import de.danoeh.antennapod.activity.AboutActivity; import de.danoeh.antennapod.activity.DirectoryChooserActivity; import de.danoeh.antennapod.activity.MainActivity; +import de.danoeh.antennapod.activity.MediaplayerActivity; import de.danoeh.antennapod.activity.PreferenceActivity; import de.danoeh.antennapod.activity.PreferenceActivityGingerbread; import de.danoeh.antennapod.activity.StatisticsActivity; @@ -96,6 +97,8 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc private static final String PREF_CHOOSE_DATA_DIR = "prefChooseDataDir"; private static final String AUTO_DL_PREF_SCREEN = "prefAutoDownloadSettings"; private static final String PREF_PLAYBACK_SPEED_LAUNCHER = "prefPlaybackSpeedLauncher"; + public static final String PREF_PLAYBACK_REWIND_DELTA_LAUNCHER = "prefPlaybackRewindDeltaLauncher"; + public static final String PREF_PLAYBACK_FAST_FORWARD_DELTA_LAUNCHER = "prefPlaybackFastForwardDeltaLauncher"; private static final String PREF_GPODNET_LOGIN = "pref_gpodnet_authenticate"; private static final String PREF_GPODNET_SETLOGIN_INFORMATION = "pref_gpodnet_setlogin_information"; private static final String PREF_GPODNET_SYNC = "pref_gpodnet_sync"; @@ -333,6 +336,16 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc VariableSpeedDialog.showDialog(activity); return true; }); + ui.findPreference(PreferenceController.PREF_PLAYBACK_REWIND_DELTA_LAUNCHER) + .setOnPreferenceClickListener(preference -> { + MediaplayerActivity.showSkipPreference(activity, MediaplayerActivity.SkipDirection.SKIP_REWIND); + return true; + }); + ui.findPreference(PreferenceController.PREF_PLAYBACK_FAST_FORWARD_DELTA_LAUNCHER) + .setOnPreferenceClickListener(preference -> { + MediaplayerActivity.showSkipPreference(activity, MediaplayerActivity.SkipDirection.SKIP_FORWARD); + return true; + }); ui.findPreference(PreferenceController.PREF_GPODNET_SETLOGIN_INFORMATION) .setOnPreferenceClickListener(preference -> { AuthenticationDialog dialog = new AuthenticationDialog(activity, @@ -701,7 +714,7 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc val = String.format(context.getString(R.string.pref_autoUpdateIntervallOrTime_at), timeOfDayStr); } else { - val = context.getString(R.string.pref_smart_mark_as_played_disabled); + val = context.getString(R.string.pref_smart_mark_as_played_disabled); // TODO: Is this a bug? Otherwise document why is this related to smart mark??? } } String summary = context.getString(R.string.pref_autoUpdateIntervallOrTime_sum) + "\n" diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index 14a8ca0ef..0f1175ca3 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -109,6 +109,14 @@ android:key="prefHardwareForwardButtonSkips" android:summary="@string/pref_hardwareForwardButtonSkips_sum" android:title="@string/pref_hardwareForwardButtonSkips_title"/> + <Preference + android:key="prefPlaybackFastForwardDeltaLauncher" + android:summary="@string/pref_fast_forward_sum" + android:title="@string/pref_fast_forward" /> + <Preference + android:key="prefPlaybackRewindDeltaLauncher" + android:summary="@string/pref_rewind_sum" + android:title="@string/pref_rewind" /> <de.danoeh.antennapod.preferences.SwitchCompatPreference android:defaultValue="false" android:enabled="true" @@ -145,7 +153,6 @@ android:key="prefPlaybackSpeedLauncher" android:summary="@string/pref_playback_speed_sum" android:title="@string/pref_playback_speed_title" /> - <de.danoeh.antennapod.preferences.SwitchCompatPreference android:defaultValue="false" android:enabled="true" |