Migrate tasker list notification to androidx prefs

pull/935/head
Alex Baker 6 years ago
parent 71d92db25f
commit bf3088ad0b

@ -15,6 +15,7 @@ import org.tasks.fragments.CommentBarFragment;
import org.tasks.preferences.fragments.DashClock;
import org.tasks.preferences.fragments.HelpAndFeedback;
import org.tasks.preferences.fragments.ScrollableWidget;
import org.tasks.preferences.fragments.TaskerListNotification;
import org.tasks.ui.CalendarControlSet;
import org.tasks.ui.DeadlineControlSet;
import org.tasks.ui.DescriptionControlSet;
@ -71,4 +72,6 @@ public interface FragmentComponent {
void inject(@NotNull ScrollableWidget scrollableWidget);
void inject(@NotNull DashClock dashClock);
void inject(@NotNull TaskerListNotification taskerListNotification);
}

@ -9,7 +9,6 @@ import timber.log.Timber;
public final class ListNotificationBundle {
public static final String BUNDLE_EXTRA_STRING_FILTER = "org.tasks.locale.STRING_FILTER";
public static final String BUNDLE_EXTRA_PREVIOUS_BUNDLE = "org.tasks.locale.PREVIOUS_BUNDLE";
private static final String BUNDLE_EXTRA_INT_VERSION_CODE = "org.tasks.locale.INT_VERSION_CODE";
private ListNotificationBundle() {}

@ -0,0 +1,81 @@
package org.tasks.locale.ui.activity
import android.content.Intent
import android.os.Bundle
import org.tasks.preferences.BasePreferences
import timber.log.Timber
abstract class AbstractFragmentPluginPreference : BasePreferences() {
companion object {
fun isLocalePluginIntent(intent: Intent): Boolean {
val action = intent.action
return com.twofortyfouram.locale.api.Intent.ACTION_EDIT_CONDITION == action
|| com.twofortyfouram.locale.api.Intent.ACTION_EDIT_SETTING == action
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (isLocalePluginIntent(intent)) {
Timber.d(
"Creating Activity with Intent=%s, savedInstanceState=%s, EXTRA_BUNDLE=%s",
intent, savedInstanceState, getPreviousBundle())
}
}
override fun finish() {
if (isLocalePluginIntent(intent)) {
if (!isCancelled()) {
val resultBundle = getResultBundle()
if (null != resultBundle) {
val blurb = getResultBlurb(resultBundle)
val result = Bundle()
result.putBundle(com.twofortyfouram.locale.api.Intent.EXTRA_BUNDLE, resultBundle)
result.putString(com.twofortyfouram.locale.api.Intent.EXTRA_STRING_BLURB, blurb)
setResult(RESULT_OK, Intent().putExtras(result))
}
}
}
super.finish()
}
/**
* @return The [EXTRA_BUNDLE][com.twofortyfouram.locale.api.Intent.EXTRA_BUNDLE] that was
* previously saved to the host and subsequently passed back to this Activity for further
* editing. Internally, this method relies on [.isBundleValid]. If the bundle
* exists but is not valid, this method will return null.
*/
protected fun getPreviousBundle(): Bundle? {
val bundle = intent.getBundleExtra(com.twofortyfouram.locale.api.Intent.EXTRA_BUNDLE)
if (null != bundle) {
if (isBundleValid(bundle)) {
return bundle
}
}
return null
}
/**
* Validates the Bundle, to ensure that a malicious application isn't attempting to pass an
* invalid Bundle.
*
* @param bundle The plug-in's Bundle previously returned by the edit Activity. `bundle`
* should not be mutated by this method.
* @return true if `bundle` is valid for the plug-in.
*/
protected abstract fun isBundleValid(bundle: Bundle?): Boolean
/** @return Bundle for the plug-in or `null` if a valid Bundle cannot be generated.
*/
protected abstract fun getResultBundle(): Bundle?
/**
* @param bundle Valid bundle for the component.
* @return Blurb for `bundle`.
*/
protected abstract fun getResultBlurb(bundle: Bundle?): String?
protected abstract fun isCancelled(): Boolean
}

@ -1,132 +0,0 @@
package org.tasks.locale.ui.activity;
import android.content.Intent;
import android.os.Bundle;
import org.tasks.injection.InjectingPreferenceActivity;
import timber.log.Timber;
public abstract class AbstractFragmentPluginPreferenceActivity extends InjectingPreferenceActivity {
boolean mIsCancelled = false;
/* package */
private static boolean isLocalePluginIntent(final Intent intent) {
final String action = intent.getAction();
return com.twofortyfouram.locale.api.Intent.ACTION_EDIT_CONDITION.equals(action)
|| com.twofortyfouram.locale.api.Intent.ACTION_EDIT_SETTING.equals(action);
}
@Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (isLocalePluginIntent(getIntent())) {
final Bundle previousBundle = getPreviousBundle();
Timber.d(
"Creating Activity with Intent=%s, savedInstanceState=%s, EXTRA_BUNDLE=%s",
getIntent(), savedInstanceState, previousBundle); // $NON-NLS-1$
}
}
@Override
protected void onPostCreate(final Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
if (isLocalePluginIntent(getIntent())) {
if (null == savedInstanceState) {
final Bundle previousBundle = getPreviousBundle();
final String previousBlurb = getPreviousBlurb();
if (null != previousBundle && null != previousBlurb) {
onPostCreateWithPreviousResult(previousBundle, previousBlurb);
}
}
}
}
@Override
public void finish() {
if (isLocalePluginIntent(getIntent())) {
if (!mIsCancelled) {
final Bundle resultBundle = getResultBundle();
if (null != resultBundle) {
String blurb = getResultBlurb(resultBundle);
Bundle result = new Bundle();
result.putBundle(com.twofortyfouram.locale.api.Intent.EXTRA_BUNDLE, resultBundle);
result.putString(com.twofortyfouram.locale.api.Intent.EXTRA_STRING_BLURB, blurb);
mergeResults(result);
}
}
}
super.finish();
}
/**
* @return The {@link com.twofortyfouram.locale.api.Intent#EXTRA_BUNDLE EXTRA_BUNDLE} that was
* previously saved to the host and subsequently passed back to this Activity for further
* editing. Internally, this method relies on {@link #isBundleValid(Bundle)}. If the bundle
* exists but is not valid, this method will return null.
*/
private Bundle getPreviousBundle() {
final Bundle bundle =
getIntent().getBundleExtra(com.twofortyfouram.locale.api.Intent.EXTRA_BUNDLE);
if (null != bundle) {
if (isBundleValid(bundle)) {
return bundle;
}
}
return null;
}
/**
* @return The {@link com.twofortyfouram.locale.api.Intent#EXTRA_STRING_BLURB EXTRA_STRING_BLURB}
* that was previously saved to the host and subsequently passed back to this Activity for
* further editing.
*/
private String getPreviousBlurb() {
return getIntent().getStringExtra(com.twofortyfouram.locale.api.Intent.EXTRA_STRING_BLURB);
}
/**
* Validates the Bundle, to ensure that a malicious application isn't attempting to pass an
* invalid Bundle.
*
* @param bundle The plug-in's Bundle previously returned by the edit Activity. {@code bundle}
* should not be mutated by this method.
* @return true if {@code bundle} is valid for the plug-in.
*/
protected abstract boolean isBundleValid(final Bundle bundle);
/**
* Plug-in Activity lifecycle callback to allow the Activity to restore state for editing a
* previously saved plug-in instance. This callback will occur during the onPostCreate() phase of
* the Activity lifecycle.
*
* <p>{@code bundle} will have been validated by {@link #isBundleValid(Bundle)} prior to this
* method being called. If {@link #isBundleValid(Bundle)} returned false, then this method will
* not be called. This helps ensure that plug-in Activity subclasses only have to worry about
* bundle validation once, in the {@link #isBundleValid(Bundle)} method.
*
* <p>Note this callback only occurs the first time the Activity is created, so it will not be
* called when the Activity is recreated (e.g. {@code savedInstanceState != null}) such as after a
* configuration change like a screen rotation.
*
* @param previousBundle Previous bundle that the Activity saved.
* @param previousBlurb Previous blurb that the Activity saved
*/
protected abstract void onPostCreateWithPreviousResult(
final Bundle previousBundle, final String previousBlurb);
/** @return Bundle for the plug-in or {@code null} if a valid Bundle cannot be generated. */
protected abstract Bundle getResultBundle();
/**
* @param bundle Valid bundle for the component.
* @return Blurb for {@code bundle}.
*/
protected abstract String getResultBlurb(final Bundle bundle);
}

@ -1,141 +0,0 @@
package org.tasks.locale.ui.activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.MenuItem;
import androidx.appcompat.widget.Toolbar;
import com.todoroo.astrid.api.Filter;
import javax.inject.Inject;
import org.tasks.R;
import org.tasks.activities.FilterSelectionActivity;
import org.tasks.billing.BillingClient;
import org.tasks.billing.Inventory;
import org.tasks.billing.PurchaseActivity;
import org.tasks.injection.ActivityComponent;
import org.tasks.locale.bundle.ListNotificationBundle;
import org.tasks.preferences.DefaultFilterProvider;
public final class TaskerSettingsActivity extends AbstractFragmentPluginPreferenceActivity
implements Toolbar.OnMenuItemClickListener {
private static final int REQUEST_SELECT_FILTER = 10124;
private static final int REQUEST_SUBSCRIPTION = 10125;
private static final String EXTRA_FILTER = "extra_filter";
@Inject DefaultFilterProvider defaultFilterProvider;
@Inject BillingClient billingClient;
@Inject Inventory inventory;
private Bundle previousBundle;
private Filter filter;
@Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences_tasker);
if (savedInstanceState != null) {
previousBundle =
savedInstanceState.getParcelable(ListNotificationBundle.BUNDLE_EXTRA_PREVIOUS_BUNDLE);
filter = savedInstanceState.getParcelable(EXTRA_FILTER);
} else {
filter = defaultFilterProvider.getDefaultFilter();
}
findPreference(R.string.filter)
.setOnPreferenceClickListener(
preference -> {
Intent intent =
new Intent(TaskerSettingsActivity.this, FilterSelectionActivity.class);
intent.putExtra(FilterSelectionActivity.EXTRA_FILTER, filter);
intent.putExtra(FilterSelectionActivity.EXTRA_RETURN_FILTER, true);
startActivityForResult(intent, REQUEST_SELECT_FILTER);
return false;
});
refreshPreferences();
if (!inventory.purchasedTasker()) {
startActivityForResult(new Intent(this, PurchaseActivity.class), REQUEST_SUBSCRIPTION);
}
}
@Override
public void onPostCreateWithPreviousResult(
final Bundle previousBundle, final String previousBlurb) {
this.previousBundle = previousBundle;
this.filter =
defaultFilterProvider.getFilterFromPreference(
ListNotificationBundle.getFilter(previousBundle));
refreshPreferences();
}
@Override
public boolean isBundleValid(final Bundle bundle) {
return ListNotificationBundle.isBundleValid(bundle);
}
@Override
protected Bundle getResultBundle() {
return ListNotificationBundle.generateBundle(
defaultFilterProvider.getFilterPreferenceValue(filter));
}
@Override
public String getResultBlurb(final Bundle bundle) {
return filter.listingTitle;
}
private void cancel() {
mIsCancelled = true;
finish();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_SELECT_FILTER) {
if (resultCode == RESULT_OK) {
filter = data.getParcelableExtra(FilterSelectionActivity.EXTRA_FILTER);
refreshPreferences();
}
} else if (requestCode == REQUEST_SUBSCRIPTION) {
if (!inventory.purchasedTasker()) {
cancel();
}
} else {
super.onActivityResult(requestCode, resultCode, data);
}
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putParcelable(ListNotificationBundle.BUNDLE_EXTRA_PREVIOUS_BUNDLE, previousBundle);
outState.putParcelable(EXTRA_FILTER, filter);
}
private void refreshPreferences() {
findPreference(getString(R.string.filter)).setSummary(filter.listingTitle);
}
@Override
public void inject(ActivityComponent component) {
component.inject(this);
}
@Override
protected String getHelpUrl() {
return "http://tasks.org/help/tasker";
}
@Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_save:
finish();
return true;
}
return super.onMenuItemClick(item);
}
}

