mirror of https://github.com/tasks/tasks
Add CalDAVSettingsActivity
parent
2a54775927
commit
bb0f99f35a
@ -1,32 +0,0 @@
|
|||||||
package org.tasks.gtasks;
|
|
||||||
|
|
||||||
import com.todoroo.astrid.activity.TaskListFragment;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
public class SyncAdapterHelper {
|
|
||||||
@Inject
|
|
||||||
public SyncAdapterHelper() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean shouldShowBackgroundSyncWarning() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void checkPlayServices(TaskListFragment taskListFragment) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean initiateManualSync() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isEnabled() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void requestSynchronization() {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,42 @@
|
|||||||
|
package org.tasks.sync;
|
||||||
|
|
||||||
|
import android.content.ContentResolver;
|
||||||
|
|
||||||
|
import com.todoroo.astrid.activity.TaskListFragment;
|
||||||
|
|
||||||
|
import org.tasks.caldav.CaldavAccountManager;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
public class SyncAdapters {
|
||||||
|
private CaldavAccountManager caldavAccountManager;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public SyncAdapters(CaldavAccountManager caldavAccountManager) {
|
||||||
|
this.caldavAccountManager = caldavAccountManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean initiateManualSync() {
|
||||||
|
return caldavAccountManager.initiateManualSync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void requestSynchronization() {
|
||||||
|
caldavAccountManager.requestSynchronization();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isGoogleTaskSyncEnabled() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void checkPlayServices(TaskListFragment taskListFragment) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isMasterSyncEnabled() {
|
||||||
|
return ContentResolver.getMasterSyncAutomatically();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSyncEnabled() {
|
||||||
|
return caldavAccountManager.getAccounts().size() > 0;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,42 @@
|
|||||||
|
package org.tasks.sync;
|
||||||
|
|
||||||
|
import android.content.ContentResolver;
|
||||||
|
|
||||||
|
import com.todoroo.astrid.activity.TaskListFragment;
|
||||||
|
|
||||||
|
import org.tasks.caldav.CaldavAccountManager;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
public class SyncAdapters {
|
||||||
|
private CaldavAccountManager caldavAccountManager;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public SyncAdapters(CaldavAccountManager caldavAccountManager) {
|
||||||
|
this.caldavAccountManager = caldavAccountManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean initiateManualSync() {
|
||||||
|
return caldavAccountManager.initiateManualSync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void requestSynchronization() {
|
||||||
|
caldavAccountManager.requestSynchronization();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isGoogleTaskSyncEnabled() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void checkPlayServices(TaskListFragment taskListFragment) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isMasterSyncEnabled() {
|
||||||
|
return ContentResolver.getMasterSyncAutomatically();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSyncEnabled() {
|
||||||
|
return caldavAccountManager.getAccounts().size() > 0;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,51 @@
|
|||||||
|
package org.tasks.sync;
|
||||||
|
|
||||||
|
import android.content.ContentResolver;
|
||||||
|
|
||||||
|
import com.todoroo.astrid.activity.TaskListFragment;
|
||||||
|
|
||||||
|
import org.tasks.caldav.CaldavAccountManager;
|
||||||
|
import org.tasks.gtasks.GtaskSyncAdapterHelper;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
public class SyncAdapters {
|
||||||
|
|
||||||
|
private final GtaskSyncAdapterHelper gtaskSyncAdapterHelper;
|
||||||
|
private final CaldavAccountManager caldavAccountManager;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public SyncAdapters(GtaskSyncAdapterHelper gtaskSyncAdapterHelper, CaldavAccountManager caldavAccountManager) {
|
||||||
|
this.gtaskSyncAdapterHelper = gtaskSyncAdapterHelper;
|
||||||
|
this.caldavAccountManager = caldavAccountManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void requestSynchronization() {
|
||||||
|
gtaskSyncAdapterHelper.requestSynchronization();
|
||||||
|
caldavAccountManager.requestSynchronization();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean initiateManualSync() {
|
||||||
|
return gtaskSyncAdapterHelper.initiateManualSync() | caldavAccountManager.initiateManualSync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isMasterSyncEnabled() {
|
||||||
|
return ContentResolver.getMasterSyncAutomatically();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSyncEnabled() {
|
||||||
|
return isGoogleTaskSyncEnabled() || isCaldavSyncEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isGoogleTaskSyncEnabled() {
|
||||||
|
return gtaskSyncAdapterHelper.isSyncEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isCaldavSyncEnabled() {
|
||||||
|
return caldavAccountManager.getAccounts().size() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void checkPlayServices(TaskListFragment taskListFragment) {
|
||||||
|
gtaskSyncAdapterHelper.checkPlayServices(taskListFragment);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,65 @@
|
|||||||
|
package org.tasks.caldav;
|
||||||
|
|
||||||
|
import android.accounts.AccountManager;
|
||||||
|
import android.content.ContentResolver;
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
public class Account {
|
||||||
|
|
||||||
|
private static final String AUTHORITY = "org.tasks";
|
||||||
|
public static final String EXTRA_UUID = "uuid";
|
||||||
|
|
||||||
|
private AccountManager accountManager;
|
||||||
|
private android.accounts.Account account;
|
||||||
|
|
||||||
|
public Account(AccountManager accountManager, android.accounts.Account account) {
|
||||||
|
this.accountManager = accountManager;
|
||||||
|
this.account = account;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return account.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUuid() {
|
||||||
|
return accountManager.getUserData(account, EXTRA_UUID);
|
||||||
|
}
|
||||||
|
|
||||||
|
String getPassword() {
|
||||||
|
return accountManager.getPassword(account);
|
||||||
|
}
|
||||||
|
|
||||||
|
public android.accounts.Account getAccount() {
|
||||||
|
return account;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setPassword(String password) {
|
||||||
|
accountManager.setPassword(account, password);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUuid(String uuid) {
|
||||||
|
accountManager.setUserData(account, EXTRA_UUID, uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isBackgroundSyncEnabled() {
|
||||||
|
return ContentResolver.getSyncAutomatically(account, AUTHORITY);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setSynchronizationEnabled(boolean enabled) {
|
||||||
|
ContentResolver.setSyncAutomatically(account, AUTHORITY, enabled);
|
||||||
|
if (enabled) {
|
||||||
|
ContentResolver.addPeriodicSync(account, AUTHORITY, Bundle.EMPTY, TimeUnit.HOURS.toSeconds(1));
|
||||||
|
} else {
|
||||||
|
ContentResolver.removePeriodicSync(account, AUTHORITY, Bundle.EMPTY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Account{" +
|
||||||
|
"account=" + account +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,59 @@
|
|||||||
|
package org.tasks.caldav;
|
||||||
|
|
||||||
|
import android.accounts.AbstractAccountAuthenticator;
|
||||||
|
import android.accounts.Account;
|
||||||
|
import android.accounts.AccountAuthenticatorResponse;
|
||||||
|
import android.accounts.AccountManager;
|
||||||
|
import android.accounts.NetworkErrorException;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
public class CalDAVAccountAuthenticator extends AbstractAccountAuthenticator {
|
||||||
|
|
||||||
|
private final Context context;
|
||||||
|
|
||||||
|
public CalDAVAccountAuthenticator(Context context) {
|
||||||
|
super(context);
|
||||||
|
this.context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Bundle editProperties(AccountAuthenticatorResponse response, String accountType) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Bundle addAccount(AccountAuthenticatorResponse response, String accountType, String authTokenType, String[] requiredFeatures, Bundle options) throws NetworkErrorException {
|
||||||
|
Intent intent = new Intent(context, CalDAVSettingsActivity.class);
|
||||||
|
intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response);
|
||||||
|
Bundle bundle = new Bundle();
|
||||||
|
bundle.putParcelable(AccountManager.KEY_INTENT, intent);
|
||||||
|
return bundle;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Bundle confirmCredentials(AccountAuthenticatorResponse response, Account account, Bundle options) throws NetworkErrorException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Bundle getAuthToken(AccountAuthenticatorResponse response, Account account, String authTokenType, Bundle options) throws NetworkErrorException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getAuthTokenLabel(String authTokenType) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Bundle updateCredentials(AccountAuthenticatorResponse response, Account account, String authTokenType, Bundle options) throws NetworkErrorException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Bundle hasFeatures(AccountAuthenticatorResponse response, Account account, String[] features) throws NetworkErrorException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
package org.tasks.caldav;
|
||||||
|
|
||||||
|
import android.accounts.AccountManager;
|
||||||
|
import android.app.Service;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.IBinder;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
|
||||||
|
public class CalDAVAccountAuthenticatorService extends Service {
|
||||||
|
|
||||||
|
private CalDAVAccountAuthenticator authenticator;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate() {
|
||||||
|
authenticator = new CalDAVAccountAuthenticator(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public IBinder onBind(Intent intent) {
|
||||||
|
return AccountManager.ACTION_AUTHENTICATOR_INTENT.equals(intent.getAction())
|
||||||
|
? authenticator.getIBinder()
|
||||||
|
: null;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,464 @@
|
|||||||
|
package org.tasks.caldav;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.support.design.widget.Snackbar;
|
||||||
|
import android.support.design.widget.TextInputEditText;
|
||||||
|
import android.support.design.widget.TextInputLayout;
|
||||||
|
import android.support.v4.content.ContextCompat;
|
||||||
|
import android.support.v7.widget.Toolbar;
|
||||||
|
import android.text.InputType;
|
||||||
|
import android.view.MenuItem;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.inputmethod.InputMethodManager;
|
||||||
|
import android.widget.CheckBox;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import com.todoroo.astrid.activity.TaskListActivity;
|
||||||
|
import com.todoroo.astrid.api.CaldavFilter;
|
||||||
|
import com.todoroo.astrid.helper.UUIDHelper;
|
||||||
|
|
||||||
|
import org.tasks.R;
|
||||||
|
import org.tasks.activities.ColorPickerActivity;
|
||||||
|
import org.tasks.analytics.Tracker;
|
||||||
|
import org.tasks.analytics.Tracking;
|
||||||
|
import org.tasks.data.CaldavAccount;
|
||||||
|
import org.tasks.data.CaldavDao;
|
||||||
|
import org.tasks.dialogs.ColorPickerDialog;
|
||||||
|
import org.tasks.dialogs.DialogBuilder;
|
||||||
|
import org.tasks.injection.ActivityComponent;
|
||||||
|
import org.tasks.injection.ThemedInjectingAppCompatActivity;
|
||||||
|
import org.tasks.preferences.Preferences;
|
||||||
|
import org.tasks.sync.SyncAdapters;
|
||||||
|
import org.tasks.themes.ThemeCache;
|
||||||
|
import org.tasks.themes.ThemeColor;
|
||||||
|
|
||||||
|
import java.net.IDN;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import butterknife.BindView;
|
||||||
|
import butterknife.ButterKnife;
|
||||||
|
import butterknife.OnClick;
|
||||||
|
import butterknife.OnFocusChange;
|
||||||
|
import butterknife.OnTextChanged;
|
||||||
|
import timber.log.Timber;
|
||||||
|
|
||||||
|
import static android.text.TextUtils.isEmpty;
|
||||||
|
import static org.tasks.caldav.DeleteAccountDialog.newDeleteAccountDialog;
|
||||||
|
import static org.tasks.caldav.RenameAccountDialog.newRenameAccountDialog;
|
||||||
|
import static org.tasks.time.DateTimeUtils.currentTimeMillis;
|
||||||
|
|
||||||
|
public class CalDAVSettingsActivity extends ThemedInjectingAppCompatActivity
|
||||||
|
implements Toolbar.OnMenuItemClickListener, DeleteAccountDialog.DeleteAccountDialogCallback,
|
||||||
|
RenameAccountDialog.RenameAccountDialogCallback {
|
||||||
|
|
||||||
|
private static final String EXTRA_SELECTED_THEME = "extra_selected_theme";
|
||||||
|
private static final String FRAG_TAG_RENAME_ACCOUNT = "frag_tag_rename_account";
|
||||||
|
private static final String FRAG_TAG_DELETE_ACCOUNT = "frag_tag_delete_account";
|
||||||
|
|
||||||
|
private static final int REQUEST_COLOR_PICKER = 10109;
|
||||||
|
|
||||||
|
public static final String EXTRA_CALDAV_DATA = "caldavData"; //$NON-NLS-1$
|
||||||
|
public static final String EXTRA_CALDAV_UUID = "uuid"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
public static final String ACTION_RELOAD = "accountRenamed";
|
||||||
|
public static final String ACTION_DELETED = "accountDeleted";
|
||||||
|
|
||||||
|
private CaldavAccount caldavAccount;
|
||||||
|
private Account localAccount;
|
||||||
|
private int selectedTheme;
|
||||||
|
|
||||||
|
@Inject DialogBuilder dialogBuilder;
|
||||||
|
@Inject Preferences preferences;
|
||||||
|
@Inject ThemeCache themeCache;
|
||||||
|
@Inject ThemeColor themeColor;
|
||||||
|
@Inject Tracker tracker;
|
||||||
|
@Inject CaldavDao caldavDao;
|
||||||
|
@Inject CaldavAccountManager caldavAccountManager;
|
||||||
|
@Inject SyncAdapters syncAdapters;
|
||||||
|
|
||||||
|
@BindView(R.id.root_layout) LinearLayout root;
|
||||||
|
@BindView(R.id.name) TextInputEditText name;
|
||||||
|
@BindView(R.id.url) TextInputEditText url;
|
||||||
|
@BindView(R.id.user) TextInputEditText user;
|
||||||
|
@BindView(R.id.password) TextInputEditText password;
|
||||||
|
@BindView(R.id.name_layout) TextInputLayout nameLayout;
|
||||||
|
@BindView(R.id.url_layout) TextInputLayout urlLayout;
|
||||||
|
@BindView(R.id.user_layout) TextInputLayout userLayout;
|
||||||
|
@BindView(R.id.password_layout) TextInputLayout passwordLayout;
|
||||||
|
@BindView(R.id.color) TextInputEditText color;
|
||||||
|
@BindView(R.id.toolbar) Toolbar toolbar;
|
||||||
|
@BindView(R.id.background_sync) CheckBox backgroundSync;
|
||||||
|
@BindView(R.id.master_sync_warning) TextView masterSyncWarning;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
setContentView(R.layout.activity_caldav_settings);
|
||||||
|
ButterKnife.bind(this);
|
||||||
|
|
||||||
|
caldavAccount = getIntent().getParcelableExtra(EXTRA_CALDAV_DATA);
|
||||||
|
|
||||||
|
if (caldavAccount != null) {
|
||||||
|
localAccount = caldavAccountManager.getAccount(caldavAccount.getUuid());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (savedInstanceState == null) {
|
||||||
|
if (caldavAccount != null) {
|
||||||
|
selectedTheme = caldavAccount.getColor();
|
||||||
|
name.setText(caldavAccount.getName());
|
||||||
|
url.setText(caldavAccount.getUrl());
|
||||||
|
user.setText(caldavAccount.getUsername());
|
||||||
|
}
|
||||||
|
backgroundSync.setChecked(localAccount == null || localAccount.isBackgroundSyncEnabled());
|
||||||
|
} else {
|
||||||
|
selectedTheme = savedInstanceState.getInt(EXTRA_SELECTED_THEME);
|
||||||
|
}
|
||||||
|
|
||||||
|
final boolean backButtonSavesTask = preferences.backButtonSavesTask();
|
||||||
|
toolbar.setTitle(caldavAccount == null ? getString(R.string.add_account) : caldavAccount.getName());
|
||||||
|
toolbar.setNavigationIcon(ContextCompat.getDrawable(this,
|
||||||
|
backButtonSavesTask ? R.drawable.ic_close_24dp : R.drawable.ic_save_24dp));
|
||||||
|
toolbar.setNavigationOnClickListener(v -> {
|
||||||
|
if (backButtonSavesTask) {
|
||||||
|
discard();
|
||||||
|
} else {
|
||||||
|
save();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
toolbar.inflateMenu(R.menu.menu_tag_settings);
|
||||||
|
toolbar.setOnMenuItemClickListener(this);
|
||||||
|
toolbar.showOverflowMenu();
|
||||||
|
|
||||||
|
color.setInputType(InputType.TYPE_NULL);
|
||||||
|
|
||||||
|
if (caldavAccount == null) {
|
||||||
|
toolbar.getMenu().findItem(R.id.delete).setVisible(false);
|
||||||
|
name.requestFocus();
|
||||||
|
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||||
|
imm.showSoftInput(name, InputMethodManager.SHOW_IMPLICIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateTheme();
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnTextChanged(R.id.name)
|
||||||
|
void onNameChanged(CharSequence text) {
|
||||||
|
nameLayout.setError(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnTextChanged(R.id.url)
|
||||||
|
void onUrlChanged(CharSequence text) {
|
||||||
|
urlLayout.setError(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnTextChanged(R.id.user)
|
||||||
|
void onUserChanged(CharSequence text) {
|
||||||
|
userLayout.setError(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnTextChanged(R.id.password)
|
||||||
|
void onPasswordChanged(CharSequence text) {
|
||||||
|
passwordLayout.setError(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onSaveInstanceState(Bundle outState) {
|
||||||
|
super.onSaveInstanceState(outState);
|
||||||
|
|
||||||
|
outState.putInt(EXTRA_SELECTED_THEME, selectedTheme);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
|
||||||
|
masterSyncWarning.setVisibility(syncAdapters.isMasterSyncEnabled() ? View.GONE : View.VISIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnFocusChange(R.id.color)
|
||||||
|
void onFocusChange(boolean focused) {
|
||||||
|
if (focused) {
|
||||||
|
color.clearFocus();
|
||||||
|
showThemePicker();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnClick(R.id.color)
|
||||||
|
protected void showThemePicker() {
|
||||||
|
Intent intent = new Intent(CalDAVSettingsActivity.this, ColorPickerActivity.class);
|
||||||
|
intent.putExtra(ColorPickerActivity.EXTRA_PALETTE, ColorPickerDialog.ColorPalette.COLORS);
|
||||||
|
intent.putExtra(ColorPickerActivity.EXTRA_SHOW_NONE, true);
|
||||||
|
startActivityForResult(intent, REQUEST_COLOR_PICKER);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void inject(ActivityComponent component) {
|
||||||
|
component.inject(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getNewName() {
|
||||||
|
return name.getText().toString().trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getNewURL() {
|
||||||
|
return url.getText().toString().trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getNewUsername() {
|
||||||
|
return user.getText().toString().trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getNewPassword() {
|
||||||
|
String input = password.getText().toString().trim();
|
||||||
|
return localAccount == null || !isEmpty(input) ? input : localAccount.getPassword();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean clashes(String newName) {
|
||||||
|
CaldavAccount existing = caldavDao.getAccountByName(newName);
|
||||||
|
return caldavAccount != null && existing != null && caldavAccount.getId() != existing.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void save() {
|
||||||
|
String newName = getNewName();
|
||||||
|
String username = getNewUsername();
|
||||||
|
String url = getNewURL();
|
||||||
|
String password = getNewPassword();
|
||||||
|
|
||||||
|
boolean failed = false;
|
||||||
|
|
||||||
|
if (isEmpty(newName)) {
|
||||||
|
nameLayout.setError(getString(R.string.name_cannot_be_empty));
|
||||||
|
failed = true;
|
||||||
|
} else if (clashes(newName)) {
|
||||||
|
nameLayout.setError(getString(R.string.tag_already_exists));
|
||||||
|
failed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isEmpty(url)) {
|
||||||
|
urlLayout.setError(getString(R.string.url_required));
|
||||||
|
failed = true;
|
||||||
|
} else {
|
||||||
|
Uri baseURL = Uri.parse(url);
|
||||||
|
String scheme = baseURL.getScheme();
|
||||||
|
if ("https".equalsIgnoreCase(scheme) || "http".equalsIgnoreCase(scheme)) {
|
||||||
|
String host = baseURL.getHost();
|
||||||
|
if (isEmpty(host)) {
|
||||||
|
urlLayout.setError(getString(R.string.url_host_name_required));
|
||||||
|
failed = true;
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
host = IDN.toASCII(host);
|
||||||
|
} catch(Exception e) {
|
||||||
|
Timber.e(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
String path = baseURL.getEncodedPath();
|
||||||
|
int port = baseURL.getPort();
|
||||||
|
try {
|
||||||
|
new URI(scheme, null, host, port, path, null, null);
|
||||||
|
} catch(URISyntaxException e) {
|
||||||
|
urlLayout.setError(e.getLocalizedMessage());
|
||||||
|
failed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
urlLayout.setError(getString(R.string.url_invalid_scheme));
|
||||||
|
failed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isEmpty(username)) {
|
||||||
|
userLayout.setError(getString(R.string.username_required));
|
||||||
|
failed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (localAccount == null && isEmpty(password)) {
|
||||||
|
passwordLayout.setError(getString(R.string.password_required));
|
||||||
|
failed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (failed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (caldavAccount == null) {
|
||||||
|
CaldavAccount newAccount = new CaldavAccount(newName, UUIDHelper.newUUID());
|
||||||
|
newAccount.setColor(selectedTheme);
|
||||||
|
newAccount.setUrl(url);
|
||||||
|
newAccount.setUsername(username);
|
||||||
|
if (caldavAccountManager.addAccount(newAccount, password)) {
|
||||||
|
Account account = caldavAccountManager.getAccount(newAccount.getUuid());
|
||||||
|
if (account == null) {
|
||||||
|
showErrorSnackbar();
|
||||||
|
} else {
|
||||||
|
newAccount.setId(caldavDao.insert(newAccount));
|
||||||
|
setResult(RESULT_OK, new Intent().putExtra(TaskListActivity.OPEN_FILTER, new CaldavFilter(newAccount)));
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
showErrorSnackbar();
|
||||||
|
}
|
||||||
|
} else if (hasChanges()) {
|
||||||
|
if (localAccount == null) {
|
||||||
|
if (!caldavAccountManager.addAccount(caldavAccount, password)) {
|
||||||
|
localAccount = caldavAccountManager.getAccount(caldavAccount.getUuid());
|
||||||
|
if (localAccount == null) {
|
||||||
|
showErrorSnackbar();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (!newName.equals(localAccount.getName())) {
|
||||||
|
newRenameAccountDialog(caldavAccount.getUuid(), newName)
|
||||||
|
.show(getSupportFragmentManager(), FRAG_TAG_RENAME_ACCOUNT);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
caldavAccount.setName(newName);
|
||||||
|
caldavAccount.setColor(selectedTheme);
|
||||||
|
caldavAccount.setUrl(url);
|
||||||
|
caldavAccount.setUsername(username);
|
||||||
|
caldavDao.update(caldavAccount);
|
||||||
|
if (!isEmpty(password)) {
|
||||||
|
localAccount.setPassword(password);
|
||||||
|
}
|
||||||
|
localAccount.setSynchronizationEnabled(backgroundSync.isChecked());
|
||||||
|
setResult(RESULT_OK, new Intent(ACTION_RELOAD).putExtra(TaskListActivity.OPEN_FILTER, new CaldavFilter(caldavAccount)));
|
||||||
|
finish();
|
||||||
|
} else {
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showErrorSnackbar() {
|
||||||
|
Snackbar snackbar = Snackbar.make(root, getString(R.string.error_adding_account), 8000)
|
||||||
|
.setActionTextColor(ContextCompat.getColor(this, R.color.snackbar_text_color));
|
||||||
|
snackbar.getView().setBackgroundColor(ContextCompat.getColor(this, R.color.snackbar_background));
|
||||||
|
snackbar.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean hasChanges() {
|
||||||
|
if (caldavAccount == null) {
|
||||||
|
return selectedTheme >= 0 || !isEmpty(getNewName()) ||
|
||||||
|
!isEmpty(getNewPassword()) || !isEmpty(getNewURL()) ||
|
||||||
|
!isEmpty(getNewUsername()) || !backgroundSync.isChecked();
|
||||||
|
}
|
||||||
|
return localAccount == null ||
|
||||||
|
selectedTheme != caldavAccount.getColor() ||
|
||||||
|
!getNewName().equals(caldavAccount.getName()) ||
|
||||||
|
!getNewURL().equals(caldavAccount.getUrl()) ||
|
||||||
|
!getNewUsername().equals(caldavAccount.getUsername()) ||
|
||||||
|
!getNewPassword().equals(localAccount.getPassword()) ||
|
||||||
|
backgroundSync.isChecked() != localAccount.isBackgroundSyncEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void finish() {
|
||||||
|
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||||
|
imm.hideSoftInputFromWindow(name.getWindowToken(), 0);
|
||||||
|
super.finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBackPressed() {
|
||||||
|
if (preferences.backButtonSavesTask()) {
|
||||||
|
save();
|
||||||
|
} else {
|
||||||
|
discard();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||||
|
if (requestCode == REQUEST_COLOR_PICKER) {
|
||||||
|
if (resultCode == RESULT_OK) {
|
||||||
|
int index = data.getIntExtra(ColorPickerActivity.EXTRA_THEME_INDEX, 0);
|
||||||
|
tracker.reportEvent(Tracking.Events.SET_TAG_COLOR, Integer.toString(index));
|
||||||
|
selectedTheme = index;
|
||||||
|
updateTheme();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
super.onActivityResult(requestCode, resultCode, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void deleteAccount() {
|
||||||
|
dialogBuilder.newMessageDialog(R.string.delete_tag_confirmation, caldavAccount.getName())
|
||||||
|
.setPositiveButton(R.string.delete, (dialog, which) -> {
|
||||||
|
if (localAccount == null) {
|
||||||
|
onListDeleted();
|
||||||
|
} else {
|
||||||
|
newDeleteAccountDialog(localAccount.getUuid())
|
||||||
|
.show(getSupportFragmentManager(), FRAG_TAG_DELETE_ACCOUNT);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.setNegativeButton(android.R.string.cancel, null)
|
||||||
|
.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void discard() {
|
||||||
|
if (!hasChanges()) {
|
||||||
|
finish();
|
||||||
|
} else {
|
||||||
|
dialogBuilder.newMessageDialog(R.string.discard_changes)
|
||||||
|
.setPositiveButton(R.string.discard, (dialog, which) -> finish())
|
||||||
|
.setNegativeButton(android.R.string.cancel, null)
|
||||||
|
.show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateTheme() {
|
||||||
|
ThemeColor themeColor;
|
||||||
|
if (selectedTheme < 0) {
|
||||||
|
themeColor = this.themeColor;
|
||||||
|
color.setText(R.string.none);
|
||||||
|
} else {
|
||||||
|
themeColor = themeCache.getThemeColor(selectedTheme);
|
||||||
|
color.setText(themeColor.getName());
|
||||||
|
}
|
||||||
|
themeColor.apply(toolbar);
|
||||||
|
themeColor.applyToStatusBar(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onMenuItemClick(MenuItem item) {
|
||||||
|
switch (item.getItemId()) {
|
||||||
|
case R.id.delete:
|
||||||
|
deleteAccount();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return super.onOptionsItemSelected(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onListDeleted() {
|
||||||
|
if (caldavAccount != null) {
|
||||||
|
caldavAccountManager.deleteAccount(caldavAccount);
|
||||||
|
setResult(RESULT_OK, new Intent(ACTION_DELETED).putExtra(EXTRA_CALDAV_UUID, caldavAccount.getUuid()));
|
||||||
|
}
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onListRenamed() {
|
||||||
|
localAccount = caldavAccountManager.getAccount(caldavAccount.getUuid());
|
||||||
|
save();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void renameFailed() {
|
||||||
|
nameLayout.setError(getString(R.string.error_renaming_account));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteAccountFailed() {
|
||||||
|
Toast.makeText(this, R.string.error_deleting_account, Toast.LENGTH_LONG).show();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,164 @@
|
|||||||
|
package org.tasks.caldav;
|
||||||
|
|
||||||
|
import android.accounts.AuthenticatorException;
|
||||||
|
import android.accounts.OperationCanceledException;
|
||||||
|
import android.content.ContentResolver;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
import com.google.common.base.Optional;
|
||||||
|
import com.google.common.base.Strings;
|
||||||
|
import com.todoroo.astrid.dao.TaskDao;
|
||||||
|
import com.todoroo.astrid.data.Task;
|
||||||
|
import com.todoroo.astrid.service.TaskDeleter;
|
||||||
|
|
||||||
|
import org.tasks.LocalBroadcastManager;
|
||||||
|
import org.tasks.data.CaldavAccount;
|
||||||
|
import org.tasks.data.CaldavDao;
|
||||||
|
import org.tasks.injection.ApplicationScope;
|
||||||
|
import org.tasks.injection.ForApplication;
|
||||||
|
import org.tasks.preferences.PermissionChecker;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import timber.log.Timber;
|
||||||
|
|
||||||
|
import static com.google.common.collect.Iterables.tryFind;
|
||||||
|
import static org.tasks.caldav.Account.EXTRA_UUID;
|
||||||
|
|
||||||
|
@ApplicationScope
|
||||||
|
public class CaldavAccountManager {
|
||||||
|
|
||||||
|
private static final String AUTHORITY = "org.tasks";
|
||||||
|
private static final String ACCOUNT_TYPE = "org.tasks.caldav";
|
||||||
|
|
||||||
|
private final PermissionChecker permissionChecker;
|
||||||
|
private final android.accounts.AccountManager accountManager;
|
||||||
|
private final LocalBroadcastManager localBroadcastManager;
|
||||||
|
private final TaskDeleter taskDeleter;
|
||||||
|
private final CaldavDao caldavDao;
|
||||||
|
private final TaskDao taskDao;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public CaldavAccountManager(@ForApplication Context context, PermissionChecker permissionChecker,
|
||||||
|
CaldavDao caldavDao, TaskDeleter taskDeleter,
|
||||||
|
LocalBroadcastManager localBroadcastManager, TaskDao taskDao) {
|
||||||
|
this.permissionChecker = permissionChecker;
|
||||||
|
this.caldavDao = caldavDao;
|
||||||
|
this.taskDao = taskDao;
|
||||||
|
this.taskDeleter = taskDeleter;
|
||||||
|
this.localBroadcastManager = localBroadcastManager;
|
||||||
|
accountManager = android.accounts.AccountManager.get(context);
|
||||||
|
syncAccountList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUuid(android.accounts.Account account) {
|
||||||
|
return accountManager.getUserData(account, EXTRA_UUID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Account getAccount(String uuid) {
|
||||||
|
for (Account account : getAccounts()) {
|
||||||
|
if (uuid.equals(account.getUuid())) {
|
||||||
|
return account;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Account> getAccounts() {
|
||||||
|
if (!permissionChecker.canAccessAccounts()) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Account> accounts = new ArrayList<>();
|
||||||
|
for (android.accounts.Account account : accountManager.getAccountsByType(ACCOUNT_TYPE)) {
|
||||||
|
accounts.add(new Account(accountManager, account));
|
||||||
|
}
|
||||||
|
return accounts;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean removeAccount(Account account) {
|
||||||
|
return removeAccount(account.getAccount());
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean removeAccount(android.accounts.Account account) {
|
||||||
|
try {
|
||||||
|
return accountManager
|
||||||
|
.removeAccount(account, null, null)
|
||||||
|
.getResult();
|
||||||
|
} catch (OperationCanceledException | IOException | AuthenticatorException e) {
|
||||||
|
Timber.e(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean addAccount(CaldavAccount caldavAccount, String password) {
|
||||||
|
Timber.d("Adding %s", caldavAccount);
|
||||||
|
android.accounts.Account account = new android.accounts.Account(caldavAccount.getName(), ACCOUNT_TYPE);
|
||||||
|
Bundle userdata = new Bundle();
|
||||||
|
userdata.putString(EXTRA_UUID, caldavAccount.getUuid());
|
||||||
|
return accountManager.addAccountExplicitly(account, password, userdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createAccount(Account account) {
|
||||||
|
Timber.d("Adding %s", account);
|
||||||
|
String uuid = account.getUuid();
|
||||||
|
if (!Strings.isNullOrEmpty(uuid)) {
|
||||||
|
caldavDao.insert(new CaldavAccount(account.getName(), uuid));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void syncAccountList() {
|
||||||
|
List<CaldavAccount> oldAccountList = caldavDao.getAllOrderedByName();
|
||||||
|
List<Account> newAccountList = getAccounts();
|
||||||
|
|
||||||
|
for (CaldavAccount local : oldAccountList) {
|
||||||
|
Optional<Account> match = tryFind(newAccountList, remote -> local.getUuid().equals(remote.getUuid()));
|
||||||
|
if (match.isPresent()) {
|
||||||
|
Timber.d("found %s", match.get());
|
||||||
|
} else {
|
||||||
|
addAccount(local, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Account remote : newAccountList) {
|
||||||
|
Optional<CaldavAccount> match = tryFind(oldAccountList, local -> remote.getUuid().equals(local.getUuid()));
|
||||||
|
if (match.isPresent()) {
|
||||||
|
Timber.d("found %s", match.get());
|
||||||
|
} else {
|
||||||
|
createAccount(remote);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void deleteAccount(CaldavAccount account) {
|
||||||
|
String uuid = account.getUuid();
|
||||||
|
for (Task task : taskDao.getCaldavTasks(uuid)) {
|
||||||
|
taskDeleter.markDeleted(task);
|
||||||
|
}
|
||||||
|
caldavDao.deleteTasksForAccount(uuid);
|
||||||
|
caldavDao.delete(account);
|
||||||
|
localBroadcastManager.broadcastRefreshList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean initiateManualSync() {
|
||||||
|
for (org.tasks.caldav.Account account : getAccounts()) {
|
||||||
|
Bundle extras = new Bundle();
|
||||||
|
extras.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
|
||||||
|
extras.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true);
|
||||||
|
ContentResolver.requestSync(account.getAccount(), AUTHORITY, extras);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void requestSynchronization() {
|
||||||
|
for (org.tasks.caldav.Account account : getAccounts()) {
|
||||||
|
ContentResolver.requestSync(account.getAccount(), AUTHORITY, new Bundle());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,93 @@
|
|||||||
|
package org.tasks.caldav;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.app.Dialog;
|
||||||
|
import android.app.ProgressDialog;
|
||||||
|
import android.os.AsyncTask;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
|
||||||
|
import org.tasks.R;
|
||||||
|
import org.tasks.dialogs.DialogBuilder;
|
||||||
|
import org.tasks.injection.DialogFragmentComponent;
|
||||||
|
import org.tasks.injection.InjectingDialogFragment;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
public class DeleteAccountDialog extends InjectingDialogFragment {
|
||||||
|
|
||||||
|
public static DeleteAccountDialog newDeleteAccountDialog(String uuid) {
|
||||||
|
DeleteAccountDialog dialog = new DeleteAccountDialog();
|
||||||
|
Bundle args = new Bundle();
|
||||||
|
args.putString(EXTRA_UUID, uuid);
|
||||||
|
dialog.setArguments(args);
|
||||||
|
return dialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface DeleteAccountDialogCallback {
|
||||||
|
void onListDeleted();
|
||||||
|
|
||||||
|
void deleteAccountFailed();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final String EXTRA_UUID = "extra_uuid";
|
||||||
|
|
||||||
|
@Inject DialogBuilder dialogBuilder;
|
||||||
|
@Inject CaldavAccountManager caldavAccountManager;
|
||||||
|
|
||||||
|
private DeleteAccountDialogCallback callback;
|
||||||
|
private String uuid;
|
||||||
|
private ProgressDialog dialog;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setRetainInstance(true);
|
||||||
|
Bundle arguments = getArguments();
|
||||||
|
uuid = arguments.getString(EXTRA_UUID);
|
||||||
|
dialog = dialogBuilder.newProgressDialog(R.string.deleting_list);
|
||||||
|
execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||||
|
return dialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAttach(Activity activity) {
|
||||||
|
super.onAttach(activity);
|
||||||
|
|
||||||
|
callback = (DeleteAccountDialogCallback) activity;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void inject(DialogFragmentComponent component) {
|
||||||
|
component.inject(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void execute() {
|
||||||
|
new AsyncTask<Void, Void, Boolean>() {
|
||||||
|
@Override
|
||||||
|
protected Boolean doInBackground(Void... voids) {
|
||||||
|
Account account = caldavAccountManager.getAccount(uuid);
|
||||||
|
return account == null || caldavAccountManager.removeAccount(account);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPostExecute(Boolean result) {
|
||||||
|
if (dialog.isShowing()) {
|
||||||
|
dialog.dismiss();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
callback.onListDeleted();
|
||||||
|
} else {
|
||||||
|
callback.deleteAccountFailed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.execute();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,112 @@
|
|||||||
|
package org.tasks.caldav;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.app.Dialog;
|
||||||
|
import android.app.ProgressDialog;
|
||||||
|
import android.os.AsyncTask;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
|
||||||
|
import com.todoroo.astrid.helper.UUIDHelper;
|
||||||
|
|
||||||
|
import org.tasks.R;
|
||||||
|
import org.tasks.data.CaldavAccount;
|
||||||
|
import org.tasks.data.CaldavDao;
|
||||||
|
import org.tasks.dialogs.DialogBuilder;
|
||||||
|
import org.tasks.injection.DialogFragmentComponent;
|
||||||
|
import org.tasks.injection.InjectingDialogFragment;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import static org.tasks.time.DateTimeUtils.currentTimeMillis;
|
||||||
|
|
||||||
|
public class RenameAccountDialog extends InjectingDialogFragment {
|
||||||
|
|
||||||
|
public static RenameAccountDialog newRenameAccountDialog(String uuid, String name) {
|
||||||
|
RenameAccountDialog dialog = new RenameAccountDialog();
|
||||||
|
Bundle args = new Bundle();
|
||||||
|
args.putString(EXTRA_NAME, name);
|
||||||
|
args.putString(EXTRA_UUID, uuid);
|
||||||
|
dialog.setArguments(args);
|
||||||
|
return dialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface RenameAccountDialogCallback {
|
||||||
|
void onListRenamed();
|
||||||
|
|
||||||
|
void renameFailed();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final String EXTRA_NAME = "extra_name";
|
||||||
|
private static final String EXTRA_UUID = "extra_uuid";
|
||||||
|
|
||||||
|
@Inject DialogBuilder dialogBuilder;
|
||||||
|
@Inject CaldavAccountManager caldavAccountManager;
|
||||||
|
@Inject CaldavDao caldavDao;
|
||||||
|
|
||||||
|
private RenameAccountDialogCallback callback;
|
||||||
|
private String name;
|
||||||
|
private String uuid;
|
||||||
|
private ProgressDialog dialog;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setRetainInstance(true);
|
||||||
|
Bundle arguments = getArguments();
|
||||||
|
name = arguments.getString(EXTRA_NAME);
|
||||||
|
uuid = arguments.getString(EXTRA_UUID);
|
||||||
|
dialog = dialogBuilder.newProgressDialog(R.string.renaming_list);
|
||||||
|
execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||||
|
return dialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAttach(Activity activity) {
|
||||||
|
super.onAttach(activity);
|
||||||
|
|
||||||
|
callback = (RenameAccountDialogCallback) activity;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void inject(DialogFragmentComponent component) {
|
||||||
|
component.inject(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void execute() {
|
||||||
|
new AsyncTask<Void, Void, Boolean>() {
|
||||||
|
@Override
|
||||||
|
protected Boolean doInBackground(Void... voids) {
|
||||||
|
CaldavAccount caldavAccount = caldavDao.getAccount(uuid);
|
||||||
|
caldavAccount.setName(name);
|
||||||
|
Account old = caldavAccountManager.getAccount(uuid);
|
||||||
|
if (!caldavAccountManager.addAccount(caldavAccount, old.getPassword())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
caldavDao.update(caldavAccount);
|
||||||
|
old.setUuid(null);
|
||||||
|
caldavAccountManager.removeAccount(old);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPostExecute(Boolean result) {
|
||||||
|
if (dialog.isShowing()) {
|
||||||
|
dialog.dismiss();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
callback.onListRenamed();
|
||||||
|
} else {
|
||||||
|
callback.renameFailed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.execute();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,133 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:id="@+id/root_layout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:background="?attr/asContentBackground"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<include layout="@layout/toolbar" />
|
||||||
|
|
||||||
|
<ScrollView
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:descendantFocusability="beforeDescendants"
|
||||||
|
android:focusableInTouchMode="true"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<android.support.design.widget.TextInputLayout
|
||||||
|
android:id="@+id/name_layout"
|
||||||
|
style="@style/TagSettingsRow">
|
||||||
|
|
||||||
|
<android.support.design.widget.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|textFilter"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:textColor="?attr/asTextColor" />
|
||||||
|
</android.support.design.widget.TextInputLayout>
|
||||||
|
|
||||||
|
<android.support.design.widget.TextInputLayout
|
||||||
|
android:id="@+id/url_layout"
|
||||||
|
style="@style/TagSettingsRow">
|
||||||
|
|
||||||
|
<android.support.design.widget.TextInputEditText
|
||||||
|
android:id="@+id/url"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:hint="@string/url"
|
||||||
|
android:textColor="?attr/asTextColor" />
|
||||||
|
|
||||||
|
</android.support.design.widget.TextInputLayout>
|
||||||
|
|
||||||
|
<android.support.design.widget.TextInputLayout
|
||||||
|
android:id="@+id/user_layout"
|
||||||
|
style="@style/TagSettingsRow">
|
||||||
|
|
||||||
|
<android.support.design.widget.TextInputEditText
|
||||||
|
android:id="@+id/user"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:hint="@string/user"
|
||||||
|
android:textColor="?attr/asTextColor" />
|
||||||
|
|
||||||
|
</android.support.design.widget.TextInputLayout>
|
||||||
|
|
||||||
|
<android.support.design.widget.TextInputLayout
|
||||||
|
android:id="@+id/password_layout"
|
||||||
|
style="@style/TagSettingsRow"
|
||||||
|
app:passwordToggleEnabled="true">
|
||||||
|
|
||||||
|
<android.support.design.widget.TextInputEditText
|
||||||
|
android:id="@+id/password"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:hint="@string/password"
|
||||||
|
android:textColor="?attr/asTextColor"
|
||||||
|
android:inputType="textPassword"/>
|
||||||
|
|
||||||
|
</android.support.design.widget.TextInputLayout>
|
||||||
|
|
||||||
|
<android.support.design.widget.TextInputLayout style="@style/TagSettingsRow">
|
||||||
|
|
||||||
|
<android.support.design.widget.TextInputEditText
|
||||||
|
android:id="@+id/color"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:hint="@string/color"
|
||||||
|
android:textColor="?attr/asTextColor" />
|
||||||
|
</android.support.design.widget.TextInputLayout>
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
style="@style/TagSettingsRow"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<CheckBox
|
||||||
|
android:id="@+id/background_sync"
|
||||||
|
android:checked="true"
|
||||||
|
android:layout_alignParentEnd="true"
|
||||||
|
android:layout_alignParentRight="true"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/background_sync_label"
|
||||||
|
android:layout_alignParentStart="true"
|
||||||
|
android:layout_alignParentLeft="true"
|
||||||
|
android:paddingTop="3dp"
|
||||||
|
android:paddingLeft="4dp"
|
||||||
|
android:paddingStart="4dp"
|
||||||
|
android:textSize="@dimen/settings_text_size"
|
||||||
|
android:layout_toLeftOf="@id/background_sync"
|
||||||
|
android:layout_toStartOf="@id/background_sync"
|
||||||
|
android:text="@string/sync_SPr_interval_title"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:textColor="?attr/asTextColor"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/master_sync_warning"
|
||||||
|
android:paddingLeft="4dp"
|
||||||
|
android:paddingStart="4dp"
|
||||||
|
android:textColor="?attr/asTextColor"
|
||||||
|
android:layout_below="@id/background_sync_label"
|
||||||
|
android:text="@string/master_sync_warning"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</ScrollView>
|
||||||
|
|
||||||
|
</LinearLayout>
|
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<account-authenticator xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:accountType="@string/account_type_caldav"
|
||||||
|
android:icon="@mipmap/ic_launcher"
|
||||||
|
android:label="@string/CalDAV"
|
||||||
|
android:smallIcon="@mipmap/ic_launcher" />
|
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<sync-adapter xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:accountType="@string/account_type_caldav"
|
||||||
|
android:contentAuthority="org.tasks"
|
||||||
|
android:supportsUploading="true"
|
||||||
|
android:isAlwaysSyncable="true"
|
||||||
|
android:userVisible="false" />
|
Loading…
Reference in New Issue