New 'Add account' dialog

pull/898/head
Alex Baker 4 years ago
parent 55e60de0a6
commit 502b81555e

@ -153,11 +153,6 @@
android:name=".activities.CameraActivity"
android:theme="@style/TranslucentDialog"/>
<activity
android:label="@string/synchronization"
android:name=".sync.SynchronizationPreferences"
android:theme="@style/Tasks"/>
<activity android:name="com.todoroo.astrid.activity.TaskEditActivity">
<intent-filter tools:ignore="AppLinkUrlError">
<action android:name="android.intent.action.VIEW"/>

@ -27,7 +27,7 @@ import org.tasks.R;
import org.tasks.billing.Inventory;
import org.tasks.filters.NavigationDrawerSubheader;
import org.tasks.locale.Locale;
import org.tasks.sync.SynchronizationPreferences;
import org.tasks.preferences.BasicPreferences;
import org.tasks.themes.CustomIcons;
import org.tasks.themes.ThemeAccent;
import org.tasks.themes.ThemeCache;
@ -104,7 +104,7 @@ public class FilterViewHolder extends RecyclerView.ViewHolder {
ButterKnife.bind(this, itemView);
icon.setOnClickListener(
v -> activity.startActivity(new Intent(activity, SynchronizationPreferences.class)));
v -> activity.startActivity(new Intent(activity, BasicPreferences.class)));
}
FilterViewHolder(@NonNull View itemView) {

@ -24,6 +24,7 @@ import org.tasks.analytics.Tracker;
import org.tasks.analytics.Tracking;
import org.tasks.calendars.AndroidCalendar;
import org.tasks.calendars.CalendarProvider;
import org.tasks.dialogs.DialogBuilder;
import org.tasks.dialogs.NativeSeekBarDialog;
import org.tasks.gtasks.RemoteListSelectionHandler;
import org.tasks.injection.ActivityComponent;
@ -34,7 +35,7 @@ import org.tasks.preferences.DefaultFilterProvider;
import org.tasks.preferences.Device;
import org.tasks.preferences.PermissionRequestor;
import org.tasks.preferences.Preferences;
import org.tasks.sync.SynchronizationPreferences;
import org.tasks.sync.AddAccountDialog;
public class DefaultsPreferences extends InjectingPreferenceActivity
implements RemoteListSelectionHandler, NativeSeekBarDialog.SeekBarCallback {
@ -51,6 +52,7 @@ public class DefaultsPreferences extends InjectingPreferenceActivity
@Inject DefaultFilterProvider defaultFilterProvider;
@Inject Locale locale;
@Inject Device device;
@Inject DialogBuilder dialogBuilder;
private Preference defaultCalendarPref;
private Preference defaultRadiusPref;
@ -139,7 +141,7 @@ public class DefaultsPreferences extends InjectingPreferenceActivity
@Override
public void addAccount() {
startActivity(new Intent(this, SynchronizationPreferences.class));
AddAccountDialog.showAddAccountDialog(this, dialogBuilder);
}
@Override

@ -6,9 +6,12 @@
package com.todoroo.astrid.gtasks.auth;
import static org.tasks.PermissionUtil.verifyPermissions;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.Bundle;
import androidx.annotation.NonNull;
import com.todoroo.andlib.utility.DialogUtilities;
import javax.inject.Inject;
import org.tasks.R;
@ -19,6 +22,8 @@ import org.tasks.gtasks.GoogleAccountManager;
import org.tasks.injection.ActivityComponent;
import org.tasks.injection.InjectingAppCompatActivity;
import org.tasks.play.AuthResultHandler;
import org.tasks.preferences.ActivityPermissionRequestor;
import org.tasks.preferences.PermissionRequestor;
/**
* This activity allows users to sign in or log in to Google Tasks through the Android account
@ -33,15 +38,15 @@ public class GtasksLoginActivity extends InjectingAppCompatActivity {
@Inject DialogBuilder dialogBuilder;
@Inject GoogleAccountManager googleAccountManager;
@Inject GoogleTaskListDao googleTaskListDao;
@Inject ActivityPermissionRequestor permissionRequestor;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent chooseAccountIntent =
android.accounts.AccountManager.newChooseAccountIntent(
null, null, new String[] {"com.google"}, false, null, null, null, null);
startActivityForResult(chooseAccountIntent, RC_CHOOSE_ACCOUNT);
if (permissionRequestor.requestAccountPermissions()) {
chooseAccount();
}
}
@Override
@ -49,6 +54,13 @@ public class GtasksLoginActivity extends InjectingAppCompatActivity {
component.inject(this);
}
private void chooseAccount() {
Intent chooseAccountIntent =
android.accounts.AccountManager.newChooseAccountIntent(
null, null, new String[] {"com.google"}, false, null, null, null, null);
startActivityForResult(chooseAccountIntent, RC_CHOOSE_ACCOUNT);
}
private void getAuthToken(String account) {
final ProgressDialog pd = dialogBuilder.newProgressDialog(R.string.gtasks_GLA_authenticating);
pd.show();
@ -99,4 +111,16 @@ public class GtasksLoginActivity extends InjectingAppCompatActivity {
super.onActivityResult(requestCode, resultCode, data);
}
}
@Override
public void onRequestPermissionsResult(
int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if (requestCode == PermissionRequestor.REQUEST_GOOGLE_ACCOUNTS) {
if (verifyPermissions(grantResults)) {
chooseAccount();
}
} else {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
}

@ -24,8 +24,8 @@ import org.tasks.filters.FilterProvider;
import org.tasks.gtasks.RemoteListSelectionHandler;
import org.tasks.injection.DialogFragmentComponent;
import org.tasks.injection.InjectingDialogFragment;
import org.tasks.sync.AddAccountDialog;
import org.tasks.sync.SyncAdapters;
import org.tasks.sync.SynchronizationPreferences;
public class RemoteListSupportPicker extends InjectingDialogFragment
implements RemoteListSelectionHandler {
@ -136,7 +136,7 @@ public class RemoteListSupportPicker extends InjectingDialogFragment
@Override
public void addAccount() {
startActivity(new Intent(getContext(), SynchronizationPreferences.class));
AddAccountDialog.showAddAccountDialog(getActivity(), dialogBuilder);
}
@Override

@ -1,6 +1,7 @@
package org.tasks.caldav;
import static android.text.TextUtils.isEmpty;
import static org.tasks.billing.PurchaseDialog.newPurchaseDialog;
import android.content.Context;
import android.content.Intent;
@ -9,12 +10,14 @@ import android.os.Bundle;
import android.view.MenuItem;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import androidx.annotation.StringRes;
import androidx.appcompat.widget.Toolbar;
import androidx.core.content.ContextCompat;
import at.bitfire.dav4jvm.exception.HttpException;
import butterknife.ButterKnife;
import butterknife.OnFocusChange;
import butterknife.OnTextChanged;
import com.google.android.material.snackbar.BaseTransientBottomBar;
import com.google.android.material.snackbar.Snackbar;
import com.google.android.material.textfield.TextInputEditText;
import com.todoroo.astrid.service.TaskDeleter;
@ -26,6 +29,7 @@ import javax.inject.Inject;
import org.tasks.R;
import org.tasks.analytics.Tracker;
import org.tasks.analytics.Tracking.Events;
import org.tasks.billing.Inventory;
import org.tasks.data.CaldavAccount;
import org.tasks.data.CaldavDao;
import org.tasks.databinding.ActivityCaldavAccountSettingsBinding;
@ -47,6 +51,7 @@ public abstract class BaseCaldavAccountSettingsActivity extends ThemedInjectingA
@Inject protected Encryption encryption;
@Inject DialogBuilder dialogBuilder;
@Inject TaskDeleter taskDeleter;
@Inject Inventory inventory;
protected CaldavAccount caldavAccount;
@ -94,6 +99,15 @@ public abstract class BaseCaldavAccountSettingsActivity extends ThemedInjectingA
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(binding.name, InputMethodManager.SHOW_IMPLICIT);
}
if (!inventory.hasPro()) {
newSnackbar(R.string.this_feature_requires_a_subscription)
.setDuration(BaseTransientBottomBar.LENGTH_INDEFINITE)
.setAction(
R.string.button_subscribe,
v -> newPurchaseDialog().show(getSupportFragmentManager(), null))
.show();
}
}
private void showProgressIndicator() {
@ -291,6 +305,14 @@ public abstract class BaseCaldavAccountSettingsActivity extends ThemedInjectingA
}
private void showSnackbar(String message) {
newSnackbar(message).show();
}
private Snackbar newSnackbar(@StringRes int resId) {
return newSnackbar(getString(resId));
}
private Snackbar newSnackbar(String message) {
Snackbar snackbar =
Snackbar.make(binding.rootLayout, message, 8000)
.setTextColor(ContextCompat.getColor(this, R.color.snackbar_text_color))
@ -298,7 +320,7 @@ public abstract class BaseCaldavAccountSettingsActivity extends ThemedInjectingA
snackbar
.getView()
.setBackgroundColor(ContextCompat.getColor(this, R.color.snackbar_background));
snackbar.show();
return snackbar;
}
private boolean hasChanges() {

@ -50,7 +50,7 @@ public class AlertDialogBuilder {
return this;
}
AlertDialogBuilder setTitle(int title) {
public AlertDialogBuilder setTitle(int title) {
builder.setTitle(title);
return this;
}
@ -62,7 +62,7 @@ public class AlertDialogBuilder {
public AlertDialogBuilder setItems(
List<String> strings, DialogInterface.OnClickListener onClickListener) {
return setItems(strings.toArray(new String[strings.size()]), onClickListener);
return setItems(strings.toArray(new String[0]), onClickListener);
}
public AlertDialogBuilder setItems(
@ -86,10 +86,10 @@ public class AlertDialogBuilder {
return this;
}
public AlertDialogBuilder setSingleChoiceItems(
AlertDialogBuilder setSingleChoiceItems(
List<String> strings, int selectedIndex, DialogInterface.OnClickListener onClickListener) {
builder.setSingleChoiceItems(
addDirectionality(strings.toArray(new String[strings.size()])),
addDirectionality(strings.toArray(new String[0])),
selectedIndex,
onClickListener);
return this;

@ -41,7 +41,6 @@ import org.tasks.preferences.DebugPreferences;
import org.tasks.preferences.MiscellaneousPreferences;
import org.tasks.reminders.NotificationActivity;
import org.tasks.reminders.SnoozeActivity;
import org.tasks.sync.SynchronizationPreferences;
import org.tasks.tags.TagPickerViewModel;
import org.tasks.themes.Theme;
import org.tasks.ui.TaskListViewModel;
@ -54,8 +53,6 @@ import org.tasks.widget.WidgetConfigActivity;
@Subcomponent(modules = {ActivityModule.class, LocationModule.class})
public interface ActivityComponent {
void inject(SynchronizationPreferences synchronizationPreferences);
void inject(GtasksLoginActivity gtasksLoginActivity);
Theme getTheme();

@ -174,6 +174,12 @@ public abstract class InjectingPreferenceActivity extends AppCompatPreferenceAct
super.finish();
}
protected void restart() {
Intent intent = getIntent();
finish();
startActivity(intent);
}
protected void emailSupport() {
startActivity(
new Intent(

@ -2,7 +2,7 @@ package org.tasks.preferences;
import static com.todoroo.andlib.utility.AndroidUtilities.atLeastJellybeanMR1;
import static com.todoroo.andlib.utility.AndroidUtilities.atLeastLollipop;
import static com.todoroo.andlib.utility.AndroidUtilities.atLeastMarshmallow;
import static com.todoroo.andlib.utility.DateUtilities.now;
import static java.util.Arrays.asList;
import static org.tasks.PermissionUtil.verifyPermissions;
import static org.tasks.dialogs.ExportTasksDialog.newExportTasksDialog;
@ -21,14 +21,17 @@ import android.net.Uri;
import android.os.Bundle;
import android.preference.CheckBoxPreference;
import android.preference.Preference;
import android.preference.PreferenceCategory;
import android.preference.PreferenceScreen;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import com.google.common.base.Strings;
import com.todoroo.astrid.activity.BeastModePreferences;
import com.todoroo.astrid.api.Filter;
import com.todoroo.astrid.core.OldTaskPreferences;
import com.todoroo.astrid.gtasks.auth.GtasksLoginActivity;
import com.todoroo.astrid.reminders.ReminderPreferences;
import com.todoroo.astrid.service.TaskDeleter;
import java.util.List;
import javax.inject.Inject;
import org.tasks.BuildConfig;
@ -43,16 +46,24 @@ import org.tasks.analytics.Tracking.Events;
import org.tasks.billing.BillingClient;
import org.tasks.billing.Inventory;
import org.tasks.billing.PurchaseActivity;
import org.tasks.caldav.CaldavAccountSettingsActivity;
import org.tasks.data.CaldavAccount;
import org.tasks.data.CaldavDao;
import org.tasks.data.GoogleTaskAccount;
import org.tasks.data.GoogleTaskListDao;
import org.tasks.dialogs.DialogBuilder;
import org.tasks.dialogs.NativeSeekBarDialog;
import org.tasks.drive.DriveLoginActivity;
import org.tasks.etesync.EteSyncAccountSettingsActivity;
import org.tasks.files.FileHelper;
import org.tasks.gtasks.GoogleAccountManager;
import org.tasks.gtasks.PlayServices;
import org.tasks.injection.ActivityComponent;
import org.tasks.injection.InjectingPreferenceActivity;
import org.tasks.jobs.WorkManager;
import org.tasks.locale.Locale;
import org.tasks.locale.LocalePickerDialog;
import org.tasks.sync.AddAccountDialog;
import org.tasks.themes.ThemeAccent;
import org.tasks.themes.ThemeBase;
import org.tasks.themes.ThemeCache;
@ -75,11 +86,13 @@ public class BasicPreferences extends InjectingPreferenceActivity
private static final int REQUEST_CODE_BACKUP_DIR = 10005;
private static final int REQUEST_PICKER = 10006;
private static final int REQUEST_LAUNCHER_PICKER = 10007;
private static final int RC_DRIVE_BACKUP = 10008;
private static final int REQUEST_DRIVE_BACKUP = 10008;
private static final int REQUEST_DEFAULT_LIST = 10009;
private static final int REQUEST_ROW_PADDING = 10010;
private static final int REQUEST_FONT_SIZE = 10011;
private static final int REQUEST_CUSTOMIZE = 10012;
public static final int REQUEST_CALDAV_SETTINGS = 10013;
public static final int REQUEST_GOOGLE_TASKS = 10014;
@Inject Tracker tracker;
@Inject Preferences preferences;
@ -97,6 +110,10 @@ public class BasicPreferences extends InjectingPreferenceActivity
@Inject BillingClient billingClient;
@Inject DefaultFilterProvider defaultFilterProvider;
@Inject LocalBroadcastManager localBroadcastManager;
@Inject WorkManager workManager;
@Inject GoogleTaskListDao googleTaskListDao;
@Inject CaldavDao caldavDao;
@Inject TaskDeleter taskDeleter;
@Override
public void onCreate(Bundle savedInstanceState) {
@ -266,7 +283,7 @@ public class BasicPreferences extends InjectingPreferenceActivity
if ((Boolean) newValue) {
if (permissionRequestor.requestAccountPermissions()) {
requestLogin();
requestGoogleDriveLogin();
}
return false;
} else {
@ -314,6 +331,37 @@ public class BasicPreferences extends InjectingPreferenceActivity
return false;
});
findPreference(getString(R.string.p_background_sync_unmetered_only))
.setOnPreferenceChangeListener(
(preference, o) -> {
workManager.updateBackgroundSync(null, null, (Boolean) o);
return true;
});
findPreference(getString(R.string.p_background_sync))
.setOnPreferenceChangeListener(
(preference, o) -> {
workManager.updateBackgroundSync(null, (Boolean) o, null);
return true;
});
CheckBoxPreference positionHack =
(CheckBoxPreference) findPreference(R.string.google_tasks_position_hack);
positionHack.setChecked(preferences.isPositionHackEnabled());
positionHack.setOnPreferenceChangeListener(
(preference, newValue) -> {
if (newValue == null) {
return false;
}
preferences.setLong(
R.string.p_google_tasks_position_hack, ((Boolean) newValue) ? now() : 0);
return true;
});
findPreference(R.string.add_account)
.setOnPreferenceClickListener(
preference -> {
AddAccountDialog.showAddAccountDialog(BasicPreferences.this, dialogBuilder);
return false;
});
findPreference(R.string.changelog)
.setSummary(getString(R.string.version_string, BuildConfig.VERSION_NAME));
@ -340,8 +388,14 @@ public class BasicPreferences extends InjectingPreferenceActivity
//noinspection ConstantConditions
if (!BuildConfig.FLAVOR.equals("googleplay")) {
((PreferenceScreen) findPreference(getString(R.string.preference_screen)))
.removePreference(findPreference(getString(R.string.TEA_control_location)));
removeGroup(R.string.TEA_control_location);
}
}
private void removeGroup(int key) {
Preference preference = findPreference(key);
if (preference != null) {
((PreferenceScreen) findPreference(R.string.preference_screen)).removePreference(preference);
}
}
@ -428,6 +482,102 @@ public class BasicPreferences extends InjectingPreferenceActivity
});
int placeProvider = getPlaceProvider();
placeProviderPreference.setSummary(choices.get(placeProvider));
PreferenceCategory synchronizationPreferences =
(PreferenceCategory) findPreference(R.string.synchronization);
synchronizationPreferences.removeAll();
boolean hasGoogleAccounts = addGoogleTasksAccounts(synchronizationPreferences);
boolean hasCaldavAccounts = addCaldavAccounts(synchronizationPreferences);
if (!hasGoogleAccounts) {
removeGroup(R.string.gtasks_GPr_header);
}
if (!(hasGoogleAccounts || hasCaldavAccounts)) {
removeGroup(R.string.sync_SPr_interval_title);
}
}
private boolean addGoogleTasksAccounts(PreferenceCategory category) {
List<GoogleTaskAccount> accounts = googleTaskListDao.getAccounts();
for (GoogleTaskAccount googleTaskAccount : accounts) {
String account = googleTaskAccount.getAccount();
Preference preference = new Preference(this);
preference.setTitle(account);
String error = googleTaskAccount.getError();
if (Strings.isNullOrEmpty(error)) {
preference.setSummary(R.string.gtasks_GPr_header);
} else {
preference.setSummary(error);
}
preference.setOnPreferenceClickListener(
p -> {
dialogBuilder
.newDialog(account)
.setItems(
asList(getString(R.string.reinitialize_account), getString(R.string.logout)),
(dialog, which) -> {
if (which == 0) {
startActivityForResult(
new Intent(this, GtasksLoginActivity.class),
BasicPreferences.REQUEST_GOOGLE_TASKS);
} else {
logoutConfirmation(googleTaskAccount);
}
})
.showThemedListView();
return false;
});
category.addPreference(preference);
}
return !accounts.isEmpty();
}
private boolean addCaldavAccounts(PreferenceCategory category) {
List<CaldavAccount> accounts = caldavDao.getAccounts();
for (CaldavAccount account : accounts) {
Preference preference = new Preference(this);
preference.setTitle(account.getName());
String error = account.getError();
if (Strings.isNullOrEmpty(error)) {
preference.setSummary(
account.isCaldavAccount() ? R.string.caldav : R.string.etesync);
} else {
preference.setSummary(error);
}
preference.setOnPreferenceClickListener(
p -> {
Intent intent =
new Intent(
this,
account.isCaldavAccount()
? CaldavAccountSettingsActivity.class
: EteSyncAccountSettingsActivity.class);
intent.putExtra(CaldavAccountSettingsActivity.EXTRA_CALDAV_DATA, account);
startActivityForResult(intent, REQUEST_CALDAV_SETTINGS);
return false;
});
category.addPreference(preference);
}
return !accounts.isEmpty();
}
private void logoutConfirmation(GoogleTaskAccount account) {
String name = account.getAccount();
AlertDialog alertDialog =
dialogBuilder
.newDialog()
.setMessage(R.string.logout_warning, name)
.setPositiveButton(
R.string.logout,
(dialog, which) -> {
taskDeleter.delete(account);
restart();
})
.setNegativeButton(android.R.string.cancel, null)
.create();
alertDialog.setCanceledOnTouchOutside(false);
alertDialog.setCancelable(false);
alertDialog.show();
}
private int getPlaceProvider() {
@ -442,8 +592,8 @@ public class BasicPreferences extends InjectingPreferenceActivity
: 0;
}
private void requestLogin() {
startActivityForResult(new Intent(this, DriveLoginActivity.class), RC_DRIVE_BACKUP);
private void requestGoogleDriveLogin() {
startActivityForResult(new Intent(this, DriveLoginActivity.class), REQUEST_DRIVE_BACKUP);
}
private void setupActivity(int key, final Class<?> target) {
@ -460,7 +610,7 @@ public class BasicPreferences extends InjectingPreferenceActivity
int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if (requestCode == PermissionRequestor.REQUEST_GOOGLE_ACCOUNTS) {
if (verifyPermissions(grantResults)) {
requestLogin();
requestGoogleDriveLogin();
}
} else {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
@ -529,7 +679,7 @@ public class BasicPreferences extends InjectingPreferenceActivity
forceRestart();
}
}
} else if (requestCode == RC_DRIVE_BACKUP) {
} else if (requestCode == REQUEST_DRIVE_BACKUP) {
boolean success = resultCode == RESULT_OK;
((CheckBoxPreference) findPreference(R.string.p_google_drive_backup)).setChecked(success);
if (!success && data != null) {
@ -546,6 +696,18 @@ public class BasicPreferences extends InjectingPreferenceActivity
if (resultCode == RESULT_OK) {
forceRestart();
}
} else if (requestCode == REQUEST_CALDAV_SETTINGS) {
if (resultCode == RESULT_OK) {
workManager.updateBackgroundSync();
restart();
}
} else if (requestCode == REQUEST_GOOGLE_TASKS) {
if (resultCode == RESULT_OK) {
workManager.updateBackgroundSync();
restart();
} else if (data != null) {
toaster.longToast(data.getStringExtra(GtasksLoginActivity.EXTRA_ERROR));
}
} else {
super.onActivityResult(requestCode, resultCode, data);
}

@ -207,7 +207,6 @@ public class Preferences {
PreferenceManager.setDefaultValues(context, R.xml.preferences, true);
PreferenceManager.setDefaultValues(context, R.xml.preferences_date_time, true);
PreferenceManager.setDefaultValues(context, R.xml.preferences_defaults, true);
PreferenceManager.setDefaultValues(context, R.xml.preferences_synchronization, true);
PreferenceManager.setDefaultValues(context, R.xml.preferences_misc, true);
PreferenceManager.setDefaultValues(context, R.xml.preferences_reminders, true);

@ -0,0 +1,82 @@
package org.tasks.sync;
import android.app.Activity;
import android.content.Intent;
import android.content.res.TypedArray;
import android.net.Uri;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.todoroo.astrid.gtasks.auth.GtasksLoginActivity;
import org.tasks.R;
import org.tasks.caldav.CaldavAccountSettingsActivity;
import org.tasks.dialogs.DialogBuilder;
import org.tasks.etesync.EteSyncAccountSettingsActivity;
import org.tasks.preferences.BasicPreferences;
public class AddAccountDialog {
public static void showAddAccountDialog(Activity activity, DialogBuilder dialogBuilder) {
String[] services = activity.getResources().getStringArray(R.array.synchronization_services);
String[] descriptions =
activity.getResources().getStringArray(R.array.synchronization_services_description);
TypedArray typedArray =
activity.getResources().obtainTypedArray(R.array.synchronization_services_icons);
int[] icons = new int[typedArray.length()];
for (int i = 0; i < icons.length; i++) {
icons[i] = typedArray.getResourceId(i, 0);
}
typedArray.recycle();
ArrayAdapter<String> adapter =
new ArrayAdapter<String>(
activity, R.layout.simple_list_item_2_themed, R.id.text1, services) {
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
View view = super.getView(position, convertView, parent);
view.<TextView>findViewById(R.id.text1).setText(services[position]);
view.<TextView>findViewById(R.id.text2).setText(descriptions[position]);
view.<ImageView>findViewById(R.id.image_view).setImageResource(icons[position]);
return view;
}
};
dialogBuilder
.newDialog()
.setTitle(R.string.choose_synchronization_service)
.setSingleChoiceItems(
adapter,
-1,
(dialog, which) -> {
switch (which) {
case 0:
activity.startActivityForResult(
new Intent(activity, GtasksLoginActivity.class),
BasicPreferences.REQUEST_GOOGLE_TASKS);
break;
case 1:
activity.startActivityForResult(
new Intent(activity, CaldavAccountSettingsActivity.class),
BasicPreferences.REQUEST_CALDAV_SETTINGS);
break;
case 2:
activity.startActivityForResult(
new Intent(activity, EteSyncAccountSettingsActivity.class),
BasicPreferences.REQUEST_CALDAV_SETTINGS);
break;
}
dialog.dismiss();
})
.setNeutralButton(
R.string.help,
(dialog, which) ->
activity.startActivity(
new Intent(
Intent.ACTION_VIEW, Uri.parse(activity.getString(R.string.help_url_sync)))))
.setNegativeButton(android.R.string.cancel, null)
.showThemedListView();
}
}

@ -1,326 +0,0 @@
/*
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
*/
package org.tasks.sync;
import static com.todoroo.andlib.utility.DateUtilities.now;
import static java.util.Arrays.asList;
import static org.tasks.PermissionUtil.verifyPermissions;
import android.content.Intent;
import android.os.Bundle;
import android.preference.CheckBoxPreference;
import android.preference.Preference;
import android.preference.PreferenceCategory;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import com.google.common.base.Strings;
import com.todoroo.astrid.gtasks.auth.GtasksLoginActivity;
import com.todoroo.astrid.service.TaskDeleter;
import javax.inject.Inject;
import org.tasks.R;
import org.tasks.analytics.Tracker;
import org.tasks.analytics.Tracking;
import org.tasks.billing.Inventory;
import org.tasks.billing.PurchaseActivity;
import org.tasks.caldav.CaldavAccountSettingsActivity;
import org.tasks.etesync.EteSyncAccountSettingsActivity;
import org.tasks.data.CaldavAccount;
import org.tasks.data.CaldavDao;
import org.tasks.data.GoogleTaskAccount;
import org.tasks.data.GoogleTaskDao;
import org.tasks.data.GoogleTaskListDao;
import org.tasks.dialogs.DialogBuilder;
import org.tasks.gtasks.GoogleAccountManager;
import org.tasks.injection.ActivityComponent;
import org.tasks.injection.InjectingPreferenceActivity;
import org.tasks.jobs.WorkManager;
import org.tasks.preferences.ActivityPermissionRequestor;
import org.tasks.preferences.PermissionChecker;
import org.tasks.preferences.PermissionRequestor;
import org.tasks.preferences.Preferences;
import org.tasks.ui.Toaster;
public class SynchronizationPreferences extends InjectingPreferenceActivity {
private static final int REQUEST_LOGIN = 0;
private static final int REQUEST_CALDAV_SETTINGS = 101;
private static final int REQUEST_CALDAV_SUBSCRIBE = 102;
private static final int REQUEST_GOOGLE_TASKS_SUBSCRIBE = 103;
private static final int REQUEST_ETESYNC_SETTINGS = 104;
private static final int REQUEST_ETESYNC_SUBSCRIBE = 105;
@Inject ActivityPermissionRequestor permissionRequestor;
@Inject PermissionChecker permissionChecker;
@Inject Tracker tracker;
@Inject DialogBuilder dialogBuilder;
@Inject SyncAdapters syncAdapters;
@Inject GoogleTaskDao googleTaskDao;
@Inject GoogleTaskListDao googleTaskListDao;
@Inject GoogleAccountManager googleAccountManager;
@Inject Preferences preferences;
@Inject WorkManager workManager;
@Inject CaldavDao caldavDao;
@Inject Inventory inventory;
@Inject TaskDeleter taskDeleter;
@Inject Toaster toaster;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setTitle(R.string.synchronization);
addPreferencesFromResource(R.xml.preferences_synchronization);
findPreference(getString(R.string.p_background_sync_unmetered_only))
.setOnPreferenceChangeListener(
(preference, o) -> {
workManager.updateBackgroundSync(null, null, (Boolean) o);
return true;
});
findPreference(getString(R.string.p_background_sync))
.setOnPreferenceChangeListener(
(preference, o) -> {
workManager.updateBackgroundSync(null, (Boolean) o, null);
return true;
});
Preference addGoogleTaskAccount = findPreference(R.string.p_add_google_task_account);
if (inventory.hasPro() || googleTaskListDao.getAccounts().isEmpty()) {
addGoogleTaskAccount.setOnPreferenceClickListener(
preference -> {
addGoogleTaskAccount();
return false;
});
} else {
addGoogleTaskAccount.setSummary(R.string.requires_pro_subscription);
addGoogleTaskAccount.setOnPreferenceClickListener(
preference -> {
startActivityForResult(
new Intent(this, PurchaseActivity.class), REQUEST_GOOGLE_TASKS_SUBSCRIBE);
return false;
});
}
CheckBoxPreference positionHack =
(CheckBoxPreference) findPreference(R.string.google_tasks_position_hack);
positionHack.setChecked(preferences.isPositionHackEnabled());
positionHack.setOnPreferenceChangeListener(
(preference, newValue) -> {
if (newValue == null) {
return false;
}
preferences.setLong(
R.string.p_google_tasks_position_hack, ((Boolean) newValue) ? now() : 0);
return true;
});
Preference addCaldavAccount = findPreference(R.string.p_add_caldav_account);
if (inventory.hasPro()) {
addCaldavAccount.setOnPreferenceClickListener(
preference -> {
addCaldavAccount();
return false;
});
} else {
addCaldavAccount.setSummary(R.string.requires_pro_subscription);
addCaldavAccount.setOnPreferenceClickListener(
preference -> {
startActivityForResult(
new Intent(this, PurchaseActivity.class), REQUEST_CALDAV_SUBSCRIBE);
return false;
});
}
Preference addEteSyncAccount = findPreference(R.string.p_add_etesync_account);
if (inventory.hasPro()) {
addEteSyncAccount.setOnPreferenceClickListener(
preference -> {
addEteSyncAccount();
return false;
});
} else {
addEteSyncAccount.setSummary(R.string.requires_pro_subscription);
addEteSyncAccount.setOnPreferenceClickListener(
preference -> {
startActivityForResult(
new Intent(this, PurchaseActivity.class), REQUEST_ETESYNC_SUBSCRIBE);
return false;
});
}
}
private void logoutConfirmation(GoogleTaskAccount account) {
String name = account.getAccount();
AlertDialog alertDialog =
dialogBuilder
.newDialog()
.setMessage(R.string.logout_warning, name)
.setPositiveButton(
R.string.logout,
(dialog, which) -> {
taskDeleter.delete(account);
restart();
})
.setNegativeButton(android.R.string.cancel, null)
.create();
alertDialog.setCanceledOnTouchOutside(false);
alertDialog.setCancelable(false);
alertDialog.show();
}
private void requestLogin() {
startActivityForResult(new Intent(this, GtasksLoginActivity.class), REQUEST_LOGIN);
}
@Override
protected void onResume() {
super.onResume();
addGoogleTasksAccounts();
addCaldavAccounts();
}
private void addGoogleTasksAccounts() {
PreferenceCategory googleTaskPreferences =
(PreferenceCategory) findPreference(getString(R.string.gtasks_GPr_header));
googleTaskPreferences.removeAll();
for (GoogleTaskAccount googleTaskAccount : googleTaskListDao.getAccounts()) {
String account = googleTaskAccount.getAccount();
Preference accountPreferences = new Preference(this);
accountPreferences.setTitle(account);
accountPreferences.setSummary(googleTaskAccount.getError());
accountPreferences.setOnPreferenceClickListener(
preference -> {
dialogBuilder
.newDialog(account)
.setItems(
asList(getString(R.string.reinitialize_account), getString(R.string.logout)),
(dialog, which) -> {
if (which == 0) {
addGoogleTaskAccount();
} else {
logoutConfirmation(googleTaskAccount);
}
})
.showThemedListView();
return false;
});
googleTaskPreferences.addPreference(accountPreferences);
}
}
private void addGoogleTaskAccount() {
if (permissionRequestor.requestAccountPermissions()) {
requestLogin();
}
}
private void addCaldavAccounts() {
PreferenceCategory caldavPreferences =
(PreferenceCategory) findPreference(getString(R.string.CalDAV));
PreferenceCategory eteSyncPreferences =
(PreferenceCategory) findPreference(R.string.etesync);
caldavPreferences.removeAll();
eteSyncPreferences.removeAll();
for (CaldavAccount caldavAccount : caldavDao.getAccounts()) {
Preference accountPreferences = new Preference(this);
accountPreferences.setTitle(caldavAccount.getName());
accountPreferences.setSummary(caldavAccount.getError());
if (caldavAccount.isCaldavAccount()) {
accountPreferences.setOnPreferenceClickListener(
preference -> {
Intent intent = new Intent(this, CaldavAccountSettingsActivity.class);
intent.putExtra(CaldavAccountSettingsActivity.EXTRA_CALDAV_DATA, caldavAccount);
startActivityForResult(intent, REQUEST_CALDAV_SETTINGS);
return false;
});
caldavPreferences.addPreference(accountPreferences);
} else if (caldavAccount.isEteSyncAccount()) {
accountPreferences.setOnPreferenceClickListener(
preference -> {
Intent intent = new Intent(this, EteSyncAccountSettingsActivity.class);
intent.putExtra(CaldavAccountSettingsActivity.EXTRA_CALDAV_DATA, caldavAccount);
startActivityForResult(intent, REQUEST_ETESYNC_SETTINGS);
return false;
}
);
eteSyncPreferences.addPreference(accountPreferences);
}
}
}
private void addCaldavAccount() {
startActivityForResult(
new Intent(this, CaldavAccountSettingsActivity.class), REQUEST_CALDAV_SETTINGS);
}
private void addEteSyncAccount() {
startActivityForResult(
new Intent(this, EteSyncAccountSettingsActivity.class), REQUEST_ETESYNC_SETTINGS);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_LOGIN) {
boolean enabled = resultCode == RESULT_OK;
if (enabled) {
tracker.reportEvent(Tracking.Events.GTASK_ENABLED);
workManager.updateBackgroundSync();
restart();
} else if (data != null) {
toaster.longToast(data.getStringExtra(GtasksLoginActivity.EXTRA_ERROR));
}
} else if (requestCode == REQUEST_CALDAV_SETTINGS || requestCode == REQUEST_ETESYNC_SETTINGS) {
if (resultCode == RESULT_OK) {
workManager.updateBackgroundSync();
restart();
}
} else if (requestCode == REQUEST_CALDAV_SUBSCRIBE) {
if (inventory.hasPro()) {
addCaldavAccount();
}
} else if (requestCode == REQUEST_GOOGLE_TASKS_SUBSCRIBE) {
if (inventory.hasPro()) {
requestLogin();
}
} else if (requestCode == REQUEST_ETESYNC_SUBSCRIBE) {
if (inventory.hasPro()) {
addEteSyncAccount();
}
} else {
super.onActivityResult(requestCode, resultCode, data);
}
}
private void restart() {
Intent intent = getIntent();
finish();
startActivity(intent);
}
@Override
public void onRequestPermissionsResult(
int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if (requestCode == PermissionRequestor.REQUEST_GOOGLE_ACCOUNTS) {
if (verifyPermissions(grantResults)) {
requestLogin();
}
} else {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
@Override
protected String getHelpUrl() {
return "http://tasks.org/subscribe";
}
@Override
public void inject(ActivityComponent component) {
component.inject(this);
}
}

@ -0,0 +1,13 @@
<vector android:autoMirrored="true" android:height="24dp"
android:viewportHeight="192" android:viewportWidth="192"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillAlpha="1" android:fillColor="#ffc107"
android:pathData="M160,67.52V30H122.48L96,3.52 69.52,30H32V67.52L5.52,94 32,120.48V158H69.52L96,184.48 122.48,158H160V120.48L186.48,94Z" android:strokeWidth="8"/>
<path android:fillAlpha="1" android:fillColor="#ffd740"
android:fillType="nonZero"
android:pathData="M79.939,93.956a16.102,16.103 0,1 0,32.204 0a16.102,16.103 0,1 0,-32.204 0z"
android:strokeAlpha="1" android:strokeColor="#ffd740"
android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="60.96912003"/>
<path android:fillAlpha="1" android:fillColor="#448aff"
android:pathData="M96,47.47L96,30.02L72.705,53.286 96,76.553v-17.45c19.277,0 34.942,15.647 34.942,34.9 0,5.875 -1.456,11.459 -4.077,16.287l8.503,8.492c4.543,-7.154 7.221,-15.647 7.221,-24.779 0,-25.709 -20.849,-46.533 -46.59,-46.533zM96,128.902c-19.277,0 -34.942,-15.647 -34.942,-34.9 0,-5.875 1.456,-11.459 4.077,-16.287l-8.503,-8.492c-4.543,7.154 -7.221,15.647 -7.221,24.779 0,25.709 20.849,46.533 46.59,46.533v17.45L119.295,134.719 96,111.452Z" android:strokeWidth="5.82016563"/>
</vector>

@ -0,0 +1,8 @@
<vector android:autoMirrored="true" android:height="24dp"
android:viewportHeight="544.3" android:viewportWidth="533.5"
android:width="23.523792dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#4285F4" android:pathData="M533.5,278.4c0,-18.5 -1.5,-37.1 -4.7,-55.3H272.1v104.8h147c-6.1,33.8 -25.7,63.7 -54.4,82.7v68h87.7C503.9,431.2 533.5,361.2 533.5,278.4z"/>
<path android:fillColor="#34A853" android:pathData="M272.1,544.3c73.4,0 135.3,-24.1 180.4,-65.7l-87.7,-68c-24.4,16.6 -55.9,26 -92.6,26c-71,0 -131.2,-47.9 -152.8,-112.3H28.9v70.1C75.1,486.3 169.2,544.3 272.1,544.3z"/>
<path android:fillColor="#FBBC04" android:pathData="M119.3,324.3c-11.4,-33.8 -11.4,-70.4 0,-104.2V150H28.9c-38.6,76.9 -38.6,167.5 0,244.4L119.3,324.3z"/>
<path android:fillColor="#EA4335" android:pathData="M272.1,107.7c38.8,-0.6 76.3,14 104.4,40.8l0,0l77.7,-77.7C405,24.6 339.7,-0.8 272.1,0C169.2,0 75.1,58 28.9,150l90.4,70.1C140.8,155.6 201.1,107.7 272.1,107.7z"/>
</vector>

@ -0,0 +1,8 @@
<vector android:autoMirrored="true" android:height="35.4dp"
android:viewportHeight="77.17024" android:viewportWidth="104.535675"
android:width="47.95324dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#000000"
android:pathData="M53.542,1.209c-4.9,1.7 -9.9,4.9 -12.9,8.2 -1.8,1.9 -0.9,1.5 2.9,-1.4 9.7,-7.3 18.6,-7.9 24.7,-1.8 3.9,3.9 5.4,9.1 5.2,17.1 -0.2,5.9 -0.2,5.9 -0.5,1 -0.6,-8.8 -0.9,-9.5 -4.9,-9.5 -2,-0 -3.7,0.6 -4,1.3 -0.3,0.8 2.2,10.3 5.5,21.3 3.2,10.9 6.4,21.8 7,24.1l1.2,4.3 6.9,-0 6.9,-0 -0.5,-3.2c-0.5,-3.2 0.8,-8.1 10.2,-36.8 3.6,-11.1 3.9,-12.4 2.6,-11.6 -0.5,0.3 -2.7,0.6 -5.1,0.7 -3.6,0.3 -4.2,0.7 -4.7,2.8 -0.4,1.5 -2.2,7.9 -4,14.4 -1.9,6.6 -3.4,12.5 -3.4,13.2 0,0.8 -0.4,1.6 -0.9,1.9 -0.5,0.3 -2.5,-5.8 -4.4,-13.6 -2,-8.1 -3.7,-13.4 -4,-12.3 -0.3,1.3 -0.5,1 -0.6,-1.2 -0.2,-4.6 -3,-12.4 -5.5,-15.2 -4.3,-4.8 -10.9,-6.2 -17.7,-3.7zM76.242,32.409c-0.5,2.4 -1.2,3.4 -2.6,3.4 -2.4,-0 -2.9,-0.9 -1.9,-4l0.7,-2.5 0.1,2.7c0.2,5.3 3,2.6 3.2,-3 0,-1.5 0.3,-2.1 0.6,-1.4 0.3,0.7 0.2,2.9 -0.1,4.8z" android:strokeColor="#00000000"/>
<path android:fillColor="#000000"
android:pathData="M13.042,13.509c-0.6,0.4 -1.9,5 -2.8,10.2 -1.9,9.8 -8.8,37.4 -10,40.3 -0.7,1.7 0,1.8 9.3,1.8l10.1,-0 0,-2.8c0.1,-2 0.5,-1.4 2,2.8 4.6,13.3 16.7,15.1 30.8,4.5 3.3,-2.5 7.5,-6.7 9.3,-9.5 3.7,-5.5 4.1,-5.7 5.9,-3.5 0.9,1 0.9,1.5 0.1,1.5 -0.6,-0 -1.1,-0.6 -1.1,-1.3 -0.1,-1.9 -5,4.6 -5,6.5 0,1.6 1,1.8 7.5,1.8l7.6,-0 -1.5,-2.7c-1.3,-2.8 -9.9,-29.8 -13.2,-42.1l-1.7,-6.3 -6.8,0.2 -6.7,0.2 0.5,3.8c0.6,4 -1,5.5 -2.1,2.1 -0.4,-1 -2,-3.1 -3.6,-4.7 -3,-2.8 -3.4,-2.9 -15.3,-3.3 -6.7,-0.1 -12.7,0.1 -13.3,0.5zM31.342,23.009c1.8,1.6 2.3,3.2 2.3,6.8 0,9.2 -5.4,24.8 -9,25.7 -2.2,0.6 -2.5,2.8 -1,6.7 0.8,2.3 1.2,2.5 3.6,1.6 1.5,-0.6 4,-2 5.6,-3.2l3,-2.1 -1.6,3.1c-0.9,1.7 -1.6,3.3 -1.6,3.7 0,0.3 2.5,0.5 5.5,0.5 3.7,-0 5.5,-0.4 5.5,-1.3 0,-0.6 0.5,-2.9 1.1,-5l1,-3.9 7.2,0.2c9.2,0.3 9.2,0.3 7.8,-1.4 -0.9,-1.1 -0.4,-1.8 2.4,-3.5 4.1,-2.4 4.5,-2.5 4.5,-1.1 0,0.6 -0.3,0.9 -0.7,0.8 -1.5,-0.4 -5.2,2.3 -4.8,3.5 0.8,2.1 -5.9,10 -11.7,14 -11.7,8.1 -21.8,6.6 -26.9,-3.9 -3.8,-8 -2.6,-21.4 3.2,-34.3 1.6,-3.5 2.8,-6.6 2.6,-6.8 -0.8,-0.7 -6.8,14 -8.2,20 -0.8,3.4 -1.5,8.7 -1.6,11.7 0,3.3 -0.3,4.8 -0.8,3.7 -0.4,-1 -1.1,-1.9 -1.6,-2 -1.3,-0.3 -1.1,-1.5 3.2,-20 3.5,-15.1 3.7,-15.7 6.2,-15.7 1.3,-0 3.5,1 4.8,2.2zM55.242,40.409c1.1,3.5 1.8,6.6 1.6,6.9 -0.9,0.9 -7.1,0.5 -7.6,-0.4 -0.7,-1.1 2.6,-14.2 3.4,-13.5 0.2,0.3 1.4,3.4 2.6,7z" android:strokeColor="#00000000"/>
</vector>

@ -1,110 +1,119 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/root_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:descendantFocusability="beforeDescendants"
android:focusable="true"
android:focusableInTouchMode="true"
android:orientation="vertical">
<include
android:id="@+id/toolbar"
layout="@layout/toolbar" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include
android:id="@+id/progress_bar"
layout="@layout/progress_view" />
<include
android:id="@+id/toolbar"
layout="@layout/toolbar" />
<ScrollView
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<include
android:id="@+id/progress_bar"
layout="@layout/progress_view" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:descendantFocusability="beforeDescendants"
android:focusableInTouchMode="true"
android:orientation="vertical">
<ScrollView
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/name_layout"
style="@style/TagSettingsRow">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/name"
android:imeOptions="flagNoExtractUi"
android:inputType="textCapSentences|textAutoCorrect"/>
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/url_layout"
style="@style/TagSettingsRow">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/url"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/url"
android:imeOptions="flagNoExtractUi"/>
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/user_layout"
style="@style/TagSettingsRow">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/user"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/user"
android:imeOptions="flagNoExtractUi"/>
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/password_layout"
style="@style/TagSettingsRow"
app:passwordToggleEnabled="true">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/password"
android:imeOptions="flagNoExtractUi"
android:inputType="textPassword"/>
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/encryption_password_layout"
style="@style/TagSettingsRow"
android:visibility="gone"
app:passwordToggleEnabled="true">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/encryption_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/encryption_password"
android:imeOptions="flagNoExtractUi"
android:inputType="textPassword"/>
</com.google.android.material.textfield.TextInputLayout>
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/repeat"
style="@style/TagSettingsRow"
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/caldav_account_repeating_tasks"/>
android:descendantFocusability="beforeDescendants"
android:focusableInTouchMode="true"
android:orientation="vertical">
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/name_layout"
style="@style/TagSettingsRow">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/display_name"
android:imeOptions="flagNoExtractUi"
android:inputType="textCapSentences|textAutoCorrect" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/url_layout"
style="@style/TagSettingsRow">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/url"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/url"
android:imeOptions="flagNoExtractUi" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/user_layout"
style="@style/TagSettingsRow">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/user"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/user"
android:imeOptions="flagNoExtractUi" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/password_layout"
style="@style/TagSettingsRow"
app:passwordToggleEnabled="true">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/password"
android:imeOptions="flagNoExtractUi"
android:inputType="textPassword" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/encryption_password_layout"
style="@style/TagSettingsRow"
android:visibility="gone"
app:passwordToggleEnabled="true">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/encryption_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/encryption_password"
android:imeOptions="flagNoExtractUi"
android:inputType="textPassword" />
</com.google.android.material.textfield.TextInputLayout>
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/repeat"
style="@style/TagSettingsRow"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/caldav_account_repeating_tasks" />
</LinearLayout>
</LinearLayout>
</ScrollView>
</ScrollView>
</LinearLayout>
</LinearLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

@ -0,0 +1,57 @@
<?xml version="1.0" encoding="utf-8"?><!-- Copyright (C) 2006 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<TwoLineListItem xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:minHeight="?attr/listPreferredItemHeight"
android:mode="twoLine"
android:paddingStart="@dimen/keyline_first"
android:paddingLeft="@dimen/keyline_first"
android:paddingTop="@dimen/list_item_spacing"
android:paddingEnd="@dimen/keyline_first"
android:paddingRight="@dimen/keyline_first"
android:paddingBottom="@dimen/list_item_spacing">
<ImageView
android:id="@+id/image_view"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_alignParentStart="true"
android:layout_alignParentLeft="true"
android:layout_marginEnd="@dimen/keyline_first"
android:layout_marginRight="@dimen/keyline_first"
android:src="@drawable/ic_etesync" />
<TextView
android:id="@id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_toEndOf="@id/image_view"
android:layout_toRightOf="@id/image_view"
android:textAppearance="?attr/textAppearanceListItem" />
<TextView
android:id="@id/text2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/text1"
android:layout_alignStart="@id/text1"
android:layout_alignLeft="@id/text1"
android:textAppearance="?attr/textAppearanceListItemSecondary" />
</TwoLineListItem>

@ -224,4 +224,22 @@
<item>3</item>
</string-array>
<string-array name="synchronization_services">
<item>@string/gtasks_GPr_header</item>
<item>@string/caldav</item>
<item>@string/etesync</item>
</string-array>
<string-array name="synchronization_services_description">
<item>@string/google_tasks_selection_description</item>
<item>@string/caldav_selection_description</item>
<item>@string/etesync_selection_description</item>
</string-array>
<array name="synchronization_services_icons">
<item>@drawable/ic_google</item>
<item>@drawable/ic_webdav_logo</item>
<item>@drawable/ic_etesync</item>
</array>
</resources>

@ -42,5 +42,5 @@
<dimen name="chip_text_padding">4dp</dimen>
<dimen name="icon_picker_size">48dp</dimen>
<dimen name="list_item_spacing">8dp</dimen>
</resources>

@ -9,6 +9,7 @@
<string name="caldav">CalDAV</string>
<string name="etesync">EteSync</string>
<string name="etesync_url">https://api.etesync.com</string>
<string name="help_url_sync">https://tasks.org/sync</string>
<string name="p_date_shortcut_morning">date_shortcut_morning</string>
<string name="p_date_shortcut_afternoon">date_shortcut_afternoon</string>
@ -304,9 +305,6 @@
<string name="p_map_provider">map_provider</string>
<string name="p_place_provider">place_provider</string>
<string name="preference_screen">preference_screen</string>
<string name="p_add_google_task_account">add_google_task_account</string>
<string name="p_add_caldav_account">add_caldav_account</string>
<string name="p_add_etesync_account">add_etesync_account</string>
<string name="p_google_tasks_add_to_top">google_tasks_add_to_top</string>
<string name="p_google_tasks_position_hack">google_tasks_position_hack</string>
<string name="google_tasks_position_hack">Custom order synchronization fix</string>

@ -523,6 +523,7 @@ File %1$s contained %2$s.\n\n
<string name="pro_tasker_plugins">Tasker plugins</string>
<string name="pro_dashclock_extension">Dashclock extension</string>
<string name="requires_pro_subscription">Requires pro subscription</string>
<string name="this_feature_requires_a_subscription">This feature requires a subscription</string>
<string name="logout">Log out</string>
<string name="logout_warning">Log out of %s? All data for this account will be removed from your device</string>
<string name="cannot_access_account">Cannot access account</string>
@ -566,4 +567,8 @@ File %1$s contained %2$s.\n\n
<string name="show_subtasks_summary">Displaying subtasks will degrade app performance</string>
<string name="enter_tag_name">Enter tag name</string>
<string name="create_new_tag">Create \"%s\"</string>
<string name="choose_synchronization_service">Select a platform</string>
<string name="google_tasks_selection_description">Basic service that synchronizes with your Google account</string>
<string name="caldav_selection_description">Synchronization based on open internet standards</string>
<string name="etesync_selection_description">Open source, end-to-end encrypted synchronization</string>
</resources>

@ -98,6 +98,45 @@
</PreferenceCategory>
<PreferenceCategory
android:key="@string/synchronization"
android:title="@string/synchronization" />
<Preference
android:key="@string/add_account"
android:title="@string/add_account" />
<PreferenceCategory
android:title="@string/gtasks_GPr_header"
android:key="@string/gtasks_GPr_header">
<CheckBoxPreference
android:defaultValue="true"
android:key="@string/p_google_tasks_add_to_top"
android:title="@string/google_tasks_add_to_top"/>
<CheckBoxPreference
android:key="@string/google_tasks_position_hack"
android:title="@string/google_tasks_position_hack"
android:summary="@string/google_tasks_position_hack_summary" />
</PreferenceCategory>
<PreferenceCategory
android:title="@string/sync_SPr_interval_title"
android:key="@string/sync_SPr_interval_title">
<CheckBoxPreference
android:defaultValue="true"
android:key="@string/p_background_sync"
android:title="@string/enabled"/>
<CheckBoxPreference
android:defaultValue="false"
android:dependency="@string/p_background_sync"
android:key="@string/p_background_sync_unmetered_only"
android:title="@string/background_sync_unmetered_only"/>
</PreferenceCategory>
<PreferenceCategory
android:key="@string/settings_general"
android:title="@string/settings_general">
@ -112,14 +151,6 @@
android:targetPackage="@string/app_package"/>
</Preference>
<Preference
android:key="@string/synchronization"
android:title="@string/synchronization">
<intent
android:targetClass="org.tasks.sync.SynchronizationPreferences"
android:targetPackage="@string/app_package"/>
</Preference>
<Preference
android:key="@string/EPr_manage_header"
android:title="@string/EPr_manage_header"/>

@ -1,54 +0,0 @@
<?xml version="1.0" encoding="utf-8"?><!--
** Copyright (c) 2012 Todoroo Inc
**
** See the file "LICENSE" for the full license governing this code.
-->
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory
android:key="@string/gtasks_GPr_header"
android:title="@string/gtasks_GPr_header"/>
<Preference
android:key="@string/p_add_google_task_account"
android:title="@string/add_account"/>
<CheckBoxPreference
android:defaultValue="true"
android:key="@string/p_google_tasks_add_to_top"
android:title="@string/google_tasks_add_to_top"/>
<CheckBoxPreference
android:key="@string/google_tasks_position_hack"
android:title="@string/google_tasks_position_hack"
android:summary="@string/google_tasks_position_hack_summary" />
<PreferenceCategory
android:key="@string/CalDAV"
android:title="@string/CalDAV"/>
<Preference
android:key="@string/p_add_caldav_account"
android:title="@string/add_account"/>
<PreferenceCategory
android:key="@string/etesync"
android:title="@string/etesync" />
<Preference
android:key="@string/p_add_etesync_account"
android:title="@string/add_account"/>
<PreferenceCategory android:title="@string/sync_SPr_interval_title">
<CheckBoxPreference
android:defaultValue="true"
android:key="@string/p_background_sync"
android:title="@string/enabled"/>
<CheckBoxPreference
android:defaultValue="false"
android:dependency="@string/p_background_sync"
android:key="@string/p_background_sync_unmetered_only"
android:title="@string/background_sync_unmetered_only"/>
</PreferenceCategory>
</PreferenceScreen>
Loading…
Cancel
Save