@ -0,0 +1,40 @@
package org.tasks.locale.ui.activity
import android.os.Bundle
import org.tasks.R
import org.tasks.injection.ActivityComponent
import org.tasks.locale.bundle.ListNotificationBundle
import org.tasks.preferences.fragments.TaskerListNotification
import org.tasks.preferences.fragments.TaskerListNotification.Companion.newTaskerListNotification
class TaskerSettingsActivity : AbstractFragmentPluginPreference() {
var filter: String? = null
override fun onCreate(savedInstanceState: Bundle?) {
if (isLocalePluginIntent(intent)) {
val previousBundle = getPreviousBundle()
if (isBundleValid(previousBundle)) {
filter = ListNotificationBundle.getFilter(previousBundle)
}
}
super.onCreate(savedInstanceState)
}
override fun isBundleValid(bundle: Bundle?) = ListNotificationBundle.isBundleValid(bundle)
override fun getResultBundle() = getFragment().getBundle()
override fun getResultBlurb(bundle: Bundle?) = getFragment().getResultBlurb()
override fun isCancelled() = getFragment().cancelled
override fun getRootTitle() = R.string.tasker_list_notification
override fun getRootPreference() = newTaskerListNotification(filter)
override fun inject(component: ActivityComponent) = component.inject(this)
private fun getFragment() = supportFragmentManager.findFragmentById(R.id.settings) as TaskerListNotification
}

