diff --git a/app/build.gradle b/app/build.gradle index 68fb851d..b795ef11 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -76,7 +76,7 @@ android { } dependencies { - coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.2.0' + coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.6' // Nextcloud SSO implementation 'com.github.nextcloud:Android-SingleSignOn:0.6.1' diff --git a/app/src/main/java/it/niedermann/owncloud/notes/manageaccounts/IManageAccountsCallback.java b/app/src/main/java/it/niedermann/owncloud/notes/manageaccounts/IManageAccountsCallback.java new file mode 100644 index 00000000..93b04811 --- /dev/null +++ b/app/src/main/java/it/niedermann/owncloud/notes/manageaccounts/IManageAccountsCallback.java @@ -0,0 +1,16 @@ +package it.niedermann.owncloud.notes.manageaccounts; + +import androidx.annotation.NonNull; + +import it.niedermann.owncloud.notes.persistence.entity.Account; + +public interface IManageAccountsCallback { + + void onSelect(@NonNull Account account); + + void onDelete(@NonNull Account account); + + void onChangeNotesPath(@NonNull Account account); + + void onChangeFileSuffix(@NonNull Account account); +} 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 19adee12..1c665857 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 @@ -21,22 +21,10 @@ public class ManageAccountAdapter extends RecyclerView.Adapter localAccounts = new ArrayList<>(); @NonNull - private final Consumer onAccountClick; - @NonNull - private final Consumer onAccountDelete; - @NonNull - Consumer onChangeNotesPath; - @NonNull - Consumer onChangeFileSuffix; + private final IManageAccountsCallback callback; - public ManageAccountAdapter(@NonNull Consumer onAccountClick, - @NonNull Consumer onAccountDelete, - @NonNull Consumer onChangeNotesPath, - @NonNull Consumer onChangeFileSuffix) { - this.onAccountClick = onAccountClick; - this.onAccountDelete = onAccountDelete; - this.onChangeNotesPath = onChangeNotesPath; - this.onChangeFileSuffix = onChangeFileSuffix; + public ManageAccountAdapter(@NonNull IManageAccountsCallback callback) { + this.callback = callback; setHasStableIds(true); } @@ -54,10 +42,7 @@ public class ManageAccountAdapter extends RecyclerView.Adapter { - setCurrentLocalAccount(localAccountClicked); - onAccountClick.accept(localAccountClicked); - }, onAccountDelete, onChangeNotesPath, onChangeFileSuffix, currentLocalAccount != null && currentLocalAccount.getId() == localAccount.getId()); + holder.bind(localAccount, callback, currentLocalAccount != null && currentLocalAccount.getId() == localAccount.getId()); } @Override diff --git a/app/src/main/java/it/niedermann/owncloud/notes/manageaccounts/ManageAccountViewHolder.java b/app/src/main/java/it/niedermann/owncloud/notes/manageaccounts/ManageAccountViewHolder.java index 3b61851a..26b1e785 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/manageaccounts/ManageAccountViewHolder.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/manageaccounts/ManageAccountViewHolder.java @@ -1,31 +1,26 @@ package it.niedermann.owncloud.notes.manageaccounts; -import android.graphics.drawable.LayerDrawable; -import android.net.Uri; -import android.view.Menu; -import android.view.View; - -import androidx.annotation.NonNull; -import androidx.appcompat.widget.PopupMenu; -import androidx.core.util.Consumer; -import androidx.recyclerview.widget.RecyclerView; - -import com.bumptech.glide.Glide; -import com.bumptech.glide.request.RequestOptions; - -import java.util.stream.Stream; - -import it.niedermann.nextcloud.sso.glide.SingleSignOnUrl; -import it.niedermann.owncloud.notes.R; -import it.niedermann.owncloud.notes.databinding.ItemAccountChooseBinding; -import it.niedermann.owncloud.notes.persistence.entity.Account; -import it.niedermann.owncloud.notes.shared.model.ApiVersion; - import static android.view.View.GONE; import static android.view.View.VISIBLE; import static it.niedermann.owncloud.notes.branding.BrandingUtil.applyBrandToLayerDrawable; import static it.niedermann.owncloud.notes.shared.util.ApiVersionUtil.getPreferredApiVersion; +import android.graphics.drawable.LayerDrawable; +import android.net.Uri; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.appcompat.widget.PopupMenu; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; + +import it.niedermann.nextcloud.sso.glide.SingleSignOnUrl; +import it.niedermann.owncloud.notes.R; +import it.niedermann.owncloud.notes.databinding.ItemAccountChooseBinding; +import it.niedermann.owncloud.notes.persistence.entity.Account; + public class ManageAccountViewHolder extends RecyclerView.ViewHolder { private final ItemAccountChooseBinding binding; @@ -37,10 +32,7 @@ public class ManageAccountViewHolder extends RecyclerView.ViewHolder { public void bind( @NonNull Account localAccount, - @NonNull Consumer onAccountClick, - @NonNull Consumer onAccountDelete, - @NonNull Consumer onChangeNotesPath, - @NonNull Consumer onChangeFileSuffix, + @NonNull IManageAccountsCallback callback, boolean isCurrentAccount ) { binding.accountName.setText(localAccount.getUserName()); @@ -50,28 +42,31 @@ public class ManageAccountViewHolder extends RecyclerView.ViewHolder { .error(R.drawable.ic_account_circle_grey_24dp) .apply(RequestOptions.circleCropTransform()) .into(binding.accountItemAvatar); - itemView.setOnClickListener((v) -> onAccountClick.accept(localAccount)); + itemView.setOnClickListener((v) -> callback.onSelect(localAccount)); binding.accountContextMenu.setVisibility(VISIBLE); binding.accountContextMenu.setOnClickListener((v) -> { final var popup = new PopupMenu(itemView.getContext(), v); popup.inflate(R.menu.menu_account); + final var preferredApiVersion = getPreferredApiVersion(localAccount.getApiVersion()); - if (preferredApiVersion != null && !preferredApiVersion.supportsSettings()) { - final var menu = popup.getMenu(); - Stream.of( - R.id.notes_path, - R.id.file_suffix - ).forEach((i) -> menu.removeItem(menu.findItem(i).getItemId())); + + if (preferredApiVersion == null || !preferredApiVersion.supportsFileSuffixChange()) { + popup.getMenu().removeItem(popup.getMenu().findItem(R.id.file_suffix).getItemId()); } + + if (preferredApiVersion == null || !preferredApiVersion.supportsNotesPathChange()) { + popup.getMenu().removeItem(popup.getMenu().findItem(R.id.notes_path).getItemId()); + } + popup.setOnMenuItemClickListener(item -> { if (item.getItemId() == R.id.notes_path) { - onChangeNotesPath.accept(localAccount); + callback.onChangeNotesPath(localAccount); return true; } else if (item.getItemId() == R.id.file_suffix) { - onChangeFileSuffix.accept(localAccount); + callback.onChangeFileSuffix(localAccount); return true; } else if (item.getItemId() == R.id.delete) { - onAccountDelete.accept(localAccount); + callback.onDelete(localAccount); return true; } return false; 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 b6341f61..8d0c253f 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,26 +1,28 @@ package it.niedermann.owncloud.notes.manageaccounts; +import static it.niedermann.owncloud.notes.shared.util.ApiVersionUtil.getPreferredApiVersion; + import android.accounts.NetworkErrorException; import android.os.Bundle; import android.util.TypedValue; import android.view.ViewGroup; -import android.widget.ArrayAdapter; import android.widget.EditText; import android.widget.FrameLayout; import android.widget.ProgressBar; -import android.widget.Spinner; import android.widget.Toast; import androidx.annotation.AttrRes; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.Px; -import androidx.appcompat.app.AlertDialog; +import androidx.annotation.StringRes; import androidx.lifecycle.ViewModelProvider; import com.nextcloud.android.sso.AccountImporter; import com.nextcloud.android.sso.exceptions.NextcloudFilesAppAccountNotFoundException; +import java.util.function.Function; + import it.niedermann.owncloud.notes.LockedActivity; import it.niedermann.owncloud.notes.R; import it.niedermann.owncloud.notes.branding.BrandedAlertDialogBuilder; @@ -35,11 +37,7 @@ 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 it.niedermann.owncloud.notes.shared.util.ApiVersionUtil.getPreferredApiVersion; - -public class ManageAccountsActivity extends LockedActivity { +public class ManageAccountsActivity extends LockedActivity implements IManageAccountsCallback { private ActivityManageAccountsBinding binding; private ManageAccountsViewModel viewModel; @@ -55,12 +53,7 @@ public class ManageAccountsActivity extends LockedActivity { setContentView(binding.getRoot()); setSupportActionBar(binding.toolbar); - adapter = new ManageAccountAdapter( - this::selectAccount, - this::deleteAccount, - this::onChangeNotesPath, - this::onChangeFileSuffix - ); + adapter = new ManageAccountAdapter(this); binding.accounts.setAdapter(adapter); viewModel.getAccounts$().observe(this, (accounts) -> { @@ -69,7 +62,7 @@ public class ManageAccountsActivity extends LockedActivity { return; } this.adapter.setLocalAccounts(accounts); - viewModel.getCurrentAccount(this, new IResponseCallback() { + viewModel.getCurrentAccount(this, new IResponseCallback<>() { @Override public void onSuccess(Account result) { runOnUiThread(() -> adapter.setCurrentLocalAccount(result)); @@ -84,12 +77,13 @@ public class ManageAccountsActivity extends LockedActivity { }); } - private void selectAccount(@NonNull Account accountToSelect) { + public void onSelect(@NonNull Account accountToSelect) { + adapter.setCurrentLocalAccount(accountToSelect); viewModel.selectAccount(accountToSelect, this); } - private void deleteAccount(@NonNull Account accountToDelete) { - viewModel.countUnsynchronizedNotes(accountToDelete.getId(), new IResponseCallback() { + public void onDelete(@NonNull Account accountToDelete) { + viewModel.countUnsynchronizedNotes(accountToDelete.getId(), new IResponseCallback<>() { @Override public void onSuccess(Long unsynchronizedChangesCount) { runOnUiThread(() -> { @@ -113,38 +107,61 @@ public class ManageAccountsActivity extends LockedActivity { }); } - private void onChangeNotesPath(@NonNull Account localAccount) { + public void onChangeNotesPath(@NonNull Account localAccount) { + changeAccountSetting(localAccount, + R.string.settings_notes_path, + R.string.settings_notes_path_description, + R.string.settings_notes_path_success, + NotesSettings::getNotesPath, + property -> new NotesSettings(property, null) + ); + } + + public void onChangeFileSuffix(@NonNull Account localAccount) { + changeAccountSetting(localAccount, + R.string.settings_file_suffix, + R.string.settings_file_suffix_description, + R.string.settings_file_suffix_success, + NotesSettings::getFileSuffix, + property -> new NotesSettings(null, property) + ); + } + + private void changeAccountSetting(@NonNull Account localAccount, @StringRes int title, @StringRes int message, @StringRes int successMessage, @NonNull Function propertyExtractor, @NonNull Function settingsFactory) { final var repository = NotesRepository.getInstance(getApplicationContext()); final var editText = new EditText(this); final var wrapper = createDialogViewWrapper(); final var dialog = new BrandedAlertDialogBuilder(this) - .setTitle(R.string.settings_notes_path) - .setMessage(R.string.settings_notes_path_description) + .setTitle(title) + .setMessage(message) .setView(wrapper) .setNeutralButton(android.R.string.cancel, null) - .setPositiveButton(R.string.action_edit_save, (v, d) -> new Thread(() -> { - try { - final var putSettingsCall = repository.putServerSettings(AccountImporter.getSingleSignOnAccount(this, localAccount.getAccountName()), new NotesSettings(editText.getText().toString(), null), getPreferredApiVersion(localAccount.getApiVersion())); - putSettingsCall.enqueue(new Callback<>() { - @Override - public void onResponse(@NonNull Call call, @NonNull Response response) { - final var body = response.body(); - if (response.isSuccessful() && body != null) { - runOnUiThread(() -> Toast.makeText(ManageAccountsActivity.this, getString(R.string.settings_notes_path_success, body.getNotesPath()), Toast.LENGTH_LONG).show()); - } else { - runOnUiThread(() -> Toast.makeText(ManageAccountsActivity.this, getString(R.string.http_status_code, response.code()), Toast.LENGTH_LONG).show()); + .setPositiveButton(R.string.action_edit_save, (v, d) -> { + final var property = editText.getText().toString(); + new Thread(() -> { + try { + final var putSettingsCall = repository.putServerSettings(AccountImporter.getSingleSignOnAccount(this, localAccount.getAccountName()), settingsFactory.apply(property), getPreferredApiVersion(localAccount.getApiVersion())); + putSettingsCall.enqueue(new Callback<>() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + final var body = response.body(); + if (response.isSuccessful() && body != null) { + runOnUiThread(() -> Toast.makeText(ManageAccountsActivity.this, getString(successMessage, propertyExtractor.apply(body)), Toast.LENGTH_LONG).show()); + } else { + runOnUiThread(() -> Toast.makeText(ManageAccountsActivity.this, getString(R.string.http_status_code, response.code()), Toast.LENGTH_LONG).show()); + } } - } - @Override - public void onFailure(@NonNull Call 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()) + @Override + public void onFailure(@NonNull Call 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(); try { repository.getServerSettings(AccountImporter.getSingleSignOnAccount(this, localAccount.getAccountName()), getPreferredApiVersion(localAccount.getApiVersion())) @@ -155,8 +172,7 @@ public class ManageAccountsActivity extends LockedActivity { final var body = response.body(); if (response.isSuccessful() && body != null) { wrapper.removeAllViews(); - final var editText = new EditText(ManageAccountsActivity.this); - editText.setText(body.getNotesPath()); + editText.setText(propertyExtractor.apply(body)); wrapper.addView(editText); } else { dialog.dismiss(); @@ -179,88 +195,13 @@ public class ManageAccountsActivity extends LockedActivity { } } - private void onChangeFileSuffix(@NonNull Account localAccount) { - final var repository = NotesRepository.getInstance(getApplicationContext()); - final var spinner = new Spinner(this); - final var wrapper = createDialogViewWrapper(); - final var adapter = ArrayAdapter.createFromResource(this, R.array.settings_file_suffixes, android.R.layout.simple_spinner_item); - adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); - spinner.setAdapter(adapter); - final var dialog = new BrandedAlertDialogBuilder(this) - .setTitle(R.string.settings_file_suffix) - .setMessage(R.string.settings_file_suffix_description) - .setView(wrapper) - .setNeutralButton(android.R.string.cancel, null) - .setPositiveButton(R.string.action_edit_save, (v, d) -> new Thread(() -> { - try { - final Call putSettingsCall = repository.putServerSettings(AccountImporter.getSingleSignOnAccount(this, localAccount.getAccountName()), new NotesSettings(null, spinner.getSelectedItem().toString()), getPreferredApiVersion(localAccount.getApiVersion())); - putSettingsCall.enqueue(new Callback<>() { - @Override - public void onResponse(@NonNull Call call, @NonNull Response response) { - final var body = response.body(); - if (response.isSuccessful() && body != null) { - runOnUiThread(() -> Toast.makeText(ManageAccountsActivity.this, getString(R.string.settings_file_suffix_success, body.getNotesPath()), Toast.LENGTH_LONG).show()); - } else { - runOnUiThread(() -> Toast.makeText(ManageAccountsActivity.this, getString(R.string.http_status_code, response.code()), Toast.LENGTH_LONG).show()); - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - runOnUiThread(() -> ExceptionDialogFragment.newInstance(t).show(getSupportFragmentManager(), ExceptionDialogFragment.class.getSimpleName())); - } - }); - } catch (NextcloudFilesAppAccountNotFoundException e) { - runOnUiThread(() -> ExceptionDialogFragment.newInstance(e).show(getSupportFragmentManager(), ExceptionDialogFragment.class.getSimpleName())); - } - }).start()) - .show(); - try { - repository.getServerSettings(AccountImporter.getSingleSignOnAccount(this, localAccount.getAccountName()), getPreferredApiVersion(localAccount.getApiVersion())) - .enqueue(new Callback<>() { - @Override - public void onResponse(@NonNull Call call, @NonNull Response response) { - final NotesSettings body = response.body(); - runOnUiThread(() -> { - if (response.isSuccessful() && body != null) { - for (int i = 0; i < adapter.getCount(); i++) { - if (adapter.getItem(i).equals(body.getFileSuffix())) { - spinner.setSelection(i); - break; - } - } - wrapper.removeAllViews(); - wrapper.addView(spinner); - } else { - dialog.dismiss(); - ExceptionDialogFragment.newInstance(new Exception(getString(R.string.http_status_code, response.code()))).show(getSupportFragmentManager(), ExceptionDialogFragment.class.getSimpleName()); - } - }); - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - runOnUiThread(() -> { - dialog.dismiss(); - ExceptionDialogFragment.newInstance(t).show(getSupportFragmentManager(), ExceptionDialogFragment.class.getSimpleName()); - }); - } - }); - } catch (NextcloudFilesAppAccountNotFoundException e) { - dialog.dismiss(); - ExceptionDialogFragment.newInstance(e).show(getSupportFragmentManager(), ExceptionDialogFragment.class.getSimpleName()); - } - } - @NonNull private ViewGroup createDialogViewWrapper() { final var progressBar = new ProgressBar(this, null, android.R.attr.progressBarStyleHorizontal); progressBar.setIndeterminate(true); final var wrapper = new FrameLayout(this); final int paddingVertical = getResources().getDimensionPixelSize(R.dimen.spacer_1x); - final int paddingHorizontal = SDK_INT >= LOLLIPOP_MR1 - ? getDimensionFromAttribute(android.R.attr.dialogPreferredPadding) - : getResources().getDimensionPixelSize(R.dimen.spacer_2x); + final int paddingHorizontal = getDimensionFromAttribute(android.R.attr.dialogPreferredPadding); wrapper.setPadding(paddingHorizontal, paddingVertical, paddingHorizontal, paddingVertical); wrapper.addView(progressBar); return wrapper; diff --git a/app/src/main/java/it/niedermann/owncloud/notes/shared/model/ApiVersion.java b/app/src/main/java/it/niedermann/owncloud/notes/shared/model/ApiVersion.java index 7ac09d66..f0dcf0ad 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/shared/model/ApiVersion.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/shared/model/ApiVersion.java @@ -4,16 +4,16 @@ package it.niedermann.owncloud.notes.shared.model; import androidx.annotation.NonNull; import java.util.Objects; -import java.util.regex.Matcher; import java.util.regex.Pattern; @SuppressWarnings("WeakerAccess") public class ApiVersion implements Comparable { private static final Pattern NUMBER_EXTRACTION_PATTERN = Pattern.compile("[0-9]+"); - private static final ApiVersion VERSION_1_2 = new ApiVersion("1.2", 1, 2); - public static final ApiVersion API_VERSION_0_2 = new ApiVersion(0, 2); - public static final ApiVersion API_VERSION_1_0 = new ApiVersion(1, 0); + public static final ApiVersion API_VERSION_0_2 = new ApiVersion("0.2", 0, 2); + public static final ApiVersion API_VERSION_1_0 = new ApiVersion("1.0", 1, 0); + public static final ApiVersion API_VERSION_1_2 = new ApiVersion("1.2", 1, 2); + public static final ApiVersion API_VERSION_1_3 = new ApiVersion("1.3", 1, 3); public static final ApiVersion[] SUPPORTED_API_VERSIONS = new ApiVersion[]{ API_VERSION_1_0, @@ -45,7 +45,7 @@ public class ApiVersion implements Comparable { public static ApiVersion of(String versionString) { int major = 0, minor = 0; if (versionString != null) { - String[] split = versionString.split("\\."); + final String[] split = versionString.split("\\."); if (split.length > 0) { major = extractNumber(split[0]); if (split.length > 1) { @@ -80,8 +80,19 @@ public class ApiVersion implements Comparable { return 0; } - public boolean supportsSettings() { - return getMajor() >= 1 && getMinor() >= 2; + /** + * While setting the file suffix to .txt or .md was possible starting + * with {@link #API_VERSION_1_2}, we will only support this feature with {@link #API_VERSION_1_3} + * because it allows us to set any value and skip client side validations. + * + * @see Settings API + */ + public boolean supportsFileSuffixChange() { + return getMajor() >= API_VERSION_1_3.getMajor() && getMinor() >= API_VERSION_1_3.getMinor(); + } + + public boolean supportsNotesPathChange() { + return getMajor() >= API_VERSION_1_2.getMajor() && getMinor() >= API_VERSION_1_2.getMinor(); } /** diff --git a/app/src/test/java/it/niedermann/owncloud/notes/shared/model/ApiVersionTest.java b/app/src/test/java/it/niedermann/owncloud/notes/shared/model/ApiVersionTest.java new file mode 100644 index 00000000..5b3b6f5b --- /dev/null +++ b/app/src/test/java/it/niedermann/owncloud/notes/shared/model/ApiVersionTest.java @@ -0,0 +1,45 @@ +package it.niedermann.owncloud.notes.shared.model; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +public class ApiVersionTest { + + @Test + public void shouldOnlyCompareMajorApiVersions() { + final var apiVersion = new ApiVersion("1.0", 1, 0); + + assertEquals(1, apiVersion.compareTo(ApiVersion.API_VERSION_0_2)); + assertEquals(0, apiVersion.compareTo(ApiVersion.API_VERSION_1_0)); + assertEquals(0, apiVersion.compareTo(ApiVersion.API_VERSION_1_2)); + } + + @Test + public void shouldOnlyEqualMajorApiVersions() { + final var apiVersion = new ApiVersion("1.0", 1, 0); + + assertNotEquals(apiVersion, ApiVersion.API_VERSION_0_2); + assertEquals(apiVersion, ApiVersion.API_VERSION_1_0); + assertEquals(apiVersion, ApiVersion.API_VERSION_1_2); + } + + @Test + public void shouldSupportFileSuffixChangesWithApi1_3andAbove() { + assertFalse(ApiVersion.API_VERSION_0_2.supportsFileSuffixChange()); + assertFalse(ApiVersion.API_VERSION_1_0.supportsFileSuffixChange()); + assertFalse(ApiVersion.API_VERSION_1_2.supportsFileSuffixChange()); + assertTrue(ApiVersion.API_VERSION_1_3.supportsFileSuffixChange()); + } + + @Test + public void shouldSupportNotesPathChangesWithApi1_2andAbove() { + assertFalse(ApiVersion.API_VERSION_0_2.supportsNotesPathChange()); + assertFalse(ApiVersion.API_VERSION_1_0.supportsNotesPathChange()); + assertTrue(ApiVersion.API_VERSION_1_2.supportsNotesPathChange()); + assertTrue(ApiVersion.API_VERSION_1_3.supportsNotesPathChange()); + } +} \ No newline at end of file diff --git a/build.gradle b/build.gradle index 6a4a994a..04e3f46c 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ buildscript { google() } dependencies { - classpath 'com.android.tools.build:gradle:7.3.0-beta05' + classpath 'com.android.tools.build:gradle:7.2.2' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files diff --git a/fastlane/metadata/android/en-US/changelogs/3005001.txt b/fastlane/metadata/android/en-US/changelogs/3005001.txt index d92d4a72..d11ac7ff 100644 --- a/fastlane/metadata/android/en-US/changelogs/3005001.txt +++ b/fastlane/metadata/android/en-US/changelogs/3005001.txt @@ -1,6 +1,7 @@ - 📱️ Add option to not keep screen on (#1531) - 🐞 Favorite star in menu not clickable (#1541) - 🐞 Fix back button behavior in widgets (#1412) - by @newhinton +- ⚙️ Support custom file extensions (Notes ≥ 4.5.0) - ⚙️ Add monochrome icon (#1544) - by @salixor - ⚙️ Use the new Android 12 SplashScreen API (#1546) - by @salixor - 🌎 Updated translations