Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/stefan-niedermann/nextcloud-notes.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Niedermann <info@niedermann.it>2021-04-29 12:09:18 +0300
committerStefan Niedermann <info@niedermann.it>2021-04-29 12:09:18 +0300
commit258d7734ea7038d4ad893e5991dde70d06c094fc (patch)
treed8e32457fd9d7ca39acae945d97150290c7e6741
parent63cf471530459dc2dcccac8437f83e1638b6c2fa (diff)
parent4b292b6d0486dc5acb112dcd5540d19f4d7c915a (diff)
Merge branch 'master' into 1167-retrofit
# Conflicts: # app/src/main/java/it/niedermann/owncloud/notes/importaccount/ImportAccountActivity.java
-rw-r--r--app/build.gradle4
-rw-r--r--app/src/main/java/it/niedermann/owncloud/notes/importaccount/ImportAccountActivity.java32
-rw-r--r--app/src/main/java/it/niedermann/owncloud/notes/importaccount/ImportAccountViewModel.java5
-rw-r--r--app/src/main/java/it/niedermann/owncloud/notes/main/MainActivity.java30
-rw-r--r--app/src/main/java/it/niedermann/owncloud/notes/main/MainViewModel.java4
-rw-r--r--app/src/main/java/it/niedermann/owncloud/notes/persistence/NotesRepository.java14
-rw-r--r--app/src/main/res/values-cs-rCZ/strings.xml9
-rw-r--r--app/src/main/res/values-de/strings.xml7
-rw-r--r--app/src/main/res/values-eu/strings.xml4
-rw-r--r--app/src/main/res/values-pl/strings.xml9
-rw-r--r--app/src/main/res/values-tr/strings.xml7
-rw-r--r--app/src/main/res/values-zh-rCN/strings.xml6
-rw-r--r--app/src/main/res/values-zh-rHK/strings.xml6
-rw-r--r--app/src/test/java/it/niedermann/owncloud/notes/persistence/NotesRepositoryTest.java44
-rw-r--r--fastlane/metadata/android/en-US/changelogs/3004001.txt4
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