diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index c84b0110b..03ba97e08 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -33,11 +33,12 @@ + android:logo="@mipmap/ic_launcher"> instance; private PreferenceController preferenceController; - private MainFragment prefFragment; private final PreferenceController.PreferenceUI preferenceUI = new PreferenceController.PreferenceUI() { + private PreferenceFragment fragment; + + @Override + public void setFragment(PreferenceFragment fragment) { + this.fragment = fragment; + } + @Override public Preference findPreference(CharSequence key) { - return prefFragment.findPreference(key); + return fragment.findPreference(key); + } + + @Override + public PreferenceScreen getPreferenceScreen() { + return fragment.getPreferenceScreen(); } @Override @@ -64,7 +77,11 @@ public class PreferenceActivity extends AppCompatActivity { // since the MainFragment depends on the preferenceController already being created preferenceController = new PreferenceController(preferenceUI); - prefFragment = new MainFragment(); + PreferenceFragment prefFragment = new MainFragment(); + preferenceUI.setFragment(prefFragment); + Bundle args = new Bundle(); + args.putInt(PARAM_RESOURCE, R.xml.preferences); + prefFragment.setArguments(args); getFragmentManager().beginTransaction().replace(R.id.content, prefFragment).commit(); } @@ -84,7 +101,11 @@ public class PreferenceActivity extends AppCompatActivity { public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case android.R.id.home: - finish(); + if (getFragmentManager().getBackStackEntryCount() == 0) { + finish(); + } else { + getFragmentManager().popBackStack(); + } return true; default: return false; @@ -97,10 +118,11 @@ public class PreferenceActivity extends AppCompatActivity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setRetainInstance(true); - addPreferencesFromResource(R.xml.preferences); + addPreferencesFromResource(getArguments().getInt(PARAM_RESOURCE)); PreferenceActivity activity = instance.get(); - if(activity != null && activity.preferenceController != null) { - activity.preferenceController.onCreate(); + if (activity != null && activity.preferenceController != null) { + activity.preferenceUI.setFragment(this); + activity.preferenceController.onCreate(getArguments().getInt(PARAM_RESOURCE)); } } @@ -109,7 +131,28 @@ public class PreferenceActivity extends AppCompatActivity { super.onResume(); PreferenceActivity activity = instance.get(); if(activity != null && activity.preferenceController != null) { - activity.preferenceController.onResume(); + activity.setTitle(getTitle(getArguments().getInt(PARAM_RESOURCE))); + activity.preferenceUI.setFragment(this); + activity.preferenceController.onResume(getArguments().getInt(PARAM_RESOURCE)); + } + } + + private int getTitle(int preferences) { + switch (preferences) { + case R.xml.preferences_network: + return R.string.network_pref; + case R.xml.preferences_autodownload: + return R.string.pref_automatic_download_title; + case R.xml.preferences_playback: + return R.string.playback_pref; + case R.xml.preferences_storage: + return R.string.storage_pref; + case R.xml.preferences_user_interface: + return R.string.user_interface_label; + case R.xml.preferences_integrations: + return R.string.integrations_label; + default: + return R.string.settings_label; } } @@ -117,7 +160,8 @@ public class PreferenceActivity extends AppCompatActivity { public void onPause() { PreferenceActivity activity = instance.get(); if(activity != null && activity.preferenceController != null) { - activity.preferenceController.onPause(); + activity.preferenceUI.setFragment(this); + activity.preferenceController.onPause(getArguments().getInt(PARAM_RESOURCE)); } super.onPause(); } @@ -126,6 +170,7 @@ public class PreferenceActivity extends AppCompatActivity { public void onStop() { PreferenceActivity activity = instance.get(); if(activity != null && activity.preferenceController != null) { + activity.preferenceUI.setFragment(this); activity.preferenceController.onStop(); } super.onStop(); diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/ExternalPlayerFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/ExternalPlayerFragment.java index 4ef26ad6c..2705e7402 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/ExternalPlayerFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/ExternalPlayerFragment.java @@ -124,8 +124,7 @@ public class ExternalPlayerFragment extends Fragment { public void onResume() { super.onResume(); controller.init(); - mProgressBar.setProgress((int) - ((double) controller.getPosition() / controller.getDuration() * 100)); + onPositionObserverUpdate(); } @Override diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java index c834b7ea7..1247aacbb 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java @@ -152,18 +152,39 @@ public class SubscriptionFragment extends Fragment { Feed feed = (Feed)selectedObject; switch(item.getItemId()) { case R.id.mark_all_seen_item: - Observable.fromCallable(() -> DBWriter.markFeedSeen(feed.getId())) - .subscribeOn(Schedulers.newThread()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(result -> loadSubscriptions(), - error -> Log.e(TAG, Log.getStackTraceString(error))); + ConfirmationDialog markAllSeenConfirmationDialog = new ConfirmationDialog(getActivity(), + R.string.mark_all_seen_label, + R.string.mark_all_seen_confirmation_msg) { + + @Override + public void onConfirmButtonPressed(DialogInterface dialog) { + dialog.dismiss(); + + Observable.fromCallable(() -> DBWriter.markFeedSeen(feed.getId())) + .subscribeOn(Schedulers.newThread()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(result -> loadSubscriptions(), + error -> Log.e(TAG, Log.getStackTraceString(error))); + } + }; + markAllSeenConfirmationDialog.createNewDialog().show(); return true; case R.id.mark_all_read_item: - Observable.fromCallable(() -> DBWriter.markFeedRead(feed.getId())) - .subscribeOn(Schedulers.newThread()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(result -> loadSubscriptions(), - error -> Log.e(TAG, Log.getStackTraceString(error))); + ConfirmationDialog markAllReadConfirmationDialog = new ConfirmationDialog(getActivity(), + R.string.mark_all_read_label, + R.string.mark_all_read_confirmation_msg) { + + @Override + public void onConfirmButtonPressed(DialogInterface dialog) { + dialog.dismiss(); + Observable.fromCallable(() -> DBWriter.markFeedRead(feed.getId())) + .subscribeOn(Schedulers.newThread()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(result -> loadSubscriptions(), + error -> Log.e(TAG, Log.getStackTraceString(error))); + } + }; + markAllReadConfirmationDialog.createNewDialog().show(); return true; case R.id.rename_item: new RenameFeedDialog(getActivity(), feed).show(); diff --git a/app/src/main/java/de/danoeh/antennapod/preferences/MasterSwitchPreference.java b/app/src/main/java/de/danoeh/antennapod/preferences/MasterSwitchPreference.java new file mode 100644 index 000000000..bcac65804 --- /dev/null +++ b/app/src/main/java/de/danoeh/antennapod/preferences/MasterSwitchPreference.java @@ -0,0 +1,45 @@ +package de.danoeh.antennapod.preferences; + +import android.annotation.TargetApi; +import android.content.Context; +import android.graphics.Typeface; +import android.os.Build; +import android.util.AttributeSet; +import android.util.TypedValue; +import android.view.View; +import android.widget.TextView; +import de.danoeh.antennapod.R; + +public class MasterSwitchPreference extends SwitchCompatPreference { + + public MasterSwitchPreference(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + @TargetApi(Build.VERSION_CODES.LOLLIPOP) + public MasterSwitchPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + } + + public MasterSwitchPreference(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public MasterSwitchPreference(Context context) { + super(context); + } + + @Override + protected void onBindView(View view) { + super.onBindView(view); + + TypedValue typedValue = new TypedValue(); + getContext().getTheme().resolveAttribute(R.attr.master_switch_background, typedValue, true); + view.setBackgroundColor(typedValue.data); + + TextView title = (TextView) view.findViewById(android.R.id.title); + if (title != null) { + title.setTypeface(title.getTypeface(), Typeface.BOLD); + } + } +} \ No newline at end of file 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 042602f66..957f3f9c8 100644 --- a/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceController.java +++ b/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceController.java @@ -3,6 +3,7 @@ package de.danoeh.antennapod.preferences; import android.Manifest; import android.annotation.SuppressLint; import android.app.Activity; +import android.app.Fragment; import android.app.ProgressDialog; import android.app.TimePickerDialog; import android.content.ActivityNotFoundException; @@ -16,10 +17,12 @@ import android.net.Uri; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiManager; import android.os.Build; +import android.os.Bundle; import android.preference.CheckBoxPreference; import android.preference.EditTextPreference; import android.preference.ListPreference; import android.preference.Preference; +import android.preference.PreferenceFragment; import android.preference.PreferenceManager; import android.preference.PreferenceScreen; import android.support.design.widget.Snackbar; @@ -38,9 +41,21 @@ import android.widget.Toast; import com.afollestad.materialdialogs.MaterialDialog; +import de.danoeh.antennapod.activity.AboutActivity; import com.afollestad.materialdialogs.prefs.MaterialListPreference; import de.danoeh.antennapod.activity.ImportExportActivity; +import de.danoeh.antennapod.activity.MediaplayerActivity; import de.danoeh.antennapod.activity.OpmlImportFromPathActivity; +import de.danoeh.antennapod.activity.PreferenceActivity; +import de.danoeh.antennapod.activity.StatisticsActivity; +import de.danoeh.antennapod.core.export.html.HtmlWriter; +import de.danoeh.antennapod.core.export.opml.OpmlWriter; +import de.danoeh.antennapod.core.service.GpodnetSyncService; +import de.danoeh.antennapod.dialog.AuthenticationDialog; +import de.danoeh.antennapod.dialog.AutoFlattrPreferenceDialog; +import de.danoeh.antennapod.dialog.GpodnetSetHostnameDialog; +import de.danoeh.antennapod.dialog.ProxyDialog; +import de.danoeh.antennapod.dialog.VariableSpeedDialog; import de.danoeh.antennapod.core.util.gui.PictureInPictureUtil; import org.apache.commons.lang3.ArrayUtils; @@ -55,30 +70,21 @@ import java.util.concurrent.TimeUnit; import de.danoeh.antennapod.CrashReportWriter; 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.StatisticsActivity; import de.danoeh.antennapod.asynctask.ExportWorker; import de.danoeh.antennapod.core.export.ExportWriter; -import de.danoeh.antennapod.core.export.html.HtmlWriter; -import de.danoeh.antennapod.core.export.opml.OpmlWriter; import de.danoeh.antennapod.core.preferences.GpodnetPreferences; import de.danoeh.antennapod.core.preferences.UserPreferences; -import de.danoeh.antennapod.core.service.GpodnetSyncService; import de.danoeh.antennapod.core.util.flattr.FlattrUtils; -import de.danoeh.antennapod.dialog.AuthenticationDialog; -import de.danoeh.antennapod.dialog.AutoFlattrPreferenceDialog; import de.danoeh.antennapod.dialog.ChooseDataFolderDialog; -import de.danoeh.antennapod.dialog.GpodnetSetHostnameDialog; -import de.danoeh.antennapod.dialog.ProxyDialog; -import de.danoeh.antennapod.dialog.VariableSpeedDialog; import rx.Observable; import rx.Subscription; import rx.android.schedulers.AndroidSchedulers; import rx.schedulers.Schedulers; +import static de.danoeh.antennapod.activity.PreferenceActivity.PARAM_RESOURCE; + /** * Sets up a preference UI that lets the user change user preferences. */ @@ -87,6 +93,13 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc private static final String TAG = "PreferenceController"; + private static final String PREF_SCREEN_USER_INTERFACE = "prefScreenInterface"; + private static final String PREF_SCREEN_PLAYBACK = "prefScreenPlayback"; + private static final String PREF_SCREEN_NETWORK = "prefScreenNetwork"; + private static final String PREF_SCREEN_INTEGRATIONS = "prefScreenIntegrations"; + private static final String PREF_SCREEN_STORAGE = "prefScreenStorage"; + private static final String PREF_SCREEN_AUTODL = "prefAutoDownloadSettings"; + private static final String PREF_FLATTR_SETTINGS = "prefFlattrSettings"; private static final String PREF_FLATTR_AUTH = "pref_flattr_authenticate"; private static final String PREF_FLATTR_REVOKE = "prefRevokeAccess"; @@ -98,7 +111,6 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc private static final String IMPORT_EXPORT = "importExport"; private static final String PREF_ABOUT = "prefAbout"; 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"; private static final String PREF_PLAYBACK_REWIND_DELTA_LAUNCHER = "prefPlaybackRewindDeltaLauncher"; private static final String PREF_PLAYBACK_FAST_FORWARD_DELTA_LAUNCHER = "prefPlaybackFastForwardDeltaLauncher"; @@ -140,7 +152,40 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc } - public void onCreate() { + + + public void onCreate(int screen) { + switch (screen) { + case R.xml.preferences: + setupMainScreen(); + break; + case R.xml.preferences_network: + setupNetworkScreen(); + break; + case R.xml.preferences_autodownload: + setupAutoDownloadScreen(); + buildAutodownloadSelectedNetworsPreference(); + setSelectedNetworksEnabled(UserPreferences.isEnableAutodownloadWifiFilter()); + buildEpisodeCleanupPreference(); + break; + case R.xml.preferences_playback: + setupPlaybackScreen(); + PreferenceControllerFlavorHelper.setupFlavoredUI(ui); + buildSmartMarkAsPlayedPreference(); + break; + case R.xml.preferences_integrations: + setupIntegrationsScreen(); + break; + case R.xml.preferences_storage: + setupStorageScreen(); + break; + case R.xml.preferences_user_interface: + setupInterfaceScreen(); + break; + } + } + + private void setupInterfaceScreen() { final Activity activity = ui.getActivity(); if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) { @@ -155,25 +200,34 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc } ); } - ui.findPreference(PreferenceController.PREF_FLATTR_REVOKE).setOnPreferenceClickListener( - preference -> { - FlattrUtils.revokeAccessToken(activity); - checkItemVisibility(); + ui.findPreference(UserPreferences.PREF_THEME) + .setOnPreferenceChangeListener( + (preference, newValue) -> { + Intent i = new Intent(activity, MainActivity.class); + i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK + | Intent.FLAG_ACTIVITY_NEW_TASK); + activity.finish(); + activity.startActivity(i); + return true; + } + ); + ui.findPreference(UserPreferences.PREF_HIDDEN_DRAWER_ITEMS) + .setOnPreferenceClickListener(preference -> { + showDrawerPreferencesDialog(); return true; - } - ); - ui.findPreference(PreferenceController.PREF_ABOUT).setOnPreferenceClickListener( - preference -> { - activity.startActivity(new Intent(activity, AboutActivity.class)); + }); + + ui.findPreference(UserPreferences.PREF_COMPACT_NOTIFICATION_BUTTONS) + .setOnPreferenceClickListener(preference -> { + showNotificationButtonsDialog(); return true; - } - ); - ui.findPreference(PreferenceController.STATISTICS).setOnPreferenceClickListener( - preference -> { - activity.startActivity(new Intent(activity, StatisticsActivity.class)); - return true; - } - ); + }); + + } + + private void setupStorageScreen() { + final Activity activity = ui.getActivity(); + ui.findPreference(PreferenceController.IMPORT_EXPORT).setOnPreferenceClickListener( preference -> { activity.startActivity(new Intent(activity, ImportExportActivity.class)); @@ -222,126 +276,34 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc return true; } ); - ui.findPreference(UserPreferences.PREF_THEME) - .setOnPreferenceChangeListener( - (preference, newValue) -> { - Intent i = new Intent(activity, MainActivity.class); - i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK - | Intent.FLAG_ACTIVITY_NEW_TASK); - activity.finish(); - activity.startActivity(i); - return true; + ui.findPreference(UserPreferences.PREF_IMAGE_CACHE_SIZE).setOnPreferenceChangeListener( + (preference, o) -> { + if (o instanceof String) { + int newValue = Integer.parseInt((String) o) * 1024 * 1024; + if (newValue != UserPreferences.getImageCacheSize()) { + AlertDialog.Builder dialog = new AlertDialog.Builder(ui.getActivity()); + dialog.setTitle(android.R.string.dialog_alert_title); + dialog.setMessage(R.string.pref_restart_required); + dialog.setPositiveButton(android.R.string.ok, null); + dialog.show(); } - ); - ui.findPreference(UserPreferences.PREF_HIDDEN_DRAWER_ITEMS) - .setOnPreferenceClickListener(preference -> { - showDrawerPreferencesDialog(); - return true; - }); - - ui.findPreference(UserPreferences.PREF_COMPACT_NOTIFICATION_BUTTONS) - .setOnPreferenceClickListener(preference -> { - showNotificationButtonsDialog(); - return true; - }); - - ui.findPreference(UserPreferences.PREF_UPDATE_INTERVAL) - .setOnPreferenceClickListener(preference -> { - showUpdateIntervalTimePreferencesDialog(); - return true; - }); - - ui.findPreference(UserPreferences.PREF_ENABLE_AUTODL).setOnPreferenceChangeListener( - (preference, newValue) -> { - if (newValue instanceof Boolean) { - boolean enabled = (Boolean) newValue; - ui.findPreference(UserPreferences.PREF_EPISODE_CACHE_SIZE).setEnabled(enabled); - ui.findPreference(UserPreferences.PREF_ENABLE_AUTODL_ON_BATTERY).setEnabled(enabled); - ui.findPreference(UserPreferences.PREF_ENABLE_AUTODL_WIFI_FILTER).setEnabled(enabled); - setSelectedNetworksEnabled(enabled && UserPreferences.isEnableAutodownloadWifiFilter()); + return true; } - return true; - }); - ui.findPreference(UserPreferences.PREF_ENABLE_AUTODL_WIFI_FILTER) - .setOnPreferenceChangeListener( - (preference, newValue) -> { - if (newValue instanceof Boolean) { - setSelectedNetworksEnabled((Boolean) newValue); - return true; - } else { - return false; - } - } - ); - ui.findPreference(UserPreferences.PREF_PARALLEL_DOWNLOADS) - .setOnPreferenceChangeListener( - (preference, o) -> { - if (o instanceof String) { - try { - int value = Integer.parseInt((String) o); - if (1 <= value && value <= 50) { - setParallelDownloadsText(value); - return true; - } - } catch (NumberFormatException e) { - return false; - } - } - return false; - } - ); - // validate and set correct value: number of downloads between 1 and 50 (inclusive) - final EditText ev = ((EditTextPreference) ui.findPreference(UserPreferences.PREF_PARALLEL_DOWNLOADS)).getEditText(); - ev.addTextChangedListener(new TextWatcher() { - @Override - public void beforeTextChanged(CharSequence s, int start, int count, int after) { - } - - @Override - public void onTextChanged(CharSequence s, int start, int before, int count) { - } - - @Override - public void afterTextChanged(Editable s) { - if (s.length() > 0) { - try { - int value = Integer.parseInt(s.toString()); - if (value <= 0) { - ev.setText("1"); - } else if (value > 50) { - ev.setText("50"); - } - } catch (NumberFormatException e) { - ev.setText("6"); - } - ev.setSelection(ev.getText().length()); + return false; } - } - }); - ui.findPreference(UserPreferences.PREF_EPISODE_CACHE_SIZE) - .setOnPreferenceChangeListener( - (preference, o) -> { - if (o instanceof String) { - setEpisodeCacheSizeText(UserPreferences.readEpisodeCacheSize((String) o)); - } - return true; - } - ); - ui.findPreference(PreferenceController.PREF_PLAYBACK_SPEED_LAUNCHER) - .setOnPreferenceClickListener(preference -> { - VariableSpeedDialog.showDialog(activity); + ); + } + + private void setupIntegrationsScreen() { + final Activity activity = ui.getActivity(); + + ui.findPreference(PreferenceController.PREF_FLATTR_REVOKE).setOnPreferenceClickListener( + preference -> { + FlattrUtils.revokeAccessToken(activity); + checkFlattrItemVisibility(); 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, @@ -402,37 +364,154 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc @Override public void onConfirmed(boolean autoFlattrEnabled, float autoFlattrValue) { UserPreferences.setAutoFlattrSettings(autoFlattrEnabled, autoFlattrValue); - checkItemVisibility(); + checkFlattrItemVisibility(); } }); return true; }); - ui.findPreference(UserPreferences.PREF_IMAGE_CACHE_SIZE).setOnPreferenceChangeListener( - (preference, o) -> { - if (o instanceof String) { - int newValue = Integer.parseInt((String) o) * 1024 * 1024; - if (newValue != UserPreferences.getImageCacheSize()) { - AlertDialog.Builder dialog = new AlertDialog.Builder(ui.getActivity()); - dialog.setTitle(android.R.string.dialog_alert_title); - dialog.setMessage(R.string.pref_restart_required); - dialog.setPositiveButton(android.R.string.ok, null); - dialog.show(); - } - return true; - } - return false; - } - ); + } + + private void setupPlaybackScreen() { + final Activity activity = ui.getActivity(); + + ui.findPreference(PreferenceController.PREF_PLAYBACK_SPEED_LAUNCHER) + .setOnPreferenceClickListener(preference -> { + 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; + }); if (!PictureInPictureUtil.supportsPictureInPicture(activity)) { MaterialListPreference behaviour = (MaterialListPreference) ui.findPreference(UserPreferences.PREF_VIDEO_BEHAVIOR); behaviour.setEntries(R.array.video_background_behavior_options_without_pip); behaviour.setEntryValues(R.array.video_background_behavior_values_without_pip); } + } + + private void setupAutoDownloadScreen() { + ui.findPreference(UserPreferences.PREF_ENABLE_AUTODL).setOnPreferenceChangeListener( + (preference, newValue) -> { + if (newValue instanceof Boolean) { + checkAutodownloadItemVisibility((Boolean) newValue); + } + return true; + }); + ui.findPreference(UserPreferences.PREF_ENABLE_AUTODL_WIFI_FILTER) + .setOnPreferenceChangeListener( + (preference, newValue) -> { + if (newValue instanceof Boolean) { + setSelectedNetworksEnabled((Boolean) newValue); + return true; + } else { + return false; + } + } + ); + ui.findPreference(UserPreferences.PREF_EPISODE_CACHE_SIZE) + .setOnPreferenceChangeListener( + (preference, o) -> { + if (o instanceof String) { + setEpisodeCacheSizeText(UserPreferences.readEpisodeCacheSize((String) o)); + } + return true; + } + ); + } + + private void setupNetworkScreen() { + final Activity activity = ui.getActivity(); + ui.findPreference(PREF_SCREEN_AUTODL).setOnPreferenceClickListener(preference -> + openScreen(R.xml.preferences_autodownload, activity)); + ui.findPreference(UserPreferences.PREF_UPDATE_INTERVAL) + .setOnPreferenceClickListener(preference -> { + showUpdateIntervalTimePreferencesDialog(); + return true; + }); + ui.findPreference(UserPreferences.PREF_PARALLEL_DOWNLOADS) + .setOnPreferenceChangeListener( + (preference, o) -> { + if (o instanceof String) { + try { + int value = Integer.parseInt((String) o); + if (1 <= value && value <= 50) { + setParallelDownloadsText(value); + return true; + } + } catch (NumberFormatException e) { + return false; + } + } + return false; + } + ); + // validate and set correct value: number of downloads between 1 and 50 (inclusive) + final EditText ev = ((EditTextPreference) ui.findPreference(UserPreferences.PREF_PARALLEL_DOWNLOADS)).getEditText(); + ev.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + } + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + } + + @Override + public void afterTextChanged(Editable s) { + if (s.length() > 0) { + try { + int value = Integer.parseInt(s.toString()); + if (value <= 0) { + ev.setText("1"); + } else if (value > 50) { + ev.setText("50"); + } + } catch (NumberFormatException e) { + ev.setText("6"); + } + ev.setSelection(ev.getText().length()); + } + } + }); ui.findPreference(PREF_PROXY).setOnPreferenceClickListener(preference -> { ProxyDialog dialog = new ProxyDialog(ui.getActivity()); dialog.createDialog().show(); return true; }); + } + + private void setupMainScreen() { + final Activity activity = ui.getActivity(); + ui.findPreference(PREF_SCREEN_USER_INTERFACE).setOnPreferenceClickListener(preference -> + openScreen(R.xml.preferences_user_interface, activity)); + ui.findPreference(PREF_SCREEN_PLAYBACK).setOnPreferenceClickListener(preference -> + openScreen(R.xml.preferences_playback, activity)); + ui.findPreference(PREF_SCREEN_NETWORK).setOnPreferenceClickListener(preference -> + openScreen(R.xml.preferences_network, activity)); + ui.findPreference(PREF_SCREEN_INTEGRATIONS).setOnPreferenceClickListener(preference -> + openScreen(R.xml.preferences_integrations, activity)); + ui.findPreference(PREF_SCREEN_STORAGE).setOnPreferenceClickListener(preference -> + openScreen(R.xml.preferences_storage, activity)); + + ui.findPreference(PreferenceController.PREF_ABOUT).setOnPreferenceClickListener( + preference -> { + activity.startActivity(new Intent(activity, AboutActivity.class)); + return true; + } + ); + ui.findPreference(PreferenceController.STATISTICS).setOnPreferenceClickListener( + preference -> { + activity.startActivity(new Intent(activity, StatisticsActivity.class)); + return true; + } + ); ui.findPreference(PREF_KNOWN_ISSUES).setOnPreferenceClickListener(preference -> { openInBrowser("https://github.com/AntennaPod/AntennaPod/labels/bug"); return true; @@ -464,11 +543,17 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc ui.getActivity().startActivity(Intent.createChooser(emailIntent, intentTitle)); return true; }); - PreferenceControllerFlavorHelper.setupFlavoredUI(ui); - buildEpisodeCleanupPreference(); - buildSmartMarkAsPlayedPreference(); - buildAutodownloadSelectedNetworsPreference(); - setSelectedNetworksEnabled(UserPreferences.isEnableAutodownloadWifiFilter()); + } + + private boolean openScreen(int preferences, Activity activity) { + Fragment prefFragment = new PreferenceActivity.MainFragment(); + Bundle args = new Bundle(); + args.putInt(PARAM_RESOURCE, preferences); + prefFragment.setArguments(args); + activity.getFragmentManager().beginTransaction() + .replace(R.id.content, prefFragment) + .addToBackStack(TAG).commit(); + return true; } private boolean export(ExportWriter exportWriter) { @@ -524,22 +609,38 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc } } - public void onResume() { - checkItemVisibility(); - setUpdateIntervalText(); - setParallelDownloadsText(UserPreferences.getParallelDownloads()); - setEpisodeCacheSizeText(UserPreferences.getEpisodeCacheSize()); - setDataFolderText(); - GpodnetPreferences.registerOnSharedPreferenceChangeListener(gpoddernetListener); - updateGpodnetPreferenceScreen(); + public void onResume(int screen) { + switch (screen) { + case R.xml.preferences_network: + setUpdateIntervalText(); + setParallelDownloadsText(UserPreferences.getParallelDownloads()); + break; + case R.xml.preferences_autodownload: + setEpisodeCacheSizeText(UserPreferences.getEpisodeCacheSize()); + checkAutodownloadItemVisibility(UserPreferences.isEnableAutodownload()); + break; + case R.xml.preferences_storage: + setDataFolderText(); + break; + case R.xml.preferences_integrations: + GpodnetPreferences.registerOnSharedPreferenceChangeListener(gpoddernetListener); + updateGpodnetPreferenceScreen(); + checkFlattrItemVisibility(); + break; + case R.xml.preferences_playback: + checkSonicItemVisibility(); + break; + } } - public void onPause() { - GpodnetPreferences.unregisterOnSharedPreferenceChangeListener(gpoddernetListener); + public void onPause(int screen) { + if (screen == R.xml.preferences_integrations) { + GpodnetPreferences.unregisterOnSharedPreferenceChangeListener(gpoddernetListener); + } } public void onStop() { - if(subscription != null) { + if (subscription != null) { subscription.unsubscribe(); } } @@ -694,21 +795,24 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc } @SuppressWarnings("deprecation") - private void checkItemVisibility() { + private void checkFlattrItemVisibility() { boolean hasFlattrToken = FlattrUtils.hasToken(); ui.findPreference(PreferenceController.PREF_FLATTR_SETTINGS).setEnabled(FlattrUtils.hasAPICredentials()); ui.findPreference(PreferenceController.PREF_FLATTR_AUTH).setEnabled(!hasFlattrToken); ui.findPreference(PreferenceController.PREF_FLATTR_REVOKE).setEnabled(hasFlattrToken); ui.findPreference(PreferenceController.PREF_AUTO_FLATTR_PREFS).setEnabled(hasFlattrToken); + } - boolean autoDownload = UserPreferences.isEnableAutodownload(); + private void checkAutodownloadItemVisibility(boolean autoDownload) { ui.findPreference(UserPreferences.PREF_EPISODE_CACHE_SIZE).setEnabled(autoDownload); ui.findPreference(UserPreferences.PREF_ENABLE_AUTODL_ON_BATTERY).setEnabled(autoDownload); ui.findPreference(UserPreferences.PREF_ENABLE_AUTODL_WIFI_FILTER).setEnabled(autoDownload); + ui.findPreference(UserPreferences.PREF_EPISODE_CLEANUP).setEnabled(autoDownload); + ui.findPreference(UserPreferences.PREF_ENABLE_AUTODL_ON_MOBILE).setEnabled(autoDownload); setSelectedNetworksEnabled(autoDownload && UserPreferences.isEnableAutodownloadWifiFilter()); + } - ui.findPreference(PREF_SEND_CRASH_REPORT).setEnabled(CrashReportWriter.getFile().exists()); - + private void checkSonicItemVisibility() { if (Build.VERSION.SDK_INT < 16) { MaterialListPreference p = ((MaterialListPreference) ui.findPreference(UserPreferences.PREF_MEDIA_PLAYER)); p.setEntries(R.array.media_player_options_no_sonic); @@ -795,7 +899,7 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc selectedNetworks = new CheckBoxPreference[networks.size()]; List prefValues = Arrays.asList(UserPreferences .getAutodownloadSelectedNetworks()); - PreferenceScreen prefScreen = (PreferenceScreen) ui.findPreference(PreferenceController.AUTO_DL_PREF_SCREEN); + PreferenceScreen prefScreen = ui.getPreferenceScreen(); Preference.OnPreferenceClickListener clickListener = preference -> { if (preference instanceof CheckBoxPreference) { String key = preference.getKey(); @@ -842,7 +946,7 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc private void clearAutodownloadSelectedNetworsPreference() { if (selectedNetworks != null) { - PreferenceScreen prefScreen = (PreferenceScreen) ui.findPreference(PreferenceController.AUTO_DL_PREF_SCREEN); + PreferenceScreen prefScreen = ui.getPreferenceScreen(); for (CheckBoxPreference network : selectedNetworks) { if (network != null) { @@ -1007,11 +1111,15 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc public interface PreferenceUI { + void setFragment(PreferenceFragment fragment); + /** * Finds a preference based on its key. */ Preference findPreference(CharSequence key); + PreferenceScreen getPreferenceScreen(); + Activity getActivity(); } } diff --git a/app/src/main/res/layout/subscription_item.xml b/app/src/main/res/layout/subscription_item.xml index 8f0539dfa..502fa8672 100644 --- a/app/src/main/res/layout/subscription_item.xml +++ b/app/src/main/res/layout/subscription_item.xml @@ -11,7 +11,7 @@ android:layout_width="fill_parent" android:layout_height="fill_parent" android:scaleType="centerCrop" - tools:src="@drawable/ic_launcher"> + tools:src="@mipmap/ic_launcher_round"> + xmlns:android="http://schemas.android.com/apk/res/android"> + - - - - - - - - - - - - - + - - - + - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + android:title="@string/statistics_label" + android:icon="?attr/statistics" /> + - - - - - diff --git a/app/src/main/res/xml/preferences_autodownload.xml b/app/src/main/res/xml/preferences_autodownload.xml new file mode 100644 index 000000000..72716423a --- /dev/null +++ b/app/src/main/res/xml/preferences_autodownload.xml @@ -0,0 +1,39 @@ + + + + + + + + + + diff --git a/app/src/main/res/xml/preferences_integrations.xml b/app/src/main/res/xml/preferences_integrations.xml new file mode 100644 index 000000000..8ce35b596 --- /dev/null +++ b/app/src/main/res/xml/preferences_integrations.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/preferences_network.xml b/app/src/main/res/xml/preferences_network.xml new file mode 100644 index 000000000..77792bf88 --- /dev/null +++ b/app/src/main/res/xml/preferences_network.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/preferences_playback.xml b/app/src/main/res/xml/preferences_playback.xml new file mode 100644 index 000000000..00af36034 --- /dev/null +++ b/app/src/main/res/xml/preferences_playback.xml @@ -0,0 +1,130 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/preferences_storage.xml b/app/src/main/res/xml/preferences_storage.xml new file mode 100644 index 000000000..091b02ced --- /dev/null +++ b/app/src/main/res/xml/preferences_storage.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/preferences_user_interface.xml b/app/src/main/res/xml/preferences_user_interface.xml new file mode 100644 index 000000000..7ffa1b00f --- /dev/null +++ b/app/src/main/res/xml/preferences_user_interface.xml @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + diff --git a/build.gradle b/build.gradle index 61345e7b2..1cd8acc7e 100644 --- a/build.gradle +++ b/build.gradle @@ -40,7 +40,7 @@ project.ext { compileSdkVersion = 25 buildToolsVersion = "27.0.3" minSdkVersion = 14 - targetSdkVersion = 25 + targetSdkVersion = 26 supportVersion = "25.3.1" commonsioVersion = "2.5" diff --git a/core/src/main/AndroidManifest.xml b/core/src/main/AndroidManifest.xml index 3a5db2c36..3257c13a7 100644 --- a/core/src/main/AndroidManifest.xml +++ b/core/src/main/AndroidManifest.xml @@ -12,7 +12,7 @@ + android:icon="@mipmap/ic_launcher"> + android:drawable="@color/ic_launcher_background"/> + android:src="@mipmap/ic_launcher_foreground"/> \ No newline at end of file diff --git a/core/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/core/src/main/res/mipmap-anydpi-v26/ic_launcher.xml new file mode 100644 index 000000000..036d09bc5 --- /dev/null +++ b/core/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/core/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/core/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml new file mode 100644 index 000000000..036d09bc5 --- /dev/null +++ b/core/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/core/src/main/res/mipmap-hdpi/ic_launcher.png b/core/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 000000000..12e9b3395 Binary files /dev/null and b/core/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/core/src/main/res/mipmap-hdpi/ic_launcher_foreground.png b/core/src/main/res/mipmap-hdpi/ic_launcher_foreground.png new file mode 100644 index 000000000..d687f94bb Binary files /dev/null and b/core/src/main/res/mipmap-hdpi/ic_launcher_foreground.png differ diff --git a/core/src/main/res/mipmap-hdpi/ic_launcher_round.png b/core/src/main/res/mipmap-hdpi/ic_launcher_round.png new file mode 100644 index 000000000..12e9b3395 Binary files /dev/null and b/core/src/main/res/mipmap-hdpi/ic_launcher_round.png differ diff --git a/core/src/main/res/mipmap-mdpi/ic_launcher.png b/core/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 000000000..1da13d374 Binary files /dev/null and b/core/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/core/src/main/res/mipmap-mdpi/ic_launcher_foreground.png b/core/src/main/res/mipmap-mdpi/ic_launcher_foreground.png new file mode 100644 index 000000000..2e7a4b74d Binary files /dev/null and b/core/src/main/res/mipmap-mdpi/ic_launcher_foreground.png differ diff --git a/core/src/main/res/mipmap-mdpi/ic_launcher_round.png b/core/src/main/res/mipmap-mdpi/ic_launcher_round.png new file mode 100644 index 000000000..1da13d374 Binary files /dev/null and b/core/src/main/res/mipmap-mdpi/ic_launcher_round.png differ diff --git a/core/src/main/res/mipmap-xhdpi/ic_launcher.png b/core/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 000000000..32b022ada Binary files /dev/null and b/core/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/core/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png b/core/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png new file mode 100644 index 000000000..5f90a1d11 Binary files /dev/null and b/core/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png differ diff --git a/core/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/core/src/main/res/mipmap-xhdpi/ic_launcher_round.png new file mode 100644 index 000000000..32b022ada Binary files /dev/null and b/core/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ diff --git a/core/src/main/res/mipmap-xxhdpi/ic_launcher.png b/core/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 000000000..321600e15 Binary files /dev/null and b/core/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/core/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png b/core/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png new file mode 100644 index 000000000..d72ffedbb Binary files /dev/null and b/core/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png differ diff --git a/core/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/core/src/main/res/mipmap-xxhdpi/ic_launcher_round.png new file mode 100644 index 000000000..321600e15 Binary files /dev/null and b/core/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ diff --git a/core/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/core/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 000000000..ff2870dca Binary files /dev/null and b/core/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/core/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png b/core/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png new file mode 100644 index 000000000..0af16fadf Binary files /dev/null and b/core/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png differ diff --git a/core/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/core/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png new file mode 100644 index 000000000..ff2870dca Binary files /dev/null and b/core/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ diff --git a/core/src/main/res/values/attrs.xml b/core/src/main/res/values/attrs.xml index 5f25796b0..b005d4dc3 100644 --- a/core/src/main/res/values/attrs.xml +++ b/core/src/main/res/values/attrs.xml @@ -12,6 +12,8 @@ + + @@ -52,6 +54,8 @@ + + diff --git a/core/src/main/res/values/colors.xml b/core/src/main/res/values/colors.xml index 969500928..c9a5b3d6a 100644 --- a/core/src/main/res/values/colors.xml +++ b/core/src/main/res/values/colors.xml @@ -33,4 +33,7 @@ #147BAF + #DDDDDD + #191919 + diff --git a/core/src/main/res/values/ic_launcher_background.xml b/core/src/main/res/values/ic_launcher_background.xml new file mode 100644 index 000000000..3df03b8f4 --- /dev/null +++ b/core/src/main/res/values/ic_launcher_background.xml @@ -0,0 +1,4 @@ + + + #008AB8 + \ No newline at end of file diff --git a/core/src/main/res/values/strings.xml b/core/src/main/res/values/strings.xml index f9a03f3a2..63796fae4 100644 --- a/core/src/main/res/values/strings.xml +++ b/core/src/main/res/values/strings.xml @@ -24,6 +24,7 @@ Cancel\nDownload Playback History gpodder.net + Synchronize with other devices gpodder.net Login %1$s free Episode cache full @@ -310,8 +311,17 @@ Other About Queue - Services + Integrations Flattr + Micropayment service + Automation + Details + Import/Export + Appearance + External elements + Interruptions + Buttons + Media player Episode Cleanup Episodes that aren\'t in the queue and aren\'t favorites should be eligible for removal if Auto Download needs space for new episodes Pause playback when headphones or bluetooth are disconnected diff --git a/core/src/main/res/values/styles.xml b/core/src/main/res/values/styles.xml index b74b55334..77758a223 100644 --- a/core/src/main/res/values/styles.xml +++ b/core/src/main/res/values/styles.xml @@ -12,6 +12,9 @@ @style/Widget.AntennaPod.Button @style/AntennaPod.Dialog.Light @color/grey600 + @drawable/ic_sd_grey600_24dp + @drawable/ic_swap_vertical_grey600_24dp + @drawable/ic_poll_box_grey600_24dp @drawable/ic_info_grey600_24dp @drawable/ic_checkbox_multiple_marked_outline_grey600_24dp @drawable/ic_search_grey600_24dp @@ -63,6 +66,7 @@ @drawable/ic_sd_storage_grey600_36dp @drawable/ic_create_new_folder_grey600_24dp @drawable/ic_cast_disconnect_grey600_36dp + @color/master_switch_background_light