diff options
author | Stefan Niedermann <info@niedermann.it> | 2021-05-03 18:36:24 +0300 |
---|---|---|
committer | Stefan Niedermann <info@niedermann.it> | 2021-05-03 19:22:38 +0300 |
commit | bbf569b0e9a1a93e4fff8074cc180274fc1f2d24 (patch) | |
tree | e43c3237b7a36d8d3f4881129cd977e93690f9db /app/src/main/java/it/niedermann/owncloud/notes/manageaccounts | |
parent | e3c4c1cb40ba229f50dd534c9edef42cb807ed18 (diff) | |
parent | 1cc44ede8e6c605345d794452c099a07a49d2f49 (diff) |
Merge branch 'master' into 916-settings
# Conflicts:
# app/src/main/java/it/niedermann/owncloud/notes/manageaccounts/ManageAccountAdapter.java
# app/src/main/java/it/niedermann/owncloud/notes/manageaccounts/ManageAccountsActivity.java
# app/src/main/java/it/niedermann/owncloud/notes/persistence/NotesClient.java
# app/src/main/java/it/niedermann/owncloud/notes/persistence/NotesClientV1.java
# app/src/main/java/it/niedermann/owncloud/notes/shared/model/ApiVersion.java
# app/src/main/res/values/strings.xml
Diffstat (limited to 'app/src/main/java/it/niedermann/owncloud/notes/manageaccounts')
3 files changed, 225 insertions, 96 deletions
diff --git a/app/src/main/java/it/niedermann/owncloud/notes/manageaccounts/ManageAccountAdapter.java b/app/src/main/java/it/niedermann/owncloud/notes/manageaccounts/ManageAccountAdapter.java index c1a4e139..25155c9a 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/manageaccounts/ManageAccountAdapter.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/manageaccounts/ManageAccountAdapter.java @@ -57,16 +57,7 @@ public class ManageAccountAdapter extends RecyclerView.Adapter<ManageAccountView holder.bind(localAccount, (localAccountClicked) -> { setCurrentLocalAccount(localAccountClicked); onAccountClick.accept(localAccountClicked); - }, (localAccountToDelete -> { - for (int i = 0; i < localAccounts.size(); i++) { - if (localAccounts.get(i).getId() == localAccountToDelete.getId()) { - localAccounts.remove(i); - notifyItemRemoved(i); - break; - } - } - onAccountDelete.accept(localAccountToDelete); - }), onChangeNotesPath, onChangeFileSuffix, currentLocalAccount != null && currentLocalAccount.getId() == localAccount.getId()); + }, onAccountDelete, onChangeNotesPath, onChangeFileSuffix, currentLocalAccount != null && currentLocalAccount.getId() == localAccount.getId()); } @Override diff --git a/app/src/main/java/it/niedermann/owncloud/notes/manageaccounts/ManageAccountsActivity.java b/app/src/main/java/it/niedermann/owncloud/notes/manageaccounts/ManageAccountsActivity.java index 408c1f2d..01eafd62 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/manageaccounts/ManageAccountsActivity.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/manageaccounts/ManageAccountsActivity.java @@ -1,5 +1,6 @@ package it.niedermann.owncloud.notes.manageaccounts; +import android.accounts.NetworkErrorException; import android.os.Bundle; import android.util.TypedValue; import android.view.View; @@ -14,98 +15,104 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.Px; import androidx.appcompat.app.AlertDialog; -import androidx.lifecycle.LiveData; +import androidx.lifecycle.ViewModelProvider; import com.nextcloud.android.sso.AccountImporter; import com.nextcloud.android.sso.exceptions.NextcloudFilesAppAccountNotFoundException; -import com.nextcloud.android.sso.exceptions.NoCurrentAccountSelectedException; -import com.nextcloud.android.sso.helper.SingleAccountHelper; -import com.nextcloud.android.sso.model.SingleSignOnAccount; - -import java.util.ArrayList; -import java.util.List; import it.niedermann.owncloud.notes.LockedActivity; import it.niedermann.owncloud.notes.R; import it.niedermann.owncloud.notes.branding.BrandedAlertDialogBuilder; +import it.niedermann.owncloud.notes.branding.BrandedDeleteAlertDialogBuilder; import it.niedermann.owncloud.notes.databinding.ActivityManageAccountsBinding; import it.niedermann.owncloud.notes.exception.ExceptionDialogFragment; -import it.niedermann.owncloud.notes.persistence.NotesClient; -import it.niedermann.owncloud.notes.persistence.NotesDatabase; +import it.niedermann.owncloud.notes.persistence.NotesRepository; import it.niedermann.owncloud.notes.persistence.entity.Account; -import it.niedermann.owncloud.notes.shared.model.ServerSettings; +import it.niedermann.owncloud.notes.shared.model.IResponseCallback; +import it.niedermann.owncloud.notes.shared.model.NotesSettings; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; import static android.os.Build.VERSION.SDK_INT; import static android.os.Build.VERSION_CODES.LOLLIPOP_MR1; -import static androidx.lifecycle.Transformations.distinctUntilChanged; public class ManageAccountsActivity extends LockedActivity { private ActivityManageAccountsBinding binding; + private ManageAccountsViewModel viewModel; private ManageAccountAdapter adapter; - private NotesDatabase db = null; - private final List<Account> localAccounts = new ArrayList<>(); @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); binding = ActivityManageAccountsBinding.inflate(getLayoutInflater()); - setContentView(binding.getRoot()); + viewModel = new ViewModelProvider(this).get(ManageAccountsViewModel.class); + setContentView(binding.getRoot()); setSupportActionBar(binding.toolbar); - db = NotesDatabase.getInstance(this); - - distinctUntilChanged(db.getAccountDao().getAccounts$()).observe(this, (localAccounts) -> { - - this.localAccounts.clear(); - this.localAccounts.addAll(localAccounts); - - adapter = new ManageAccountAdapter( - (localAccount) -> SingleAccountHelper.setCurrentAccount(getApplicationContext(), localAccount.getAccountName()), - this::onAccountDelete, - this::onChangeNotesPath, - this::onChangeFileSuffix - ); - adapter.setLocalAccounts(localAccounts); - try { - final SingleSignOnAccount ssoAccount = SingleAccountHelper.getCurrentSingleSignOnAccount(this); - if (ssoAccount != null) { - new Thread(() -> { - final Account account = db.getAccountDao().getAccountByName(ssoAccount.name); - runOnUiThread(() -> adapter.setCurrentLocalAccount(account)); - }).start(); - } - } catch (NextcloudFilesAppAccountNotFoundException | NoCurrentAccountSelectedException e) { - e.printStackTrace(); + adapter = new ManageAccountAdapter( + this::selectAccount, + this::deleteAccount, + this::onChangeNotesPath, + this::onChangeFileSuffix + ); + binding.accounts.setAdapter(adapter); + + viewModel.getAccounts$().observe(this, (accounts) -> { + if (accounts == null || accounts.size() < 1) { + finish(); + return; } - binding.accounts.setAdapter(adapter); + this.adapter.setLocalAccounts(accounts); + viewModel.getCurrentAccount(this, new IResponseCallback<Account>() { + @Override + public void onSuccess(Account result) { + runOnUiThread(() -> adapter.setCurrentLocalAccount(result)); + } + + @Override + public void onError(@NonNull Throwable t) { + runOnUiThread(() -> adapter.setCurrentLocalAccount(null)); + t.printStackTrace(); + } + }); }); } - private void onAccountDelete(@NonNull Account localAccount) { - final LiveData<Void> deleteLiveData = db.deleteAccount(localAccount); - deleteLiveData.observe(this, (v) -> { - for (Account temp : localAccounts) { - if (temp.getId() == localAccount.getId()) { - localAccounts.remove(temp); - break; - } + private void selectAccount(@NonNull Account accountToSelect) { + viewModel.selectAccount(accountToSelect, this); + } + + private void deleteAccount(@NonNull Account accountToDelete) { + viewModel.countUnsynchronizedNotes(accountToDelete.getId(), new IResponseCallback<Long>() { + @Override + public void onSuccess(Long unsynchronizedChangesCount) { + runOnUiThread(() -> { + if (unsynchronizedChangesCount > 0) { + new BrandedDeleteAlertDialogBuilder(ManageAccountsActivity.this) + .setTitle(getString(R.string.remove_account, accountToDelete.getUserName())) + .setMessage(getResources().getQuantityString(R.plurals.remove_account_message, (int) unsynchronizedChangesCount.longValue(), accountToDelete.getAccountName(), unsynchronizedChangesCount)) + .setNeutralButton(android.R.string.cancel, null) + .setPositiveButton(R.string.simple_remove, (d, l) -> viewModel.deleteAccount(accountToDelete, ManageAccountsActivity.this)) + .show(); + } else { + viewModel.deleteAccount(accountToDelete, ManageAccountsActivity.this); + } + }); } - if (localAccounts.size() > 0) { - SingleAccountHelper.setCurrentAccount(getApplicationContext(), localAccounts.get(0).getAccountName()); - adapter.setCurrentLocalAccount(localAccounts.get(0)); - } else { - SingleAccountHelper.setCurrentAccount(getApplicationContext(), null); - finish(); + + @Override + public void onError(@NonNull Throwable t) { + ExceptionDialogFragment.newInstance(t).show(getSupportFragmentManager(), ExceptionDialogFragment.class.getSimpleName()); } - deleteLiveData.removeObservers(this); }); } private void onChangeNotesPath(@NonNull Account localAccount) { - final NotesClient client = NotesClient.newInstance(localAccount.getPreferredApiVersion(), getApplicationContext()); + final NotesRepository repository = NotesRepository.getInstance(getApplicationContext()); final EditText editText = new EditText(this); editText.setEnabled(false); final View wrapper = createDialogViewWrapper(editText); @@ -116,27 +123,55 @@ public class ManageAccountsActivity extends LockedActivity { .setNeutralButton(android.R.string.cancel, null) .setPositiveButton(R.string.action_edit_save, (v, d) -> new Thread(() -> { try { - final ServerSettings newSettings = client.putServerSettings(AccountImporter.getSingleSignOnAccount(this, localAccount.getAccountName()), new ServerSettings(editText.getText().toString(), null)); - Toast.makeText(this, "New notes path: " + newSettings.getNotesPath(), Toast.LENGTH_LONG).show(); - } catch (Exception e) { + final Call<NotesSettings> putSettingsCall = repository.putServerSettings(AccountImporter.getSingleSignOnAccount(this, localAccount.getAccountName()), new NotesSettings(editText.getText().toString(), null), localAccount.getPreferredApiVersion()); + putSettingsCall.enqueue(new Callback<NotesSettings>() { + @Override + public void onResponse(@NonNull Call<NotesSettings> call, @NonNull Response<NotesSettings> response) { + if (response.isSuccessful()) { + Toast.makeText(ManageAccountsActivity.this, "New notes path: " + response.body().getNotesPath(), Toast.LENGTH_LONG).show(); + } else { + Toast.makeText(ManageAccountsActivity.this, "HTTP status code: " + response.code(), Toast.LENGTH_LONG).show(); + } + } + + @Override + public void onFailure(@NonNull Call<NotesSettings> call, @NonNull Throwable t) { + runOnUiThread(() -> ExceptionDialogFragment.newInstance(t).show(getSupportFragmentManager(), ExceptionDialogFragment.class.getSimpleName())); + } + }); + } catch (NextcloudFilesAppAccountNotFoundException e) { ExceptionDialogFragment.newInstance(e).show(getSupportFragmentManager(), ExceptionDialogFragment.class.getSimpleName()); } }).start()) .show(); - new Thread(() -> { - try { - final ServerSettings oldSettings = client.getServerSettings(AccountImporter.getSingleSignOnAccount(this, localAccount.getAccountName())); - editText.setText(oldSettings.getNotesPath()); - editText.setEnabled(true); - } catch (Exception e) { - dialog.dismiss(); - ExceptionDialogFragment.newInstance(e).show(getSupportFragmentManager(), ExceptionDialogFragment.class.getSimpleName()); - } - }).start(); + try { + final Call<NotesSettings> oldSettingsCall = repository.getServerSettings(AccountImporter.getSingleSignOnAccount(this, localAccount.getAccountName()), localAccount.getPreferredApiVersion()); + oldSettingsCall.enqueue(new Callback<NotesSettings>() { + @Override + public void onResponse(@NonNull Call<NotesSettings> call, @NonNull Response<NotesSettings> response) { + runOnUiThread(() -> { + if (response.isSuccessful()) { + editText.setText(response.body().getNotesPath()); + editText.setEnabled(true); + } else { + ExceptionDialogFragment.newInstance(new NetworkErrorException("HTTP status code: " + response.code())).show(getSupportFragmentManager(), ExceptionDialogFragment.class.getSimpleName()); + } + }); + } + + @Override + public void onFailure(@NonNull Call<NotesSettings> call, @NonNull Throwable t) { + ExceptionDialogFragment.newInstance(t).show(getSupportFragmentManager(), ExceptionDialogFragment.class.getSimpleName()); + } + }); + } catch (NextcloudFilesAppAccountNotFoundException e) { + dialog.dismiss(); + ExceptionDialogFragment.newInstance(e).show(getSupportFragmentManager(), ExceptionDialogFragment.class.getSimpleName()); + } } private void onChangeFileSuffix(@NonNull Account localAccount) { - final NotesClient client = NotesClient.newInstance(localAccount.getPreferredApiVersion(), getApplicationContext()); + final NotesRepository repository = NotesRepository.getInstance(getApplicationContext()); final Spinner spinner = new Spinner(this); spinner.setEnabled(false); final View wrapper = createDialogViewWrapper(spinner); @@ -150,28 +185,57 @@ public class ManageAccountsActivity extends LockedActivity { .setNeutralButton(android.R.string.cancel, null) .setPositiveButton("Save", (v, d) -> new Thread(() -> { try { - final ServerSettings newSettings = client.putServerSettings(AccountImporter.getSingleSignOnAccount(this, localAccount.getAccountName()), new ServerSettings(null, spinner.getSelectedItem().toString())); - Toast.makeText(this, "New file suffix: " + newSettings.getNotesPath(), Toast.LENGTH_LONG).show(); - } catch (Exception e) { + final Call<NotesSettings> putSettingsCall = repository.putServerSettings(AccountImporter.getSingleSignOnAccount(this, localAccount.getAccountName()), new NotesSettings(null, spinner.getSelectedItem().toString()), localAccount.getPreferredApiVersion()); + putSettingsCall.enqueue(new Callback<NotesSettings>() { + @Override + public void onResponse(@NonNull Call<NotesSettings> call, @NonNull Response<NotesSettings> response) { + if (response.isSuccessful()) { + Toast.makeText(ManageAccountsActivity.this, "New file suffix: " + response.body().getNotesPath(), Toast.LENGTH_LONG).show(); + } else { + Toast.makeText(ManageAccountsActivity.this, "HTTP status code: " + response.code(), Toast.LENGTH_LONG).show(); + } + } + + @Override + public void onFailure(@NonNull Call<NotesSettings> call, @NonNull Throwable t) { + runOnUiThread(() -> ExceptionDialogFragment.newInstance(t).show(getSupportFragmentManager(), ExceptionDialogFragment.class.getSimpleName())); + } + }); + } catch (NextcloudFilesAppAccountNotFoundException e) { ExceptionDialogFragment.newInstance(e).show(getSupportFragmentManager(), ExceptionDialogFragment.class.getSimpleName()); } }).start()) .show(); - new Thread(() -> { - try { - final ServerSettings oldSettings = client.getServerSettings(AccountImporter.getSingleSignOnAccount(this, localAccount.getAccountName())); - for (int i = 0; i < adapter.getCount(); i++) { - if (adapter.getItem(i).equals(oldSettings.getFileSuffix())) { - spinner.setSelection(i); - break; - } + try { + final Call<NotesSettings> oldSettingsCall = repository.getServerSettings(AccountImporter.getSingleSignOnAccount(this, localAccount.getAccountName()), localAccount.getPreferredApiVersion()); + oldSettingsCall.enqueue(new Callback<NotesSettings>() { + @Override + public void onResponse(@NonNull Call<NotesSettings> call, @NonNull Response<NotesSettings> response) { + runOnUiThread(() -> { + if (response.isSuccessful()) { + for (int i = 0; i < adapter.getCount(); i++) { + if (adapter.getItem(i).equals(response.body().getFileSuffix())) { + spinner.setSelection(i); + break; + } + } + spinner.setEnabled(true); + } else { + ExceptionDialogFragment.newInstance(new Exception("HTTP status code: " + response.code())).show(getSupportFragmentManager(), ExceptionDialogFragment.class.getSimpleName()); + } + }); } - spinner.setEnabled(true); - } catch (Exception e) { - dialog.dismiss(); - ExceptionDialogFragment.newInstance(e).show(getSupportFragmentManager(), ExceptionDialogFragment.class.getSimpleName()); - } - }).start(); + + @Override + public void onFailure(@NonNull Call<NotesSettings> call, @NonNull Throwable t) { + dialog.dismiss(); + ExceptionDialogFragment.newInstance(t).show(getSupportFragmentManager(), ExceptionDialogFragment.class.getSimpleName()); + } + }); + } catch (NextcloudFilesAppAccountNotFoundException e) { + dialog.dismiss(); + ExceptionDialogFragment.newInstance(e).show(getSupportFragmentManager(), ExceptionDialogFragment.class.getSimpleName()); + } } @NonNull diff --git a/app/src/main/java/it/niedermann/owncloud/notes/manageaccounts/ManageAccountsViewModel.java b/app/src/main/java/it/niedermann/owncloud/notes/manageaccounts/ManageAccountsViewModel.java new file mode 100644 index 00000000..2ee45cf8 --- /dev/null +++ b/app/src/main/java/it/niedermann/owncloud/notes/manageaccounts/ManageAccountsViewModel.java @@ -0,0 +1,74 @@ +package it.niedermann.owncloud.notes.manageaccounts; + +import android.app.Application; +import android.content.Context; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.lifecycle.AndroidViewModel; +import androidx.lifecycle.LiveData; + +import com.nextcloud.android.sso.exceptions.NextcloudFilesAppAccountNotFoundException; +import com.nextcloud.android.sso.exceptions.NoCurrentAccountSelectedException; +import com.nextcloud.android.sso.helper.SingleAccountHelper; + +import java.util.List; + +import it.niedermann.owncloud.notes.persistence.NotesDatabase; +import it.niedermann.owncloud.notes.persistence.NotesRepository; +import it.niedermann.owncloud.notes.persistence.entity.Account; +import it.niedermann.owncloud.notes.shared.model.IResponseCallback; + +import static androidx.lifecycle.Transformations.distinctUntilChanged; + +public class ManageAccountsViewModel extends AndroidViewModel { + + private static final String TAG = ManageAccountsViewModel.class.getSimpleName(); + + @NonNull + private final NotesRepository repo; + + public ManageAccountsViewModel(@NonNull Application application) { + super(application); + this.repo = NotesRepository.getInstance(application); + } + + public void getCurrentAccount(@NonNull Context context, @NonNull IResponseCallback<Account> callback) { + try { + callback.onSuccess(repo.getAccountByName((SingleAccountHelper.getCurrentSingleSignOnAccount(context).name))); + } catch (NextcloudFilesAppAccountNotFoundException | NoCurrentAccountSelectedException e) { + callback.onError(e); + } + } + + public LiveData<List<Account>> getAccounts$() { + return distinctUntilChanged(repo.getAccounts$()); + } + + public void deleteAccount(@NonNull Account account, @NonNull Context context) { + new Thread(() -> { + final List<Account> accounts = repo.getAccounts(); + for (int i = 0; i < accounts.size(); i++) { + if (accounts.get(i).getId() == account.getId()) { + if (i > 0) { + selectAccount(accounts.get(i - 1), context); + } else if (accounts.size() > 1) { + selectAccount(accounts.get(i + 1), context); + } else { + selectAccount(null, context); + } + repo.deleteAccount(accounts.get(i)); + break; + } + } + }).start(); + } + + public void selectAccount(@Nullable Account account, @NonNull Context context) { + SingleAccountHelper.setCurrentAccount(context, (account == null) ? null : account.getAccountName()); + } + + public void countUnsynchronizedNotes(long accountId, @NonNull IResponseCallback<Long> callback) { + new Thread(() -> callback.onSuccess(repo.countUnsynchronizedNotes(accountId))).start(); + } +}
\ No newline at end of file |