@ -0,0 +1,99 @@
package org.tasks.preferences.fragments
import android.app.Activity.RESULT_OK
import android.content.Intent
import android.os.Bundle
import com.todoroo.astrid.api.Filter
import org.tasks.R
import org.tasks.activities.FilterSelectionActivity
import org.tasks.billing.Inventory
import org.tasks.billing.PurchaseActivity
import org.tasks.injection.FragmentComponent
import org.tasks.injection.InjectingPreferenceFragment
import org.tasks.locale.bundle.ListNotificationBundle
import org.tasks.preferences.DefaultFilterProvider
import javax.inject.Inject
const val EXTRA_FILTER = "extra_filter"
private const val REQUEST_SELECT_FILTER = 10124
private const val REQUEST_SUBSCRIPTION = 10125
class TaskerListNotification : InjectingPreferenceFragment() {
companion object {
fun newTaskerListNotification(filter: String?): TaskerListNotification {
val fragment = TaskerListNotification()
val args = Bundle()
args.putString(EXTRA_FILTER, filter)
fragment.arguments = args
return fragment
}
}
@Inject lateinit var defaultFilterProvider: DefaultFilterProvider
@Inject lateinit var inventory: Inventory
var filter: Filter? = null
var cancelled: Boolean = false
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.preferences_tasker, rootKey)
filter = if (savedInstanceState == null) {
defaultFilterProvider.getFilterFromPreference(arguments?.getString(EXTRA_FILTER))
} else {
savedInstanceState.getParcelable(EXTRA_FILTER)
}
refreshPreferences()
findPreference(R.string.filter).setOnPreferenceClickListener {
val intent = Intent(context, FilterSelectionActivity::class.java)
intent.putExtra(FilterSelectionActivity.EXTRA_FILTER, filter)
intent.putExtra(FilterSelectionActivity.EXTRA_RETURN_FILTER, true)
startActivityForResult(intent, REQUEST_SELECT_FILTER)
false
}
if (!inventory.purchasedTasker()) {
startActivityForResult(Intent(context, PurchaseActivity::class.java), REQUEST_SUBSCRIPTION)
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (requestCode == REQUEST_SELECT_FILTER) {
if (resultCode == RESULT_OK) {
filter = data!!.getParcelableExtra(FilterSelectionActivity.EXTRA_FILTER)
refreshPreferences()
}
} else if (requestCode == REQUEST_SUBSCRIPTION) {
if (!inventory.purchasedTasker()) {
cancelled = true
activity!!.finish()
}
} else {
super.onActivityResult(requestCode, resultCode, data)
}
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.putParcelable(EXTRA_FILTER, filter)
}
private fun refreshPreferences() {
findPreference(R.string.filter).summary = filter?.listingTitle
}
fun getResultBlurb(): String? {
return filter?.listingTitle
}
fun getBundle(): Bundle {
return ListNotificationBundle.generateBundle(
defaultFilterProvider.getFilterPreferenceValue(filter))
}
override fun inject(component: FragmentComponent) = component.inject(this)
}

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<com.todoroo.astrid.ui.MultilinePreference
<Preference
android:key="@string/filter"
android:title="@string/filter"/>
</PreferenceScreen>
Loading…
Cancel
Save