diff options
21 files changed, 368 insertions, 233 deletions
diff --git a/app/build.gradle b/app/build.gradle index a97bac1b2..e4ed38f52 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -172,7 +172,7 @@ dependencies { implementation "com.github.AntennaPod:AntennaPod-AudioPlayer:$audioPlayerVersion" implementation 'com.github.mfietz:fyydlin:v0.4.2' - implementation 'com.github.ByteHamster:SearchPreference:v1.2.6' + implementation 'com.github.ByteHamster:SearchPreference:v1.3.0' implementation "org.awaitility:awaitility:$awaitilityVersion" androidTestImplementation 'com.nanohttpd:nanohttpd-webserver:2.1.1' diff --git a/app/src/main/java/de/danoeh/antennapod/activity/AudioplayerActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/AudioplayerActivity.java index 2bcd7a461..9db860598 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/AudioplayerActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/AudioplayerActivity.java @@ -76,14 +76,7 @@ public class AudioplayerActivity extends MediaplayerInfoActivity { } float speed = 1.0f; if(controller.canSetPlaybackSpeed()) { - try { - // we can only retrieve the playback speed from the controller/playback service - // once mediaplayer has been initialized - speed = Float.parseFloat(UserPreferences.getPlaybackSpeed()); - } catch (NumberFormatException e) { - Log.e(TAG, Log.getStackTraceString(e)); - UserPreferences.setPlaybackSpeed(String.valueOf(speed)); - } + speed = UserPreferences.getPlaybackSpeed(); } String speedStr = new DecimalFormat("0.00x").format(speed); butPlaybackSpeed.setText(speedStr); @@ -105,7 +98,7 @@ public class AudioplayerActivity extends MediaplayerInfoActivity { } if (controller.canSetPlaybackSpeed()) { String[] availableSpeeds = UserPreferences.getPlaybackSpeedArray(); - String currentSpeed = UserPreferences.getPlaybackSpeed(); + String currentSpeed = new DecimalFormat("0.00x").format(UserPreferences.getPlaybackSpeed()); // Provide initial value in case the speed list has changed // out from under us 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 3946400a4..52497a27f 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java @@ -22,8 +22,6 @@ import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; -import android.widget.Button; -import android.widget.CheckBox; import android.widget.ImageButton; import android.widget.SeekBar; import android.widget.SeekBar.OnSeekBarChangeListener; @@ -35,8 +33,6 @@ import com.bumptech.glide.Glide; import com.joanzapata.iconify.IconDrawable; import com.joanzapata.iconify.fonts.FontAwesomeIcons; -import java.util.Locale; - import de.danoeh.antennapod.R; import de.danoeh.antennapod.core.feed.FeedItem; import de.danoeh.antennapod.core.feed.FeedMedia; @@ -44,7 +40,6 @@ import de.danoeh.antennapod.core.feed.MediaType; import de.danoeh.antennapod.core.preferences.UserPreferences; import de.danoeh.antennapod.core.service.playback.PlaybackService; import de.danoeh.antennapod.core.storage.DBReader; -import de.danoeh.antennapod.core.storage.DBTasks; import de.danoeh.antennapod.core.storage.DBWriter; import de.danoeh.antennapod.core.util.Consumer; import de.danoeh.antennapod.core.util.Converter; @@ -62,8 +57,8 @@ import de.danoeh.antennapod.core.util.playback.MediaPlayerError; import de.danoeh.antennapod.core.util.playback.Playable; import de.danoeh.antennapod.core.util.playback.PlaybackController; import de.danoeh.antennapod.core.util.playback.PlaybackServiceStarter; +import de.danoeh.antennapod.dialog.PlaybackControlsDialog; import de.danoeh.antennapod.dialog.SleepTimerDialog; -import de.danoeh.antennapod.dialog.VariableSpeedDialog; import io.reactivex.Observable; import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.disposables.Disposable; @@ -79,9 +74,6 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements private static final String PREFS = "MediaPlayerActivityPreferences"; private static final String PREF_SHOW_TIME_LEFT = "showTimeLeft"; private static final int REQUEST_CODE_STORAGE = 42; - private static final float PLAYBACK_SPEED_STEP = 0.05f; - private static final float DEFAULT_MIN_PLAYBACK_SPEED = 0.5f; - private static final float DEFAULT_MAX_PLAYBACK_SPEED = 2.5f; PlaybackController controller; @@ -365,7 +357,8 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements menu.findItem(R.id.audio_controls).setIcon(new IconDrawable(this, FontAwesomeIcons.fa_sliders).color(textColor).actionBarSize()); } else { - menu.findItem(R.id.audio_controls).setVisible(false); + menu.findItem(R.id.audio_controls).setIcon(new IconDrawable(this, + FontAwesomeIcons.fa_sliders).color(0xffffffff).actionBarSize()); } return true; @@ -451,148 +444,9 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements } break; case R.id.audio_controls: - MaterialDialog dialog = new MaterialDialog.Builder(this) - .title(R.string.audio_controls) - .customView(R.layout.audio_controls, true) - .neutralText(R.string.close_label) - .onNeutral((dialog1, which) -> { - final SeekBar left = (SeekBar) dialog1.findViewById(R.id.volume_left); - final SeekBar right = (SeekBar) dialog1.findViewById(R.id.volume_right); - UserPreferences.setVolume(left.getProgress(), right.getProgress()); - }) - .show(); - final SeekBar barPlaybackSpeed = (SeekBar) dialog.findViewById(R.id.playback_speed); - final Button butDecSpeed = (Button) dialog.findViewById(R.id.butDecSpeed); - butDecSpeed.setOnClickListener(v -> { - if(controller != null && controller.canSetPlaybackSpeed()) { - barPlaybackSpeed.setProgress(barPlaybackSpeed.getProgress() - 1); - } else { - VariableSpeedDialog.showGetPluginDialog(this); - } - }); - final Button butIncSpeed = (Button) dialog.findViewById(R.id.butIncSpeed); - butIncSpeed.setOnClickListener(v -> { - if(controller != null && controller.canSetPlaybackSpeed()) { - barPlaybackSpeed.setProgress(barPlaybackSpeed.getProgress() + 1); - } else { - VariableSpeedDialog.showGetPluginDialog(this); - } - }); - - final TextView txtvPlaybackSpeed = (TextView) dialog.findViewById(R.id.txtvPlaybackSpeed); - float currentSpeed = 1.0f; - try { - currentSpeed = Float.parseFloat(UserPreferences.getPlaybackSpeed()); - } catch (NumberFormatException e) { - Log.e(TAG, Log.getStackTraceString(e)); - UserPreferences.setPlaybackSpeed(String.valueOf(currentSpeed)); - } - - String[] availableSpeeds = UserPreferences.getPlaybackSpeedArray(); - final float minPlaybackSpeed = availableSpeeds.length > 1 ? - Float.valueOf(availableSpeeds[0]) : DEFAULT_MIN_PLAYBACK_SPEED; - float maxPlaybackSpeed = availableSpeeds.length > 1 ? - Float.valueOf(availableSpeeds[availableSpeeds.length - 1]) : DEFAULT_MAX_PLAYBACK_SPEED; - int progressMax = (int) ((maxPlaybackSpeed - minPlaybackSpeed) / PLAYBACK_SPEED_STEP); - barPlaybackSpeed.setMax(progressMax); - - txtvPlaybackSpeed.setText(String.format("%.2fx", currentSpeed)); - barPlaybackSpeed.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { - @Override - public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { - if(controller != null && controller.canSetPlaybackSpeed()) { - float playbackSpeed = progress * PLAYBACK_SPEED_STEP + minPlaybackSpeed; - controller.setPlaybackSpeed(playbackSpeed); - String speedPref = String.format(Locale.US, "%.2f", playbackSpeed); - UserPreferences.setPlaybackSpeed(speedPref); - String speedStr = String.format("%.2fx", playbackSpeed); - txtvPlaybackSpeed.setText(speedStr); - } else if(fromUser) { - float speed = Float.valueOf(UserPreferences.getPlaybackSpeed()); - barPlaybackSpeed.post(() -> barPlaybackSpeed.setProgress( - (int) ((speed - minPlaybackSpeed) / PLAYBACK_SPEED_STEP))); - } - } - - @Override - public void onStartTrackingTouch(SeekBar seekBar) { - if(controller != null && !controller.canSetPlaybackSpeed()) { - VariableSpeedDialog.showGetPluginDialog(MediaplayerActivity.this); - } - } - - @Override - public void onStopTrackingTouch(SeekBar seekBar) { - } - }); - barPlaybackSpeed.setProgress((int) ((currentSpeed - minPlaybackSpeed) / PLAYBACK_SPEED_STEP)); - - final SeekBar barLeftVolume = (SeekBar) dialog.findViewById(R.id.volume_left); - barLeftVolume.setProgress(UserPreferences.getLeftVolumePercentage()); - final SeekBar barRightVolume = (SeekBar) dialog.findViewById(R.id.volume_right); - barRightVolume.setProgress(UserPreferences.getRightVolumePercentage()); - final CheckBox stereoToMono = (CheckBox) dialog.findViewById(R.id.stereo_to_mono); - stereoToMono.setChecked(UserPreferences.stereoToMono()); - if (controller != null && !controller.canDownmix()) { - stereoToMono.setEnabled(false); - String sonicOnly = getString(R.string.sonic_only); - stereoToMono.setText(stereoToMono.getText() + " [" + sonicOnly + "]"); - } - - if (UserPreferences.useExoplayer()) { - barRightVolume.setEnabled(false); - } - - final CheckBox skipSilence = (CheckBox) dialog.findViewById(R.id.skipSilence); - skipSilence.setChecked(UserPreferences.isSkipSilence()); - if (!UserPreferences.useExoplayer()) { - skipSilence.setEnabled(false); - String exoplayerOnly = getString(R.string.exoplayer_only); - skipSilence.setText(skipSilence.getText() + " [" + exoplayerOnly + "]"); - } - skipSilence.setOnCheckedChangeListener((buttonView, isChecked) -> { - UserPreferences.setSkipSilence(isChecked); - controller.setSkipSilence(isChecked); - }); - - barLeftVolume.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { - @Override - public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { - controller.setVolume( - Converter.getVolumeFromPercentage(progress), - Converter.getVolumeFromPercentage(barRightVolume.getProgress())); - } - - @Override - public void onStartTrackingTouch(SeekBar seekBar) { - } - - @Override - public void onStopTrackingTouch(SeekBar seekBar) { - } - }); - barRightVolume.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { - @Override - public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { - controller.setVolume( - Converter.getVolumeFromPercentage(barLeftVolume.getProgress()), - Converter.getVolumeFromPercentage(progress)); - } - - @Override - public void onStartTrackingTouch(SeekBar seekBar) { - } - - @Override - public void onStopTrackingTouch(SeekBar seekBar) { - } - }); - stereoToMono.setOnCheckedChangeListener((buttonView, isChecked) -> { - UserPreferences.stereoToMono(isChecked); - if (controller != null) { - controller.setDownmix(isChecked); - } - }); + boolean isPlayingVideo = controller.getMedia().getMediaType() == MediaType.VIDEO; + PlaybackControlsDialog dialog = PlaybackControlsDialog.newInstance(isPlayingVideo); + dialog.show(getSupportFragmentManager(), "playback_controls"); break; case R.id.visit_website_item: Uri uri = Uri.parse(getWebsiteLinkWithFallback(media)); @@ -666,9 +520,10 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements return; } - int currentPosition = TimeSpeedConverter.convert(controller.getPosition()); - int duration = TimeSpeedConverter.convert(controller.getDuration()); - int remainingTime = TimeSpeedConverter.convert( + TimeSpeedConverter converter = new TimeSpeedConverter(controller.getCurrentPlaybackSpeedMultiplier()); + int currentPosition = converter.convert(controller.getPosition()); + int duration = converter.convert(controller.getDuration()); + int remainingTime = converter.convert( controller.getDuration() - controller.getPosition()); Log.d(TAG, "currentPosition " + Converter.getDurationStringLong(currentPosition)); if (currentPosition == PlaybackService.INVALID_TIME || @@ -824,14 +679,15 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements return; } + TimeSpeedConverter converter = new TimeSpeedConverter(controller.getCurrentPlaybackSpeedMultiplier()); String length; if (showTimeLeft) { - int remainingTime = TimeSpeedConverter.convert( + int remainingTime = converter.convert( media.getDuration() - media.getPosition()); length = "-" + Converter.getDurationStringLong(remainingTime); } else { - int duration = TimeSpeedConverter.convert(media.getDuration()); + int duration = converter.convert(media.getDuration()); length = Converter.getDurationStringLong(duration); } txtvLength.setText(length); @@ -935,7 +791,8 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements prog = controller.onSeekBarProgressChanged(seekBar, progress, fromUser, txtvPosition); if (showTimeLeft && prog != 0) { int duration = controller.getDuration(); - int timeLeft = TimeSpeedConverter.convert(duration - (int) (prog * duration)); + TimeSpeedConverter converter = new TimeSpeedConverter(controller.getCurrentPlaybackSpeedMultiplier()); + int timeLeft = converter.convert(duration - (int) (prog * duration)); String length = "-" + Converter.getDurationStringLong(timeLeft); txtvLength.setText(length); } diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/PlaybackControlsDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/PlaybackControlsDialog.java new file mode 100644 index 000000000..e8c7520b7 --- /dev/null +++ b/app/src/main/java/de/danoeh/antennapod/dialog/PlaybackControlsDialog.java @@ -0,0 +1,214 @@ +package de.danoeh.antennapod.dialog; + +import android.app.Dialog; +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.v4.app.DialogFragment; +import android.widget.Button; +import android.widget.CheckBox; +import android.widget.SeekBar; +import android.widget.TextView; +import com.afollestad.materialdialogs.MaterialDialog; +import de.danoeh.antennapod.R; +import de.danoeh.antennapod.core.preferences.UserPreferences; +import de.danoeh.antennapod.core.util.Converter; +import de.danoeh.antennapod.core.util.playback.PlaybackController; + +import java.util.Locale; + +public class PlaybackControlsDialog extends DialogFragment { + private static final float PLAYBACK_SPEED_STEP = 0.05f; + private static final float DEFAULT_MIN_PLAYBACK_SPEED = 0.5f; + private static final float DEFAULT_MAX_PLAYBACK_SPEED = 2.5f; + private static final String ARGUMENT_IS_PLAYING_VIDEO = "isPlayingVideo"; + + private PlaybackController controller; + private MaterialDialog dialog; + private boolean isPlayingVideo; + + public static PlaybackControlsDialog newInstance(boolean isPlayingVideo) { + Bundle arguments = new Bundle(); + arguments.putBoolean(ARGUMENT_IS_PLAYING_VIDEO, isPlayingVideo); + PlaybackControlsDialog dialog = new PlaybackControlsDialog(); + dialog.setArguments(arguments); + return dialog; + } + + public PlaybackControlsDialog() { + // Empty constructor required for DialogFragment + } + + @Override + public void onStart() { + super.onStart(); + controller = new PlaybackController(getActivity(), false); + controller.init(); + setupUi(); + } + + @Override + public void onStop() { + super.onStop(); + controller.release(); + controller = null; + } + + @NonNull + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + isPlayingVideo = getArguments() != null && getArguments().getBoolean(ARGUMENT_IS_PLAYING_VIDEO); + + dialog = new MaterialDialog.Builder(getContext()) + .title(R.string.audio_controls) + .customView(R.layout.audio_controls, true) + .neutralText(R.string.close_label) + .onNeutral((dialog1, which) -> { + final SeekBar left = (SeekBar) dialog1.findViewById(R.id.volume_left); + final SeekBar right = (SeekBar) dialog1.findViewById(R.id.volume_right); + UserPreferences.setVolume(left.getProgress(), right.getProgress()); + }).build(); + return dialog; + } + + private void setupUi() { + final SeekBar barPlaybackSpeed = (SeekBar) dialog.findViewById(R.id.playback_speed); + final Button butDecSpeed = (Button) dialog.findViewById(R.id.butDecSpeed); + butDecSpeed.setOnClickListener(v -> { + if (controller != null && controller.canSetPlaybackSpeed()) { + barPlaybackSpeed.setProgress(barPlaybackSpeed.getProgress() - 1); + } else { + VariableSpeedDialog.showGetPluginDialog(getContext()); + } + }); + final Button butIncSpeed = (Button) dialog.findViewById(R.id.butIncSpeed); + butIncSpeed.setOnClickListener(v -> { + if (controller != null && controller.canSetPlaybackSpeed()) { + barPlaybackSpeed.setProgress(barPlaybackSpeed.getProgress() + 1); + } else { + VariableSpeedDialog.showGetPluginDialog(getContext()); + } + }); + + final TextView txtvPlaybackSpeed = (TextView) dialog.findViewById(R.id.txtvPlaybackSpeed); + float currentSpeed = getCurrentSpeed(); + + String[] availableSpeeds = UserPreferences.getPlaybackSpeedArray(); + final float minPlaybackSpeed = availableSpeeds.length > 1 ? + Float.valueOf(availableSpeeds[0]) : DEFAULT_MIN_PLAYBACK_SPEED; + float maxPlaybackSpeed = availableSpeeds.length > 1 ? + Float.valueOf(availableSpeeds[availableSpeeds.length - 1]) : DEFAULT_MAX_PLAYBACK_SPEED; + int progressMax = (int) ((maxPlaybackSpeed - minPlaybackSpeed) / PLAYBACK_SPEED_STEP); + barPlaybackSpeed.setMax(progressMax); + + txtvPlaybackSpeed.setText(String.format("%.2fx", currentSpeed)); + barPlaybackSpeed.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { + @Override + public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { + if (controller != null && controller.canSetPlaybackSpeed()) { + float playbackSpeed = progress * PLAYBACK_SPEED_STEP + minPlaybackSpeed; + controller.setPlaybackSpeed(playbackSpeed); + String speedPref = String.format(Locale.US, "%.2f", playbackSpeed); + + if (isPlayingVideo) { + UserPreferences.setVideoPlaybackSpeed(speedPref); + } else { + UserPreferences.setPlaybackSpeed(speedPref); + } + + String speedStr = String.format("%.2fx", playbackSpeed); + txtvPlaybackSpeed.setText(speedStr); + } else if (fromUser) { + float speed = getCurrentSpeed(); + barPlaybackSpeed.post(() -> barPlaybackSpeed.setProgress( + (int) ((speed - minPlaybackSpeed) / PLAYBACK_SPEED_STEP))); + } + } + + @Override + public void onStartTrackingTouch(SeekBar seekBar) { + if (controller != null && !controller.canSetPlaybackSpeed()) { + VariableSpeedDialog.showGetPluginDialog(getContext()); + } + } + + @Override + public void onStopTrackingTouch(SeekBar seekBar) { + } + }); + barPlaybackSpeed.setProgress((int) ((currentSpeed - minPlaybackSpeed) / PLAYBACK_SPEED_STEP)); + + final SeekBar barLeftVolume = (SeekBar) dialog.findViewById(R.id.volume_left); + barLeftVolume.setProgress(UserPreferences.getLeftVolumePercentage()); + final SeekBar barRightVolume = (SeekBar) dialog.findViewById(R.id.volume_right); + barRightVolume.setProgress(UserPreferences.getRightVolumePercentage()); + final CheckBox stereoToMono = (CheckBox) dialog.findViewById(R.id.stereo_to_mono); + stereoToMono.setChecked(UserPreferences.stereoToMono()); + if (controller != null && !controller.canDownmix()) { + stereoToMono.setEnabled(false); + String sonicOnly = getString(R.string.sonic_only); + stereoToMono.setText(stereoToMono.getText() + " [" + sonicOnly + "]"); + } + + if (UserPreferences.useExoplayer()) { + barRightVolume.setEnabled(false); + } + + final CheckBox skipSilence = (CheckBox) dialog.findViewById(R.id.skipSilence); + skipSilence.setChecked(UserPreferences.isSkipSilence()); + if (!UserPreferences.useExoplayer()) { + skipSilence.setEnabled(false); + String exoplayerOnly = getString(R.string.exoplayer_only); + skipSilence.setText(skipSilence.getText() + " [" + exoplayerOnly + "]"); + } + skipSilence.setOnCheckedChangeListener((buttonView, isChecked) -> { + UserPreferences.setSkipSilence(isChecked); + controller.setSkipSilence(isChecked); + }); + + barLeftVolume.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { + @Override + public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { + controller.setVolume( + Converter.getVolumeFromPercentage(progress), + Converter.getVolumeFromPercentage(barRightVolume.getProgress())); + } + + @Override + public void onStartTrackingTouch(SeekBar seekBar) { + } + + @Override + public void onStopTrackingTouch(SeekBar seekBar) { + } + }); + barRightVolume.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { + @Override + public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { + controller.setVolume( + Converter.getVolumeFromPercentage(barLeftVolume.getProgress()), + Converter.getVolumeFromPercentage(progress)); + } + + @Override + public void onStartTrackingTouch(SeekBar seekBar) { + } + + @Override + public void onStopTrackingTouch(SeekBar seekBar) { + } + }); + stereoToMono.setOnCheckedChangeListener((buttonView, isChecked) -> { + UserPreferences.stereoToMono(isChecked); + if (controller != null) { + controller.setDownmix(isChecked); + } + }); + } + + private float getCurrentSpeed() { + if (isPlayingVideo) { + return UserPreferences.getVideoPlaybackSpeed(); + } + return UserPreferences.getPlaybackSpeed(); + } +} diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java index e22a70584..4f07e1b59 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java @@ -596,7 +596,7 @@ public class QueueFragment extends Fragment { String info = queue.size() + getString(R.string.episodes_suffix); if(queue.size() > 0) { long timeLeft = 0; - float playbackSpeed = Float.valueOf(UserPreferences.getPlaybackSpeed()); + float playbackSpeed = UserPreferences.getPlaybackSpeed(); for(FeedItem item : queue) { if(item.getMedia() != null) { timeLeft += diff --git a/app/src/main/res/layout/episodes_apply_action_fragment.xml b/app/src/main/res/layout/episodes_apply_action_fragment.xml index 984e960d8..d6e18bb37 100644 --- a/app/src/main/res/layout/episodes_apply_action_fragment.xml +++ b/app/src/main/res/layout/episodes_apply_action_fragment.xml @@ -39,7 +39,7 @@ android:id="@+id/fabSD" android:layout_width="match_parent" android:layout_height="wrap_content" - app:sdMainFabClosedSrc="@drawable/ic_fab_edit" + app:sdMainFabClosedSrc="?attr/batch_edit_fab_icon" app:sdOverlayLayout="@id/fabSDOverlay" android:layout_marginEnd="16dp" android:layout_marginRight="16dp" diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index f45847e54..6c1e470c0 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -1,9 +1,13 @@ <?xml version="1.0" encoding="utf-8"?> <PreferenceScreen - xmlns:android="http://schemas.android.com/apk/res/android"> + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:search="http://schemas.android.com/apk/res-auto"> <com.bytehamster.lib.preferencesearch.SearchPreference - android:key="searchPreference" /> + android:key="searchPreference" + search:textHint="@string/preference_search_hint" + search:textNoResults="@string/preference_search_no_results" + search:textClearHistory="@string/preference_search_clear_history" /> <Preference android:key="prefScreenInterface" diff --git a/core/src/main/java/de/danoeh/antennapod/core/preferences/UserPreferences.java b/core/src/main/java/de/danoeh/antennapod/core/preferences/UserPreferences.java index 4cc1a9c32..b8ab1c888 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/preferences/UserPreferences.java +++ b/core/src/main/java/de/danoeh/antennapod/core/preferences/UserPreferences.java @@ -109,6 +109,7 @@ public class UserPreferences { public static final String PREF_MEDIA_PLAYER = "prefMediaPlayer"; public static final String PREF_MEDIA_PLAYER_EXOPLAYER = "exoplayer"; private static final String PREF_PLAYBACK_SPEED = "prefPlaybackSpeed"; + private static final String PREF_VIDEO_PLAYBACK_SPEED = "prefVideoPlaybackSpeed"; public static final String PREF_PLAYBACK_SKIP_SILENCE = "prefSkipSilence"; private static final String PREF_FAST_FORWARD_SECS = "prefFastForwardSecs"; private static final String PREF_REWIND_SECS = "prefRewindSecs"; @@ -319,8 +320,24 @@ public class UserPreferences { return prefs.getBoolean(PREF_DELETE_REMOVES_FROM_QUEUE, false); } - public static String getPlaybackSpeed() { - return prefs.getString(PREF_PLAYBACK_SPEED, "1.00"); + public static float getPlaybackSpeed() { + try { + return Float.parseFloat(prefs.getString(PREF_PLAYBACK_SPEED, "1.00")); + } catch (NumberFormatException e) { + Log.e(TAG, Log.getStackTraceString(e)); + UserPreferences.setPlaybackSpeed("1.00"); + return 1.0f; + } + } + + public static float getVideoPlaybackSpeed() { + try { + return Float.parseFloat(prefs.getString(PREF_VIDEO_PLAYBACK_SPEED, "1.00")); + } catch (NumberFormatException e) { + Log.e(TAG, Log.getStackTraceString(e)); + UserPreferences.setVideoPlaybackSpeed("1.00"); + return 1.0f; + } } public static boolean isSkipSilence() { @@ -559,6 +576,12 @@ public class UserPreferences { .apply(); } + public static void setVideoPlaybackSpeed(String speed) { + prefs.edit() + .putString(PREF_VIDEO_PLAYBACK_SPEED, speed) + .apply(); + } + public static void setSkipSilence(boolean skipSilence) { prefs.edit() .putBoolean(PREF_PLAYBACK_SKIP_SILENCE, skipSilence) diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/PlayerWidgetJobService.java b/core/src/main/java/de/danoeh/antennapod/core/service/PlayerWidgetJobService.java index b26d3011d..7938e262d 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/PlayerWidgetJobService.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/PlayerWidgetJobService.java @@ -213,8 +213,9 @@ public class PlayerWidgetJobService extends SafeJobIntentService { private String getProgressString(int position, int duration) { if (position > 0 && duration > 0) { - position = TimeSpeedConverter.convert(position); - duration = TimeSpeedConverter.convert(duration); + TimeSpeedConverter converter = new TimeSpeedConverter(playbackService.getCurrentPlaybackSpeed()); + position = converter.convert(position); + duration = converter.convert(duration); return Converter.getDurationStringLong(position) + " / " + Converter.getDurationStringLong(duration); } else { diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/playback/LocalPSMP.java b/core/src/main/java/de/danoeh/antennapod/core/service/playback/LocalPSMP.java index 9a8353806..6bd736de7 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/playback/LocalPSMP.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/playback/LocalPSMP.java @@ -303,14 +303,11 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer { Log.d(TAG, "Audiofocus successfully requested"); Log.d(TAG, "Resuming/Starting playback"); acquireWifiLockIfNecessary(); - float speed = 1.0f; - try { - speed = Float.parseFloat(UserPreferences.getPlaybackSpeed()); - } catch(NumberFormatException e) { - Log.e(TAG, Log.getStackTraceString(e)); - UserPreferences.setPlaybackSpeed(String.valueOf(speed)); + if (media.getMediaType() == MediaType.VIDEO) { + setPlaybackParams(UserPreferences.getVideoPlaybackSpeed(), UserPreferences.isSkipSilence()); + } else { + setPlaybackParams(UserPreferences.getPlaybackSpeed(), UserPreferences.isSkipSilence()); } - setPlaybackParams(speed, UserPreferences.isSkipSilence()); setVolume(UserPreferences.getLeftVolume(), UserPreferences.getRightVolume()); if (playerStatus == PlayerStatus.PREPARED && media.getPosition() > 0) { @@ -601,11 +598,7 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer { */ @Override public boolean canSetSpeed() { - boolean retVal = false; - if (mediaPlayer != null && media != null && media.getMediaType() == MediaType.AUDIO) { - retVal = (mediaPlayer).canSetSpeed(); - } - return retVal; + return mediaPlayer != null && mediaPlayer.canSetSpeed(); } /** @@ -614,13 +607,11 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer { */ private void setSpeedSyncAndSkipSilence(float speed, boolean skipSilence) { playerLock.lock(); - if (media != null && media.getMediaType() == MediaType.AUDIO) { - if (mediaPlayer.canSetSpeed()) { - Log.d(TAG, "Playback speed was set to " + speed); - callback.playbackSpeedChanged(speed); - } - mediaPlayer.setPlaybackParams(speed, skipSilence); + if (mediaPlayer.canSetSpeed()) { + Log.d(TAG, "Playback speed was set to " + speed); + callback.playbackSpeedChanged(speed); } + mediaPlayer.setPlaybackParams(speed, skipSilence); playerLock.unlock(); } @@ -667,10 +658,8 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer { */ private void setVolumeSync(float volumeLeft, float volumeRight) { playerLock.lock(); - if (media != null && media.getMediaType() == MediaType.AUDIO) { - mediaPlayer.setVolume(volumeLeft, volumeRight); - Log.d(TAG, "Media player volume was set to " + volumeLeft + " " + volumeRight); - } + mediaPlayer.setVolume(volumeLeft, volumeRight); + Log.d(TAG, "Media player volume was set to " + volumeLeft + " " + volumeRight); playerLock.unlock(); } diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java index 8089bcbb6..f7a13d81e 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java @@ -98,6 +98,7 @@ public class PlaybackService extends MediaBrowserServiceCompat { */ public static final String EXTRA_SHOULD_STREAM = "extra.de.danoeh.antennapod.core.service.shouldStream"; public static final String EXTRA_ALLOW_STREAM_THIS_TIME = "extra.de.danoeh.antennapod.core.service.allowStream"; + public static final String EXTRA_ALLOW_STREAM_ALWAYS = "extra.de.danoeh.antennapod.core.service.allowStreamAlways"; /** * True if playback should be started immediately after media has been * prepared. @@ -326,7 +327,7 @@ public class PlaybackService extends MediaBrowserServiceCompat { public void onDestroy() { super.onDestroy(); Log.d(TAG, "Service is about to be destroyed"); - stateManager.stopForeground(true); + stateManager.stopForeground(!UserPreferences.isPersistNotify()); isRunning = false; currentMediaType = MediaType.UNKNOWN; @@ -444,9 +445,18 @@ public class PlaybackService extends MediaBrowserServiceCompat { if (!stateManager.isInForeground()) { PlaybackServiceNotificationBuilder notificationBuilder = new PlaybackServiceNotificationBuilder(this); + if (mediaPlayer != null && getPlayable() != null) { + notificationBuilder.addMetadata(getPlayable(), mediaSession.getSessionToken(), getStatus(), isCasting); + if (notificationBuilder.isIconCached(getPlayable())) { + notificationBuilder.loadIcon(getPlayable()); + } + } startForeground(NOTIFICATION_ID, notificationBuilder.build()); } + NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this); + notificationManager.cancel(NOTIFICATION_ID_STREAMING); + final int keycode = intent.getIntExtra(MediaButtonReceiver.EXTRA_KEYCODE, -1); final boolean castDisconnect = intent.getBooleanExtra(EXTRA_CAST_DISCONNECT, false); Playable playable = intent.getParcelableExtra(EXTRA_PLAYABLE); @@ -471,6 +481,7 @@ public class PlaybackService extends MediaBrowserServiceCompat { stateManager.validStartCommandWasReceived(); boolean stream = intent.getBooleanExtra(EXTRA_SHOULD_STREAM, true); boolean allowStreamThisTime = intent.getBooleanExtra(EXTRA_ALLOW_STREAM_THIS_TIME, false); + boolean allowStreamAlways = intent.getBooleanExtra(EXTRA_ALLOW_STREAM_ALWAYS, false); boolean startWhenPrepared = intent.getBooleanExtra(EXTRA_START_WHEN_PREPARED, false); boolean prepareImmediately = intent.getBooleanExtra(EXTRA_PREPARE_IMMEDIATELY, false); sendNotificationBroadcast(NOTIFICATION_TYPE_RELOAD, 0); @@ -479,6 +490,9 @@ public class PlaybackService extends MediaBrowserServiceCompat { if (playable instanceof FeedMedia) { playable = DBReader.getFeedMedia(((FeedMedia) playable).getId()); } + if (allowStreamAlways) { + UserPreferences.setAllowMobileStreaming(true); + } if (stream && !NetworkUtils.isStreamingAllowed() && !allowStreamThisTime) { displayStreamingNotAllowedNotification(intent); writePlaybackPreferencesNoMediaPlaying(); @@ -496,23 +510,38 @@ public class PlaybackService extends MediaBrowserServiceCompat { } private void displayStreamingNotAllowedNotification(Intent originalIntent) { - Intent intent = new Intent(originalIntent); - intent.putExtra(EXTRA_ALLOW_STREAM_THIS_TIME, true); - PendingIntent pendingIntent; + Intent intentAllowThisTime = new Intent(originalIntent); + intentAllowThisTime.putExtra(EXTRA_ALLOW_STREAM_THIS_TIME, true); + PendingIntent pendingIntentAllowThisTime; if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { - pendingIntent = PendingIntent.getForegroundService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); + pendingIntentAllowThisTime = PendingIntent.getForegroundService(this, 0, intentAllowThisTime, PendingIntent.FLAG_UPDATE_CURRENT); } else { - pendingIntent = PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); + pendingIntentAllowThisTime = PendingIntent.getService(this, 0, intentAllowThisTime, PendingIntent.FLAG_UPDATE_CURRENT); + } + + Intent intentAlwaysAllow = new Intent(intentAllowThisTime); + intentAlwaysAllow.putExtra(EXTRA_ALLOW_STREAM_ALWAYS, true); + PendingIntent pendingIntentAlwaysAllow; + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { + pendingIntentAlwaysAllow = PendingIntent.getForegroundService(this, 0, intentAlwaysAllow, PendingIntent.FLAG_UPDATE_CURRENT); + } else { + pendingIntentAlwaysAllow = PendingIntent.getService(this, 0, intentAlwaysAllow, PendingIntent.FLAG_UPDATE_CURRENT); } NotificationCompat.Builder builder = new NotificationCompat.Builder(this, NotificationUtils.CHANNEL_ID_USER_ACTION) - .setSmallIcon(R.drawable.stat_notify_sync_error) + .setSmallIcon(R.drawable.ic_stream_white) .setContentTitle(getString(R.string.confirm_mobile_streaming_notification_title)) .setContentText(getString(R.string.confirm_mobile_streaming_notification_message)) .setStyle(new NotificationCompat.BigTextStyle() .bigText(getString(R.string.confirm_mobile_streaming_notification_message))) .setPriority(NotificationCompat.PRIORITY_DEFAULT) - .setContentIntent(pendingIntent) + .setContentIntent(pendingIntentAllowThisTime) + .addAction(R.drawable.ic_stream_white, + getString(R.string.stream_label), + pendingIntentAllowThisTime) + .addAction(R.drawable.ic_stream_white, + getString(R.string.confirm_mobile_streaming_button_always), + pendingIntentAlwaysAllow) .setAutoCancel(true); NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this); notificationManager.notify(NOTIFICATION_ID_STREAMING, builder.build()); @@ -733,7 +762,7 @@ public class PlaybackService extends MediaBrowserServiceCompat { @Override public void shouldStop() { - stateManager.stopService(); + setupNotification(getPlayable()); // Stops foreground if not playing } @Override diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceStateManager.java b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceStateManager.java index b8541748e..18c8fa51f 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceStateManager.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceStateManager.java @@ -1,6 +1,8 @@ package de.danoeh.antennapod.core.service.playback; import android.app.Notification; +import android.app.Service; +import android.os.Build; class PlaybackServiceStateManager { private final PlaybackService playbackService; @@ -19,12 +21,19 @@ class PlaybackServiceStateManager { void stopService() { stopForeground(true); - isInForeground = false; playbackService.stopSelf(); } void stopForeground(boolean removeNotification) { - playbackService.stopForeground(removeNotification); + if (isInForeground) { + if (Build.VERSION.SDK_INT < 24) { + playbackService.stopForeground(removeNotification); + } else if (removeNotification) { + playbackService.stopForeground(Service.STOP_FOREGROUND_REMOVE); + } else { + playbackService.stopForeground(Service.STOP_FOREGROUND_DETACH); + } + } isInForeground = false; hasReceivedValidStartCommand = false; } diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/TimeSpeedConverter.java b/core/src/main/java/de/danoeh/antennapod/core/util/TimeSpeedConverter.java index 5fea8238b..5d44c14b8 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/TimeSpeedConverter.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/TimeSpeedConverter.java @@ -3,18 +3,19 @@ package de.danoeh.antennapod.core.util; import de.danoeh.antennapod.core.preferences.UserPreferences; public class TimeSpeedConverter { - private TimeSpeedConverter() { + private final float speed; + public TimeSpeedConverter(float speed) { + this.speed = speed; } /** Convert millisecond according to the current playback speed * @param time: time to convert * @return converted time (can be < 0 if time is < 0) */ - public static int convert(int time) { + public int convert(int time) { boolean timeRespectsSpeed = UserPreferences.timeRespectsSpeed(); if (time > 0 && timeRespectsSpeed) { - float speed = Float.parseFloat(UserPreferences.getPlaybackSpeed()); return (int)(time / speed); } return time; diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/playback/MediaPlayerError.java b/core/src/main/java/de/danoeh/antennapod/core/util/playback/MediaPlayerError.java index b04c02075..32d37a67e 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/playback/MediaPlayerError.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/playback/MediaPlayerError.java @@ -16,10 +16,16 @@ public class MediaPlayerError { case MediaPlayer.MEDIA_ERROR_SERVER_DIED: resId = R.string.playback_error_server_died; break; + case MediaPlayer.MEDIA_ERROR_UNSUPPORTED: + resId = R.string.playback_error_unsupported; + break; + case MediaPlayer.MEDIA_ERROR_TIMED_OUT: + resId = R.string.playback_error_timeout; + break; default: resId = R.string.playback_error_unknown; break; } - return context.getString(resId); + return context.getString(resId) + " (" + code + ")"; } } diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java b/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java index 5b2d7b13e..0cfaaab3c 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java @@ -54,7 +54,7 @@ import org.greenrobot.eventbus.ThreadMode; * Communicates with the playback service. GUI classes should use this class to * control playback instead of communicating with the PlaybackService directly. */ -public abstract class PlaybackController { +public class PlaybackController { private static final String TAG = "PlaybackController"; @@ -567,7 +567,8 @@ public abstract class PlaybackController { if (fromUser && playbackService != null && media != null) { float prog = progress / ((float) seekBar.getMax()); int duration = media.getDuration(); - int position = TimeSpeedConverter.convert((int) (prog * duration)); + TimeSpeedConverter converter = new TimeSpeedConverter(playbackService.getCurrentPlaybackSpeed()); + int position = converter.convert((int) (prog * duration)); txtvPosition.setText(Converter.getDurationStringLong(position)); return prog; } @@ -719,6 +720,7 @@ public abstract class PlaybackController { public boolean canSetPlaybackSpeed() { return org.antennapod.audio.MediaPlayer.isPrestoLibraryInstalled(activity.getApplicationContext()) || UserPreferences.useSonic() + || UserPreferences.useExoplayer() || Build.VERSION.SDK_INT >= 23 || (playbackService != null && playbackService.canSetSpeed()); } @@ -741,7 +743,7 @@ public abstract class PlaybackController { } public float getCurrentPlaybackSpeedMultiplier() { - if (canSetPlaybackSpeed()) { + if (playbackService != null && canSetPlaybackSpeed()) { return playbackService.getCurrentPlaybackSpeed(); } else { return -1; diff --git a/core/src/main/res/drawable/ic_fab_edit_black.xml b/core/src/main/res/drawable/ic_fab_edit_black.xml new file mode 100644 index 000000000..a9fec7080 --- /dev/null +++ b/core/src/main/res/drawable/ic_fab_edit_black.xml @@ -0,0 +1,5 @@ +<vector android:height="24dp" + android:viewportHeight="24.0" android:viewportWidth="24.0" + android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="#FF000000" android:pathData="M3,17.25V21h3.75L17.81,9.94l-3.75,-3.75L3,17.25zM20.71,7.04c0.39,-0.39 0.39,-1.02 0,-1.41l-2.34,-2.34c-0.39,-0.39 -1.02,-0.39 -1.41,0l-1.83,1.83 3.75,3.75 1.83,-1.83z"/> +</vector> diff --git a/core/src/main/res/drawable/ic_fab_edit.xml b/core/src/main/res/drawable/ic_fab_edit_white.xml index cb2e394b0..cb2e394b0 100644 --- a/core/src/main/res/drawable/ic_fab_edit.xml +++ b/core/src/main/res/drawable/ic_fab_edit_white.xml diff --git a/core/src/main/res/drawable/ic_stream_white.xml b/core/src/main/res/drawable/ic_stream_white.xml new file mode 100644 index 000000000..3c59bbad7 --- /dev/null +++ b/core/src/main/res/drawable/ic_stream_white.xml @@ -0,0 +1,5 @@ +<vector android:height="24dp" + android:viewportHeight="24.0" android:viewportWidth="24.0" + android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="#FFFFFFFF" android:pathData="M12,5c-3.87,0 -7,3.13 -7,7h2c0,-2.76 2.24,-5 5,-5s5,2.24 5,5h2c0,-3.87 -3.13,-7 -7,-7zM13,14.29c0.88,-0.39 1.5,-1.26 1.5,-2.29 0,-1.38 -1.12,-2.5 -2.5,-2.5S9.5,10.62 9.5,12c0,1.02 0.62,1.9 1.5,2.29v3.3L7.59,21 9,22.41l3,-3 3,3L16.41,21 13,17.59v-3.3zM12,1C5.93,1 1,5.93 1,12h2c0,-4.97 4.03,-9 9,-9s9,4.03 9,9h2c0,-6.07 -4.93,-11 -11,-11z"/> +</vector> diff --git a/core/src/main/res/values/attrs.xml b/core/src/main/res/values/attrs.xml index eb7f065ce..5b0bf5717 100644 --- a/core/src/main/res/values/attrs.xml +++ b/core/src/main/res/values/attrs.xml @@ -74,4 +74,5 @@ <attr name="about_screen_card_background" format="color"/> <attr name="about_screen_card_border" format="color"/> <attr name="about_screen_font_color" format="color"/> + <attr name="batch_edit_fab_icon" format="reference"/> </resources> diff --git a/core/src/main/res/values/strings.xml b/core/src/main/res/values/strings.xml index a4084b76b..c9c6506a9 100644 --- a/core/src/main/res/values/strings.xml +++ b/core/src/main/res/values/strings.xml @@ -267,6 +267,7 @@ <string name="confirm_mobile_download_dialog_message">Downloading over mobile data connection is disabled in the settings.\n\nDo you want to allow downloading temporarily?\n\n<small>Your choice will be remembered for 10 minutes.</small></string> <string name="confirm_mobile_streaming_notification_title">Confirm Mobile streaming</string> <string name="confirm_mobile_streaming_notification_message">Streaming over mobile data connection is disabled in the settings. Tap to stream anyway.</string> + <string name="confirm_mobile_streaming_button_always">Always allow</string> <string name="confirm_mobile_download_dialog_only_add_to_queue">Enqueue</string> <string name="confirm_mobile_download_dialog_enable_temporarily">Allow temporarily</string> @@ -277,6 +278,8 @@ <string name="player_ready_msg">Ready</string> <string name="player_seeking_msg">Seeking</string> <string name="playback_error_server_died">Server died</string> + <string name="playback_error_unsupported">Unsupported media type</string> + <string name="playback_error_timeout">Operation timed out</string> <string name="playback_error_unknown">Unknown Error</string> <string name="no_media_playing_label">No media playing</string> <string name="position_default_label" translate="false">00:00:00</string> @@ -353,6 +356,9 @@ <string name="external_elements">External elements</string> <string name="interruptions">Interruptions</string> <string name="playback_control">Playback control</string> + <string name="preference_search_hint">Search…</string> + <string name="preference_search_no_results">No results</string> + <string name="preference_search_clear_history">Clear history</string> <string name="media_player">Media player</string> <string name="pref_episode_cleanup_title">Episode Cleanup</string> <string name="pref_episode_cleanup_summary">Episodes that aren\'t in the queue and aren\'t favorites should be eligible for removal if Auto Download needs space for new episodes</string> diff --git a/core/src/main/res/values/styles.xml b/core/src/main/res/values/styles.xml index 4c69306a9..fb69e54e7 100644 --- a/core/src/main/res/values/styles.xml +++ b/core/src/main/res/values/styles.xml @@ -72,6 +72,7 @@ <item name="ic_bug">@drawable/ic_bug_grey600_24dp</item> <item name="ic_known_issues">@drawable/ic_format_list_bulleted_grey600_24dp</item> <item name="ic_bookmark">@drawable/ic_bookmark_grey600_24dp</item> + <item name="batch_edit_fab_icon">@drawable/ic_fab_edit_white</item> <item name="master_switch_background">@color/master_switch_background_light</item> <item name="currently_playing_background">@color/highlight_light</item> @@ -156,6 +157,7 @@ <item name="ic_bug">@drawable/ic_bug_white_24dp</item> <item name="ic_known_issues">@drawable/ic_format_list_bulleted_white_24dp</item> <item name="ic_bookmark">@drawable/ic_bookmark_white_24dp</item> + <item name="batch_edit_fab_icon">@drawable/ic_fab_edit_white</item> <item name="master_switch_background">@color/master_switch_background_dark</item> <item name="currently_playing_background">@color/highlight_dark</item> <item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item> @@ -176,6 +178,7 @@ <item name="overlay_background">@color/black</item> <item name="overlay_drawable">@drawable/overlay_drawable_dark_trueblack</item> <item name="dragview_background">@drawable/ic_drag_vertical_white_48dp</item> + <item name="batch_edit_fab_icon">@drawable/ic_fab_edit_black</item> <item name="dragview_float_background">@color/black</item> <item name="nav_drawer_background">@color/black</item> <item name="drawer_activated_color">@color/highlight_trueblack</item> @@ -213,23 +216,10 @@ <!-- Room for API dependent attributes --> </style> - <style name="Theme.Base.AntennaPod.TrueBlack.NoTitle" parent="Theme.Base.AntennaPod.Dark.NoTitle"> - <item name="progressBarTheme">@style/ProgressBarTrueBlack</item> - <item name="non_transparent_background">@color/black</item> - <item name="overlay_background">@color/black</item> - <item name="overlay_drawable">@drawable/overlay_drawable_dark_trueblack</item> - <item name="dragview_background">@drawable/ic_drag_vertical_white_48dp</item> - <item name="dragview_float_background">@color/black</item> - <item name="nav_drawer_background">@color/black</item> - <item name="drawer_activated_color">@color/highlight_trueblack</item> - <item name="currently_playing_background">@color/highlight_trueblack</item> - <item name="android:textColorPrimary">@color/white</item> - <item name="android:color">@color/white</item> - <item name="android:colorBackground">@color/black</item> - <item name="android:windowBackground">@color/black</item> - <item name="android:actionBarStyle">@color/black</item> - <item name="colorPrimary">@color/black</item> - <item name="colorPrimaryDark">@color/black</item> + <style name="Theme.Base.AntennaPod.TrueBlack.NoTitle" parent="Theme.Base.AntennaPod.TrueBlack"> + <item name="windowActionBar">false</item> + <item name="windowNoTitle">true</item> + <item name="windowActionModeOverlay">true</item> </style> |