diff options
author | Stefan Niedermann <info@niedermann.it> | 2021-04-29 12:09:18 +0300 |
---|---|---|
committer | Stefan Niedermann <info@niedermann.it> | 2021-04-29 12:09:18 +0300 |
commit | 258d7734ea7038d4ad893e5991dde70d06c094fc (patch) | |
tree | d8e32457fd9d7ca39acae945d97150290c7e6741 | |
parent | 63cf471530459dc2dcccac8437f83e1638b6c2fa (diff) | |
parent | 4b292b6d0486dc5acb112dcd5540d19f4d7c915a (diff) |
Merge branch 'master' into 1167-retrofit
# Conflicts:
# app/src/main/java/it/niedermann/owncloud/notes/importaccount/ImportAccountActivity.java
15 files changed, 140 insertions, 45 deletions
diff --git a/app/build.gradle b/app/build.gradle index 4aa25400..27f6a08b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -14,8 +14,8 @@ android { applicationId "it.niedermann.owncloud.notes" minSdkVersion 21 targetSdkVersion 29 - versionCode 3004000 - versionName "3.4.0" + versionCode 3004001 + versionName "3.4.1" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" javaCompileOptions { annotationProcessorOptions { diff --git a/app/src/main/java/it/niedermann/owncloud/notes/importaccount/ImportAccountActivity.java b/app/src/main/java/it/niedermann/owncloud/notes/importaccount/ImportAccountActivity.java index 8446dbb6..6d03327a 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/importaccount/ImportAccountActivity.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/importaccount/ImportAccountActivity.java @@ -8,7 +8,6 @@ import android.view.View; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; -import androidx.lifecycle.LiveData; import androidx.lifecycle.ViewModelProvider; import com.nextcloud.android.sso.AccountImporter; @@ -31,6 +30,7 @@ import it.niedermann.owncloud.notes.persistence.CapabilitiesClient; import it.niedermann.owncloud.notes.persistence.SSOClient; import it.niedermann.owncloud.notes.persistence.entity.Account; import it.niedermann.owncloud.notes.shared.model.Capabilities; +import it.niedermann.owncloud.notes.shared.model.IResponseCallback; public class ImportAccountActivity extends AppCompatActivity { @@ -89,18 +89,25 @@ public class ImportAccountActivity extends AppCompatActivity { try { Log.i(TAG, "Loading capabilities for " + ssoAccount.name); final Capabilities capabilities = CapabilitiesClient.getCapabilities(getApplicationContext(), ssoAccount, null); - LiveData<Account> createLiveData = importAccountViewModel.addAccount(ssoAccount.url, ssoAccount.userId, ssoAccount.name, capabilities); - runOnUiThread(() -> createLiveData.observe(this, (account) -> { - if (account != null) { - Log.i(TAG, capabilities.toString()); - BrandingUtil.saveBrandColors(this, capabilities.getColor(), capabilities.getTextColor()); - setResult(RESULT_OK); - finish(); - } else { - binding.addButton.setEnabled(true); - ExceptionDialogFragment.newInstance(new IllegalStateException("Created account is null.")).show(getSupportFragmentManager(), ExceptionDialogFragment.class.getSimpleName()); + importAccountViewModel.addAccount(ssoAccount.url, ssoAccount.userId, ssoAccount.name, capabilities, new IResponseCallback<Account>() { + @Override + public void onSuccess(Account account) { + runOnUiThread(() -> { + Log.i(TAG, capabilities.toString()); + BrandingUtil.saveBrandColors(ImportAccountActivity.this, capabilities.getColor(), capabilities.getTextColor()); + setResult(RESULT_OK); + finish(); + }); + } + + @Override + public void onError(@NonNull Throwable t) { + runOnUiThread(() -> { + binding.addButton.setEnabled(true); + ExceptionDialogFragment.newInstance(t).show(getSupportFragmentManager(), ExceptionDialogFragment.class.getSimpleName()); + }); } - })); + }); } catch (Throwable t) { t.printStackTrace(); SSOClient.invalidateAPICache(ssoAccount); @@ -114,6 +121,7 @@ public class ImportAccountActivity extends AppCompatActivity { binding.status.setText(getString(R.string.error_sync, getString(R.string.error_no_network))); binding.status.setVisibility(View.VISIBLE); } else if (t instanceof UnknownErrorException && t.getMessage().contains("No address associated with hostname")) { + // https://github.com/stefan-niedermann/nextcloud-notes/issues/1014 binding.status.setText(R.string.you_have_to_be_connected_to_the_internet_in_order_to_add_an_account); binding.status.setVisibility(View.VISIBLE); } else { diff --git a/app/src/main/java/it/niedermann/owncloud/notes/importaccount/ImportAccountViewModel.java b/app/src/main/java/it/niedermann/owncloud/notes/importaccount/ImportAccountViewModel.java index abcf68e3..905a59b1 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/importaccount/ImportAccountViewModel.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/importaccount/ImportAccountViewModel.java @@ -9,6 +9,7 @@ import androidx.lifecycle.LiveData; import it.niedermann.owncloud.notes.persistence.NotesRepository; import it.niedermann.owncloud.notes.persistence.entity.Account; import it.niedermann.owncloud.notes.shared.model.Capabilities; +import it.niedermann.owncloud.notes.shared.model.IResponseCallback; public class ImportAccountViewModel extends AndroidViewModel { @@ -22,7 +23,7 @@ public class ImportAccountViewModel extends AndroidViewModel { this.repo = NotesRepository.getInstance(application); } - public LiveData<Account> addAccount(@NonNull String url, @NonNull String username, @NonNull String accountName, @NonNull Capabilities capabilities) { - return repo.addAccount(url, username, accountName, capabilities); + public void addAccount(@NonNull String url, @NonNull String username, @NonNull String accountName, @NonNull Capabilities capabilities, @NonNull IResponseCallback<Account> callback) { + repo.addAccount(url, username, accountName, capabilities, callback); } } diff --git a/app/src/main/java/it/niedermann/owncloud/notes/main/MainActivity.java b/app/src/main/java/it/niedermann/owncloud/notes/main/MainActivity.java index cd67ea13..ef518c2b 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/main/MainActivity.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/main/MainActivity.java @@ -43,6 +43,7 @@ import com.nextcloud.android.sso.exceptions.NextcloudFilesAppAccountNotFoundExce import com.nextcloud.android.sso.exceptions.NextcloudHttpRequestFailedException; import com.nextcloud.android.sso.exceptions.NoCurrentAccountSelectedException; import com.nextcloud.android.sso.exceptions.TokenMismatchException; +import com.nextcloud.android.sso.exceptions.UnknownErrorException; import com.nextcloud.android.sso.helper.SingleAccountHelper; import java.net.HttpURLConnection; @@ -74,6 +75,7 @@ import it.niedermann.owncloud.notes.main.navigation.NavigationClickListener; import it.niedermann.owncloud.notes.main.navigation.NavigationItem; import it.niedermann.owncloud.notes.persistence.CapabilitiesClient; import it.niedermann.owncloud.notes.persistence.CapabilitiesWorker; +import it.niedermann.owncloud.notes.persistence.SSOClient; import it.niedermann.owncloud.notes.persistence.entity.Account; import it.niedermann.owncloud.notes.persistence.entity.Note; import it.niedermann.owncloud.notes.shared.model.Capabilities; @@ -646,16 +648,23 @@ public class MainActivity extends LockedActivity implements NoteClickListener, A try { Log.i(TAG, "Refreshing capabilities for " + ssoAccount.name); final Capabilities capabilities = CapabilitiesClient.getCapabilities(getApplicationContext(), ssoAccount, null); - LiveData<Account> createLiveData = mainViewModel.addAccount(ssoAccount.url, ssoAccount.userId, ssoAccount.name, capabilities); - runOnUiThread(() -> createLiveData.observe(this, (account) -> { - createLiveData.removeObservers(this); - new Thread(() -> { - Log.i(TAG, capabilities.toString()); - final Account a = mainViewModel.getLocalAccountByAccountName(ssoAccount.name); - runOnUiThread(() -> mainViewModel.postCurrentAccount(a)); - }).start(); - })); + mainViewModel.addAccount(ssoAccount.url, ssoAccount.userId, ssoAccount.name, capabilities, new IResponseCallback<Account>() { + @Override + public void onSuccess(Account result) { + new Thread(() -> { + Log.i(TAG, capabilities.toString()); + final Account a = mainViewModel.getLocalAccountByAccountName(ssoAccount.name); + runOnUiThread(() -> mainViewModel.postCurrentAccount(a)); + }).start(); + } + + @Override + public void onError(@NonNull Throwable t) { + runOnUiThread(() -> ExceptionDialogFragment.newInstance(t).show(getSupportFragmentManager(), ExceptionDialogFragment.class.getSimpleName())); + } + }); } catch (Exception e) { + SSOClient.invalidateAPICache(ssoAccount); // Happens when importing an already existing account the second time if (e instanceof TokenMismatchException && mainViewModel.getLocalAccountByAccountName(ssoAccount.name) != null) { Log.w(TAG, "Received " + TokenMismatchException.class.getSimpleName() + " and the given ssoAccount.name (" + ssoAccount.name + ") does already exist in the database. Assume that this account has already been imported."); @@ -664,6 +673,9 @@ public class MainActivity extends LockedActivity implements NoteClickListener, A // TODO there is already a sync in progress and results in displaying a TokenMissMatchException snackbar which conflicts with this one coordinatorLayout.post(() -> BrandedSnackbar.make(coordinatorLayout, R.string.account_already_imported, Snackbar.LENGTH_LONG).show()); }); + } else if (e instanceof UnknownErrorException && e.getMessage().contains("No address associated with hostname")) { + // https://github.com/stefan-niedermann/nextcloud-notes/issues/1014 + runOnUiThread(() -> Snackbar.make(coordinatorLayout, R.string.you_have_to_be_connected_to_the_internet_in_order_to_add_an_account, Snackbar.LENGTH_LONG).show()); } else { e.printStackTrace(); runOnUiThread(() -> { diff --git a/app/src/main/java/it/niedermann/owncloud/notes/main/MainViewModel.java b/app/src/main/java/it/niedermann/owncloud/notes/main/MainViewModel.java index 4e4d0195..1eca83a5 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/main/MainViewModel.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/main/MainViewModel.java @@ -530,8 +530,8 @@ public class MainViewModel extends AndroidViewModel { }); } - public LiveData<Account> addAccount(@NonNull String url, @NonNull String username, @NonNull String accountName, @NonNull Capabilities capabilities) { - return repo.addAccount(url, username, accountName, capabilities); + public void addAccount(@NonNull String url, @NonNull String username, @NonNull String accountName, @NonNull Capabilities capabilities, @NonNull IResponseCallback<Account> callback) { + repo.addAccount(url, username, accountName, capabilities, callback); } public LiveData<Note> getFullNote$(long id) { diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/NotesRepository.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/NotesRepository.java index fed86489..aa5fe39d 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/persistence/NotesRepository.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/NotesRepository.java @@ -57,6 +57,7 @@ import it.niedermann.owncloud.notes.shared.model.Capabilities; import it.niedermann.owncloud.notes.shared.model.CategorySortingMethod; import it.niedermann.owncloud.notes.shared.model.DBStatus; import it.niedermann.owncloud.notes.shared.model.ENavigationCategoryType; +import it.niedermann.owncloud.notes.shared.model.IResponseCallback; import it.niedermann.owncloud.notes.shared.model.ISyncCallback; import it.niedermann.owncloud.notes.shared.model.NavigationCategory; import it.niedermann.owncloud.notes.shared.model.SyncResultStatus; @@ -160,8 +161,13 @@ public class NotesRepository { // Accounts @AnyThread - public LiveData<Account> addAccount(@NonNull String url, @NonNull String username, @NonNull String accountName, @NonNull Capabilities capabilities) { - return db.getAccountDao().getAccountById$(db.getAccountDao().insert(new Account(url, username, accountName, capabilities))); + public void addAccount(@NonNull String url, @NonNull String username, @NonNull String accountName, @NonNull Capabilities capabilities, @NonNull IResponseCallback<Account> callback) { + final Account createdAccount = db.getAccountDao().getAccountById(db.getAccountDao().insert(new Account(url, username, accountName, capabilities))); + if (createdAccount == null) { + callback.onError(new Exception("Could not read created account.")); + } else { + callback.onSuccess(createdAccount); + } } @WorkerThread @@ -772,7 +778,7 @@ public class NotesRepository { * * @param onlyLocalChanges Whether to only push local changes to the server or to also load the whole list of notes from the server. */ - public void scheduleSync(Account account, boolean onlyLocalChanges) { + public synchronized void scheduleSync(Account account, boolean onlyLocalChanges) { if (account == null) { Log.i(TAG, SingleSignOnAccount.class.getSimpleName() + " is null. Is this a local account?"); } else { @@ -781,6 +787,7 @@ public class NotesRepository { } Log.d(TAG, "Sync requested (" + (onlyLocalChanges ? "onlyLocalChanges" : "full") + "; " + (Boolean.TRUE.equals(syncActive.get(account.getId())) ? "sync active" : "sync NOT active") + ") ..."); if (isSyncPossible() && (!Boolean.TRUE.equals(syncActive.get(account.getId())) || onlyLocalChanges)) { + syncActive.put(account.getId(), true); try { Log.d(TAG, "... starting now"); final NotesServerSyncTask syncTask = new NotesServerSyncTask(context, this, account, onlyLocalChanges) { @@ -793,7 +800,6 @@ public class NotesRepository { if (!onlyLocalChanges && Boolean.TRUE.equals(syncScheduled.get(localAccount.getId()))) { syncScheduled.put(localAccount.getId(), false); } - syncActive.put(localAccount.getId(), true); } @Override diff --git a/app/src/main/res/values-cs-rCZ/strings.xml b/app/src/main/res/values-cs-rCZ/strings.xml index 100d57c2..a5252866 100644 --- a/app/src/main/res/values-cs-rCZ/strings.xml +++ b/app/src/main/res/values-cs-rCZ/strings.xml @@ -257,6 +257,13 @@ <string name="no_other_accounts">Zatím jste nenastavili žádné další účty.</string> <string name="choose_account">Zvolte účet</string> <string name="context_based_formatting">Kontextové vyskakovací okno formátování</string> + <plurals name="remove_account_message"> + <item quantity="one">Odebrání účtu %1$s také nenahraditelně odstraní jednu nesynchronizovanou změnu.</item> + <item quantity="few">Odebrání účtu %1$s také nenahraditelně odstraní %2$d nesynchronizovaných změn.</item> + <item quantity="many">Odebrání účtu %1$s také nenahraditelně odstraní %2$d nesynchronizovaných změn.</item> + <item quantity="other">Odebrání účtu %1$s také nenahraditelně odstraní %2$d nesynchronizované změny.</item> + </plurals> <string name="remove_account">Odebrat %1$s</string> - </resources> + <string name="you_have_to_be_connected_to_the_internet_in_order_to_add_an_account">Abyste mohli přidat účet je třeba, abyste byli připojení k Internetu.</string> +</resources> diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index f248617d..a90c81e1 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -249,6 +249,11 @@ <string name="no_other_accounts">Sie haben bislang keine weiteren Konten eingerichtet.</string> <string name="choose_account">Konto auswählen</string> <string name="context_based_formatting">Popup für die kontextbasierte Formatierung</string> + <plurals name="remove_account_message"> + <item quantity="one">Beim Entfernen des Kontos %1$s wird auch eine unsynchronisierte Änderung unwiderruflich gelöscht werden.</item> + <item quantity="other">Beim Entfernen des Kontos %1$s werden auch %2$d unsynchronisierte Änderungen unwiderruflich gelöscht werden.</item> + </plurals> <string name="remove_account">%1$s entfernen</string> - </resources> + <string name="you_have_to_be_connected_to_the_internet_in_order_to_add_an_account">Sie müssen mit dem Internet verbunden sein, um ein Konto hinzufügen zu können.</string> +</resources> diff --git a/app/src/main/res/values-eu/strings.xml b/app/src/main/res/values-eu/strings.xml index dc0e4c8e..187fd1ee 100644 --- a/app/src/main/res/values-eu/strings.xml +++ b/app/src/main/res/values-eu/strings.xml @@ -13,6 +13,7 @@ <string name="action_sorting_method">Ordenatze metodoa</string> <string name="simple_cancel">Utzi</string> <string name="simple_edit">Editatu</string> + <string name="simple_remove">Kendu</string> <string name="action_edit_save">Gorde</string> <string name="simple_about">Honi buruz</string> <string name="simple_link">Esteka</string> @@ -248,4 +249,5 @@ <string name="no_other_accounts">Oraindik ez duzu konturik konfiguratu.</string> <string name="choose_account">Aukeratu kontua</string> <string name="context_based_formatting">Testuinguruan oinarritutako formateatze leiho gainerakorra </string> - </resources> + <string name="you_have_to_be_connected_to_the_internet_in_order_to_add_an_account">Kontu bat gehitzeko internetera konektatuta egon behar zara.</string> +</resources> diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 5b335eed..cd513c01 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -257,6 +257,13 @@ <string name="no_other_accounts">Nie masz jeszcze skonfigurowanych żadnych innych kont.</string> <string name="choose_account">Wybierz konto</string> <string name="context_based_formatting">Okno podręczne formatowania opartego na kontekście</string> + <plurals name="remove_account_message"> + <item quantity="one">Usunięcie konta %1$s, usunie również nieodwracalnie jedną niezsynchronizowaną zmianę.</item> + <item quantity="few">Usunięcie konta %1$s, usunie również nieodwracalnie %2$d niezsynchronizowane zmiany.</item> + <item quantity="many">Usunięcie konta %1$s, usunie również nieodwracalnie %2$d niezsynchronizowanych zmian.</item> + <item quantity="other">Usunięcie konta %1$s, usunie również nieodwracalnie %2$d niezsynchronizowanych zmian.</item> + </plurals> <string name="remove_account">Usuń %1$s</string> - </resources> + <string name="you_have_to_be_connected_to_the_internet_in_order_to_add_an_account">Aby dodać konto, musisz mieć połączenie z Internetem.</string> +</resources> diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index cdbbf653..537b7c52 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -249,6 +249,11 @@ <string name="no_other_accounts">Henüz başka bir hesap yapılandırmamışsınız.</string> <string name="choose_account">Hesap seçin</string> <string name="context_based_formatting">Bağlam tabanlı biçimlendirme açılan penceresi</string> + <plurals name="remove_account_message"> + <item quantity="one">%1$s hesabı silindiğinde bir eşitlenmemiş değişiklik de geri alınamayacak şekilde silinecek.</item> + <item quantity="other">%1$s hesabı silindiğinde %2$d eşitlenmemiş değişiklik de geri alınamayacak şekilde silinecek.</item> + </plurals> <string name="remove_account">%1$s sil</string> - </resources> + <string name="you_have_to_be_connected_to_the_internet_in_order_to_add_an_account">Bir hesap ekleyebilmeniz için çalışan bir İnternet bağlantınız olmalı.</string> +</resources> diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 942bf45b..df7c0011 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -245,6 +245,10 @@ <string name="no_other_accounts">您尚未配置任何其他帐户。</string> <string name="choose_account">选择一个账户</string> <string name="context_based_formatting">基于上下文的格式弹出窗口 </string> + <plurals name="remove_account_message"> + <item quantity="other">移除账户 %1$s 会同样不可恢复地删除 %2$d 未同步的更改</item> + </plurals> <string name="remove_account">移除 %1$s</string> - </resources> + <string name="you_have_to_be_connected_to_the_internet_in_order_to_add_an_account">要添加账号,你必须连接到互联网。</string> +</resources> diff --git a/app/src/main/res/values-zh-rHK/strings.xml b/app/src/main/res/values-zh-rHK/strings.xml index 55a9eb64..026d4682 100644 --- a/app/src/main/res/values-zh-rHK/strings.xml +++ b/app/src/main/res/values-zh-rHK/strings.xml @@ -245,6 +245,10 @@ <string name="no_other_accounts">你尚未設定其它帳號。</string> <string name="choose_account">選擇賬戶</string> <string name="context_based_formatting">基於 context 的格式彈出框</string> + <plurals name="remove_account_message"> + <item quantity="other">刪除賬戶 %1$s 還將刪除 %2$d 個無法恢復的非同步更改。</item> + </plurals> <string name="remove_account">移除 %1$s</string> - </resources> + <string name="you_have_to_be_connected_to_the_internet_in_order_to_add_an_account">您必須連線到互聯網才能新增賬戶。</string> +</resources> diff --git a/app/src/test/java/it/niedermann/owncloud/notes/persistence/NotesRepositoryTest.java b/app/src/test/java/it/niedermann/owncloud/notes/persistence/NotesRepositoryTest.java index d4253ea2..11c58dde 100644 --- a/app/src/test/java/it/niedermann/owncloud/notes/persistence/NotesRepositoryTest.java +++ b/app/src/test/java/it/niedermann/owncloud/notes/persistence/NotesRepositoryTest.java @@ -3,6 +3,7 @@ package it.niedermann.owncloud.notes.persistence; import android.content.Context; import android.os.Build; +import androidx.annotation.NonNull; import androidx.arch.core.executor.testing.InstantTaskExecutorRule; import androidx.room.Room; import androidx.test.core.app.ApplicationProvider; @@ -30,6 +31,7 @@ import java.util.concurrent.ExecutorService; import it.niedermann.owncloud.notes.persistence.entity.Account; import it.niedermann.owncloud.notes.persistence.entity.Note; import it.niedermann.owncloud.notes.shared.model.Capabilities; +import it.niedermann.owncloud.notes.shared.model.IResponseCallback; import static it.niedermann.owncloud.notes.persistence.NotesDatabaseTestUtil.getOrAwaitValue; import static it.niedermann.owncloud.notes.shared.model.DBStatus.LOCAL_DELETED; @@ -38,6 +40,7 @@ import static it.niedermann.owncloud.notes.shared.model.DBStatus.VOID; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThrows; +import static org.junit.Assert.fail; @RunWith(RobolectricTestRunner.class) @Config(sdk = {Build.VERSION_CODES.P}) @@ -63,10 +66,30 @@ public class NotesRepositoryTest { constructor.setAccessible(true); repo = constructor.newInstance(context, db, MoreExecutors.newDirectExecutorService()); - repo.addAccount("https://äöüß.example.com", "彼得", "彼得@äöüß.example.com", new Capabilities("{\"ocs\":{\"meta\":{\"status\":\"ok\",\"statuscode\":200,\"message\":\"OK\"},\"data\":{\"version\":{\"major\":18,\"minor\":0,\"micro\":4,\"string\":\"18.0.4\",\"edition\":\"\",\"extendedSupport\":false},\"capabilities\":{\"core\":{\"pollinterval\":60,\"webdav-root\":\"remote.php\\/webdav\"},\"bruteforce\":{\"delay\":0},\"files\":{\"bigfilechunking\":true,\"blacklisted_files\":[\".htaccess\"],\"directEditing\":{\"url\":\"https:\\/\\/efss.qloud.my\\/ocs\\/v2.php\\/apps\\/files\\/api\\/v1\\/directEditing\",\"etag\":\"ed2b141af2a39b0e42666952ba60988d\"},\"versioning\":true,\"undelete\":true},\"activity\":{\"apiv2\":[\"filters\",\"filters-api\",\"previews\",\"rich-strings\"]},\"ocm\":{\"enabled\":true,\"apiVersion\":\"1.0-proposal1\",\"endPoint\":\"https:\\/\\/efss.qloud.my\\/index.php\\/ocm\",\"resourceTypes\":[{\"name\":\"file\",\"shareTypes\":[\"user\",\"group\"],\"protocols\":{\"webdav\":\"\\/public.php\\/webdav\\/\"}}]},\"deck\":{\"version\":\"0.8.2\"},\"richdocuments\":{\"mimetypes\":[\"application\\/vnd.oasis.opendocument.text\",\"application\\/vnd.oasis.opendocument.spreadsheet\",\"application\\/vnd.oasis.opendocument.graphics\",\"application\\/vnd.oasis.opendocument.presentation\",\"application\\/vnd.lotus-wordpro\",\"application\\/vnd.visio\",\"application\\/vnd.wordperfect\",\"application\\/msonenote\",\"application\\/msword\",\"application\\/rtf\",\"text\\/rtf\",\"application\\/vnd.openxmlformats-officedocument.wordprocessingml.document\",\"application\\/vnd.openxmlformats-officedocument.wordprocessingml.template\",\"application\\/vnd.ms-word.document.macroEnabled.12\",\"application\\/vnd.ms-word.template.macroEnabled.12\",\"application\\/vnd.ms-excel\",\"application\\/vnd.openxmlformats-officedocument.spreadsheetml.sheet\",\"application\\/vnd.openxmlformats-officedocument.spreadsheetml.template\",\"application\\/vnd.ms-excel.sheet.macroEnabled.12\",\"application\\/vnd.ms-excel.template.macroEnabled.12\",\"application\\/vnd.ms-excel.addin.macroEnabled.12\",\"application\\/vnd.ms-excel.sheet.binary.macroEnabled.12\",\"application\\/vnd.ms-powerpoint\",\"application\\/vnd.openxmlformats-officedocument.presentationml.presentation\",\"application\\/vnd.openxmlformats-officedocument.presentationml.template\",\"application\\/vnd.openxmlformats-officedocument.presentationml.slideshow\",\"application\\/vnd.ms-powerpoint.addin.macroEnabled.12\",\"application\\/vnd.ms-powerpoint.presentation.macroEnabled.12\",\"application\\/vnd.ms-powerpoint.template.macroEnabled.12\",\"application\\/vnd.ms-powerpoint.slideshow.macroEnabled.12\",\"text\\/csv\"],\"mimetypesNoDefaultOpen\":[\"image\\/svg+xml\",\"application\\/pdf\",\"text\\/plain\",\"text\\/spreadsheet\"],\"collabora\":[],\"direct_editing\":false,\"templates\":false,\"productName\":\"\\u5728\\u7ebf\\u534f\\u4f5c\"},\"dav\":{\"chunking\":\"1.0\"},\"files_sharing\":{\"api_enabled\":true,\"public\":{\"enabled\":true,\"password\":{\"enforced\":true,\"askForOptionalPassword\":false},\"expire_date\":{\"enabled\":true,\"days\":\"7\",\"enforced\":false},\"multiple_links\":true,\"expire_date_internal\":{\"enabled\":false},\"send_mail\":false,\"upload\":true,\"upload_files_drop\":true},\"resharing\":true,\"user\":{\"send_mail\":false,\"expire_date\":{\"enabled\":true}},\"group_sharing\":true,\"group\":{\"enabled\":true,\"expire_date\":{\"enabled\":true}},\"default_permissions\":31,\"federation\":{\"outgoing\":false,\"incoming\":false,\"expire_date\":{\"enabled\":true}},\"sharee\":{\"query_lookup_default\":false},\"sharebymail\":{\"enabled\":true,\"upload_files_drop\":{\"enabled\":true},\"password\":{\"enabled\":true},\"expire_date\":{\"enabled\":true}}},\"external\":{\"v1\":[\"sites\",\"device\",\"groups\",\"redirect\"]},\"notifications\":{\"ocs-endpoints\":[\"list\",\"get\",\"delete\",\"delete-all\",\"icons\",\"rich-strings\",\"action-web\"],\"push\":[\"devices\",\"object-data\",\"delete\"],\"admin-notifications\":[\"ocs\",\"cli\"]},\"password_policy\":{\"minLength\":8,\"enforceNonCommonPassword\":true,\"enforceNumericCharacters\":false,\"enforceSpecialCharacters\":false,\"enforceUpperLowerCase\":false,\"api\":{\"generate\":\"https:\\/\\/efss.qloud.my\\/ocs\\/v2.php\\/apps\\/password_policy\\/api\\/v1\\/generate\",\"validate\":\"https:\\/\\/efss.qloud.my\\/ocs\\/v2.php\\/apps\\/password_policy\\/api\\/v1\\/validate\"}},\"theming\":{\"name\":\"QloudData\",\"url\":\"https:\\/\\/www.qloud.my\\/qloud-data\\/\",\"slogan\":\"Powered by NextCloud\",\"color\":\"#1E4164\",\"color-text\":\"#ffffff\",\"color-element\":\"#1E4164\",\"logo\":\"https:\\/\\/efss.qloud.my\\/index.php\\/apps\\/theming\\/image\\/logo?useSvg=1&v=47\",\"background\":\"https:\\/\\/efss.qloud.my\\/core\\/img\\/background.png?v=47\",\"background-plain\":false,\"background-default\":true,\"logoheader\":\"https:\\/\\/efss.qloud.my\\/index.php\\/apps\\/theming\\/image\\/logo?useSvg=1&v=47\",\"favicon\":\"https:\\/\\/efss.qloud.my\\/index.php\\/apps\\/theming\\/image\\/logo?useSvg=1&v=47\"},\"registration\":{\"enabled\":true,\"apiRoot\":\"\\/ocs\\/v2.php\\/apps\\/registration\\/api\\/v1\\/\",\"apiLevel\":\"v1\"}}}}}", null)); + repo.addAccount("https://äöüß.example.com", "彼得", "彼得@äöüß.example.com", new Capabilities("{\"ocs\":{\"meta\":{\"status\":\"ok\",\"statuscode\":200,\"message\":\"OK\"},\"data\":{\"version\":{\"major\":18,\"minor\":0,\"micro\":4,\"string\":\"18.0.4\",\"edition\":\"\",\"extendedSupport\":false},\"capabilities\":{\"core\":{\"pollinterval\":60,\"webdav-root\":\"remote.php\\/webdav\"},\"bruteforce\":{\"delay\":0},\"files\":{\"bigfilechunking\":true,\"blacklisted_files\":[\".htaccess\"],\"directEditing\":{\"url\":\"https:\\/\\/efss.qloud.my\\/ocs\\/v2.php\\/apps\\/files\\/api\\/v1\\/directEditing\",\"etag\":\"ed2b141af2a39b0e42666952ba60988d\"},\"versioning\":true,\"undelete\":true},\"activity\":{\"apiv2\":[\"filters\",\"filters-api\",\"previews\",\"rich-strings\"]},\"ocm\":{\"enabled\":true,\"apiVersion\":\"1.0-proposal1\",\"endPoint\":\"https:\\/\\/efss.qloud.my\\/index.php\\/ocm\",\"resourceTypes\":[{\"name\":\"file\",\"shareTypes\":[\"user\",\"group\"],\"protocols\":{\"webdav\":\"\\/public.php\\/webdav\\/\"}}]},\"deck\":{\"version\":\"0.8.2\"},\"richdocuments\":{\"mimetypes\":[\"application\\/vnd.oasis.opendocument.text\",\"application\\/vnd.oasis.opendocument.spreadsheet\",\"application\\/vnd.oasis.opendocument.graphics\",\"application\\/vnd.oasis.opendocument.presentation\",\"application\\/vnd.lotus-wordpro\",\"application\\/vnd.visio\",\"application\\/vnd.wordperfect\",\"application\\/msonenote\",\"application\\/msword\",\"application\\/rtf\",\"text\\/rtf\",\"application\\/vnd.openxmlformats-officedocument.wordprocessingml.document\",\"application\\/vnd.openxmlformats-officedocument.wordprocessingml.template\",\"application\\/vnd.ms-word.document.macroEnabled.12\",\"application\\/vnd.ms-word.template.macroEnabled.12\",\"application\\/vnd.ms-excel\",\"application\\/vnd.openxmlformats-officedocument.spreadsheetml.sheet\",\"application\\/vnd.openxmlformats-officedocument.spreadsheetml.template\",\"application\\/vnd.ms-excel.sheet.macroEnabled.12\",\"application\\/vnd.ms-excel.template.macroEnabled.12\",\"application\\/vnd.ms-excel.addin.macroEnabled.12\",\"application\\/vnd.ms-excel.sheet.binary.macroEnabled.12\",\"application\\/vnd.ms-powerpoint\",\"application\\/vnd.openxmlformats-officedocument.presentationml.presentation\",\"application\\/vnd.openxmlformats-officedocument.presentationml.template\",\"application\\/vnd.openxmlformats-officedocument.presentationml.slideshow\",\"application\\/vnd.ms-powerpoint.addin.macroEnabled.12\",\"application\\/vnd.ms-powerpoint.presentation.macroEnabled.12\",\"application\\/vnd.ms-powerpoint.template.macroEnabled.12\",\"application\\/vnd.ms-powerpoint.slideshow.macroEnabled.12\",\"text\\/csv\"],\"mimetypesNoDefaultOpen\":[\"image\\/svg+xml\",\"application\\/pdf\",\"text\\/plain\",\"text\\/spreadsheet\"],\"collabora\":[],\"direct_editing\":false,\"templates\":false,\"productName\":\"\\u5728\\u7ebf\\u534f\\u4f5c\"},\"dav\":{\"chunking\":\"1.0\"},\"files_sharing\":{\"api_enabled\":true,\"public\":{\"enabled\":true,\"password\":{\"enforced\":true,\"askForOptionalPassword\":false},\"expire_date\":{\"enabled\":true,\"days\":\"7\",\"enforced\":false},\"multiple_links\":true,\"expire_date_internal\":{\"enabled\":false},\"send_mail\":false,\"upload\":true,\"upload_files_drop\":true},\"resharing\":true,\"user\":{\"send_mail\":false,\"expire_date\":{\"enabled\":true}},\"group_sharing\":true,\"group\":{\"enabled\":true,\"expire_date\":{\"enabled\":true}},\"default_permissions\":31,\"federation\":{\"outgoing\":false,\"incoming\":false,\"expire_date\":{\"enabled\":true}},\"sharee\":{\"query_lookup_default\":false},\"sharebymail\":{\"enabled\":true,\"upload_files_drop\":{\"enabled\":true},\"password\":{\"enabled\":true},\"expire_date\":{\"enabled\":true}}},\"external\":{\"v1\":[\"sites\",\"device\",\"groups\",\"redirect\"]},\"notifications\":{\"ocs-endpoints\":[\"list\",\"get\",\"delete\",\"delete-all\",\"icons\",\"rich-strings\",\"action-web\"],\"push\":[\"devices\",\"object-data\",\"delete\"],\"admin-notifications\":[\"ocs\",\"cli\"]},\"password_policy\":{\"minLength\":8,\"enforceNonCommonPassword\":true,\"enforceNumericCharacters\":false,\"enforceSpecialCharacters\":false,\"enforceUpperLowerCase\":false,\"api\":{\"generate\":\"https:\\/\\/efss.qloud.my\\/ocs\\/v2.php\\/apps\\/password_policy\\/api\\/v1\\/generate\",\"validate\":\"https:\\/\\/efss.qloud.my\\/ocs\\/v2.php\\/apps\\/password_policy\\/api\\/v1\\/validate\"}},\"theming\":{\"name\":\"QloudData\",\"url\":\"https:\\/\\/www.qloud.my\\/qloud-data\\/\",\"slogan\":\"Powered by NextCloud\",\"color\":\"#1E4164\",\"color-text\":\"#ffffff\",\"color-element\":\"#1E4164\",\"logo\":\"https:\\/\\/efss.qloud.my\\/index.php\\/apps\\/theming\\/image\\/logo?useSvg=1&v=47\",\"background\":\"https:\\/\\/efss.qloud.my\\/core\\/img\\/background.png?v=47\",\"background-plain\":false,\"background-default\":true,\"logoheader\":\"https:\\/\\/efss.qloud.my\\/index.php\\/apps\\/theming\\/image\\/logo?useSvg=1&v=47\",\"favicon\":\"https:\\/\\/efss.qloud.my\\/index.php\\/apps\\/theming\\/image\\/logo?useSvg=1&v=47\"},\"registration\":{\"enabled\":true,\"apiRoot\":\"\\/ocs\\/v2.php\\/apps\\/registration\\/api\\/v1\\/\",\"apiLevel\":\"v1\"}}}}}", null), new IResponseCallback<Account>() { + @Override + public void onSuccess(Account result) { + + } + + @Override + public void onError(@NonNull Throwable t) { + fail(); + } + }); account = repo.getAccountByName("彼得@äöüß.example.com"); - repo.addAccount("https://example.org", "test", "test@example.org", new Capabilities("{ocs: {}}", null)); + repo.addAccount("https://example.org", "test", "test@example.org", new Capabilities("{ocs: {}}", null), new IResponseCallback<Account>() { + @Override + public void onSuccess(Account result) { + + } + + @Override + public void onError(@NonNull Throwable t) { + fail(); + } + }); secondAccount = repo.getAccountByName("test@example.org"); Arrays.stream(new Note[]{ @@ -102,10 +125,19 @@ public class NotesRepositoryTest { @Test public void testAddAccount() throws NextcloudHttpRequestFailedException, InterruptedException { - final Account createdAccount = getOrAwaitValue(repo.addAccount("https://äöüß.example.com", "彼得", "彼得@äöüß.example.com", new Capabilities("{ocs: {}}", null))); - assertEquals("https://äöüß.example.com", createdAccount.getUrl()); - assertEquals("彼得", createdAccount.getUserName()); - assertEquals("彼得@äöüß.example.com", createdAccount.getAccountName()); + repo.addAccount("https://äöüß.example.com", "彼得", "彼得@äöüß.example.com", new Capabilities("{ocs: {}}", null), new IResponseCallback<Account>() { + @Override + public void onSuccess(Account createdAccount) { + assertEquals("https://äöüß.example.com", createdAccount.getUrl()); + assertEquals("彼得", createdAccount.getUserName()); + assertEquals("彼得@äöüß.example.com", createdAccount.getAccountName()); + } + + @Override + public void onError(@NonNull Throwable t) { + fail(); + } + }); } @Test diff --git a/fastlane/metadata/android/en-US/changelogs/3004001.txt b/fastlane/metadata/android/en-US/changelogs/3004001.txt index 42471085..1a2e41bf 100644 --- a/fastlane/metadata/android/en-US/changelogs/3004001.txt +++ b/fastlane/metadata/android/en-US/changelogs/3004001.txt @@ -1,3 +1,5 @@ - ⚠️️ Display confirm dialog when deleting an account with unsynchronized changes (#989) - by @AlpAcA0072 - ➖ Allow dashes in note titles (#1104) -- 🌐 Support links in tables (#1115)
\ No newline at end of file +- 🌐 Support links in tables (#1115) +- 🔌 Handle offline state when adding accounts (#1014) +- 🐞 Fix parallel synchronization issues which can lead to duplicate primary keys
\ No newline at end of file |