From a492e3d044f1b4a9be31ffbd3c5b047679f72ddc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 8 Dec 2022 13:07:31 +0000 Subject: [PATCH 001/163] Bump fragment from 1.5.4 to 1.5.5 Bumps fragment from 1.5.4 to 1.5.5. --- updated-dependencies: - dependency-name: androidx.fragment:fragment dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 27ceced8b..8a587ef06 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -94,7 +94,7 @@ dependencies { // Android X implementation 'androidx.appcompat:appcompat:1.5.1' implementation 'androidx.core:core-splashscreen:1.0.0' - implementation 'androidx.fragment:fragment:1.5.4' + implementation 'androidx.fragment:fragment:1.5.5' implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1' implementation 'androidx.preference:preference:1.2.0' implementation 'androidx.recyclerview:recyclerview-selection:1.1.0' -- GitLab From 740f70381917a34bc0836dba6036cac6c7dc9e25 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 15 Dec 2022 13:02:16 +0000 Subject: [PATCH 002/163] Bump mockito-core from 4.9.0 to 4.10.0 Bumps [mockito-core](https://github.com/mockito/mockito) from 4.9.0 to 4.10.0. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v4.9.0...v4.10.0) --- updated-dependencies: - dependency-name: org.mockito:mockito-core dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 8a587ef06..bc16fc16c 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -120,7 +120,7 @@ dependencies { testImplementation 'androidx.test:core:1.5.0' testImplementation 'androidx.arch.core:core-testing:2.1.0' testImplementation 'junit:junit:4.13.2' - testImplementation 'org.mockito:mockito-core:4.9.0' + testImplementation 'org.mockito:mockito-core:4.10.0' testImplementation 'org.robolectric:robolectric:4.9' implementation fileTree(dir: 'libs', include: ['*.jar']) -- GitLab From f590d38fffddb8f7cf883957af516f8e1d8347cc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 20 Dec 2022 13:03:47 +0000 Subject: [PATCH 003/163] Bump robolectric from 4.9 to 4.9.1 Bumps [robolectric](https://github.com/robolectric/robolectric) from 4.9 to 4.9.1. - [Release notes](https://github.com/robolectric/robolectric/releases) - [Commits](https://github.com/robolectric/robolectric/compare/robolectric-4.9...robolectric-4.9.1) --- updated-dependencies: - dependency-name: org.robolectric:robolectric dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index bc16fc16c..d4db92ddb 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -121,7 +121,7 @@ dependencies { testImplementation 'androidx.arch.core:core-testing:2.1.0' testImplementation 'junit:junit:4.13.2' testImplementation 'org.mockito:mockito-core:4.10.0' - testImplementation 'org.robolectric:robolectric:4.9' + testImplementation 'org.robolectric:robolectric:4.9.1' implementation fileTree(dir: 'libs', include: ['*.jar']) } -- GitLab From 70083557b198ba6f2f2ac7b2f89c0607fdbefd72 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 28 Dec 2022 13:02:26 +0000 Subject: [PATCH 004/163] Bump robolectric from 4.9.1 to 4.9.2 Bumps [robolectric](https://github.com/robolectric/robolectric) from 4.9.1 to 4.9.2. - [Release notes](https://github.com/robolectric/robolectric/releases) - [Commits](https://github.com/robolectric/robolectric/compare/robolectric-4.9.1...robolectric-4.9.2) --- updated-dependencies: - dependency-name: org.robolectric:robolectric dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index d4db92ddb..c1029a69e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -121,7 +121,7 @@ dependencies { testImplementation 'androidx.arch.core:core-testing:2.1.0' testImplementation 'junit:junit:4.13.2' testImplementation 'org.mockito:mockito-core:4.10.0' - testImplementation 'org.robolectric:robolectric:4.9.1' + testImplementation 'org.robolectric:robolectric:4.9.2' implementation fileTree(dir: 'libs', include: ['*.jar']) } -- GitLab From ecfc761015ee5565b51b749dcb9b8f0000cb5d07 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 29 Dec 2022 13:02:50 +0000 Subject: [PATCH 005/163] Bump mockito-core from 4.10.0 to 4.11.0 Bumps [mockito-core](https://github.com/mockito/mockito) from 4.10.0 to 4.11.0. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v4.10.0...v4.11.0) --- updated-dependencies: - dependency-name: org.mockito:mockito-core dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index c1029a69e..f86ddb8a4 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -120,7 +120,7 @@ dependencies { testImplementation 'androidx.test:core:1.5.0' testImplementation 'androidx.arch.core:core-testing:2.1.0' testImplementation 'junit:junit:4.13.2' - testImplementation 'org.mockito:mockito-core:4.10.0' + testImplementation 'org.mockito:mockito-core:4.11.0' testImplementation 'org.robolectric:robolectric:4.9.2' implementation fileTree(dir: 'libs', include: ['*.jar']) -- GitLab From 11846c7e55bcc0eb6c70320fcddbb9e0fd6fb3bf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Jan 2023 13:06:07 +0000 Subject: [PATCH 006/163] Bump gson from 2.10 to 2.10.1 Bumps [gson](https://github.com/google/gson) from 2.10 to 2.10.1. - [Release notes](https://github.com/google/gson/releases) - [Changelog](https://github.com/google/gson/blob/master/CHANGELOG.md) - [Commits](https://github.com/google/gson/compare/gson-parent-2.10...gson-parent-2.10.1) --- updated-dependencies: - dependency-name: com.google.code.gson:gson dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index f86ddb8a4..b7324c4fc 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -111,7 +111,7 @@ dependencies { implementation 'com.squareup.retrofit2:retrofit:2.9.0' // Gson - implementation 'com.google.code.gson:gson:2.10' + implementation 'com.google.code.gson:gson:2.10.1' // ReactiveX implementation 'io.reactivex.rxjava2:rxjava:2.2.21' -- GitLab From 2a3a292bd36988a379e10bbbf48dc76860abb835 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 12 Jan 2023 13:05:44 +0000 Subject: [PATCH 007/163] Bump appcompat from 1.5.1 to 1.6.0 Bumps appcompat from 1.5.1 to 1.6.0. --- updated-dependencies: - dependency-name: androidx.appcompat:appcompat dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index b7324c4fc..f5cbfc7b9 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -92,7 +92,7 @@ dependencies { annotationProcessor 'com.github.bumptech.glide:compiler:4.14.2' // Android X - implementation 'androidx.appcompat:appcompat:1.5.1' + implementation 'androidx.appcompat:appcompat:1.6.0' implementation 'androidx.core:core-splashscreen:1.0.0' implementation 'androidx.fragment:fragment:1.5.5' implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1' -- GitLab From fbf0c9d7551aee45697ea6c04fb5fe9612da33a1 Mon Sep 17 00:00:00 2001 From: Stefan Niedermann Date: Sat, 14 Jan 2023 09:31:11 +0100 Subject: [PATCH 008/163] Adjust links --- .github/FUNDING.yml | 3 +- .github/ISSUE_TEMPLATE/bug_report.md | 2 +- FAQ.md | 46 +++++++++---------- README.md | 20 ++++---- .../notes/branding/BrandedActivity.java | 2 +- .../importaccount/ImportAccountActivity.java | 2 +- .../owncloud/notes/main/MainActivity.java | 6 +-- .../owncloud/notes/main/MainViewModel.java | 2 +- .../notes/persistence/NotesRepository.java | 4 +- .../notes/persistence/SyncWorker.java | 2 +- .../migration/Migration_13_14.java | 2 +- .../migration/Migration_14_15.java | 2 +- .../migration/Migration_15_16.java | 2 +- .../migration/Migration_16_17.java | 2 +- .../migration/Migration_21_22.java | 2 +- .../migration/Migration_22_23.java | 2 +- .../persistence/migration/Migration_9_10.java | 2 +- app/src/main/res/values/strings.xml | 6 +-- .../notes/shared/util/NoteUtilTest.java | 2 +- .../android/en-US/full_description.txt | 2 +- 20 files changed, 56 insertions(+), 57 deletions(-) diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index a70c33a47..414afb07e 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,4 +1,3 @@ # These are supported funding model platforms -liberapay: stefan-niedermann -custom: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=K7HVLE6J7SXXA +custom: https://nextcloud.com/include/ diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 5b98b9a61..49078cc83 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -8,7 +8,7 @@ labels: bug Guidelines for submitting issues: * Bug reports which do not fill the complete issue template will be closed. -* Please have a look at our [FAQ](https://github.com/stefan-niedermann/nextcloud-notes/blob/master/FAQ.md) +* Please have a look at our [FAQ](https://github.com/nextcloud/notes-android/blob/master/FAQ.md) * Please search the existing issues first, it's likely that your issue was already reported or even fixed. * This repository is *only* for issues within the Nextcloud Notes Android app --> diff --git a/FAQ.md b/FAQ.md index b75c76066..610220868 100644 --- a/FAQ.md +++ b/FAQ.md @@ -1,19 +1,19 @@ # Frequently asked questions -- [Why aren't there any buttons to apply formatting?](https://github.com/stefan-niedermann/nextcloud-notes/blob/master/FAQ.md#why-arent-there-any-buttons-to-apply-formatting) -- [I have experienced an error](https://github.com/stefan-niedermann/nextcloud-notes/blob/master/FAQ.md#i-have-experienced-an-error) - - [`NextcloudApiNotRespondingException`](https://github.com/stefan-niedermann/nextcloud-notes/blob/master/FAQ.md#nextcloudapinotrespondingexception) - - [`UnknownErrorException: Read timed out`](https://github.com/stefan-niedermann/nextcloud-notes/blob/master/FAQ.md#unknownerrorexception-read-timed-out) - - [`NextcloudHttpRequestFailedException`](https://github.com/stefan-niedermann/nextcloud-notes/blob/master/FAQ.md#nextcloudhttprequestfailedexception) - - [`IllegalStateException: Duplicate key`](https://github.com/stefan-niedermann/nextcloud-notes/blob/master/FAQ.md#illegalstateexception-duplicate-key) - - [`NextcloudFilesAppAccountNotFoundException`](https://github.com/stefan-niedermann/nextcloud-notes/blob/master/FAQ.md#nextcloudfilesappaccountnotfoundexception) - - [`TokenMismatchException`](https://github.com/stefan-niedermann/nextcloud-notes/blob/master/FAQ.md#tokenmismatchexception) - - [Workarounds](https://github.com/stefan-niedermann/nextcloud-notes/blob/master/FAQ.md#workarounds) -- [How to share notes?](https://github.com/stefan-niedermann/nextcloud-notes/blob/master/FAQ.md#how-to-share-notes) -- [Why don't you make an option for…?](https://github.com/stefan-niedermann/nextcloud-notes/blob/master/FAQ.md#why-dont-you-make-an-option-for) -- [Why is there no support for pens?](https://github.com/stefan-niedermann/nextcloud-notes/blob/master/FAQ.md#why-is-there-no-support-for-pens) -- [Why has my bug report been closed?](https://github.com/stefan-niedermann/nextcloud-notes/blob/master/FAQ.md#why-has-my-bug-report-been-closed) -- [How can i activate the dark mode for widgets?](https://github.com/stefan-niedermann/nextcloud-notes/blob/master/FAQ.md#how-can-i-activate-the-dark-mode-for-widgets) +- [Why aren't there any buttons to apply formatting?](https://github.com/nextcloud/notes-android/blob/master/FAQ.md#why-arent-there-any-buttons-to-apply-formatting) +- [I have experienced an error](https://github.com/nextcloud/notes-android/blob/master/FAQ.md#i-have-experienced-an-error) + - [`NextcloudApiNotRespondingException`](https://github.com/nextcloud/notes-android/blob/master/FAQ.md#nextcloudapinotrespondingexception) + - [`UnknownErrorException: Read timed out`](https://github.com/nextcloud/notes-android/blob/master/FAQ.md#unknownerrorexception-read-timed-out) + - [`NextcloudHttpRequestFailedException`](https://github.com/nextcloud/notes-android/blob/master/FAQ.md#nextcloudhttprequestfailedexception) + - [`IllegalStateException: Duplicate key`](https://github.com/nextcloud/notes-android/blob/master/FAQ.md#illegalstateexception-duplicate-key) + - [`NextcloudFilesAppAccountNotFoundException`](https://github.com/nextcloud/notes-android/blob/master/FAQ.md#nextcloudfilesappaccountnotfoundexception) + - [`TokenMismatchException`](https://github.com/nextcloud/notes-android/blob/master/FAQ.md#tokenmismatchexception) + - [Workarounds](https://github.com/nextcloud/notes-android/blob/master/FAQ.md#workarounds) +- [How to share notes?](https://github.com/nextcloud/notes-android/blob/master/FAQ.md#how-to-share-notes) +- [Why don't you make an option for…?](https://github.com/nextcloud/notes-android/blob/master/FAQ.md#why-dont-you-make-an-option-for) +- [Why is there no support for pens?](https://github.com/nextcloud/notes-android/blob/master/FAQ.md#why-is-there-no-support-for-pens) +- [Why has my bug report been closed?](https://github.com/nextcloud/notes-android/blob/master/FAQ.md#why-has-my-bug-report-been-closed) +- [How can i activate the dark mode for widgets?](https://github.com/nextcloud/notes-android/blob/master/FAQ.md#how-can-i-activate-the-dark-mode-for-widgets) ## Why aren't there any buttons to apply formatting @@ -49,7 +49,7 @@ Probably you will experience it when importing an account, because at this momen Further synchronizations are usually not causing this issue, because the Notes app tries to synchronize only *changed* notes after the first import. If your notes are not ten thousands of characters long, it is very unlikely that this causes a connection timeout. -We improved the import of an account in version `3.4.12` to make it more reliable by [fetching notes step by step](https://github.com/stefan-niedermann/nextcloud-notes/issues/761#issuecomment-836989421). +We improved the import of an account in version `3.4.12` to make it more reliable by [fetching notes step by step](https://github.com/nextcloud/notes-android/issues/761#issuecomment-836989421). If you are using an older version, you can as a workaround for the first import try to 1. move all your notes to a different folder on your Nextcloud instance 2. import your account on your smartphone @@ -59,29 +59,29 @@ If you are using an older version, you can as a workaround for the first import #### `HTTP status-code: 301` -This issue can happen in case of a complex inconsistent state between the Notes Android app, the Single Sign On library, the Nextcloud Android app and your Nextcloud instance. Please try to remove your account from *both*, Notes Android *and* Nextcloud Android and readd it again [as described in the `workarounds` section](https://github.com/stefan-niedermann/nextcloud-notes/blob/master/FAQ.md#workarounds). If the issue persists, please report especially any changes on your server side environment: Did you change your domain or IP address of your Nextcloud server? Did you change something about your user account or en- / disabled multi factor authentication (2FA / MFA)? Did you remove your account (only) from the Nextcloud Android app? +This issue can happen in case of a complex inconsistent state between the Notes Android app, the Single Sign On library, the Nextcloud Android app and your Nextcloud instance. Please try to remove your account from *both*, Notes Android *and* Nextcloud Android and readd it again [as described in the `workarounds` section](https://github.com/nextcloud/notes-android/blob/master/FAQ.md#workarounds). If the issue persists, please report especially any changes on your server side environment: Did you change your domain or IP address of your Nextcloud server? Did you change something about your user account or en- / disabled multi factor authentication (2FA / MFA)? Did you remove your account (only) from the Nextcloud Android app? #### `HTTP status-code: 302` -As clearly described in the description of the app, [one of the requirements](https://github.com/stefan-niedermann/nextcloud-notes#link-requirements) is to have installed the [`Notes`](https://apps.nextcloud.com/apps/notes) app on your server. This means: +As clearly described in the description of the app, [one of the requirements](https://github.com/nextcloud/notes-android#link-requirements) is to have installed the [`Notes`](https://apps.nextcloud.com/apps/notes) app on your server. This means: - **not** [`Quick notes`](https://apps.nextcloud.com/apps/quicknotes) - **not** [`Carnet`](https://apps.nextcloud.com/apps/carnet) - **not** `SimpleNote`, `NextNotes`, `Joplin` nor any other app. -Only the [`Notes`](https://apps.nextcloud.com/apps/notes) app is supported by the Notes Android app. Granted, detecting a missing installation of the `Notes` app should be more seamlessly - [we are aware of it](https://github.com/stefan-niedermann/nextcloud-notes/issues/1475) and will try to enhance the detection. +Only the [`Notes`](https://apps.nextcloud.com/apps/notes) app is supported by the Notes Android app. Granted, detecting a missing installation of the `Notes` app should be more seamlessly - [we are aware of it](https://github.com/nextcloud/notes-android/issues/1475) and will try to enhance the detection. ### `IllegalStateException: Duplicate key` -This is issue was caused by a bug which was present in the Notes Android app between `3.4.0` and `3.4.10`. It has been fixed in `3.4.11`, though it created a corrupt database state which is not recoverable automatically without data loss. It is therefore required to [clear the storage of the Notes Android app](https://github.com/stefan-niedermann/nextcloud-notes/blob/master/FAQ.md#workarounds) and import your account again from scratch. Make sure to backup unsynchronized changes before doing this. +This is issue was caused by a bug which was present in the Notes Android app between `3.4.0` and `3.4.10`. It has been fixed in `3.4.11`, though it created a corrupt database state which is not recoverable automatically without data loss. It is therefore required to [clear the storage of the Notes Android app](https://github.com/nextcloud/notes-android/blob/master/FAQ.md#workarounds) and import your account again from scratch. Make sure to backup unsynchronized changes before doing this. ### `NextcloudFilesAppAccountNotFoundException` -We are not yet sure what exactly causes this issue, but investigate it by [adding more debug logs to recent versions](https://github.com/stefan-niedermann/nextcloud-notes/issues/1256#issuecomment-859505153). In theory this might happen if an already imported account has been deleted in the Nextcloud app. +We are not yet sure what exactly causes this issue, but investigate it by [adding more debug logs to recent versions](https://github.com/nextcloud/notes-android/issues/1256#issuecomment-859505153). In theory this might happen if an already imported account has been deleted in the Nextcloud app. As a workaround you can remove the account (or clear the storage of the app as described below if you can't access the account manager anymore) and import it again. ### `TokenMismatchException` -The reason of this error is not yet clear. It often seems to be connected to changes of the authentication (for example enabling 2FA after some time). Please clear the storage of both, the Notes and the Nextcloud Android apps as described in the [workarounds](https://github.com/stefan-niedermann/nextcloud-notes/blob/master/FAQ.md#wrokarounds) section. +The reason of this error is not yet clear. It often seems to be connected to changes of the authentication (for example enabling 2FA after some time). Please clear the storage of both, the Notes and the Nextcloud Android apps as described in the [workarounds](https://github.com/nextcloud/notes-android/blob/master/FAQ.md#wrokarounds) section. ### Workarounds @@ -106,7 +106,7 @@ Nextcloud / Notes Then set up your account in the Nextcloud Android app again and import the configured account in the Notes Android app. -If the issue persists, [open a bug report in our issue tracker](https://github.com/stefan-niedermann/nextcloud-notes/issues/new?assignees=&labels=bug&template=bug_report.md&title=). +If the issue persists, [open a bug report in our issue tracker](https://github.com/nextcloud/notes-android/issues/new?assignees=&labels=bug&template=bug_report.md&title=). ## How to share notes? @@ -145,7 +145,7 @@ Since i am not aware of any proper free SDK for pens, I recommend you to ask you ### Hardware issues -Given a [free SDK](#licensing-issues) can be found, there is another issue: I don't own a device with a pen. I welcome [Pull Requests](https://github.com/stefan-niedermann/nextcloud-notes/pulls) with contributions to this topic, but i can and will not buy a new device just for this aspect, sorry. +Given a [free SDK](#licensing-issues) can be found, there is another issue: I don't own a device with a pen. I welcome [Pull Requests](https://github.com/nextcloud/notes-android/pulls) with contributions to this topic, but i can and will not buy a new device just for this aspect, sorry. ## Why has my bug report been closed? diff --git a/README.md b/README.md index c9bcdbd2b..d40e18d6e 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,15 @@ # Nextcloud Notes for Android An android client for [Nextcloud Notes App](https://github.com/nextcloud/notes/). -[![Android CI](https://github.com/stefan-niedermann/nextcloud-notes/workflows/Android%20CI/badge.svg)](https://github.com/stefan-niedermann/nextcloud-notes/actions) -[![Codacy Badge](https://api.codacy.com/project/badge/Grade/9f784826834042e8b512d531cab84711)](https://www.codacy.com/manual/info_147/nextcloud-notes?utm_source=github.com&utm_medium=referral&utm_content=stefan-niedermann/nextcloud-notes&utm_campaign=Badge_Grade) -[![GitHub issues](https://img.shields.io/github/issues/stefan-niedermann/nextcloud-notes.svg)](https://github.com/stefan-niedermann/nextcloud-notes/issues) -[![GitHub stars](https://img.shields.io/github/stars/stefan-niedermann/nextcloud-notes.svg)](https://github.com/stefan-niedermann/nextcloud-notes/stargazers) +[![Android CI](https://github.com/nextcloud/notes-android/workflows/Android%20CI/badge.svg)](https://github.com/nextcloud/notes-android/actions) +[![Codacy Badge](https://api.codacy.com/project/badge/Grade/9f784826834042e8b512d531cab84711)](https://www.codacy.com/manual/info_147/nextcloud-notes?utm_source=github.com&utm_medium=referral&utm_content=nextcloud/notes-android&utm_campaign=Badge_Grade) +[![GitHub issues](https://img.shields.io/github/issues/nextcloud/notes-android.svg)](https://github.com/nextcloud/notes-android/issues) +[![GitHub stars](https://img.shields.io/github/stars/nextcloud/notes-android.svg)](https://github.com/nextcloud/notes-android/stargazers) [![License: GPL v3](https://img.shields.io/badge/License-GPL%20v3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0) ## :arrow_forward: Access -[![Latest Release](https://img.shields.io/github/v/tag/stefan-niedermann/nextcloud-notes?label=latest+release&sort=semver)](https://github.com/stefan-niedermann/nextcloud-notes/tags) +[![Latest Release](https://img.shields.io/github/v/tag/nextcloud/notes-android?label=latest+release&sort=semver)](https://github.com/nextcloud/notes-android/tags) [![F-Droid Release](https://img.shields.io/f-droid/v/it.niedermann.owncloud.notes)](https://f-droid.org/de/packages/it.niedermann.owncloud.notes/) [ mainViewModel.postCurrentAccount(account)); } catch (NextcloudFilesAppAccountNotFoundException e) { - // Verbose log output for https://github.com/stefan-niedermann/nextcloud-notes/issues/1256 + // Verbose log output for https://github.com/nextcloud/notes-android/issues/1256 runOnUiThread(() -> new MaterialAlertDialogBuilder(this) .setTitle(NextcloudFilesAppAccountNotFoundException.class.getSimpleName()) .setMessage(R.string.backup) @@ -670,7 +670,7 @@ public class MainActivity extends LockedActivity implements NoteClickListener, A } case REQUEST_CODE_SERVER_SETTINGS: { // Recreate activity completely, because theme switching makes problems when only invalidating the views. - // @see https://github.com/stefan-niedermann/nextcloud-notes/issues/529 + // @see https://github.com/nextcloud/notes-android/issues/529 if (RESULT_OK == resultCode) { ActivityCompat.recreate(this); return; @@ -730,7 +730,7 @@ public class MainActivity extends LockedActivity implements NoteClickListener, A .show()); }); } else if (e instanceof UnknownErrorException && e.getMessage() != null && e.getMessage().contains("No address associated with hostname")) { - // https://github.com/stefan-niedermann/nextcloud-notes/issues/1014 + // https://github.com/nextcloud/notes-android/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) .setAnchorView(binding.activityNotesListView.fabCreate) .show()); 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 4de6ebece..fd13bbb62 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 @@ -625,7 +625,7 @@ public class MainViewModel extends AndroidViewModel { /** * @return true if {@param exceptions} contains at least one exception which is not caused by flaky infrastructure. - * @see Issue #1303 + * @see Issue #1303 */ public boolean containsNonInfrastructureRelatedItems(@Nullable Collection exceptions) { if (exceptions == null || exceptions.isEmpty()) { 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 27865a3ba..5f1811f1a 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 @@ -500,7 +500,7 @@ public class NotesRepository { public Note updateNoteAndSync(@NonNull Account localAccount, @NonNull Note oldNote, @Nullable String newContent, @Nullable String newTitle, @Nullable ISyncCallback callback) { final Note newNote; // Re-read the up to date remoteId from the database because the UI might not have the state after synchronization yet - // https://github.com/stefan-niedermann/nextcloud-notes/issues/1198 + // https://github.com/nextcloud/notes-android/issues/1198 @Nullable final Long remoteId = db.getNoteDao().getRemoteId(oldNote.getId()); if (newContent == null) { newNote = new Note(oldNote.getId(), remoteId, oldNote.getModified(), oldNote.getTitle(), oldNote.getContent(), oldNote.getCategory(), oldNote.getFavorite(), oldNote.getETag(), DBStatus.LOCAL_EDITED, localAccount.getId(), oldNote.getExcerpt(), oldNote.getScrollY()); @@ -598,7 +598,7 @@ public class NotesRepository { .setIntent(intent) .build()); } else { - // Prevent crash https://github.com/stefan-niedermann/nextcloud-notes/issues/613 + // Prevent crash https://github.com/nextcloud/notes-android/issues/613 Log.e(TAG, "shortLabel cannot be empty " + (BuildConfig.DEBUG ? note : note.getTitle())); } } diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/SyncWorker.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/SyncWorker.java index 3816f6b8f..b5b2efb4b 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/persistence/SyncWorker.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/SyncWorker.java @@ -55,7 +55,7 @@ public class SyncWorker extends Worker { /** * Set up sync work to enabled every 15 minutes or just disabled - * https://github.com/stefan-niedermann/nextcloud-notes/issues/1168 + * https://github.com/nextcloud/notes-android/issues/1168 * * @param context the application * @param backgroundSync the toggle result backgroundSync diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_13_14.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_13_14.java index 805204f69..ba206d1fb 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_13_14.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_13_14.java @@ -32,7 +32,7 @@ public class Migration_13_14 extends Migration { /** * Move single note widget preferences to database - * https://github.com/stefan-niedermann/nextcloud-notes/issues/754 + * https://github.com/nextcloud/notes-android/issues/754 */ @Override public void migrate(@NonNull SupportSQLiteDatabase db) { diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_14_15.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_14_15.java index bda4d0462..b03e12287 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_14_15.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_14_15.java @@ -22,7 +22,7 @@ public class Migration_14_15 extends Migration { /** * Normalize database (move category from string field to own table) - * https://github.com/stefan-niedermann/nextcloud-notes/issues/814 + * https://github.com/nextcloud/notes-android/issues/814 */ @Override public void migrate(@NonNull SupportSQLiteDatabase db) { diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_15_16.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_15_16.java index 7be785112..ab2690a76 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_15_16.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_15_16.java @@ -33,7 +33,7 @@ public class Migration_15_16 extends Migration { /** * Moves note list widget preferences from {@link SharedPreferences} to database - * https://github.com/stefan-niedermann/nextcloud-notes/issues/832 + * https://github.com/nextcloud/notes-android/issues/832 */ @Override public void migrate(@NonNull SupportSQLiteDatabase db) { diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_16_17.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_16_17.java index b61262ebc..a772fe845 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_16_17.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_16_17.java @@ -12,7 +12,7 @@ public class Migration_16_17 extends Migration { /** * Adds a column to store the current scroll position per note - * https://github.com/stefan-niedermann/nextcloud-notes/issues/227 + * https://github.com/nextcloud/notes-android/issues/227 */ @Override public void migrate(@NonNull SupportSQLiteDatabase db) { diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_21_22.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_21_22.java index c076d38e8..c52ad8e38 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_21_22.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_21_22.java @@ -12,7 +12,7 @@ import it.niedermann.owncloud.notes.persistence.SyncWorker; /** * Enabling backgroundSync, set from {@link String} values to {@link Boolean} values - * https://github.com/stefan-niedermann/nextcloud-notes/issues/1168 + * https://github.com/nextcloud/notes-android/issues/1168 */ public class Migration_21_22 extends Migration { @NonNull diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_22_23.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_22_23.java index 1ba08a3c9..2a993a2b7 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_22_23.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_22_23.java @@ -25,7 +25,7 @@ import it.niedermann.owncloud.notes.shared.model.ApiVersion; /** * Add displayName property to {@link Account}. *

- * See: #1079 Show DisplayName instead of uid attribute for LDAP users + * See: #1079 Show DisplayName instead of uid attribute for LDAP users *

* Sanitizes the stored API versions in the database. */ diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_9_10.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_9_10.java index 9b4b328fa..b637e5164 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_9_10.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_9_10.java @@ -19,7 +19,7 @@ public class Migration_9_10 extends Migration { /** * Adds a column to store excerpt instead of regenerating it each time - * https://github.com/stefan-niedermann/nextcloud-notes/issues/528 + * https://github.com/nextcloud/notes-android/issues/528 */ @Override public void migrate(@NonNull SupportSQLiteDatabase db) { diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 961c42f30..74b1fa17f 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -59,9 +59,9 @@ Server is in maintenance mode An unknown error has occurred. - https://github.com/stefan-niedermann/nextcloud-notes - https://github.com/stefan-niedermann/nextcloud-notes/issues/new/choose - https://github.com/stefan-niedermann/nextcloud-notes/blob/master/LICENSE + https://github.com/nextcloud/notes-android + https://github.com/nextcloud/notes-android/issues/new/choose + https://github.com/nextcloud/notes-android/blob/master/LICENSE https://www.transifex.com/nextcloud/nextcloud/ https://www.niedermann.it/ https://github.com/nextcloud/notes/blob/76d15214f80f2bf7ea08427bff73ad145128f090/img/notes.svg diff --git a/app/src/test/java/it/niedermann/owncloud/notes/shared/util/NoteUtilTest.java b/app/src/test/java/it/niedermann/owncloud/notes/shared/util/NoteUtilTest.java index ff0ca4e67..bffa68963 100644 --- a/app/src/test/java/it/niedermann/owncloud/notes/shared/util/NoteUtilTest.java +++ b/app/src/test/java/it/niedermann/owncloud/notes/shared/util/NoteUtilTest.java @@ -49,7 +49,7 @@ public class NoteUtilTest extends TestCase { assertEquals("Test", NoteUtil.generateNoteTitle("\nTest")); assertEquals("Test", NoteUtil.generateNoteTitle("\n\nTest")); - // https://github.com/stefan-niedermann/nextcloud-notes/issues/1104 + // https://github.com/nextcloud/notes-android/issues/1104 assertEquals("2021-03-24 - Example title", MarkdownUtil.removeMarkdown("2021-03-24 - Example title")); } diff --git a/fastlane/metadata/android/en-US/full_description.txt b/fastlane/metadata/android/en-US/full_description.txt index 9128f5260..b8f42e2fb 100644 --- a/fastlane/metadata/android/en-US/full_description.txt +++ b/fastlane/metadata/android/en-US/full_description.txt @@ -25,4 +25,4 @@ Companion app to Nextcloud Notes. 👨‍👩‍👦 Mitwirken - * https://github.com/stefan-niedermann/nextcloud-notes#family-join-the-team + * https://github.com/nextcloud/notes-android#family-join-the-team -- GitLab From 857d4462f45dba3d694d8949c66e8abab744448f Mon Sep 17 00:00:00 2001 From: Stefan Niedermann Date: Sat, 14 Jan 2023 09:36:55 +0100 Subject: [PATCH 009/163] Adjust CONTRIBUTING.md and README.md --- CONTRIBUTING.md | 2 +- README.md | 6 ------ 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 107335520..cf84171f5 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,7 +2,7 @@ ## Submitting bug reports -If you find a bug, feel free to [open an issue](https://github.com/stefan-niedermann/OwnCloud-Notes/issues/new). But please provide these information in the comment: +If you find a bug, feel free to [open an issue](https://github.com/nextcloud/notes-android/issues/new). But please provide these information in the comment: **Android version:** e. g. 6.0.1 Marshmallow diff --git a/README.md b/README.md index d40e18d6e..70e8b03b6 100644 --- a/README.md +++ b/README.md @@ -18,12 +18,6 @@ An android client for [Nextcloud Notes App](https://github.com/nextcloud/notes/) [Get it on F-Droid](https://f-droid.org/repository/browse/?fdid=it.niedermann.owncloud.notes) -[Donate with PayPal](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=K7HVLE6J7SXXA) -[Donate using Liberapay](https://liberapay.com/stefan-niedermann/donate) ## :eyes: Screenshots -- GitLab From 392baf1904b9f8faaa0e8ce758c48a3d79da387a Mon Sep 17 00:00:00 2001 From: Niedermann IT-Dienstleistungen Date: Sat, 14 Jan 2023 10:16:52 +0100 Subject: [PATCH 010/163] Remove unnecessary build flavors Signed-off-by: Niedermann IT-Dienstleistungen --- app/build.gradle | 8 -------- 1 file changed, 8 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index f5cbfc7b9..56c841d5d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -53,14 +53,6 @@ android { play { dimension "version" } - pfungstadt { - dimension "version" - applicationIdSuffix ".pfungstadt" - } - mdm { - dimension "version" - applicationIdSuffix ".mdm" - } } testOptions { -- GitLab From fdc812165b5915c95e9430bb4957d3092f1a177c Mon Sep 17 00:00:00 2001 From: Nextcloud bot Date: Mon, 16 Jan 2023 10:22:19 +0000 Subject: [PATCH 011/163] =?UTF-8?q?Fix(l10n):=20=F0=9F=94=A0=20Update=20tr?= =?UTF-8?q?anslations=20from=20Transifex?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Nextcloud bot --- app/src/main/res/values-b+en+001/strings.xml | 305 +++++++++++++++++++ app/src/main/res/values-da/strings.xml | 206 +++++++++++++ app/src/main/res/values-el/strings.xml | 6 +- app/src/main/res/values-eu/strings.xml | 84 ++--- app/src/main/res/values-fr/strings.xml | 2 +- app/src/main/res/values-gl/strings.xml | 39 +++ app/src/main/res/values-he/strings.xml | 205 +++++++++++++ app/src/main/res/values-ia/strings.xml | 8 - app/src/main/res/values-lv/strings.xml | 53 ---- app/src/main/res/values-nb-rNO/strings.xml | 3 + app/src/main/res/values-oc/strings.xml | 154 ++++++++++ app/src/main/res/values-pt-rBR/strings.xml | 2 +- app/src/main/res/values-sv/strings.xml | 40 ++- app/src/main/res/values-zh-rCN/strings.xml | 3 + 14 files changed, 1003 insertions(+), 107 deletions(-) create mode 100644 app/src/main/res/values-b+en+001/strings.xml create mode 100644 app/src/main/res/values-da/strings.xml create mode 100644 app/src/main/res/values-he/strings.xml delete mode 100644 app/src/main/res/values-ia/strings.xml delete mode 100644 app/src/main/res/values-lv/strings.xml create mode 100644 app/src/main/res/values-oc/strings.xml diff --git a/app/src/main/res/values-b+en+001/strings.xml b/app/src/main/res/values-b+en+001/strings.xml new file mode 100644 index 000000000..76db2177b --- /dev/null +++ b/app/src/main/res/values-b+en+001/strings.xml @@ -0,0 +1,305 @@ + + + + Notes + Nextcloud Notes + All notes + Favourites + New note + Welcome to %1$s + Settings + Deleted notes + Search + Sorting method + Cancel + Switch + Edit + Remove + Save + About + Link + Deleted %1$s + Restored %1$s + Undo + Uncategorised + Delete + Category + Favourite + Preview + Share + + Search in %1$s + Search all notes + + Choose a category + + Today + Yesterday + This week + Last week + This month + Last month + + Display mode for notes + Theme + Monospace font + Font size + Sync only on Wi-Fi + App lock (Beta) + Device credentials + Background synchronization + Prevent screen capture + Grid view + Keep screen on + When viewing or editing a note + + Synchronisation failed: %1$s + Synchronization failed + No network connection + Server is in maintenance mode + An unknown error has occurred. + + Version + You are currently using %1$s + Maintainer + Developers + Translators + Nextcloud community on %1$s + Testers + Source code + This project is hosted on GitHub: %1$s + Issues + You can report bugs, enhancement proposals and feature requests at the GitHub issue tracker: %1$s + Translate + Join the Nextcloud team on Transifex and help us to translate this app: %1$s + App licence + This application is licensed under the GNU GENERAL PUBLIC LICENSE v3+. + View licence + Icons + For the original icon see %1$s. + All further icons used by this app are %1$s made by Google Inc. and licensed under the Apache 2.0 License. + Material Design Icons + Credits + Contribution + Licence + + Note list + No notes + Single note + Note not found + Please login to Notes before using this widget + Star icon is used to denote an item as a favourite + + Select note + + Create a new note + + Normal + Sync on Wi-Fi and mobile data + Password protection + + Error + Close + Copy + Exception + Pin to homescreen + This note has been deleted + Add account + + Music + Movies + Movie + Work + ToDo + ToDos + Checklists + Tasks + Recipe + Recipes + Restaurant + Restaurants + Food + Bake + + Key + + Keys + Password + Passwords + Credential + Game + Games + + Play + Gift + Gifts + + Present + + Presents + + Account has already been imported + No notes yet + Press + button to create a new note + More + Move + Read only + No category + Add %1$s + Checkbox + Unlock notes + Oh no - What now? 🙁 + Please try to force close the app and restart it again. There might have been an incorrect connection to the Nextcloud app. + If the issue persists, try to clear the storage of both apps: Nextcloud and Nextcloud Notes to solve this issue. + You can clear the storage by opening the app info and selecting Storage → Clear storage. ⚠️ Warning: This will delete not yet synchronized notes! + Your Nextcloud app seems to be outdated. Please visit the Play Store or F-Droid to get the latest version. + Something seems to be wrong with your Nextcloud app. Please try to force stop both, the Nextcloud app and the Nextcloud Notes app. + If force stopping them does not help, you can try to clear the storage of both apps. + There wasn\'t a response from your server in the given time. Please make sure your instance is running well. + Check your network connection. Sometime toggling the mobile data or Wi-Fi off and on again can help. + The response of your server was not correct. Please check whether you can access your notes via web interface. + There is an issue with your Nextcloud setup. Please have a look into the server log files. + Please check whether your Nextcloud instance is not currently in maintenance mode. + Your Nextcloud instance has no free storage left. Please delete some files to sync your local changes into your cloud. + We need the following technical information to help you: + Please make sure you have installed and enabled the "Notes" app on your server. + Your server did respond with a HTTP 302 status code, which implies, that you do not have installed the Notes app on your server or something is misconfigured. This can be caused by custom overrides in a .htaccess-file or by Nextcloud apps like OID Client. + Please disable all battery optimizations for Nextcloud and the Notes app. + The Notes Android app requires the Nextcloud Android app to be at least version 3.18. + Added "%1$s" + Shared text was empty + Append to note + Change note title + Edit title + Security + Appearance and behavior + Synchronization + Manage accounts + Formatting + + + Open in edit mode + Open in preview mode + Remember my last selection + + + + Small + Medium + Large + + + + Light + Dark + System Default + + + + %d selected + %d selected + + + Deleted one note + Deleted %1$d notes + + + Restored one note + Restored %1$d notes + + + Share content of %1$d note + Share content of %1$d notes + + + --- + `%1$s` + \\`%1$s\\` + ``` + ```` + ```javascript + Context based formatting + A major design goal of the Notes app is to provide a distraction free tool. Though you will be able to format your texts with Markdown. For various of the below mentioned examples, you can use shortcuts so you can format your notes without typing in the codes below. + Just select a range of text or tap on your cursor at any position and you will get a popup menu which contains next to the default entries %1$s, %2$s, %3$s entries like %4$s or %5$s. + + Text + It\'s very easy to make some words %1$sbold%1$s and other words %2$sitalic%2$s with Markdown. You can %3$sstrike%3$s some words through and even [link to Nextcloud](https://nextcloud.com). + + Lists + Sometimes you want numbered lists: + One + Two + Three + Sometimes you want bullet points: + Start a line with a dash + And if you have sub points, put two spaces before the dash or star: + Like this + And this + + Checkboxes + To create a checkbox, use a list followed by brackets + Item 1 + Item 2 + + Structured documents + Sometimes it\'s useful to have different levels of headings to structure your documents. Start lines with a %1$s to create headings. Multiple %2$s in a row denote smaller heading sizes. + This is a third-tier heading + You can use one %1$s all the way up to %2$s six for different heading sizes. + If you\'d like to quote someone, use the %1$s character before the line: + Imagination is more important than knowledge. Knowledge is limited. Imagination encircles the world. + - Albert Einstein + + Code + There are many different ways to style code with Markdown. If you have inline code blocks, wrap them in backticks: + Markdown also supports something called code fencing, which allows for multiple lines without indentation: + And if you\'d like to use syntax highlighting, include the language: + + Tables + + Column %1d + + Value %1d + + Links have to be either complete URLs starting with a protocol and domain or absolute paths starting with a %1$s character. + In order to conform to the Markdown format, please use escape characters in the image URL. This means for example, replace spaces with %1$s in the URL. + Images + Fancy image + + Other + Sort by modified date + Sort by alphabet + Battery settings + Open App info + Network settings + Update + No account configured yet + You don\'t have configured any other accounts yet. + Choose account + Context based formatting popover + + Removing the account %1$s will also delete irrecoverable one unsynchronized change. + Removing the account %1$s will also delete irrecoverable %2$d unsynchronized changes. + + Remove %1$s + + You have to be connected to the internet in order to add an account. + Set folder + + Next + Previous + Backup + We detected an irrecoverably state of the app. Please backup your unsynchronized changes and clear the storage of the Notes app. + Folder to store your notes in your Nextcloud + + .txt + .md + + New notes folder: %1$s + File extension + File extension for new notes in your Nextcloud + New file suffix: %1$s + HTTP status code: %1$d + Importing notes… + Importing note %1$d of %2$d… + Account imported. + diff --git a/app/src/main/res/values-da/strings.xml b/app/src/main/res/values-da/strings.xml new file mode 100644 index 000000000..322be1ef2 --- /dev/null +++ b/app/src/main/res/values-da/strings.xml @@ -0,0 +1,206 @@ + + + + Noter + Nextcloud noter + Alle noter + Foretrukne + Ny note + Velkommen til %1$s + Indstillinger + Slettede noter + Søg + Sorteringsmetode + Annuller + Byt rundt + Rediger + Fjern + Gem + Om + Link + %1$s blev slettet + %1$s blev gendannet + Fortryd + Ikke kategoriseret + Slet + Kategori + Foretrukken + Vis eksempel + Del + + Søg i %1$s + Søg i alle noter + + Vælg en kategori + + I dag + I går + Denne uge + Seneste uge + Denne måned + Seneste måned + + Visningstilstand for noter + Tema + Monospace font + Skriftstørrelse + Synk kun på Wi-Fi + Enheds legitimationsoplysninger + Synkronisering i baggrunden + Grid visning + Synkronisering fejlede: %1$s + Synkroniseringen mislykkedes + Ingen netværksforbindelse + Serveren er i vedligeholdelsestilstand + En ukendt fejl er opstået + + Version + Du bruger lige nu %1$s + Maintainer + Udviklere + Oversættere + Nextcloud fællesskabet på %1$s + Testere + Kildekode + Dette projekt hostes på GitHub: %1$s + Problemer + Du kan rapportere fejl, foreslå forbedringer og ønske nye funktioner på Github: %1$s + Oversæt + Bliv en dal af Nextcloudholdet på Transifex, og hjælp os med at oversætte denne app: %1$s + App licens + Denne applikation er licenseret under GNU GENERAL PUBLIC LICENSE v3+. + Vis licens + Ikoner + For det oprindelige ikon, se %1$s. + Alle andre ikoner som anvendes af app\'en er %1$s lavet med Google Inc. og licensieret under et Apache 2.0-licens. + Material Design ikoner + Credits + Bidrag + Licens + + Noteliste + Ingen noter + Enkel note + Note ikke fundet + Log venligst ind i Notes før du bruger denne widget + Vælg note + + Opret en ny note + + Normal + Synk på Wi-Fi og mobil data + Password protection + + Fejl + Luk + Kopier + Undtagelse + Fastgør til hjemmeskærm + Denne note er blevet slettet + Tilføj konto + + Musik + Film + Film + Arbejde + Opgaver + Opskrifter + Adgangskode + Adgangskoder + Spil + + Afspil + Kontoen er allerede importeret + Ingen noter endnu + Tryk på + for at oprette en ny note + Mere + Flyt + Skrivebeskyttet + Ingen kategori + Tilføj %1$s + Afkrydsningsfeldt + Lås noter op + Åh nej - hvad nu? 🙁 + Forsøg venligst at tvinge app\'en til at lukke og start den påny igen. Der kan have været en ukorrekt forbindelse til Nextcloud-app\'en. + Hvis problemet ikke løses, så forsøg at rydde lageret for begge apps: Nextcloud og Nextcloud Notes, for at løse problemet. + Din Nextcloud-app ser ud til at være forældet. Gå venligst til Play Butik eller F-Droid for at få seneste version. + Det lader til at være noget galt med din Nextcloud-app. Forsøg venligst at gennemtvinge stop af både Nextcloud-app\'en og Nextcloud Notes-app\'en. + Hvis det ikke hjælper at stoppe begge, så kan du forsøge at rydde lagerpladsen for begge apps. + Der var intet svar fra din server på nuværende tidspunkt. Sørg venligst for at sikre, at din instans kører rigtigt. + Tjek din netværksforbindelse. Undertiden kan det hjælpe at slukke og tænde for mobildata eller wifi. + Svaret fra din server var ikke korrekt. Tjek venligst om du kan tilgå dine noter via webgrænsefladen. + Der er et problem med din opsætning af Nextcloud. Kig venligst i serverens logfiler. + Sørg venligst for at din Nextcloud-instans ikke er i vedligeholdelsestilstand. + Din Nextcloud-instans har ikke mere ledig lagerplads. Slet venligst nogle filer for at synkronisere dine lokale ændringer ind i skyen. + Vi har brug for følgende tekniske information for at hjælpe dig: + Tjek venligst, om du har installeret og aktiveret appen \"Noter\" på din server. + Din server svarede med en HTTP 302-statuskode, hvilket betyder, at du endnu ikke har installeret app\'en Noter på din server, eller at der er en forkert konfiguration. Dette kan skyldes brugerdefinerede tilsidesættelser i en .htaccess-fil eller af apps fra Nextcloud som OID Client. + Tilføjet \"%1$s\" + Den delte tekst var tom + Tilføj til note + Skift titel på note + Rediger titel + Sikkerhed + Synchronization + Administrer konti + Formatering + + + Åbn i redigeringstilstand + Åbn forhåndsvisning + Husk mine sidste selektion + + + + Lille + Mellem + Stor + + + + Lys + Mørk + System Standard + + + + %d valgt + %d valgt + + + En note slettet + %1$d noter slettet + + + En note gendannet + %1$d noter gendannet + + + Del indhold i %1$d note + Del indhold i %1$d noter + + + --- + `%1$s` + Kontekstbaseret formatering + Tekst + Lister + En + To + Tre + Afkrydsningsfelter + Kode + Billeder + Andet + Sortér efter dato ændret + Sortér alfabetisk + Batteriindstillinger + Åbn App info + Netværksindstillinger + Opdater + Vælg konto + Du skal være koblet på en internetforbindelse for at tilføje en konto. + Næste + Tidligere + Backup + diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index d4e144ca5..457940c29 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -56,7 +56,7 @@ Προέκυψε άγνωστο σφάλμα. Έκδοση - Αυτήν την στιγμή χρησιμοποιείτε %1$s + Αυτή τη στιγμή χρησιμοποιείτε %1$s Συντηρητής Προγραμματιστές Μεταφραστές @@ -107,14 +107,18 @@ Ταινία Εργασία Εργασίες + Συνταγή Συνταγές Εστιατόριο + Εστιατόρια + Φαγητό Συνθηματικό Συνθηματικά Παιχνίδι Παιχνίδια Αναπαραγωγή + Δώρο Παρόν Ο λογαριασμός έχει εισαχθεί ήδη diff --git a/app/src/main/res/values-eu/strings.xml b/app/src/main/res/values-eu/strings.xml index c1bb29b20..38861b350 100644 --- a/app/src/main/res/values-eu/strings.xml +++ b/app/src/main/res/values-eu/strings.xml @@ -18,8 +18,8 @@ Gorde Honi buruz Esteka - %1$s ezabatuta - %1$szaharberrituta + %1$s ezabatu da + %1$sberreskuratu da Desegin Kategoria gabe Ezabatu @@ -48,7 +48,7 @@ Aplikazioen blokeoa (Beta) Gailuaren kredentzialak Atzeko planoko sinkronizazioa - Saihestu pantaila argazkia + Eragotzi pantaila argazkia Sareta ikuspegia Mantendu pantaila piztuta Nota bat ikusi edo editatzean @@ -69,16 +69,16 @@ Iturburu-kodea Proiektu hau GitHuben ostatatuta dago: %1$s Arazoak - Akatsen berri eman, hobekuntzak proposatu eta ezaugarri berriak eskatu ditzakezu GitHub arazo kontrolatzailean: %1$s + Akatsen berri eman, hobekuntzak proposatu eta ezaugarri berriak eska ditzakezu GitHub arazo kontrolatzailean: %1$s Itzuli Elkartu Nextcloud taldera Transifexen eta lagundu app hau itzultzen: %1$s Aplikazio lizentzia Aplikazio hau GNU GENERAL PUBLIC LICENSE v3+ lizentziapean dago. - Lizentzia ikusi - Irudiak + Ikusi lizentzia + Ikonoak Jatorrizko ikonora jotzeko ikusi %1$s. App honetan erabilitako gainontzeko ikonoen egilea %1$s Google Inc. da eta Apache 2.0 lizentzia daukate. - Material Design ikonoak + Material Design Icons Kredituak Kontribuzioak Lizentzia @@ -87,7 +87,7 @@ Oharrik ez Ohar bakarra Oharra ez da aurkitu - Hasi saioa oharrak aplikazioan trepeta hau erabili aurretik + Hasi saioa Oharrak aplikazioan trepeta hau erabili aurretik Izarraren ikonoa elementu bat gogoko gisa adierazteko erabiltzen da Hautatu oharra @@ -102,7 +102,7 @@ Itxi Kopiatu Salbuespena - Hasierako pantailara egokitu + Finkatu hasierako pantailan Ohar hau ezabatu da Gehitu kontua @@ -119,22 +119,22 @@ Jatetxea Jatetxeak Janaria - Egosi + Kozinatu Gakoa Gakoak Pasahitza Pasahitzak - Kredentzial + Kredentziala Jokoa Jokoak - Erreproduzitu + Jokatu Oparia Opariak - Aurkeztu + Oparia Opariak @@ -147,11 +147,11 @@ Kategoria gabe Gehitu %1$s Kontrol laukia - Desblokeatzearen oharrak - Oh ez - Orain zer? 🙁 + Desblokeatu oharrak + Oh ez - Eta orain zer? 🙁 Saia zaitez aplikazioa itxi eta berrabiarazten. Agian Nextcloud aplikazioarekin gaizki konektatzea gertatu da. Arazoak jarraitzen badu, saiatu bi aplikazioen biltegiak garbitzen: Nextcloud eta Nextcloud Oharrak aplikazioen biltegiak. - Biltegia garbi dezakezu aplikazioaren informazioa ireki eta hautatuz: Biltegia → Garbitu biltegia. ⚠️Abisua: Honek oraindik sinkronizatuta ez dauden oharrak ezabatuko ditu! + Biltegia garbi dezakezu aplikazioaren informazioa ireki eta hautatuz: Biltegia → Garbitu biltegia. ⚠️ Abisua: Honek oraindik sinkronizatuta ez dauden oharrak ezabatuko ditu! Daukazun Nextcloud aplikazioa zaharkituta dagoela dirudi. Zoaz Play Store edo F-Droidera azken bertsioa lortzeko. Daukazun Nextcloud aplikazioan zerbait gaizki dabilela dirudi. Saia zaitez Nextcloud aplikazioa eta Nextcloud Oharrak, biak, geldiarazten. Geldiarazteak ez badu arazoa konpontzen, bi biltegiak garbitzen saia zaitezke. @@ -162,14 +162,14 @@ Egiazta ezazu zure Nextcloud instantzia ez dagoela mantentze moduan une honetan. Zure Nextcloud instantziak ez du biltegiratze leku libre gehiagorik. Ezabatu fitxategi batzuk, aldaketa lokalak hodeiarekin sinkroniza daitezen. Zuri laguntzeko hurrengo informazio teknikoa behar dugu: - Mesedez egiaztatu \"Notak\" aplikazioa instalatu eta gaitu duzula zure zerbitzarian. - Zure zerbitzariak HTTP 302 egoera kodearekin erantzun du, honek esan nahi du ez duzula Notak aplikazioa ez duzula zure zerbitzarian instalatu edo zerbait txarto konfiguratuta dagoela. Hau .htaccess fitxategi batean arau pertsonalizatuak daudelako edo OID Bezeroa izeneko aplikazioarengatik sortua izan daiteke. + Egiaztatu \"Oharrak\" aplikazioa instalatuta eta gaituta duzula zure zerbitzarian. + Zure zerbitzariak HTTP 302 egoera kodearekin erantzun du, honek esan nahi du ez duzula Oharrak aplikazioa zure zerbitzarian instalatu edo zerbait txarto konfiguratuta dagoela. Hau .htaccess fitxategi batean arau pertsonalizatuak daudelako edo OID Bezeroa izeneko aplikazioarengatik sortua izan daiteke. Desgaitu bateria optimizazio guztiak Nextcloudentzat eta Oharrak aplikazioarentzat. - The Notes Android aplikazioak eskatzen du gutxienez Nextcloud Android aplikazioaren 3.18 bertsioa izatea. + Notes Android aplikazioak behar du Nextcloud Android aplikazioaren 3.18 bertsioa izatea gutxienez. \"%1$s\" gehituta Partekatutako testua hutsik zegoen - Gehitu notara - Aldatu notaren titulua + Gehitu oharrari + Aldatu oharraren titulua Editatu izenburua Segurtasuna Itxura eta portaera @@ -209,7 +209,7 @@ Partekatu %1$doharraren edukia - Partekatu %1$doharraren edukia + Partekatu %1$doharren edukia --- @@ -219,33 +219,33 @@ ```` ```javascript Testuinguruan oinarritutako formatu ematea - Oharrak aplikazioaren diseinuaren erronka handi bat arreta-galtzerik gabeko tresna bat eskaintzea da. Baina aukera dago Markdown erabiliz testuei formatua emateko. Behean adierazitako adibide ugaritarako, lasterbideak erabil daitezke oharrei formatua emateko beheko kodeak idatzi gabe. + Oharrak aplikazioko diseinuaren erronka handi bat arreta-galtzerik gabeko tresna eskaintzea da. Baina aukera dago Markdown erabiliz testuei formatua emateko. Behean adierazitako adibide anitzetan, lasterbideak erabil daitezke oharrei formatua emateko beheko kodeak idatzi gabe. Testuaren zati bat hautatu edo sakatu kurtsorea edozein tokitan eta popup menua agertuko zaizu, %1$s, %2$s eta %3$s bezalako sarrera lehenetsien ondoan %4$seta%5$s bezalakoak ere badituena. - Testu + Testua Oso erraza da hitz batzuk %1$slodi%1$s jartzea eta beste batzuk %2$setzatea%2$s Markdown erabiliz. Hitz batzuk %3$smarratu%3$s ditzakezu eta baita estekak gehitu ere [Nextcloudera joateko](https://nextcloud.com). Zerrendak - Batzuetan zerrenda zenbatuak nahi dituzu: + Batzuetan zerrenda zenbakidunak nahi dituzu: Bat Bi Hiru Noizean behin bulet-puntuak jarri nahi izaten dira: - Lerro bat marratxo batekin hastea - Eta azpipuntuak izanez gero, utzi bi tarte marratxoa edo izarraren aurretik: + Lerro bat marratxo batekin hasi + Eta azpipuntuak nahi izanez gero, utzi bi tarte marratxoa edo izarraren aurretik: Honela - eta horrela + eta honela Kontrol-laukiak - Egiaztapen-laukitxo bat sortzeko, erabili zerrenda bat eta paréntesis. + Kontrol-lauki bat sortzeko, erabili zerrenda bat eta kortxeteak. 1 elementua 2 elementua Egitura duten dokumentuak Noizean behin erabilgarria izaten da maila uagriko izenburuak idaztea dokumentuei egitura emateko. Hasi lerroak %1$sbatekin izenburuak sortzeko. %2$s batzuk jartzeak tamaina txikiagoko izenburuak sortzen ditu. Hau hirugarren mailako izenburu bat da - %1$seta %2$sbitartean sei izenburu tamaina ezberdin erabil ditzakezu. - Norbait aipatzekotan, erabili %1$s karakterea lerroaren aurretik: + %1$sbatetik %2$ssei arteko izenburu tamaina ezberdinak erabil ditzakezu. + Norbait aipatzeko, erabili %1$s karakterea lerroaren aurretik: Irudimena ezagutza baino garrantzitsuagoa da. Ezagutza mugatua da. Irudimenak munduari buelta ematen dio. - Albert Einstein @@ -260,8 +260,8 @@ %1dbalioa - Estekak protokolo eta domeinuarekin hasten diren URL oso edo %1$s karakterearekin hasten diren bide-izen absolutuak izan behar dira. - Markdown formatua betetzeko, mesedez, erabili ihespen karaktereak irudiaren URLan. Hau da, ordeztu tarteak %1$s karakterearekin URLan. + Estekak protokolo eta domeinuarekin hasten diren URL osoak edo %1$s karakterearekin hasten diren bide-izen absolutuak izan behar dira. + Markdown formatua betetzeko, mesedez, erabili ihespen karaktereak irudiaren URLan. Hau da, adibidez ordeztu tarteak %1$s karakterearekin URLan. Irudiak Irudi dotorea @@ -273,33 +273,33 @@ Sareko ezarpenak Eguneratu Oraindik ez da konturik konfiguratu - Oraindik ez duzu konturik konfiguratu. + Oraindik ez duzu beste konturik konfiguratu. Aukeratu kontua Testuinguruan oinarritutako formateatze leiho gainerakorra %1$skontua kentzeak berreskuraezinak diren sinkronizatu gabeko aldaketak ere ezabatuko ditu. - %1$s kontua kentzeak berreskuraezinak diren%2$d sinkronizatu gabeko aldaketak ere ezabatuko ditu. + %1$s kontua kentzeak berreskuraezinak diren%2$d sinkronizatu gabeko aldaketa ere ezabatuko ditu. %1$s kendu - Kontu bat gehitzeko internetera konektatuta egon behar zara. + Kontu bat gehitzeko internetera konektatuta egon behar duzu. Ezarri karpeta Hurrengoa Aurrekoa Babeskopia - Aplikazioaren egoera berreskuraezina antzeman dugu. Mesedez, babestu sinkronizatu gabeko aldaketak eta garbitu Notes aplikazioaren biltegiratzea. - Zure notak Nextclouden gordetzeko karpeta + Aplikazioaren egoera berreskuraezina antzeman dugu. Mesedez, egin sinkronizatu gabeko aldaketen babeskopia eta garbitu Notes aplikazioaren biltegiratzea. + Zure oharrak Nextclouden gordetzeko karpeta .txt .md - Nota karpeta berria: %1$s + Oharren karpeta berria: %1$s Fitxategi-luzapena - Zure Nextcloudeko nota berrien fitxategi-luzapena + Zure Nextcloudeko ohar berrien fitxategi-luzapena Fitxategi berrien luzapena: %1$s HTTP egoera kodea: %1$d - Notak inportatzen... - %2$dtik %1$d nota inportatzen... + Oharrak inportatzen... + %2$dtik %1$doharra inportatzen... Kontua inportatuta. diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 820bc4ad1..2ebed3264 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -102,7 +102,7 @@ Fermer Copier Exception - Épingler sur la page d’accueil + Épingler sur l\'écran d\'accueil Cette note a été supprimée Ajouter un compte diff --git a/app/src/main/res/values-gl/strings.xml b/app/src/main/res/values-gl/strings.xml index 9b07fbb69..1bd89f0f3 100644 --- a/app/src/main/res/values-gl/strings.xml +++ b/app/src/main/res/values-gl/strings.xml @@ -50,6 +50,9 @@ Sincronización do traballo en segundo plano Evitar a captura da pantalla Ver como grella + Mantén a pantalla acesa + Ao ver ou editar unha nota + Produciuse un fallo na sincronización: %1$s Produciuse un fallo na sincronización Sen conexión de rede @@ -85,6 +88,8 @@ Nota única Non se atopou a nota Acceda a Notas antes de empregar este trebello + A icona de estrela úsase para indicar un elemento como favorito + Seleccionar unha nota Crear unha nota nova @@ -105,18 +110,34 @@ Filmes Filme Traballo + Tarefa + Tarefas + Listas de verificación Tarefas Receita Receitas Restaurante + Restaurantes + Comida + Enfornar + + Chave + + Chaves Contrasinal Contrasinais + Credencial Xogo Xogos Reproducir + Agasallo + Agasallos Presentar + + Agasallos + A conta xa foi importada Aínda non hai notas Prema o botón + para crear unha nota nova @@ -144,6 +165,7 @@ Asegúrese de ter instalada e activada a aplicación «Notas» no seu servidor. O seu servidor respondeu cun código de estado HTTP 302, o que implica que non ten instalada a aplicación Notas no servidor ou que algo está mal configurado. Isto pode ser causado por substitucións personalizadas nun ficheiro .htaccess ou por aplicacións Nextcloud como Client OID. Desactive todas as optimizacións de batería para Nextcloud e a apli Notas. + A aplicación de Android Notes require que a aplicación de Android Nextcloud teña como mínimo a versión 3.18. Engadido «%1$s» O texto compartido estaba baleiro Anexo á nota @@ -238,6 +260,8 @@ Valor %1d + As ligazóns teñen que ser URL completos que comezan cun protocolo e dominio ou camiños absolutos que comezan cun carácter %1$s. + Para axustarse ao formato Markdown, utiliza caracteres de escape no URL da imaxe. Isto significa, por exemplo, substituír espazos por %1$s no URL. Imaxes Imaxe elegante @@ -252,10 +276,25 @@ Aínda non ten configurada ningunha outra conta. Escolla unha conta Xanela emerxente de formato baseado no contexto + Eliminar %1$s + Para engadir unha conta tes que estar conectado a internet. + Establecer cartafol + Seguinte Anterior Copia de seguridade + Detectamos un estado irrecuperable da aplicación. Fai unha copia de seguranza dos cambios non sincronizados e limpa o almacenamento da aplicación Notes. + Cartafol para almacenar as túas notas no teu Nextcloud + + .txt + .md + + Novo cartafol de notas: %1$s + Extensión de ficheiro + Extensión de ficheiro para novas notas no teu Nextcloud + Novo sufixo de ficheiro: %1$s + Código de estado HTTP: %1$d A importar notas... A importar a nota %1$d de %2$d... Conta importada. diff --git a/app/src/main/res/values-he/strings.xml b/app/src/main/res/values-he/strings.xml new file mode 100644 index 000000000..bee675e20 --- /dev/null +++ b/app/src/main/res/values-he/strings.xml @@ -0,0 +1,205 @@ + + + + פתקים + פתקים של Nextcloud + כל הפתקים + מועדפים + פתק חדש + ברוך בואך אל %1$s + הגדרות + פתקים שנמחקו + חיפוש + שיטת מיון + ביטול + החלפה + עריכה + הסרה + שמירה + על אודות + קישור + %1$s נמחק + %1$s שוחזר + ביטול + ללא קטגוריה + מחיקה + קטגוריה + סימון כמועדף + תצוגה מקדימה + שיתוף + + חיפוש תחת %1$s + חיפוש בכל הפתקים + + בחירת קטגוריה + + היום + אתמול + השבוע + שבוע שעבר + החודש + חודש שעבר + + מצב תצוגת פתקים + ערכת עיצוב + גופן ברוחב אחיד + גודל גופן + סנכרון רק דרך רשת אלחוטית + פרטי זיהוי להתקן + סנכרון ברקע + תצוגת רשת + הסנכרון נכשל: %1$s + הסנכרון נכשל + אין חיבור לאינטרנט + אירעה שגיאה בלתי ידועה. + + גרסה + אתה משתמש כרגע ב%1$s + מתחזק + מפתחים + מתרגמים + קהילת nextcloud ב %1$s + בודקים + קוד מקור + הפרוייקט מתארח ב GitHub %1$s + תקלו + ניתן לדווח על תקלות, להציע שיפורים ותכונות במערכת מעקב התקלות שלנו שב־GitHub: %1$s + תרגום + ניתן להצטרף לצוות של Nextcloud ב־Transifex ולסייע לנו לתרגם את היישומון הזה: %1$s + רישיון היישומון + היישומון מוגן ברישיון הציבורי הכללי של GNU גרסה 3 ומעלה. + הצגת הרישיון + סמלים + לסמל המקורי יש לגשת אל %1$s. + כל שאר הסמלים בהם נעשה שימוש ביישומון זה הם %1$s שנוצרו על ידי Google בע״מ ומוגשים תחת הרישוי Apache 2.0. + עיצוב צלמיות + תודות + תרומה + רישיון + + רשימת פתקים + אין פתקים + פתק בודד + לא נמצא פתק + נא להיכנס לפתקים לפני השימוש בחלונית הזאת + נא לבחור פתק + + יצירת פתק חדש + + רגיל + עדכון דרך רשת אלחוטית ונתונים סלולריים + Password protection + + שגיאה + סגור + העתק + חריגה + הוסף למסך הבית + פתק זה נמחק + הוספת חשבון + + מוזיקה + סרטים + סרט + עבודה + משימות + מתכון + מסעדה + ססמה + ססמאות + משחק + משחקים + + נגן + + מתנה + החשבון הזה כבר עבר ייבוא + אין פתקים עדיין + לחיצה + כפתור כדי ליצור פתק חדש + עוד + העברה + קריאה בלבד + אין קטגוריה + הוספת %1$s + תיבת סימון + שחרור פתקים + שוד ושבר - מה עכשיו? 🙁 + נראה כי יישומון ה־Nextcloud שלך אינו עדכני. נא לבקר בחנות Play או ב־F-Droid כדי לעדכן לגרסה האחרונה. + כנראה שמשהו השתבש ביישומון ה־Nextcloud שלך. נא לנסות לכפות עצירה על שניהם, יישומון ה־Nextcloud ויישומון הפתקים של Nextcloud. + אם כפיית עצירה לא עוזרת, ניתן לנסות לרוקן את האחסון של שני היישומונים. + לא חזרה תגובה מהשרת שלך בזמן קצוב. נא לוודא שהעותק פועל כראוי. + נא לבדוק שעותק ה־Nextcloud שלך אינו במצב תחזוקה כרגע. + אנו זקוקים לפירוט הטכני הבא כדי לסייע לך: + הטקסט ששותף היה ריק + הוספה לסוף הפתק + עריכת כותרת + אבטחה + סנכרון + ניהול חשבונות + עיצוב + + + פתיחה במצב עריכה + פתיחה במצב תצוגה מקדימה + שמירת הבחירה האחרונה שלי + + + + קטן + בינוני + גדול + + + + בהירה + כהה + ברירת מחדל של המערכת + + + + נבחר %d + נבחרו %d + נבחרו %d + נבחרו %d + + --- + `%1$s` + \\`%1$s\\` + ``` + ```javascript + עיצוב מבוסס הקשר + טקסט + רשימות + לפעמים יעניין אותך להוסיף רשימות ממוספרות: + אחת + שתיים + שלוש + לפעמים יעניין אותך דווקא תבליטים: + התחלת שורה במינוס + ככה + וככה + + תיבות סימון + כדי ליצור תיבת סימון, יש להשתמש ברשימה עם סוגריים מרובעים אחריה + פריט 1 + פריט 2 + + מסמכים עם מבנה פנימ + זו כותרת מסדר שלישי + ניתן להשתמש ב־%1$s עד %2$s שש לגדלי כותרות שונים. + כדי לצטט מישהו, יש להשתמש בתו %1$s לפני השורה: + דמיון חשוב יותר מידע. ידע הוא מוגבל. דמיון חובק את העולם. + - אלברט אינשטיין + + קוד + טבלאות + תמונות + אחר + פתיחת פרטי יישומון + הגדרות רשת + עדכון + נא לבחור חשבון + על המכשיר שלך להיות מחובר לאינטרנט כדי שיתאפשר לך להוסיף חשבון. + הבא + הקודם + diff --git a/app/src/main/res/values-ia/strings.xml b/app/src/main/res/values-ia/strings.xml deleted file mode 100644 index 0e883a628..000000000 --- a/app/src/main/res/values-ia/strings.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - %d selectionate - %d selectionate - - \ No newline at end of file diff --git a/app/src/main/res/values-lv/strings.xml b/app/src/main/res/values-lv/strings.xml deleted file mode 100644 index 25b885bf8..000000000 --- a/app/src/main/res/values-lv/strings.xml +++ /dev/null @@ -1,53 +0,0 @@ - - - - Piezīmes - Jauna piezīme - Iestatījumi - Atcelt - Rediģēt - Saglabāt - Par - Piezīme ir dzēsta - Piezīme restaurēta - Atsaukt - Dzēst - Izlase - Priekšskatīt - Koplietot - - Šodien - Vakar - Šonedēļ - Šis mēnesis - - - - - - Sinhronizācija neizdevās: %1$s - nav tīkla savienojumu - - - - - Versija - Uzturētājs - Izstrādātāji - Tulkotāji - Testētāji - Izejas kods - Tulkot - Programmas licence - Šī lietojumprogramma tiek licencēta zem GNU GENERAL PUBLIC LICENSE v3+. - Skatīt licenci - Ikonas - Kredīti - Licence - - Viena piezīme - - - Izveidot jaunu pierakstu - - diff --git a/app/src/main/res/values-nb-rNO/strings.xml b/app/src/main/res/values-nb-rNO/strings.xml index 734a66f63..df8d92bd8 100644 --- a/app/src/main/res/values-nb-rNO/strings.xml +++ b/app/src/main/res/values-nb-rNO/strings.xml @@ -106,6 +106,7 @@ Film Arbeid Oppgaver + Oppskrifter Restaurant PassordP Passord @@ -146,6 +147,7 @@ Endre tittel på notat Rediger tittel Sikkerhet + Utseende og oppførsel Synkronisering Håndter kontoer Formatering @@ -227,6 +229,7 @@ Åpne App info Nettverksinnstillinger Oppdater + Ingen konto er konfigurert Du har ikke konfigurert noen konto enda. Velg konto Du må være koblet til internett for å kunne legge til en konto. diff --git a/app/src/main/res/values-oc/strings.xml b/app/src/main/res/values-oc/strings.xml new file mode 100644 index 000000000..a82cde215 --- /dev/null +++ b/app/src/main/res/values-oc/strings.xml @@ -0,0 +1,154 @@ + + + + Nòtas + Nòtas de Nextcloud + Totas las nòtas + Favoridas + Nòta novèla + La benvenguda a %1$s + Paramètres + Nòtas suprimidas + Recercar + Metòde de tria + Anullar + Modificar + Suprimir + Salvar + A prepaus + Ligam + %1$s suprimit + Restaurar %1$s + Desfar + Desorganizadas + Suprimir + Categoria + Favorit + Apercebut + Partejar + + Cercar dins %1$s + Cercar totas las nòtas + + Causir una categoria + + Uèi + Ièr + Aquesta setmana + La setmana passada + Aqueste mes + Lo mes passat + + Mòde d’afichatge per las nòtas + Tèma + Poliça monospace + Talha poliça + Sincro. sonque en Wi-Fi + Varrolh app. (Beta) + Identificants del periferic + Sincronizacion en rèireplan + Empachar captura d’ecran + Vista en grasilha + Fracàs de la sincronizacion : %1$s + Sincronizacion fracassada + Pas de connexion ret + Lo servidor es en mòde manteniment + Una error desconeguda s\'es produsida. + + Version + Manteneire + Desvolopaires + Traductors + Provaires + Còdi font + Avarias + Translate + Licéncia de l’app + Veire la licéncia + Icònas + Crèdits + Contribucions + Licéncia + + Lista de nòtas + Cap de nòta + Sola nòta + Nòta pas trobada + Normala + Password protection + + Error + Tampar + Copiar + Excepcion + Penjar a l’ecran d’acuèlh + Aqueste nòta es estada suprimida + Apondre un compte + + Musica + Films + Film + Professional(a) + Prètzfaches + Senhal + Senhals + Jòc + Jòcs + + Aviar + Cap de nòta pel moment + Mai + Desplaçar + Lectura sola + Cap de categoria + Apondre %1$s + Cambiar lo títol de la nòta + Modificar lo títol + Seguretat + Synchronization + Maneja comptes + + Clar + Escur + + + + %d seleccionat + %d seleccionats + + Tèxt + Un + Dos + Tres + Atail + Element 1 + Element 2 + + Documents estructurats + - Albert Einstein + + Còdi + Tablèus + + Colomna %1d + + Valor %1d + + Imatges + Imatge crane + + Autre + Triar per data de modificacion + Triar alfabeticament + Paramètres de batariá + Dobrir info app + Paramètres de ret + Actualizar + Cap de compte pas configurat pel moment + Causir un compte + Suprimir %1$s + + Seguent + Precedent + Salvagarda + diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index b1ff6a8bc..6882a296c 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -227,7 +227,7 @@ Basta selecionar um intervalo de texto ou tocar no cursor em qualquer posição e você obterá um menu pop-up que contém ao lado das entradas padrão %1$s, %2$s, %3$s entradas como %4$s ou %5$s. Texto - É muito fácil fazer algumas palavras %1$snegritas%1$s e outras %2$sitálicas%2$s com Markdown. Você pode %3$sriscar%3$s algumas palavras e até [linkar para o Nextcloud](https://nextcloud.com). + É muito fácil fazer algumas palavras %1$snegritas%1$s e outras %2$sitálicas%2$s com Markdown. Você pode %3$sriscar%3$s algumas palavras e até [apontar para o Nextcloud](https://nextcloud.com). Listas Às vezes você deseja listas numeradas: diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml index b271a031d..c04250719 100644 --- a/app/src/main/res/values-sv/strings.xml +++ b/app/src/main/res/values-sv/strings.xml @@ -50,6 +50,9 @@ Bakgrundssynkronisering Hindra skärmklipp Rutnätsvy + Håll skärmen igång + När du visar eller redigerar en anteckning + Synkronisering misslyckades: %1$s Synkroniseringen misslyckades Ingen nätverksanslutning @@ -108,8 +111,10 @@ Film Arbete Uppgifter + Uppgifter Checklistor Uppgifter + Recept Recept Restaurang Restauranger @@ -160,12 +165,14 @@ Se till att du har installerat och aktiverat Notes-appen på din server. Din server svarade med ett HTTP 302 statusmeddelande, vilket innebär att du inte har installerat Notes-appen på din server eller att något är felkonfigurerat. Detta kan orsakas av manuella ändringar i en .htaccess-fil eller av Nextcloud-appar som \"OID Client\". Stäng av alla batterioptimeringar för Nextcloud och Notes-appen. + Anteckningar Android-appen kräver att Nextcloud Android-appen är minst version 3.18. La till \"%1$s\" Den delade texten var tom Lägg till i anteckning Ändra anteckningstitel Redigera titel Säkerhet + Utseende och beteende Synkronisering Hantera konton Formatering @@ -209,9 +216,12 @@ `%1$s` \\`%1$s\\` ``` + ```` ```javascript Innehållsbaserad formatering Ett stort deignmål med Notes-appen är att tillahandahålla ett distraktionsfritt verktyg. Fast du kan formatera dina texter med Markdown. För de olika nedan nämnda exemplena kan du använda genvägar så att du kan formatera dina anteckningar utan att skriva in koderna nedan. + Markera bara ett stycke text eller tryck på din markör vid valfri position och du kommer få en popup-meny som utöver standardposterna såsom %1$s, %2$s, %3$s även innehåller poster som %4$s eller %5$s. + Text Listor Ibland vill du ha en numrerad lista: @@ -243,7 +253,14 @@ Och om du vill använda syntaxmarkering kan du inkludera språket: Tabeller + + Kolumn %1d + + Värde %1d + Bilder + Snygg bild + Övrigt Sortera efter ändrat datum Sortera alfabetiskt @@ -251,9 +268,30 @@ Öppna appinformation Nätverksinställningar Uppdatera + Inget konto konfigurerat än Du har inte konfigurerat några andra konton än. Välj konto + Kontextbaserad formaterings-popover + Ta bort %1$s + Du måste vara ansluten till internet för att lägga till ett konto. + Sätt mapp + Nästa Föregående - + Backup + Vi upptäckte ett oåterkalleligt tillstånd i appen. Säkerhetskopiera dina osynkroniserade ändringar och rensa lagringen av Antecknings-appen. + Mapp för att lagra din anteckningar i ditt Nextcloud + + .txt + .md + + Ny anteckningsmapp: %1$s + Filändelse + Filändelse för nya anteckningar i ditt Nextcloud + Ny filändelse: %1$s + HTTP statuskod: %1$d + Importerar anteckningar... + Importerar anteckning %1$d av %2$d... + Konto importerat. + diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 5a9b1a915..b95c1b56d 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -50,6 +50,9 @@ 后台同步 防止截屏 网格视图 + 保持屏幕常亮 + 查看或编辑笔记时 + 同步失败:%1$s 同步失败 没有网络连接 -- GitLab From 7181a251b3a7c877bedfee1cced0eabdd2675cc6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Jan 2023 13:23:53 +0000 Subject: [PATCH 012/163] Bump mockito-core from 4.11.0 to 5.0.0 Bumps [mockito-core](https://github.com/mockito/mockito) from 4.11.0 to 5.0.0. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v4.11.0...v5.0.0) --- updated-dependencies: - dependency-name: org.mockito:mockito-core dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 56c841d5d..2be806dc9 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -112,7 +112,7 @@ dependencies { testImplementation 'androidx.test:core:1.5.0' testImplementation 'androidx.arch.core:core-testing:2.1.0' testImplementation 'junit:junit:4.13.2' - testImplementation 'org.mockito:mockito-core:4.11.0' + testImplementation 'org.mockito:mockito-core:5.0.0' testImplementation 'org.robolectric:robolectric:4.9.2' implementation fileTree(dir: 'libs', include: ['*.jar']) -- GitLab From d45482ca633e6e95aaf23dc8ad03946d0af30feb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Jan 2023 14:21:01 +0000 Subject: [PATCH 013/163] Bump gradle from 7.3.1 to 7.4.0 Bumps gradle from 7.3.1 to 7.4.0. --- updated-dependencies: - dependency-name: com.android.tools.build:gradle dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 6b962c7c1..219117ea0 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ buildscript { google() } dependencies { - classpath 'com.android.tools.build:gradle:7.3.1' + classpath 'com.android.tools.build:gradle:7.4.0' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files -- GitLab From 7727efbbdf8ebb5f56523e5cba7169c63b4f4389 Mon Sep 17 00:00:00 2001 From: Nextcloud bot Date: Fri, 20 Jan 2023 02:31:17 +0000 Subject: [PATCH 014/163] =?UTF-8?q?Fix(l10n):=20=F0=9F=94=A0=20Update=20tr?= =?UTF-8?q?anslations=20from=20Transifex?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Nextcloud bot --- app/src/main/res/values-ro/strings.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index 9cb7cef6c..4a2141533 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -50,6 +50,9 @@ Sincronizare în fundal Oprește captura de ecran Vizualizare tip grilă + Menține ecranul deschis + Când vizionezi sau editezi o notiță + Sincronizare eșuată: %1$s Sincronizare eșuată Nu exista conexiune -- GitLab From 27f6968f7cf2ec1546add8e6f3f8ce86ab703a3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Brey?= Date: Mon, 23 Jan 2023 18:17:00 +0100 Subject: [PATCH 015/163] Create command-rebase.yml MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Álvaro Brey --- .github/workflows/command-rebase.yml | 51 ++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 .github/workflows/command-rebase.yml diff --git a/.github/workflows/command-rebase.yml b/.github/workflows/command-rebase.yml new file mode 100644 index 000000000..1b388439b --- /dev/null +++ b/.github/workflows/command-rebase.yml @@ -0,0 +1,51 @@ +# This workflow is provided via the organization template repository +# +# https://github.com/nextcloud/.github +# https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization + +name: Rebase command + +on: + issue_comment: + types: created + +permissions: + contents: read + +jobs: + rebase: + runs-on: ubuntu-latest + permissions: + contents: none + + # On pull requests and if the comment starts with `/rebase` + if: github.event.issue.pull_request != '' && startsWith(github.event.comment.body, '/rebase') + + steps: + - name: Add reaction on start + uses: peter-evans/create-or-update-comment@5adcb0bb0f9fb3f95ef05400558bdb3f329ee808 # v2.1.0 + with: + token: ${{ secrets.COMMAND_BOT_PAT }} + repository: ${{ github.event.repository.full_name }} + comment-id: ${{ github.event.comment.id }} + reaction-type: "+1" + + - name: Checkout the latest code + uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3 + with: + fetch-depth: 0 + token: ${{ secrets.COMMAND_BOT_PAT }} + + - name: Automatic Rebase + uses: cirrus-actions/rebase@6e572f08c244e2f04f9beb85a943eb618218714d # 1.7 + env: + GITHUB_TOKEN: ${{ secrets.COMMAND_BOT_PAT }} + + - name: Add reaction on failure + uses: peter-evans/create-or-update-comment@5adcb0bb0f9fb3f95ef05400558bdb3f329ee808 # v2.1.0 + if: failure() + with: + token: ${{ secrets.COMMAND_BOT_PAT }} + repository: ${{ github.event.repository.full_name }} + comment-id: ${{ github.event.comment.id }} + reaction-type: "-1" -- GitLab From 3965a2d24510ba41b612c3a187deca64579b0a10 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 24 Jan 2023 13:15:53 +0000 Subject: [PATCH 016/163] Bump cirrus-actions/rebase from 1.7 to 1.8 Bumps [cirrus-actions/rebase](https://github.com/cirrus-actions/rebase) from 1.7 to 1.8. - [Release notes](https://github.com/cirrus-actions/rebase/releases) - [Commits](https://github.com/cirrus-actions/rebase/compare/6e572f08c244e2f04f9beb85a943eb618218714d...b87d48154a87a85666003575337e27b8cd65f691) --- updated-dependencies: - dependency-name: cirrus-actions/rebase dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/command-rebase.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/command-rebase.yml b/.github/workflows/command-rebase.yml index 1b388439b..13f7f31a6 100644 --- a/.github/workflows/command-rebase.yml +++ b/.github/workflows/command-rebase.yml @@ -37,7 +37,7 @@ jobs: token: ${{ secrets.COMMAND_BOT_PAT }} - name: Automatic Rebase - uses: cirrus-actions/rebase@6e572f08c244e2f04f9beb85a943eb618218714d # 1.7 + uses: cirrus-actions/rebase@b87d48154a87a85666003575337e27b8cd65f691 # 1.8 env: GITHUB_TOKEN: ${{ secrets.COMMAND_BOT_PAT }} -- GitLab From 214c285da6604c17d01e838a9b45285a4c8ec575 Mon Sep 17 00:00:00 2001 From: Andy Scherzinger Date: Thu, 26 Jan 2023 18:30:28 +0100 Subject: [PATCH 017/163] unify room dependency version Signed-off-by: Andy Scherzinger --- app/build.gradle | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 2be806dc9..ac3c0bc0f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -67,6 +67,10 @@ android { namespace 'it.niedermann.owncloud.notes' } +ext { + roomVersion = "2.4.3" +} + dependencies { coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.6' @@ -96,8 +100,8 @@ dependencies { implementation 'com.google.android.material:material:1.7.0' // Database - implementation 'androidx.room:room-runtime:2.4.3' - annotationProcessor 'androidx.room:room-compiler:2.4.3' + implementation "androidx.room:room-runtime:${roomVersion}" + annotationProcessor "androidx.room:room-compiler:${roomVersion}" // Retrofit implementation 'com.squareup.retrofit2:retrofit:2.9.0' -- GitLab From 432477cb64e8c58da6920ad8d486ec351ba72e4f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 26 Jan 2023 19:44:51 +0000 Subject: [PATCH 018/163] Bump material from 1.7.0 to 1.8.0 Bumps [material](https://github.com/material-components/material-components-android) from 1.7.0 to 1.8.0. - [Release notes](https://github.com/material-components/material-components-android/releases) - [Commits](https://github.com/material-components/material-components-android/compare/1.7.0...1.8.0) --- updated-dependencies: - dependency-name: com.google.android.material:material dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index ac3c0bc0f..53e153293 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -97,7 +97,7 @@ dependencies { implementation 'androidx.recyclerview:recyclerview:1.2.1' implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0' implementation 'androidx.work:work-runtime:2.7.1' - implementation 'com.google.android.material:material:1.7.0' + implementation 'com.google.android.material:material:1.8.0' // Database implementation "androidx.room:room-runtime:${roomVersion}" -- GitLab From f606056a8dd31b4d08d53603ffd64802ad00079e Mon Sep 17 00:00:00 2001 From: Andy Scherzinger Date: Thu, 26 Jan 2023 20:58:25 +0100 Subject: [PATCH 019/163] Bump room to 2.5.0 Signed-off-by: Andy Scherzinger --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index ac3c0bc0f..4dca9554b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -68,7 +68,7 @@ android { } ext { - roomVersion = "2.4.3" + roomVersion = "2.5.0" } dependencies { -- GitLab From a810a133af30316494b2549afc0a529bcdc98ec0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Brey?= Date: Fri, 27 Jan 2023 13:25:49 +0100 Subject: [PATCH 020/163] Update maintainer and developer list in credits screen MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Álvaro Brey --- .../owncloud/notes/about/AboutFragmentCreditsTab.java | 7 ++++--- .../owncloud/notes/shared/util/SupportUtil.java | 4 ++++ app/src/main/res/layout/fragment_about_credits_tab.xml | 3 ++- app/src/main/res/values/strings.xml | 10 ++++++---- 4 files changed, 16 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/it/niedermann/owncloud/notes/about/AboutFragmentCreditsTab.java b/app/src/main/java/it/niedermann/owncloud/notes/about/AboutFragmentCreditsTab.java index 028bfa4e0..717640b65 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/about/AboutFragmentCreditsTab.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/about/AboutFragmentCreditsTab.java @@ -5,6 +5,7 @@ import static it.niedermann.owncloud.notes.shared.util.SupportUtil.strong; import static it.niedermann.owncloud.notes.shared.util.SupportUtil.url; import android.os.Bundle; +import android.text.Spannable; import android.text.method.LinkMovementMethod; import android.view.LayoutInflater; import android.view.View; @@ -23,9 +24,9 @@ public class AboutFragmentCreditsTab extends Fragment { public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { final var binding = FragmentAboutCreditsTabBinding.inflate(inflater, container, false); binding.aboutVersion.setText(getString(R.string.about_version, strong(BuildConfig.VERSION_NAME))); - binding.aboutMaintainer.setText(url(getString(R.string.about_maintainer), getString(R.string.url_maintainer))); - binding.aboutMaintainer.setMovementMethod(new LinkMovementMethod()); + final var founderText = getString(R.string.about_developers_stefan, getString(R.string.about_developers_founder)); + setTextWithURL(binding.aboutDevelopers, getResources(), R.string.about_developers, founderText, R.string.url_niedermann_it); setTextWithURL(binding.aboutTranslators, getResources(), R.string.about_translators_transifex, R.string.about_translators_transifex_label, R.string.url_translations); return binding.getRoot(); } -} \ No newline at end of file +} diff --git a/app/src/main/java/it/niedermann/owncloud/notes/shared/util/SupportUtil.java b/app/src/main/java/it/niedermann/owncloud/notes/shared/util/SupportUtil.java index d914c13fa..9c7abd8ca 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/shared/util/SupportUtil.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/shared/util/SupportUtil.java @@ -33,6 +33,10 @@ public class SupportUtil { public static void setTextWithURL(@NonNull TextView textView, @NonNull Resources resources, @StringRes int containerTextId, @StringRes int linkLabelId, @StringRes int urlId) { final String linkLabel = resources.getString(linkLabelId); + setTextWithURL(textView, resources, containerTextId, linkLabel, urlId); + } + + public static void setTextWithURL(@NonNull TextView textView, @NonNull Resources resources, @StringRes int containerTextId, final String linkLabel, @StringRes int urlId) { final String finalText = resources.getString(containerTextId, linkLabel); final var spannable = new SpannableString(finalText); spannable.setSpan(new URLSpan(resources.getString(urlId)), finalText.indexOf(linkLabel), finalText.indexOf(linkLabel) + linkLabel.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); diff --git a/app/src/main/res/layout/fragment_about_credits_tab.xml b/app/src/main/res/layout/fragment_about_credits_tab.xml index fad03f626..5ed56956f 100644 --- a/app/src/main/res/layout/fragment_about_credits_tab.xml +++ b/app/src/main/res/layout/fragment_about_credits_tab.xml @@ -56,6 +56,7 @@ android:text="@string/about_developers_title" /> - \ No newline at end of file + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 74b1fa17f..d3e5f7c89 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -63,16 +63,18 @@ https://github.com/nextcloud/notes-android/issues/new/choose https://github.com/nextcloud/notes-android/blob/master/LICENSE https://www.transifex.com/nextcloud/nextcloud/ - https://www.niedermann.it/ + https://www.niedermann.it/ https://github.com/nextcloud/notes/blob/76d15214f80f2bf7ea08427bff73ad145128f090/img/notes.svg https://materialdesignicons.com/ Version You are currently using %1$s Maintainer - Niedermann IT-Dienstleistungen + Nextcloud Developers - Stefan Niedermann, Kristof Hamann, HeaDBanGer84, Felix Edelmann, Daniel Bailey + %1$s, Kristof Hamann, HeaDBanGer84, Felix Edelmann, Daniel Bailey + Stefan Niedermann (%1$s) + founder Translators Nextcloud community on %1$s Transifex @@ -313,7 +315,7 @@ Links have to be either complete URLs starting with a protocol and domain or absolute paths starting with a %1$s character. In order to conform to the Markdown format, please use escape characters in the image URL. This means for example, replace spaces with %1$s in the URL. - %20 + %20 / Images Fancy image -- GitLab From 38a672bee651684148ebdd2d65377555c941b467 Mon Sep 17 00:00:00 2001 From: nextcloud-android-bot Date: Sat, 28 Jan 2023 02:39:34 +0000 Subject: [PATCH 021/163] =?UTF-8?q?=F0=9F=94=84=20synced=20local=20'.githu?= =?UTF-8?q?b/workflows/'=20with=20remote=20'config/workflows/'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: nextcloud-android-bot --- .github/workflows/autoApproveSync.yml | 19 ++++++++++ .github/workflows/codeql.yml | 48 +++++++++++++++++------- .github/workflows/detectNewJavaFiles.yml | 32 ++++++++++++++++ .github/workflows/stale.yml | 28 ++++++++++++++ 4 files changed, 114 insertions(+), 13 deletions(-) create mode 100644 .github/workflows/autoApproveSync.yml create mode 100644 .github/workflows/detectNewJavaFiles.yml create mode 100644 .github/workflows/stale.yml diff --git a/.github/workflows/autoApproveSync.yml b/.github/workflows/autoApproveSync.yml new file mode 100644 index 000000000..707ef9b80 --- /dev/null +++ b/.github/workflows/autoApproveSync.yml @@ -0,0 +1,19 @@ +# synced from @nextcloud/android-config +name: Auto approve +on: + pull_request_target: + branches: + - master + - main + +permissions: + pull-requests: write + +jobs: + auto-approve: + runs-on: ubuntu-latest + steps: + - uses: hmarr/auto-approve-action@de8ae18c173c131e182d4adf2c874d8d2308a85b # v3.1.0 + if: ${{ contains(github.event.pull_request.labels.*.name, 'sync') && github.actor == 'nextcloud-android-bot' }} + with: + github-token: "${{ secrets.GITHUB_TOKEN }}" diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index d06291f0a..e3ef9f8c4 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -1,27 +1,49 @@ -name: CodeQL security scan +# synced from @nextcloud/android-config +name: "CodeQL" on: + push: + branches: [ "master", "main", "stable-*" ] pull_request: + branches: [ "master", "main" ] schedule: - - cron: '0 12 * * *' + - cron: '24 18 * * 3' permissions: contents: read - security-events: write - pull-requests: read jobs: - codeql: - name: CodeQL security scan + analyze: + name: Analyze runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + strategy: + fail-fast: false + matrix: + language: [ 'java' ] steps: - - name: Checkout - uses: actions/checkout@v3 + - name: Checkout repository + uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 + - name: Set Swap Space + uses: pierotofy/set-swap-space@49819abfb41bd9b44fb781159c033dba90353a7c # v1.0 + with: + swap-size-gb: 10 - name: Initialize CodeQL - uses: github/codeql-action/init@v2 + uses: github/codeql-action/init@436dbd9100756e97f42f45da571adeebf8270723 # v2.2.0 + with: + languages: ${{ matrix.language }} + - name: Set up JDK + uses: actions/setup-java@1df8dbefe2a8cbc99770194893dd902763bee34b # v3.9.0 with: - languages: java - - name: Build debug APK - run: bash ./gradlew assembleDev --stacktrace + distribution: "temurin" + java-version: 11 + - name: Assemble + run: | + mkdir -p "$HOME/.gradle" + echo "org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError" > "$HOME/.gradle/gradle.properties" + ./gradlew assembleDebug - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + uses: github/codeql-action/analyze@436dbd9100756e97f42f45da571adeebf8270723 # v2.2.0 diff --git a/.github/workflows/detectNewJavaFiles.yml b/.github/workflows/detectNewJavaFiles.yml new file mode 100644 index 000000000..b64964cef --- /dev/null +++ b/.github/workflows/detectNewJavaFiles.yml @@ -0,0 +1,32 @@ +# synced from @nextcloud/android-config +name: "Detect new java files" + +on: + pull_request: + branches: [ master, main, stable-* ] + +permissions: read-all + +jobs: + detectNewJavaFiles: + runs-on: ubuntu-latest + steps: + - id: file_changes + uses: trilom/file-changes-action@a6ca26c14274c33b15e6499323aac178af06ad4b # v1.2.4 + with: + output: ',' + - name: Detect new java files + run: | + if [ -z '${{ steps.file_changes.outputs.files_added }}' ]; then + echo "No new files added" + exit 0 + fi + new_java=$(echo '${{ steps.file_changes.outputs.files_added }}' | tr ',' '\n' | grep '\.java$' | cat) + if [ -n "$new_java" ]; then + # shellcheck disable=SC2016 + printf 'New java files detected:\n```\n%s\n```\n' "$new_java" | tee "$GITHUB_STEP_SUMMARY" + exit 1 + else + echo "No new java files detected" + exit 0 + fi diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml new file mode 100644 index 000000000..a959af77b --- /dev/null +++ b/.github/workflows/stale.yml @@ -0,0 +1,28 @@ +# synced from @nextcloud/android-config +name: 'Close stale issues' +on: + schedule: + - cron: '0 0 * * *' + +# Declare default permissions as read only. +permissions: read-all + +jobs: + stale: + runs-on: ubuntu-latest + permissions: + issues: write + pull-requests: write + steps: + - uses: actions/stale@6f05e4244c9a0b2ed3401882b05d701dd0a7289b # v7.0.0 + with: + days-before-stale: 28 + days-before-close: 14 + days-before-pr-close: -1 + only-labels: 'bug,needs info' + exempt-issue-labels: 'no-stale' + stale-issue-message: >- + This bug report did not receive an update in the last 4 weeks. + Please take a look again and update the issue with new details, + otherwise the issue will be automatically closed in 2 weeks. Thank you! + exempt-all-pr-milestones: true -- GitLab From 127d18bd5bdccf70d72b7d3ff8c17dd8e0c7baad Mon Sep 17 00:00:00 2001 From: nextcloud-android-bot Date: Sat, 28 Jan 2023 02:39:34 +0000 Subject: [PATCH 022/163] =?UTF-8?q?=F0=9F=94=84=20synced=20local=20'.githu?= =?UTF-8?q?b/dependabot.yml'=20with=20remote=20'config/dependabot.yml'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: nextcloud-android-bot --- .github/dependabot.yml | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 75c8395a5..60f86e7b8 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,12 +1,18 @@ +# synced from @nextcloud/android-config version: 2 updates: -- package-ecosystem: gradle - directory: "/" - schedule: - interval: daily - open-pull-requests-limit: 10 -- package-ecosystem: github-actions - directory: "/" - schedule: - interval: daily - open-pull-requests-limit: 10 + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + - package-ecosystem: gradle + directory: "/" + schedule: + interval: daily + time: "03:00" + timezone: Europe/Paris + rebase-strategy: "disabled" + open-pull-requests-limit: 10 + labels: + - 3. to review + - dependencies -- GitLab From 327ac6d319b0a7f6b7415f0b9fd73f2e71988066 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 28 Jan 2023 13:47:24 +0000 Subject: [PATCH 023/163] Bump github/codeql-action from 2.2.0 to 2.2.1 Bumps [github/codeql-action](https://github.com/github/codeql-action) from 2.2.0 to 2.2.1. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/436dbd9100756e97f42f45da571adeebf8270723...3ebbd71c74ef574dbc558c82f70e52732c8b44fe) --- updated-dependencies: - dependency-name: github/codeql-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/codeql.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index e3ef9f8c4..1608d962d 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -32,7 +32,7 @@ jobs: with: swap-size-gb: 10 - name: Initialize CodeQL - uses: github/codeql-action/init@436dbd9100756e97f42f45da571adeebf8270723 # v2.2.0 + uses: github/codeql-action/init@3ebbd71c74ef574dbc558c82f70e52732c8b44fe # v2.2.1 with: languages: ${{ matrix.language }} - name: Set up JDK @@ -46,4 +46,4 @@ jobs: echo "org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError" > "$HOME/.gradle/gradle.properties" ./gradlew assembleDebug - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@436dbd9100756e97f42f45da571adeebf8270723 # v2.2.0 + uses: github/codeql-action/analyze@3ebbd71c74ef574dbc558c82f70e52732c8b44fe # v2.2.1 -- GitLab From 510f7edc579e19346dbfee870f67197453bb0427 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 28 Jan 2023 13:51:57 +0000 Subject: [PATCH 024/163] Bump desugar_jdk_libs from 1.1.6 to 2.0.0 Bumps [desugar_jdk_libs](https://github.com/google/desugar_jdk_libs) from 1.1.6 to 2.0.0. - [Release notes](https://github.com/google/desugar_jdk_libs/releases) - [Changelog](https://github.com/google/desugar_jdk_libs/blob/master/CHANGELOG.md) - [Commits](https://github.com/google/desugar_jdk_libs/commits) --- updated-dependencies: - dependency-name: com.android.tools:desugar_jdk_libs dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 049019942..437364d9f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -72,7 +72,7 @@ ext { } dependencies { - coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.6' + coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.0' // Nextcloud SSO implementation 'com.github.nextcloud:Android-SingleSignOn:0.6.1' -- GitLab From 76daeee87d67379321b7387686ee8e842b8b1c7b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 30 Jan 2023 02:33:44 +0000 Subject: [PATCH 025/163] Bump mockito-core from 5.0.0 to 5.1.0 Bumps [mockito-core](https://github.com/mockito/mockito) from 5.0.0 to 5.1.0. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v5.0.0...v5.1.0) --- updated-dependencies: - dependency-name: org.mockito:mockito-core dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 049019942..e6de08c40 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -116,7 +116,7 @@ dependencies { testImplementation 'androidx.test:core:1.5.0' testImplementation 'androidx.arch.core:core-testing:2.1.0' testImplementation 'junit:junit:4.13.2' - testImplementation 'org.mockito:mockito-core:5.0.0' + testImplementation 'org.mockito:mockito-core:5.1.0' testImplementation 'org.robolectric:robolectric:4.9.2' implementation fileTree(dir: 'libs', include: ['*.jar']) -- GitLab From d89e04dc283752653887838b1ffe9cb31271e57f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 31 Jan 2023 02:09:07 +0000 Subject: [PATCH 026/163] Bump org.mockito:mockito-core from 5.1.0 to 5.1.1 Bumps [org.mockito:mockito-core](https://github.com/mockito/mockito) from 5.1.0 to 5.1.1. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v5.1.0...v5.1.1) --- updated-dependencies: - dependency-name: org.mockito:mockito-core dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index d3b394daa..7a5bdda1b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -116,7 +116,7 @@ dependencies { testImplementation 'androidx.test:core:1.5.0' testImplementation 'androidx.arch.core:core-testing:2.1.0' testImplementation 'junit:junit:4.13.2' - testImplementation 'org.mockito:mockito-core:5.1.0' + testImplementation 'org.mockito:mockito-core:5.1.1' testImplementation 'org.robolectric:robolectric:4.9.2' implementation fileTree(dir: 'libs', include: ['*.jar']) -- GitLab From 35c3d3f364a99db37df3a84f4257319d76313a1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Brey?= Date: Wed, 1 Feb 2023 12:40:44 +0100 Subject: [PATCH 027/163] Add Kotlin support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As Android team we've agreed to only use Kotlin for new code. Let's get the ball rolling for Notes too. Signed-off-by: Álvaro Brey --- app/build.gradle | 2 ++ build.gradle | 12 +++++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 7a5bdda1b..2879368fd 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,4 +1,5 @@ apply plugin: 'com.android.application' +apply plugin: 'org.jetbrains.kotlin.android' android { compileSdkVersion 33 @@ -89,6 +90,7 @@ dependencies { // Android X implementation 'androidx.appcompat:appcompat:1.6.0' + implementation 'androidx.core:core-ktx:1.9.0' implementation 'androidx.core:core-splashscreen:1.0.0' implementation 'androidx.fragment:fragment:1.5.5' implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1' diff --git a/build.gradle b/build.gradle index 219117ea0..04a97c6a3 100644 --- a/build.gradle +++ b/build.gradle @@ -1,12 +1,16 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { + ext { + kotlinVersion = '1.8.0' + } repositories { mavenCentral() google() } dependencies { classpath 'com.android.tools.build:gradle:7.4.0' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion" // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files @@ -19,10 +23,16 @@ allprojects { google() maven { url "https://jitpack.io" } } + } subprojects { tasks.withType(Test) { maxParallelForks = Runtime.runtime.availableProcessors().intdiv(2) ?: 1 } -} \ No newline at end of file + tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile) { + kotlinOptions { + jvmTarget = "11" + } + } +} -- GitLab From d50d57f305a6de9e6d163fdb2c705e472476d574 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Brey?= Date: Wed, 1 Feb 2023 12:51:18 +0100 Subject: [PATCH 028/163] CI: Don't run on push except on main and stable branches MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Right now, when opening a PR the CI is ran twice (one for the push event and one for the PR event). This prevents that: PRs will only get the CI ran once Signed-off-by: Álvaro Brey --- .github/workflows/android.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml index a994c5c06..bdc401a0b 100644 --- a/.github/workflows/android.yml +++ b/.github/workflows/android.yml @@ -1,6 +1,9 @@ name: Android CI -on: [push, pull_request] +on: + pull_request: + push: + branches: [ main, stable-* ] permissions: contents: read -- GitLab From e37bf5f99daf95c5cd93ec7be72112057156406f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Brey?= Date: Wed, 1 Feb 2023 15:31:55 +0100 Subject: [PATCH 029/163] Update launcher icon MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Requested by design team. Uses MDI edit icon. Signed-off-by: Álvaro Brey --- .../res/drawable/ic_launcher_foreground.xml | 24 +++++++++--------- app/src/main/ic_launcher-web.png | Bin 17774 -> 37187 bytes .../ic_launcher_background.xml | 0 .../res/drawable/ic_launcher_foreground.xml | 22 ++++++++-------- .../drawable/ic_launcher_foreground_full.xml | 21 ++++++--------- .../res/mipmap-anydpi-v26/ic_launcher.xml | 5 ++-- app/src/main/res/mipmap-hdpi/ic_launcher.png | Bin 4323 -> 4602 bytes app/src/main/res/mipmap-mdpi/ic_launcher.png | Bin 2716 -> 2846 bytes app/src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 6070 -> 6705 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 9147 -> 10702 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 13007 -> 15310 bytes 11 files changed, 33 insertions(+), 39 deletions(-) rename app/src/main/res/{drawable => drawable-v24}/ic_launcher_background.xml (100%) diff --git a/app/src/dev/res/drawable/ic_launcher_foreground.xml b/app/src/dev/res/drawable/ic_launcher_foreground.xml index 9cb8dccf2..24e5d164e 100644 --- a/app/src/dev/res/drawable/ic_launcher_foreground.xml +++ b/app/src/dev/res/drawable/ic_launcher_foreground.xml @@ -1,21 +1,21 @@ - - + android:viewportWidth="24" + android:viewportHeight="24"> + + android:fillColor="@android:color/white" + android:pathData="M20.71,7.04C21.1,6.65 21.1,6 20.71,5.63L18.37,3.29C18,2.9 17.35,2.9 16.96,3.29L15.12,5.12L18.87,8.87M3,17.25V21H6.75L17.81,9.93L14.06,6.18L3,17.25Z" /> + android:scaleX=".075" + android:scaleY=".075" + android:translateX="11.5" + android:translateY="13.5"> diff --git a/app/src/main/ic_launcher-web.png b/app/src/main/ic_launcher-web.png index c1e67d8b80be48e46b8a786bd79bc1f4245cdb57..07747f3be8e1890c7dc542683b9bf5a024bc0cec 100644 GIT binary patch literal 37187 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�hC!+cF_wdlNu23Z6C=s=1^Nuip)J|C|5${rIXc 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 Q;hz_0zBJ?TH1pg451jKuX8-^I literal 17774 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 diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable-v24/ic_launcher_background.xml similarity index 100% rename from app/src/main/res/drawable/ic_launcher_background.xml rename to app/src/main/res/drawable-v24/ic_launcher_background.xml diff --git a/app/src/main/res/drawable/ic_launcher_foreground.xml b/app/src/main/res/drawable/ic_launcher_foreground.xml index b3eb55f92..d06f1778d 100644 --- a/app/src/main/res/drawable/ic_launcher_foreground.xml +++ b/app/src/main/res/drawable/ic_launcher_foreground.xml @@ -1,14 +1,14 @@ - - - - - \ No newline at end of file + android:viewportWidth="24" + android:viewportHeight="24"> + + + + diff --git a/app/src/main/res/drawable/ic_launcher_foreground_full.xml b/app/src/main/res/drawable/ic_launcher_foreground_full.xml index cf08e71a5..d9c9707b2 100644 --- a/app/src/main/res/drawable/ic_launcher_foreground_full.xml +++ b/app/src/main/res/drawable/ic_launcher_foreground_full.xml @@ -1,14 +1,9 @@ - - - - - \ No newline at end of file + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + + diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml index 6f3b755bf..bbd3e0212 100644 --- a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -1,6 +1,5 @@ - - - + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png index ba3e251024ad47984447acd1830e1c6828431dc7..e3ff8ab5be0537ddb142e7ccafc9e58f06aa6cd6 100644 GIT binary patch literal 4602 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 literal 4323 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%0AC&T}Z zJD&=Xt_yJ_#yLA`r}*r1)aQ5hNKYqQ;|RHbx1S!D z{2@rX$FGxU3IwLp+*YYF%Zu9?jG!hg)t-+Pf)=Rne1lLIcHF0}^h`25V}I2n9)k5P`%akr`s;;UKwq!$_=vbV5zcbNgv^N^5vh;|IQ10D!f;=kMUNsFZGKGiY~pd4IL#y+l`r z004q^6A&;rk(GzW$jBs18#zNwECgXo^@{ZIgNJB_7bIs0h1_pm{iZeUzxLHb_h?Jc zjUj-xte1l*FaT;I2oXp!1Ou^v^LYpTWaR49&JTemP}m?ynL$tn0^jg3m1+h8n)PM5 zaRBw}2j*+bx-V(V&Qkyy34b&ZgnTp-5I;HKmrWbNf}jZ$wpH9KBxfiI2>ObO-yNJV z=DQw90KB~CK5f}K22gsQ0!#|2T&||(W)u_mseBTL%(!BeRPbt8z9*#yL4k3z09Ku74RbKMMeqUB;llP&YRwtp%Nmp4Gzqr_aB-YcXa zGDZToaX=rY!oThYpOx(Gk&O~Fl$#Fbt9PA4fS9HfEd@f9Qp*qc$i>T3JCB-p^5AGv zzet{Dr6Hz>L<|HSv%q=ASAX{!`kXXMD4*H!u)3t{3WI<&Du3;!0I3l38u~J(%>{r% zVH?H0LJmUiRW)_z!{MWwXXZ-JRqfMn{V0(=iE-MX-g@E_3Q%$`LeohCVzGN5&0(=2 z910t&Q=;MVAmW!J$r&mILR_KheG!a=vG7DY_-dve$9?B@pv-T1NnPAU03wE#fM6h6 z5cgttf11;R4S&!l@008mspH4=AckY+hS8WA&ev~nWBTAuwrCa-UeD%ycdmNdXC6o; zfas3$nn;3pNCp6Ne%bzEVysN>6><<#gP;sV)a-z#Uv$Q+$bBF;$>;cDQP8MfY}u?X z?u#s?siKEMU?eb|P!sbUeWK1Sf)EdavJj$_ibD)0DpbvI1S4VC+I|*%`zG~p zRh!H)NMYUw?(ZDb}$!NcqJeEVI@*wySo2j#`L;usH!D8APa1HwTe4&5Fg1&esfb#=4;x zHcjpNh9dMyI(1SPmZnv!Fhp~dFYn!>D*7ivaG4;I$B$csFjV7q<`8FubF>@x?L%Lv zPg!m5;$nKhP~EHA*!D+05|B=v@pQ@_A~8Q@1%FZ1A2ooG4Oq>7v;Q#o@NMdgY~IVQ zHu?oM*nDOF`yZ%woM8|s>=IU;vV{<4s0)S#6U{A5QL*cV4AoSGgOKuVr=)rgFAo# z0FIY+6YZ9dPpck(;TL!>de3R6johNbE&3`-|Wqw`?B)U+UEEgpqvzl~O zi(Zq~d3ukpaN(0-H_?LK1$O_;@8#vGRu^qiPZOHTg0XeJ(D0DYO}`kl+wQllqqMfsw7# z2UoC>R$t%ycGp@-s{@%3&AiziX^;2Y|9kIy-?vIhne2y=v z`?Y;C$vt4HQa{~W?ADmy^Gw&*jm}2H{d*hT8p-RNfNS8jzD~!@<(>x(RqhqWDpy(B zF84{}F1O88?RJ@}JR_!R??_sW#|36ftM#5V)ee`LYDQL=Yp*_d_d!s4(Ni{5x|SO& zoyWkg87o}`wtvL9i!;+M7co`2Iji=NG{I`ToYf9p13Q*hH?n+Mol`A!k307f;+)?% zmJhBnSO&Tb6%Jyk7zD>1XaQrzAZx5}u&__fROw^^gtIC)wKTLEZ$JPs*A5YLjkn8O zH@a#fCs2($mLH2Fsw&fPap25WGcEB18=@fOvekr4XDo zrPW<|OzPf~b{-sEqc0!u0{{VI_2qUy4?$HBEF6LYM1v5*soLW=*9`F>!+vw!(3;6Z zh@X6Ee~GRP951^}^d)v500bzA01yWvrV;`Kgq6A0>zh!c%2Sp+gs2*T^SgE6xUQ_9 zg?$$HDSrs3L}Cz?@xmzxV#bgX)Tnap0T-s+9)u`)bj7`;+R}caE9nF0FM;#0F93)k z#2}Ioj+hYPYES?nH!AFw35bLeo3HWU{43g$OGFFKYr%OiqC>lz5VgYq;vwd;{=ZCA zr`UDAnbu%sLC>S$xL;e`OTbvzC)DmB#JoKovVZu&?Id$|yGVWK4RXsL1VAM)oFd9Bj1vGs(k%T}(@XWbNEP^}ug-5-t}g5$ zU@Q+ol7f&Zv%mbnO?pOekuM=^HlDjerhipA$gDai`Dgc+ArP1o(qqLCn}!7-@4|DT zDu_yxI=}Ony6_?a6?_PgEJU~(>4!bkdBI5xovqDR$xH|(gg_EL83!wBp|}e>=XN( z#D4Wwg!5u0Fq|+aFtM>ZMeU(*tiXiELXg$8I#^P91ytL=s8H>+64eeX3lJnJ2$34; zhg_sX19;fES?#&hP-hRNUiYR^`u{08qUC!5n3N`>-;% zq2C;E$LygZ0I0zS8Fj#m z3qj}JE}}2AxfRcDniEXopT1~hvj1me@;V3@2f#zbR03@IzZ}GK!rkkYz zPOL)Rn#Z5{hPa(mFzfhJWkyzYH$o{bP5k*ex6%GPb zpj%0Z*%jTS#eI`H>4R4I?7$5Qfl4gna{?24(Y}F6HG&}!7CVb8f%*dLRpsyA`f)IN zg6*_MvGL>MirhBB_B4Us7bZ5`YMxg+mA+8$NOqzeKWPPCU$q6IW($uO-(;RpN3$Up^Sn z!}03XHEU@f6tY4tOwVR~@7s#apIQ|;Z2-~kr)o$*9PhhM9YzRL0>i1HeUv8lOiOpz zSdn-mD7EszLx1@77I^wu=WQvo=FO6x*mEi{sV~;9S7f&!Ku`q{gsHHTxUSy7p zr(HChFehRUc$0zX59lld0X-bAT3!7&^ilf7N|0!}?ClfHkkACe$%iV4mC*0xAfi^N zBpbn~5G9v=2%_0|<^uROlX|$MG0HL{r-EW?`nsp(?|(Lr(@@IcLMb$yqE{#>hH(U*5^c?)5gYw2mzTaL{Tp~&uZZ~<(j>F z(HH7d!hdgVxO_mVX3N(!9^{pPaBA^~K;*`Th~JV+l-a^=zoz68(O~Gkw*N5ra3A$0 zYTQSC!9h<@fX$I*ythZb^*jfW-Qoj?Ktd2v8o?;Z9nci^_%y|RM1$8@(|}L@e(D3i z@Rr0Y)yz~LVwQZx&Mf)nvtx3h#A1aKgCq|TP=6QLeCnd!00qhZd`$g((RRG&jr{5TZb*bJ`JvH`@jLn( zcg!^Y92vdFUH!9%lp@rLMme7+f;#yB2Q6=E{yP~x24{hI&K-#J{{x~-1iM`9M-4y# O00001P{v#6(zGaqvWNnOIr7TCcbpmR6aTmj3+p#nt-5 zB*pUi2ElTpi*6VlYzBen6%SZ;<$HHX3Vg6~1ZlacKZ{E$U&_?DUrEP(Ss} zL*J7*1V20MAmA0ZSF%j7)^ylim+913oT|0IIaLKiT{e$>45odm6+&I69jc$(Pg7tw zja3uV@B%bm)DzFFf|sL_1{E)3Lp+1eQ(ygvp5Ip1YQ{Au7qU_u_J@iSE{vxn;s-vK zng(&bG~HW+DQ6lF>KS)OCRtZM@R{23&o%p-G16_Dyw8elee-9FwOV@8EHNd~lxZ^a zLqn+hp)ak*kNy}iIa3H8@$Pfuaaq>RhFRs###M{VEZNouRFtP$*hVme`QWvMK}cf-F{)Zv}#GyqVfL87+$02UlA$@&B$H4@V) zarXiwdjrKY%!74+LG{v#SltFUxJ3OKcXsK~ikKWJUfNUFzjC>oqLsFM`GskikYp1h zik3wKQojRoXljCJZlIL`igJL{7{8_sD3E3@g?;=_?1_+HdaH4|P})#jY(V9*yPxqa zdO4H1>h&HmU9F6im~RfUK^0w=6qNdX#v0p~VT9H=Zg-u?*;VVfiTH`2?#MW#NxXyg z;ImoDm3#BB;%Ap=lWX6v=hp5Kg&0wUr;LOHv&VK6s&)6+~l{{VxdZ4Y^$AC1s!tw-d(U;#gqtKX@rXf*VRh zjm1KU_sp-({_(!>R+ZPbXbhF~jUK{9s?gg~Mn>yKVpSLQ#b8QF^Gp;HrEmhUOY7>7%(|@2vJTb?SxwXVWwtQB5~iR zNFR<$HN=k!M6C;Y6dz1X1!L>e=FHVqv@g0>K;j?`nh`^fk`md5L^zEhf-Oit1;+!Q zaJ(p;w`)JMWH$rFhT*1u1>>!oN0r^8Twqh``o6a<009~h2bLR83CjB#0z^*Ch^(13 zp*o{IfC?qPc{Wm0{!PD5akj7}rAVRqs#19Ps`-_@cjnUVu^1_Eh9d!m)}e66wK3+@{mKa4Dx3hs>H!vQ!X*P)P*k0-^2fT3AtJ z*OxWFR5ta)2OTwURw@>RIfS%c0)Acj9QYeaxo~lFof)PGM0vbO-2y)y<=cnMk4+Do z-Zx60$9X(i?oKjj`0(|!+}d|5tH(LGalO1I$L)QTeIc>#_750(k;#a>P)h1zYK+Cx zKP$UN;8!W{jWwyZa#uRN?s2T6emVN@3;oyY@M?jtcB7i*U4VN$oKClc9aC~egc^*x zm|kk85q?X<=v0EpsVs33(W@M@`B7TQFGZleE^gVL;+}RqoQhQl#sl)eXoMqdlU`yn zDM1XjlyNui9dqUl-{YcJA^wpRMTUN(w8^3BVF2z$dLl~76{JU8mI;jSgoY$OcaEe+ zFT6`l)G2!@Rs&tJ6c6B%R}eY(HnXZvsA2j$i~ftJ>i>nR~%fw zZ|Th+1Rw90i!sebzsg28y9n}4dGJp1#&1C?iP5h(ZQ7rGcB1g)QU=cA7Eh|QaWjdp zmi2f~(EtaY4ZIATLc$3mO;DIGx8-lGDW9{#lVz8==K{M&UCLX(KIOsPB~2tEJeoUg zCdZ5Zb@I)>%Es*88M7DSb(Sc%yU&j4A4kE- z;4O?lnO0{CK6^8JzEUOMyN5hp>mNu|@{L<+6fLjl&_CI=QIqGy^~kxD>I1!XeGf(B zI22kF+fu}_cy-)*ss0E(`eAfLY|g1!{@^vA#j+AmA_QWoDU#6c1Y$N$L;3T)892_ zq!>{p@J>`avxB<}trD#!3$2WQ@O4w=Y1ShAjAzK8M3`;Gx4-d>084R2e?I+YXz%oy ztb2D~XPTn&qD_1DscTuCeXKI)7yIU-t7dSK9`+HqxQLrP=w!EyZ928yaoJ2?n9KRB z1@)D$iR4><8C#=kwvqq_n9($pk7Xjz4mOG5R%c+vcCXjP1e_!8((lnDs-uHoRbgNGU01aF^<7qZNNzwPdt1Mv+vi>Y<;GIoFYZ>FQvlvB^ZQz7Edv zw-NFp&dZlg7)MVU*5PV3S80HHl@%y!hms1(OzKb0_y*n?cPXnziD zN&TLPKR`5&5gB_UC=625C-s@|hH)*CRGZW>_sS%H)jj6Bk!92LoIBz0Psg?6^_o%q zzZfK7C{0P^#Cz&Ipum8HNp|h9UtML{hT}%H{S7g2ld%-ULn;Fc>wfsm(x612ZCBs8 zx#!#~42aL5oI${W+^kPIBP`>tS%rzb5(eF2Kz4z_nY~o|mPtPbvX<3@k){2=&X#8D z&ZoHNvNb>MZx#!6QA-D>z#qQ(Q(B1iejsCdVt6c!fXZtuYa+wt{8iqaF^^b$;{R{H zIecR&9lgxj&VmFY;Otl#{CHULJ$!SC#0zPCf8Rd}&2N9AC;2yS?B?j2@~s5(a{fhA zrKvacXtqo|q=`tjHPyMt5VA2Vdcu2*iEDoXO`k6KM60#EEB_$Fk2MGXksh(ZIDLWb zo2KtG$L#yl??(0TRAETH6?0YA#C3*sXn`CtM&JOpTW!wj{pYU%zxQTMy^I8BD00hk zoGmY`ufJOuW7RuTYX(pfu%}|>raBSuhuiNlJ?ZLeM6(})xS@R_hUGE^Bpi+j&ncp` zxHsX{{NHxq4}ejjuUydA(say#Lb8Gi2u1@4@R*GXEv1x*=C&N9bXaolp}UJ@RIVBo zy5#0KZsa)^kIuklpp)1#vl@#TDO#N0RQt3<9OLbZN4tRy8=0;Gy90d)xOxe~!`T4D z0uvi(-}c?Q^WW*spq#v03A^z|W?{2Q5f{_ZhTAkeX(0M@#dw?xzQ7kejLzVqggYoIeee z@q7!mge?uxl{H#{=*X`Cp4^zBNIauv))CFpyB%wl8S)!mXN*llK%9IQsnJsw%n$W!s`qO6QlP0nh1 zhNQU7lL(zWxFJM`MKMwAK^-N(RX=!b7QLaz=0_YL12+mqX^4Gp+6EbvhH*r5ga-jx z_U`F@A2r_4o(|(+{okxQ_1>&};lB__XwI(`Cd@{-BSh(Ub#l=0-+u4&SED6?@#C8J zk=O6zC$7bgRlZ4n?O%CL5u)JFjyhb$je+&z@d%vipPmv2cK%G7O_3~<3sDBn6s3dF8l+w6u46GC zUOOw!^MO*Dm#$7416f=&@G%B&O+n^}uMEXxYS^S-?D_q}_sh=4H1S)vV2dN$nM0C) zU)nkv7-0`0M}aIvf#ncNVdGqM!5S zA+Gb7IvG(i3*DXe#mAc5Hi$8Fq^E@_@DTwQ;uJr>!8ML?#EzrGyjH*9RGW22)rXjh zbrQwgv2Yqzdi0$`pJR=xnZas~jX#(X3ztcQbNB0$*8XCY$p3y|59KM8V0201;SQbe zPGMg=su7%~>9b4zU$E=+F9eNmL)ovxG&DhaIL8FnIz{94!df7xK6>`{NOr!tM|QU$ z@BIM#*}mp8{$acg`Br6F&%41L6a9J{6rSeRjIUa(ngJd< zC2JO5(bEeP0~fwbrX#iOQf)JQqIOPyFt!Lv+kB&#{T2LHR%V}Dbd70$dSJ-xRbuH9 zU?6;@Gzp=L1=10W;m@{C|0de~1oB+BerfYucXLW!kexI;bQ>nAE>nodpjcoYwn?;r zsty0G(KqizzX}=$fyMwUe0d)x4>D>3zNX7PRftjRKv!bfqxoi}1^2svzCB5kzENI! z_{UK(Ac-2I0xXNX=C3lzILL6sW#||rfyM8CCl=cG$HWS`sS8Mt)@rk;lX3$D3U55} zDX4R;^qBR@rVY@rZ4q;$hPoj~3O`1+4Qr;Gom)fNUj;LLzz0)sY9bB#vXUMuX$NE7 zV)<(}6tz<~Wnz_N6<|{KdisZrf(3T~_tpAY;o*XHn-PW!8)y&>2pf>SK5l>k(CgJV zlz+w)8B?lVNG_*@2nZNuDHaeq-cEb;w;(+-Q`FY~vS(M$VIHmOO)y)7iKWTvb`zEo zT!h&`mCTxxjQuEt$9-j z?Iau`H1+%TWY$ihkhh^+oW&uH2{#U69B$Y11mg1bx)jH*Md}G~#?1Ou@xtVN6$8Un zKY3{I)u!U>Qr1|uc>8k6Z8ks;B4ZyNezXyeGaUNU)-l>K{j>iC)7Ru2YwPtYHJG$w z+g3*bPuY^X*n2JXYvE|9G#u?g`sUi#ovQLl7g3P3z~9RL!0I$?dSrpx4*H&2d!CSo zJ7lhKD7cs$$k^8AZmG-iCi;h>FBfJj9@v7M5tnbkRtQppWP?zA1R-y7d_2lzuvc|6 zZ%VV;&hvP4Om?r6M)>3J{DH;W$@;0^sNY|qXVCJ5Mt1T42k1+nXGi`IcsW7jcb6p% zf+KB9rpZA{<)i9$NZ=69e2jjbqnYz$WHXW`uuW_()*X5B-b*mowe#%dSdurrk?|;$ zDU3I_k$DG09MTt=z1k{1DzG|8vzGTfaAY!=R5 zxl~mmYRVUK*^`7x4`N)Ld@fTvUtE`*@bt9;&r(zxguJ{ON6aoTLv*6ub^HE6b6W%# z@tBnULOVUlgSRKZ`&>W=*U|T@u5`6k}8NW=&&h)XbS6=08N@o5<`e@;y8JXr;31L@6E|Ghi42oEF{SdKn z4B_{mrl(o@L<;KlCI?wtf@-hk7~T*QWW?~ISP~}(SZYH7H0ko8~IA(w+Z6=uSGaAvPmn-ikK`59T%e*6$e6#M` zuy^36t!7E37i4uRp=<|*KGnV37KKa-msj#=1!a4ztlgsiIuWoX^X*I$m%cc^s9K53 z5V|bwj%$gVL0D{8+V73t5Az+-c6`SMh32Qt~JL->%LF7VY52Xx#5|IuP!}lF?VMF9M;X!4~b^JWU^| zVu771@opt!V(3#}J43?i!__+9V>-b}G$j5dCqYbQm$FG1M0fGE&yvZHUbrYi1Na*wl$$ffMdy1PA9>=m z8I*Vay2Xh%u=PiMWze&q4fER>CbA2fd>9?sz>xCH0-juAM*w%W_MI=Jt(OIqpuYUK zm+B&ApOj%$SQn{9de`v1g&8c*nYO+JtcTq_<$zi;W%YFL1B1PJ1T7L0h)-Pb#Buwc zO*HU+f4fVse^JyXepP#nb&PZD>H7Z5sLo^szyJKR-RJK^*|G`q1r+Gp*SHzEo?b1I zkyxp8SxsfB@|AIo)w~_3)}e4+28Ts!Kzn)e5x;qTw-kM=ig=q!YWrw~kH_`3|7_P3 zO@+`ps>;J^wr-m!=I_dhr>H}c{l8u+V+-}o4&c7tz1_<=aK21pfmj9Xp6nO ziOuc#tIK$BX5~m>fT`)-4S@pt6q=8^dR4#Cj%^^PZ0d)CdZSrpeP?~=e20Tuf*t$? z<2!;+y4wF)Bmksas~!hDZNv{38t3kD(5zvG>-8$-Y-0K)hozLl6Fz5uajx&L{kk{v zT{$(qF$S37zt$g9HF2_V96d5qvr-ev!h3$uOI4OQwtlVm-lwmMO<}1kAC$t&BsPvE zVz^?&q;E{Ub(TEUKk+snc49bklWq(GmGHKYQBGGyRn3)VzxISpgmQSXfuVxq9E@DL zmBZ5dyx|-FmHBhoxv4C@TOHhz`I4O#@XvQk^(3;!1}h`bOx5gl?bPRl>B97O2IB0m zf!enYWxsj<{=whjrHzXcrM6jmCutdin%;u>s`$Hnv#9DZ$5}(g0+;!xG+i3Q?v2_;ZA^A;&9jkPO}Fop=X6Np xJ7f&6QPA^#uA*j_pCpXMAJ7#kzvwup@EtDhFeUbBke`A8U9CHsl^A>c{{YB&A}Rm? literal 6070 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 diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png index b464fdc0e1bcff3d30ca6ee7f612ca17835724b9..b763e09e5b3617362037b99ec585bfd7f04a96f2 100644 GIT binary patch literal 10702 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≻lno74b@~(U(gvbD_%GBMhfWV`R^AbA^(zNhgoY! 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 literal 9147 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 -- GitLab From c99da1315cb002a8167a968efd72f560d2d09bb1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 Feb 2023 15:02:46 +0000 Subject: [PATCH 030/163] Bump com.github.stefan-niedermann:android-commons from 0.2.7 to 0.2.9 Bumps com.github.stefan-niedermann:android-commons from 0.2.7 to 0.2.9. --- updated-dependencies: - dependency-name: com.github.stefan-niedermann:android-commons dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 2879368fd..4bd46c3e0 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -77,7 +77,7 @@ dependencies { // Nextcloud SSO implementation 'com.github.nextcloud:Android-SingleSignOn:0.6.1' - implementation 'com.github.stefan-niedermann:android-commons:0.2.7' + implementation 'com.github.stefan-niedermann:android-commons:0.2.9' implementation 'com.github.stefan-niedermann.nextcloud-commons:sso-glide:1.6.4' implementation 'com.github.stefan-niedermann.nextcloud-commons:exception:1.6.4' implementation('com.github.stefan-niedermann.nextcloud-commons:markdown:1.6.4') { -- GitLab From 882e222bf6ecff9e8ba0baa9437bbf1dc7b5588a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 2 Feb 2023 02:07:41 +0000 Subject: [PATCH 031/163] Bump com.android.tools.build:gradle from 7.4.0 to 7.4.1 Bumps com.android.tools.build:gradle from 7.4.0 to 7.4.1. --- updated-dependencies: - dependency-name: com.android.tools.build:gradle dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 04a97c6a3..6dfbe833d 100644 --- a/build.gradle +++ b/build.gradle @@ -9,7 +9,7 @@ buildscript { google() } dependencies { - classpath 'com.android.tools.build:gradle:7.4.0' + classpath 'com.android.tools.build:gradle:7.4.1' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion" // NOTE: Do not place your application dependencies here; they belong -- GitLab From 907d83f4a9520ff50ee1bbbee4ae61912de325c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Brey?= Date: Thu, 2 Feb 2023 15:24:20 +0100 Subject: [PATCH 032/163] Install fastlane MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Álvaro Brey --- .bundle/config | 2 + .gitignore | 2 + Gemfile | 3 + Gemfile.lock | 218 +++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 225 insertions(+) create mode 100644 .bundle/config create mode 100644 Gemfile create mode 100644 Gemfile.lock diff --git a/.bundle/config b/.bundle/config new file mode 100644 index 000000000..236922881 --- /dev/null +++ b/.bundle/config @@ -0,0 +1,2 @@ +--- +BUNDLE_PATH: "vendor/bundle" diff --git a/.gitignore b/.gitignore index e93457ad0..449e34b5d 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,5 @@ /.idea/ *.iml /projectFilesBackup/ +# fastlane +/vendor/bundle diff --git a/Gemfile b/Gemfile new file mode 100644 index 000000000..adc90d98c --- /dev/null +++ b/Gemfile @@ -0,0 +1,3 @@ +source "https://rubygems.org" + +gem "fastlane" \ No newline at end of file diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 000000000..2c5fd63b5 --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,218 @@ +GEM + remote: https://rubygems.org/ + specs: + CFPropertyList (3.0.6) + rexml + addressable (2.8.1) + public_suffix (>= 2.0.2, < 6.0) + artifactory (3.0.15) + atomos (0.1.3) + aws-eventstream (1.2.0) + aws-partitions (1.703.0) + aws-sdk-core (3.170.0) + aws-eventstream (~> 1, >= 1.0.2) + aws-partitions (~> 1, >= 1.651.0) + aws-sigv4 (~> 1.5) + jmespath (~> 1, >= 1.6.1) + aws-sdk-kms (1.62.0) + aws-sdk-core (~> 3, >= 3.165.0) + aws-sigv4 (~> 1.1) + aws-sdk-s3 (1.119.0) + aws-sdk-core (~> 3, >= 3.165.0) + aws-sdk-kms (~> 1) + aws-sigv4 (~> 1.4) + aws-sigv4 (1.5.2) + aws-eventstream (~> 1, >= 1.0.2) + babosa (1.0.4) + claide (1.1.0) + colored (1.2) + colored2 (3.1.2) + commander (4.6.0) + highline (~> 2.0.0) + declarative (0.0.20) + digest-crc (0.6.4) + rake (>= 12.0.0, < 14.0.0) + domain_name (0.5.20190701) + unf (>= 0.0.5, < 1.0.0) + dotenv (2.8.1) + emoji_regex (3.2.3) + excon (0.98.0) + faraday (1.10.3) + faraday-em_http (~> 1.0) + faraday-em_synchrony (~> 1.0) + faraday-excon (~> 1.1) + faraday-httpclient (~> 1.0) + faraday-multipart (~> 1.0) + faraday-net_http (~> 1.0) + faraday-net_http_persistent (~> 1.0) + faraday-patron (~> 1.0) + faraday-rack (~> 1.0) + faraday-retry (~> 1.0) + ruby2_keywords (>= 0.0.4) + faraday-cookie_jar (0.0.7) + faraday (>= 0.8.0) + http-cookie (~> 1.0.0) + faraday-em_http (1.0.0) + faraday-em_synchrony (1.0.0) + faraday-excon (1.1.0) + faraday-httpclient (1.0.1) + faraday-multipart (1.0.4) + multipart-post (~> 2) + faraday-net_http (1.0.1) + faraday-net_http_persistent (1.2.0) + faraday-patron (1.0.0) + faraday-rack (1.0.0) + faraday-retry (1.0.3) + faraday_middleware (1.2.0) + faraday (~> 1.0) + fastimage (2.2.6) + fastlane (2.211.0) + CFPropertyList (>= 2.3, < 4.0.0) + addressable (>= 2.8, < 3.0.0) + artifactory (~> 3.0) + aws-sdk-s3 (~> 1.0) + babosa (>= 1.0.3, < 2.0.0) + bundler (>= 1.12.0, < 3.0.0) + colored + commander (~> 4.6) + dotenv (>= 2.1.1, < 3.0.0) + emoji_regex (>= 0.1, < 4.0) + excon (>= 0.71.0, < 1.0.0) + faraday (~> 1.0) + faraday-cookie_jar (~> 0.0.6) + faraday_middleware (~> 1.0) + fastimage (>= 2.1.0, < 3.0.0) + gh_inspector (>= 1.1.2, < 2.0.0) + google-apis-androidpublisher_v3 (~> 0.3) + google-apis-playcustomapp_v1 (~> 0.1) + google-cloud-storage (~> 1.31) + highline (~> 2.0) + json (< 3.0.0) + jwt (>= 2.1.0, < 3) + mini_magick (>= 4.9.4, < 5.0.0) + multipart-post (~> 2.0.0) + naturally (~> 2.2) + optparse (~> 0.1.1) + plist (>= 3.1.0, < 4.0.0) + rubyzip (>= 2.0.0, < 3.0.0) + security (= 0.1.3) + simctl (~> 1.6.3) + terminal-notifier (>= 2.0.0, < 3.0.0) + terminal-table (>= 1.4.5, < 2.0.0) + tty-screen (>= 0.6.3, < 1.0.0) + tty-spinner (>= 0.8.0, < 1.0.0) + word_wrap (~> 1.0.0) + xcodeproj (>= 1.13.0, < 2.0.0) + xcpretty (~> 0.3.0) + xcpretty-travis-formatter (>= 0.0.3) + gh_inspector (1.1.3) + google-apis-androidpublisher_v3 (0.33.0) + google-apis-core (>= 0.9.1, < 2.a) + google-apis-core (0.10.0) + addressable (~> 2.5, >= 2.5.1) + googleauth (>= 0.16.2, < 2.a) + httpclient (>= 2.8.1, < 3.a) + mini_mime (~> 1.0) + representable (~> 3.0) + retriable (>= 2.0, < 4.a) + rexml + webrick + google-apis-iamcredentials_v1 (0.16.0) + google-apis-core (>= 0.9.1, < 2.a) + google-apis-playcustomapp_v1 (0.12.0) + google-apis-core (>= 0.9.1, < 2.a) + google-apis-storage_v1 (0.19.0) + google-apis-core (>= 0.9.0, < 2.a) + google-cloud-core (1.6.0) + google-cloud-env (~> 1.0) + google-cloud-errors (~> 1.0) + google-cloud-env (1.6.0) + faraday (>= 0.17.3, < 3.0) + google-cloud-errors (1.3.0) + google-cloud-storage (1.44.0) + addressable (~> 2.8) + digest-crc (~> 0.4) + google-apis-iamcredentials_v1 (~> 0.1) + google-apis-storage_v1 (~> 0.19.0) + google-cloud-core (~> 1.6) + googleauth (>= 0.16.2, < 2.a) + mini_mime (~> 1.0) + googleauth (1.3.0) + faraday (>= 0.17.3, < 3.a) + jwt (>= 1.4, < 3.0) + memoist (~> 0.16) + multi_json (~> 1.11) + os (>= 0.9, < 2.0) + signet (>= 0.16, < 2.a) + highline (2.0.3) + http-cookie (1.0.5) + domain_name (~> 0.5) + httpclient (2.8.3) + jmespath (1.6.2) + json (2.6.3) + jwt (2.7.0) + memoist (0.16.2) + mini_magick (4.12.0) + mini_mime (1.1.2) + multi_json (1.15.0) + multipart-post (2.0.0) + nanaimo (0.3.0) + naturally (2.2.1) + optparse (0.1.1) + os (1.1.4) + plist (3.6.0) + public_suffix (5.0.1) + rake (13.0.6) + representable (3.2.0) + declarative (< 0.1.0) + trailblazer-option (>= 0.1.1, < 0.2.0) + uber (< 0.2.0) + retriable (3.1.2) + rexml (3.2.5) + rouge (2.0.7) + ruby2_keywords (0.0.5) + rubyzip (2.3.2) + security (0.1.3) + signet (0.17.0) + addressable (~> 2.8) + faraday (>= 0.17.5, < 3.a) + jwt (>= 1.5, < 3.0) + multi_json (~> 1.10) + simctl (1.6.10) + CFPropertyList + naturally + terminal-notifier (2.0.0) + terminal-table (1.8.0) + unicode-display_width (~> 1.1, >= 1.1.1) + trailblazer-option (0.1.2) + tty-cursor (0.7.1) + tty-screen (0.8.1) + tty-spinner (0.9.3) + tty-cursor (~> 0.7) + uber (0.1.0) + unf (0.1.4) + unf_ext + unf_ext (0.0.8.2) + unicode-display_width (1.8.0) + webrick (1.8.1) + word_wrap (1.0.0) + xcodeproj (1.22.0) + CFPropertyList (>= 2.3.3, < 4.0) + atomos (~> 0.1.3) + claide (>= 1.0.2, < 2.0) + colored2 (~> 3.1) + nanaimo (~> 0.3.0) + rexml (~> 3.2.4) + xcpretty (0.3.0) + rouge (~> 2.0.7) + xcpretty-travis-formatter (1.0.1) + xcpretty (~> 0.2, >= 0.0.7) + +PLATFORMS + x86_64-linux + +DEPENDENCIES + fastlane + +BUNDLED WITH + 2.4.6 -- GitLab From 6e96336550d8dfa60cb902fef441fd97849708af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Brey?= Date: Thu, 2 Feb 2023 15:29:06 +0100 Subject: [PATCH 033/163] Run fastlane init MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Álvaro Brey --- fastlane/Appfile | 2 ++ fastlane/Fastfile | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 fastlane/Appfile create mode 100644 fastlane/Fastfile diff --git a/fastlane/Appfile b/fastlane/Appfile new file mode 100644 index 000000000..9d87857c8 --- /dev/null +++ b/fastlane/Appfile @@ -0,0 +1,2 @@ +json_key_file("~/.gradle/Google Play Android Developer-Fastlane.json") # Path to the json secret file - Follow https://docs.fastlane.tools/actions/supply/#setup to get one +package_name("it.niedermann.owncloud.notes") # e.g. com.krausefx.app diff --git a/fastlane/Fastfile b/fastlane/Fastfile new file mode 100644 index 000000000..19c557cc6 --- /dev/null +++ b/fastlane/Fastfile @@ -0,0 +1,38 @@ +# This file contains the fastlane.tools configuration +# You can find the documentation at https://docs.fastlane.tools +# +# For a list of all available actions, check out +# +# https://docs.fastlane.tools/actions +# +# For a list of all available plugins, check out +# +# https://docs.fastlane.tools/plugins/available-plugins +# + +# Uncomment the line if you want fastlane to automatically update itself +# update_fastlane + +default_platform(:android) + +platform :android do + desc "Runs all the tests" + lane :test do + gradle(task: "test") + end + + desc "Submit a new Beta Build to Crashlytics Beta" + lane :beta do + gradle(task: "clean assembleRelease") + crashlytics + + # sh "your_script.sh" + # You can also use other beta testing services here + end + + desc "Deploy a new version to the Google Play" + lane :deploy do + gradle(task: "clean assembleRelease") + upload_to_play_store + end +end -- GitLab From bed7449f1d9a007864fe7ce6e0bcf290c506b6a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Brey?= Date: Thu, 2 Feb 2023 15:32:45 +0100 Subject: [PATCH 034/163] fastlane: skip doc generation, remove test task MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Álvaro Brey --- fastlane/Fastfile | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 19c557cc6..9cd1be39c 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -13,14 +13,11 @@ # Uncomment the line if you want fastlane to automatically update itself # update_fastlane +skip_docs + default_platform(:android) platform :android do - desc "Runs all the tests" - lane :test do - gradle(task: "test") - end - desc "Submit a new Beta Build to Crashlytics Beta" lane :beta do gradle(task: "clean assembleRelease") -- GitLab From 3ca4301c7a13f8a4bcf8c5167f09600ea5dcace5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Brey?= Date: Thu, 2 Feb 2023 16:48:06 +0100 Subject: [PATCH 035/163] Change 'founder' to 'original author' in credits MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Better wording Signed-off-by: Álvaro Brey --- .../owncloud/notes/about/AboutFragmentCreditsTab.java | 5 +---- app/src/main/res/values/strings.xml | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/it/niedermann/owncloud/notes/about/AboutFragmentCreditsTab.java b/app/src/main/java/it/niedermann/owncloud/notes/about/AboutFragmentCreditsTab.java index 717640b65..8bfd785e1 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/about/AboutFragmentCreditsTab.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/about/AboutFragmentCreditsTab.java @@ -2,11 +2,8 @@ package it.niedermann.owncloud.notes.about; import static it.niedermann.owncloud.notes.shared.util.SupportUtil.setTextWithURL; import static it.niedermann.owncloud.notes.shared.util.SupportUtil.strong; -import static it.niedermann.owncloud.notes.shared.util.SupportUtil.url; import android.os.Bundle; -import android.text.Spannable; -import android.text.method.LinkMovementMethod; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -24,7 +21,7 @@ public class AboutFragmentCreditsTab extends Fragment { public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { final var binding = FragmentAboutCreditsTabBinding.inflate(inflater, container, false); binding.aboutVersion.setText(getString(R.string.about_version, strong(BuildConfig.VERSION_NAME))); - final var founderText = getString(R.string.about_developers_stefan, getString(R.string.about_developers_founder)); + final var founderText = getString(R.string.about_developers_stefan, getString(R.string.about_developers_original_author)); setTextWithURL(binding.aboutDevelopers, getResources(), R.string.about_developers, founderText, R.string.url_niedermann_it); setTextWithURL(binding.aboutTranslators, getResources(), R.string.about_translators_transifex, R.string.about_translators_transifex_label, R.string.url_translations); return binding.getRoot(); diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index d3e5f7c89..41e7e9fcf 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -74,7 +74,7 @@ Developers %1$s, Kristof Hamann, HeaDBanGer84, Felix Edelmann, Daniel Bailey Stefan Niedermann (%1$s) - founder + original author Translators Nextcloud community on %1$s Transifex -- GitLab From a02624d7e2066cea6075983fe9ead349a2586cf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Brey?= Date: Thu, 2 Feb 2023 16:26:23 +0100 Subject: [PATCH 036/163] Setup fastlane to build app, release on Google Play and create git tag MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Álvaro Brey --- .gitignore | 1 + Gemfile | 2 +- fastlane/Fastfile | 114 ++++++++++++++++++++++++++++++++++++++++------ 3 files changed, 102 insertions(+), 15 deletions(-) diff --git a/.gitignore b/.gitignore index 449e34b5d..10595f178 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ /projectFilesBackup/ # fastlane /vendor/bundle +fastlane/report.xml diff --git a/Gemfile b/Gemfile index adc90d98c..7a118b49b 100644 --- a/Gemfile +++ b/Gemfile @@ -1,3 +1,3 @@ source "https://rubygems.org" -gem "fastlane" \ No newline at end of file +gem "fastlane" diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 9cd1be39c..2600dd976 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -13,23 +13,109 @@ # Uncomment the line if you want fastlane to automatically update itself # update_fastlane +## config +# add following to your shell rc: +# export FASTLANE_NOTES_UPLOAD_STORE_FILE="" +# export FASTLANE_NOTES_UPLOAD_STORE_PASSWORD="" +# export FASTLANE_NOTES_UPLOAD_KEY_ALIAS="" +# export FASTLANE_NOTES_UPLOAD_KEY_PASSWORD="" +# export FASTLANE_NEXTCLOUD_GITHUB_API_TOKEN="" + + skip_docs default_platform(:android) +BUNDLE_PATH = "app/build/outputs/bundle/playRelease/app-play-release.aab" + platform :android do - desc "Submit a new Beta Build to Crashlytics Beta" - lane :beta do - gradle(task: "clean assembleRelease") - crashlytics - - # sh "your_script.sh" - # You can also use other beta testing services here - end - - desc "Deploy a new version to the Google Play" - lane :deploy do - gradle(task: "clean assembleRelease") - upload_to_play_store - end +desc "Build app bundle" + + lane :releasePhase1 do + test() + buildBundle() + end + + lane :test do + gradle(task: "clean testPlayReleaseUnitTest testFdroidReleaseUnitTest") + end + + lane :buildBundle do + gradle( + task: 'bundle', + flavor: 'play', + build_type: 'Release', + print_command: false, + properties: { + "android.injected.signing.store.file" => ENV["FASTLANE_NOTES_UPLOAD_STORE_FILE"], + "android.injected.signing.store.password" => ENV["FASTLANE_NOTES_UPLOAD_STORE_PASSWORD"], + "android.injected.signing.key.alias" => ENV["FASTLANE_NOTES_UPLOAD_KEY_ALIAS"], + "android.injected.signing.key.password" => ENV["FASTLANE_NOTES_UPLOAD_KEY_PASSWORD"], + } + ) + end + + lane :releasePhase2 do + versionInfo = getVersionInfo() + promptVersion(versionInfo) + checkArtifactsExist() + tag(versionInfo) + uploadToPlayStore() + end + + desc "Read versions from gradle file" + private_lane :getVersionInfo do + File.open("../app/build.gradle","r") do |file| + text = file.read + versionName = text.match(/versionName "([0-9\.]*)"$/)[1] + versionCode = text.match(/versionCode ([0-9]*)$/)[1] + + { "versionCode" => versionCode, "versionName" => versionName } + end + end + + desc "Show versions and prompt for confirmation" + private_lane :promptVersion do |versionInfo| + currentBranch = git_branch() + print "Version code: #{versionInfo["versionCode"]}\n" + print "Version name: #{versionInfo["versionName"]}\n" + print "Current branch: #{currentBranch}\n" + print "Tag (to be created): #{versionInfo["versionName"]}\n" + + + answer = prompt(text: "is this okay?", boolean: true) + + if !answer + exit + end + end + + desc "Check if release artifacts exist" + private_lane :checkArtifactsExist do + if !File.exist?("../#{BUNDLE_PATH}") + print "Bundle not found at #{BUNDLE_PATH}\n" + exit + end + end + + + desc "Create release tag" + private_lane :tag do |versionInfo| + tagName = versionInfo["versionName"] + add_git_tag( + tag: tagName, + sign: true + ) + push_git_tags(tag: tagName) + end + + desc "Upload release artifacts to Google Play" + private_lane :uploadToPlayStore do + upload_to_play_store( + skip_upload_images: true, + skip_upload_apk: true, + aab: BUNDLE_PATH, + ) + end + end -- GitLab From 974a7a7b75269502d59912e065e1dd52dc1bc8b1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 3 Feb 2023 02:11:46 +0000 Subject: [PATCH 037/163] Bump org.jetbrains.kotlin:kotlin-gradle-plugin from 1.8.0 to 1.8.10 Bumps [org.jetbrains.kotlin:kotlin-gradle-plugin](https://github.com/JetBrains/kotlin) from 1.8.0 to 1.8.10. - [Release notes](https://github.com/JetBrains/kotlin/releases) - [Changelog](https://github.com/JetBrains/kotlin/blob/v1.8.10/ChangeLog.md) - [Commits](https://github.com/JetBrains/kotlin/compare/v1.8.0...v1.8.10) --- updated-dependencies: - dependency-name: org.jetbrains.kotlin:kotlin-gradle-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 6dfbe833d..89ae36e08 100644 --- a/build.gradle +++ b/build.gradle @@ -2,7 +2,7 @@ buildscript { ext { - kotlinVersion = '1.8.0' + kotlinVersion = '1.8.10' } repositories { mavenCentral() -- GitLab From 0087139150550506875c79689c20719664a345a8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 3 Feb 2023 02:11:59 +0000 Subject: [PATCH 038/163] Bump com.android.tools:desugar_jdk_libs from 2.0.0 to 2.0.1 Bumps [com.android.tools:desugar_jdk_libs](https://github.com/google/desugar_jdk_libs) from 2.0.0 to 2.0.1. - [Release notes](https://github.com/google/desugar_jdk_libs/releases) - [Changelog](https://github.com/google/desugar_jdk_libs/blob/master/CHANGELOG.md) - [Commits](https://github.com/google/desugar_jdk_libs/commits) --- updated-dependencies: - dependency-name: com.android.tools:desugar_jdk_libs dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 4bd46c3e0..38e40109a 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -73,7 +73,7 @@ ext { } dependencies { - coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.0' + coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.1' // Nextcloud SSO implementation 'com.github.nextcloud:Android-SingleSignOn:0.6.1' -- GitLab From 96c13932539ca5a8d1775cdb003616d5fcb57839 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Brey?= Date: Fri, 3 Feb 2023 10:47:21 +0100 Subject: [PATCH 039/163] build: Change version code schema to match Files/Talk, bump to 4.0.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Álvaro Brey --- app/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 4bd46c3e0..2b8614768 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -15,8 +15,8 @@ android { applicationId "it.niedermann.owncloud.notes" minSdkVersion 23 targetSdkVersion 33 - versionCode 3007001 - versionName "3.7.1" + versionCode 40000000 + versionName "4.0.0 Alpha 1" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" javaCompileOptions { annotationProcessorOptions { -- GitLab From 5a8bad3a58edc7cef7a8e278cf251f84c24cdbb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Brey?= Date: Fri, 3 Feb 2023 10:47:45 +0100 Subject: [PATCH 040/163] fastlane: implement lanes to handle/bump versions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Álvaro Brey --- fastlane/Fastfile | 21 +----- fastlane/utils.Fastfile | 138 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 141 insertions(+), 18 deletions(-) create mode 100644 fastlane/utils.Fastfile diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 2600dd976..10f141c7a 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -28,6 +28,8 @@ default_platform(:android) BUNDLE_PATH = "app/build/outputs/bundle/playRelease/app-play-release.aab" +import("./utils.Fastfile") + platform :android do desc "Build app bundle" @@ -63,17 +65,6 @@ desc "Build app bundle" uploadToPlayStore() end - desc "Read versions from gradle file" - private_lane :getVersionInfo do - File.open("../app/build.gradle","r") do |file| - text = file.read - versionName = text.match(/versionName "([0-9\.]*)"$/)[1] - versionCode = text.match(/versionCode ([0-9]*)$/)[1] - - { "versionCode" => versionCode, "versionName" => versionName } - end - end - desc "Show versions and prompt for confirmation" private_lane :promptVersion do |versionInfo| currentBranch = git_branch() @@ -81,13 +72,7 @@ desc "Build app bundle" print "Version name: #{versionInfo["versionName"]}\n" print "Current branch: #{currentBranch}\n" print "Tag (to be created): #{versionInfo["versionName"]}\n" - - - answer = prompt(text: "is this okay?", boolean: true) - - if !answer - exit - end + promptYesNo() end desc "Check if release artifacts exist" diff --git a/fastlane/utils.Fastfile b/fastlane/utils.Fastfile new file mode 100644 index 000000000..1eb2ad9e8 --- /dev/null +++ b/fastlane/utils.Fastfile @@ -0,0 +1,138 @@ +BUILD_NUMBER_RC_START = 51 +BUILD_NUMBER_FINAL_START = 90 + +MAJOR_MULTIPLIER = 10000000 +MINOR_MULTIPLIER = 10000 +PATCH_MULTIPLIER = 100 + +platform :android do + desc "Print version info" + lane :printVersionInfo do + versionInfo = getVersionInfo() + versionComponents = parseVersionCode(versionInfo) + print "Version code: #{versionInfo["versionCode"]}\n" + print "Version name: #{versionInfo["versionName"]}\n" + print "Major: #{versionComponents["major"]}\n" + print "Minor: #{versionComponents["minor"]}\n" + print "Patch: #{versionComponents["patch"]}\n" + print "Build: #{versionComponents["build"]}\n" + end + + # Usage: fastlane incrementVersion [type:major|minor|patch|rc|final] + # For major, minor, and patch: will increment that version number by 1 and set the smaller ones to 0 + # For rc, final: will set build number to first rc/first final or increment it by 1 + desc "Increment version code and version name" + lane :incrementVersion do |options| + versionInfo = getVersionInfo() + versionComponents = parseVersionCode(versionInfo) + newVersionComponents = incrementVersionComponents(versionComponents: versionComponents, type: options[:type]) + versionNameGenerated = generateVersionName(newVersionComponents) + versionCodeGenerated = generateVersionCode(newVersionComponents) + + print "Version code: #{versionInfo["versionCode"]} -> #{versionCodeGenerated}\n" + print "Version name: #{versionInfo["versionName"]} -> #{versionNameGenerated}\n" + promptYesNo() + writeVersions(versionCode: versionCodeGenerated, versionName: versionNameGenerated) + end + + + desc "Parse major, minor, patch and build from versionCode" + private_lane :parseVersionCode do |versionInfo| + versionCode = versionInfo["versionCode"] + build = versionCode % 100 + patch = (versionCode / PATCH_MULTIPLIER) % 100 + minor = (versionCode / MINOR_MULTIPLIER) % 100 + major = (versionCode / MAJOR_MULTIPLIER) % 100 + + { "major" => major, "minor" => minor, "patch" => patch, "build" => build } + end + + desc "Generate versionCode from version components" + private_lane :generateVersionCode do |versionComponents| + print "Generating version code from #{versionComponents}\n" + major = versionComponents["major"] + minor = versionComponents["minor"] + patch = versionComponents["patch"] + build = versionComponents["build"] + test = major * MAJOR_MULTIPLIER + minor * MINOR_MULTIPLIER + patch * PATCH_MULTIPLIER + build + test + end + + desc "Compute version name from version code" + private_lane :generateVersionName do |versionComponents| + suffix = "" + buildNumber = versionComponents["build"] + case + when buildNumber >= BUILD_NUMBER_RC_START && buildNumber < BUILD_NUMBER_FINAL_START + rcNumber = (buildNumber - BUILD_NUMBER_RC_START) + 1 + suffix = " RC #{rcNumber}" + when buildNumber < BUILD_NUMBER_RC_START + suffix = " Alpha #{buildNumber + 1}" + end + "#{versionComponents["major"]}.#{versionComponents["minor"]}.#{versionComponents["patch"]}#{suffix}" + end + + desc "Read versions from gradle file" + private_lane :getVersionInfo do + File.open("../app/build.gradle","r") do |file| + text = file.read + versionName = text.match(/versionName "(.*)"$/)[1] + versionCode = text.match(/versionCode ([0-9]*)$/)[1].to_i + + { "versionCode" => versionCode, "versionName" => versionName } + end + end + + desc "Write versions to gradle file" + private_lane :writeVersions do |options| + File.open("../app/build.gradle","r+") do |file| + text = file.read + text.gsub!(/versionName "(.*)"$/, "versionName \"#{options[:versionName]}\"") + text.gsub!(/versionCode ([0-9]*)$/, "versionCode #{options[:versionCode]}") + file.rewind + file.write(text) + file.truncate(file.pos) + end + end + + private_lane :incrementVersionComponents do |options| + versionComponents = options[:versionComponents] + case options[:type] + when "major" + versionComponents["major"] = versionComponents["major"] + 1 + versionComponents["minor"] = 0 + versionComponents["patch"] = 0 + versionComponents["build"] = 0 + when "minor" + versionComponents["minor"] = versionComponents["minor"] + 1 + versionComponents["patch"] = 0 + versionComponents["build"] = 0 + when "patch" + versionComponents["patch"] = versionComponents["patch"] + 1 + versionComponents["build"] = 0 + when "rc" + if versionComponents["build"] < BUILD_NUMBER_RC_START || versionComponents["build"] >= BUILD_NUMBER_FINAL_START + versionComponents["build"] = BUILD_NUMBER_RC_START + else + versionComponents["build"] = versionComponents["build"] + 1 + end + when "final" + if versionComponents["build"] < BUILD_NUMBER_FINAL_START + versionComponents["build"] = BUILD_NUMBER_FINAL_START + else + versionComponents["build"] = versionComponents["build"] + 1 + end + else + print "Unknown or missing version type: #{options[:type]}\n" + exit + end + versionComponents + end + + private_lane :promptYesNo do + answer = prompt(text: "is this okay?", boolean: true) + if !answer + exit + end + end +end -- GitLab From 0825988be345e04ed7926ee74fab1b0406ae9e65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Brey?= Date: Fri, 3 Feb 2023 11:54:43 +0100 Subject: [PATCH 041/163] fastlane: Add utilities to increment version numbers and allow uploading RCs to beta MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Álvaro Brey --- fastlane/Fastfile | 52 ++++++----- fastlane/{utils.Fastfile => common.Fastfile} | 93 ++++++++++++++++---- 2 files changed, 107 insertions(+), 38 deletions(-) rename fastlane/{utils.Fastfile => common.Fastfile} (61%) diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 10f141c7a..926e88511 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -28,21 +28,37 @@ default_platform(:android) BUNDLE_PATH = "app/build/outputs/bundle/playRelease/app-play-release.aab" -import("./utils.Fastfile") +import("./common.Fastfile") platform :android do desc "Build app bundle" + desc "Run tests and build app" lane :releasePhase1 do test() buildBundle() end + desc "Release previously built app to Google Play and create tag" + lane :releasePhase2 do + versionInfo = getVersionInfo() + versionComponents = parseVersionCode(versionInfo) + checkReleasable(versionComponents) + storeTrack = getPlayStoreTrack(versionComponents) + tagName = getTagName(versionComponents) + preReleaseChecks(versionInfo: versionInfo, tagName: tagName, type: versionComponents["type"], track: storeTrack) + checkArtifactsExist() + tag(tagName) + uploadToPlayStore() + end + + desc "Run tests" lane :test do gradle(task: "clean testPlayReleaseUnitTest testFdroidReleaseUnitTest") end - lane :buildBundle do + desc "Build app bundle" + lane :buildBundle do gradle( task: 'bundle', flavor: 'play', @@ -57,29 +73,24 @@ desc "Build app bundle" ) end - lane :releasePhase2 do - versionInfo = getVersionInfo() - promptVersion(versionInfo) - checkArtifactsExist() - tag(versionInfo) - uploadToPlayStore() - end - desc "Show versions and prompt for confirmation" - private_lane :promptVersion do |versionInfo| + private_lane :preReleaseChecks do |options| + versionInfo = options[:versionInfo] + tagName = options[:tagName] currentBranch = git_branch() - print "Version code: #{versionInfo["versionCode"]}\n" - print "Version name: #{versionInfo["versionName"]}\n" - print "Current branch: #{currentBranch}\n" - print "Tag (to be created): #{versionInfo["versionName"]}\n" - promptYesNo() + text = "Version code: #{versionInfo["versionCode"]}\n" + + "Version name: #{versionInfo["versionName"]}\n" + + "Current branch: #{currentBranch}\n" + + "Version type: #{options[:type]}\n" + + "Tag: #{tagName}\n" + + "Track: #{options[:track]}" + promptYesNo(text: text) end desc "Check if release artifacts exist" private_lane :checkArtifactsExist do if !File.exist?("../#{BUNDLE_PATH}") - print "Bundle not found at #{BUNDLE_PATH}\n" - exit + UI.user_error!("Bundle not found at #{BUNDLE_PATH}") end end @@ -95,11 +106,12 @@ desc "Build app bundle" end desc "Upload release artifacts to Google Play" - private_lane :uploadToPlayStore do + private_lane :uploadToPlayStore do |options| upload_to_play_store( skip_upload_images: true, skip_upload_apk: true, - aab: BUNDLE_PATH, + track: options[:track], + aab: BUNDLE_PATH ) end diff --git a/fastlane/utils.Fastfile b/fastlane/common.Fastfile similarity index 61% rename from fastlane/utils.Fastfile rename to fastlane/common.Fastfile index 1eb2ad9e8..742e0b2e1 100644 --- a/fastlane/utils.Fastfile +++ b/fastlane/common.Fastfile @@ -5,6 +5,10 @@ MAJOR_MULTIPLIER = 10000000 MINOR_MULTIPLIER = 10000 PATCH_MULTIPLIER = 100 +TYPE_ALPHA = "alpha" +TYPE_RC = "rc" +TYPE_FINAL = "final" + platform :android do desc "Print version info" lane :printVersionInfo do @@ -18,7 +22,7 @@ platform :android do print "Build: #{versionComponents["build"]}\n" end - # Usage: fastlane incrementVersion [type:major|minor|patch|rc|final] + # Usage: fastlane incrementVersion type:(major|minor|patch|rc|final) # For major, minor, and patch: will increment that version number by 1 and set the smaller ones to 0 # For rc, final: will set build number to first rc/first final or increment it by 1 desc "Increment version code and version name" @@ -29,9 +33,9 @@ platform :android do versionNameGenerated = generateVersionName(newVersionComponents) versionCodeGenerated = generateVersionCode(newVersionComponents) - print "Version code: #{versionInfo["versionCode"]} -> #{versionCodeGenerated}\n" - print "Version name: #{versionInfo["versionName"]} -> #{versionNameGenerated}\n" - promptYesNo() + promptYesNo(text: "Version code: #{versionInfo["versionCode"]} -> #{versionCodeGenerated}\n" + + "Version name: #{versionInfo["versionName"]} -> #{versionNameGenerated}" + ) writeVersions(versionCode: versionCodeGenerated, versionName: versionNameGenerated) end @@ -44,12 +48,30 @@ platform :android do minor = (versionCode / MINOR_MULTIPLIER) % 100 major = (versionCode / MAJOR_MULTIPLIER) % 100 - { "major" => major, "minor" => minor, "patch" => patch, "build" => build } + type = getVersionType(build: build) + + + { "major" => major, "minor" => minor, "patch" => patch, "build" => build, "type" => type } end + desc "Get version type from build number" + private_lane :getVersionType do |options| + build = options[:build] + if build < BUILD_NUMBER_RC_START + type = TYPE_ALPHA + elsif build < BUILD_NUMBER_FINAL_START + type = TYPE_RC + else + type = TYPE_FINAL + end + type + end + + + desc "Generate versionCode from version components" private_lane :generateVersionCode do |versionComponents| - print "Generating version code from #{versionComponents}\n" + puts "Generating version code from #{versionComponents}" major = versionComponents["major"] minor = versionComponents["minor"] patch = versionComponents["patch"] @@ -62,12 +84,13 @@ platform :android do private_lane :generateVersionName do |versionComponents| suffix = "" buildNumber = versionComponents["build"] + puts "Generating version name from #{versionComponents}\n" case - when buildNumber >= BUILD_NUMBER_RC_START && buildNumber < BUILD_NUMBER_FINAL_START + when versionComponents["type"] == TYPE_RC rcNumber = (buildNumber - BUILD_NUMBER_RC_START) + 1 - suffix = " RC #{rcNumber}" - when buildNumber < BUILD_NUMBER_RC_START - suffix = " Alpha #{buildNumber + 1}" + suffix = " RC#{rcNumber}" + when versionComponents["type"] == TYPE_ALPHA + suffix = " Alpha#{buildNumber + 1}" end "#{versionComponents["major"]}.#{versionComponents["minor"]}.#{versionComponents["patch"]}#{suffix}" end @@ -111,28 +134,62 @@ platform :android do versionComponents["patch"] = versionComponents["patch"] + 1 versionComponents["build"] = 0 when "rc" - if versionComponents["build"] < BUILD_NUMBER_RC_START || versionComponents["build"] >= BUILD_NUMBER_FINAL_START + if versionComponents["type"] != TYPE_RC versionComponents["build"] = BUILD_NUMBER_RC_START else versionComponents["build"] = versionComponents["build"] + 1 end when "final" - if versionComponents["build"] < BUILD_NUMBER_FINAL_START + if versionComponents["type"] != TYPE_FINAL versionComponents["build"] = BUILD_NUMBER_FINAL_START else versionComponents["build"] = versionComponents["build"] + 1 end else - print "Unknown or missing version type: #{options[:type]}\n" - exit + UI.user_error!("Unknown or missing version increment type #{options[:type]}. Usage: incrementVersion type:(major|minor|patch|rc|final)") end + versionComponents["type"] = getVersionType(build: versionComponents["build"]) versionComponents end - private_lane :promptYesNo do - answer = prompt(text: "is this okay?", boolean: true) - if !answer - exit + desc "Get tag name from version components" + private_lane :getTagName do |versionComponents| + if versionComponents["type"] == TYPE_FINAL + tag = "#{versionComponents["major"]}.#{versionComponents["minor"]}.#{versionComponents["patch"]}" + elsif versionComponents["type"] == TYPE_RC + rcNumber = (versionComponents["build"] - BUILD_NUMBER_RC_START) + 1 + rcNumberPadded = "%02d" % rcNumber + tag = "rc-#{versionComponents["major"]}.#{versionComponents["minor"]}.#{versionComponents["patch"]}-#{rcNumberPadded}" + else + UI.user_error!("Build number cannot be tagged: #{versionComponents["build"]}") end end + + desc "Check if version is releasable" + private_lane :checkReleasable do |versionComponents| + if versionComponents["type"] != TYPE_FINAL && versionComponents["type"] != TYPE_RC + UI.user_error!("Version is not releasable: #{versionComponents["type"]}") + end + end + + desc "Get play store track from version type" + private_lane :getPlayStoreTrack do |versionComponents| + case versionComponents["type"] + when TYPE_RC + track = "beta" + when TYPE_FINAL + track = "production" + else + UI.user_error!("Version is not releasable: #{versionComponents["type"]}") + end + end + +end + +private_lane :promptYesNo do |options| + puts "\n" + options[:text] + answer = prompt(text: "is this okay?", boolean: true) + if !answer + UI.user_error!("Aborting") + end end -- GitLab From 94e2459de856493ce61bb5aba1a87334862204d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Brey?= Date: Fri, 3 Feb 2023 13:36:04 +0100 Subject: [PATCH 042/163] Appfile: remove unneeded comments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Álvaro Brey --- fastlane/Appfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fastlane/Appfile b/fastlane/Appfile index 9d87857c8..9b2637fa2 100644 --- a/fastlane/Appfile +++ b/fastlane/Appfile @@ -1,2 +1,2 @@ -json_key_file("~/.gradle/Google Play Android Developer-Fastlane.json") # Path to the json secret file - Follow https://docs.fastlane.tools/actions/supply/#setup to get one -package_name("it.niedermann.owncloud.notes") # e.g. com.krausefx.app +json_key_file("~/.gradle/Google Play Android Developer-Fastlane.json") +package_name("it.niedermann.owncloud.notes") -- GitLab From 6bef883ef63ba997fee658d42a5dc1e4164fe5fc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Feb 2023 02:41:52 +0000 Subject: [PATCH 043/163] Bump com.android.tools:desugar_jdk_libs from 2.0.1 to 2.0.2 Bumps [com.android.tools:desugar_jdk_libs](https://github.com/google/desugar_jdk_libs) from 2.0.1 to 2.0.2. - [Release notes](https://github.com/google/desugar_jdk_libs/releases) - [Changelog](https://github.com/google/desugar_jdk_libs/blob/master/CHANGELOG.md) - [Commits](https://github.com/google/desugar_jdk_libs/commits) --- updated-dependencies: - dependency-name: com.android.tools:desugar_jdk_libs dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 980010b18..bc442a89f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -73,7 +73,7 @@ ext { } dependencies { - coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.1' + coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.2' // Nextcloud SSO implementation 'com.github.nextcloud:Android-SingleSignOn:0.6.1' -- GitLab From 250df96cdf3478b0d463e2bbed25f3eff83012a0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Feb 2023 13:19:03 +0000 Subject: [PATCH 044/163] Bump peter-evans/create-or-update-comment from 2.1.0 to 2.1.1 Bumps [peter-evans/create-or-update-comment](https://github.com/peter-evans/create-or-update-comment) from 2.1.0 to 2.1.1. - [Release notes](https://github.com/peter-evans/create-or-update-comment/releases) - [Commits](https://github.com/peter-evans/create-or-update-comment/compare/5adcb0bb0f9fb3f95ef05400558bdb3f329ee808...67dcc547d311b736a8e6c5c236542148a47adc3d) --- updated-dependencies: - dependency-name: peter-evans/create-or-update-comment dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/command-rebase.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/command-rebase.yml b/.github/workflows/command-rebase.yml index 13f7f31a6..8529e4bae 100644 --- a/.github/workflows/command-rebase.yml +++ b/.github/workflows/command-rebase.yml @@ -23,7 +23,7 @@ jobs: steps: - name: Add reaction on start - uses: peter-evans/create-or-update-comment@5adcb0bb0f9fb3f95ef05400558bdb3f329ee808 # v2.1.0 + uses: peter-evans/create-or-update-comment@67dcc547d311b736a8e6c5c236542148a47adc3d # v2.1.1 with: token: ${{ secrets.COMMAND_BOT_PAT }} repository: ${{ github.event.repository.full_name }} @@ -42,7 +42,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.COMMAND_BOT_PAT }} - name: Add reaction on failure - uses: peter-evans/create-or-update-comment@5adcb0bb0f9fb3f95ef05400558bdb3f329ee808 # v2.1.0 + uses: peter-evans/create-or-update-comment@67dcc547d311b736a8e6c5c236542148a47adc3d # v2.1.1 if: failure() with: token: ${{ secrets.COMMAND_BOT_PAT }} -- GitLab From fedf1a0395cb85b4c5eeb0086f953114045edb01 Mon Sep 17 00:00:00 2001 From: Niedermann IT-Dienstleistungen Date: Tue, 7 Feb 2023 21:54:50 +0100 Subject: [PATCH 045/163] Fix branchname in FAQ links Links im the FAQ should contain `main` instead of `master` Signed-off-by: Niedermann IT-Dienstleistungen --- FAQ.md | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/FAQ.md b/FAQ.md index 610220868..df910738d 100644 --- a/FAQ.md +++ b/FAQ.md @@ -1,19 +1,19 @@ # Frequently asked questions -- [Why aren't there any buttons to apply formatting?](https://github.com/nextcloud/notes-android/blob/master/FAQ.md#why-arent-there-any-buttons-to-apply-formatting) -- [I have experienced an error](https://github.com/nextcloud/notes-android/blob/master/FAQ.md#i-have-experienced-an-error) - - [`NextcloudApiNotRespondingException`](https://github.com/nextcloud/notes-android/blob/master/FAQ.md#nextcloudapinotrespondingexception) - - [`UnknownErrorException: Read timed out`](https://github.com/nextcloud/notes-android/blob/master/FAQ.md#unknownerrorexception-read-timed-out) - - [`NextcloudHttpRequestFailedException`](https://github.com/nextcloud/notes-android/blob/master/FAQ.md#nextcloudhttprequestfailedexception) - - [`IllegalStateException: Duplicate key`](https://github.com/nextcloud/notes-android/blob/master/FAQ.md#illegalstateexception-duplicate-key) - - [`NextcloudFilesAppAccountNotFoundException`](https://github.com/nextcloud/notes-android/blob/master/FAQ.md#nextcloudfilesappaccountnotfoundexception) - - [`TokenMismatchException`](https://github.com/nextcloud/notes-android/blob/master/FAQ.md#tokenmismatchexception) - - [Workarounds](https://github.com/nextcloud/notes-android/blob/master/FAQ.md#workarounds) -- [How to share notes?](https://github.com/nextcloud/notes-android/blob/master/FAQ.md#how-to-share-notes) -- [Why don't you make an option for…?](https://github.com/nextcloud/notes-android/blob/master/FAQ.md#why-dont-you-make-an-option-for) -- [Why is there no support for pens?](https://github.com/nextcloud/notes-android/blob/master/FAQ.md#why-is-there-no-support-for-pens) -- [Why has my bug report been closed?](https://github.com/nextcloud/notes-android/blob/master/FAQ.md#why-has-my-bug-report-been-closed) -- [How can i activate the dark mode for widgets?](https://github.com/nextcloud/notes-android/blob/master/FAQ.md#how-can-i-activate-the-dark-mode-for-widgets) +- [Why aren't there any buttons to apply formatting?](https://github.com/nextcloud/notes-android/blob/main/FAQ.md#why-arent-there-any-buttons-to-apply-formatting) +- [I have experienced an error](https://github.com/nextcloud/notes-android/blob/main/FAQ.md#i-have-experienced-an-error) + - [`NextcloudApiNotRespondingException`](https://github.com/nextcloud/notes-android/blob/main/FAQ.md#nextcloudapinotrespondingexception) + - [`UnknownErrorException: Read timed out`](https://github.com/nextcloud/notes-android/blob/main/FAQ.md#unknownerrorexception-read-timed-out) + - [`NextcloudHttpRequestFailedException`](https://github.com/nextcloud/notes-android/blob/main/FAQ.md#nextcloudhttprequestfailedexception) + - [`IllegalStateException: Duplicate key`](https://github.com/nextcloud/notes-android/blob/main/FAQ.md#illegalstateexception-duplicate-key) + - [`NextcloudFilesAppAccountNotFoundException`](https://github.com/nextcloud/notes-android/blob/main/FAQ.md#nextcloudfilesappaccountnotfoundexception) + - [`TokenMismatchException`](https://github.com/nextcloud/notes-android/blob/main/FAQ.md#tokenmismatchexception) + - [Workarounds](https://github.com/nextcloud/notes-android/blob/main/FAQ.md#workarounds) +- [How to share notes?](https://github.com/nextcloud/notes-android/blob/main/FAQ.md#how-to-share-notes) +- [Why don't you make an option for…?](https://github.com/nextcloud/notes-android/blob/main/FAQ.md#why-dont-you-make-an-option-for) +- [Why is there no support for pens?](https://github.com/nextcloud/notes-android/blob/main/FAQ.md#why-is-there-no-support-for-pens) +- [Why has my bug report been closed?](https://github.com/nextcloud/notes-android/blob/main/FAQ.md#why-has-my-bug-report-been-closed) +- [How can i activate the dark mode for widgets?](https://github.com/nextcloud/notes-android/blob/main/FAQ.md#how-can-i-activate-the-dark-mode-for-widgets) ## Why aren't there any buttons to apply formatting -- GitLab From 2b26bec123a4a72191ae6fe29f23b61bd970c829 Mon Sep 17 00:00:00 2001 From: tobiasKaminsky Date: Wed, 8 Feb 2023 08:49:44 +0100 Subject: [PATCH 046/163] part 2 --- .github/ISSUE_TEMPLATE/bug_report.md | 2 +- FAQ.md | 6 +++--- app/src/main/res/values/strings.xml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 49078cc83..042b6066e 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -8,7 +8,7 @@ labels: bug Guidelines for submitting issues: * Bug reports which do not fill the complete issue template will be closed. -* Please have a look at our [FAQ](https://github.com/nextcloud/notes-android/blob/master/FAQ.md) +* Please have a look at our [FAQ](https://github.com/nextcloud/notes-android/blob/main/FAQ.md) * Please search the existing issues first, it's likely that your issue was already reported or even fixed. * This repository is *only* for issues within the Nextcloud Notes Android app --> diff --git a/FAQ.md b/FAQ.md index df910738d..0ddbb7bbd 100644 --- a/FAQ.md +++ b/FAQ.md @@ -59,7 +59,7 @@ If you are using an older version, you can as a workaround for the first import #### `HTTP status-code: 301` -This issue can happen in case of a complex inconsistent state between the Notes Android app, the Single Sign On library, the Nextcloud Android app and your Nextcloud instance. Please try to remove your account from *both*, Notes Android *and* Nextcloud Android and readd it again [as described in the `workarounds` section](https://github.com/nextcloud/notes-android/blob/master/FAQ.md#workarounds). If the issue persists, please report especially any changes on your server side environment: Did you change your domain or IP address of your Nextcloud server? Did you change something about your user account or en- / disabled multi factor authentication (2FA / MFA)? Did you remove your account (only) from the Nextcloud Android app? +This issue can happen in case of a complex inconsistent state between the Notes Android app, the Single Sign On library, the Nextcloud Android app and your Nextcloud instance. Please try to remove your account from *both*, Notes Android *and* Nextcloud Android and readd it again [as described in the `workarounds` section](https://github.com/nextcloud/notes-android/blob/main/FAQ.md#workarounds). If the issue persists, please report especially any changes on your server side environment: Did you change your domain or IP address of your Nextcloud server? Did you change something about your user account or en- / disabled multi factor authentication (2FA / MFA)? Did you remove your account (only) from the Nextcloud Android app? #### `HTTP status-code: 302` @@ -72,7 +72,7 @@ Only the [`Notes`](https://apps.nextcloud.com/apps/notes) app is supported by th ### `IllegalStateException: Duplicate key` -This is issue was caused by a bug which was present in the Notes Android app between `3.4.0` and `3.4.10`. It has been fixed in `3.4.11`, though it created a corrupt database state which is not recoverable automatically without data loss. It is therefore required to [clear the storage of the Notes Android app](https://github.com/nextcloud/notes-android/blob/master/FAQ.md#workarounds) and import your account again from scratch. Make sure to backup unsynchronized changes before doing this. +This is issue was caused by a bug which was present in the Notes Android app between `3.4.0` and `3.4.10`. It has been fixed in `3.4.11`, though it created a corrupt database state which is not recoverable automatically without data loss. It is therefore required to [clear the storage of the Notes Android app](https://github.com/nextcloud/notes-android/blob/main/FAQ.md#workarounds) and import your account again from scratch. Make sure to backup unsynchronized changes before doing this. ### `NextcloudFilesAppAccountNotFoundException` @@ -81,7 +81,7 @@ As a workaround you can remove the account (or clear the storage of the app as d ### `TokenMismatchException` -The reason of this error is not yet clear. It often seems to be connected to changes of the authentication (for example enabling 2FA after some time). Please clear the storage of both, the Notes and the Nextcloud Android apps as described in the [workarounds](https://github.com/nextcloud/notes-android/blob/master/FAQ.md#wrokarounds) section. +The reason of this error is not yet clear. It often seems to be connected to changes of the authentication (for example enabling 2FA after some time). Please clear the storage of both, the Notes and the Nextcloud Android apps as described in the [workarounds](https://github.com/nextcloud/notes-android/blob/main/FAQ.md#wrokarounds) section. ### Workarounds diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 41e7e9fcf..4458476d7 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -61,7 +61,7 @@ https://github.com/nextcloud/notes-android https://github.com/nextcloud/notes-android/issues/new/choose - https://github.com/nextcloud/notes-android/blob/master/LICENSE + https://github.com/nextcloud/notes-android/blob/main/LICENSE https://www.transifex.com/nextcloud/nextcloud/ https://www.niedermann.it/ https://github.com/nextcloud/notes/blob/76d15214f80f2bf7ea08427bff73ad145128f090/img/notes.svg -- GitLab From 43f6c11f409f10debd7b545e962c9c4ea3b2418c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 9 Feb 2023 02:08:52 +0000 Subject: [PATCH 047/163] Bump androidx.work:work-runtime from 2.7.1 to 2.8.0 Bumps androidx.work:work-runtime from 2.7.1 to 2.8.0. --- updated-dependencies: - dependency-name: androidx.work:work-runtime dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index bc442a89f..b378ee0ac 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -98,7 +98,7 @@ dependencies { implementation 'androidx.recyclerview:recyclerview-selection:1.1.0' implementation 'androidx.recyclerview:recyclerview:1.2.1' implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0' - implementation 'androidx.work:work-runtime:2.7.1' + implementation 'androidx.work:work-runtime:2.8.0' implementation 'com.google.android.material:material:1.8.0' // Database -- GitLab From 6a5c8190fed798d2f64075e896eafcf61103708e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 9 Feb 2023 02:09:02 +0000 Subject: [PATCH 048/163] Bump androidx.appcompat:appcompat from 1.6.0 to 1.6.1 Bumps androidx.appcompat:appcompat from 1.6.0 to 1.6.1. --- updated-dependencies: - dependency-name: androidx.appcompat:appcompat dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index bc442a89f..f00ed993f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -89,7 +89,7 @@ dependencies { annotationProcessor 'com.github.bumptech.glide:compiler:4.14.2' // Android X - implementation 'androidx.appcompat:appcompat:1.6.0' + implementation 'androidx.appcompat:appcompat:1.6.1' implementation 'androidx.core:core-ktx:1.9.0' implementation 'androidx.core:core-splashscreen:1.0.0' implementation 'androidx.fragment:fragment:1.5.5' -- GitLab From 590750802933ef3f67e891f192ba4aa1d5798a0f Mon Sep 17 00:00:00 2001 From: nextcloud-android-bot Date: Fri, 10 Feb 2023 03:11:54 +0000 Subject: [PATCH 049/163] =?UTF-8?q?=F0=9F=94=84=20synced=20local=20'.githu?= =?UTF-8?q?b/workflows/'=20with=20remote=20'config/workflows/'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: nextcloud-android-bot --- .github/workflows/autoApproveDependabot.yml | 30 +++++++++++++++++++++ .github/workflows/autoApproveSync.yml | 14 ++++++++-- 2 files changed, 42 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/autoApproveDependabot.yml diff --git a/.github/workflows/autoApproveDependabot.yml b/.github/workflows/autoApproveDependabot.yml new file mode 100644 index 000000000..4d65e886a --- /dev/null +++ b/.github/workflows/autoApproveDependabot.yml @@ -0,0 +1,30 @@ +# synced from @nextcloud/android-config +name: Auto approve dependabot + +on: + pull_request_target: + branches: + - main + - master + - stable-* + +permissions: + contents: read + +concurrency: + group: dependabot-approve-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + auto-approve: + name: Auto approve dependabot + runs-on: ubuntu-latest + if: github.actor == 'dependabot[bot]' + permissions: + # needed to approve the PR + pull-requests: write + + steps: + - uses: hmarr/auto-approve-action@de8ae18c173c131e182d4adf2c874d8d2308a85b # v3.1.0 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/autoApproveSync.yml b/.github/workflows/autoApproveSync.yml index 707ef9b80..aa7279581 100644 --- a/.github/workflows/autoApproveSync.yml +++ b/.github/workflows/autoApproveSync.yml @@ -1,19 +1,29 @@ # synced from @nextcloud/android-config -name: Auto approve +name: Auto approve sync on: pull_request_target: branches: - master - main + types: + - opened + - reopened + - synchronize + - labeled + +concurrency: + group: sync-approve-${{ github.head_ref || github.run_id }} + cancel-in-progress: true permissions: pull-requests: write jobs: auto-approve: + name: Auto approve sync runs-on: ubuntu-latest + if: ${{ contains(github.event.pull_request.labels.*.name, 'sync') && github.actor == 'nextcloud-android-bot' }} steps: - uses: hmarr/auto-approve-action@de8ae18c173c131e182d4adf2c874d8d2308a85b # v3.1.0 - if: ${{ contains(github.event.pull_request.labels.*.name, 'sync') && github.actor == 'nextcloud-android-bot' }} with: github-token: "${{ secrets.GITHUB_TOKEN }}" -- GitLab From c9f50bf4ec06c5682f877adfc2853024d619d30b Mon Sep 17 00:00:00 2001 From: Stefan Niedermann Date: Sun, 12 Feb 2023 11:41:02 +0100 Subject: [PATCH 050/163] feat(theming): Use nextcloud-common library for theming UI elements Signed-off-by: Stefan Niedermann --- app/build.gradle | 1 + .../notes/FormattingHelpActivity.java | 4 +- .../owncloud/notes/NotesApplication.java | 5 +- .../owncloud/notes/about/AboutActivity.java | 6 +- .../notes/about/AboutFragmentLicenseTab.java | 5 +- .../AccountSwitcherDialog.java | 6 +- .../notes/branding/BrandedActivity.java | 41 +---- .../notes/branding/BrandedFragment.java | 10 +- .../branding/BrandedPreferenceCategory.java | 10 +- .../notes/branding/BrandedSnackbar.java | 21 +-- .../branding/BrandedSwitchPreference.java | 19 +-- .../owncloud/notes/branding/BrandingUtil.java | 146 +++++------------- .../notes/branding/NotesViewThemeUtils.java | 100 ++++++++++++ .../owncloud/notes/edit/BaseNoteFragment.java | 12 +- .../owncloud/notes/edit/EditNoteActivity.java | 4 +- .../owncloud/notes/edit/NoteEditFragment.java | 6 +- .../notes/edit/NotePreviewFragment.java | 6 +- .../edit/SearchableBaseNoteFragment.java | 7 +- .../edit/category/CategoryDialogFragment.java | 3 +- .../edit/title/EditTitleDialogFragment.java | 6 +- .../owncloud/notes/main/MainActivity.java | 10 +- .../notes/main/items/NoteViewHolder.java | 15 +- .../main/navigation/NavigationAdapter.java | 12 +- .../ManageAccountViewHolder.java | 5 +- .../ManageAccountsActivity.java | 10 +- .../preferences/PreferencesActivity.java | 4 +- 26 files changed, 227 insertions(+), 247 deletions(-) create mode 100644 app/src/main/java/it/niedermann/owncloud/notes/branding/NotesViewThemeUtils.java diff --git a/app/build.gradle b/app/build.gradle index 53f6b8b23..9bc16ed2d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -76,6 +76,7 @@ dependencies { coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.2' // Nextcloud SSO + implementation 'com.github.nextcloud:android-common:0.4.0' implementation 'com.github.nextcloud:Android-SingleSignOn:0.6.1' implementation 'com.github.stefan-niedermann:android-commons:0.2.9' implementation 'com.github.stefan-niedermann.nextcloud-commons:sso-glide:1.6.4' diff --git a/app/src/main/java/it/niedermann/owncloud/notes/FormattingHelpActivity.java b/app/src/main/java/it/niedermann/owncloud/notes/FormattingHelpActivity.java index 91ef3724a..f4e8d788f 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/FormattingHelpActivity.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/FormattingHelpActivity.java @@ -12,6 +12,7 @@ import androidx.preference.PreferenceManager; import it.niedermann.owncloud.notes.R; import it.niedermann.owncloud.notes.branding.BrandedActivity; +import it.niedermann.owncloud.notes.branding.BrandingUtil; import it.niedermann.owncloud.notes.databinding.ActivityFormattingHelpBinding; import static it.niedermann.owncloud.notes.shared.util.NoteUtil.getFontSizeFromPreferences; @@ -223,6 +224,7 @@ public class FormattingHelpActivity extends BrandedActivity { @Override public void applyBrand(int mainColor, int textColor) { - applyBrandToPrimaryToolbar(binding.appBar, binding.toolbar); + final var util = BrandingUtil.of(mainColor, this); + util.notes.applyBrandToPrimaryToolbar(binding.appBar, binding.toolbar, colorAccent); } } diff --git a/app/src/main/java/it/niedermann/owncloud/notes/NotesApplication.java b/app/src/main/java/it/niedermann/owncloud/notes/NotesApplication.java index e177f7c7c..5c98201ec 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/NotesApplication.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/NotesApplication.java @@ -13,6 +13,8 @@ import it.niedermann.owncloud.notes.preferences.DarkModeSetting; import static androidx.preference.PreferenceManager.getDefaultSharedPreferences; +import com.nextcloud.android.common.ui.util.PlatformThemeUtil; + public class NotesApplication extends Application { private static final String TAG = NotesApplication.class.getSimpleName(); @@ -66,8 +68,7 @@ public class NotesApplication extends Application { } public static boolean isDarkThemeActive(Context context) { - final int uiMode = context.getResources().getConfiguration().uiMode; - return (uiMode & Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES; + return PlatformThemeUtil.isDarkMode(context); } public static void setLockedPreference(boolean lockedPreference) { diff --git a/app/src/main/java/it/niedermann/owncloud/notes/about/AboutActivity.java b/app/src/main/java/it/niedermann/owncloud/notes/about/AboutActivity.java index 5c5bf519f..2c187af65 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/about/AboutActivity.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/about/AboutActivity.java @@ -51,9 +51,9 @@ public class AboutActivity extends LockedActivity { @Override public void applyBrand(int mainColor, int textColor) { - applyBrandToPrimaryToolbar(binding.appBar, binding.toolbar); - @ColorInt int finalMainColor = BrandingUtil.getSecondaryForegroundColorDependingOnTheme(this, mainColor); - binding.tabs.setSelectedTabIndicatorColor(finalMainColor); + final var util = BrandingUtil.of(mainColor, this); + util.material.themeTabLayout(binding.tabs); + util.notes.applyBrandToPrimaryToolbar(binding.appBar, binding.toolbar, colorAccent); } private static class TabsStateAdapter extends FragmentStateAdapter { diff --git a/app/src/main/java/it/niedermann/owncloud/notes/about/AboutFragmentLicenseTab.java b/app/src/main/java/it/niedermann/owncloud/notes/about/AboutFragmentLicenseTab.java index 10cc02c74..173d36617 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/about/AboutFragmentLicenseTab.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/about/AboutFragmentLicenseTab.java @@ -35,8 +35,7 @@ public class AboutFragmentLicenseTab extends BrandedFragment { @Override public void applyBrand(int mainColor, int textColor) { - @ColorInt final int finalMainColor = BrandingUtil.getSecondaryForegroundColorDependingOnTheme(requireContext(), mainColor); - DrawableCompat.setTintList(binding.aboutAppLicenseButton.getBackground(), ColorStateList.valueOf(finalMainColor)); - binding.aboutAppLicenseButton.setTextColor(ColorUtil.INSTANCE.getForegroundColorForBackgroundColor(finalMainColor)); + final var util = BrandingUtil.of(mainColor, requireContext()); + util.material.colorMaterialButtonPrimaryFilled(binding.aboutAppLicenseButton); } } \ No newline at end of file diff --git a/app/src/main/java/it/niedermann/owncloud/notes/accountswitcher/AccountSwitcherDialog.java b/app/src/main/java/it/niedermann/owncloud/notes/accountswitcher/AccountSwitcherDialog.java index 7d088afea..56f37773b 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/accountswitcher/AccountSwitcherDialog.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/accountswitcher/AccountSwitcherDialog.java @@ -1,7 +1,5 @@ package it.niedermann.owncloud.notes.accountswitcher; -import static it.niedermann.owncloud.notes.branding.BrandingUtil.applyBrandToLayerDrawable; - import android.app.Dialog; import android.content.Context; import android.content.Intent; @@ -18,6 +16,7 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder; import it.niedermann.owncloud.notes.R; import it.niedermann.owncloud.notes.branding.BrandedDialogFragment; +import it.niedermann.owncloud.notes.branding.BrandingUtil; import it.niedermann.owncloud.notes.databinding.DialogAccountSwitcherBinding; import it.niedermann.owncloud.notes.manageaccounts.ManageAccountsActivity; import it.niedermann.owncloud.notes.persistence.NotesRepository; @@ -118,6 +117,7 @@ public class AccountSwitcherDialog extends BrandedDialogFragment { @Override public void applyBrand(int mainColor, int textColor) { - applyBrandToLayerDrawable((LayerDrawable) binding.check.getDrawable(), R.id.area, mainColor); + final var util = BrandingUtil.of(mainColor, requireContext()); + util.notes.colorLayerDrawable((LayerDrawable) binding.check.getDrawable(), R.id.area, mainColor); } } diff --git a/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandedActivity.java b/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandedActivity.java index 0b96ca8d1..492a7dece 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandedActivity.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandedActivity.java @@ -1,35 +1,20 @@ package it.niedermann.owncloud.notes.branding; -import android.content.res.ColorStateList; -import android.graphics.PorterDuff; -import android.graphics.drawable.Drawable; +import static it.niedermann.owncloud.notes.branding.BrandingUtil.readBrandColors; + import android.util.TypedValue; import android.view.Menu; import androidx.annotation.ColorInt; -import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; -import androidx.appcompat.widget.Toolbar; -import androidx.core.content.ContextCompat; - -import com.google.android.material.appbar.AppBarLayout; -import com.google.android.material.floatingactionbutton.FloatingActionButton; import it.niedermann.owncloud.notes.R; -import static it.niedermann.owncloud.notes.branding.BrandingUtil.readBrandColors; -import static it.niedermann.owncloud.notes.branding.BrandingUtil.tintMenuIcon; - public abstract class BrandedActivity extends AppCompatActivity implements Branded { @ColorInt protected int colorAccent; - public static void applyBrandToFAB(@ColorInt int mainColor, @ColorInt int textColor, @NonNull FloatingActionButton fab) { - fab.setSupportBackgroundTintList(ColorStateList.valueOf(mainColor)); - fab.setColorFilter(textColor); - } - @Override protected void onStart() { super.onStart(); @@ -43,26 +28,12 @@ public abstract class BrandedActivity extends AppCompatActivity implements Brand @Override public boolean onCreateOptionsMenu(Menu menu) { - for (int i = 0; i < menu.size(); i++) { - tintMenuIcon(menu.getItem(i), colorAccent); - } - return super.onCreateOptionsMenu(menu); - } - - public void applyBrandToPrimaryToolbar(@NonNull AppBarLayout appBarLayout, @NonNull Toolbar toolbar) { - // FIXME Workaround for https://github.com/nextcloud/notes-android/issues/889 - appBarLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.primary)); + final var utils = BrandingUtil.of(colorAccent, this); - final var overflowDrawable = toolbar.getOverflowIcon(); - if (overflowDrawable != null) { - overflowDrawable.setColorFilter(colorAccent, PorterDuff.Mode.SRC_ATOP); - toolbar.setOverflowIcon(overflowDrawable); + for (int i = 0; i < menu.size(); i++) { + utils.platform.colorToolbarMenuIcon(this, menu.getItem(i)); } - final var navigationDrawable = toolbar.getNavigationIcon(); - if (navigationDrawable != null) { - navigationDrawable.setColorFilter(colorAccent, PorterDuff.Mode.SRC_ATOP); - toolbar.setNavigationIcon(navigationDrawable); - } + return super.onCreateOptionsMenu(menu); } } diff --git a/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandedFragment.java b/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandedFragment.java index 993ee3778..708815b38 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandedFragment.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandedFragment.java @@ -1,19 +1,15 @@ package it.niedermann.owncloud.notes.branding; -import android.content.Context; import android.util.TypedValue; import android.view.Menu; import android.view.MenuInflater; import androidx.annotation.ColorInt; import androidx.annotation.NonNull; -import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; import it.niedermann.owncloud.notes.R; -import static it.niedermann.owncloud.notes.branding.BrandingUtil.tintMenuIcon; - public abstract class BrandedFragment extends Fragment implements Branded { @ColorInt @@ -40,8 +36,12 @@ public abstract class BrandedFragment extends Fragment implements Branded { @Override public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { super.onCreateOptionsMenu(menu, inflater); + final var utils = BrandingUtil.of(colorAccent, requireContext()); + for (int i = 0; i < menu.size(); i++) { - tintMenuIcon(menu.getItem(i), colorAccent); + if (menu.getItem(i).getIcon() != null) { + utils.platform.colorToolbarMenuIcon(requireContext(), menu.getItem(i)); + } } } } diff --git a/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandedPreferenceCategory.java b/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandedPreferenceCategory.java index 620ec4b66..f922a071b 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandedPreferenceCategory.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandedPreferenceCategory.java @@ -2,16 +2,12 @@ package it.niedermann.owncloud.notes.branding; import android.content.Context; import android.util.AttributeSet; -import android.view.View; import android.widget.TextView; -import androidx.annotation.ColorInt; import androidx.annotation.Nullable; import androidx.preference.PreferenceCategory; import androidx.preference.PreferenceViewHolder; -import static it.niedermann.owncloud.notes.branding.BrandingUtil.getSecondaryForegroundColorDependingOnTheme; - public class BrandedPreferenceCategory extends PreferenceCategory { public BrandedPreferenceCategory(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { @@ -36,9 +32,9 @@ public class BrandedPreferenceCategory extends PreferenceCategory { final var view = holder.itemView.findViewById(android.R.id.title); @Nullable final var context = getContext(); - if (context != null && view instanceof TextView) { - @ColorInt final int mainColor = getSecondaryForegroundColorDependingOnTheme(context, BrandingUtil.readBrandMainColor(context)); - ((TextView) view).setTextColor(mainColor); + if (view instanceof TextView) { + final var util = BrandingUtil.of(BrandingUtil.readBrandMainColor(context), context);; + ((TextView) view).setTextColor(util.notes.getOnPrimaryContainer(context)); } } } diff --git a/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandedSnackbar.java b/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandedSnackbar.java index 1c0ebf11e..1789dc90a 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandedSnackbar.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandedSnackbar.java @@ -1,11 +1,7 @@ package it.niedermann.owncloud.notes.branding; -import static it.niedermann.owncloud.notes.NotesApplication.isDarkThemeActive; -import static it.niedermann.owncloud.notes.branding.BrandingUtil.getAttribute; import static it.niedermann.owncloud.notes.branding.BrandingUtil.readBrandMainColor; -import static it.niedermann.owncloud.notes.shared.util.NotesColorUtil.contrastRatioIsSufficient; -import android.graphics.Color; import android.view.View; import androidx.annotation.ColorInt; @@ -15,26 +11,15 @@ import androidx.annotation.StringRes; import com.google.android.material.snackbar.BaseTransientBottomBar; import com.google.android.material.snackbar.Snackbar; -import it.niedermann.owncloud.notes.R; - public class BrandedSnackbar { @NonNull public static Snackbar make(@NonNull View view, @NonNull CharSequence text, @BaseTransientBottomBar.Duration int duration) { - final var snackbar = Snackbar.make(view, text, duration); - - @ColorInt final int backgroundColor = getAttribute(view.getContext(), R.attr.colorSurfaceInverse); @ColorInt final int color = readBrandMainColor(view.getContext()); + final var snackbar = Snackbar.make(view, text, duration); + final var utils = BrandingUtil.of(color, view.getContext()); - if (contrastRatioIsSufficient(backgroundColor, color)) { - snackbar.setActionTextColor(color); - } else { - if (isDarkThemeActive(view.getContext())) { - snackbar.setActionTextColor(Color.BLACK); - } else { - snackbar.setActionTextColor(Color.WHITE); - } - } + utils.material.themeSnackbar(snackbar); return snackbar; } diff --git a/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandedSwitchPreference.java b/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandedSwitchPreference.java index 07eb0c63c..3fe0f0839 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandedSwitchPreference.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandedSwitchPreference.java @@ -2,8 +2,6 @@ package it.niedermann.owncloud.notes.branding; import android.annotation.SuppressLint; import android.content.Context; -import android.content.res.ColorStateList; -import android.graphics.Color; import android.util.AttributeSet; import android.view.View; import android.view.ViewGroup; @@ -11,14 +9,9 @@ import android.widget.Switch; import androidx.annotation.ColorInt; import androidx.annotation.Nullable; -import androidx.core.graphics.drawable.DrawableCompat; import androidx.preference.PreferenceViewHolder; import androidx.preference.SwitchPreference; -import it.niedermann.owncloud.notes.R; - -import static it.niedermann.owncloud.notes.branding.BrandingUtil.getSecondaryForegroundColorDependingOnTheme; - public class BrandedSwitchPreference extends SwitchPreference implements Branded { @ColorInt @@ -69,16 +62,8 @@ public class BrandedSwitchPreference extends SwitchPreference implements Branded private void applyBrand() { if (switchView != null) { - final int finalMainColor = getSecondaryForegroundColorDependingOnTheme(getContext(), mainColor); - // int trackColor = Color.argb(77, Color.red(finalMainColor), Color.green(finalMainColor), Color.blue(finalMainColor)); - DrawableCompat.setTintList(switchView.getThumbDrawable(), new ColorStateList( - new int[][]{new int[]{android.R.attr.state_checked}, new int[]{}}, - new int[]{finalMainColor, getContext().getResources().getColor(R.color.fg_default_low)} - )); - DrawableCompat.setTintList(switchView.getTrackDrawable(), new ColorStateList( - new int[][]{new int[]{android.R.attr.state_checked}, new int[]{}}, - new int[]{finalMainColor, getContext().getResources().getColor(R.color.fg_default_low)} - )); + final var util = BrandingUtil.of(mainColor, getContext()); + util.platform.colorSwitch(switchView); } } diff --git a/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandingUtil.java b/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandingUtil.java index ba79fa0e6..b797a9e29 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandingUtil.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandingUtil.java @@ -12,6 +12,7 @@ import android.util.Log; import android.util.TypedValue; import android.view.MenuItem; import android.widget.EditText; +import android.widget.TextView; import androidx.annotation.AttrRes; import androidx.annotation.ColorInt; @@ -26,21 +27,55 @@ import androidx.lifecycle.MediatorLiveData; import androidx.preference.PreferenceManager; import com.google.android.material.textfield.TextInputLayout; +import com.nextcloud.android.common.ui.theme.MaterialSchemes; +import com.nextcloud.android.common.ui.theme.ViewThemeUtilsBase; +import com.nextcloud.android.common.ui.theme.utils.AndroidViewThemeUtils; +import com.nextcloud.android.common.ui.theme.utils.AndroidXViewThemeUtils; +import com.nextcloud.android.common.ui.theme.utils.DialogViewThemeUtils; +import com.nextcloud.android.common.ui.theme.utils.MaterialViewThemeUtils; +import com.nextcloud.android.common.ui.util.PlatformThemeUtil; + +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; import it.niedermann.android.sharedpreferences.SharedPreferenceIntLiveData; import it.niedermann.android.util.ColorUtil; import it.niedermann.owncloud.notes.NotesApplication; import it.niedermann.owncloud.notes.R; import it.niedermann.owncloud.notes.shared.util.NotesColorUtil; +import scheme.Scheme; -public class BrandingUtil { +public class BrandingUtil extends ViewThemeUtilsBase { private static final String TAG = BrandingUtil.class.getSimpleName(); + private static final ConcurrentMap CACHE = new ConcurrentHashMap<>(); private static final String pref_key_branding_main = "branding_main"; private static final String pref_key_branding_text = "branding_text"; - private BrandingUtil() { + public final AndroidViewThemeUtils platform; + public final MaterialViewThemeUtils material; + public final AndroidXViewThemeUtils androidx; + public final DialogViewThemeUtils dialog; + public final NotesViewThemeUtils notes; + + private BrandingUtil( + final MaterialSchemes schemes, + final com.nextcloud.android.common.ui.color.ColorUtil colorUtil + ) { + super(schemes); + + this.platform = new AndroidViewThemeUtils(schemes, colorUtil); + this.material = new MaterialViewThemeUtils(schemes, colorUtil); + this.androidx = new AndroidXViewThemeUtils(schemes, this.platform); + this.dialog = new DialogViewThemeUtils(schemes); + this.notes = new NotesViewThemeUtils(schemes); + } + public static BrandingUtil of(@ColorInt int color, @NonNull Context context) { + return CACHE.computeIfAbsent(color, c -> new BrandingUtil( + MaterialSchemes.Companion.fromColor(c), + new com.nextcloud.android.common.ui.color.ColorUtil(context) + )); } public static LiveData> readBrandColors(@NonNull Context context) { @@ -111,111 +146,4 @@ public class BrandingUtil { } } } - - /** - * Since we may collide with dark theme in this area, we have to make sure that the color is visible depending on the background - */ - @ColorInt - public static int getSecondaryForegroundColorDependingOnTheme(@NonNull Context context, @ColorInt int mainColor) { - final int primaryColor = ContextCompat.getColor(context, R.color.primary); - final boolean isDarkTheme = NotesApplication.isDarkThemeActive(context); - if (isDarkTheme && !contrastRatioIsSufficient(mainColor, primaryColor)) { - Log.v(TAG, "Contrast ratio between brand color " + String.format("#%06X", (0xFFFFFF & mainColor)) + " and dark theme is too low. Falling back to WHITE as brand color."); - return Color.WHITE; - } else if (!isDarkTheme && !contrastRatioIsSufficient(mainColor, primaryColor)) { - Log.v(TAG, "Contrast ratio between brand color " + String.format("#%06X", (0xFFFFFF & mainColor)) + " and light theme is too low. Falling back to BLACK as brand color."); - return Color.BLACK; - } else { - return mainColor; - } - } - - public static void applyBrandToEditText(@ColorInt int mainColor, @ColorInt int textColor, @NonNull EditText editText) { - @ColorInt final int finalMainColor = getSecondaryForegroundColorDependingOnTheme(editText.getContext(), mainColor); - DrawableCompat.setTintList(editText.getBackground(), new ColorStateList( - new int[][]{ - new int[]{android.R.attr.state_active}, - new int[]{android.R.attr.state_activated}, - new int[]{android.R.attr.state_focused}, - new int[]{android.R.attr.state_pressed}, - new int[]{} - }, - new int[]{ - finalMainColor, - finalMainColor, - finalMainColor, - finalMainColor, - editText.getContext().getResources().getColor(R.color.fg_default_low) - } - )); - } - - public static void applyBrandToEditTextInputLayout(@ColorInt int color, @NonNull TextInputLayout til) { - final int colorPrimary = ContextCompat.getColor(til.getContext(), R.color.primary); - final int colorAccent = ContextCompat.getColor(til.getContext(), R.color.accent); - final var colorDanger = ColorStateList.valueOf(ContextCompat.getColor(til.getContext(), R.color.danger)); - til.setBoxStrokeColor(contrastRatioIsSufficientBigAreas(color, colorPrimary) ? color : colorAccent); - til.setHintTextColor(ColorStateList.valueOf(contrastRatioIsSufficient(color, colorPrimary) ? color : colorAccent)); - til.setErrorTextColor(colorDanger); - til.setBoxStrokeErrorColor(colorDanger); - til.setErrorIconTintList(colorDanger); - } - - public static void tintMenuIcon(@NonNull MenuItem menuItem, @ColorInt int color) { - var drawable = menuItem.getIcon(); - if (drawable != null) { - drawable = DrawableCompat.wrap(drawable); - DrawableCompat.setTint(drawable, color); - menuItem.setIcon(drawable); - } - } - - public static void applyBrandToLayerDrawable(@NonNull LayerDrawable check, @IdRes int areaToColor, @ColorInt int mainColor) { - final var drawable = check.findDrawableByLayerId(areaToColor); - if (drawable == null) { - Log.e(TAG, "Could not find areaToColor (" + areaToColor + "). Cannot apply brand."); - } else { - DrawableCompat.setTint(drawable, mainColor); - } - } - - @ColorInt - public static int getAttribute(@NonNull Context context, @AttrRes int id) { - final var typedValue = new TypedValue(); - context.getTheme().resolveAttribute(id, typedValue, true); - return typedValue.data; - } - - @ColorInt - public static int getTextHighlightBackgroundColor(@NonNull Context context, @ColorInt int mainColor, @ColorInt int colorPrimary, @ColorInt int colorAccent) { - if (isDarkThemeActive(context)) { // Dark background - if (ColorUtil.INSTANCE.isColorDark(mainColor)) { // Dark brand color - if (NotesColorUtil.contrastRatioIsSufficient(mainColor, colorPrimary)) { // But also dark text - return mainColor; - } else { - return ContextCompat.getColor(context, R.color.defaultTextHighlightBackground); - } - } else { // Light brand color - if (NotesColorUtil.contrastRatioIsSufficient(mainColor, colorAccent)) { // But also dark text - return Color.argb(77, Color.red(mainColor), Color.green(mainColor), Color.blue(mainColor)); - } else { - return ContextCompat.getColor(context, R.color.defaultTextHighlightBackground); - } - } - } else { // Light background - if (ColorUtil.INSTANCE.isColorDark(mainColor)) { // Dark brand color - if (NotesColorUtil.contrastRatioIsSufficient(mainColor, colorAccent)) { // But also dark text - return Color.argb(77, Color.red(mainColor), Color.green(mainColor), Color.blue(mainColor)); - } else { - return ContextCompat.getColor(context, R.color.defaultTextHighlightBackground); - } - } else { // Light brand color - if (NotesColorUtil.contrastRatioIsSufficient(mainColor, colorPrimary)) { // But also dark text - return mainColor; - } else { - return ContextCompat.getColor(context, R.color.defaultTextHighlightBackground); - } - } - } - } } diff --git a/app/src/main/java/it/niedermann/owncloud/notes/branding/NotesViewThemeUtils.java b/app/src/main/java/it/niedermann/owncloud/notes/branding/NotesViewThemeUtils.java new file mode 100644 index 000000000..78cf0df6f --- /dev/null +++ b/app/src/main/java/it/niedermann/owncloud/notes/branding/NotesViewThemeUtils.java @@ -0,0 +1,100 @@ +package it.niedermann.owncloud.notes.branding; + +import static it.niedermann.owncloud.notes.NotesApplication.isDarkThemeActive; + +import android.content.Context; +import android.graphics.Color; +import android.graphics.PorterDuff; +import android.graphics.drawable.LayerDrawable; +import android.util.Log; + +import androidx.annotation.ColorInt; +import androidx.annotation.IdRes; +import androidx.annotation.NonNull; +import androidx.appcompat.widget.Toolbar; +import androidx.core.content.ContextCompat; +import androidx.core.graphics.drawable.DrawableCompat; + +import com.google.android.material.appbar.AppBarLayout; +import com.nextcloud.android.common.ui.theme.MaterialSchemes; +import com.nextcloud.android.common.ui.theme.ViewThemeUtilsBase; + +import it.niedermann.android.util.ColorUtil; +import it.niedermann.owncloud.notes.R; +import it.niedermann.owncloud.notes.shared.util.NotesColorUtil; +import scheme.Scheme; + +public class NotesViewThemeUtils extends ViewThemeUtilsBase { + + private static final String TAG = NotesViewThemeUtils.class.getSimpleName(); + + public NotesViewThemeUtils(@NonNull MaterialSchemes schemes) { + super(schemes); + } + + @ColorInt + public int getOnPrimaryContainer(@NonNull Context context) { + return withScheme(context, Scheme::getOnPrimaryContainer); + } + + @Deprecated(forRemoval = true) + public void applyBrandToPrimaryToolbar(@NonNull AppBarLayout appBarLayout, @NonNull Toolbar toolbar, @ColorInt int color) { + // FIXME Workaround for https://github.com/nextcloud/notes-android/issues/889 + appBarLayout.setBackgroundColor(ContextCompat.getColor(appBarLayout.getContext(), R.color.primary)); + + final var overflowDrawable = toolbar.getOverflowIcon(); + if (overflowDrawable != null) { + overflowDrawable.setColorFilter(color, PorterDuff.Mode.SRC_ATOP); + toolbar.setOverflowIcon(overflowDrawable); + } + + final var navigationDrawable = toolbar.getNavigationIcon(); + if (navigationDrawable != null) { + navigationDrawable.setColorFilter(color, PorterDuff.Mode.SRC_ATOP); + toolbar.setNavigationIcon(navigationDrawable); + } + } + + @Deprecated(forRemoval = true) + public void colorLayerDrawable(@NonNull LayerDrawable check, @IdRes int areaToColor, @ColorInt int mainColor) { + final var drawable = check.findDrawableByLayerId(areaToColor); + if (drawable == null) { + Log.e(TAG, "Could not find areaToColor (" + areaToColor + "). Cannot apply brand."); + } else { + DrawableCompat.setTint(drawable, mainColor); + } + } + + @ColorInt + public int getTextHighlightBackgroundColor(@NonNull Context context, @ColorInt int mainColor, @ColorInt int colorPrimary, @ColorInt int colorAccent) { + if (isDarkThemeActive(context)) { // Dark background + if (ColorUtil.INSTANCE.isColorDark(mainColor)) { // Dark brand color + if (NotesColorUtil.contrastRatioIsSufficient(mainColor, colorPrimary)) { // But also dark text + return mainColor; + } else { + return ContextCompat.getColor(context, R.color.defaultTextHighlightBackground); + } + } else { // Light brand color + if (NotesColorUtil.contrastRatioIsSufficient(mainColor, colorAccent)) { // But also dark text + return Color.argb(77, Color.red(mainColor), Color.green(mainColor), Color.blue(mainColor)); + } else { + return ContextCompat.getColor(context, R.color.defaultTextHighlightBackground); + } + } + } else { // Light background + if (ColorUtil.INSTANCE.isColorDark(mainColor)) { // Dark brand color + if (NotesColorUtil.contrastRatioIsSufficient(mainColor, colorAccent)) { // But also dark text + return Color.argb(77, Color.red(mainColor), Color.green(mainColor), Color.blue(mainColor)); + } else { + return ContextCompat.getColor(context, R.color.defaultTextHighlightBackground); + } + } else { // Light brand color + if (NotesColorUtil.contrastRatioIsSufficient(mainColor, colorPrimary)) { // But also dark text + return mainColor; + } else { + return ContextCompat.getColor(context, R.color.defaultTextHighlightBackground); + } + } + } + } +} diff --git a/app/src/main/java/it/niedermann/owncloud/notes/edit/BaseNoteFragment.java b/app/src/main/java/it/niedermann/owncloud/notes/edit/BaseNoteFragment.java index b524e2fb2..4d969382a 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/edit/BaseNoteFragment.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/edit/BaseNoteFragment.java @@ -1,15 +1,12 @@ package it.niedermann.owncloud.notes.edit; import static java.lang.Boolean.TRUE; -import static it.niedermann.owncloud.notes.NotesApplication.isDarkThemeActive; -import static it.niedermann.owncloud.notes.branding.BrandingUtil.tintMenuIcon; import static it.niedermann.owncloud.notes.edit.EditNoteActivity.ACTION_SHORTCUT; import static it.niedermann.owncloud.notes.shared.util.WidgetUtil.pendingIntentFlagCompat; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; -import android.graphics.Color; import android.os.Build; import android.os.Bundle; import android.util.Log; @@ -20,10 +17,8 @@ import android.view.View; import android.widget.ScrollView; import androidx.annotation.CallSuper; -import androidx.annotation.ColorInt; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.core.content.ContextCompat; import androidx.core.content.pm.ShortcutInfoCompat; import androidx.core.content.pm.ShortcutManagerCompat; import androidx.core.graphics.drawable.IconCompat; @@ -37,10 +32,10 @@ import java.util.Calendar; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; -import it.niedermann.android.util.ColorUtil; import it.niedermann.owncloud.notes.R; import it.niedermann.owncloud.notes.accountpicker.AccountPickerDialogFragment; import it.niedermann.owncloud.notes.branding.BrandedFragment; +import it.niedermann.owncloud.notes.branding.BrandingUtil; import it.niedermann.owncloud.notes.edit.category.CategoryDialogFragment; import it.niedermann.owncloud.notes.edit.category.CategoryDialogFragment.CategoryDialogListener; import it.niedermann.owncloud.notes.edit.title.EditTitleDialogFragment; @@ -53,7 +48,6 @@ import it.niedermann.owncloud.notes.shared.model.DBStatus; import it.niedermann.owncloud.notes.shared.model.ISyncCallback; import it.niedermann.owncloud.notes.shared.util.ApiVersionUtil; import it.niedermann.owncloud.notes.shared.util.NoteUtil; -import it.niedermann.owncloud.notes.shared.util.NotesColorUtil; import it.niedermann.owncloud.notes.shared.util.ShareUtil; public abstract class BaseNoteFragment extends BrandedFragment implements CategoryDialogListener, EditTitleListener { @@ -203,7 +197,9 @@ public abstract class BaseNoteFragment extends BrandedFragment implements Catego private void prepareFavoriteOption(MenuItem item) { item.setIcon(note.getFavorite() ? R.drawable.ic_star_white_24dp : R.drawable.ic_star_border_white_24dp); item.setChecked(note.getFavorite()); - tintMenuIcon(item, colorAccent); + + final var utils = BrandingUtil.of(colorAccent, requireContext()); + utils.platform.colorToolbarMenuIcon(requireContext(), item); } /** diff --git a/app/src/main/java/it/niedermann/owncloud/notes/edit/EditNoteActivity.java b/app/src/main/java/it/niedermann/owncloud/notes/edit/EditNoteActivity.java index 8cb12bad1..2446c8df8 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/edit/EditNoteActivity.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/edit/EditNoteActivity.java @@ -30,6 +30,7 @@ import it.niedermann.android.sharedpreferences.SharedPreferenceBooleanLiveData; import it.niedermann.owncloud.notes.LockedActivity; import it.niedermann.owncloud.notes.R; import it.niedermann.owncloud.notes.accountpicker.AccountPickerListener; +import it.niedermann.owncloud.notes.branding.BrandingUtil; import it.niedermann.owncloud.notes.databinding.ActivityEditBinding; import it.niedermann.owncloud.notes.edit.category.CategoryViewModel; import it.niedermann.owncloud.notes.main.MainActivity; @@ -314,6 +315,7 @@ public class EditNoteActivity extends LockedActivity implements BaseNoteFragment @Override public void applyBrand(int mainColor, int textColor) { - applyBrandToPrimaryToolbar(binding.appBar, binding.toolbar); + final var util = BrandingUtil.of(mainColor, this); + util.notes.applyBrandToPrimaryToolbar(binding.appBar, binding.toolbar, colorAccent); } } \ No newline at end of file diff --git a/app/src/main/java/it/niedermann/owncloud/notes/edit/NoteEditFragment.java b/app/src/main/java/it/niedermann/owncloud/notes/edit/NoteEditFragment.java index 081c60d86..29e8a99bd 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/edit/NoteEditFragment.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/edit/NoteEditFragment.java @@ -1,7 +1,6 @@ package it.niedermann.owncloud.notes.edit; import static androidx.core.view.ViewCompat.isAttachedToWindow; -import static it.niedermann.owncloud.notes.branding.BrandingUtil.getTextHighlightBackgroundColor; import static it.niedermann.owncloud.notes.shared.util.NoteUtil.getFontSizeFromPreferences; import android.content.Context; @@ -29,6 +28,7 @@ import androidx.preference.PreferenceManager; import com.google.android.material.floatingactionbutton.FloatingActionButton; import it.niedermann.owncloud.notes.R; +import it.niedermann.owncloud.notes.branding.BrandingUtil; import it.niedermann.owncloud.notes.databinding.FragmentNoteEditBinding; import it.niedermann.owncloud.notes.persistence.entity.Note; import it.niedermann.owncloud.notes.shared.model.ISyncCallback; @@ -252,8 +252,10 @@ public class NoteEditFragment extends SearchableBaseNoteFragment { @Override public void applyBrand(int mainColor, int textColor) { super.applyBrand(mainColor, textColor); + + final var util = BrandingUtil.of(mainColor, requireContext()); binding.editContent.setSearchColor(mainColor); - binding.editContent.setHighlightColor(getTextHighlightBackgroundColor(requireContext(), mainColor, colorPrimary, colorAccent)); + binding.editContent.setHighlightColor(util.notes.getTextHighlightBackgroundColor(requireContext(), mainColor, colorPrimary, colorAccent)); } public static BaseNoteFragment newInstance(long accountId, long noteId) { diff --git a/app/src/main/java/it/niedermann/owncloud/notes/edit/NotePreviewFragment.java b/app/src/main/java/it/niedermann/owncloud/notes/edit/NotePreviewFragment.java index 52db93a46..2f3b18b71 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/edit/NotePreviewFragment.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/edit/NotePreviewFragment.java @@ -1,7 +1,6 @@ package it.niedermann.owncloud.notes.edit; import static androidx.core.view.ViewCompat.isAttachedToWindow; -import static it.niedermann.owncloud.notes.branding.BrandingUtil.getTextHighlightBackgroundColor; import static it.niedermann.owncloud.notes.shared.util.NoteUtil.getFontSizeFromPreferences; import android.content.Intent; @@ -29,6 +28,7 @@ import com.nextcloud.android.sso.exceptions.NoCurrentAccountSelectedException; import com.nextcloud.android.sso.helper.SingleAccountHelper; import it.niedermann.owncloud.notes.R; +import it.niedermann.owncloud.notes.branding.BrandingUtil; import it.niedermann.owncloud.notes.databinding.FragmentNotePreviewBinding; import it.niedermann.owncloud.notes.persistence.entity.Note; import it.niedermann.owncloud.notes.shared.util.SSOUtil; @@ -179,8 +179,10 @@ public class NotePreviewFragment extends SearchableBaseNoteFragment implements O @Override public void applyBrand(int mainColor, int textColor) { super.applyBrand(mainColor, textColor); + + final var util = BrandingUtil.of(mainColor, requireContext()); binding.singleNoteContent.setSearchColor(mainColor); - binding.singleNoteContent.setHighlightColor(getTextHighlightBackgroundColor(requireContext(), mainColor, colorPrimary, colorAccent)); + binding.singleNoteContent.setHighlightColor(util.notes.getTextHighlightBackgroundColor(requireContext(), mainColor, colorPrimary, colorAccent)); } public static BaseNoteFragment newInstance(long accountId, long noteId) { diff --git a/app/src/main/java/it/niedermann/owncloud/notes/edit/SearchableBaseNoteFragment.java b/app/src/main/java/it/niedermann/owncloud/notes/edit/SearchableBaseNoteFragment.java index 794bfee71..2cda0250a 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/edit/SearchableBaseNoteFragment.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/edit/SearchableBaseNoteFragment.java @@ -26,6 +26,7 @@ import java.util.regex.Pattern; import it.niedermann.owncloud.notes.R; import it.niedermann.owncloud.notes.branding.BrandedActivity; +import it.niedermann.owncloud.notes.branding.BrandingUtil; public abstract class SearchableBaseNoteFragment extends BaseNoteFragment { @@ -295,7 +296,9 @@ public abstract class SearchableBaseNoteFragment extends BaseNoteFragment { public void applyBrand(int mainColor, int textColor) { this.mainColor = mainColor; this.textColor = textColor; - BrandedActivity.applyBrandToFAB(mainColor, textColor, getSearchPrevButton()); - BrandedActivity.applyBrandToFAB(mainColor, textColor, getSearchNextButton()); + + final var util = BrandingUtil.of(mainColor, requireContext()); + util.material.themeFAB(getSearchNextButton()); + util.material.themeFAB(getSearchPrevButton()); } } diff --git a/app/src/main/java/it/niedermann/owncloud/notes/edit/category/CategoryDialogFragment.java b/app/src/main/java/it/niedermann/owncloud/notes/edit/category/CategoryDialogFragment.java index c440f8302..97d9a4a1a 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/edit/category/CategoryDialogFragment.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/edit/category/CategoryDialogFragment.java @@ -49,7 +49,8 @@ public class CategoryDialogFragment extends BrandedDialogFragment { @Override public void applyBrand(int mainColor, int textColor) { - BrandingUtil.applyBrandToEditTextInputLayout(mainColor, binding.inputWrapper); + final var util = BrandingUtil.of(mainColor, requireContext()); + util.material.colorTextInputLayout(binding.inputWrapper); } /** diff --git a/app/src/main/java/it/niedermann/owncloud/notes/edit/title/EditTitleDialogFragment.java b/app/src/main/java/it/niedermann/owncloud/notes/edit/title/EditTitleDialogFragment.java index e48ff63dc..0f1f644f9 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/edit/title/EditTitleDialogFragment.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/edit/title/EditTitleDialogFragment.java @@ -1,7 +1,5 @@ package it.niedermann.owncloud.notes.edit.title; -import static it.niedermann.owncloud.notes.branding.BrandingUtil.applyBrandToEditTextInputLayout; - import android.app.Dialog; import android.content.Context; import android.os.Bundle; @@ -18,6 +16,7 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder; import it.niedermann.owncloud.notes.R; import it.niedermann.owncloud.notes.branding.BrandedDialogFragment; +import it.niedermann.owncloud.notes.branding.BrandingUtil; import it.niedermann.owncloud.notes.databinding.DialogEditTitleBinding; public class EditTitleDialogFragment extends BrandedDialogFragment { @@ -88,7 +87,8 @@ public class EditTitleDialogFragment extends BrandedDialogFragment { @Override public void applyBrand(int mainColor, int textColor) { - applyBrandToEditTextInputLayout(mainColor, binding.inputWrapper); + final var util = BrandingUtil.of(mainColor, requireContext()); + util.material.colorTextInputLayout(binding.inputWrapper); } /** 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 943be0251..1443a0c02 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 @@ -6,7 +6,6 @@ import static android.view.View.GONE; import static android.view.View.VISIBLE; import static it.niedermann.owncloud.notes.NotesApplication.isDarkThemeActive; import static it.niedermann.owncloud.notes.NotesApplication.isGridViewEnabled; -import static it.niedermann.owncloud.notes.branding.BrandingUtil.getSecondaryForegroundColorDependingOnTheme; import static it.niedermann.owncloud.notes.shared.model.ENavigationCategoryType.DEFAULT_CATEGORY; import static it.niedermann.owncloud.notes.shared.model.ENavigationCategoryType.FAVORITES; import static it.niedermann.owncloud.notes.shared.model.ENavigationCategoryType.RECENT; @@ -19,7 +18,6 @@ import android.animation.AnimatorInflater; import android.app.SearchManager; import android.content.Intent; import android.graphics.Color; -import android.graphics.PorterDuff; import android.net.Uri; import android.os.Bundle; import android.text.TextUtils; @@ -71,6 +69,7 @@ import it.niedermann.owncloud.notes.accountpicker.AccountPickerListener; import it.niedermann.owncloud.notes.accountswitcher.AccountSwitcherDialog; import it.niedermann.owncloud.notes.accountswitcher.AccountSwitcherListener; import it.niedermann.owncloud.notes.branding.BrandedSnackbar; +import it.niedermann.owncloud.notes.branding.BrandingUtil; import it.niedermann.owncloud.notes.databinding.ActivityNotesListViewBinding; import it.niedermann.owncloud.notes.databinding.DrawerLayoutBinding; import it.niedermann.owncloud.notes.edit.EditNoteActivity; @@ -592,12 +591,13 @@ public class MainActivity extends LockedActivity implements NoteClickListener, A @Override public void applyBrand(int mainColor, int textColor) { - applyBrandToPrimaryToolbar(activityBinding.appBar, activityBinding.searchToolbar); - applyBrandToFAB(mainColor, textColor, activityBinding.fabCreate); + final var util = BrandingUtil.of(mainColor, this); + util.material.themeFAB(activityBinding.fabCreate); + util.platform.colorCircularProgressBar(activityBinding.progressCircular); + util.notes.applyBrandToPrimaryToolbar(activityBinding.appBar, activityBinding.searchToolbar, colorAccent); binding.headerView.setBackgroundColor(mainColor); binding.appName.setTextColor(textColor); - activityBinding.progressCircular.getIndeterminateDrawable().setColorFilter(getSecondaryForegroundColorDependingOnTheme(this, mainColor), PorterDuff.Mode.SRC_IN); // TODO We assume, that the background of the spinner is always white activityBinding.swiperefreshlayout.setColorSchemeColors(contrastRatioIsSufficient(Color.WHITE, mainColor) ? mainColor : Color.BLACK); diff --git a/app/src/main/java/it/niedermann/owncloud/notes/main/items/NoteViewHolder.java b/app/src/main/java/it/niedermann/owncloud/notes/main/items/NoteViewHolder.java index 609d1aeff..6b5ab83c7 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/main/items/NoteViewHolder.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/main/items/NoteViewHolder.java @@ -1,5 +1,9 @@ package it.niedermann.owncloud.notes.main.items; +import static android.view.View.INVISIBLE; +import static android.view.View.VISIBLE; +import static it.niedermann.owncloud.notes.shared.util.NotesColorUtil.contrastRatioIsSufficient; + import android.content.Context; import android.content.res.ColorStateList; import android.graphics.Color; @@ -34,10 +38,6 @@ import it.niedermann.owncloud.notes.persistence.entity.Note; import it.niedermann.owncloud.notes.shared.model.DBStatus; import it.niedermann.owncloud.notes.shared.model.NoteClickListener; -import static android.view.View.INVISIBLE; -import static android.view.View.VISIBLE; -import static it.niedermann.owncloud.notes.shared.util.NotesColorUtil.contrastRatioIsSufficient; - public abstract class NoteViewHolder extends RecyclerView.ViewHolder { @NonNull private final NoteClickListener noteClickListener; @@ -56,7 +56,8 @@ public abstract class NoteViewHolder extends RecyclerView.ViewHolder { protected void bindStatus(AppCompatImageView noteStatus, DBStatus status, int mainColor) { noteStatus.setVisibility(DBStatus.VOID.equals(status) ? INVISIBLE : VISIBLE); - DrawableCompat.setTint(noteStatus.getDrawable(), BrandingUtil.getSecondaryForegroundColorDependingOnTheme(noteStatus.getContext(), mainColor)); + final var context = noteStatus.getContext(); + DrawableCompat.setTint(noteStatus.getDrawable(), BrandingUtil.of(mainColor, context).notes.getOnPrimaryContainer(context)); } protected void bindCategory(@NonNull Context context, @NonNull TextView noteCategory, boolean showCategory, @NonNull String category, int mainColor) { @@ -111,13 +112,13 @@ public abstract class NoteViewHolder extends RecyclerView.ViewHolder { protected void bindSearchableContent(@NonNull Context context, @NonNull TextView textView, @Nullable CharSequence searchQuery, @NonNull String content, int mainColor) { CharSequence processedContent = content; if (!TextUtils.isEmpty(searchQuery)) { + final var util = BrandingUtil.of(mainColor, context); + @ColorInt final int searchForeground = util.notes.getOnPrimaryContainer(context); @ColorInt final int searchBackground = ContextCompat.getColor(context, R.color.bg_highlighted); - @ColorInt final int searchForeground = BrandingUtil.getSecondaryForegroundColorDependingOnTheme(context, mainColor); // The Pattern.quote method will add \Q to the very beginning of the string and \E to the end of the string // It implies that the string between \Q and \E is a literal string and thus the reserved keyword in such string will be ignored. // See https://stackoverflow.com/questions/15409296/what-is-the-use-of-pattern-quote-method - //noinspection ConstantConditions final Pattern pattern = Pattern.compile("(" + Pattern.quote(searchQuery.toString()) + ")", Pattern.CASE_INSENSITIVE); SpannableString spannableString = new SpannableString(content); Matcher matcher = pattern.matcher(spannableString); diff --git a/app/src/main/java/it/niedermann/owncloud/notes/main/navigation/NavigationAdapter.java b/app/src/main/java/it/niedermann/owncloud/notes/main/navigation/NavigationAdapter.java index 78ac616d2..85cd3545c 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/main/navigation/NavigationAdapter.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/main/navigation/NavigationAdapter.java @@ -1,15 +1,15 @@ package it.niedermann.owncloud.notes.main.navigation; +import static it.niedermann.owncloud.notes.shared.model.ENavigationCategoryType.UNCATEGORIZED; + import android.content.Context; import android.text.TextUtils; import android.view.LayoutInflater; -import android.view.View; import android.view.ViewGroup; import androidx.annotation.ColorInt; import androidx.annotation.DrawableRes; import androidx.annotation.NonNull; -import androidx.annotation.Nullable; import androidx.recyclerview.widget.RecyclerView; import java.util.ArrayList; @@ -19,8 +19,6 @@ import it.niedermann.owncloud.notes.R; import it.niedermann.owncloud.notes.branding.BrandingUtil; import it.niedermann.owncloud.notes.main.MainActivity; -import static it.niedermann.owncloud.notes.shared.model.ENavigationCategoryType.UNCATEGORIZED; - public class NavigationAdapter extends RecyclerView.Adapter { @NonNull @@ -41,7 +39,8 @@ public class NavigationAdapter extends RecyclerView.Adapter { mainColor$.removeObservers(this); - applyBrandToEditTextInputLayout(color, binding.inputWrapper); - binding.progress.setIndicatorColor(color); + final var util = BrandingUtil.of(color, this); + util.material.colorTextInputLayout(binding.inputWrapper); + util.material.colorProgressBar(binding.progress); }); binding.inputWrapper.setHint(title); @@ -208,6 +209,7 @@ public class ManageAccountsActivity extends LockedActivity implements IManageAcc @Override public void applyBrand(int mainColor, int textColor) { - applyBrandToPrimaryToolbar(binding.appBar, binding.toolbar); + final var util = BrandingUtil.of(mainColor, this); + util.notes.applyBrandToPrimaryToolbar(binding.appBar, binding.toolbar, colorAccent); } } diff --git a/app/src/main/java/it/niedermann/owncloud/notes/preferences/PreferencesActivity.java b/app/src/main/java/it/niedermann/owncloud/notes/preferences/PreferencesActivity.java index 2dcd99ec1..99cc89e15 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/preferences/PreferencesActivity.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/preferences/PreferencesActivity.java @@ -7,6 +7,7 @@ import androidx.lifecycle.ViewModelProvider; import it.niedermann.owncloud.notes.LockedActivity; import it.niedermann.owncloud.notes.R; +import it.niedermann.owncloud.notes.branding.BrandingUtil; import it.niedermann.owncloud.notes.databinding.ActivityPreferencesBinding; public class PreferencesActivity extends LockedActivity { @@ -32,6 +33,7 @@ public class PreferencesActivity extends LockedActivity { @Override public void applyBrand(int mainColor, int textColor) { - applyBrandToPrimaryToolbar(binding.appBar, binding.toolbar); + final var util = BrandingUtil.of(mainColor, this); + util.notes.applyBrandToPrimaryToolbar(binding.appBar, binding.toolbar, colorAccent); } } -- GitLab From 05a4fad5d92c4dac2fd1a896d1762aa56c58a58c Mon Sep 17 00:00:00 2001 From: Stefan Niedermann Date: Sun, 12 Feb 2023 12:56:10 +0100 Subject: [PATCH 051/163] feat(theming): Get rid of textColor property Signed-off-by: Stefan Niedermann --- .../notes/FormattingHelpActivity.java | 4 +- .../owncloud/notes/about/AboutActivity.java | 4 +- .../notes/about/AboutFragmentLicenseTab.java | 4 +- .../AccountPickerDialogFragment.java | 2 +- .../AccountSwitcherDialog.java | 6 +- .../owncloud/notes/branding/Branded.java | 2 +- .../notes/branding/BrandedActivity.java | 4 +- .../notes/branding/BrandedDialogFragment.java | 5 +- .../notes/branding/BrandedFragment.java | 5 +- .../branding/BrandedSwitchPreference.java | 10 +-- .../owncloud/notes/branding/BrandingUtil.java | 74 +------------------ .../owncloud/notes/edit/EditNoteActivity.java | 4 +- .../owncloud/notes/edit/NoteEditFragment.java | 12 +-- .../notes/edit/NotePreviewFragment.java | 13 ++-- .../edit/SearchableBaseNoteFragment.java | 33 +++------ .../edit/category/CategoryDialogFragment.java | 4 +- .../edit/title/EditTitleDialogFragment.java | 4 +- .../importaccount/ImportAccountActivity.java | 3 +- .../owncloud/notes/main/MainActivity.java | 20 ++--- .../owncloud/notes/main/MainViewModel.java | 7 +- .../notes/main/items/ItemAdapter.java | 16 ++-- .../notes/main/items/NoteViewHolder.java | 2 +- .../main/items/grid/NoteViewGridHolder.java | 13 ++-- .../grid/NoteViewGridHolderOnlyTitle.java | 8 +- .../items/list/NoteViewHolderWithExcerpt.java | 13 ++-- .../list/NoteViewHolderWithoutExcerpt.java | 10 +-- .../notes/main/menu/MenuViewHolder.java | 1 - .../main/navigation/NavigationAdapter.java | 12 +-- .../ManageAccountsActivity.java | 4 +- .../notes/persistence/CapabilitiesWorker.java | 2 +- .../notes/persistence/NotesDatabase.java | 6 +- .../notes/persistence/NotesRepository.java | 4 +- .../notes/persistence/dao/AccountDao.java | 4 +- .../notes/persistence/entity/Account.java | 1 - .../migration/Migration_23_24.java | 28 +++++++ .../preferences/PreferencesActivity.java | 4 +- .../preferences/PreferencesFragment.java | 24 +++--- .../NoteListWidgetConfigurationActivity.java | 3 +- 38 files changed, 159 insertions(+), 216 deletions(-) create mode 100644 app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_23_24.java diff --git a/app/src/main/java/it/niedermann/owncloud/notes/FormattingHelpActivity.java b/app/src/main/java/it/niedermann/owncloud/notes/FormattingHelpActivity.java index f4e8d788f..6fe0047e3 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/FormattingHelpActivity.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/FormattingHelpActivity.java @@ -223,8 +223,8 @@ public class FormattingHelpActivity extends BrandedActivity { } @Override - public void applyBrand(int mainColor, int textColor) { - final var util = BrandingUtil.of(mainColor, this); + public void applyBrand(int color) { + final var util = BrandingUtil.of(color, this); util.notes.applyBrandToPrimaryToolbar(binding.appBar, binding.toolbar, colorAccent); } } diff --git a/app/src/main/java/it/niedermann/owncloud/notes/about/AboutActivity.java b/app/src/main/java/it/niedermann/owncloud/notes/about/AboutActivity.java index 2c187af65..3d871f6a2 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/about/AboutActivity.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/about/AboutActivity.java @@ -50,8 +50,8 @@ public class AboutActivity extends LockedActivity { } @Override - public void applyBrand(int mainColor, int textColor) { - final var util = BrandingUtil.of(mainColor, this); + public void applyBrand(int color) { + final var util = BrandingUtil.of(color, this); util.material.themeTabLayout(binding.tabs); util.notes.applyBrandToPrimaryToolbar(binding.appBar, binding.toolbar, colorAccent); } diff --git a/app/src/main/java/it/niedermann/owncloud/notes/about/AboutFragmentLicenseTab.java b/app/src/main/java/it/niedermann/owncloud/notes/about/AboutFragmentLicenseTab.java index 173d36617..df6d43940 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/about/AboutFragmentLicenseTab.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/about/AboutFragmentLicenseTab.java @@ -34,8 +34,8 @@ public class AboutFragmentLicenseTab extends BrandedFragment { } @Override - public void applyBrand(int mainColor, int textColor) { - final var util = BrandingUtil.of(mainColor, requireContext()); + public void applyBrand(int color) { + final var util = BrandingUtil.of(color, requireContext()); util.material.colorMaterialButtonPrimaryFilled(binding.aboutAppLicenseButton); } } \ No newline at end of file diff --git a/app/src/main/java/it/niedermann/owncloud/notes/accountpicker/AccountPickerDialogFragment.java b/app/src/main/java/it/niedermann/owncloud/notes/accountpicker/AccountPickerDialogFragment.java index 8caa45402..12272889a 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/accountpicker/AccountPickerDialogFragment.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/accountpicker/AccountPickerDialogFragment.java @@ -109,7 +109,7 @@ public class AccountPickerDialogFragment extends BrandedDialogFragment { } @Override - public void applyBrand(int mainColor, int textColor) { + public void applyBrand(int color) { // Nothing to do... } } diff --git a/app/src/main/java/it/niedermann/owncloud/notes/accountswitcher/AccountSwitcherDialog.java b/app/src/main/java/it/niedermann/owncloud/notes/accountswitcher/AccountSwitcherDialog.java index 56f37773b..c33a17e36 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/accountswitcher/AccountSwitcherDialog.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/accountswitcher/AccountSwitcherDialog.java @@ -116,8 +116,8 @@ public class AccountSwitcherDialog extends BrandedDialogFragment { } @Override - public void applyBrand(int mainColor, int textColor) { - final var util = BrandingUtil.of(mainColor, requireContext()); - util.notes.colorLayerDrawable((LayerDrawable) binding.check.getDrawable(), R.id.area, mainColor); + public void applyBrand(int color) { + final var util = BrandingUtil.of(color, requireContext()); + util.notes.colorLayerDrawable((LayerDrawable) binding.check.getDrawable(), R.id.area, color); } } diff --git a/app/src/main/java/it/niedermann/owncloud/notes/branding/Branded.java b/app/src/main/java/it/niedermann/owncloud/notes/branding/Branded.java index 7ef9138de..29a33868b 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/branding/Branded.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/branding/Branded.java @@ -5,5 +5,5 @@ import androidx.annotation.UiThread; public interface Branded { @UiThread - void applyBrand(@ColorInt int mainColor, @ColorInt int textColor); + void applyBrand(@ColorInt int color); } \ No newline at end of file diff --git a/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandedActivity.java b/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandedActivity.java index 492a7dece..113db2a92 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandedActivity.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandedActivity.java @@ -1,6 +1,6 @@ package it.niedermann.owncloud.notes.branding; -import static it.niedermann.owncloud.notes.branding.BrandingUtil.readBrandColors; +import static it.niedermann.owncloud.notes.branding.BrandingUtil.readBrandMainColorLiveData; import android.util.TypedValue; import android.view.Menu; @@ -23,7 +23,7 @@ public abstract class BrandedActivity extends AppCompatActivity implements Brand getTheme().resolveAttribute(R.attr.colorAccent, typedValue, true); colorAccent = typedValue.data; - readBrandColors(this).observe(this, (pair) -> applyBrand(pair.first, pair.second)); + readBrandMainColorLiveData(this).observe(this, this::applyBrand); } @Override diff --git a/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandedDialogFragment.java b/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandedDialogFragment.java index b930c63a9..bf232b7da 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandedDialogFragment.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandedDialogFragment.java @@ -13,8 +13,7 @@ public abstract class BrandedDialogFragment extends DialogFragment implements Br super.onStart(); @Nullable final var context = requireContext(); - @ColorInt final int mainColor = BrandingUtil.readBrandMainColor(context); - @ColorInt final int textColor = BrandingUtil.readBrandTextColor(context); - applyBrand(mainColor, textColor); + @ColorInt final int color = BrandingUtil.readBrandMainColor(context); + applyBrand(color); } } diff --git a/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandedFragment.java b/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandedFragment.java index 708815b38..ac197ef8f 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandedFragment.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandedFragment.java @@ -28,9 +28,8 @@ public abstract class BrandedFragment extends Fragment implements Branded { context.getTheme().resolveAttribute(R.attr.colorPrimary, typedValue, true); colorPrimary = typedValue.data; - @ColorInt final int mainColor = BrandingUtil.readBrandMainColor(context); - @ColorInt final int textColor = BrandingUtil.readBrandTextColor(context); - applyBrand(mainColor, textColor); + @ColorInt final int color = BrandingUtil.readBrandMainColor(context); + applyBrand(color); } @Override diff --git a/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandedSwitchPreference.java b/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandedSwitchPreference.java index 3fe0f0839..6536b164b 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandedSwitchPreference.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandedSwitchPreference.java @@ -17,9 +17,6 @@ public class BrandedSwitchPreference extends SwitchPreference implements Branded @ColorInt private Integer mainColor = null; - @ColorInt - private Integer textColor = null; - @SuppressLint("UseSwitchCompatOrMaterialCode") @Nullable private Switch switchView; @@ -46,16 +43,15 @@ public class BrandedSwitchPreference extends SwitchPreference implements Branded if (holder.itemView instanceof ViewGroup) { switchView = findSwitchWidget(holder.itemView); - if (mainColor != null && textColor != null) { + if (mainColor != null) { applyBrand(); } } } @Override - public void applyBrand(@ColorInt int mainColor, @ColorInt int textColor) { - this.mainColor = mainColor; - this.textColor = textColor; + public void applyBrand(@ColorInt int color) { + this.mainColor = color; // onBindViewHolder is called after applyBrand, therefore we have to store the given values and apply them later. applyBrand(); } diff --git a/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandingUtil.java b/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandingUtil.java index b797a9e29..ab447f83b 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandingUtil.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandingUtil.java @@ -1,56 +1,32 @@ package it.niedermann.owncloud.notes.branding; -import static it.niedermann.owncloud.notes.NotesApplication.isDarkThemeActive; -import static it.niedermann.owncloud.notes.shared.util.NotesColorUtil.contrastRatioIsSufficient; -import static it.niedermann.owncloud.notes.shared.util.NotesColorUtil.contrastRatioIsSufficientBigAreas; - import android.content.Context; -import android.content.res.ColorStateList; -import android.graphics.Color; -import android.graphics.drawable.LayerDrawable; import android.util.Log; -import android.util.TypedValue; -import android.view.MenuItem; -import android.widget.EditText; -import android.widget.TextView; -import androidx.annotation.AttrRes; import androidx.annotation.ColorInt; -import androidx.annotation.IdRes; import androidx.annotation.NonNull; import androidx.core.app.ActivityCompat; -import androidx.core.content.ContextCompat; -import androidx.core.graphics.drawable.DrawableCompat; -import androidx.core.util.Pair; import androidx.lifecycle.LiveData; -import androidx.lifecycle.MediatorLiveData; import androidx.preference.PreferenceManager; -import com.google.android.material.textfield.TextInputLayout; import com.nextcloud.android.common.ui.theme.MaterialSchemes; import com.nextcloud.android.common.ui.theme.ViewThemeUtilsBase; import com.nextcloud.android.common.ui.theme.utils.AndroidViewThemeUtils; import com.nextcloud.android.common.ui.theme.utils.AndroidXViewThemeUtils; import com.nextcloud.android.common.ui.theme.utils.DialogViewThemeUtils; import com.nextcloud.android.common.ui.theme.utils.MaterialViewThemeUtils; -import com.nextcloud.android.common.ui.util.PlatformThemeUtil; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import it.niedermann.android.sharedpreferences.SharedPreferenceIntLiveData; -import it.niedermann.android.util.ColorUtil; -import it.niedermann.owncloud.notes.NotesApplication; import it.niedermann.owncloud.notes.R; -import it.niedermann.owncloud.notes.shared.util.NotesColorUtil; -import scheme.Scheme; public class BrandingUtil extends ViewThemeUtilsBase { private static final String TAG = BrandingUtil.class.getSimpleName(); private static final ConcurrentMap CACHE = new ConcurrentHashMap<>(); private static final String pref_key_branding_main = "branding_main"; - private static final String pref_key_branding_text = "branding_text"; public final AndroidViewThemeUtils platform; public final MaterialViewThemeUtils material; @@ -78,44 +54,12 @@ public class BrandingUtil extends ViewThemeUtilsBase { )); } - public static LiveData> readBrandColors(@NonNull Context context) { - return new BrandingLiveData(context); - } - - private static class BrandingLiveData extends MediatorLiveData> { - @ColorInt - Integer lastMainColor = null; - @ColorInt - Integer lastTextColor = null; - - public BrandingLiveData(@NonNull Context context) { - addSource(readBrandMainColorLiveData(context), (nextMainColor) -> { - lastMainColor = nextMainColor; - if (lastTextColor != null) { - postValue(new Pair<>(lastMainColor, lastTextColor)); - } - }); - addSource(readBrandTextColorLiveData(context), (nextTextColor) -> { - lastTextColor = nextTextColor; - if (lastMainColor != null) { - postValue(new Pair<>(lastMainColor, lastTextColor)); - } - }); - } - } - public static LiveData readBrandMainColorLiveData(@NonNull Context context) { final var sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context.getApplicationContext()); Log.v(TAG, "--- Read: shared_preference_theme_main"); return new SharedPreferenceIntLiveData(sharedPreferences, pref_key_branding_main, context.getApplicationContext().getResources().getColor(R.color.defaultBrand)); } - public static LiveData readBrandTextColorLiveData(@NonNull Context context) { - final var sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context.getApplicationContext()); - Log.v(TAG, "--- Read: shared_preference_theme_text"); - return new SharedPreferenceIntLiveData(sharedPreferences, pref_key_branding_text, Color.WHITE); - } - @ColorInt public static int readBrandMainColor(@NonNull Context context) { final var sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context.getApplicationContext()); @@ -123,24 +67,14 @@ public class BrandingUtil extends ViewThemeUtilsBase { return sharedPreferences.getInt(pref_key_branding_main, context.getApplicationContext().getResources().getColor(R.color.defaultBrand)); } - @ColorInt - public static int readBrandTextColor(@NonNull Context context) { - final var sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context.getApplicationContext()); - Log.v(TAG, "--- Read: shared_preference_theme_text"); - return sharedPreferences.getInt(pref_key_branding_text, Color.WHITE); - } - - public static void saveBrandColors(@NonNull Context context, @ColorInt int mainColor, @ColorInt int textColor) { + public static void saveBrandColor(@NonNull Context context, @ColorInt int color) { final int previousMainColor = readBrandMainColor(context); - final int previousTextColor = readBrandTextColor(context); final var editor = PreferenceManager.getDefaultSharedPreferences(context).edit(); - Log.v(TAG, "--- Write: shared_preference_theme_main" + " | " + mainColor); - Log.v(TAG, "--- Write: shared_preference_theme_text" + " | " + textColor); - editor.putInt(pref_key_branding_main, mainColor); - editor.putInt(pref_key_branding_text, textColor); + Log.v(TAG, "--- Write: shared_preference_theme_main" + " | " + color); + editor.putInt(pref_key_branding_main, color); editor.apply(); if (context instanceof BrandedActivity) { - if (mainColor != previousMainColor || textColor != previousTextColor) { + if (color != previousMainColor) { final var activity = (BrandedActivity) context; activity.runOnUiThread(() -> ActivityCompat.recreate(activity)); } diff --git a/app/src/main/java/it/niedermann/owncloud/notes/edit/EditNoteActivity.java b/app/src/main/java/it/niedermann/owncloud/notes/edit/EditNoteActivity.java index 2446c8df8..0fbc0bbf8 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/edit/EditNoteActivity.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/edit/EditNoteActivity.java @@ -314,8 +314,8 @@ public class EditNoteActivity extends LockedActivity implements BaseNoteFragment } @Override - public void applyBrand(int mainColor, int textColor) { - final var util = BrandingUtil.of(mainColor, this); + public void applyBrand(int color) { + final var util = BrandingUtil.of(color, this); util.notes.applyBrandToPrimaryToolbar(binding.appBar, binding.toolbar, colorAccent); } } \ No newline at end of file diff --git a/app/src/main/java/it/niedermann/owncloud/notes/edit/NoteEditFragment.java b/app/src/main/java/it/niedermann/owncloud/notes/edit/NoteEditFragment.java index 29e8a99bd..13061417c 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/edit/NoteEditFragment.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/edit/NoteEditFragment.java @@ -242,7 +242,7 @@ public class NoteEditFragment extends SearchableBaseNoteFragment { } @Override - protected void colorWithText(@NonNull String newText, @Nullable Integer current, int mainColor, int textColor) { + protected void colorWithText(@NonNull String newText, @Nullable Integer current, int color) { if (binding != null && isAttachedToWindow(binding.editContent)) { binding.editContent.clearFocus(); binding.editContent.setSearchText(newText, current); @@ -250,12 +250,12 @@ public class NoteEditFragment extends SearchableBaseNoteFragment { } @Override - public void applyBrand(int mainColor, int textColor) { - super.applyBrand(mainColor, textColor); + public void applyBrand(int color) { + super.applyBrand(color); - final var util = BrandingUtil.of(mainColor, requireContext()); - binding.editContent.setSearchColor(mainColor); - binding.editContent.setHighlightColor(util.notes.getTextHighlightBackgroundColor(requireContext(), mainColor, colorPrimary, colorAccent)); + final var util = BrandingUtil.of(color, requireContext()); + binding.editContent.setSearchColor(color); + binding.editContent.setHighlightColor(util.notes.getTextHighlightBackgroundColor(requireContext(), color, colorPrimary, colorAccent)); } public static BaseNoteFragment newInstance(long accountId, long noteId) { diff --git a/app/src/main/java/it/niedermann/owncloud/notes/edit/NotePreviewFragment.java b/app/src/main/java/it/niedermann/owncloud/notes/edit/NotePreviewFragment.java index 2f3b18b71..0b2991a7d 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/edit/NotePreviewFragment.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/edit/NotePreviewFragment.java @@ -17,6 +17,7 @@ import android.view.ViewGroup; import android.widget.ScrollView; import android.widget.Toast; +import androidx.annotation.ColorInt; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.preference.PreferenceManager; @@ -138,7 +139,7 @@ public class NotePreviewFragment extends SearchableBaseNoteFragment implements O } @Override - protected void colorWithText(@NonNull String newText, @Nullable Integer current, int mainColor, int textColor) { + protected void colorWithText(@NonNull String newText, @Nullable Integer current, @ColorInt int color) { if (binding != null && isAttachedToWindow(binding.singleNoteContent)) { binding.singleNoteContent.clearFocus(); binding.singleNoteContent.setSearchText(newText, current); @@ -177,12 +178,12 @@ public class NotePreviewFragment extends SearchableBaseNoteFragment implements O } @Override - public void applyBrand(int mainColor, int textColor) { - super.applyBrand(mainColor, textColor); + public void applyBrand(int color) { + super.applyBrand(color); - final var util = BrandingUtil.of(mainColor, requireContext()); - binding.singleNoteContent.setSearchColor(mainColor); - binding.singleNoteContent.setHighlightColor(util.notes.getTextHighlightBackgroundColor(requireContext(), mainColor, colorPrimary, colorAccent)); + final var util = BrandingUtil.of(color, requireContext()); + binding.singleNoteContent.setSearchColor(color); + binding.singleNoteContent.setHighlightColor(util.notes.getTextHighlightBackgroundColor(requireContext(), color, colorPrimary, colorAccent)); } public static BaseNoteFragment newInstance(long accountId, long noteId) { diff --git a/app/src/main/java/it/niedermann/owncloud/notes/edit/SearchableBaseNoteFragment.java b/app/src/main/java/it/niedermann/owncloud/notes/edit/SearchableBaseNoteFragment.java index 2cda0250a..4d1ec24fd 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/edit/SearchableBaseNoteFragment.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/edit/SearchableBaseNoteFragment.java @@ -7,11 +7,8 @@ import android.text.Layout; import android.text.TextUtils; import android.util.Log; import android.view.Menu; -import android.view.MenuItem; import android.view.View; import android.view.ViewTreeObserver; -import android.widget.LinearLayout; -import android.widget.ScrollView; import androidx.annotation.CallSuper; import androidx.annotation.ColorInt; @@ -21,11 +18,9 @@ import androidx.appcompat.widget.SearchView; import com.google.android.material.floatingactionbutton.FloatingActionButton; -import java.util.regex.Matcher; import java.util.regex.Pattern; import it.niedermann.owncloud.notes.R; -import it.niedermann.owncloud.notes.branding.BrandedActivity; import it.niedermann.owncloud.notes.branding.BrandingUtil; public abstract class SearchableBaseNoteFragment extends BaseNoteFragment { @@ -41,14 +36,11 @@ public abstract class SearchableBaseNoteFragment extends BaseNoteFragment { private static final int delay = 50; // If the search string does not change after $delay ms, then the search task starts. @ColorInt - private int mainColor; - @ColorInt - private int textColor; + private int color; @Override public void onStart() { - this.mainColor = getResources().getColor(R.color.defaultBrand); - this.textColor = Color.WHITE; + this.color = getResources().getColor(R.color.defaultBrand); super.onStart(); } @@ -89,12 +81,12 @@ public abstract class SearchableBaseNoteFragment extends BaseNoteFragment { if (currentVisibility != oldVisibility) { if (currentVisibility != View.VISIBLE) { - colorWithText("", null, mainColor, textColor); + colorWithText("", null, color); searchQuery = ""; hideSearchFabs(); } else { jumpToOccurrence(); - colorWithText(searchQuery, null, mainColor, textColor); + colorWithText(searchQuery, null, color); occurrenceCount = countOccurrences(getContent(), searchQuery); showSearchFabs(); } @@ -112,7 +104,7 @@ public abstract class SearchableBaseNoteFragment extends BaseNoteFragment { next.setOnClickListener(v -> { currentOccurrence++; jumpToOccurrence(); - colorWithText(searchView.getQuery().toString(), currentOccurrence, mainColor, textColor); + colorWithText(searchView.getQuery().toString(), currentOccurrence, color); }); } @@ -121,7 +113,7 @@ public abstract class SearchableBaseNoteFragment extends BaseNoteFragment { occurrenceCount = countOccurrences(getContent(), searchView.getQuery().toString()); currentOccurrence--; jumpToOccurrence(); - colorWithText(searchView.getQuery().toString(), currentOccurrence, mainColor, textColor); + colorWithText(searchView.getQuery().toString(), currentOccurrence, color); }); } @@ -133,7 +125,7 @@ public abstract class SearchableBaseNoteFragment extends BaseNoteFragment { public boolean onQueryTextSubmit(@NonNull String query) { currentOccurrence++; jumpToOccurrence(); - colorWithText(query, currentOccurrence, mainColor, textColor); + colorWithText(query, currentOccurrence, color); return true; } @@ -153,7 +145,7 @@ public abstract class SearchableBaseNoteFragment extends BaseNoteFragment { } currentOccurrence = 1; jumpToOccurrence(); - colorWithText(searchQuery, currentOccurrence, mainColor, textColor); + colorWithText(searchQuery, currentOccurrence, color); } private void queryWithHandler(@NonNull String newText) { @@ -199,7 +191,7 @@ public abstract class SearchableBaseNoteFragment extends BaseNoteFragment { } } - protected abstract void colorWithText(@NonNull String newText, @Nullable Integer current, int mainColor, int textColor); + protected abstract void colorWithText(@NonNull String newText, @Nullable Integer current, @ColorInt int color); protected abstract Layout getLayout(); @@ -293,11 +285,10 @@ public abstract class SearchableBaseNoteFragment extends BaseNoteFragment { @CallSuper @Override - public void applyBrand(int mainColor, int textColor) { - this.mainColor = mainColor; - this.textColor = textColor; + public void applyBrand(int color) { + this.color = color; - final var util = BrandingUtil.of(mainColor, requireContext()); + final var util = BrandingUtil.of(color, requireContext()); util.material.themeFAB(getSearchNextButton()); util.material.themeFAB(getSearchPrevButton()); } diff --git a/app/src/main/java/it/niedermann/owncloud/notes/edit/category/CategoryDialogFragment.java b/app/src/main/java/it/niedermann/owncloud/notes/edit/category/CategoryDialogFragment.java index 97d9a4a1a..8e904556a 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/edit/category/CategoryDialogFragment.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/edit/category/CategoryDialogFragment.java @@ -48,8 +48,8 @@ public class CategoryDialogFragment extends BrandedDialogFragment { private LiveData> categoryLiveData; @Override - public void applyBrand(int mainColor, int textColor) { - final var util = BrandingUtil.of(mainColor, requireContext()); + public void applyBrand(int color) { + final var util = BrandingUtil.of(color, requireContext()); util.material.colorTextInputLayout(binding.inputWrapper); } diff --git a/app/src/main/java/it/niedermann/owncloud/notes/edit/title/EditTitleDialogFragment.java b/app/src/main/java/it/niedermann/owncloud/notes/edit/title/EditTitleDialogFragment.java index 0f1f644f9..d9b023fbe 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/edit/title/EditTitleDialogFragment.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/edit/title/EditTitleDialogFragment.java @@ -86,8 +86,8 @@ public class EditTitleDialogFragment extends BrandedDialogFragment { } @Override - public void applyBrand(int mainColor, int textColor) { - final var util = BrandingUtil.of(mainColor, requireContext()); + public void applyBrand(int color) { + final var util = BrandingUtil.of(color, requireContext()); util.material.colorTextInputLayout(binding.inputWrapper); } 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 906c95258..72ec0c268 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 @@ -33,7 +33,6 @@ import it.niedermann.owncloud.notes.persistence.ApiProvider; import it.niedermann.owncloud.notes.persistence.CapabilitiesClient; import it.niedermann.owncloud.notes.persistence.SyncWorker; 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 { @@ -107,7 +106,7 @@ public class ImportAccountActivity extends AppCompatActivity { public void onSuccess(Account account) { runOnUiThread(() -> { Log.i(TAG, capabilities.toString()); - BrandingUtil.saveBrandColors(ImportAccountActivity.this, capabilities.getColor(), capabilities.getTextColor()); + BrandingUtil.saveBrandColor(ImportAccountActivity.this, capabilities.getColor()); setResult(RESULT_OK); finish(); }); 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 1443a0c02..962c0eccb 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 @@ -24,6 +24,7 @@ import android.text.TextUtils; import android.util.Log; import android.view.View; +import androidx.annotation.ColorInt; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.ActionBarDrawerToggle; @@ -63,6 +64,7 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.stream.Collectors; +import it.niedermann.android.util.ColorUtil; import it.niedermann.owncloud.notes.LockedActivity; import it.niedermann.owncloud.notes.R; import it.niedermann.owncloud.notes.accountpicker.AccountPickerListener; @@ -590,22 +592,22 @@ public class MainActivity extends LockedActivity implements NoteClickListener, A } @Override - public void applyBrand(int mainColor, int textColor) { - final var util = BrandingUtil.of(mainColor, this); + public void applyBrand(int color) { + final var util = BrandingUtil.of(color, this); util.material.themeFAB(activityBinding.fabCreate); util.platform.colorCircularProgressBar(activityBinding.progressCircular); util.notes.applyBrandToPrimaryToolbar(activityBinding.appBar, activityBinding.searchToolbar, colorAccent); - binding.headerView.setBackgroundColor(mainColor); - binding.appName.setTextColor(textColor); + binding.headerView.setBackgroundColor(color); + @ColorInt final int headerTextColor = ColorUtil.INSTANCE.getForegroundColorForBackgroundColor(color); + binding.appName.setTextColor(headerTextColor); + DrawableCompat.setTint(binding.logo.getDrawable(), headerTextColor); // TODO We assume, that the background of the spinner is always white - activityBinding.swiperefreshlayout.setColorSchemeColors(contrastRatioIsSufficient(Color.WHITE, mainColor) ? mainColor : Color.BLACK); - binding.appName.setTextColor(textColor); - DrawableCompat.setTint(binding.logo.getDrawable(), textColor); + activityBinding.swiperefreshlayout.setColorSchemeColors(contrastRatioIsSufficient(Color.WHITE, color) ? color : Color.BLACK); - adapter.applyBrand(mainColor, textColor); - adapterCategories.applyBrand(mainColor, textColor); + adapter.applyBrand(color); + adapterCategories.applyBrand(color); invalidateOptionsMenu(); } 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 fd13bbb62..30e365e2d 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 @@ -120,7 +120,7 @@ public class MainViewModel extends AndroidViewModel { public void postCurrentAccount(@NonNull Account account) { state.set(KEY_CURRENT_ACCOUNT, account); - BrandingUtil.saveBrandColors(getApplication(), account.getColor(), account.getTextColor()); + BrandingUtil.saveBrandColor(getApplication(), account.getColor()); SingleAccountHelper.setCurrentAccount(getApplication(), account.getAccountName()); final var currentAccount = this.currentAccount.getValue(); @@ -410,10 +410,9 @@ public class MainViewModel extends AndroidViewModel { try { final var capabilities = CapabilitiesClient.getCapabilities(getApplication(), ssoAccount, localAccount.getCapabilitiesETag(), ApiProvider.getInstance()); repo.updateCapabilitiesETag(localAccount.getId(), capabilities.getETag()); - repo.updateBrand(localAccount.getId(), capabilities.getColor(), capabilities.getTextColor()); + repo.updateBrand(localAccount.getId(), capabilities.getColor()); localAccount.setColor(capabilities.getColor()); - localAccount.setTextColor(capabilities.getTextColor()); - BrandingUtil.saveBrandColors(getApplication(), localAccount.getColor(), localAccount.getTextColor()); + BrandingUtil.saveBrandColor(getApplication(), localAccount.getColor()); repo.updateApiVersion(localAccount.getId(), capabilities.getApiVersion()); callback.onSuccess(null); } catch (Throwable t) { diff --git a/app/src/main/java/it/niedermann/owncloud/notes/main/items/ItemAdapter.java b/app/src/main/java/it/niedermann/owncloud/notes/main/items/ItemAdapter.java index 7470fa257..769240420 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/main/items/ItemAdapter.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/main/items/ItemAdapter.java @@ -1,8 +1,6 @@ package it.niedermann.owncloud.notes.main.items; import android.content.Context; -import android.content.SharedPreferences; -import android.graphics.Color; import android.text.TextUtils; import android.view.LayoutInflater; import android.view.ViewGroup; @@ -59,17 +57,14 @@ public class ItemAdapter extends RecyclerView.Adapter i private final float fontSize; private final boolean monospace; @ColorInt - private int mainColor; - @ColorInt - private int textColor; + private int color; @Nullable private Integer swipedPosition; public ItemAdapter(@NonNull T context, boolean gridView) { this.noteClickListener = context; this.gridView = gridView; - this.mainColor = ContextCompat.getColor(context, R.color.defaultBrand); - this.textColor = Color.WHITE; + this.color = ContextCompat.getColor(context, R.color.defaultBrand); final var sp = PreferenceManager.getDefaultSharedPreferences(context.getApplicationContext()); this.fontSize = getFontSizeFromPreferences(context, sp); this.monospace = sp.getBoolean(context.getString(R.string.pref_key_font), false); @@ -156,7 +151,7 @@ public class ItemAdapter extends RecyclerView.Adapter i case TYPE_NOTE_WITH_EXCERPT: case TYPE_NOTE_WITHOUT_EXCERPT: case TYPE_NOTE_ONLY_TITLE: { - ((NoteViewHolder) holder).bind(isSelected, (Note) itemList.get(position), showCategory, mainColor, textColor, searchQuery); + ((NoteViewHolder) holder).bind(isSelected, (Note) itemList.get(position), showCategory, color, searchQuery); break; } } @@ -208,9 +203,8 @@ public class ItemAdapter extends RecyclerView.Adapter i } @Override - public void applyBrand(int mainColor, int textColor) { - this.mainColor = mainColor; - this.textColor = textColor; + public void applyBrand(int color) { + this.color = color; notifyDataSetChanged(); } diff --git a/app/src/main/java/it/niedermann/owncloud/notes/main/items/NoteViewHolder.java b/app/src/main/java/it/niedermann/owncloud/notes/main/items/NoteViewHolder.java index 6b5ab83c7..c7a0bf701 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/main/items/NoteViewHolder.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/main/items/NoteViewHolder.java @@ -49,7 +49,7 @@ public abstract class NoteViewHolder extends RecyclerView.ViewHolder { } @CallSuper - public void bind(boolean isSelected, @NonNull Note note, boolean showCategory, int mainColor, int textColor, @Nullable CharSequence searchQuery) { + public void bind(boolean isSelected, @NonNull Note note, boolean showCategory, @ColorInt int color, @Nullable CharSequence searchQuery) { itemView.setSelected(isSelected); itemView.setOnClickListener((view) -> noteClickListener.onNoteClick(getLayoutPosition(), view)); } diff --git a/app/src/main/java/it/niedermann/owncloud/notes/main/items/grid/NoteViewGridHolder.java b/app/src/main/java/it/niedermann/owncloud/notes/main/items/grid/NoteViewGridHolder.java index 7c4cecfe9..84d705e58 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/main/items/grid/NoteViewGridHolder.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/main/items/grid/NoteViewGridHolder.java @@ -6,6 +6,7 @@ import android.text.TextUtils; import android.util.TypedValue; import android.view.View; +import androidx.annotation.ColorInt; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.Px; @@ -39,14 +40,14 @@ public class NoteViewGridHolder extends NoteViewHolder { throw new UnsupportedOperationException(NoteViewGridHolder.class.getSimpleName() + " does not support swiping"); } - public void bind(boolean isSelected, @NonNull Note note, boolean showCategory, int mainColor, int textColor, @Nullable CharSequence searchQuery) { - super.bind(isSelected, note, showCategory, mainColor, textColor, searchQuery); + public void bind(boolean isSelected, @NonNull Note note, boolean showCategory, @ColorInt int color, @Nullable CharSequence searchQuery) { + super.bind(isSelected, note, showCategory, color, searchQuery); @NonNull final Context context = itemView.getContext(); - bindCategory(context, binding.noteCategory, showCategory, note.getCategory(), mainColor); - bindStatus(binding.noteStatus, note.getStatus(), mainColor); + bindCategory(context, binding.noteCategory, showCategory, note.getCategory(), color); + bindStatus(binding.noteStatus, note.getStatus(), color); bindFavorite(binding.noteFavorite, note.getFavorite()); - bindSearchableContent(context, binding.noteTitle, searchQuery, note.getTitle(), mainColor); - bindSearchableContent(context, binding.noteExcerpt, searchQuery, note.getExcerpt().replace(EXCERPT_LINE_SEPARATOR, "\n"), mainColor); + bindSearchableContent(context, binding.noteTitle, searchQuery, note.getTitle(), color); + bindSearchableContent(context, binding.noteExcerpt, searchQuery, note.getExcerpt().replace(EXCERPT_LINE_SEPARATOR, "\n"), color); binding.noteExcerpt.setVisibility(TextUtils.isEmpty(note.getExcerpt()) ? GONE : VISIBLE); } diff --git a/app/src/main/java/it/niedermann/owncloud/notes/main/items/grid/NoteViewGridHolderOnlyTitle.java b/app/src/main/java/it/niedermann/owncloud/notes/main/items/grid/NoteViewGridHolderOnlyTitle.java index 416d99d25..e6b6df499 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/main/items/grid/NoteViewGridHolderOnlyTitle.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/main/items/grid/NoteViewGridHolderOnlyTitle.java @@ -32,12 +32,12 @@ public class NoteViewGridHolderOnlyTitle extends NoteViewHolder { throw new UnsupportedOperationException(NoteViewGridHolderOnlyTitle.class.getSimpleName() + " does not support swiping"); } - public void bind(boolean isSelected, @NonNull Note note, boolean showCategory, int mainColor, int textColor, @Nullable CharSequence searchQuery) { - super.bind(isSelected, note, showCategory, mainColor, textColor, searchQuery); + public void bind(boolean isSelected, @NonNull Note note, boolean showCategory, int color, @Nullable CharSequence searchQuery) { + super.bind(isSelected, note, showCategory, color, searchQuery); @NonNull final Context context = itemView.getContext(); - bindStatus(binding.noteStatus, note.getStatus(), mainColor); + bindStatus(binding.noteStatus, note.getStatus(), color); bindFavorite(binding.noteFavorite, note.getFavorite()); - bindSearchableContent(context, binding.noteTitle, searchQuery, note.getTitle(), mainColor); + bindSearchableContent(context, binding.noteTitle, searchQuery, note.getTitle(), color); } @Nullable diff --git a/app/src/main/java/it/niedermann/owncloud/notes/main/items/list/NoteViewHolderWithExcerpt.java b/app/src/main/java/it/niedermann/owncloud/notes/main/items/list/NoteViewHolderWithExcerpt.java index c171a236a..ba6fc1d28 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/main/items/list/NoteViewHolderWithExcerpt.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/main/items/list/NoteViewHolderWithExcerpt.java @@ -3,6 +3,7 @@ package it.niedermann.owncloud.notes.main.items.list; import android.content.Context; import android.view.View; +import androidx.annotation.ColorInt; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -28,16 +29,16 @@ public class NoteViewHolderWithExcerpt extends NoteViewHolder { binding.noteSwipeFrame.setBackgroundResource(left ? R.color.bg_warning : R.color.bg_attention); } - public void bind(boolean isSelected, @NonNull Note note, boolean showCategory, int mainColor, int textColor, @Nullable CharSequence searchQuery) { - super.bind(isSelected, note, showCategory, mainColor, textColor, searchQuery); + public void bind(boolean isSelected, @NonNull Note note, boolean showCategory, @ColorInt int color, @Nullable CharSequence searchQuery) { + super.bind(isSelected, note, showCategory, color, searchQuery); @NonNull final var context = itemView.getContext(); binding.noteSwipeable.setAlpha(DBStatus.LOCAL_DELETED.equals(note.getStatus()) ? 0.5f : 1.0f); - bindCategory(context, binding.noteCategory, showCategory, note.getCategory(), mainColor); - bindStatus(binding.noteStatus, note.getStatus(), mainColor); + bindCategory(context, binding.noteCategory, showCategory, note.getCategory(), color); + bindStatus(binding.noteStatus, note.getStatus(), color); bindFavorite(binding.noteFavorite, note.getFavorite()); - bindSearchableContent(context, binding.noteTitle, searchQuery, note.getTitle(), mainColor); - bindSearchableContent(context, binding.noteExcerpt, searchQuery, note.getExcerpt(), mainColor); + bindSearchableContent(context, binding.noteTitle, searchQuery, note.getTitle(), color); + bindSearchableContent(context, binding.noteExcerpt, searchQuery, note.getExcerpt(), color); } @NonNull diff --git a/app/src/main/java/it/niedermann/owncloud/notes/main/items/list/NoteViewHolderWithoutExcerpt.java b/app/src/main/java/it/niedermann/owncloud/notes/main/items/list/NoteViewHolderWithoutExcerpt.java index 3ca136e49..84426dba0 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/main/items/list/NoteViewHolderWithoutExcerpt.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/main/items/list/NoteViewHolderWithoutExcerpt.java @@ -28,14 +28,14 @@ public class NoteViewHolderWithoutExcerpt extends NoteViewHolder { binding.noteSwipeFrame.setBackgroundResource(left ? R.color.bg_warning : R.color.bg_attention); } - public void bind(boolean isSelected, @NonNull Note note, boolean showCategory, int mainColor, int textColor, @Nullable CharSequence searchQuery) { - super.bind(isSelected, note, showCategory, mainColor, textColor, searchQuery); + public void bind(boolean isSelected, @NonNull Note note, boolean showCategory, int color, @Nullable CharSequence searchQuery) { + super.bind(isSelected, note, showCategory, color, searchQuery); @NonNull final Context context = itemView.getContext(); binding.noteSwipeable.setAlpha(DBStatus.LOCAL_DELETED.equals(note.getStatus()) ? 0.5f : 1.0f); - bindCategory(context, binding.noteCategory, showCategory, note.getCategory(), mainColor); - bindStatus(binding.noteStatus, note.getStatus(), mainColor); + bindCategory(context, binding.noteCategory, showCategory, note.getCategory(), color); + bindStatus(binding.noteStatus, note.getStatus(), color); bindFavorite(binding.noteFavorite, note.getFavorite()); - bindSearchableContent(context, binding.noteTitle, searchQuery, note.getTitle(), mainColor); + bindSearchableContent(context, binding.noteTitle, searchQuery, note.getTitle(), color); } @NonNull diff --git a/app/src/main/java/it/niedermann/owncloud/notes/main/menu/MenuViewHolder.java b/app/src/main/java/it/niedermann/owncloud/notes/main/menu/MenuViewHolder.java index d5a2f6088..416be4724 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/main/menu/MenuViewHolder.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/main/menu/MenuViewHolder.java @@ -24,7 +24,6 @@ public class MenuViewHolder extends RecyclerView.ViewHolder { public void bind(@NonNull MenuItem menuItem, @NonNull Consumer onClick) { @NonNull Context context = itemView.getContext(); binding.navigationItemLabel.setText(context.getString(menuItem.getLabelResource())); - binding.navigationItemLabel.setTextColor(binding.getRoot().getResources().getColor(R.color.fg_default)); binding.navigationItemIcon.setImageDrawable(ContextCompat.getDrawable(context, menuItem.getDrawableResource())); binding.navigationItemCount.setVisibility(GONE); binding.getRoot().setOnClickListener((v) -> onClick.accept(menuItem)); diff --git a/app/src/main/java/it/niedermann/owncloud/notes/main/navigation/NavigationAdapter.java b/app/src/main/java/it/niedermann/owncloud/notes/main/navigation/NavigationAdapter.java index 85cd3545c..bf6f3840e 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/main/navigation/NavigationAdapter.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/main/navigation/NavigationAdapter.java @@ -24,7 +24,7 @@ public class NavigationAdapter extends RecyclerView.Adapter countAccounts$(); - @Query("UPDATE Account SET COLOR = :color, TEXTCOLOR = :textColor WHERE id = :id") - void updateBrand(long id, @ColorInt Integer color, @ColorInt Integer textColor); + @Query("UPDATE Account SET COLOR = :color WHERE id = :id") + void updateBrand(long id, @ColorInt Integer color); @Query("UPDATE Account SET ETAG = :eTag WHERE ID = :id") void updateETag(long id, String eTag); diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/entity/Account.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/entity/Account.java index 016b2fd0c..24e5222d8 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/persistence/entity/Account.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/entity/Account.java @@ -77,7 +77,6 @@ public class Account implements Serializable { capabilitiesETag = capabilities.getETag(); apiVersion = capabilities.getApiVersion(); setColor(capabilities.getColor()); - setTextColor(capabilities.getTextColor()); } public long getId() { diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_23_24.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_23_24.java new file mode 100644 index 000000000..6aa892311 --- /dev/null +++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_23_24.java @@ -0,0 +1,28 @@ +package it.niedermann.owncloud.notes.persistence.migration; + +import android.content.Context; + +import androidx.annotation.NonNull; +import androidx.preference.PreferenceManager; +import androidx.room.migration.Migration; +import androidx.sqlite.db.SupportSQLiteDatabase; + +/** + * Remove textColor property from {@link android.content.SharedPreferences} and the + * database as it is no longer needed for theming. + */ +public class Migration_23_24 extends Migration { + + @NonNull + private final Context context; + + public Migration_23_24(@NonNull Context context) { + super(23, 24); + this.context = context; + } + + @Override + public void migrate(@NonNull SupportSQLiteDatabase db) { + PreferenceManager.getDefaultSharedPreferences(context).edit().remove("branding_text").apply(); + } +} diff --git a/app/src/main/java/it/niedermann/owncloud/notes/preferences/PreferencesActivity.java b/app/src/main/java/it/niedermann/owncloud/notes/preferences/PreferencesActivity.java index 99cc89e15..fb3cb8705 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/preferences/PreferencesActivity.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/preferences/PreferencesActivity.java @@ -32,8 +32,8 @@ public class PreferencesActivity extends LockedActivity { } @Override - public void applyBrand(int mainColor, int textColor) { - final var util = BrandingUtil.of(mainColor, this); + public void applyBrand(int color) { + final var util = BrandingUtil.of(color, this); util.notes.applyBrandToPrimaryToolbar(binding.appBar, binding.toolbar, colorAccent); } } diff --git a/app/src/main/java/it/niedermann/owncloud/notes/preferences/PreferencesFragment.java b/app/src/main/java/it/niedermann/owncloud/notes/preferences/PreferencesFragment.java index f2a252598..c3d532cbe 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/preferences/PreferencesFragment.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/preferences/PreferencesFragment.java @@ -115,27 +115,25 @@ public class PreferencesFragment extends PreferenceFragmentCompat implements Bra public void onStart() { super.onStart(); final var context = requireContext(); - @ColorInt final int mainColor = BrandingUtil.readBrandMainColor(context); - @ColorInt final int textColor = BrandingUtil.readBrandTextColor(context); - applyBrand(mainColor, textColor); + @ColorInt final int color = BrandingUtil.readBrandMainColor(context); + applyBrand(color); } /** * Change color for backgroundSyncPref as well * https://github.com/stefan-niedermann/nextcloud-deck/issues/531 * - * @param mainColor color of main brand - * @param textColor color of text + * @param color color of main brand */ @Override - public void applyBrand(int mainColor, int textColor) { - fontPref.applyBrand(mainColor, textColor); - lockPref.applyBrand(mainColor, textColor); - wifiOnlyPref.applyBrand(mainColor, textColor); - gridViewPref.applyBrand(mainColor, textColor); - preventScreenCapturePref.applyBrand(mainColor, textColor); - backgroundSyncPref.applyBrand(mainColor, textColor); - keepScreenOnPref.applyBrand(mainColor, textColor); + public void applyBrand(int color) { + fontPref.applyBrand(color); + lockPref.applyBrand(color); + wifiOnlyPref.applyBrand(color); + gridViewPref.applyBrand(color); + preventScreenCapturePref.applyBrand(color); + backgroundSyncPref.applyBrand(color); + keepScreenOnPref.applyBrand(color); } } diff --git a/app/src/main/java/it/niedermann/owncloud/notes/widget/notelist/NoteListWidgetConfigurationActivity.java b/app/src/main/java/it/niedermann/owncloud/notes/widget/notelist/NoteListWidgetConfigurationActivity.java index fb94f7d86..c3effacf5 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/widget/notelist/NoteListWidgetConfigurationActivity.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/widget/notelist/NoteListWidgetConfigurationActivity.java @@ -142,6 +142,7 @@ public class NoteListWidgetConfigurationActivity extends LockedActivity { } @Override - public void applyBrand(int mainColor, int textColor) { + public void applyBrand(int color) { + // Nothing to do... } } -- GitLab From a40704a73a0d990ac9b4d6f0d5a6569dd64b894b Mon Sep 17 00:00:00 2001 From: Stefan Niedermann Date: Sun, 12 Feb 2023 13:36:02 +0100 Subject: [PATCH 052/163] feat(theming): Theme NavigationView Signed-off-by: Stefan Niedermann --- .../owncloud/notes/branding/BrandingUtil.java | 5 +- .../notes/branding/NotesViewThemeUtils.java | 60 ++++++++++++++++++- .../owncloud/notes/main/MainActivity.java | 7 ++- .../owncloud/notes/main/menu/MenuAdapter.java | 14 ++++- .../notes/main/menu/MenuViewHolder.java | 14 ++++- .../main/navigation/NavigationAdapter.java | 14 ++--- .../main/navigation/NavigationViewHolder.java | 15 +++-- app/src/main/res/layout/drawer_layout.xml | 1 + 8 files changed, 108 insertions(+), 22 deletions(-) diff --git a/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandingUtil.java b/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandingUtil.java index ab447f83b..1e93f1348 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandingUtil.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandingUtil.java @@ -6,6 +6,7 @@ import android.util.Log; import androidx.annotation.ColorInt; import androidx.annotation.NonNull; import androidx.core.app.ActivityCompat; +import androidx.core.content.ContextCompat; import androidx.lifecycle.LiveData; import androidx.preference.PreferenceManager; @@ -57,14 +58,14 @@ public class BrandingUtil extends ViewThemeUtilsBase { public static LiveData readBrandMainColorLiveData(@NonNull Context context) { final var sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context.getApplicationContext()); Log.v(TAG, "--- Read: shared_preference_theme_main"); - return new SharedPreferenceIntLiveData(sharedPreferences, pref_key_branding_main, context.getApplicationContext().getResources().getColor(R.color.defaultBrand)); + return new SharedPreferenceIntLiveData(sharedPreferences, pref_key_branding_main, ContextCompat.getColor(context, R.color.defaultBrand)); } @ColorInt public static int readBrandMainColor(@NonNull Context context) { final var sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context.getApplicationContext()); Log.v(TAG, "--- Read: shared_preference_theme_main"); - return sharedPreferences.getInt(pref_key_branding_main, context.getApplicationContext().getResources().getColor(R.color.defaultBrand)); + return sharedPreferences.getInt(pref_key_branding_main, ContextCompat.getColor(context, R.color.defaultBrand)); } public static void saveBrandColor(@NonNull Context context, @ColorInt int color) { diff --git a/app/src/main/java/it/niedermann/owncloud/notes/branding/NotesViewThemeUtils.java b/app/src/main/java/it/niedermann/owncloud/notes/branding/NotesViewThemeUtils.java index 78cf0df6f..48c0551bb 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/branding/NotesViewThemeUtils.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/branding/NotesViewThemeUtils.java @@ -1,5 +1,6 @@ package it.niedermann.owncloud.notes.branding; +import static com.nextcloud.android.common.ui.util.ColorStateListUtilsKt.buildColorStateList; import static it.niedermann.owncloud.notes.NotesApplication.isDarkThemeActive; import android.content.Context; @@ -7,6 +8,9 @@ import android.graphics.Color; import android.graphics.PorterDuff; import android.graphics.drawable.LayerDrawable; import android.util.Log; +import android.view.View; +import android.widget.ImageView; +import android.widget.TextView; import androidx.annotation.ColorInt; import androidx.annotation.IdRes; @@ -16,20 +20,27 @@ import androidx.core.content.ContextCompat; import androidx.core.graphics.drawable.DrawableCompat; import com.google.android.material.appbar.AppBarLayout; +import com.google.android.material.appbar.MaterialToolbar; +import com.google.android.material.navigation.NavigationView; import com.nextcloud.android.common.ui.theme.MaterialSchemes; import com.nextcloud.android.common.ui.theme.ViewThemeUtilsBase; +import com.nextcloud.android.common.ui.theme.utils.MaterialViewThemeUtils; import it.niedermann.android.util.ColorUtil; import it.niedermann.owncloud.notes.R; +import it.niedermann.owncloud.notes.main.navigation.NavigationItem; import it.niedermann.owncloud.notes.shared.util.NotesColorUtil; +import kotlin.Pair; import scheme.Scheme; public class NotesViewThemeUtils extends ViewThemeUtilsBase { private static final String TAG = NotesViewThemeUtils.class.getSimpleName(); + private final MaterialSchemes schemes; public NotesViewThemeUtils(@NonNull MaterialSchemes schemes) { super(schemes); + this.schemes = schemes; } @ColorInt @@ -37,6 +48,51 @@ public class NotesViewThemeUtils extends ViewThemeUtilsBase { return withScheme(context, Scheme::getOnPrimaryContainer); } + /** + * The Notes app uses custom navigation view items because they have several features which are + * not covered by {@link NavigationItem}. + */ + public void colorNavigationViewItem(@NonNull View view) { + withScheme(view, scheme -> { + view.setBackgroundTintList(buildColorStateList( + new Pair<>(android.R.attr.state_selected, scheme.getSecondaryContainer()), + new Pair<>(-android.R.attr.state_selected, Color.TRANSPARENT) + )); + return view; + }); + } + + /** + * The Notes app uses custom navigation view items because they have several features which are + * not covered by {@link NavigationItem}. + */ + public void colorNavigationViewItemIcon(@NonNull ImageView view) { + withScheme(view, scheme -> { + view.setImageTintList(buildColorStateList( + new Pair<>(android.R.attr.state_selected, scheme.getOnSecondaryContainer()), + new Pair<>(-android.R.attr.state_selected, scheme.getOnSurfaceVariant()) + )); + return view; + }); + } + + /** + * The Notes app uses custom navigation view items because they have several features which are + * not covered by {@link NavigationItem}. + */ + public void colorNavigationViewItemText(@NonNull TextView view) { + withScheme(view, scheme -> { + view.setTextColor(buildColorStateList( + new Pair<>(android.R.attr.state_selected, scheme.getOnSecondaryContainer()), + new Pair<>(-android.R.attr.state_selected, scheme.getOnSurfaceVariant()) + )); + return view; + }); + } + + /** + * @deprecated should be replaced by {@link MaterialViewThemeUtils#themeToolbar(MaterialToolbar)}. + */ @Deprecated(forRemoval = true) public void applyBrandToPrimaryToolbar(@NonNull AppBarLayout appBarLayout, @NonNull Toolbar toolbar, @ColorInt int color) { // FIXME Workaround for https://github.com/nextcloud/notes-android/issues/889 @@ -55,7 +111,9 @@ public class NotesViewThemeUtils extends ViewThemeUtilsBase { } } - @Deprecated(forRemoval = true) + /** + * Colorizes only a specific part of a drawable + */ public void colorLayerDrawable(@NonNull LayerDrawable check, @IdRes int areaToColor, @ColorInt int mainColor) { final var drawable = check.findDrawableByLayerId(areaToColor); if (drawable == null) { 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 962c0eccb..97d497b56 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 @@ -122,6 +122,7 @@ public class MainActivity extends LockedActivity implements NoteClickListener, A protected ItemAdapter adapter; private NavigationAdapter adapterCategories; + @Nullable private MenuAdapter menuAdapter; private SelectionTracker tracker; @@ -351,7 +352,7 @@ public class MainActivity extends LockedActivity implements NoteClickListener, A } else { startActivityForResult(menuItem.getIntent(), resultCode); } - }); + }, nextAccount.getColor()); binding.navigationMenu.setAdapter(menuAdapter); } else { @@ -596,6 +597,7 @@ public class MainActivity extends LockedActivity implements NoteClickListener, A final var util = BrandingUtil.of(color, this); util.material.themeFAB(activityBinding.fabCreate); util.platform.colorCircularProgressBar(activityBinding.progressCircular); + util.platform.colorNavigationView(binding.navigationView); util.notes.applyBrandToPrimaryToolbar(activityBinding.appBar, activityBinding.searchToolbar, colorAccent); binding.headerView.setBackgroundColor(color); @@ -608,6 +610,9 @@ public class MainActivity extends LockedActivity implements NoteClickListener, A adapter.applyBrand(color); adapterCategories.applyBrand(color); + if (menuAdapter != null) { + menuAdapter.applyBrand(color); + } invalidateOptionsMenu(); } diff --git a/app/src/main/java/it/niedermann/owncloud/notes/main/menu/MenuAdapter.java b/app/src/main/java/it/niedermann/owncloud/notes/main/menu/MenuAdapter.java index 8112f7ec3..f920813d2 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/main/menu/MenuAdapter.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/main/menu/MenuAdapter.java @@ -7,6 +7,7 @@ import android.net.Uri; import android.view.LayoutInflater; import android.view.ViewGroup; +import androidx.annotation.ColorInt; import androidx.annotation.NonNull; import androidx.core.util.Consumer; import androidx.recyclerview.widget.RecyclerView; @@ -17,6 +18,7 @@ import com.nextcloud.android.sso.helper.VersionCheckHelper; import it.niedermann.owncloud.notes.FormattingHelpActivity; import it.niedermann.owncloud.notes.R; import it.niedermann.owncloud.notes.about.AboutActivity; +import it.niedermann.owncloud.notes.branding.BrandingUtil; import it.niedermann.owncloud.notes.databinding.ItemNavigationBinding; import it.niedermann.owncloud.notes.persistence.entity.Account; import it.niedermann.owncloud.notes.preferences.PreferencesActivity; @@ -25,10 +27,12 @@ public class MenuAdapter extends RecyclerView.Adapter { @NonNull private final MenuItem[] menuItems; + @ColorInt + private int color; @NonNull private final Consumer onClick; - public MenuAdapter(@NonNull Context context, @NonNull Account account, int settingsRequestCode, @NonNull Consumer onClick) { + public MenuAdapter(@NonNull Context context, @NonNull Account account, int settingsRequestCode, @NonNull Consumer onClick, @ColorInt int color) { this.menuItems = new MenuItem[]{ new MenuItem(new Intent(context, FormattingHelpActivity.class), R.string.action_formatting_help, R.drawable.ic_baseline_help_outline_24), new MenuItem(generateTrashbinIntent(context, account), R.string.action_trashbin, R.drawable.ic_delete_grey600_24dp), @@ -36,9 +40,15 @@ public class MenuAdapter extends RecyclerView.Adapter { new MenuItem(new Intent(context, AboutActivity.class), R.string.simple_about, R.drawable.ic_info_outline_grey600_24dp) }; this.onClick = onClick; + this.color = color; setHasStableIds(true); } + public void applyBrand(int color) { + this.color = color; + notifyDataSetChanged(); + } + @Override public long getItemId(int position) { return position; @@ -52,7 +62,7 @@ public class MenuAdapter extends RecyclerView.Adapter { @Override public void onBindViewHolder(@NonNull MenuViewHolder holder, int position) { - holder.bind(menuItems[position], onClick); + holder.bind(menuItems[position], color, onClick); } public void updateAccount(@NonNull Context context, @NonNull Account account) { diff --git a/app/src/main/java/it/niedermann/owncloud/notes/main/menu/MenuViewHolder.java b/app/src/main/java/it/niedermann/owncloud/notes/main/menu/MenuViewHolder.java index 416be4724..bc42a2b42 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/main/menu/MenuViewHolder.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/main/menu/MenuViewHolder.java @@ -2,12 +2,14 @@ package it.niedermann.owncloud.notes.main.menu; import android.content.Context; +import androidx.annotation.ColorInt; import androidx.annotation.NonNull; import androidx.core.content.ContextCompat; import androidx.core.util.Consumer; import androidx.recyclerview.widget.RecyclerView; import it.niedermann.owncloud.notes.R; +import it.niedermann.owncloud.notes.branding.BrandingUtil; import it.niedermann.owncloud.notes.databinding.ItemNavigationBinding; import static android.view.View.GONE; @@ -21,11 +23,19 @@ public class MenuViewHolder extends RecyclerView.ViewHolder { this.binding = binding; } - public void bind(@NonNull MenuItem menuItem, @NonNull Consumer onClick) { + public void bind(@NonNull MenuItem menuItem, @ColorInt int color, @NonNull Consumer onClick) { @NonNull Context context = itemView.getContext(); - binding.navigationItemLabel.setText(context.getString(menuItem.getLabelResource())); + binding.navigationItemIcon.setImageDrawable(ContextCompat.getDrawable(context, menuItem.getDrawableResource())); + binding.navigationItemLabel.setText(context.getString(menuItem.getLabelResource())); binding.navigationItemCount.setVisibility(GONE); binding.getRoot().setOnClickListener((v) -> onClick.accept(menuItem)); + + final var util = BrandingUtil.of(color, binding.getRoot().getContext()); + + util.notes.colorNavigationViewItem(binding.getRoot()); + util.notes.colorNavigationViewItemIcon(binding.navigationItemIcon); + util.notes.colorNavigationViewItemText(binding.navigationItemCount); + util.notes.colorNavigationViewItemText(binding.navigationItemLabel); } } diff --git a/app/src/main/java/it/niedermann/owncloud/notes/main/navigation/NavigationAdapter.java b/app/src/main/java/it/niedermann/owncloud/notes/main/navigation/NavigationAdapter.java index bf6f3840e..ee934dd37 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/main/navigation/NavigationAdapter.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/main/navigation/NavigationAdapter.java @@ -38,12 +38,6 @@ public class NavigationAdapter extends RecyclerView.Adapter items = new ArrayList<>(); private String selectedItem = null; @@ -52,11 +46,15 @@ public class NavigationAdapter extends RecyclerView.Adapter navigationClickListener.onItemClick(currentItem)); } - public void bind(@NonNull NavigationItem item, @ColorInt int mainColor, String selectedItem) { + public void bind(@NonNull NavigationItem item, @ColorInt int color, String selectedItem) { currentItem = item; final boolean isSelected = item.id.equals(selectedItem); name.setText(NoteUtil.extendCategory(item.label)); @@ -53,15 +54,17 @@ class NavigationViewHolder extends RecyclerView.ViewHolder { } else { icon.setVisibility(View.GONE); } - final int textColor = isSelected ? mainColor : view.getResources().getColor(R.color.fg_default); - name.setTextColor(textColor); - count.setTextColor(textColor); - icon.setColorFilter(isSelected ? textColor : 0); + final var util = BrandingUtil.of(color, itemView.getContext()); + + util.notes.colorNavigationViewItem(view); + util.notes.colorNavigationViewItemIcon(icon); + util.notes.colorNavigationViewItemText(name); + util.notes.colorNavigationViewItemText(count); view.setSelected(isSelected); - ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) view.getLayoutParams(); + final var params = (ViewGroup.MarginLayoutParams) view.getLayoutParams(); params.leftMargin = item.icon == NavigationAdapter.ICON_SUB_FOLDER || item.icon == NavigationAdapter.ICON_SUB_MULTIPLE ? view.getResources().getDimensionPixelSize(R.dimen.spacer_3x) : 0; diff --git a/app/src/main/res/layout/drawer_layout.xml b/app/src/main/res/layout/drawer_layout.xml index 0b868cec1..dc273cc57 100644 --- a/app/src/main/res/layout/drawer_layout.xml +++ b/app/src/main/res/layout/drawer_layout.xml @@ -14,6 +14,7 @@ android:layout_height="match_parent" /> Date: Sun, 12 Feb 2023 14:13:50 +0100 Subject: [PATCH 053/163] feat(theming): Get rid of custom theme checking... ... and rely on PlatformThemeUtil.isDarkMode in stead. Signed-off-by: Stefan Niedermann --- .../owncloud/notes/NotesApplication.java | 20 +------ .../notes/branding/NotesViewThemeUtils.java | 5 +- .../owncloud/notes/main/MainActivity.java | 5 +- .../notes/main/items/NoteViewHolder.java | 58 ++++++------------- 4 files changed, 25 insertions(+), 63 deletions(-) diff --git a/app/src/main/java/it/niedermann/owncloud/notes/NotesApplication.java b/app/src/main/java/it/niedermann/owncloud/notes/NotesApplication.java index 5c98201ec..b53a3b7bc 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/NotesApplication.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/NotesApplication.java @@ -1,9 +1,9 @@ package it.niedermann.owncloud.notes; +import static androidx.preference.PreferenceManager.getDefaultSharedPreferences; + import android.app.Application; import android.content.Context; -import android.content.SharedPreferences; -import android.content.res.Configuration; import android.util.Log; import androidx.appcompat.app.AppCompatDelegate; @@ -11,10 +11,6 @@ import androidx.preference.PreferenceManager; import it.niedermann.owncloud.notes.preferences.DarkModeSetting; -import static androidx.preference.PreferenceManager.getDefaultSharedPreferences; - -import com.nextcloud.android.common.ui.util.PlatformThemeUtil; - public class NotesApplication extends Application { private static final String TAG = NotesApplication.class.getSimpleName(); @@ -59,18 +55,6 @@ public class NotesApplication extends Application { return DarkModeSetting.valueOf(mode); } - public static boolean isDarkThemeActive(Context context, DarkModeSetting setting) { - if (setting == DarkModeSetting.SYSTEM_DEFAULT) { - return isDarkThemeActive(context); - } else { - return setting == DarkModeSetting.DARK; - } - } - - public static boolean isDarkThemeActive(Context context) { - return PlatformThemeUtil.isDarkMode(context); - } - public static void setLockedPreference(boolean lockedPreference) { Log.i(TAG, "New locked preference: " + lockedPreference); NotesApplication.lockedPreference = lockedPreference; diff --git a/app/src/main/java/it/niedermann/owncloud/notes/branding/NotesViewThemeUtils.java b/app/src/main/java/it/niedermann/owncloud/notes/branding/NotesViewThemeUtils.java index 48c0551bb..18faa5745 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/branding/NotesViewThemeUtils.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/branding/NotesViewThemeUtils.java @@ -1,7 +1,7 @@ package it.niedermann.owncloud.notes.branding; import static com.nextcloud.android.common.ui.util.ColorStateListUtilsKt.buildColorStateList; -import static it.niedermann.owncloud.notes.NotesApplication.isDarkThemeActive; +import static com.nextcloud.android.common.ui.util.PlatformThemeUtil.isDarkMode; import android.content.Context; import android.graphics.Color; @@ -21,7 +21,6 @@ import androidx.core.graphics.drawable.DrawableCompat; import com.google.android.material.appbar.AppBarLayout; import com.google.android.material.appbar.MaterialToolbar; -import com.google.android.material.navigation.NavigationView; import com.nextcloud.android.common.ui.theme.MaterialSchemes; import com.nextcloud.android.common.ui.theme.ViewThemeUtilsBase; import com.nextcloud.android.common.ui.theme.utils.MaterialViewThemeUtils; @@ -125,7 +124,7 @@ public class NotesViewThemeUtils extends ViewThemeUtilsBase { @ColorInt public int getTextHighlightBackgroundColor(@NonNull Context context, @ColorInt int mainColor, @ColorInt int colorPrimary, @ColorInt int colorAccent) { - if (isDarkThemeActive(context)) { // Dark background + if (isDarkMode(context)) { // Dark background if (ColorUtil.INSTANCE.isColorDark(mainColor)) { // Dark brand color if (NotesColorUtil.contrastRatioIsSufficient(mainColor, colorPrimary)) { // But also dark text return mainColor; 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 97d497b56..122505918 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 @@ -4,7 +4,7 @@ import static android.os.Build.VERSION.SDK_INT; import static android.os.Build.VERSION_CODES.O; import static android.view.View.GONE; import static android.view.View.VISIBLE; -import static it.niedermann.owncloud.notes.NotesApplication.isDarkThemeActive; +import static com.nextcloud.android.common.ui.util.PlatformThemeUtil.isDarkMode; import static it.niedermann.owncloud.notes.NotesApplication.isGridViewEnabled; import static it.niedermann.owncloud.notes.shared.model.ENavigationCategoryType.DEFAULT_CATEGORY; import static it.niedermann.owncloud.notes.shared.model.ENavigationCategoryType.FAVORITES; @@ -49,6 +49,7 @@ import com.bumptech.glide.request.RequestOptions; import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.floatingactionbutton.FloatingActionButton; import com.google.android.material.snackbar.Snackbar; +import com.nextcloud.android.common.ui.util.PlatformThemeUtil; import com.nextcloud.android.sso.AccountImporter; import com.nextcloud.android.sso.exceptions.AccountImportCancelledException; import com.nextcloud.android.sso.exceptions.NextcloudFilesAppAccountNotFoundException; @@ -159,7 +160,7 @@ public class MainActivity extends LockedActivity implements NoteClickListener, A gridView = isGridViewEnabled(); - if (!gridView || isDarkThemeActive(this)) { + if (!gridView || isDarkMode(this)) { activityBinding.activityNotesListView.setBackgroundColor(ContextCompat.getColor(this, R.color.primary)); } diff --git a/app/src/main/java/it/niedermann/owncloud/notes/main/items/NoteViewHolder.java b/app/src/main/java/it/niedermann/owncloud/notes/main/items/NoteViewHolder.java index c7a0bf701..5778a3993 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/main/items/NoteViewHolder.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/main/items/NoteViewHolder.java @@ -2,11 +2,10 @@ package it.niedermann.owncloud.notes.main.items; import static android.view.View.INVISIBLE; import static android.view.View.VISIBLE; -import static it.niedermann.owncloud.notes.shared.util.NotesColorUtil.contrastRatioIsSufficient; + +import static com.nextcloud.android.common.ui.util.PlatformThemeUtil.isDarkMode; import android.content.Context; -import android.content.res.ColorStateList; -import android.graphics.Color; import android.text.SpannableString; import android.text.TextUtils; import android.text.style.BackgroundColorSpan; @@ -26,12 +25,12 @@ import androidx.recyclerview.selection.ItemDetailsLookup; import androidx.recyclerview.widget.RecyclerView; import com.google.android.material.chip.Chip; +import com.nextcloud.android.common.ui.theme.utils.ColorRole; +import com.nextcloud.android.common.ui.util.PlatformThemeUtil; import java.util.regex.Matcher; import java.util.regex.Pattern; -import it.niedermann.android.util.ColorUtil; -import it.niedermann.owncloud.notes.NotesApplication; import it.niedermann.owncloud.notes.R; import it.niedermann.owncloud.notes.branding.BrandingUtil; import it.niedermann.owncloud.notes.persistence.entity.Note; @@ -60,47 +59,26 @@ public abstract class NoteViewHolder extends RecyclerView.ViewHolder { DrawableCompat.setTint(noteStatus.getDrawable(), BrandingUtil.of(mainColor, context).notes.getOnPrimaryContainer(context)); } - protected void bindCategory(@NonNull Context context, @NonNull TextView noteCategory, boolean showCategory, @NonNull String category, int mainColor) { - final boolean isDarkThemeActive = NotesApplication.isDarkThemeActive(context); - noteCategory.setVisibility(showCategory && !category.isEmpty() ? View.VISIBLE : View.GONE); - noteCategory.setText(category); + protected void bindCategory(@NonNull Context context, @NonNull TextView noteCategory, boolean showCategory, @NonNull String category, int color) { + if (!showCategory || category.isEmpty()) { + noteCategory.setVisibility(View.GONE); + } else { + noteCategory.setText(category); - @ColorInt final int categoryForeground; - @ColorInt final int categoryBackground; + final var util = BrandingUtil.of(color, context); - if (isDarkThemeActive) { - if (ColorUtil.INSTANCE.isColorDark(mainColor)) { - if (contrastRatioIsSufficient(mainColor, Color.BLACK)) { - categoryBackground = mainColor; - categoryForeground = Color.WHITE; + if (noteCategory instanceof Chip) { + util.material.colorChipBackground((Chip) noteCategory); + } else { + util.platform.tintDrawable(context, noteCategory.getBackground(), ColorRole.PRIMARY); + if (isDarkMode(context)) { + util.platform.colorTextView(noteCategory, ColorRole.ON_PRIMARY); } else { - categoryBackground = Color.WHITE; - categoryForeground = mainColor; + util.platform.colorTextView(noteCategory, ColorRole.ON_SECONDARY_CONTAINER); } - } else { - categoryBackground = mainColor; - categoryForeground = Color.BLACK; } - } else { - categoryForeground = Color.BLACK; - if (ColorUtil.INSTANCE.isColorDark(mainColor) || contrastRatioIsSufficient(mainColor, Color.WHITE)) { - categoryBackground = mainColor; - } else { - categoryBackground = Color.BLACK; - } - } - noteCategory.setTextColor(categoryForeground); - if (noteCategory instanceof Chip) { - final Chip chip = (Chip) noteCategory; - chip.setChipStrokeColor(ColorStateList.valueOf(categoryBackground)); - if(isDarkThemeActive) { - chip.setChipBackgroundColor(ColorStateList.valueOf(categoryBackground)); - } else { - chip.setChipBackgroundColorResource(R.color.grid_item_background_selector); - } - } else { - DrawableCompat.setTint(noteCategory.getBackground(), categoryBackground); + noteCategory.setVisibility(View.VISIBLE); } } -- GitLab From c78eab05be85cb11a6ec0ea601ef668ed1340127 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Feb 2023 14:15:36 +0000 Subject: [PATCH 054/163] Bump actions/setup-java from 3.9.0 to 3.10.0 Bumps [actions/setup-java](https://github.com/actions/setup-java) from 3.9.0 to 3.10.0. - [Release notes](https://github.com/actions/setup-java/releases) - [Commits](https://github.com/actions/setup-java/compare/1df8dbefe2a8cbc99770194893dd902763bee34b...3f07048e3d294f56e9b90ac5ea2c6f74e9ad0f98) --- updated-dependencies: - dependency-name: actions/setup-java dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/codeql.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 1608d962d..1ecdddbd2 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -36,7 +36,7 @@ jobs: with: languages: ${{ matrix.language }} - name: Set up JDK - uses: actions/setup-java@1df8dbefe2a8cbc99770194893dd902763bee34b # v3.9.0 + uses: actions/setup-java@3f07048e3d294f56e9b90ac5ea2c6f74e9ad0f98 # v3.10.0 with: distribution: "temurin" java-version: 11 -- GitLab From 3bbff6dc5b168d532d02bebfca84560d6ffa25ea Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Feb 2023 14:15:51 +0000 Subject: [PATCH 055/163] Bump github/codeql-action from 2.2.1 to 2.2.4 Bumps [github/codeql-action](https://github.com/github/codeql-action) from 2.2.1 to 2.2.4. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/3ebbd71c74ef574dbc558c82f70e52732c8b44fe...17573ee1cc1b9d061760f3a006fc4aac4f944fd5) --- updated-dependencies: - dependency-name: github/codeql-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/codeql.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 1608d962d..c90ccec10 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -32,7 +32,7 @@ jobs: with: swap-size-gb: 10 - name: Initialize CodeQL - uses: github/codeql-action/init@3ebbd71c74ef574dbc558c82f70e52732c8b44fe # v2.2.1 + uses: github/codeql-action/init@17573ee1cc1b9d061760f3a006fc4aac4f944fd5 # v2.2.4 with: languages: ${{ matrix.language }} - name: Set up JDK @@ -46,4 +46,4 @@ jobs: echo "org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError" > "$HOME/.gradle/gradle.properties" ./gradlew assembleDebug - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@3ebbd71c74ef574dbc558c82f70e52732c8b44fe # v2.2.1 + uses: github/codeql-action/analyze@17573ee1cc1b9d061760f3a006fc4aac4f944fd5 # v2.2.4 -- GitLab From 2a27df1d66fc162e562959565b8c51c4d79da5f5 Mon Sep 17 00:00:00 2001 From: nextcloud-android-bot Date: Tue, 14 Feb 2023 02:47:08 +0000 Subject: [PATCH 056/163] =?UTF-8?q?=F0=9F=94=84=20synced=20local=20'.githu?= =?UTF-8?q?b/workflows/'=20with=20remote=20'config/workflows/'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: nextcloud-android-bot --- .../workflows/gradle-wrapper-validation.yml | 18 +++++++++ .github/workflows/scorecard.yml | 38 +++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 .github/workflows/gradle-wrapper-validation.yml create mode 100644 .github/workflows/scorecard.yml diff --git a/.github/workflows/gradle-wrapper-validation.yml b/.github/workflows/gradle-wrapper-validation.yml new file mode 100644 index 000000000..df15a7542 --- /dev/null +++ b/.github/workflows/gradle-wrapper-validation.yml @@ -0,0 +1,18 @@ +# synced from @nextcloud/android-config +name: "Validate Gradle Wrapper" +on: + pull_request: + branches: [ master, stable-* ] + push: + branches: [ master, stable-* ] + +# Declare default permissions as read only. +permissions: read-all + +jobs: + validation: + name: "Validation" + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 + - uses: gradle/wrapper-validation-action@55e685c48d84285a5b0418cd094606e199cca3b6 # v1.0.5 diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml new file mode 100644 index 000000000..b9fb8d6d0 --- /dev/null +++ b/.github/workflows/scorecard.yml @@ -0,0 +1,38 @@ +# synced from @nextcloud/android-config +name: Scorecard supply-chain security +on: + branch_protection_rule: + schedule: + - cron: '32 23 * * 4' + push: + branches: [ "main", "master" ] + +# Declare default permissions as read only. +permissions: read-all + +jobs: + analysis: + name: Scorecard analysis + runs-on: ubuntu-latest + permissions: + # Needed to upload the results to code-scanning dashboard. + security-events: write + + steps: + - name: "Checkout code" + uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # v3.1.0 + with: + persist-credentials: false + + - name: "Run analysis" + uses: ossf/scorecard-action@99c53751e09b9529366343771cc321ec74e9bd3d # v2.0.6 + with: + results_file: results.sarif + results_format: sarif + publish_results: false + + # Upload the results to GitHub's code scanning dashboard. + - name: "Upload to code-scanning" + uses: github/codeql-action/upload-sarif@807578363a7869ca324a79039e6db9c843e0e100 # v2.1.27 + with: + sarif_file: results.sarif -- GitLab From d8aaba3a94ce4245371fd2286cb03bdc7be8b77a Mon Sep 17 00:00:00 2001 From: nextcloud-android-bot Date: Thu, 16 Feb 2023 02:46:32 +0000 Subject: [PATCH 057/163] =?UTF-8?q?=F0=9F=94=84=20synced=20local=20'.githu?= =?UTF-8?q?b/workflows/'=20with=20remote=20'config/workflows/'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: nextcloud-android-bot --- .github/workflows/scorecard.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index b9fb8d6d0..1a8aa0647 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -20,12 +20,12 @@ jobs: steps: - name: "Checkout code" - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # v3.1.0 + uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 with: persist-credentials: false - name: "Run analysis" - uses: ossf/scorecard-action@99c53751e09b9529366343771cc321ec74e9bd3d # v2.0.6 + uses: ossf/scorecard-action@e38b1902ae4f44df626f11ba0734b14fb91f8f86 # v2.1.2 with: results_file: results.sarif results_format: sarif @@ -33,6 +33,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@807578363a7869ca324a79039e6db9c843e0e100 # v2.1.27 + uses: github/codeql-action/upload-sarif@17573ee1cc1b9d061760f3a006fc4aac4f944fd5 # v2.2.4 with: sarif_file: results.sarif -- GitLab From 990a5b5a8085261826f9e4e2f6868eb3893f7a00 Mon Sep 17 00:00:00 2001 From: Stefan Niedermann Date: Thu, 16 Feb 2023 12:50:39 +0100 Subject: [PATCH 058/163] feat(theming): Resolve change requests * Only add the needed module rather than the entire lib * Use ColorRole where possible in favor of querying the wanted color from the Scheme directly * Use util for theming SwipeRefreshLayout Signed-off-by: Stefan Niedermann --- app/build.gradle | 2 +- .../owncloud/notes/branding/BrandedPreferenceCategory.java | 7 +++++-- .../owncloud/notes/branding/NotesViewThemeUtils.java | 7 +++++-- .../it/niedermann/owncloud/notes/main/MainActivity.java | 7 +++---- .../owncloud/notes/main/items/NoteViewHolder.java | 6 ++++-- 5 files changed, 18 insertions(+), 11 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 9bc16ed2d..473c4b1bf 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -76,7 +76,7 @@ dependencies { coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.2' // Nextcloud SSO - implementation 'com.github.nextcloud:android-common:0.4.0' + implementation 'com.github.nextcloud.android-common:ui:0.6.0' implementation 'com.github.nextcloud:Android-SingleSignOn:0.6.1' implementation 'com.github.stefan-niedermann:android-commons:0.2.9' implementation 'com.github.stefan-niedermann.nextcloud-commons:sso-glide:1.6.4' diff --git a/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandedPreferenceCategory.java b/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandedPreferenceCategory.java index f922a071b..3925bec48 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandedPreferenceCategory.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandedPreferenceCategory.java @@ -8,6 +8,8 @@ import androidx.annotation.Nullable; import androidx.preference.PreferenceCategory; import androidx.preference.PreferenceViewHolder; +import com.nextcloud.android.common.ui.theme.utils.ColorRole; + public class BrandedPreferenceCategory extends PreferenceCategory { public BrandedPreferenceCategory(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { @@ -33,8 +35,9 @@ public class BrandedPreferenceCategory extends PreferenceCategory { final var view = holder.itemView.findViewById(android.R.id.title); @Nullable final var context = getContext(); if (view instanceof TextView) { - final var util = BrandingUtil.of(BrandingUtil.readBrandMainColor(context), context);; - ((TextView) view).setTextColor(util.notes.getOnPrimaryContainer(context)); + final var util = BrandingUtil.of(BrandingUtil.readBrandMainColor(context), context); + + util.platform.colorTextView((TextView) view, ColorRole.ON_PRIMARY_CONTAINER); } } } diff --git a/app/src/main/java/it/niedermann/owncloud/notes/branding/NotesViewThemeUtils.java b/app/src/main/java/it/niedermann/owncloud/notes/branding/NotesViewThemeUtils.java index 18faa5745..65a1b53e0 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/branding/NotesViewThemeUtils.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/branding/NotesViewThemeUtils.java @@ -23,6 +23,7 @@ import com.google.android.material.appbar.AppBarLayout; import com.google.android.material.appbar.MaterialToolbar; import com.nextcloud.android.common.ui.theme.MaterialSchemes; import com.nextcloud.android.common.ui.theme.ViewThemeUtilsBase; +import com.nextcloud.android.common.ui.theme.utils.ColorRole; import com.nextcloud.android.common.ui.theme.utils.MaterialViewThemeUtils; import it.niedermann.android.util.ColorUtil; @@ -35,13 +36,15 @@ import scheme.Scheme; public class NotesViewThemeUtils extends ViewThemeUtilsBase { private static final String TAG = NotesViewThemeUtils.class.getSimpleName(); - private final MaterialSchemes schemes; public NotesViewThemeUtils(@NonNull MaterialSchemes schemes) { super(schemes); - this.schemes = schemes; } + /** + * Use {@link ColorRole#ON_PRIMARY_CONTAINER} + */ + @Deprecated(forRemoval = true) @ColorInt public int getOnPrimaryContainer(@NonNull Context context) { return withScheme(context, Scheme::getOnPrimaryContainer); 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 122505918..3ec92ffb5 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 @@ -49,6 +49,7 @@ import com.bumptech.glide.request.RequestOptions; import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.floatingactionbutton.FloatingActionButton; import com.google.android.material.snackbar.Snackbar; +import com.nextcloud.android.common.ui.theme.utils.ColorRole; import com.nextcloud.android.common.ui.util.PlatformThemeUtil; import com.nextcloud.android.sso.AccountImporter; import com.nextcloud.android.sso.exceptions.AccountImportCancelledException; @@ -597,7 +598,8 @@ public class MainActivity extends LockedActivity implements NoteClickListener, A public void applyBrand(int color) { final var util = BrandingUtil.of(color, this); util.material.themeFAB(activityBinding.fabCreate); - util.platform.colorCircularProgressBar(activityBinding.progressCircular); + util.androidx.themeSwipeRefreshLayout(activityBinding.swiperefreshlayout); + util.platform.colorCircularProgressBar(activityBinding.progressCircular, ColorRole.PRIMARY); util.platform.colorNavigationView(binding.navigationView); util.notes.applyBrandToPrimaryToolbar(activityBinding.appBar, activityBinding.searchToolbar, colorAccent); @@ -606,9 +608,6 @@ public class MainActivity extends LockedActivity implements NoteClickListener, A binding.appName.setTextColor(headerTextColor); DrawableCompat.setTint(binding.logo.getDrawable(), headerTextColor); - // TODO We assume, that the background of the spinner is always white - activityBinding.swiperefreshlayout.setColorSchemeColors(contrastRatioIsSufficient(Color.WHITE, color) ? color : Color.BLACK); - adapter.applyBrand(color); adapterCategories.applyBrand(color); if (menuAdapter != null) { diff --git a/app/src/main/java/it/niedermann/owncloud/notes/main/items/NoteViewHolder.java b/app/src/main/java/it/niedermann/owncloud/notes/main/items/NoteViewHolder.java index 5778a3993..bed7c0a56 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/main/items/NoteViewHolder.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/main/items/NoteViewHolder.java @@ -53,10 +53,12 @@ public abstract class NoteViewHolder extends RecyclerView.ViewHolder { itemView.setOnClickListener((view) -> noteClickListener.onNoteClick(getLayoutPosition(), view)); } - protected void bindStatus(AppCompatImageView noteStatus, DBStatus status, int mainColor) { + protected void bindStatus(AppCompatImageView noteStatus, DBStatus status, int color) { noteStatus.setVisibility(DBStatus.VOID.equals(status) ? INVISIBLE : VISIBLE); + final var context = noteStatus.getContext(); - DrawableCompat.setTint(noteStatus.getDrawable(), BrandingUtil.of(mainColor, context).notes.getOnPrimaryContainer(context)); + final var util = BrandingUtil.of(color, context); + util.platform.tintDrawable(context, noteStatus.getDrawable(), ColorRole.ON_PRIMARY_CONTAINER); } protected void bindCategory(@NonNull Context context, @NonNull TextView noteCategory, boolean showCategory, @NonNull String category, int color) { -- GitLab From 2558acd4bfa26f6f2468d359acde9e22212765ed Mon Sep 17 00:00:00 2001 From: Stefan Niedermann Date: Thu, 16 Feb 2023 13:08:07 +0100 Subject: [PATCH 059/163] feat(theming): Remove NotesViewThemeUtils#getOnPrimaryContainer in favor of AndroidViewThemeUtils#highlightText Signed-off-by: Stefan Niedermann --- .../notes/branding/NotesViewThemeUtils.java | 9 ------- .../notes/main/items/NoteViewHolder.java | 25 ++++--------------- 2 files changed, 5 insertions(+), 29 deletions(-) diff --git a/app/src/main/java/it/niedermann/owncloud/notes/branding/NotesViewThemeUtils.java b/app/src/main/java/it/niedermann/owncloud/notes/branding/NotesViewThemeUtils.java index 65a1b53e0..5c659afd9 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/branding/NotesViewThemeUtils.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/branding/NotesViewThemeUtils.java @@ -41,15 +41,6 @@ public class NotesViewThemeUtils extends ViewThemeUtilsBase { super(schemes); } - /** - * Use {@link ColorRole#ON_PRIMARY_CONTAINER} - */ - @Deprecated(forRemoval = true) - @ColorInt - public int getOnPrimaryContainer(@NonNull Context context) { - return withScheme(context, Scheme::getOnPrimaryContainer); - } - /** * The Notes app uses custom navigation view items because they have several features which are * not covered by {@link NavigationItem}. diff --git a/app/src/main/java/it/niedermann/owncloud/notes/main/items/NoteViewHolder.java b/app/src/main/java/it/niedermann/owncloud/notes/main/items/NoteViewHolder.java index bed7c0a56..4baf154d2 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/main/items/NoteViewHolder.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/main/items/NoteViewHolder.java @@ -89,28 +89,13 @@ public abstract class NoteViewHolder extends RecyclerView.ViewHolder { noteFavorite.setOnClickListener(view -> noteClickListener.onNoteFavoriteClick(getLayoutPosition(), view)); } - protected void bindSearchableContent(@NonNull Context context, @NonNull TextView textView, @Nullable CharSequence searchQuery, @NonNull String content, int mainColor) { - CharSequence processedContent = content; - if (!TextUtils.isEmpty(searchQuery)) { - final var util = BrandingUtil.of(mainColor, context); - @ColorInt final int searchForeground = util.notes.getOnPrimaryContainer(context); - @ColorInt final int searchBackground = ContextCompat.getColor(context, R.color.bg_highlighted); - - // The Pattern.quote method will add \Q to the very beginning of the string and \E to the end of the string - // It implies that the string between \Q and \E is a literal string and thus the reserved keyword in such string will be ignored. - // See https://stackoverflow.com/questions/15409296/what-is-the-use-of-pattern-quote-method - final Pattern pattern = Pattern.compile("(" + Pattern.quote(searchQuery.toString()) + ")", Pattern.CASE_INSENSITIVE); - SpannableString spannableString = new SpannableString(content); - Matcher matcher = pattern.matcher(spannableString); - - while (matcher.find()) { - spannableString.setSpan(new ForegroundColorSpan(searchForeground), matcher.start(), matcher.end(), 0); - spannableString.setSpan(new BackgroundColorSpan(searchBackground), matcher.start(), matcher.end(), 0); - } + protected void bindSearchableContent(@NonNull Context context, @NonNull TextView textView, @Nullable CharSequence searchQuery, @NonNull String content, int color) { + textView.setText(content); - processedContent = spannableString; + if (!TextUtils.isEmpty(searchQuery)) { + final var util = BrandingUtil.of(color, context); + util.platform.highlightText(textView, content, searchQuery.toString()); } - textView.setText(processedContent); } public abstract void showSwipe(boolean left); -- GitLab From ed8333af75565865133347e445b017e75c713352 Mon Sep 17 00:00:00 2001 From: nextcloud-android-bot Date: Tue, 21 Feb 2023 03:02:44 +0000 Subject: [PATCH 060/163] =?UTF-8?q?=F0=9F=94=84=20synced=20local=20'.githu?= =?UTF-8?q?b/workflows/'=20with=20remote=20'config/workflows/'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: nextcloud-android-bot --- .github/workflows/gradle-wrapper-validation.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gradle-wrapper-validation.yml b/.github/workflows/gradle-wrapper-validation.yml index df15a7542..c0bd4c8b1 100644 --- a/.github/workflows/gradle-wrapper-validation.yml +++ b/.github/workflows/gradle-wrapper-validation.yml @@ -15,4 +15,4 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 - - uses: gradle/wrapper-validation-action@55e685c48d84285a5b0418cd094606e199cca3b6 # v1.0.5 + - uses: gradle/wrapper-validation-action@8d49e559aae34d3e0eb16cde532684bc9702762b # v1.0.6 -- GitLab From d6e4980fec5e6f30013fbd10e98076a2a8f7da41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Brey?= Date: Thu, 23 Feb 2023 11:30:41 +0100 Subject: [PATCH 061/163] fix: Squished dialogs when opening keyboard programmatically MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Álvaro Brey --- .../edit/category/CategoryDialogFragment.java | 8 ++----- .../edit/title/EditTitleDialogFragment.java | 9 ++------ .../notes/shared/util/KeyboardUtils.kt | 23 +++++++++++++++++++ 3 files changed, 27 insertions(+), 13 deletions(-) create mode 100644 app/src/main/java/it/niedermann/owncloud/notes/shared/util/KeyboardUtils.kt diff --git a/app/src/main/java/it/niedermann/owncloud/notes/edit/category/CategoryDialogFragment.java b/app/src/main/java/it/niedermann/owncloud/notes/edit/category/CategoryDialogFragment.java index 8e904556a..b29f14cf8 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/edit/category/CategoryDialogFragment.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/edit/category/CategoryDialogFragment.java @@ -25,6 +25,7 @@ import it.niedermann.owncloud.notes.branding.BrandedDialogFragment; import it.niedermann.owncloud.notes.branding.BrandingUtil; import it.niedermann.owncloud.notes.databinding.DialogChangeCategoryBinding; import it.niedermann.owncloud.notes.main.navigation.NavigationItem; +import it.niedermann.owncloud.notes.shared.util.KeyboardUtils; /** * This {@link DialogFragment} allows for the selection of a category. @@ -170,12 +171,7 @@ public class CategoryDialogFragment extends BrandedDialogFragment { public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); if (editCategory.getText() == null || editCategory.getText().length() == 0) { - editCategory.requestFocus(); - if (getDialog() != null && getDialog().getWindow() != null) { - getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE); - } else { - Log.w(TAG, "can not set SOFT_INPUT_STATE_ALWAYAS_VISIBLE because getWindow() == null"); - } + KeyboardUtils.showKeyboardForEditText(editCategory); } } diff --git a/app/src/main/java/it/niedermann/owncloud/notes/edit/title/EditTitleDialogFragment.java b/app/src/main/java/it/niedermann/owncloud/notes/edit/title/EditTitleDialogFragment.java index d9b023fbe..b370f7982 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/edit/title/EditTitleDialogFragment.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/edit/title/EditTitleDialogFragment.java @@ -18,6 +18,7 @@ import it.niedermann.owncloud.notes.R; import it.niedermann.owncloud.notes.branding.BrandedDialogFragment; import it.niedermann.owncloud.notes.branding.BrandingUtil; import it.niedermann.owncloud.notes.databinding.DialogEditTitleBinding; +import it.niedermann.owncloud.notes.shared.util.KeyboardUtils; public class EditTitleDialogFragment extends BrandedDialogFragment { @@ -68,13 +69,7 @@ public class EditTitleDialogFragment extends BrandedDialogFragment { @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); - binding.title.requestFocus(); - final var window = requireDialog().getWindow(); - if (window != null) { - window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE); - } else { - Log.w(TAG, "can not enable soft keyboard because " + Window.class.getSimpleName() + " is null."); - } + KeyboardUtils.showKeyboardForEditText(binding.title); } public static DialogFragment newInstance(String title) { diff --git a/app/src/main/java/it/niedermann/owncloud/notes/shared/util/KeyboardUtils.kt b/app/src/main/java/it/niedermann/owncloud/notes/shared/util/KeyboardUtils.kt new file mode 100644 index 000000000..627dfe91b --- /dev/null +++ b/app/src/main/java/it/niedermann/owncloud/notes/shared/util/KeyboardUtils.kt @@ -0,0 +1,23 @@ +package it.niedermann.owncloud.notes.shared.util + +import android.content.Context +import android.view.inputmethod.InputMethodManager +import android.widget.EditText + +object KeyboardUtils { + private const val SHOW_INPUT_DELAY_MILLIS = 100L + + @JvmStatic + fun showKeyboardForEditText(editText: EditText) { + editText.requestFocus() + // needs 100ms delay to account for focus animations + editText.postDelayed({ + val context = editText.context + if (context != null) { + val inputMethodManager = + context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager + inputMethodManager.showSoftInput(editText, InputMethodManager.SHOW_IMPLICIT) + } + }, SHOW_INPUT_DELAY_MILLIS) + } +} -- GitLab From 7c381abf1744fda543103ab7bd598bb8e2d916da Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 24 Feb 2023 03:06:43 +0000 Subject: [PATCH 062/163] Bump androidx.arch.core:core-testing from 2.1.0 to 2.2.0 Bumps androidx.arch.core:core-testing from 2.1.0 to 2.2.0. --- updated-dependencies: - dependency-name: androidx.arch.core:core-testing dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 473c4b1bf..484b5bca8 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -117,7 +117,7 @@ dependencies { // Testing testImplementation 'androidx.test:core:1.5.0' - testImplementation 'androidx.arch.core:core-testing:2.1.0' + testImplementation 'androidx.arch.core:core-testing:2.2.0' testImplementation 'junit:junit:4.13.2' testImplementation 'org.mockito:mockito-core:5.1.1' testImplementation 'org.robolectric:robolectric:4.9.2' -- GitLab From e7bf3ffe989de1dfb592f8dfe15176cc662c7624 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 Feb 2023 03:31:13 +0000 Subject: [PATCH 063/163] Bump com.github.bumptech.glide:glide from 4.14.2 to 4.15.0 Bumps [com.github.bumptech.glide:glide](https://github.com/bumptech/glide) from 4.14.2 to 4.15.0. - [Release notes](https://github.com/bumptech/glide/releases) - [Commits](https://github.com/bumptech/glide/compare/v4.14.2...v4.15.0) --- updated-dependencies: - dependency-name: com.github.bumptech.glide:glide dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- app/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 484b5bca8..8aa1ae0cc 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -86,8 +86,8 @@ dependencies { } // Glide - implementation 'com.github.bumptech.glide:glide:4.14.2' - annotationProcessor 'com.github.bumptech.glide:compiler:4.14.2' + implementation 'com.github.bumptech.glide:glide:4.15.0' + annotationProcessor 'com.github.bumptech.glide:compiler:4.15.0' // Android X implementation 'androidx.appcompat:appcompat:1.6.1' -- GitLab From 270217037b66a9fd53c00c0b4c434137b1cc1e43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Brey?= Date: Mon, 27 Feb 2023 09:40:35 +0100 Subject: [PATCH 064/163] chore(build): Single constant for glide version MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Prevents duplicate dependabot PRs Signed-off-by: Álvaro Brey --- app/build.gradle | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 8aa1ae0cc..cf15cb573 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -69,6 +69,7 @@ android { } ext { + glideVersion = '4.15.0' roomVersion = "2.5.0" } @@ -86,8 +87,8 @@ dependencies { } // Glide - implementation 'com.github.bumptech.glide:glide:4.15.0' - annotationProcessor 'com.github.bumptech.glide:compiler:4.15.0' + implementation "com.github.bumptech.glide:glide:$glideVersion" + annotationProcessor "com.github.bumptech.glide:compiler:$glideVersion" // Android X implementation 'androidx.appcompat:appcompat:1.6.1' -- GitLab From 19ef732a3661fe63393a304a58612b64a3be4ae1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 Feb 2023 14:12:23 +0000 Subject: [PATCH 065/163] build(deps): Bump github/codeql-action from 2.2.4 to 2.2.5 Bumps [github/codeql-action](https://github.com/github/codeql-action) from 2.2.4 to 2.2.5. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/17573ee1cc1b9d061760f3a006fc4aac4f944fd5...32dc499307d133bb5085bae78498c0ac2cf762d5) --- updated-dependencies: - dependency-name: github/codeql-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/codeql.yml | 4 ++-- .github/workflows/scorecard.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 0cb0c8b72..7ad8c8a9e 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -32,7 +32,7 @@ jobs: with: swap-size-gb: 10 - name: Initialize CodeQL - uses: github/codeql-action/init@17573ee1cc1b9d061760f3a006fc4aac4f944fd5 # v2.2.4 + uses: github/codeql-action/init@32dc499307d133bb5085bae78498c0ac2cf762d5 # v2.2.5 with: languages: ${{ matrix.language }} - name: Set up JDK @@ -46,4 +46,4 @@ jobs: echo "org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError" > "$HOME/.gradle/gradle.properties" ./gradlew assembleDebug - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@17573ee1cc1b9d061760f3a006fc4aac4f944fd5 # v2.2.4 + uses: github/codeql-action/analyze@32dc499307d133bb5085bae78498c0ac2cf762d5 # v2.2.5 diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 1a8aa0647..280c9a709 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -33,6 +33,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@17573ee1cc1b9d061760f3a006fc4aac4f944fd5 # v2.2.4 + uses: github/codeql-action/upload-sarif@32dc499307d133bb5085bae78498c0ac2cf762d5 # v2.2.5 with: sarif_file: results.sarif -- GitLab From 14ce1b661dd199622e2e53f678c035becc703550 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 28 Feb 2023 03:07:04 +0000 Subject: [PATCH 066/163] build(deps): Bump com.android.tools.build:gradle from 7.4.1 to 7.4.2 Bumps com.android.tools.build:gradle from 7.4.1 to 7.4.2. --- updated-dependencies: - dependency-name: com.android.tools.build:gradle dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 89ae36e08..b30250eb7 100644 --- a/build.gradle +++ b/build.gradle @@ -9,7 +9,7 @@ buildscript { google() } dependencies { - classpath 'com.android.tools.build:gradle:7.4.1' + classpath 'com.android.tools.build:gradle:7.4.2' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion" // NOTE: Do not place your application dependencies here; they belong -- GitLab From a7406e3e7477cab29850f83e398c2b0fa7df44ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Brey?= Date: Wed, 1 Mar 2023 11:58:55 +0100 Subject: [PATCH 067/163] build: Revert kotlin version to 1.8.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1.8.10 not supported by CodeQL for now Signed-off-by: Álvaro Brey --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index b30250eb7..2493eece8 100644 --- a/build.gradle +++ b/build.gradle @@ -2,7 +2,7 @@ buildscript { ext { - kotlinVersion = '1.8.10' + kotlinVersion = '1.8.0' } repositories { mavenCentral() -- GitLab From 4e096b4bdfac20f5f7315e174a69b4a950250535 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Brey?= Date: Tue, 7 Mar 2023 16:20:48 +0100 Subject: [PATCH 068/163] Support direct editing for notes (#1686) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(capabilities): Fetch and store direct editing capability using existing capabilities code Signed-off-by: Álvaro Brey * feat: Implement direct editing repo Signed-off-by: Álvaro Brey * wip: Edit note with webview Signed-off-by: Álvaro Brey * wip: allow switching between the three note opening modes in preferences Signed-off-by: Álvaro Brey * EditNoteActivity: if no setting, use plain edit, not direct edit Required by UX team Signed-off-by: Álvaro Brey * feat: Add FAB to switch to rich editing mode from plain edit/preview Signed-off-by: Álvaro Brey * feat: add fab while direct editing to switch to normal editing Signed-off-by: Álvaro Brey * Fix toolbar when switching between direct edit and normal edit Signed-off-by: Álvaro Brey * wip: error and conflict handling when switching edit modes Signed-off-by: Álvaro Brey * Only show direct editing FAB if direct editing is available Signed-off-by: Álvaro Brey * EditNoteActivity: if pref is direct edit but it's not available, launch normal edit instead Signed-off-by: Álvaro Brey * Show error if direct editing not loaded after 10 seconds Signed-off-by: Álvaro Brey * Update user agent for Notes webview Signed-off-by: Álvaro Brey * Support opening new notes with direct editing Signed-off-by: Álvaro Brey * Allow invalid ssl certs for debug builds in webview Development only! Signed-off-by: Álvaro Brey * NoteDirectEdit: prevent duplicate note creation when creating it with direct edit remote id needs to be set Signed-off-by: Álvaro Brey * Fix create with plain edit -> direct edit flow Signed-off-by: Álvaro Brey --------- Signed-off-by: Álvaro Brey --- app/build.gradle | 1 + .../owncloud/notes/NotesApplication.java | 4 + .../owncloud/notes/edit/BaseNoteFragment.java | 27 +- .../owncloud/notes/edit/EditNoteActivity.java | 174 ++++++-- .../notes/edit/NoteDirectEditFragment.kt | 401 ++++++++++++++++++ .../owncloud/notes/edit/NoteEditFragment.java | 6 + .../notes/edit/NotePreviewFragment.java | 6 + .../edit/SearchableBaseNoteFragment.java | 56 ++- .../owncloud/notes/main/MainActivity.java | 3 - .../owncloud/notes/main/MainViewModel.java | 3 +- .../notes/persistence/ApiProvider.java | 13 + .../notes/persistence/CapabilitiesWorker.java | 1 + .../persistence/DirectEditingRepository.kt | 69 +++ .../notes/persistence/NotesDatabase.java | 22 +- .../notes/persistence/NotesRepository.java | 3 + .../notes/persistence/dao/AccountDao.java | 9 +- .../notes/persistence/entity/Account.java | 23 +- .../persistence/migration/Migration_24_25.kt | 13 + .../sync/CapabilitiesDeserializer.java | 17 + .../notes/persistence/sync/FilesAPI.kt | 18 + .../notes/shared/model/Capabilities.java | 16 +- .../owncloud/notes/shared/model/OcsUrl.kt | 9 + .../directediting/DirectEditingCreator.kt | 18 + .../directediting/DirectEditingEditor.kt | 19 + .../model/directediting/DirectEditingInfo.kt | 10 + .../directediting/DirectEditingRequestBody.kt | 12 + .../notes/shared/util/ExtendedFabUtil.kt | 65 +++ .../notes/shared/util/rx/DisposableSet.kt | 16 + app/src/main/res/drawable/ic_notes.xml | 11 + app/src/main/res/drawable/ic_rich_editing.xml | 24 ++ .../res/layout/fragment_note_direct_edit.xml | 41 ++ .../main/res/layout/fragment_note_edit.xml | 17 +- .../main/res/layout/fragment_note_preview.xml | 17 +- app/src/main/res/values/arrays.xml | 3 +- app/src/main/res/values/strings.xml | 21 +- app/src/main/res/xml/preferences.xml | 20 +- .../sync/CapabilitiesDeserializerTest.java | 66 ++- 37 files changed, 1156 insertions(+), 98 deletions(-) create mode 100644 app/src/main/java/it/niedermann/owncloud/notes/edit/NoteDirectEditFragment.kt create mode 100644 app/src/main/java/it/niedermann/owncloud/notes/persistence/DirectEditingRepository.kt create mode 100644 app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_24_25.kt create mode 100644 app/src/main/java/it/niedermann/owncloud/notes/persistence/sync/FilesAPI.kt create mode 100644 app/src/main/java/it/niedermann/owncloud/notes/shared/model/OcsUrl.kt create mode 100644 app/src/main/java/it/niedermann/owncloud/notes/shared/model/directediting/DirectEditingCreator.kt create mode 100644 app/src/main/java/it/niedermann/owncloud/notes/shared/model/directediting/DirectEditingEditor.kt create mode 100644 app/src/main/java/it/niedermann/owncloud/notes/shared/model/directediting/DirectEditingInfo.kt create mode 100644 app/src/main/java/it/niedermann/owncloud/notes/shared/model/directediting/DirectEditingRequestBody.kt create mode 100644 app/src/main/java/it/niedermann/owncloud/notes/shared/util/ExtendedFabUtil.kt create mode 100644 app/src/main/java/it/niedermann/owncloud/notes/shared/util/rx/DisposableSet.kt create mode 100644 app/src/main/res/drawable/ic_notes.xml create mode 100644 app/src/main/res/drawable/ic_rich_editing.xml create mode 100644 app/src/main/res/layout/fragment_note_direct_edit.xml diff --git a/app/build.gradle b/app/build.gradle index cf15cb573..578bdbaa9 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -115,6 +115,7 @@ dependencies { // ReactiveX implementation 'io.reactivex.rxjava2:rxjava:2.2.21' + implementation 'io.reactivex.rxjava2:rxandroid:2.1.1' // Testing testImplementation 'androidx.test:core:1.5.0' diff --git a/app/src/main/java/it/niedermann/owncloud/notes/NotesApplication.java b/app/src/main/java/it/niedermann/owncloud/notes/NotesApplication.java index b53a3b7bc..82cdf60f5 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/NotesApplication.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/NotesApplication.java @@ -5,6 +5,7 @@ import static androidx.preference.PreferenceManager.getDefaultSharedPreferences; import android.app.Application; import android.content.Context; import android.util.Log; +import android.webkit.WebView; import androidx.appcompat.app.AppCompatDelegate; import androidx.preference.PreferenceManager; @@ -29,6 +30,9 @@ public class NotesApplication extends Application { lockedPreference = prefs.getBoolean(getString(R.string.pref_key_lock), false); isGridViewEnabled = getDefaultSharedPreferences(this).getBoolean(getString(R.string.pref_key_gridview), false); super.onCreate(); + if (BuildConfig.DEBUG) { + WebView.setWebContentsDebuggingEnabled(true); + } } public static void setAppTheme(DarkModeSetting setting) { diff --git a/app/src/main/java/it/niedermann/owncloud/notes/edit/BaseNoteFragment.java b/app/src/main/java/it/niedermann/owncloud/notes/edit/BaseNoteFragment.java index 4d969382a..162454336 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/edit/BaseNoteFragment.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/edit/BaseNoteFragment.java @@ -71,7 +71,8 @@ public abstract class BaseNoteFragment extends BrandedFragment implements Catego private Note originalNote; private int originalScrollY; protected NotesRepository repo; - private NoteFragmentListener listener; + @Nullable + protected NoteFragmentListener listener; private boolean titleModified = false; protected boolean isNew = true; @@ -143,6 +144,7 @@ public abstract class BaseNoteFragment extends BrandedFragment implements Catego @Nullable protected abstract ScrollView getScrollView(); + protected abstract void scrollToY(int scrollY); @Override @@ -240,7 +242,7 @@ public abstract class BaseNoteFragment extends BrandedFragment implements Catego .show(requireActivity().getSupportFragmentManager(), BaseNoteFragment.class.getSimpleName())); return true; } else if (itemId == R.id.menu_share) { - ShareUtil.openShareDialog(requireContext(), note.getTitle(), note.getContent()); + shareNote(); return false; } else if (itemId == MENU_ID_PIN) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { @@ -263,6 +265,10 @@ public abstract class BaseNoteFragment extends BrandedFragment implements Catego return super.onOptionsItemSelected(item); } + protected void shareNote() { + ShareUtil.openShareDialog(requireContext(), note.getTitle(), note.getContent()); + } + @CallSuper protected void onNoteLoaded(Note note) { this.originalScrollY = note.getScrollY(); @@ -273,10 +279,21 @@ public abstract class BaseNoteFragment extends BrandedFragment implements Catego if (scrollY > 0) { note.setScrollY(scrollY); } + onScroll(scrollY, oldScrollY); }); } } + /** + * Scroll callback, to be overridden by subclasses. Default implementation is empty + */ + protected void onScroll(int scrollY, int oldScrollY) { + } + + protected boolean shouldShowToolbar() { + return true; + } + public void onCloseNote() { if (!titleModified && originalNote == null && getContent().isEmpty()) { repo.deleteNoteAndSync(localAccount, note.getId()); @@ -367,8 +384,14 @@ public abstract class BaseNoteFragment extends BrandedFragment implements Catego } public interface NoteFragmentListener { + enum Mode { + EDIT, PREVIEW, DIRECT_EDIT + } + void close(); void onNoteUpdated(Note note); + + void changeMode(@NonNull Mode mode, boolean reloadNote); } } diff --git a/app/src/main/java/it/niedermann/owncloud/notes/edit/EditNoteActivity.java b/app/src/main/java/it/niedermann/owncloud/notes/edit/EditNoteActivity.java index 0fbc0bbf8..d5306d8ac 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/edit/EditNoteActivity.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/edit/EditNoteActivity.java @@ -8,10 +8,12 @@ import android.text.TextUtils; import android.util.Log; import android.view.Menu; import android.view.MenuItem; +import android.view.View; import android.view.WindowManager; import android.widget.Toast; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; import androidx.lifecycle.ViewModelProvider; import androidx.preference.PreferenceManager; @@ -19,6 +21,7 @@ import androidx.preference.PreferenceManager; import com.nextcloud.android.sso.exceptions.NextcloudFilesAppAccountNotFoundException; import com.nextcloud.android.sso.exceptions.NoCurrentAccountSelectedException; import com.nextcloud.android.sso.helper.SingleAccountHelper; +import com.nextcloud.android.sso.model.SingleSignOnAccount; import java.io.BufferedReader; import java.io.IOException; @@ -34,6 +37,7 @@ import it.niedermann.owncloud.notes.branding.BrandingUtil; import it.niedermann.owncloud.notes.databinding.ActivityEditBinding; import it.niedermann.owncloud.notes.edit.category.CategoryViewModel; import it.niedermann.owncloud.notes.main.MainActivity; +import it.niedermann.owncloud.notes.persistence.NotesRepository; import it.niedermann.owncloud.notes.persistence.entity.Account; import it.niedermann.owncloud.notes.persistence.entity.Note; import it.niedermann.owncloud.notes.shared.model.NavigationCategory; @@ -57,11 +61,14 @@ public class EditNoteActivity extends LockedActivity implements BaseNoteFragment private ActivityEditBinding binding; private BaseNoteFragment fragment; + private NotesRepository repo; @Override protected void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); + repo = NotesRepository.getInstance(getApplicationContext()); + try { if (SingleAccountHelper.getCurrentSingleSignOnAccount(this) == null) { throw new NoCurrentAccountSelectedException(); @@ -118,9 +125,20 @@ public class EditNoteActivity extends LockedActivity implements BaseNoteFragment } private long getAccountId() { - return getIntent().getLongExtra(PARAM_ACCOUNT_ID, 0); + final long idParam = getIntent().getLongExtra(PARAM_ACCOUNT_ID, 0); + if (idParam == 0) { + try { + final SingleSignOnAccount ssoAcc = SingleAccountHelper.getCurrentSingleSignOnAccount(this); + return repo.getAccountByName(ssoAcc.name).getId(); + } catch (NextcloudFilesAppAccountNotFoundException | + NoCurrentAccountSelectedException e) { + Log.w(TAG, "getAccountId: no current account", e); + } + } + return idParam; } + /** * Starts the note fragment for an existing note or a new note. * The actual behavior is triggered by the activity's intent. @@ -145,44 +163,109 @@ public class EditNoteActivity extends LockedActivity implements BaseNoteFragment * @param noteId ID of the existing note. */ private void launchExistingNote(long accountId, long noteId) { - final var prefKeyNoteMode = getString(R.string.pref_key_note_mode); - final var prefKeyLastMode = getString(R.string.pref_key_last_note_mode); - final var prefValueEdit = getString(R.string.pref_value_mode_edit); - final var prefValuePreview = getString(R.string.pref_value_mode_preview); - final var prefValueLast = getString(R.string.pref_value_mode_last); + launchExistingNote(accountId, noteId, null); + } - final var preferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); - final String mode = preferences.getString(prefKeyNoteMode, prefValueEdit); - final String lastMode = preferences.getString(prefKeyLastMode, prefValueEdit); - boolean editMode = true; - if (prefValuePreview.equals(mode) || (prefValueLast.equals(mode) && prefValuePreview.equals(lastMode))) { - editMode = false; - } - launchExistingNote(accountId, noteId, editMode); + private void launchExistingNote(long accountId, long noteId, @Nullable final String mode) { + launchExistingNote(accountId, noteId, mode, false); } /** * Starts a {@link NoteEditFragment} or {@link NotePreviewFragment} for an existing note. * - * @param noteId ID of the existing note. - * @param edit View-mode of the fragment: - * true for {@link NoteEditFragment}, - * false for {@link NotePreviewFragment}. + * @param noteId ID of the existing note. + * @param mode View-mode of the fragment (pref value or null). If null will be chosen based on + * user preferences. + * @param discardState If true, the state of the fragment will be discarded and a new fragment will be created */ - private void launchExistingNote(long accountId, long noteId, boolean edit) { + private void launchExistingNote(long accountId, long noteId, @Nullable final String mode, final boolean discardState) { // save state of the fragment in order to resume with the same note and originalNote - Fragment.SavedState savedState = null; - if (fragment != null) { - savedState = getSupportFragmentManager().saveFragmentInstanceState(fragment); + runOnUiThread(() -> { + Fragment.SavedState savedState = null; + if (fragment != null && !discardState) { + savedState = getSupportFragmentManager().saveFragmentInstanceState(fragment); + } + fragment = getNoteFragment(accountId, noteId, mode); + if (savedState != null) { + fragment.setInitialSavedState(savedState); + } + replaceFragment(); + }); + } + + private void replaceFragment() { + getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container_view, fragment).commit(); + if (!fragment.shouldShowToolbar()) { + binding.toolbar.setVisibility(View.GONE); + } else { + binding.toolbar.setVisibility(View.VISIBLE); } - fragment = edit - ? NoteEditFragment.newInstance(accountId, noteId) - : NotePreviewFragment.newInstance(accountId, noteId); + } + + + /** + * Returns the preferred mode for the account. If the mode is "remember last" the last mode is returned. + * If the mode is "direct edit" and the account does not support direct edit, the default mode is returned. + */ + private String getPreferenceMode(long accountId) { + + final var prefKeyNoteMode = getString(R.string.pref_key_note_mode); + final var prefKeyLastMode = getString(R.string.pref_key_last_note_mode); + final var defaultMode = getString(R.string.pref_value_mode_edit); + final var prefValueLast = getString(R.string.pref_value_mode_last); + final var prefValueDirectEdit = getString(R.string.pref_value_mode_direct_edit); - if (savedState != null) { - fragment.setInitialSavedState(savedState); + + final var preferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); + final String modePreference = preferences.getString(prefKeyNoteMode, defaultMode); + + String effectiveMode = modePreference; + if (modePreference.equals(prefValueLast)) { + effectiveMode = preferences.getString(prefKeyLastMode, defaultMode); + } + + if (effectiveMode.equals(prefValueDirectEdit)) { + final Account accountById = repo.getAccountById(accountId); + final var directEditAvailable = accountById != null && accountById.isDirectEditingAvailable(); + if (!directEditAvailable) { + effectiveMode = defaultMode; + } + } + + return effectiveMode; + } + + private BaseNoteFragment getNoteFragment(long accountId, long noteId, final @Nullable String modePref) { + + final var effectiveMode = modePref == null ? getPreferenceMode(accountId) : modePref; + + final var prefValueEdit = getString(R.string.pref_value_mode_edit); + final var prefValueDirectEdit = getString(R.string.pref_value_mode_direct_edit); + final var prefValuePreview = getString(R.string.pref_value_mode_preview); + + if (effectiveMode.equals(prefValueEdit)) { + return NoteEditFragment.newInstance(accountId, noteId); + } else if (effectiveMode.equals(prefValueDirectEdit)) { + return NoteDirectEditFragment.newInstance(accountId, noteId); + } else if (effectiveMode.equals(prefValuePreview)) { + return NotePreviewFragment.newInstance(accountId, noteId); + } else { + throw new IllegalStateException("Unknown note modePref: " + modePref); + } + } + + + @NonNull + private BaseNoteFragment getNewNoteFragment(Note newNote) { + final var mode = getPreferenceMode(getAccountId()); + + final var prefValueDirectEdit = getString(R.string.pref_value_mode_direct_edit); + + if (mode.equals(prefValueDirectEdit)) { + return NoteDirectEditFragment.newInstanceWithNewNote(newNote); + } else { + return NoteEditFragment.newInstanceWithNewNote(newNote); } - getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container_view, fragment).commit(); } /** @@ -219,10 +302,11 @@ public class EditNoteActivity extends LockedActivity implements BaseNoteFragment content = ""; } final var newNote = new Note(null, Calendar.getInstance(), NoteUtil.generateNonEmptyNoteTitle(content, this), content, categoryTitle, favorite, null); - fragment = NoteEditFragment.newInstanceWithNewNote(newNote); - getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container_view, fragment).commit(); + fragment = getNewNoteFragment(newNote); + replaceFragment(); } + private void launchReadonlyNote() { final var intent = getIntent(); final var content = new StringBuilder(); @@ -238,7 +322,7 @@ public class EditNoteActivity extends LockedActivity implements BaseNoteFragment } fragment = NoteReadonlyFragment.newInstance(content.toString()); - getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container_view, fragment).commit(); + replaceFragment(); } @Override @@ -260,10 +344,10 @@ public class EditNoteActivity extends LockedActivity implements BaseNoteFragment close(); return true; } else if (itemId == R.id.menu_preview) { - launchExistingNote(getAccountId(), getNoteId(), false); + changeMode(Mode.PREVIEW, false); return true; } else if (itemId == R.id.menu_edit) { - launchExistingNote(getAccountId(), getNoteId(), true); + changeMode(Mode.EDIT, false); return true; } return super.onOptionsItemSelected(item); @@ -281,8 +365,10 @@ public class EditNoteActivity extends LockedActivity implements BaseNoteFragment final String prefKeyLastMode = getString(R.string.pref_key_last_note_mode); if (fragment instanceof NoteEditFragment) { preferences.edit().putString(prefKeyLastMode, getString(R.string.pref_value_mode_edit)).apply(); - } else { + } else if (fragment instanceof NotePreviewFragment) { preferences.edit().putString(prefKeyLastMode, getString(R.string.pref_value_mode_preview)).apply(); + } else if (fragment instanceof NoteDirectEditFragment) { + preferences.edit().putString(prefKeyLastMode, getString(R.string.pref_value_mode_direct_edit)).apply(); } fragment.onCloseNote(); @@ -308,6 +394,24 @@ public class EditNoteActivity extends LockedActivity implements BaseNoteFragment } } + @Override + public void changeMode(@NonNull Mode mode, boolean reloadNote) { + switch (mode) { + case EDIT: + launchExistingNote(getAccountId(), getNoteId(), getString(R.string.pref_value_mode_edit), reloadNote); + break; + case PREVIEW: + launchExistingNote(getAccountId(), getNoteId(), getString(R.string.pref_value_mode_preview), reloadNote); + break; + case DIRECT_EDIT: + launchExistingNote(getAccountId(), getNoteId(), getString(R.string.pref_value_mode_direct_edit), reloadNote); + break; + default: + throw new IllegalStateException("Unknown mode: " + mode); + } + } + + @Override public void onAccountPicked(@NonNull Account account) { fragment.moveNote(account); @@ -318,4 +422,4 @@ public class EditNoteActivity extends LockedActivity implements BaseNoteFragment final var util = BrandingUtil.of(color, this); util.notes.applyBrandToPrimaryToolbar(binding.appBar, binding.toolbar, colorAccent); } -} \ No newline at end of file +} diff --git a/app/src/main/java/it/niedermann/owncloud/notes/edit/NoteDirectEditFragment.kt b/app/src/main/java/it/niedermann/owncloud/notes/edit/NoteDirectEditFragment.kt new file mode 100644 index 000000000..0c9b9772f --- /dev/null +++ b/app/src/main/java/it/niedermann/owncloud/notes/edit/NoteDirectEditFragment.kt @@ -0,0 +1,401 @@ +package it.niedermann.owncloud.notes.edit + +import android.annotation.SuppressLint +import android.net.http.SslError +import android.os.Bundle +import android.util.Log +import android.view.LayoutInflater +import android.view.MotionEvent +import android.view.View +import android.view.ViewGroup +import android.webkit.JavascriptInterface +import android.webkit.SslErrorHandler +import android.webkit.WebResourceError +import android.webkit.WebResourceRequest +import android.webkit.WebSettings +import android.webkit.WebView +import android.webkit.WebViewClient +import android.widget.ScrollView +import androidx.core.view.isVisible +import com.google.android.material.snackbar.Snackbar +import com.nextcloud.android.common.ui.theme.utils.ColorRole +import com.nextcloud.android.sso.helper.SingleAccountHelper +import com.nextcloud.android.sso.model.SingleSignOnAccount +import io.reactivex.Single +import io.reactivex.android.schedulers.AndroidSchedulers +import io.reactivex.schedulers.Schedulers +import it.niedermann.owncloud.notes.BuildConfig +import it.niedermann.owncloud.notes.R +import it.niedermann.owncloud.notes.branding.Branded +import it.niedermann.owncloud.notes.branding.BrandedSnackbar +import it.niedermann.owncloud.notes.branding.BrandingUtil +import it.niedermann.owncloud.notes.databinding.FragmentNoteDirectEditBinding +import it.niedermann.owncloud.notes.persistence.ApiProvider +import it.niedermann.owncloud.notes.persistence.DirectEditingRepository +import it.niedermann.owncloud.notes.persistence.entity.Note +import it.niedermann.owncloud.notes.persistence.sync.NotesAPI +import it.niedermann.owncloud.notes.shared.model.ApiVersion +import it.niedermann.owncloud.notes.shared.model.ISyncCallback +import it.niedermann.owncloud.notes.shared.util.ExtendedFabUtil +import it.niedermann.owncloud.notes.shared.util.rx.DisposableSet +import java.util.concurrent.TimeUnit + +class NoteDirectEditFragment : BaseNoteFragment(), Branded { + private var _binding: FragmentNoteDirectEditBinding? = null + private val binding: FragmentNoteDirectEditBinding + get() = _binding!! + + private val disposables: DisposableSet = DisposableSet() + private var switchToEditPending = false + + val account: SingleSignOnAccount by lazy { + SingleAccountHelper.getCurrentSingleSignOnAccount( + requireContext(), + ) + } + + val notesApi: NotesAPI by lazy { + ApiProvider.getInstance().getNotesAPI(requireContext(), account, ApiVersion.API_VERSION_1_0) + } + + // for hiding / showing the fab + private var scrollStart: Int = 0 + + public override fun getScrollView(): ScrollView? { + return null + } + + override fun scrollToY(y: Int) { + // do nothing + } + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle?, + ): View { + Log.d(TAG, "onCreateView() called") + _binding = FragmentNoteDirectEditBinding.inflate(inflater, container, false) + setupFab() + prepareWebView() + return binding.root + } + + @SuppressLint("ClickableViewAccessibility") // touch listener only for UI purposes, no need to handle click + private fun setupFab() { + binding.plainEditingFab.isExtended = false + ExtendedFabUtil.toggleExtendedOnLongClick(binding.plainEditingFab) + // manually detect scroll as we can't get it from the webview (maybe with custom JS?) + binding.noteWebview.setOnTouchListener { _, event -> + when (event.action) { + MotionEvent.ACTION_DOWN -> { + scrollStart = event.y.toInt() + } + MotionEvent.ACTION_UP -> { + val scrollEnd = event.y.toInt() + ExtendedFabUtil.toggleVisibilityOnScroll( + binding.plainEditingFab, + scrollStart, + scrollEnd, + ) + } + } + return@setOnTouchListener false + } + binding.plainEditingFab.setOnClickListener { switchToPlainEdit() } + } + + private fun switchToPlainEdit() { + switchToEditPending = true + binding.noteWebview.evaluateJavascript(JS_CLOSE) { result -> + val resultWithoutQuotes = result.replace("\"", "") + if (resultWithoutQuotes != JS_RESULT_OK) { + Log.w(TAG, "Closing via JS failed: $resultWithoutQuotes") + changeToEditMode() + } + // if result is OK, switch will be handled by JS interface callback + } + } + + override fun onDestroyView() { + super.onDestroyView() + disposables.dispose() + binding.noteWebview.destroy() + _binding = null + } + + override fun onResume() { + super.onResume() + val timeoutDisposable = Single.just(Unit) + .delay(LOAD_TIMEOUT_SECONDS, TimeUnit.SECONDS) + .map { + if (!binding.noteWebview.isVisible) { + Log.w(TAG, "Editor not loaded after $LOAD_TIMEOUT_SECONDS seconds") + handleLoadError() + } + }.subscribe() + disposables.add(timeoutDisposable) + } + + override fun onNoteLoaded(note: Note) { + super.onNoteLoaded(note) + Log.d(TAG, "onNoteLoaded() called") + val newNoteParam = arguments?.getSerializable(PARAM_NEWNOTE) as Note? + if (newNoteParam != null || note.remoteId == null) { + createAndLoadNote(note) + } else { + loadNoteInWebView(note) + } + } + + private fun createAndLoadNote(newNote: Note) { + Log.d(TAG, "createAndLoadNote() called") + val noteCreateDisposable = Single + .fromCallable { + notesApi.createNote(newNote).execute().body()!! + } + .map { createdNote -> + repo.updateRemoteId(newNote.id, createdNote.remoteId) + repo.getNoteById(newNote.id) + } + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe({ createdNote -> + loadNoteInWebView(createdNote) + }, { throwable -> + note = null + handleLoadError() + Log.e(TAG, "createAndLoadNote:", throwable) + }) + disposables.add(noteCreateDisposable) + } + + private fun loadNoteInWebView(note: Note) { + Log.d(TAG, "loadNoteInWebView() called") + val directEditingRepository = + DirectEditingRepository.getInstance(requireContext().applicationContext) + val urlDisposable = directEditingRepository.getDirectEditingUrl(account, note) + .observeOn(AndroidSchedulers.mainThread()).subscribe({ url -> + if (BuildConfig.DEBUG) { + Log.d(TAG, "loadNoteInWebView: url = $url") + } + binding.noteWebview.loadUrl(url) + }, { throwable -> + handleLoadError() + Log.e(TAG, "loadNoteInWebView:", throwable) + }) + disposables.add(urlDisposable) + } + + private fun handleLoadError() { + val snackbar = BrandedSnackbar.make( + binding.plainEditingFab, + getString(R.string.direct_editing_error), + Snackbar.LENGTH_INDEFINITE, + ) + if (note != null) { + snackbar.setAction(R.string.switch_to_plain_editing) { + changeToEditMode() + } + } else { + snackbar.setAction(R.string.action_back) { + close() + } + } + snackbar.show() + } + + override fun shouldShowToolbar(): Boolean = false + + @SuppressLint("SetJavaScriptEnabled") + private fun prepareWebView() { + val webSettings = binding.noteWebview.settings + // enable zoom + webSettings.setSupportZoom(true) + webSettings.builtInZoomControls = true + webSettings.displayZoomControls = false + + // Non-responsive webs are zoomed out when loaded + webSettings.useWideViewPort = true + webSettings.loadWithOverviewMode = true + + // user agent + val userAgent = + getString(R.string.user_agent, getString(R.string.app_name), BuildConfig.VERSION_NAME) + webSettings.userAgentString = userAgent + + // no private data storing + webSettings.savePassword = false + webSettings.saveFormData = false + + // disable local file access + webSettings.allowFileAccess = false + + // enable javascript + webSettings.javaScriptEnabled = true + webSettings.domStorageEnabled = true + + if (BuildConfig.DEBUG) { + // caching disabled in debug mode + binding.noteWebview.settings.cacheMode = WebSettings.LOAD_NO_CACHE + } + + binding.noteWebview.addJavascriptInterface( + DirectEditingMobileInterface(this), + JS_INTERFACE_NAME, + ) + + binding.noteWebview.webViewClient = object : WebViewClient() { + override fun onReceivedError( + view: WebView?, + request: WebResourceRequest?, + error: WebResourceError?, + ) { + super.onReceivedError(view, request, error) + if (request?.isForMainFrame == true) { + handleLoadError() + } + } + + @SuppressLint("WebViewClientOnReceivedSslError") // only for debug mode + override fun onReceivedSslError( + view: WebView?, + handler: SslErrorHandler?, + error: SslError?, + ) { + if (BuildConfig.DEBUG) { + handler?.proceed() + } else { + super.onReceivedSslError(view, handler, error) + } + } + } + } + + /** + * Gets the current content of the EditText field in the UI. + * + * @return String of the current content. + */ + override fun getContent(): String { + // no way to get content from webview + return "" + } + + override fun saveNote(callback: ISyncCallback?) { + val acc = repo.getAccountByName(account.name) + repo.scheduleSync(acc, false) + } + + override fun onCloseNote() { + saveNote(null) + } + + override fun applyBrand(color: Int) { + val util = BrandingUtil.of(color, requireContext()) + util.material.themeExtendedFAB(binding.plainEditingFab) + util.platform.colorCircularProgressBar(binding.progress, ColorRole.PRIMARY) + } + + private class DirectEditingMobileInterface(val noteDirectEditFragment: NoteDirectEditFragment) { + @JavascriptInterface + fun close() { + noteDirectEditFragment.close() + } + + @JavascriptInterface + fun share() { + noteDirectEditFragment.share() + } + + @JavascriptInterface + fun loaded() { + noteDirectEditFragment.onLoaded() + } + } + + private fun close() { + if (switchToEditPending) { + Log.d(TAG, "close: switching to plain edit") + changeToEditMode() + } else { + Log.d(TAG, "close: closing") + listener?.close() + } + } + + private fun changeToEditMode() { + toggleLoadingUI(true) + val updateDisposable = Single.just(note.remoteId) + .map { remoteId -> + val newNote = notesApi.getNote(remoteId).singleOrError().blockingGet().response + val localAccount = repo.getAccountByName(account.name) + repo.updateNoteAndSync(localAccount, note, newNote.content, newNote.title, null) + } + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe({ + listener?.changeMode(NoteFragmentListener.Mode.EDIT, true) + }, { throwable -> + Log.e(TAG, "changeToEditMode: ", throwable) + listener?.changeMode(NoteFragmentListener.Mode.EDIT, true) + }) + disposables.add(updateDisposable) + } + + private fun share() { + super.shareNote() + } + + private fun onLoaded() { + Log.d(TAG, "onLoaded: note loaded") + toggleLoadingUI(false) + } + + private fun toggleLoadingUI(loading: Boolean) { + activity?.runOnUiThread { + binding.progress.isVisible = loading + binding.noteWebview.isVisible = !loading + binding.plainEditingFab.isVisible = !loading + } + } + + companion object { + private const val TAG = "NoteDirectEditFragment" + private const val LOAD_TIMEOUT_SECONDS = 10L + private const val JS_INTERFACE_NAME = "DirectEditingMobileInterface" + private const val JS_RESULT_OK = "ok" + + // language=js + private val JS_CLOSE = """ + (function () { + var closeIcons = document.getElementsByClassName("icon-close"); + if (closeIcons.length > 0) { + closeIcons[0].click(); + } else { + return "close button not available"; + } + return "$JS_RESULT_OK"; + })(); + """.trimIndent() + + @JvmStatic + fun newInstance(accountId: Long, noteId: Long): BaseNoteFragment { + val fragment = NoteDirectEditFragment() + val args = Bundle() + args.putLong(PARAM_NOTE_ID, noteId) + args.putLong(PARAM_ACCOUNT_ID, accountId) + fragment.arguments = args + return fragment + } + + @JvmStatic + fun newInstanceWithNewNote(newNote: Note?): BaseNoteFragment { + val fragment = NoteDirectEditFragment() + val args = Bundle() + args.putSerializable(PARAM_NEWNOTE, newNote) + fragment.arguments = args + return fragment + } + } +} diff --git a/app/src/main/java/it/niedermann/owncloud/notes/edit/NoteEditFragment.java b/app/src/main/java/it/niedermann/owncloud/notes/edit/NoteEditFragment.java index 13061417c..9ba17f95a 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/edit/NoteEditFragment.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/edit/NoteEditFragment.java @@ -25,6 +25,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.preference.PreferenceManager; +import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton; import com.google.android.material.floatingactionbutton.FloatingActionButton; import it.niedermann.owncloud.notes.R; @@ -103,6 +104,11 @@ public class NoteEditFragment extends SearchableBaseNoteFragment { return binding.searchPrev; } + @Override + protected @NonNull ExtendedFloatingActionButton getDirectEditingButton() { + return binding.directEditing; + } + @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) { diff --git a/app/src/main/java/it/niedermann/owncloud/notes/edit/NotePreviewFragment.java b/app/src/main/java/it/niedermann/owncloud/notes/edit/NotePreviewFragment.java index 0b2991a7d..37048d6ac 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/edit/NotePreviewFragment.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/edit/NotePreviewFragment.java @@ -23,6 +23,7 @@ import androidx.annotation.Nullable; import androidx.preference.PreferenceManager; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener; +import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton; import com.google.android.material.floatingactionbutton.FloatingActionButton; import com.nextcloud.android.sso.exceptions.NextcloudFilesAppAccountNotFoundException; import com.nextcloud.android.sso.exceptions.NoCurrentAccountSelectedException; @@ -80,6 +81,11 @@ public class NotePreviewFragment extends SearchableBaseNoteFragment implements O return binding.searchPrev; } + @Override + protected @NonNull ExtendedFloatingActionButton getDirectEditingButton() { + return binding.directEditing; + } + @Override protected Layout getLayout() { binding.singleNoteContent.onPreDraw(); diff --git a/app/src/main/java/it/niedermann/owncloud/notes/edit/SearchableBaseNoteFragment.java b/app/src/main/java/it/niedermann/owncloud/notes/edit/SearchableBaseNoteFragment.java index 4d1ec24fd..10c9510cb 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/edit/SearchableBaseNoteFragment.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/edit/SearchableBaseNoteFragment.java @@ -1,6 +1,5 @@ package it.niedermann.owncloud.notes.edit; -import android.graphics.Color; import android.os.Bundle; import android.os.Handler; import android.text.Layout; @@ -16,12 +15,19 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.widget.SearchView; +import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton; import com.google.android.material.floatingactionbutton.FloatingActionButton; +import com.nextcloud.android.sso.exceptions.NextcloudFilesAppAccountNotFoundException; +import com.nextcloud.android.sso.exceptions.NoCurrentAccountSelectedException; +import com.nextcloud.android.sso.helper.SingleAccountHelper; +import com.nextcloud.android.sso.model.SingleSignOnAccount; import java.util.regex.Pattern; import it.niedermann.owncloud.notes.R; import it.niedermann.owncloud.notes.branding.BrandingUtil; +import it.niedermann.owncloud.notes.persistence.entity.Account; +import it.niedermann.owncloud.notes.shared.util.ExtendedFabUtil; public abstract class SearchableBaseNoteFragment extends BaseNoteFragment { @@ -34,6 +40,7 @@ public abstract class SearchableBaseNoteFragment extends BaseNoteFragment { private SearchView searchView; private String searchQuery = null; private static final int delay = 50; // If the search string does not change after $delay ms, then the search task starts. + private boolean directEditAvailable = false; @ColorInt private int color; @@ -54,6 +61,47 @@ public abstract class SearchableBaseNoteFragment extends BaseNoteFragment { } } + @Override + protected void onScroll(int scrollY, int oldScrollY) { + super.onScroll(scrollY, oldScrollY); + if (directEditAvailable) { + // only show FAB if search is not active + if (getSearchNextButton() == null || getSearchNextButton().getVisibility() != View.VISIBLE) { + final ExtendedFloatingActionButton directFab = getDirectEditingButton(); + ExtendedFabUtil.toggleVisibilityOnScroll(directFab, scrollY, oldScrollY); + } + } + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + checkDirectEditingAvailable(); + if (directEditAvailable) { + final ExtendedFloatingActionButton directEditingButton = getDirectEditingButton(); + directEditingButton.setExtended(false); + ExtendedFabUtil.toggleExtendedOnLongClick(directEditingButton); + directEditingButton.setOnClickListener(v -> { + if (listener != null) { + listener.changeMode(NoteFragmentListener.Mode.DIRECT_EDIT, false); + } + }); + } else { + getDirectEditingButton().setVisibility(View.GONE); + } + } + + private void checkDirectEditingAvailable() { + try { + final SingleSignOnAccount ssoAccount = SingleAccountHelper.getCurrentSingleSignOnAccount(requireContext()); + final Account localAccount = repo.getAccountByName(ssoAccount.name); + directEditAvailable = localAccount != null && localAccount.isDirectEditingAvailable(); + } catch (NextcloudFilesAppAccountNotFoundException | NoCurrentAccountSelectedException e) { + Log.w(TAG, "checkDirectEditingAvailable: ", e); + directEditAvailable = false; + } + } + @Override public void onPrepareOptionsMenu(@NonNull Menu menu) { super.onPrepareOptionsMenu(menu); @@ -199,7 +247,12 @@ public abstract class SearchableBaseNoteFragment extends BaseNoteFragment { protected abstract FloatingActionButton getSearchPrevButton(); + @NonNull + protected abstract ExtendedFloatingActionButton getDirectEditingButton(); + + private void showSearchFabs() { + ExtendedFabUtil.setExtendedFabVisibility(getDirectEditingButton(), false); final var next = getSearchNextButton(); final var prev = getSearchPrevButton(); if (prev != null) { @@ -291,5 +344,6 @@ public abstract class SearchableBaseNoteFragment extends BaseNoteFragment { final var util = BrandingUtil.of(color, requireContext()); util.material.themeFAB(getSearchNextButton()); util.material.themeFAB(getSearchPrevButton()); + util.material.themeExtendedFAB(getDirectEditingButton()); } } 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 3ec92ffb5..479529f30 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 @@ -10,14 +10,12 @@ import static it.niedermann.owncloud.notes.shared.model.ENavigationCategoryType. import static it.niedermann.owncloud.notes.shared.model.ENavigationCategoryType.FAVORITES; import static it.niedermann.owncloud.notes.shared.model.ENavigationCategoryType.RECENT; import static it.niedermann.owncloud.notes.shared.model.ENavigationCategoryType.UNCATEGORIZED; -import static it.niedermann.owncloud.notes.shared.util.NotesColorUtil.contrastRatioIsSufficient; import static it.niedermann.owncloud.notes.shared.util.SSOUtil.askForNewAccount; import android.accounts.NetworkErrorException; import android.animation.AnimatorInflater; import android.app.SearchManager; import android.content.Intent; -import android.graphics.Color; import android.net.Uri; import android.os.Bundle; import android.text.TextUtils; @@ -50,7 +48,6 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.floatingactionbutton.FloatingActionButton; import com.google.android.material.snackbar.Snackbar; import com.nextcloud.android.common.ui.theme.utils.ColorRole; -import com.nextcloud.android.common.ui.util.PlatformThemeUtil; import com.nextcloud.android.sso.AccountImporter; import com.nextcloud.android.sso.exceptions.AccountImportCancelledException; import com.nextcloud.android.sso.exceptions.NextcloudFilesAppAccountNotFoundException; 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 30e365e2d..75d02c52d 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 @@ -414,6 +414,7 @@ public class MainViewModel extends AndroidViewModel { localAccount.setColor(capabilities.getColor()); BrandingUtil.saveBrandColor(getApplication(), localAccount.getColor()); repo.updateApiVersion(localAccount.getId(), capabilities.getApiVersion()); + repo.updateDirectEditingAvailable(localAccount.getId(), capabilities.isDirectEditingAvailable()); callback.onSuccess(null); } catch (Throwable t) { if (t.getClass() == NextcloudHttpRequestFailedException.class || t instanceof NextcloudHttpRequestFailedException) { @@ -662,4 +663,4 @@ public class MainViewModel extends AndroidViewModel { final var lower = input.toLowerCase(Locale.ROOT); return lower.contains("failed to connect") && lower.contains("network is unreachable"); } -} \ No newline at end of file +} diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/ApiProvider.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/ApiProvider.java index ce6096075..4be0a493d 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/persistence/ApiProvider.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/ApiProvider.java @@ -20,6 +20,7 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import it.niedermann.owncloud.notes.persistence.sync.CapabilitiesDeserializer; +import it.niedermann.owncloud.notes.persistence.sync.FilesAPI; import it.niedermann.owncloud.notes.persistence.sync.NotesAPI; import it.niedermann.owncloud.notes.persistence.sync.OcsAPI; import it.niedermann.owncloud.notes.shared.model.ApiVersion; @@ -39,11 +40,14 @@ public class ApiProvider { private static final ApiProvider INSTANCE = new ApiProvider(); private static final String API_ENDPOINT_OCS = "/ocs/v2.php/cloud/"; + private static final String API_ENDPOINT_FILES ="/ocs/v2.php/apps/files/api/v1/"; private static final Map API_CACHE = new ConcurrentHashMap<>(); private static final Map API_CACHE_OCS = new ConcurrentHashMap<>(); private static final Map API_CACHE_NOTES = new ConcurrentHashMap<>(); + private static final Map API_CACHE_FILES = new ConcurrentHashMap<>(); + public static ApiProvider getInstance() { return INSTANCE; @@ -77,6 +81,15 @@ public class ApiProvider { return notesAPI; } + public synchronized FilesAPI getFilesAPI(@NonNull Context context, @NonNull SingleSignOnAccount ssoAccount) { + if (API_CACHE_FILES.containsKey(ssoAccount.name)) { + return API_CACHE_FILES.get(ssoAccount.name); + } + final var filesAPI = new NextcloudRetrofitApiBuilder(getNextcloudAPI(context, ssoAccount), API_ENDPOINT_FILES).create(FilesAPI.class); + API_CACHE_FILES.put(ssoAccount.name, filesAPI); + return filesAPI; + } + private synchronized NextcloudAPI getNextcloudAPI(@NonNull Context context, @NonNull SingleSignOnAccount ssoAccount) { if (API_CACHE.containsKey(ssoAccount.name)) { return API_CACHE.get(ssoAccount.name); diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/CapabilitiesWorker.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/CapabilitiesWorker.java index ebe6198ed..43ff28812 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/persistence/CapabilitiesWorker.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/CapabilitiesWorker.java @@ -51,6 +51,7 @@ public class CapabilitiesWorker extends Worker { repo.updateCapabilitiesETag(account.getId(), capabilities.getETag()); repo.updateBrand(account.getId(), capabilities.getColor()); repo.updateApiVersion(account.getId(), capabilities.getApiVersion()); + repo.updateDirectEditingAvailable(account.getId(), capabilities.isDirectEditingAvailable()); Log.i(TAG, capabilities.toString()); repo.updateDisplayName(account.getId(), CapabilitiesClient.getDisplayName(getApplicationContext(), ssoAccount, ApiProvider.getInstance())); } catch (Throwable e) { diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/DirectEditingRepository.kt b/app/src/main/java/it/niedermann/owncloud/notes/persistence/DirectEditingRepository.kt new file mode 100644 index 000000000..01cdfb1ac --- /dev/null +++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/DirectEditingRepository.kt @@ -0,0 +1,69 @@ +package it.niedermann.owncloud.notes.persistence + +import android.app.Application +import android.content.Context +import com.nextcloud.android.sso.model.SingleSignOnAccount +import io.reactivex.Single +import io.reactivex.schedulers.Schedulers +import it.niedermann.owncloud.notes.persistence.entity.Note +import it.niedermann.owncloud.notes.shared.model.ApiVersion +import it.niedermann.owncloud.notes.shared.model.directediting.DirectEditingRequestBody + +class DirectEditingRepository private constructor(private val applicationContext: Context) { + + private val apiProvider: ApiProvider by lazy { ApiProvider.getInstance() } + private val notesRepository: NotesRepository by lazy { + NotesRepository.getInstance( + applicationContext, + ) + } + + private fun getNotesPath(account: SingleSignOnAccount): Single { + return Single.fromCallable { + val call = notesRepository.getServerSettings(account, ApiVersion.API_VERSION_1_0) + val response = call.execute() + response.body()?.notesPath ?: throw RuntimeException("No notes path available") + }.subscribeOn(Schedulers.io()) + } + + fun getDirectEditingUrl( + account: SingleSignOnAccount, + note: Note, + ): Single { + return getNotesPath(account) + .flatMap { notesPath -> + val filesAPI = apiProvider.getFilesAPI(applicationContext, account) + Single.fromCallable { + val call = + filesAPI.getDirectEditingUrl( + DirectEditingRequestBody( + path = notesPath, + editorId = SUPPORTED_EDITOR_ID, + fileId = note.remoteId!!, + ), + ) + val response = call.execute() + response.body()?.ocs?.data?.url + ?: throw RuntimeException("No url available") + }.subscribeOn(Schedulers.io()) + } + } + + companion object { + private const val SUPPORTED_EDITOR_ID = "text" + + private var instance: DirectEditingRepository? = null + + /** + * @param applicationContext The application context. Do NOT use a view context to prevent leaks. + */ + @JvmStatic + fun getInstance(applicationContext: Context): DirectEditingRepository { + require(applicationContext is Application) + if (instance == null) { + instance = DirectEditingRepository(applicationContext) + } + return instance!! + } + } +} diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/NotesDatabase.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/NotesDatabase.java index d062f4c54..a50604073 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/persistence/NotesDatabase.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/NotesDatabase.java @@ -21,22 +21,7 @@ import it.niedermann.owncloud.notes.persistence.entity.Converters; import it.niedermann.owncloud.notes.persistence.entity.Note; import it.niedermann.owncloud.notes.persistence.entity.NotesListWidgetData; import it.niedermann.owncloud.notes.persistence.entity.SingleNoteWidgetData; -import it.niedermann.owncloud.notes.persistence.migration.Migration_10_11; -import it.niedermann.owncloud.notes.persistence.migration.Migration_11_12; -import it.niedermann.owncloud.notes.persistence.migration.Migration_12_13; -import it.niedermann.owncloud.notes.persistence.migration.Migration_13_14; -import it.niedermann.owncloud.notes.persistence.migration.Migration_14_15; -import it.niedermann.owncloud.notes.persistence.migration.Migration_15_16; -import it.niedermann.owncloud.notes.persistence.migration.Migration_16_17; -import it.niedermann.owncloud.notes.persistence.migration.Migration_17_18; -import it.niedermann.owncloud.notes.persistence.migration.Migration_18_19; -import it.niedermann.owncloud.notes.persistence.migration.Migration_19_20; -import it.niedermann.owncloud.notes.persistence.migration.Migration_20_21; -import it.niedermann.owncloud.notes.persistence.migration.Migration_21_22; -import it.niedermann.owncloud.notes.persistence.migration.Migration_22_23; -import it.niedermann.owncloud.notes.persistence.migration.Migration_23_24; -import it.niedermann.owncloud.notes.persistence.migration.Migration_9_10; - +import it.niedermann.owncloud.notes.persistence.migration.*; @Database( entities = { Account.class, @@ -44,7 +29,7 @@ import it.niedermann.owncloud.notes.persistence.migration.Migration_9_10; CategoryOptions.class, SingleNoteWidgetData.class, NotesListWidgetData.class - }, version = 24 + }, version = 25 ) @TypeConverters({Converters.class}) public abstract class NotesDatabase extends RoomDatabase { @@ -80,7 +65,8 @@ public abstract class NotesDatabase extends RoomDatabase { new Migration_20_21(), new Migration_21_22(context), new Migration_22_23(), - new Migration_23_24(context) + new Migration_23_24(context), + new Migration_24_25() ) .fallbackToDestructiveMigrationOnDowngrade() .fallbackToDestructiveMigration() 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 6825fdba3..1ea2f7cbf 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 @@ -263,6 +263,9 @@ public class NotesRepository { public void updateModified(long id, long modified) { db.getAccountDao().updateModified(id, modified); } + public void updateDirectEditingAvailable(final long id, final boolean available) { + db.getAccountDao().updateDirectEditingAvailable(id, available); + } // Notes diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/dao/AccountDao.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/dao/AccountDao.java index bb4a05410..8b3424adf 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/persistence/dao/AccountDao.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/dao/AccountDao.java @@ -21,8 +21,8 @@ public interface AccountDao { @Delete void deleteAccount(Account localAccount); - String getAccounts = "SELECT id, url, userName, accountName, eTag, modified, apiVersion, color, textColor, capabilitiesEtag, COALESCE(displayName, userName) as displayName FROM Account"; - String getAccountById = "SELECT id, url, userName, accountName, eTag, modified, apiVersion, color, textColor, capabilitiesEtag, COALESCE(displayName, userName) as displayName FROM Account WHERE ID = :accountId"; + String getAccounts = "SELECT id, url, userName, accountName, eTag, modified, apiVersion, color, textColor, capabilitiesEtag, COALESCE(displayName, userName) as displayName, directEditingAvailable FROM Account"; + String getAccountById = "SELECT id, url, userName, accountName, eTag, modified, apiVersion, color, textColor, capabilitiesEtag, COALESCE(displayName, userName) as displayName, directEditingAvailable FROM Account WHERE ID = :accountId"; @Query(getAccounts) LiveData> getAccounts$(); @@ -36,7 +36,7 @@ public interface AccountDao { @Query(getAccountById) Account getAccountById(long accountId); - @Query("SELECT id, url, userName, accountName, eTag, modified, apiVersion, color, textColor, capabilitiesEtag, COALESCE(displayName, userName) as displayName FROM Account WHERE ACCOUNTNAME = :accountName") + @Query("SELECT id, url, userName, accountName, eTag, modified, apiVersion, color, textColor, capabilitiesEtag, COALESCE(displayName, userName) as displayName, directEditingAvailable FROM Account WHERE ACCOUNTNAME = :accountName") Account getAccountByName(String accountName); @Query("SELECT COUNT(*) FROM Account") @@ -59,4 +59,7 @@ public interface AccountDao { @Query("UPDATE Account SET DISPLAYNAME = :displayName WHERE id = :id") void updateDisplayName(long id, @Nullable String displayName); + + @Query("UPDATE Account SET directEditingAvailable = :available WHERE id = :id") + void updateDirectEditingAvailable(long id, boolean available); } diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/entity/Account.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/entity/Account.java index 24e5222d8..05b957f0f 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/persistence/entity/Account.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/entity/Account.java @@ -10,17 +10,9 @@ import androidx.room.Entity; import androidx.room.Index; import androidx.room.PrimaryKey; -import org.json.JSONArray; -import org.json.JSONException; - import java.io.Serializable; import java.util.Calendar; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.NoSuchElementException; -import it.niedermann.owncloud.notes.shared.model.ApiVersion; import it.niedermann.owncloud.notes.shared.model.Capabilities; @Entity( @@ -60,6 +52,7 @@ public class Account implements Serializable { private String capabilitiesETag; @Nullable private String displayName; + private boolean directEditingAvailable; public Account() { // Default constructor @@ -76,6 +69,7 @@ public class Account implements Serializable { public void setCapabilities(@NonNull Capabilities capabilities) { capabilitiesETag = capabilities.getETag(); apiVersion = capabilities.getApiVersion(); + directEditingAvailable = capabilities.isDirectEditingAvailable(); setColor(capabilities.getColor()); } @@ -175,6 +169,14 @@ public class Account implements Serializable { this.displayName = displayName; } + public boolean isDirectEditingAvailable() { + return directEditingAvailable; + } + + public void setDirectEditingAvailable(boolean directEditingAvailable) { + this.directEditingAvailable = directEditingAvailable; + } + @Override public boolean equals(Object o) { if (this == o) return true; @@ -195,6 +197,7 @@ public class Account implements Serializable { return false; if (capabilitiesETag != null ? !capabilitiesETag.equals(account.capabilitiesETag) : account.capabilitiesETag != null) return false; + if (directEditingAvailable != account.directEditingAvailable) return false; return true; } @@ -210,6 +213,7 @@ public class Account implements Serializable { result = 31 * result + color; result = 31 * result + textColor; result = 31 * result + (capabilitiesETag != null ? capabilitiesETag.hashCode() : 0); + result = 31 * result + (directEditingAvailable ? 1 : 0); return result; } @@ -227,6 +231,7 @@ public class Account implements Serializable { ", color=" + color + ", textColor=" + textColor + ", capabilitiesETag='" + capabilitiesETag + '\'' + + ", directEditingAvailable='" + directEditingAvailable + '\'' + '}'; } -} \ No newline at end of file +} diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_24_25.kt b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_24_25.kt new file mode 100644 index 000000000..e172d1786 --- /dev/null +++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_24_25.kt @@ -0,0 +1,13 @@ +package it.niedermann.owncloud.notes.persistence.migration + +import androidx.room.migration.Migration +import androidx.sqlite.db.SupportSQLiteDatabase + +@Suppress("ClassName", "Detekt.ClassNaming", "Detekt.MagicNumber") +class Migration_24_25 : Migration(24, 25) { + override fun migrate(db: SupportSQLiteDatabase) { + db.execSQL("ALTER TABLE Account ADD COLUMN directEditingAvailable INTEGER DEFAULT 0 NOT NULL") + // remove capabilities etag to force refresh + db.execSQL("UPDATE Account SET capabilitiesETag = NULL") + } +} diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/sync/CapabilitiesDeserializer.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/sync/CapabilitiesDeserializer.java index d5ae7b494..e3b268ab7 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/persistence/sync/CapabilitiesDeserializer.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/sync/CapabilitiesDeserializer.java @@ -31,6 +31,9 @@ public class CapabilitiesDeserializer implements JsonDeserializer private static final String CAPABILITIES_THEMING = "theming"; private static final String CAPABILITIES_THEMING_COLOR = "color"; private static final String CAPABILITIES_THEMING_COLOR_TEXT = "color-text"; + private static final String CAPABILITIES_FILES = "files"; + private static final String CAPABILITIES_FILES_DIRECT_EDITING = "directEditing"; + private static final String CAPABILITIES_FILES_DIRECT_EDITING_SUPPORTS_FILE_ID = "supportsFileId"; @Override public Capabilities deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { @@ -61,7 +64,21 @@ public class CapabilitiesDeserializer implements JsonDeserializer } } } + response.setDirectEditingAvailable(hasDirectEditingCapability(capabilities)); } return response; } + + private boolean hasDirectEditingCapability(final JsonObject capabilities) { + if (capabilities.has(CAPABILITIES_FILES)) { + final var files = capabilities.getAsJsonObject(CAPABILITIES_FILES); + if (files.has(CAPABILITIES_FILES_DIRECT_EDITING)) { + final var directEditing = files.getAsJsonObject(CAPABILITIES_FILES_DIRECT_EDITING); + if (directEditing.has(CAPABILITIES_FILES_DIRECT_EDITING_SUPPORTS_FILE_ID)) { + return directEditing.get(CAPABILITIES_FILES_DIRECT_EDITING_SUPPORTS_FILE_ID).getAsBoolean(); + } + } + } + return false; + } } diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/sync/FilesAPI.kt b/app/src/main/java/it/niedermann/owncloud/notes/persistence/sync/FilesAPI.kt new file mode 100644 index 000000000..a14dcdd84 --- /dev/null +++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/sync/FilesAPI.kt @@ -0,0 +1,18 @@ +package it.niedermann.owncloud.notes.persistence.sync + +import it.niedermann.owncloud.notes.shared.model.OcsResponse +import it.niedermann.owncloud.notes.shared.model.OcsUrl +import it.niedermann.owncloud.notes.shared.model.directediting.DirectEditingInfo +import it.niedermann.owncloud.notes.shared.model.directediting.DirectEditingRequestBody +import retrofit2.Call +import retrofit2.http.Body +import retrofit2.http.GET +import retrofit2.http.POST + +interface FilesAPI { + @GET("directEditing?format=json") + fun getDirectEditingInfo(): Call> + + @POST("directEditing/open?format=json") + fun getDirectEditingUrl(@Body body: DirectEditingRequestBody): Call> +} diff --git a/app/src/main/java/it/niedermann/owncloud/notes/shared/model/Capabilities.java b/app/src/main/java/it/niedermann/owncloud/notes/shared/model/Capabilities.java index 06bd867d3..e3d739dee 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/shared/model/Capabilities.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/shared/model/Capabilities.java @@ -3,7 +3,6 @@ package it.niedermann.owncloud.notes.shared.model; import android.graphics.Color; import androidx.annotation.ColorInt; -import androidx.annotation.NonNull; import androidx.annotation.Nullable; public class Capabilities { @@ -16,6 +15,8 @@ public class Capabilities { @Nullable private String eTag; + private boolean directEditingAvailable; + public void setApiVersion(String apiVersion) { this.apiVersion = apiVersion; } @@ -49,7 +50,15 @@ public class Capabilities { this.textColor = textColor; } - @NonNull + + public boolean isDirectEditingAvailable() { + return directEditingAvailable; + } + + public void setDirectEditingAvailable(boolean directEditingAvailable) { + this.directEditingAvailable = directEditingAvailable; + } + @Override public String toString() { return "Capabilities{" + @@ -57,6 +66,7 @@ public class Capabilities { ", color=" + color + ", textColor=" + textColor + ", eTag='" + eTag + '\'' + + ", hasDirectEditing=" + directEditingAvailable + '}'; } -} \ No newline at end of file +} diff --git a/app/src/main/java/it/niedermann/owncloud/notes/shared/model/OcsUrl.kt b/app/src/main/java/it/niedermann/owncloud/notes/shared/model/OcsUrl.kt new file mode 100644 index 000000000..bc9e2a14f --- /dev/null +++ b/app/src/main/java/it/niedermann/owncloud/notes/shared/model/OcsUrl.kt @@ -0,0 +1,9 @@ +package it.niedermann.owncloud.notes.shared.model + +import com.google.gson.annotations.Expose + +data class OcsUrl( + @Expose + @JvmField + var url: String? = null +) diff --git a/app/src/main/java/it/niedermann/owncloud/notes/shared/model/directediting/DirectEditingCreator.kt b/app/src/main/java/it/niedermann/owncloud/notes/shared/model/directediting/DirectEditingCreator.kt new file mode 100644 index 000000000..7fb7b5acc --- /dev/null +++ b/app/src/main/java/it/niedermann/owncloud/notes/shared/model/directediting/DirectEditingCreator.kt @@ -0,0 +1,18 @@ +package it.niedermann.owncloud.notes.shared.model.directediting + +import com.google.gson.annotations.Expose + +data class DirectEditingCreator( + @Expose + val id: String, + @Expose + val editor: String, + @Expose + val name: String, + @Expose + val extension: String, + @Expose + val mimetype: String, + @Expose + val templates: Boolean, +) diff --git a/app/src/main/java/it/niedermann/owncloud/notes/shared/model/directediting/DirectEditingEditor.kt b/app/src/main/java/it/niedermann/owncloud/notes/shared/model/directediting/DirectEditingEditor.kt new file mode 100644 index 000000000..5e5de2e3d --- /dev/null +++ b/app/src/main/java/it/niedermann/owncloud/notes/shared/model/directediting/DirectEditingEditor.kt @@ -0,0 +1,19 @@ +package it.niedermann.owncloud.notes.shared.model.directediting + +import com.google.gson.annotations.Expose + +/** + * Editor for direct editing data model + */ +data class DirectEditingEditor( + @Expose + val id: String, + @Expose + val name: String, + @Expose + val mimetypes: ArrayList, + @Expose + val optionalMimetypes: ArrayList, + @Expose + val secure: Boolean, +) diff --git a/app/src/main/java/it/niedermann/owncloud/notes/shared/model/directediting/DirectEditingInfo.kt b/app/src/main/java/it/niedermann/owncloud/notes/shared/model/directediting/DirectEditingInfo.kt new file mode 100644 index 000000000..47131dd30 --- /dev/null +++ b/app/src/main/java/it/niedermann/owncloud/notes/shared/model/directediting/DirectEditingInfo.kt @@ -0,0 +1,10 @@ +package it.niedermann.owncloud.notes.shared.model.directediting + +import com.google.gson.annotations.Expose + +data class DirectEditingInfo( + @Expose + val editors: Map, + @Expose + val creators: Map, +) diff --git a/app/src/main/java/it/niedermann/owncloud/notes/shared/model/directediting/DirectEditingRequestBody.kt b/app/src/main/java/it/niedermann/owncloud/notes/shared/model/directediting/DirectEditingRequestBody.kt new file mode 100644 index 000000000..9bfea16bf --- /dev/null +++ b/app/src/main/java/it/niedermann/owncloud/notes/shared/model/directediting/DirectEditingRequestBody.kt @@ -0,0 +1,12 @@ +package it.niedermann.owncloud.notes.shared.model.directediting + +import com.google.gson.annotations.Expose + +data class DirectEditingRequestBody( + @Expose + val path: String, + @Expose + val editorId: String, + @Expose + val fileId: Long, +) diff --git a/app/src/main/java/it/niedermann/owncloud/notes/shared/util/ExtendedFabUtil.kt b/app/src/main/java/it/niedermann/owncloud/notes/shared/util/ExtendedFabUtil.kt new file mode 100644 index 000000000..a27714fbe --- /dev/null +++ b/app/src/main/java/it/niedermann/owncloud/notes/shared/util/ExtendedFabUtil.kt @@ -0,0 +1,65 @@ +package it.niedermann.owncloud.notes.shared.util + +import android.view.View +import android.view.animation.Animation +import android.view.animation.AnimationUtils +import com.google.android.material.R +import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton + +object ExtendedFabUtil { + @JvmStatic + fun setExtendedFabVisibility( + extendedFab: ExtendedFloatingActionButton, + visibility: Boolean, + ) { + if (visibility) { + extendedFab.show() + } else { + if (extendedFab.isExtended) { + extendedFab.hide() + } else { + if (extendedFab.animation == null) { + val animation = AnimationUtils.loadAnimation( + extendedFab.context, + R.anim.abc_shrink_fade_out_from_bottom, + ) + animation.setAnimationListener(object : Animation.AnimationListener { + override fun onAnimationStart(animation: Animation) {} + override fun onAnimationEnd(animation: Animation) { + extendedFab.visibility = View.GONE + } + + override fun onAnimationRepeat(animation: Animation) {} + }) + extendedFab.startAnimation(animation) + } + } + } + } + + @JvmStatic + fun toggleExtendedOnLongClick(extendedFab: ExtendedFloatingActionButton) { + extendedFab.setOnLongClickListener { v: View? -> + if (extendedFab.isExtended) { + extendedFab.shrink() + } else { + extendedFab.extend() + } + true + } + } + + @JvmStatic + fun toggleVisibilityOnScroll( + extendedFab: ExtendedFloatingActionButton, + scrollY: Int, + oldScrollY: Int, + ) { + @Suppress("ConvertTwoComparisonsToRangeCheck") + if (oldScrollY > 0 && scrollY > oldScrollY && extendedFab.isShown) { + setExtendedFabVisibility(extendedFab, false) + } else if (scrollY < oldScrollY && !extendedFab.isShown) { + setExtendedFabVisibility(extendedFab, true) + } + } +} diff --git a/app/src/main/java/it/niedermann/owncloud/notes/shared/util/rx/DisposableSet.kt b/app/src/main/java/it/niedermann/owncloud/notes/shared/util/rx/DisposableSet.kt new file mode 100644 index 000000000..12982ed64 --- /dev/null +++ b/app/src/main/java/it/niedermann/owncloud/notes/shared/util/rx/DisposableSet.kt @@ -0,0 +1,16 @@ +package it.niedermann.owncloud.notes.shared.util.rx + +import io.reactivex.disposables.Disposable + +class DisposableSet { + private val disposables = mutableSetOf() + + fun add(disposable: Disposable) { + disposables.add(disposable) + } + + fun dispose() { + disposables.forEach { it.dispose() } + disposables.clear() + } +} diff --git a/app/src/main/res/drawable/ic_notes.xml b/app/src/main/res/drawable/ic_notes.xml new file mode 100644 index 000000000..7ef43fc14 --- /dev/null +++ b/app/src/main/res/drawable/ic_notes.xml @@ -0,0 +1,11 @@ + + + diff --git a/app/src/main/res/drawable/ic_rich_editing.xml b/app/src/main/res/drawable/ic_rich_editing.xml new file mode 100644 index 000000000..3f13365f4 --- /dev/null +++ b/app/src/main/res/drawable/ic_rich_editing.xml @@ -0,0 +1,24 @@ + + + + diff --git a/app/src/main/res/layout/fragment_note_direct_edit.xml b/app/src/main/res/layout/fragment_note_direct_edit.xml new file mode 100644 index 000000000..cecad852a --- /dev/null +++ b/app/src/main/res/layout/fragment_note_direct_edit.xml @@ -0,0 +1,41 @@ + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_note_edit.xml b/app/src/main/res/layout/fragment_note_edit.xml index 75e6ab846..79cef9468 100644 --- a/app/src/main/res/layout/fragment_note_edit.xml +++ b/app/src/main/res/layout/fragment_note_edit.xml @@ -64,4 +64,19 @@ app:backgroundTint="@color/defaultBrand" app:srcCompat="@drawable/ic_keyboard_arrow_down_white_24dp" tools:visibility="visible" /> - \ No newline at end of file + + + diff --git a/app/src/main/res/layout/fragment_note_preview.xml b/app/src/main/res/layout/fragment_note_preview.xml index bd9aabefa..f9028fb56 100644 --- a/app/src/main/res/layout/fragment_note_preview.xml +++ b/app/src/main/res/layout/fragment_note_preview.xml @@ -61,4 +61,19 @@ app:backgroundTint="@color/defaultBrand" app:srcCompat="@drawable/ic_keyboard_arrow_down_white_24dp" tools:visibility="visible" /> - \ No newline at end of file + + + diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index a7557c374..7894ca845 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -3,6 +3,7 @@ @string/pref_value_mode_edit @string/pref_value_mode_preview + @string/pref_value_mode_direct_edit @string/pref_value_mode_last @@ -15,4 +16,4 @@ @string/pref_value_theme_dark @string/pref_value_theme_system_default - \ No newline at end of file + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 4458476d7..87ffff577 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -41,6 +41,7 @@ Last month Display mode for notes + Notes opening behaviour Theme Monospace font Font size @@ -122,6 +123,7 @@ lastNoteMode backgroundSync edit + directEdit preview last small @@ -213,10 +215,17 @@ Manage accounts Formatting - - Open in edit mode - Open in preview mode - Remember my last selection + + Plain edit mode + Plain preview + Rich edit mode + Remember my last selection + + + @string/noteMode_plain_edit + @string/noteMode_plain_preview + @string/noteMode_rich_edit + @string/noteMode_remember_last @@ -357,4 +366,8 @@ Importing notes… Importing note %1$d of %2$d… Account imported. + Error while loading rich editing + Switch to plain editing + Back + Mozilla/5.0 (Android) %1$s-android/%2$s diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index 810f7ae6f..e9a13a5d1 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -35,6 +35,16 @@ android:summary="%s" android:title="@string/settings_theme_title" /> + + - - Date: Wed, 8 Mar 2023 12:27:09 +0100 Subject: [PATCH 069/163] fix(fastlane): Fix parameters for release tasks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Álvaro Brey --- fastlane/Fastfile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 926e88511..b7ddf1e99 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -48,8 +48,8 @@ desc "Build app bundle" tagName = getTagName(versionComponents) preReleaseChecks(versionInfo: versionInfo, tagName: tagName, type: versionComponents["type"], track: storeTrack) checkArtifactsExist() - tag(tagName) - uploadToPlayStore() + tag(name: tagName) + uploadToPlayStore(track: storeTrack) end desc "Run tests" @@ -96,8 +96,8 @@ desc "Build app bundle" desc "Create release tag" - private_lane :tag do |versionInfo| - tagName = versionInfo["versionName"] + private_lane :tag do |options| + tagName = options[:name] add_git_tag( tag: tagName, sign: true -- GitLab From abeaf1ce779184bc6006740a0b17a46100bdc123 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Brey?= Date: Wed, 8 Mar 2023 12:28:00 +0100 Subject: [PATCH 070/163] Update fastlane MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Álvaro Brey --- Gemfile.lock | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 2c5fd63b5..3a30044fa 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -8,16 +8,16 @@ GEM artifactory (3.0.15) atomos (0.1.3) aws-eventstream (1.2.0) - aws-partitions (1.703.0) + aws-partitions (1.722.0) aws-sdk-core (3.170.0) aws-eventstream (~> 1, >= 1.0.2) aws-partitions (~> 1, >= 1.651.0) aws-sigv4 (~> 1.5) jmespath (~> 1, >= 1.6.1) - aws-sdk-kms (1.62.0) + aws-sdk-kms (1.63.0) aws-sdk-core (~> 3, >= 3.165.0) aws-sigv4 (~> 1.1) - aws-sdk-s3 (1.119.0) + aws-sdk-s3 (1.119.1) aws-sdk-core (~> 3, >= 3.165.0) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.4) @@ -36,7 +36,7 @@ GEM unf (>= 0.0.5, < 1.0.0) dotenv (2.8.1) emoji_regex (3.2.3) - excon (0.98.0) + excon (0.99.0) faraday (1.10.3) faraday-em_http (~> 1.0) faraday-em_synchrony (~> 1.0) @@ -66,7 +66,7 @@ GEM faraday_middleware (1.2.0) faraday (~> 1.0) fastimage (2.2.6) - fastlane (2.211.0) + fastlane (2.212.1) CFPropertyList (>= 2.3, < 4.0.0) addressable (>= 2.8, < 3.0.0) artifactory (~> 3.0) @@ -106,9 +106,9 @@ GEM xcpretty (~> 0.3.0) xcpretty-travis-formatter (>= 0.0.3) gh_inspector (1.1.3) - google-apis-androidpublisher_v3 (0.33.0) - google-apis-core (>= 0.9.1, < 2.a) - google-apis-core (0.10.0) + google-apis-androidpublisher_v3 (0.35.0) + google-apis-core (>= 0.11.0, < 2.a) + google-apis-core (0.11.0) addressable (~> 2.5, >= 2.5.1) googleauth (>= 0.16.2, < 2.a) httpclient (>= 2.8.1, < 3.a) @@ -117,10 +117,10 @@ GEM retriable (>= 2.0, < 4.a) rexml webrick - google-apis-iamcredentials_v1 (0.16.0) - google-apis-core (>= 0.9.1, < 2.a) - google-apis-playcustomapp_v1 (0.12.0) - google-apis-core (>= 0.9.1, < 2.a) + google-apis-iamcredentials_v1 (0.17.0) + google-apis-core (>= 0.11.0, < 2.a) + google-apis-playcustomapp_v1 (0.13.0) + google-apis-core (>= 0.11.0, < 2.a) google-apis-storage_v1 (0.19.0) google-apis-core (>= 0.9.0, < 2.a) google-cloud-core (1.6.0) @@ -128,7 +128,7 @@ GEM google-cloud-errors (~> 1.0) google-cloud-env (1.6.0) faraday (>= 0.17.3, < 3.0) - google-cloud-errors (1.3.0) + google-cloud-errors (1.3.1) google-cloud-storage (1.44.0) addressable (~> 2.8) digest-crc (~> 0.4) @@ -160,7 +160,7 @@ GEM naturally (2.2.1) optparse (0.1.1) os (1.1.4) - plist (3.6.0) + plist (3.7.0) public_suffix (5.0.1) rake (13.0.6) representable (3.2.0) -- GitLab From 6926fd8e1b6ae99a2ea37482dc74090db13a2f24 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 9 Mar 2023 03:05:40 +0000 Subject: [PATCH 071/163] build(deps): Bump androidx.lifecycle:lifecycle-viewmodel-ktx Bumps androidx.lifecycle:lifecycle-viewmodel-ktx from 2.5.1 to 2.6.0. --- updated-dependencies: - dependency-name: androidx.lifecycle:lifecycle-viewmodel-ktx dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 578bdbaa9..dfab000c5 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -95,7 +95,7 @@ dependencies { implementation 'androidx.core:core-ktx:1.9.0' implementation 'androidx.core:core-splashscreen:1.0.0' implementation 'androidx.fragment:fragment:1.5.5' - implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1' + implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.0' implementation 'androidx.preference:preference:1.2.0' implementation 'androidx.recyclerview:recyclerview-selection:1.1.0' implementation 'androidx.recyclerview:recyclerview:1.2.1' -- GitLab From d58ea3a47f753de781837e6526699b739e60f746 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 9 Mar 2023 03:05:46 +0000 Subject: [PATCH 072/163] build(deps): Bump androidx.recyclerview:recyclerview from 1.2.1 to 1.3.0 Bumps androidx.recyclerview:recyclerview from 1.2.1 to 1.3.0. --- updated-dependencies: - dependency-name: androidx.recyclerview:recyclerview dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 578bdbaa9..f0089b682 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -98,7 +98,7 @@ dependencies { implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1' implementation 'androidx.preference:preference:1.2.0' implementation 'androidx.recyclerview:recyclerview-selection:1.1.0' - implementation 'androidx.recyclerview:recyclerview:1.2.1' + implementation 'androidx.recyclerview:recyclerview:1.3.0' implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0' implementation 'androidx.work:work-runtime:2.8.0' implementation 'com.google.android.material:material:1.8.0' -- GitLab From ab505b38fc4fc549228a7cd86d387936ebca1922 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 10 Mar 2023 03:04:16 +0000 Subject: [PATCH 073/163] build(deps): Bump org.mockito:mockito-core from 5.1.1 to 5.2.0 Bumps [org.mockito:mockito-core](https://github.com/mockito/mockito) from 5.1.1 to 5.2.0. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v5.1.1...v5.2.0) --- updated-dependencies: - dependency-name: org.mockito:mockito-core dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 578bdbaa9..9b975b7af 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -121,7 +121,7 @@ dependencies { testImplementation 'androidx.test:core:1.5.0' testImplementation 'androidx.arch.core:core-testing:2.2.0' testImplementation 'junit:junit:4.13.2' - testImplementation 'org.mockito:mockito-core:5.1.1' + testImplementation 'org.mockito:mockito-core:5.2.0' testImplementation 'org.robolectric:robolectric:4.9.2' implementation fileTree(dir: 'libs', include: ['*.jar']) -- GitLab From afbd308cd9e8fe6a4bafd8d1d741e499636754b1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Mar 2023 14:07:58 +0000 Subject: [PATCH 074/163] build(deps): Bump hmarr/auto-approve-action from 3.1.0 to 3.2.1 Bumps [hmarr/auto-approve-action](https://github.com/hmarr/auto-approve-action) from 3.1.0 to 3.2.1. - [Release notes](https://github.com/hmarr/auto-approve-action/releases) - [Commits](https://github.com/hmarr/auto-approve-action/compare/de8ae18c173c131e182d4adf2c874d8d2308a85b...44888193675f29a83e04faf4002fa8c0b537b1e4) --- updated-dependencies: - dependency-name: hmarr/auto-approve-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/autoApproveDependabot.yml | 2 +- .github/workflows/autoApproveSync.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/autoApproveDependabot.yml b/.github/workflows/autoApproveDependabot.yml index 4d65e886a..160c7f8e6 100644 --- a/.github/workflows/autoApproveDependabot.yml +++ b/.github/workflows/autoApproveDependabot.yml @@ -25,6 +25,6 @@ jobs: pull-requests: write steps: - - uses: hmarr/auto-approve-action@de8ae18c173c131e182d4adf2c874d8d2308a85b # v3.1.0 + - uses: hmarr/auto-approve-action@44888193675f29a83e04faf4002fa8c0b537b1e4 # v3.2.1 with: github-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/autoApproveSync.yml b/.github/workflows/autoApproveSync.yml index aa7279581..fb7144674 100644 --- a/.github/workflows/autoApproveSync.yml +++ b/.github/workflows/autoApproveSync.yml @@ -24,6 +24,6 @@ jobs: runs-on: ubuntu-latest if: ${{ contains(github.event.pull_request.labels.*.name, 'sync') && github.actor == 'nextcloud-android-bot' }} steps: - - uses: hmarr/auto-approve-action@de8ae18c173c131e182d4adf2c874d8d2308a85b # v3.1.0 + - uses: hmarr/auto-approve-action@44888193675f29a83e04faf4002fa8c0b537b1e4 # v3.2.1 with: github-token: "${{ secrets.GITHUB_TOKEN }}" -- GitLab From a29bd91f8f3e1f278e6558e899a051b0793cb8fe Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Mar 2023 14:08:09 +0000 Subject: [PATCH 075/163] build(deps): Bump github/codeql-action from 2.2.5 to 2.2.7 Bumps [github/codeql-action](https://github.com/github/codeql-action) from 2.2.5 to 2.2.7. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/32dc499307d133bb5085bae78498c0ac2cf762d5...168b99b3c22180941ae7dbdd5f5c9678ede476ba) --- updated-dependencies: - dependency-name: github/codeql-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/codeql.yml | 4 ++-- .github/workflows/scorecard.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 7ad8c8a9e..a5da648a9 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -32,7 +32,7 @@ jobs: with: swap-size-gb: 10 - name: Initialize CodeQL - uses: github/codeql-action/init@32dc499307d133bb5085bae78498c0ac2cf762d5 # v2.2.5 + uses: github/codeql-action/init@168b99b3c22180941ae7dbdd5f5c9678ede476ba # v2.2.7 with: languages: ${{ matrix.language }} - name: Set up JDK @@ -46,4 +46,4 @@ jobs: echo "org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError" > "$HOME/.gradle/gradle.properties" ./gradlew assembleDebug - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@32dc499307d133bb5085bae78498c0ac2cf762d5 # v2.2.5 + uses: github/codeql-action/analyze@168b99b3c22180941ae7dbdd5f5c9678ede476ba # v2.2.7 diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 280c9a709..a8f2916d8 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -33,6 +33,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@32dc499307d133bb5085bae78498c0ac2cf762d5 # v2.2.5 + uses: github/codeql-action/upload-sarif@168b99b3c22180941ae7dbdd5f5c9678ede476ba # v2.2.7 with: sarif_file: results.sarif -- GitLab From e132d3d52c61f8b7fc3f6ed424d5fa5bcc139399 Mon Sep 17 00:00:00 2001 From: nextcloud-android-bot Date: Wed, 22 Mar 2023 02:30:10 +0000 Subject: [PATCH 076/163] =?UTF-8?q?=F0=9F=94=84=20synced=20local=20'.githu?= =?UTF-8?q?b/workflows/'=20with=20remote=20'config/workflows/'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: nextcloud-android-bot --- .github/workflows/autoApproveDependabot.yml | 2 +- .github/workflows/autoApproveSync.yml | 2 +- .github/workflows/codeql.yml | 6 +++--- .github/workflows/gradle-wrapper-validation.yml | 2 +- .github/workflows/scorecard.yml | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/autoApproveDependabot.yml b/.github/workflows/autoApproveDependabot.yml index 4d65e886a..160c7f8e6 100644 --- a/.github/workflows/autoApproveDependabot.yml +++ b/.github/workflows/autoApproveDependabot.yml @@ -25,6 +25,6 @@ jobs: pull-requests: write steps: - - uses: hmarr/auto-approve-action@de8ae18c173c131e182d4adf2c874d8d2308a85b # v3.1.0 + - uses: hmarr/auto-approve-action@44888193675f29a83e04faf4002fa8c0b537b1e4 # v3.2.1 with: github-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/autoApproveSync.yml b/.github/workflows/autoApproveSync.yml index aa7279581..fb7144674 100644 --- a/.github/workflows/autoApproveSync.yml +++ b/.github/workflows/autoApproveSync.yml @@ -24,6 +24,6 @@ jobs: runs-on: ubuntu-latest if: ${{ contains(github.event.pull_request.labels.*.name, 'sync') && github.actor == 'nextcloud-android-bot' }} steps: - - uses: hmarr/auto-approve-action@de8ae18c173c131e182d4adf2c874d8d2308a85b # v3.1.0 + - uses: hmarr/auto-approve-action@44888193675f29a83e04faf4002fa8c0b537b1e4 # v3.2.1 with: github-token: "${{ secrets.GITHUB_TOKEN }}" diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 7ad8c8a9e..78ba4ee94 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -26,13 +26,13 @@ jobs: language: [ 'java' ] steps: - name: Checkout repository - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 + uses: actions/checkout@24cb9080177205b6e8c946b17badbe402adc938f # v3.4.0 - name: Set Swap Space uses: pierotofy/set-swap-space@49819abfb41bd9b44fb781159c033dba90353a7c # v1.0 with: swap-size-gb: 10 - name: Initialize CodeQL - uses: github/codeql-action/init@32dc499307d133bb5085bae78498c0ac2cf762d5 # v2.2.5 + uses: github/codeql-action/init@168b99b3c22180941ae7dbdd5f5c9678ede476ba # v2.2.7 with: languages: ${{ matrix.language }} - name: Set up JDK @@ -46,4 +46,4 @@ jobs: echo "org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError" > "$HOME/.gradle/gradle.properties" ./gradlew assembleDebug - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@32dc499307d133bb5085bae78498c0ac2cf762d5 # v2.2.5 + uses: github/codeql-action/analyze@168b99b3c22180941ae7dbdd5f5c9678ede476ba # v2.2.7 diff --git a/.github/workflows/gradle-wrapper-validation.yml b/.github/workflows/gradle-wrapper-validation.yml index c0bd4c8b1..a8849cdc8 100644 --- a/.github/workflows/gradle-wrapper-validation.yml +++ b/.github/workflows/gradle-wrapper-validation.yml @@ -14,5 +14,5 @@ jobs: name: "Validation" runs-on: ubuntu-latest steps: - - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 + - uses: actions/checkout@24cb9080177205b6e8c946b17badbe402adc938f # v3.4.0 - uses: gradle/wrapper-validation-action@8d49e559aae34d3e0eb16cde532684bc9702762b # v1.0.6 diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 280c9a709..7d6055b16 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -20,7 +20,7 @@ jobs: steps: - name: "Checkout code" - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 + uses: actions/checkout@24cb9080177205b6e8c946b17badbe402adc938f # v3.4.0 with: persist-credentials: false @@ -33,6 +33,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@32dc499307d133bb5085bae78498c0ac2cf762d5 # v2.2.5 + uses: github/codeql-action/upload-sarif@168b99b3c22180941ae7dbdd5f5c9678ede476ba # v2.2.7 with: sarif_file: results.sarif -- GitLab From ad74c63fc740c8e5ee1136c1eaad905a1c684b37 Mon Sep 17 00:00:00 2001 From: Stefan Niedermann Date: Wed, 22 Mar 2023 08:17:27 +0100 Subject: [PATCH 077/163] fix(launcher): Fix missing monochrome icon (#1715) Signed-off-by: Stefan Niedermann --- app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml index bbd3e0212..6f3b755bf 100644 --- a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -1,5 +1,6 @@ - - + + + \ No newline at end of file -- GitLab From 31e158a919354a04a3ff4ae7c628b3401e6926ee Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 22 Mar 2023 08:11:46 +0000 Subject: [PATCH 078/163] build(deps): Bump com.github.nextcloud.android-common:ui Bumps com.github.nextcloud.android-common:ui from 0.6.0 to 0.7.0. --- updated-dependencies: - dependency-name: com.github.nextcloud.android-common:ui dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 9b975b7af..e8c4266b2 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -77,7 +77,7 @@ dependencies { coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.2' // Nextcloud SSO - implementation 'com.github.nextcloud.android-common:ui:0.6.0' + implementation 'com.github.nextcloud.android-common:ui:0.7.0' implementation 'com.github.nextcloud:Android-SingleSignOn:0.6.1' implementation 'com.github.stefan-niedermann:android-commons:0.2.9' implementation 'com.github.stefan-niedermann.nextcloud-commons:sso-glide:1.6.4' -- GitLab From 7dfe85a1edb01b74b8c76cecac53a2002b0f3aa4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 22 Mar 2023 08:20:33 +0000 Subject: [PATCH 079/163] build(deps): Bump glideVersion from 4.15.0 to 4.15.1 Bumps `glideVersion` from 4.15.0 to 4.15.1. Updates `com.github.bumptech.glide:glide` from 4.15.0 to 4.15.1 - [Release notes](https://github.com/bumptech/glide/releases) - [Commits](https://github.com/bumptech/glide/compare/v4.15.0...v4.15.1) Updates `com.github.bumptech.glide:compiler` from 4.15.0 to 4.15.1 - [Release notes](https://github.com/bumptech/glide/releases) - [Commits](https://github.com/bumptech/glide/compare/v4.15.0...v4.15.1) --- updated-dependencies: - dependency-name: com.github.bumptech.glide:glide dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: com.github.bumptech.glide:compiler dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index e8c4266b2..11d60a435 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -69,7 +69,7 @@ android { } ext { - glideVersion = '4.15.0' + glideVersion = '4.15.1' roomVersion = "2.5.0" } -- GitLab From c5e6f2f70ead67310313fd1f788691ab1a7bacbf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 22 Mar 2023 08:40:28 +0000 Subject: [PATCH 080/163] build(deps): Bump org.jetbrains.kotlin:kotlin-gradle-plugin Bumps [org.jetbrains.kotlin:kotlin-gradle-plugin](https://github.com/JetBrains/kotlin) from 1.8.0 to 1.8.10. - [Release notes](https://github.com/JetBrains/kotlin/releases) - [Changelog](https://github.com/JetBrains/kotlin/blob/v1.8.10/ChangeLog.md) - [Commits](https://github.com/JetBrains/kotlin/compare/v1.8.0...v1.8.10) --- updated-dependencies: - dependency-name: org.jetbrains.kotlin:kotlin-gradle-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 2493eece8..b30250eb7 100644 --- a/build.gradle +++ b/build.gradle @@ -2,7 +2,7 @@ buildscript { ext { - kotlinVersion = '1.8.0' + kotlinVersion = '1.8.10' } repositories { mavenCentral() -- GitLab From b24c5e1dfd811fa71b6583d97aeefe6e1fae6e53 Mon Sep 17 00:00:00 2001 From: Andy Scherzinger Date: Wed, 22 Mar 2023 09:44:41 +0100 Subject: [PATCH 081/163] chore: Bump buildToolsVersion from 31.0.0 to 33.0.2 Signed-off-by: Andy Scherzinger --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 46fe25578..fd98cde51 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -3,7 +3,7 @@ apply plugin: 'org.jetbrains.kotlin.android' android { compileSdkVersion 33 - buildToolsVersion '31.0.0' + buildToolsVersion '33.0.2' compileOptions { coreLibraryDesugaringEnabled true -- GitLab From 51aaad3f48a76e5956394340717dfae016e231c6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 23 Mar 2023 03:05:26 +0000 Subject: [PATCH 082/163] build(deps): Bump androidx.work:work-runtime from 2.8.0 to 2.8.1 Bumps androidx.work:work-runtime from 2.8.0 to 2.8.1. --- updated-dependencies: - dependency-name: androidx.work:work-runtime dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 46fe25578..f6b628812 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -100,7 +100,7 @@ dependencies { implementation 'androidx.recyclerview:recyclerview-selection:1.1.0' implementation 'androidx.recyclerview:recyclerview:1.3.0' implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0' - implementation 'androidx.work:work-runtime:2.8.0' + implementation 'androidx.work:work-runtime:2.8.1' implementation 'com.google.android.material:material:1.8.0' // Database -- GitLab From d91d124c6cfdc1580127c85825b9d12ccbfde220 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 23 Mar 2023 03:05:34 +0000 Subject: [PATCH 083/163] build(deps): Bump roomVersion from 2.5.0 to 2.5.1 Bumps `roomVersion` from 2.5.0 to 2.5.1. Updates `androidx.room:room-runtime` from 2.5.0 to 2.5.1 Updates `androidx.room:room-compiler` from 2.5.0 to 2.5.1 --- updated-dependencies: - dependency-name: androidx.room:room-runtime dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: androidx.room:room-compiler dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 46fe25578..54654fa1b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -70,7 +70,7 @@ android { ext { glideVersion = '4.15.1' - roomVersion = "2.5.0" + roomVersion = "2.5.1" } dependencies { -- GitLab From bcc3809fe4f308abf44a14acebc2c3cbbfb63acb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 23 Mar 2023 03:05:43 +0000 Subject: [PATCH 084/163] build(deps): Bump androidx.fragment:fragment from 1.5.5 to 1.5.6 Bumps androidx.fragment:fragment from 1.5.5 to 1.5.6. --- updated-dependencies: - dependency-name: androidx.fragment:fragment dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 46fe25578..4990cae04 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -94,7 +94,7 @@ dependencies { implementation 'androidx.appcompat:appcompat:1.6.1' implementation 'androidx.core:core-ktx:1.9.0' implementation 'androidx.core:core-splashscreen:1.0.0' - implementation 'androidx.fragment:fragment:1.5.5' + implementation 'androidx.fragment:fragment:1.5.6' implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.0' implementation 'androidx.preference:preference:1.2.0' implementation 'androidx.recyclerview:recyclerview-selection:1.1.0' -- GitLab From b790d2115be30c45d0d8c37f889b192a0fa5243d Mon Sep 17 00:00:00 2001 From: Stefan Niedermann Date: Fri, 24 Mar 2023 20:51:40 +0100 Subject: [PATCH 085/163] chore: Remove unused flavors from .gitignore Signed-off-by: Stefan Niedermann --- app/.gitignore | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/.gitignore b/app/.gitignore index 3548d2f2d..120fe1141 100644 --- a/app/.gitignore +++ b/app/.gitignore @@ -3,6 +3,4 @@ /build /play /fdroid -/dev -/mdm -/pfungstadt \ No newline at end of file +/dev \ No newline at end of file -- GitLab From e077e7e29cff420c25897311049353032bac99a5 Mon Sep 17 00:00:00 2001 From: nextcloud-android-bot Date: Mon, 27 Mar 2023 02:41:31 +0000 Subject: [PATCH 086/163] =?UTF-8?q?=F0=9F=94=84=20synced=20local=20'.githu?= =?UTF-8?q?b/workflows/'=20with=20remote=20'config/workflows/'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: nextcloud-android-bot --- .github/workflows/codeql.yml | 6 +++--- .github/workflows/gradle-wrapper-validation.yml | 2 +- .github/workflows/scorecard.yml | 4 ++-- .github/workflows/stale.yml | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 78ba4ee94..ec075f83d 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -26,13 +26,13 @@ jobs: language: [ 'java' ] steps: - name: Checkout repository - uses: actions/checkout@24cb9080177205b6e8c946b17badbe402adc938f # v3.4.0 + uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3 # v3.5.0 - name: Set Swap Space uses: pierotofy/set-swap-space@49819abfb41bd9b44fb781159c033dba90353a7c # v1.0 with: swap-size-gb: 10 - name: Initialize CodeQL - uses: github/codeql-action/init@168b99b3c22180941ae7dbdd5f5c9678ede476ba # v2.2.7 + uses: github/codeql-action/init@67a35a08586135a9573f4327e904ecbf517a882d # v2.2.8 with: languages: ${{ matrix.language }} - name: Set up JDK @@ -46,4 +46,4 @@ jobs: echo "org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError" > "$HOME/.gradle/gradle.properties" ./gradlew assembleDebug - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@168b99b3c22180941ae7dbdd5f5c9678ede476ba # v2.2.7 + uses: github/codeql-action/analyze@67a35a08586135a9573f4327e904ecbf517a882d # v2.2.8 diff --git a/.github/workflows/gradle-wrapper-validation.yml b/.github/workflows/gradle-wrapper-validation.yml index a8849cdc8..66cf73678 100644 --- a/.github/workflows/gradle-wrapper-validation.yml +++ b/.github/workflows/gradle-wrapper-validation.yml @@ -14,5 +14,5 @@ jobs: name: "Validation" runs-on: ubuntu-latest steps: - - uses: actions/checkout@24cb9080177205b6e8c946b17badbe402adc938f # v3.4.0 + - uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3 # v3.5.0 - uses: gradle/wrapper-validation-action@8d49e559aae34d3e0eb16cde532684bc9702762b # v1.0.6 diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 7d6055b16..2f9021e6a 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -20,7 +20,7 @@ jobs: steps: - name: "Checkout code" - uses: actions/checkout@24cb9080177205b6e8c946b17badbe402adc938f # v3.4.0 + uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3 # v3.5.0 with: persist-credentials: false @@ -33,6 +33,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@168b99b3c22180941ae7dbdd5f5c9678ede476ba # v2.2.7 + uses: github/codeql-action/upload-sarif@67a35a08586135a9573f4327e904ecbf517a882d # v2.2.8 with: sarif_file: results.sarif diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index a959af77b..d996914db 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -14,7 +14,7 @@ jobs: issues: write pull-requests: write steps: - - uses: actions/stale@6f05e4244c9a0b2ed3401882b05d701dd0a7289b # v7.0.0 + - uses: actions/stale@1160a2240286f5da8ec72b1c0816ce2481aabf84 # v8.0.0 with: days-before-stale: 28 days-before-close: 14 -- GitLab From d2fe027a0e8dc7ab17d5ccbc597eeb03eee28cf1 Mon Sep 17 00:00:00 2001 From: tobiasKaminsky Date: Thu, 2 Mar 2023 09:22:08 +0100 Subject: [PATCH 087/163] Bump Kotlin to 1.8.10 Signed-off-by: tobiasKaminsky --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 2493eece8..b30250eb7 100644 --- a/build.gradle +++ b/build.gradle @@ -2,7 +2,7 @@ buildscript { ext { - kotlinVersion = '1.8.0' + kotlinVersion = '1.8.10' } repositories { mavenCentral() -- GitLab From e3d4ee9598c824574068b4440b126793adb824cd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 Mar 2023 08:22:19 +0000 Subject: [PATCH 088/163] build(deps): Bump androidx.lifecycle:lifecycle-viewmodel-ktx Bumps androidx.lifecycle:lifecycle-viewmodel-ktx from 2.6.0 to 2.6.1. --- updated-dependencies: - dependency-name: androidx.lifecycle:lifecycle-viewmodel-ktx dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 4990cae04..ad93bfd82 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -95,7 +95,7 @@ dependencies { implementation 'androidx.core:core-ktx:1.9.0' implementation 'androidx.core:core-splashscreen:1.0.0' implementation 'androidx.fragment:fragment:1.5.6' - implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.0' + implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.1' implementation 'androidx.preference:preference:1.2.0' implementation 'androidx.recyclerview:recyclerview-selection:1.1.0' implementation 'androidx.recyclerview:recyclerview:1.3.0' -- GitLab From 7c9fba41331dd984e89312433a9503bf0e188705 Mon Sep 17 00:00:00 2001 From: tobiasKaminsky Date: Mon, 27 Mar 2023 10:41:58 +0200 Subject: [PATCH 089/163] Not needed anymore to specify it Signed-off-by: tobiasKaminsky --- app/build.gradle | 1 - 1 file changed, 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index fd98cde51..3aa8c401f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -3,7 +3,6 @@ apply plugin: 'org.jetbrains.kotlin.android' android { compileSdkVersion 33 - buildToolsVersion '33.0.2' compileOptions { coreLibraryDesugaringEnabled true -- GitLab From c2b4983c52497b1dd62be87226e8d7c2d11a3f73 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 31 Mar 2023 02:04:50 +0000 Subject: [PATCH 090/163] build(deps): Bump org.jetbrains.kotlin:kotlin-gradle-plugin Bumps [org.jetbrains.kotlin:kotlin-gradle-plugin](https://github.com/JetBrains/kotlin) from 1.8.10 to 1.8.20. - [Release notes](https://github.com/JetBrains/kotlin/releases) - [Changelog](https://github.com/JetBrains/kotlin/blob/master/ChangeLog.md) - [Commits](https://github.com/JetBrains/kotlin/commits) --- updated-dependencies: - dependency-name: org.jetbrains.kotlin:kotlin-gradle-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index b30250eb7..5d898a6b4 100644 --- a/build.gradle +++ b/build.gradle @@ -2,7 +2,7 @@ buildscript { ext { - kotlinVersion = '1.8.10' + kotlinVersion = '1.8.20' } repositories { mavenCentral() -- GitLab From 68421456d6013577796c60c586e091aced63d5e9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Apr 2023 02:05:16 +0000 Subject: [PATCH 091/163] build(deps): Bump com.android.tools:desugar_jdk_libs from 2.0.2 to 2.0.3 Bumps [com.android.tools:desugar_jdk_libs](https://github.com/google/desugar_jdk_libs) from 2.0.2 to 2.0.3. - [Release notes](https://github.com/google/desugar_jdk_libs/releases) - [Changelog](https://github.com/google/desugar_jdk_libs/blob/master/CHANGELOG.md) - [Commits](https://github.com/google/desugar_jdk_libs/commits) --- updated-dependencies: - dependency-name: com.android.tools:desugar_jdk_libs dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 055d4cf77..c2b6de019 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -73,7 +73,7 @@ ext { } dependencies { - coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.2' + coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.3' // Nextcloud SSO implementation 'com.github.nextcloud.android-common:ui:0.7.0' -- GitLab From 0e9222d1f8c6ef6f7b4f402d46095475679fbbf6 Mon Sep 17 00:00:00 2001 From: nextcloud-android-bot Date: Tue, 4 Apr 2023 02:28:54 +0000 Subject: [PATCH 092/163] =?UTF-8?q?=F0=9F=94=84=20synced=20local=20'.githu?= =?UTF-8?q?b/workflows/'=20with=20remote=20'config/workflows/'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: nextcloud-android-bot --- .github/workflows/codeql.yml | 6 +++--- .github/workflows/scorecard.yml | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index ec075f83d..e7dc2c2b3 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -32,11 +32,11 @@ jobs: with: swap-size-gb: 10 - name: Initialize CodeQL - uses: github/codeql-action/init@67a35a08586135a9573f4327e904ecbf517a882d # v2.2.8 + uses: github/codeql-action/init@04df1262e6247151b5ac09cd2c303ac36ad3f62b # v2.2.9 with: languages: ${{ matrix.language }} - name: Set up JDK - uses: actions/setup-java@3f07048e3d294f56e9b90ac5ea2c6f74e9ad0f98 # v3.10.0 + uses: actions/setup-java@5ffc13f4174014e2d4d4572b3d74c3fa61aeb2c2 # v3.11.0 with: distribution: "temurin" java-version: 11 @@ -46,4 +46,4 @@ jobs: echo "org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError" > "$HOME/.gradle/gradle.properties" ./gradlew assembleDebug - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@67a35a08586135a9573f4327e904ecbf517a882d # v2.2.8 + uses: github/codeql-action/analyze@04df1262e6247151b5ac09cd2c303ac36ad3f62b # v2.2.9 diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 2f9021e6a..a622027b5 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -25,7 +25,7 @@ jobs: persist-credentials: false - name: "Run analysis" - uses: ossf/scorecard-action@e38b1902ae4f44df626f11ba0734b14fb91f8f86 # v2.1.2 + uses: ossf/scorecard-action@80e868c13c90f172d68d1f4501dee99e2479f7af # v2.1.3 with: results_file: results.sarif results_format: sarif @@ -33,6 +33,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@67a35a08586135a9573f4327e904ecbf517a882d # v2.2.8 + uses: github/codeql-action/upload-sarif@04df1262e6247151b5ac09cd2c303ac36ad3f62b # v2.2.9 with: sarif_file: results.sarif -- GitLab From c443381acdf603bc6fe8ddafc25c7d4b0532e365 Mon Sep 17 00:00:00 2001 From: Stefan Niedermann Date: Wed, 5 Apr 2023 11:35:41 +0200 Subject: [PATCH 093/163] fix(i18n): Adjust links to transifex https://help.nextcloud.com/t/transifex-announcement-web-applications-domain-change/159445 Signed-off-by: Stefan Niedermann --- README.md | 4 ++-- app/src/main/res/values/strings.xml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 70e8b03b6..92f3ffb38 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ An android client for [Nextcloud Notes App](https://github.com/nextcloud/notes/) * In-note search * Single note widget and note list widget * Render Markdown (using [Markwon](https://noties.io/Markwon)) - * Translated in many languages on [Transifex](https://www.transifex.com/nextcloud/nextcloud/android-notes/) + * Translated in many languages on [Transifex](https://app.transifex.com/nextcloud/nextcloud/android-notes/) * Context based formatting ([#363](https://github.com/nextcloud/notes-android/issues/363)) * Password protection ([#354](https://github.com/nextcloud/notes-android/issues/354)) @@ -48,7 +48,7 @@ An android client for [Nextcloud Notes App](https://github.com/nextcloud/notes/) * Report issues in the [issue tracker](https://github.com/nextcloud/notes-android/issues) * [Pick a good first issue](https://github.com/nextcloud/notes-android/labels/Good%20first%20issue) :notebook: * Create a [Pull Request](https://opensource.guide/how-to-contribute/#opening-a-pull-request) - * Help translating this app on [Transifex](https://www.transifex.com/nextcloud/nextcloud/android-notes/) 🌎 + * Help translating this app on [Transifex](https://app.transifex.com/nextcloud/nextcloud/android-notes/) 🌎 * Buy this app on [Google Play Store](https://play.google.com/store/apps/details?id=it.niedermann.owncloud.notes) * Send me a bottle of your favorite beer :beers: :wink: diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 87ffff577..c45fa5ba5 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -63,7 +63,7 @@ https://github.com/nextcloud/notes-android https://github.com/nextcloud/notes-android/issues/new/choose https://github.com/nextcloud/notes-android/blob/main/LICENSE - https://www.transifex.com/nextcloud/nextcloud/ + https://app.transifex.com/nextcloud/nextcloud/ https://www.niedermann.it/ https://github.com/nextcloud/notes/blob/76d15214f80f2bf7ea08427bff73ad145128f090/img/notes.svg https://materialdesignicons.com/ -- GitLab From 51074e6a1e4304f78516351bef966e49a7190d30 Mon Sep 17 00:00:00 2001 From: Stefan Niedermann Date: Fri, 7 Apr 2023 15:24:20 +0200 Subject: [PATCH 094/163] fix(theming): Fix category theming Signed-off-by: Stefan Niedermann --- .../owncloud/notes/main/items/NoteViewHolder.java | 7 ++++--- app/src/main/res/layout/item_notes_list_note_item_grid.xml | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/it/niedermann/owncloud/notes/main/items/NoteViewHolder.java b/app/src/main/java/it/niedermann/owncloud/notes/main/items/NoteViewHolder.java index 4baf154d2..cf92dc063 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/main/items/NoteViewHolder.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/main/items/NoteViewHolder.java @@ -72,11 +72,12 @@ public abstract class NoteViewHolder extends RecyclerView.ViewHolder { if (noteCategory instanceof Chip) { util.material.colorChipBackground((Chip) noteCategory); } else { - util.platform.tintDrawable(context, noteCategory.getBackground(), ColorRole.PRIMARY); if (isDarkMode(context)) { - util.platform.colorTextView(noteCategory, ColorRole.ON_PRIMARY); - } else { + util.platform.tintDrawable(context, noteCategory.getBackground(), ColorRole.SECONDARY_CONTAINER); util.platform.colorTextView(noteCategory, ColorRole.ON_SECONDARY_CONTAINER); + } else { + util.platform.tintDrawable(context, noteCategory.getBackground(), ColorRole.PRIMARY); + util.platform.colorTextView(noteCategory, ColorRole.ON_PRIMARY_CONTAINER); } } diff --git a/app/src/main/res/layout/item_notes_list_note_item_grid.xml b/app/src/main/res/layout/item_notes_list_note_item_grid.xml index d9325f195..ecdea4cab 100644 --- a/app/src/main/res/layout/item_notes_list_note_item_grid.xml +++ b/app/src/main/res/layout/item_notes_list_note_item_grid.xml @@ -93,7 +93,7 @@ app:chipEndPadding="@dimen/spacer_1x" app:chipMinHeight="0dp" app:chipStartPadding="@dimen/spacer_1x" - app:chipStrokeColor="@color/defaultBrand" + app:chipStrokeColor="@android:color/transparent" app:chipStrokeWidth="1dp" app:ensureMinTouchTargetSize="false" app:textEndPadding="0dp" -- GitLab From 5fb6d7955af413953217a6bcc19a6f250719065a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Apr 2023 14:03:35 +0000 Subject: [PATCH 095/163] build(deps): Bump peter-evans/create-or-update-comment Bumps [peter-evans/create-or-update-comment](https://github.com/peter-evans/create-or-update-comment) from 2.1.1 to 3.0.0. - [Release notes](https://github.com/peter-evans/create-or-update-comment/releases) - [Commits](https://github.com/peter-evans/create-or-update-comment/compare/67dcc547d311b736a8e6c5c236542148a47adc3d...3383acd359705b10cb1eeef05c0e88c056ea4666) --- updated-dependencies: - dependency-name: peter-evans/create-or-update-comment dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/command-rebase.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/command-rebase.yml b/.github/workflows/command-rebase.yml index 8529e4bae..6d2e42e6d 100644 --- a/.github/workflows/command-rebase.yml +++ b/.github/workflows/command-rebase.yml @@ -23,7 +23,7 @@ jobs: steps: - name: Add reaction on start - uses: peter-evans/create-or-update-comment@67dcc547d311b736a8e6c5c236542148a47adc3d # v2.1.1 + uses: peter-evans/create-or-update-comment@3383acd359705b10cb1eeef05c0e88c056ea4666 # v3.0.0 with: token: ${{ secrets.COMMAND_BOT_PAT }} repository: ${{ github.event.repository.full_name }} @@ -42,7 +42,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.COMMAND_BOT_PAT }} - name: Add reaction on failure - uses: peter-evans/create-or-update-comment@67dcc547d311b736a8e6c5c236542148a47adc3d # v2.1.1 + uses: peter-evans/create-or-update-comment@3383acd359705b10cb1eeef05c0e88c056ea4666 # v3.0.0 if: failure() with: token: ${{ secrets.COMMAND_BOT_PAT }} -- GitLab From 12bc4adb10d395d14527879b19435cd34be0d867 Mon Sep 17 00:00:00 2001 From: nextcloud-android-bot Date: Tue, 11 Apr 2023 02:27:51 +0000 Subject: [PATCH 096/163] =?UTF-8?q?=F0=9F=94=84=20synced=20local=20'.githu?= =?UTF-8?q?b/workflows/'=20with=20remote=20'config/workflows/'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: nextcloud-android-bot --- .github/workflows/codeql.yml | 4 ++-- .github/workflows/scorecard.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index e7dc2c2b3..166052eee 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -32,7 +32,7 @@ jobs: with: swap-size-gb: 10 - name: Initialize CodeQL - uses: github/codeql-action/init@04df1262e6247151b5ac09cd2c303ac36ad3f62b # v2.2.9 + uses: github/codeql-action/init@8c8d71dde4abced210732d8486586914b97752e8 # v2.2.10 with: languages: ${{ matrix.language }} - name: Set up JDK @@ -46,4 +46,4 @@ jobs: echo "org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError" > "$HOME/.gradle/gradle.properties" ./gradlew assembleDebug - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@04df1262e6247151b5ac09cd2c303ac36ad3f62b # v2.2.9 + uses: github/codeql-action/analyze@8c8d71dde4abced210732d8486586914b97752e8 # v2.2.10 diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index a622027b5..03fd9bcd7 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -33,6 +33,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@04df1262e6247151b5ac09cd2c303ac36ad3f62b # v2.2.9 + uses: github/codeql-action/upload-sarif@8c8d71dde4abced210732d8486586914b97752e8 # v2.2.10 with: sarif_file: results.sarif -- GitLab From 1dbde30c46af406f2228bf4c83b09ac93d7cc2de Mon Sep 17 00:00:00 2001 From: Stefan Niedermann Date: Fri, 7 Apr 2023 13:36:13 +0200 Subject: [PATCH 097/163] feat(theming): Align theming closer to files app Follow-Up to https://github.com/nextcloud/notes-android/pull/1680 Signed-off-by: Stefan Niedermann --- .../notes/FormattingHelpActivity.java | 9 +++---- .../owncloud/notes/about/AboutActivity.java | 5 ++-- .../notes/branding/NotesViewThemeUtils.java | 27 +++++++++++++++++-- .../owncloud/notes/edit/EditNoteActivity.java | 3 ++- .../owncloud/notes/main/MainActivity.java | 3 ++- .../ManageAccountsActivity.java | 3 ++- .../preferences/PreferencesActivity.java | 3 ++- app/src/main/res/layout/activity_about.xml | 9 ++----- app/src/main/res/layout/activity_edit.xml | 20 +++++--------- .../main/res/layout/activity_exception.xml | 7 ++--- .../res/layout/activity_formatting_help.xml | 21 +++++---------- .../res/layout/activity_manage_accounts.xml | 21 +++++---------- .../res/layout/activity_notes_list_view.xml | 12 ++++----- .../main/res/layout/activity_preferences.xml | 23 +++++----------- app/src/main/res/values/styles.xml | 1 + 15 files changed, 76 insertions(+), 91 deletions(-) diff --git a/app/src/main/java/it/niedermann/owncloud/notes/FormattingHelpActivity.java b/app/src/main/java/it/niedermann/owncloud/notes/FormattingHelpActivity.java index 6fe0047e3..036d24e93 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/FormattingHelpActivity.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/FormattingHelpActivity.java @@ -1,6 +1,7 @@ package it.niedermann.owncloud.notes; -import android.content.SharedPreferences; +import static it.niedermann.owncloud.notes.shared.util.NoteUtil.getFontSizeFromPreferences; + import android.graphics.Typeface; import android.os.Bundle; import android.text.method.LinkMovementMethod; @@ -10,13 +11,10 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.preference.PreferenceManager; -import it.niedermann.owncloud.notes.R; import it.niedermann.owncloud.notes.branding.BrandedActivity; import it.niedermann.owncloud.notes.branding.BrandingUtil; import it.niedermann.owncloud.notes.databinding.ActivityFormattingHelpBinding; -import static it.niedermann.owncloud.notes.shared.util.NoteUtil.getFontSizeFromPreferences; - public class FormattingHelpActivity extends BrandedActivity { private ActivityFormattingHelpBinding binding; @@ -225,6 +223,7 @@ public class FormattingHelpActivity extends BrandedActivity { @Override public void applyBrand(int color) { final var util = BrandingUtil.of(color, this); - util.notes.applyBrandToPrimaryToolbar(binding.appBar, binding.toolbar, colorAccent); + util.platform.themeStatusBar(this); + util.material.themeToolbar(binding.toolbar); } } diff --git a/app/src/main/java/it/niedermann/owncloud/notes/about/AboutActivity.java b/app/src/main/java/it/niedermann/owncloud/notes/about/AboutActivity.java index 3d871f6a2..1a31d88ca 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/about/AboutActivity.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/about/AboutActivity.java @@ -52,8 +52,9 @@ public class AboutActivity extends LockedActivity { @Override public void applyBrand(int color) { final var util = BrandingUtil.of(color, this); - util.material.themeTabLayout(binding.tabs); - util.notes.applyBrandToPrimaryToolbar(binding.appBar, binding.toolbar, colorAccent); + util.platform.themeStatusBar(this); + util.material.themeToolbar(binding.toolbar); + util.material.themeTabLayoutOnSurface(binding.tabs); } private static class TabsStateAdapter extends FragmentStateAdapter { diff --git a/app/src/main/java/it/niedermann/owncloud/notes/branding/NotesViewThemeUtils.java b/app/src/main/java/it/niedermann/owncloud/notes/branding/NotesViewThemeUtils.java index 5c659afd9..c26b0bf1d 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/branding/NotesViewThemeUtils.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/branding/NotesViewThemeUtils.java @@ -4,6 +4,7 @@ import static com.nextcloud.android.common.ui.util.ColorStateListUtilsKt.buildCo import static com.nextcloud.android.common.ui.util.PlatformThemeUtil.isDarkMode; import android.content.Context; +import android.content.res.ColorStateList; import android.graphics.Color; import android.graphics.PorterDuff; import android.graphics.drawable.LayerDrawable; @@ -21,9 +22,9 @@ import androidx.core.graphics.drawable.DrawableCompat; import com.google.android.material.appbar.AppBarLayout; import com.google.android.material.appbar.MaterialToolbar; +import com.google.android.material.card.MaterialCardView; import com.nextcloud.android.common.ui.theme.MaterialSchemes; import com.nextcloud.android.common.ui.theme.ViewThemeUtilsBase; -import com.nextcloud.android.common.ui.theme.utils.ColorRole; import com.nextcloud.android.common.ui.theme.utils.MaterialViewThemeUtils; import it.niedermann.android.util.ColorUtil; @@ -31,7 +32,6 @@ import it.niedermann.owncloud.notes.R; import it.niedermann.owncloud.notes.main.navigation.NavigationItem; import it.niedermann.owncloud.notes.shared.util.NotesColorUtil; import kotlin.Pair; -import scheme.Scheme; public class NotesViewThemeUtils extends ViewThemeUtilsBase { @@ -148,4 +148,27 @@ public class NotesViewThemeUtils extends ViewThemeUtilsBase { } } } + + /** + * @deprecated Should be replaced with {@link com.google.android.material.search.SearchBar} component. + */ + @Deprecated + public void themeSearchCardView(@NonNull MaterialCardView searchBarWrapper) { + withScheme(searchBarWrapper, scheme -> { + searchBarWrapper.setBackgroundTintList(ColorStateList.valueOf(scheme.getSurface())); + return searchBarWrapper; + }); + } + + /** + * @deprecated Should be replaced with {@link com.google.android.material.search.SearchBar} or {@link MaterialViewThemeUtils#themeToolbar(MaterialToolbar)} + */ + @Deprecated + public void themeSearchToolbar(@NonNull MaterialToolbar toolbar) { + withScheme(toolbar, scheme -> { + toolbar.setNavigationIconTint(scheme.getOnSurface()); + toolbar.setTitleTextColor(scheme.getOnSurface()); + return toolbar; + }); + } } diff --git a/app/src/main/java/it/niedermann/owncloud/notes/edit/EditNoteActivity.java b/app/src/main/java/it/niedermann/owncloud/notes/edit/EditNoteActivity.java index d5306d8ac..71b43db5b 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/edit/EditNoteActivity.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/edit/EditNoteActivity.java @@ -420,6 +420,7 @@ public class EditNoteActivity extends LockedActivity implements BaseNoteFragment @Override public void applyBrand(int color) { final var util = BrandingUtil.of(color, this); - util.notes.applyBrandToPrimaryToolbar(binding.appBar, binding.toolbar, colorAccent); + util.platform.themeStatusBar(this); + util.material.themeToolbar(binding.toolbar); } } 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 479529f30..bcba3df2d 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 @@ -598,7 +598,8 @@ public class MainActivity extends LockedActivity implements NoteClickListener, A util.androidx.themeSwipeRefreshLayout(activityBinding.swiperefreshlayout); util.platform.colorCircularProgressBar(activityBinding.progressCircular, ColorRole.PRIMARY); util.platform.colorNavigationView(binding.navigationView); - util.notes.applyBrandToPrimaryToolbar(activityBinding.appBar, activityBinding.searchToolbar, colorAccent); + util.notes.themeSearchCardView(binding.activityNotesListView.searchBarWrapper); + util.notes.themeSearchToolbar(binding.activityNotesListView.searchToolbar); binding.headerView.setBackgroundColor(color); @ColorInt final int headerTextColor = ColorUtil.INSTANCE.getForegroundColorForBackgroundColor(color); 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 294a530fc..18da71bae 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 @@ -210,6 +210,7 @@ public class ManageAccountsActivity extends LockedActivity implements IManageAcc @Override public void applyBrand(int color) { final var util = BrandingUtil.of(color, this); - util.notes.applyBrandToPrimaryToolbar(binding.appBar, binding.toolbar, colorAccent); + util.platform.themeStatusBar(this); + util.material.themeToolbar(binding.toolbar); } } diff --git a/app/src/main/java/it/niedermann/owncloud/notes/preferences/PreferencesActivity.java b/app/src/main/java/it/niedermann/owncloud/notes/preferences/PreferencesActivity.java index fb3cb8705..8741f76bf 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/preferences/PreferencesActivity.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/preferences/PreferencesActivity.java @@ -34,6 +34,7 @@ public class PreferencesActivity extends LockedActivity { @Override public void applyBrand(int color) { final var util = BrandingUtil.of(color, this); - util.notes.applyBrandToPrimaryToolbar(binding.appBar, binding.toolbar, colorAccent); + util.platform.themeStatusBar(this); + util.material.themeToolbar(binding.toolbar); } } diff --git a/app/src/main/res/layout/activity_about.xml b/app/src/main/res/layout/activity_about.xml index 89c2aaa66..b560bf171 100644 --- a/app/src/main/res/layout/activity_about.xml +++ b/app/src/main/res/layout/activity_about.xml @@ -4,7 +4,6 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" - android:background="?attr/colorPrimary" android:orientation="vertical"> - @@ -26,7 +23,6 @@ android:id="@+id/tabs" android:layout_width="match_parent" android:layout_height="wrap_content" - android:background="?attr/colorPrimary" app:tabMode="fixed" /> @@ -34,7 +30,6 @@ android:id="@+id/pager" android:layout_width="match_parent" android:layout_height="wrap_content" - android:background="?attr/colorPrimary" android:paddingHorizontal="@dimen/spacer_1x" /> \ No newline at end of file diff --git a/app/src/main/res/layout/activity_edit.xml b/app/src/main/res/layout/activity_edit.xml index 8948c0768..4d4b375c9 100644 --- a/app/src/main/res/layout/activity_edit.xml +++ b/app/src/main/res/layout/activity_edit.xml @@ -6,21 +6,13 @@ android:layout_height="match_parent" android:orientation="vertical"> - - - - + android:layout_height="wrap_content" + app:navigationIcon="@drawable/ic_arrow_back_grey600_24dp" + app:titleMarginStart="0dp" + tools:title="Edit Sample note" /> - diff --git a/app/src/main/res/layout/activity_formatting_help.xml b/app/src/main/res/layout/activity_formatting_help.xml index 99dbb182e..ca8450136 100644 --- a/app/src/main/res/layout/activity_formatting_help.xml +++ b/app/src/main/res/layout/activity_formatting_help.xml @@ -4,24 +4,15 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" - android:background="@color/primary" android:orientation="vertical"> - - - - + android:layout_height="wrap_content" + app:navigationIcon="@drawable/ic_arrow_back_grey600_24dp" + app:title="@string/action_formatting_help" + app:titleMarginStart="0dp" /> - - - - + android:layout_height="wrap_content" + app:navigationIcon="@drawable/ic_arrow_back_grey600_24dp" + app:title="@string/manage_accounts" + app:titleMarginStart="0dp" /> - - + - @@ -97,7 +97,7 @@ android:id="@+id/search_view" android:layout_width="match_parent" android:layout_height="wrap_content" /> - + diff --git a/app/src/main/res/layout/activity_preferences.xml b/app/src/main/res/layout/activity_preferences.xml index ec4cce0c9..203d7cff1 100644 --- a/app/src/main/res/layout/activity_preferences.xml +++ b/app/src/main/res/layout/activity_preferences.xml @@ -5,26 +5,17 @@ android:layout_height="match_parent" android:orientation="vertical"> - - - - + android:layout_height="wrap_content" + app:navigationIcon="@drawable/ic_arrow_back_grey600_24dp" + app:title="@string/action_settings" + app:titleMarginStart="0dp" /> + android:layout_height="match_parent" /> \ No newline at end of file diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 661bcfd2f..4d8c787af 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -13,6 +13,7 @@ ?android:colorAccent @color/defaultTextHighlightBackground true + @color/bg_default ?attr/colorPrimary -- GitLab From 8eb9890c8a94ae52ac573afc9764d542e53aa163 Mon Sep 17 00:00:00 2001 From: Stefan Niedermann Date: Fri, 7 Apr 2023 14:01:36 +0200 Subject: [PATCH 098/163] feat(theming): Align theming closer to files app Follow-Up to https://github.com/nextcloud/notes-android/pull/1680 Signed-off-by: Stefan Niedermann --- .../notes/branding/NotesViewThemeUtils.java | 21 +++++++++++++++++++ .../owncloud/notes/main/MainActivity.java | 3 ++- app/src/main/res/layout/activity_about.xml | 1 - app/src/main/res/layout/activity_edit.xml | 1 - .../main/res/layout/activity_exception.xml | 1 - .../res/layout/activity_formatting_help.xml | 3 +-- .../res/layout/activity_manage_accounts.xml | 3 +-- .../res/layout/activity_notes_list_view.xml | 5 ++--- .../main/res/layout/activity_preferences.xml | 3 +-- app/src/main/res/values/styles.xml | 5 +++++ 10 files changed, 33 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/it/niedermann/owncloud/notes/branding/NotesViewThemeUtils.java b/app/src/main/java/it/niedermann/owncloud/notes/branding/NotesViewThemeUtils.java index c26b0bf1d..f1862e4f0 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/branding/NotesViewThemeUtils.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/branding/NotesViewThemeUtils.java @@ -16,6 +16,7 @@ import android.widget.TextView; import androidx.annotation.ColorInt; import androidx.annotation.IdRes; import androidx.annotation.NonNull; +import androidx.appcompat.widget.SearchView; import androidx.appcompat.widget.Toolbar; import androidx.core.content.ContextCompat; import androidx.core.graphics.drawable.DrawableCompat; @@ -171,4 +172,24 @@ public class NotesViewThemeUtils extends ViewThemeUtilsBase { return toolbar; }); } + + /** + * @deprecated Should be replaced with {@link com.google.android.material.search.SearchView} + * @see com.nextcloud.android.common.ui.theme.utils.AndroidXViewThemeUtils#themeToolbarSearchView(SearchView) + */ + @Deprecated + public void themeToolbarSearchView(@NonNull SearchView searchView) { + withScheme(searchView, scheme -> { + // hacky as no default way is provided + final var editText = (SearchView.SearchAutoComplete) searchView.findViewById(androidx.appcompat.R.id.search_src_text); + final var closeButton = (ImageView) searchView.findViewById(androidx.appcompat.R.id.search_close_btn); + final var searchButton = (ImageView) searchView.findViewById(androidx.appcompat.R.id.search_button); + editText.setHintTextColor(scheme.getOnSurfaceVariant()); + editText.setHighlightColor(scheme.getInverseOnSurface()); + editText.setTextColor(scheme.getOnSurface()); + closeButton.setColorFilter(scheme.getOnSurface()); + searchButton.setColorFilter(scheme.getOnSurface()); + return searchView; + }); + } } 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 bcba3df2d..43e482a75 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 @@ -594,12 +594,13 @@ public class MainActivity extends LockedActivity implements NoteClickListener, A @Override public void applyBrand(int color) { final var util = BrandingUtil.of(color, this); - util.material.themeFAB(activityBinding.fabCreate); util.androidx.themeSwipeRefreshLayout(activityBinding.swiperefreshlayout); util.platform.colorCircularProgressBar(activityBinding.progressCircular, ColorRole.PRIMARY); util.platform.colorNavigationView(binding.navigationView); + util.material.themeFAB(activityBinding.fabCreate); util.notes.themeSearchCardView(binding.activityNotesListView.searchBarWrapper); util.notes.themeSearchToolbar(binding.activityNotesListView.searchToolbar); + util.notes.themeToolbarSearchView(binding.activityNotesListView.searchView); binding.headerView.setBackgroundColor(color); @ColorInt final int headerTextColor = ColorUtil.INSTANCE.getForegroundColorForBackgroundColor(color); diff --git a/app/src/main/res/layout/activity_about.xml b/app/src/main/res/layout/activity_about.xml index b560bf171..bf04d6f5f 100644 --- a/app/src/main/res/layout/activity_about.xml +++ b/app/src/main/res/layout/activity_about.xml @@ -16,7 +16,6 @@ android:layout_width="match_parent" android:layout_height="wrap_content" app:navigationIcon="@drawable/ic_arrow_back_grey600_24dp" - app:titleMarginStart="0dp" tools:title="@string/simple_about" /> + app:title="@string/action_formatting_help" /> + app:title="@string/manage_accounts" /> + app:contentInsetStartWithNavigation="0dp"> + app:title="@string/action_settings" /> @dimen/spacer_activity_sides + + \ No newline at end of file diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 6dc7248f0..90dae3ed0 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -6,7 +6,7 @@ ?android:colorPrimary @color/accent - ?attr/colorPrimary + @color/bg_default @bool/isDayMode ?attr/colorAccent ?attr/colorAccent @@ -14,7 +14,7 @@ @color/defaultTextHighlightBackground true @color/bg_default - ?attr/colorPrimary + @color/bg_default -- GitLab From 5cab30bcf19aa97dd9df8ca8096e1e6874e05f1b Mon Sep 17 00:00:00 2001 From: Andy Scherzinger Date: Tue, 11 Apr 2023 10:53:01 +0200 Subject: [PATCH 102/163] reformat for 120 characters line length Signed-off-by: Andy Scherzinger --- .../notes/branding/NotesViewThemeUtils.java | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/it/niedermann/owncloud/notes/branding/NotesViewThemeUtils.java b/app/src/main/java/it/niedermann/owncloud/notes/branding/NotesViewThemeUtils.java index f1862e4f0..d3970b338 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/branding/NotesViewThemeUtils.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/branding/NotesViewThemeUtils.java @@ -88,7 +88,9 @@ public class NotesViewThemeUtils extends ViewThemeUtilsBase { * @deprecated should be replaced by {@link MaterialViewThemeUtils#themeToolbar(MaterialToolbar)}. */ @Deprecated(forRemoval = true) - public void applyBrandToPrimaryToolbar(@NonNull AppBarLayout appBarLayout, @NonNull Toolbar toolbar, @ColorInt int color) { + public void applyBrandToPrimaryToolbar(@NonNull AppBarLayout appBarLayout, + @NonNull Toolbar toolbar, + @ColorInt int color) { // FIXME Workaround for https://github.com/nextcloud/notes-android/issues/889 appBarLayout.setBackgroundColor(ContextCompat.getColor(appBarLayout.getContext(), R.color.primary)); @@ -118,7 +120,10 @@ public class NotesViewThemeUtils extends ViewThemeUtilsBase { } @ColorInt - public int getTextHighlightBackgroundColor(@NonNull Context context, @ColorInt int mainColor, @ColorInt int colorPrimary, @ColorInt int colorAccent) { + public int getTextHighlightBackgroundColor(@NonNull Context context, + @ColorInt int mainColor, + @ColorInt int colorPrimary, + @ColorInt int colorAccent) { if (isDarkMode(context)) { // Dark background if (ColorUtil.INSTANCE.isColorDark(mainColor)) { // Dark brand color if (NotesColorUtil.contrastRatioIsSufficient(mainColor, colorPrimary)) { // But also dark text @@ -162,7 +167,8 @@ public class NotesViewThemeUtils extends ViewThemeUtilsBase { } /** - * @deprecated Should be replaced with {@link com.google.android.material.search.SearchBar} or {@link MaterialViewThemeUtils#themeToolbar(MaterialToolbar)} + * @deprecated Should be replaced with {@link com.google.android.material.search.SearchBar} or + * {@link MaterialViewThemeUtils#themeToolbar(MaterialToolbar)} */ @Deprecated public void themeSearchToolbar(@NonNull MaterialToolbar toolbar) { @@ -181,7 +187,8 @@ public class NotesViewThemeUtils extends ViewThemeUtilsBase { public void themeToolbarSearchView(@NonNull SearchView searchView) { withScheme(searchView, scheme -> { // hacky as no default way is provided - final var editText = (SearchView.SearchAutoComplete) searchView.findViewById(androidx.appcompat.R.id.search_src_text); + final var editText = (SearchView.SearchAutoComplete) searchView + .findViewById(androidx.appcompat.R.id.search_src_text); final var closeButton = (ImageView) searchView.findViewById(androidx.appcompat.R.id.search_close_btn); final var searchButton = (ImageView) searchView.findViewById(androidx.appcompat.R.id.search_button); editText.setHintTextColor(scheme.getOnSurfaceVariant()); -- GitLab From fcd4f8a6ad84755b498aed83305b460d7a7f10c0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 11 Apr 2023 09:32:04 +0000 Subject: [PATCH 103/163] build(deps): Bump github/codeql-action from 2.2.9 to 2.2.11 Bumps [github/codeql-action](https://github.com/github/codeql-action) from 2.2.9 to 2.2.11. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/04df1262e6247151b5ac09cd2c303ac36ad3f62b...d186a2a36cc67bfa1b860e6170d37fb9634742c7) --- updated-dependencies: - dependency-name: github/codeql-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/codeql.yml | 4 ++-- .github/workflows/scorecard.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 166052eee..d34a7b604 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -32,7 +32,7 @@ jobs: with: swap-size-gb: 10 - name: Initialize CodeQL - uses: github/codeql-action/init@8c8d71dde4abced210732d8486586914b97752e8 # v2.2.10 + uses: github/codeql-action/init@d186a2a36cc67bfa1b860e6170d37fb9634742c7 # v2.2.11 with: languages: ${{ matrix.language }} - name: Set up JDK @@ -46,4 +46,4 @@ jobs: echo "org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError" > "$HOME/.gradle/gradle.properties" ./gradlew assembleDebug - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@8c8d71dde4abced210732d8486586914b97752e8 # v2.2.10 + uses: github/codeql-action/analyze@d186a2a36cc67bfa1b860e6170d37fb9634742c7 # v2.2.11 diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 03fd9bcd7..966b21eac 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -33,6 +33,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@8c8d71dde4abced210732d8486586914b97752e8 # v2.2.10 + uses: github/codeql-action/upload-sarif@d186a2a36cc67bfa1b860e6170d37fb9634742c7 # v2.2.11 with: sarif_file: results.sarif -- GitLab From 57eb57747944087289c2145145d05ab6260b5a4d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 11 Apr 2023 09:35:05 +0000 Subject: [PATCH 104/163] build(deps): Bump androidx.core:core-ktx from 1.9.0 to 1.10.0 Bumps androidx.core:core-ktx from 1.9.0 to 1.10.0. --- updated-dependencies: - dependency-name: androidx.core:core-ktx dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 756b04dca..c682590be 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -91,7 +91,7 @@ dependencies { // Android X implementation 'androidx.appcompat:appcompat:1.6.1' - implementation 'androidx.core:core-ktx:1.9.0' + implementation 'androidx.core:core-ktx:1.10.0' implementation 'androidx.core:core-splashscreen:1.0.0' implementation 'androidx.fragment:fragment:1.5.6' implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.1' -- GitLab From cbddf418362bc8cb59bb40ebc17f54878a8dfebe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Brey?= Date: Wed, 8 Mar 2023 12:35:48 +0100 Subject: [PATCH 105/163] chore: Increment minor version on main branch with fastlane incrementVersion type:minor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Álvaro Brey --- app/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index c682590be..5f1b1f6e8 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -14,8 +14,8 @@ android { applicationId "it.niedermann.owncloud.notes" minSdkVersion 23 targetSdkVersion 33 - versionCode 40000000 - versionName "4.0.0 Alpha 1" + versionCode 40010000 + versionName "4.1.0 Alpha1" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" javaCompileOptions { annotationProcessorOptions { -- GitLab From dcec2bafb98590de4bda12435287310ecc8e146e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 12 Apr 2023 02:03:00 +0000 Subject: [PATCH 106/163] build(deps): Bump org.mockito:mockito-core from 5.2.0 to 5.3.0 Bumps [org.mockito:mockito-core](https://github.com/mockito/mockito) from 5.2.0 to 5.3.0. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v5.2.0...v5.3.0) --- updated-dependencies: - dependency-name: org.mockito:mockito-core dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 5f1b1f6e8..12bc9014e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -120,7 +120,7 @@ dependencies { testImplementation 'androidx.test:core:1.5.0' testImplementation 'androidx.arch.core:core-testing:2.2.0' testImplementation 'junit:junit:4.13.2' - testImplementation 'org.mockito:mockito-core:5.2.0' + testImplementation 'org.mockito:mockito-core:5.3.0' testImplementation 'org.robolectric:robolectric:4.9.2' implementation fileTree(dir: 'libs', include: ['*.jar']) -- GitLab From cfe10a0755d178462836a2530458afbf7915262c Mon Sep 17 00:00:00 2001 From: nextcloud-android-bot Date: Wed, 12 Apr 2023 02:28:09 +0000 Subject: [PATCH 107/163] =?UTF-8?q?=F0=9F=94=84=20synced=20local=20'.githu?= =?UTF-8?q?b/workflows/'=20with=20remote=20'config/workflows/'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: nextcloud-android-bot --- .github/workflows/codeql.yml | 4 ++-- .github/workflows/scorecard.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index d34a7b604..166052eee 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -32,7 +32,7 @@ jobs: with: swap-size-gb: 10 - name: Initialize CodeQL - uses: github/codeql-action/init@d186a2a36cc67bfa1b860e6170d37fb9634742c7 # v2.2.11 + uses: github/codeql-action/init@8c8d71dde4abced210732d8486586914b97752e8 # v2.2.10 with: languages: ${{ matrix.language }} - name: Set up JDK @@ -46,4 +46,4 @@ jobs: echo "org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError" > "$HOME/.gradle/gradle.properties" ./gradlew assembleDebug - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@d186a2a36cc67bfa1b860e6170d37fb9634742c7 # v2.2.11 + uses: github/codeql-action/analyze@8c8d71dde4abced210732d8486586914b97752e8 # v2.2.10 diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 966b21eac..03fd9bcd7 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -33,6 +33,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@d186a2a36cc67bfa1b860e6170d37fb9634742c7 # v2.2.11 + uses: github/codeql-action/upload-sarif@8c8d71dde4abced210732d8486586914b97752e8 # v2.2.10 with: sarif_file: results.sarif -- GitLab From 437e63c06cf5a820a482ffd092635b11e33eeda8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 12 Apr 2023 06:22:47 +0000 Subject: [PATCH 108/163] build(deps): Bump org.robolectric:robolectric from 4.9.2 to 4.10 Bumps [org.robolectric:robolectric](https://github.com/robolectric/robolectric) from 4.9.2 to 4.10. - [Release notes](https://github.com/robolectric/robolectric/releases) - [Commits](https://github.com/robolectric/robolectric/compare/robolectric-4.9.2...robolectric-4.10) --- updated-dependencies: - dependency-name: org.robolectric:robolectric dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 12bc9014e..d739a3ee4 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -121,7 +121,7 @@ dependencies { testImplementation 'androidx.arch.core:core-testing:2.2.0' testImplementation 'junit:junit:4.13.2' testImplementation 'org.mockito:mockito-core:5.3.0' - testImplementation 'org.robolectric:robolectric:4.9.2' + testImplementation 'org.robolectric:robolectric:4.10' implementation fileTree(dir: 'libs', include: ['*.jar']) } -- GitLab From 9acc56d736bcd2cd48c3090b303f5bb78bbf328f Mon Sep 17 00:00:00 2001 From: nextcloud-android-bot Date: Mon, 17 Apr 2023 02:39:39 +0000 Subject: [PATCH 109/163] =?UTF-8?q?=F0=9F=94=84=20synced=20local=20'.githu?= =?UTF-8?q?b/workflows/'=20with=20remote=20'config/workflows/'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: nextcloud-android-bot --- .github/workflows/codeql.yml | 6 +++--- .github/workflows/gradle-wrapper-validation.yml | 2 +- .github/workflows/scorecard.yml | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 166052eee..83ea2c1c2 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -26,13 +26,13 @@ jobs: language: [ 'java' ] steps: - name: Checkout repository - uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3 # v3.5.0 + uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 - name: Set Swap Space uses: pierotofy/set-swap-space@49819abfb41bd9b44fb781159c033dba90353a7c # v1.0 with: swap-size-gb: 10 - name: Initialize CodeQL - uses: github/codeql-action/init@8c8d71dde4abced210732d8486586914b97752e8 # v2.2.10 + uses: github/codeql-action/init@7df0ce34898d659f95c0c4a09eaa8d4e32ee64db # v2.2.12 with: languages: ${{ matrix.language }} - name: Set up JDK @@ -46,4 +46,4 @@ jobs: echo "org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError" > "$HOME/.gradle/gradle.properties" ./gradlew assembleDebug - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@8c8d71dde4abced210732d8486586914b97752e8 # v2.2.10 + uses: github/codeql-action/analyze@7df0ce34898d659f95c0c4a09eaa8d4e32ee64db # v2.2.12 diff --git a/.github/workflows/gradle-wrapper-validation.yml b/.github/workflows/gradle-wrapper-validation.yml index 66cf73678..be44c9e6a 100644 --- a/.github/workflows/gradle-wrapper-validation.yml +++ b/.github/workflows/gradle-wrapper-validation.yml @@ -14,5 +14,5 @@ jobs: name: "Validation" runs-on: ubuntu-latest steps: - - uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3 # v3.5.0 + - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 - uses: gradle/wrapper-validation-action@8d49e559aae34d3e0eb16cde532684bc9702762b # v1.0.6 diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 03fd9bcd7..be01ef331 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -20,7 +20,7 @@ jobs: steps: - name: "Checkout code" - uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3 # v3.5.0 + uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 with: persist-credentials: false @@ -33,6 +33,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@8c8d71dde4abced210732d8486586914b97752e8 # v2.2.10 + uses: github/codeql-action/upload-sarif@7df0ce34898d659f95c0c4a09eaa8d4e32ee64db # v2.2.12 with: sarif_file: results.sarif -- GitLab From 05cfad76e1a9bd1ee1f77af688a813a1ce3a22d1 Mon Sep 17 00:00:00 2001 From: tobiasKaminsky Date: Fri, 24 Mar 2023 08:51:16 +0100 Subject: [PATCH 110/163] Set minSdkVersion to 24 + remove checks Signed-off-by: tobiasKaminsky --- app/build.gradle | 2 +- .../owncloud/notes/quicksettings/NewNoteTileService.java | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index d739a3ee4..3f253a946 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -12,7 +12,7 @@ android { defaultConfig { applicationId "it.niedermann.owncloud.notes" - minSdkVersion 23 + minSdkVersion 24 targetSdkVersion 33 versionCode 40010000 versionName "4.1.0 Alpha1" diff --git a/app/src/main/java/it/niedermann/owncloud/notes/quicksettings/NewNoteTileService.java b/app/src/main/java/it/niedermann/owncloud/notes/quicksettings/NewNoteTileService.java index d660f182e..56bb20b53 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/quicksettings/NewNoteTileService.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/quicksettings/NewNoteTileService.java @@ -1,8 +1,6 @@ package it.niedermann.owncloud.notes.quicksettings; -import android.annotation.TargetApi; import android.content.Intent; -import android.os.Build; import android.service.quicksettings.Tile; import android.service.quicksettings.TileService; @@ -11,7 +9,6 @@ import it.niedermann.owncloud.notes.edit.EditNoteActivity; /** * This {@link TileService} adds a quick settings tile that leads to the new note view. */ -@TargetApi(Build.VERSION_CODES.N) public class NewNoteTileService extends TileService { @Override -- GitLab From ec519d94e31f8b4a095ac5809138f27b504beae1 Mon Sep 17 00:00:00 2001 From: Andy Scherzinger Date: Mon, 17 Apr 2023 14:20:26 +0200 Subject: [PATCH 111/163] bump robolectric to min 24 Signed-off-by: Andy Scherzinger --- app/src/test/resources/robolectric.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/test/resources/robolectric.properties b/app/src/test/resources/robolectric.properties index 5d28440d3..e23ee50f1 100644 --- a/app/src/test/resources/robolectric.properties +++ b/app/src/test/resources/robolectric.properties @@ -1 +1 @@ -sdk=23, 30 \ No newline at end of file +sdk=24, 30 \ No newline at end of file -- GitLab From d22093ff608aebdcf974d40485e951e3a79f0b5b Mon Sep 17 00:00:00 2001 From: tobiasKaminsky Date: Mon, 17 Apr 2023 11:30:25 +0200 Subject: [PATCH 112/163] Streamline commons version Signed-off-by: tobiasKaminsky --- app/build.gradle | 8 ++++---- .../niedermann/owncloud/notes/main/menu/MenuAdapter.java | 9 ++++----- build.gradle | 1 + 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 3f253a946..c0edb3f3c 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -77,11 +77,11 @@ dependencies { // Nextcloud SSO implementation 'com.github.nextcloud.android-common:ui:0.8.0' - implementation 'com.github.nextcloud:Android-SingleSignOn:0.6.1' + implementation 'com.github.nextcloud:Android-SingleSignOn:0.7.0' implementation 'com.github.stefan-niedermann:android-commons:0.2.9' - implementation 'com.github.stefan-niedermann.nextcloud-commons:sso-glide:1.6.4' - implementation 'com.github.stefan-niedermann.nextcloud-commons:exception:1.6.4' - implementation('com.github.stefan-niedermann.nextcloud-commons:markdown:1.6.4') { + implementation "com.github.stefan-niedermann.nextcloud-commons:sso-glide:$commonsVersion" + implementation "com.github.stefan-niedermann.nextcloud-commons:exception:$commonsVersion" + implementation("com.github.stefan-niedermann.nextcloud-commons:markdown:$commonsVersion") { exclude group: 'org.jetbrains', module: 'annotations-java5' } diff --git a/app/src/main/java/it/niedermann/owncloud/notes/main/menu/MenuAdapter.java b/app/src/main/java/it/niedermann/owncloud/notes/main/menu/MenuAdapter.java index f920813d2..855cda890 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/main/menu/MenuAdapter.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/main/menu/MenuAdapter.java @@ -12,13 +12,12 @@ import androidx.annotation.NonNull; import androidx.core.util.Consumer; import androidx.recyclerview.widget.RecyclerView; -import com.nextcloud.android.sso.Constants; import com.nextcloud.android.sso.helper.VersionCheckHelper; +import com.nextcloud.android.sso.model.FilesAppType; import it.niedermann.owncloud.notes.FormattingHelpActivity; import it.niedermann.owncloud.notes.R; import it.niedermann.owncloud.notes.about.AboutActivity; -import it.niedermann.owncloud.notes.branding.BrandingUtil; import it.niedermann.owncloud.notes.databinding.ItemNavigationBinding; import it.niedermann.owncloud.notes.persistence.entity.Account; import it.niedermann.owncloud.notes.preferences.PreferencesActivity; @@ -79,9 +78,9 @@ public class MenuAdapter extends RecyclerView.Adapter { // https://github.com/nextcloud/android/pull/8405#issuecomment-852966877 final int minVersionCode = 30170090; try { - if (VersionCheckHelper.getNextcloudFilesVersionCode(context, true) > minVersionCode) { + if (VersionCheckHelper.getNextcloudFilesVersionCode(context, FilesAppType.PROD) > minVersionCode) { return generateTrashbinAppIntent(context, account, true); - } else if (VersionCheckHelper.getNextcloudFilesVersionCode(context, false) > minVersionCode) { + } else if (VersionCheckHelper.getNextcloudFilesVersionCode(context, FilesAppType.DEV) > minVersionCode) { return generateTrashbinAppIntent(context, account, false); } else { // Files app is too old to be able to switch the account when launching the TrashbinActivity @@ -95,7 +94,7 @@ public class MenuAdapter extends RecyclerView.Adapter { private static Intent generateTrashbinAppIntent(@NonNull Context context, @NonNull Account account, boolean prod) throws PackageManager.NameNotFoundException { final var packageManager = context.getPackageManager(); - final String packageName = prod ? Constants.PACKAGE_NAME_PROD : Constants.PACKAGE_NAME_DEV; + final String packageName = prod ? FilesAppType.PROD.packageId : FilesAppType.DEV.packageId; final var intent = new Intent(); intent.setClassName(packageName, "com.owncloud.android.ui.trashbin.TrashbinActivity"); if (packageManager.resolveActivity(intent, 0) != null) { diff --git a/build.gradle b/build.gradle index 5d898a6b4..fcc04a018 100644 --- a/build.gradle +++ b/build.gradle @@ -3,6 +3,7 @@ buildscript { ext { kotlinVersion = '1.8.20' + commonsVersion = '1.7.0' } repositories { mavenCentral() -- GitLab From 908ecbd60986c931e2d280ee8007e62d10ddee38 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Apr 2023 02:09:06 +0000 Subject: [PATCH 113/163] build(deps): Bump org.mockito:mockito-core from 5.3.0 to 5.3.1 Bumps [org.mockito:mockito-core](https://github.com/mockito/mockito) from 5.3.0 to 5.3.1. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v5.3.0...v5.3.1) --- updated-dependencies: - dependency-name: org.mockito:mockito-core dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index c0edb3f3c..dc74bb98a 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -120,7 +120,7 @@ dependencies { testImplementation 'androidx.test:core:1.5.0' testImplementation 'androidx.arch.core:core-testing:2.2.0' testImplementation 'junit:junit:4.13.2' - testImplementation 'org.mockito:mockito-core:5.3.0' + testImplementation 'org.mockito:mockito-core:5.3.1' testImplementation 'org.robolectric:robolectric:4.10' implementation fileTree(dir: 'libs', include: ['*.jar']) -- GitLab From 84635be80ea0a30a2cf8cb958253882624d76c3c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 26 Apr 2023 02:07:28 +0000 Subject: [PATCH 114/163] build(deps): Bump org.jetbrains.kotlin:kotlin-gradle-plugin Bumps [org.jetbrains.kotlin:kotlin-gradle-plugin](https://github.com/JetBrains/kotlin) from 1.8.20 to 1.8.21. - [Release notes](https://github.com/JetBrains/kotlin/releases) - [Changelog](https://github.com/JetBrains/kotlin/blob/master/ChangeLog.md) - [Commits](https://github.com/JetBrains/kotlin/compare/v1.8.20...v1.8.21) --- updated-dependencies: - dependency-name: org.jetbrains.kotlin:kotlin-gradle-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index fcc04a018..1ccfb64c8 100644 --- a/build.gradle +++ b/build.gradle @@ -2,7 +2,7 @@ buildscript { ext { - kotlinVersion = '1.8.20' + kotlinVersion = '1.8.21' commonsVersion = '1.7.0' } repositories { -- GitLab From 3fd7e37694e44ea1fdf19da38822c809b7f89e75 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 5 May 2023 02:01:44 +0000 Subject: [PATCH 115/163] build(deps): Bump com.google.android.material:material Bumps [com.google.android.material:material](https://github.com/material-components/material-components-android) from 1.8.0 to 1.9.0. - [Release notes](https://github.com/material-components/material-components-android/releases) - [Commits](https://github.com/material-components/material-components-android/compare/1.8.0...1.9.0) --- updated-dependencies: - dependency-name: com.google.android.material:material dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index c0edb3f3c..6c8eb10c8 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -100,7 +100,7 @@ dependencies { implementation 'androidx.recyclerview:recyclerview:1.3.0' implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0' implementation 'androidx.work:work-runtime:2.8.1' - implementation 'com.google.android.material:material:1.8.0' + implementation 'com.google.android.material:material:1.9.0' // Database implementation "androidx.room:room-runtime:${roomVersion}" -- GitLab From d1047254af4593c083d26862192edb70573a5934 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 May 2023 14:03:56 +0000 Subject: [PATCH 116/163] build(deps): Bump peter-evans/create-or-update-comment Bumps [peter-evans/create-or-update-comment](https://github.com/peter-evans/create-or-update-comment) from 3.0.0 to 3.0.1. - [Release notes](https://github.com/peter-evans/create-or-update-comment/releases) - [Commits](https://github.com/peter-evans/create-or-update-comment/compare/3383acd359705b10cb1eeef05c0e88c056ea4666...ca08ebd5dc95aa0cd97021e9708fcd6b87138c9b) --- updated-dependencies: - dependency-name: peter-evans/create-or-update-comment dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/command-rebase.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/command-rebase.yml b/.github/workflows/command-rebase.yml index 6d2e42e6d..03109861e 100644 --- a/.github/workflows/command-rebase.yml +++ b/.github/workflows/command-rebase.yml @@ -23,7 +23,7 @@ jobs: steps: - name: Add reaction on start - uses: peter-evans/create-or-update-comment@3383acd359705b10cb1eeef05c0e88c056ea4666 # v3.0.0 + uses: peter-evans/create-or-update-comment@ca08ebd5dc95aa0cd97021e9708fcd6b87138c9b # v3.0.1 with: token: ${{ secrets.COMMAND_BOT_PAT }} repository: ${{ github.event.repository.full_name }} @@ -42,7 +42,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.COMMAND_BOT_PAT }} - name: Add reaction on failure - uses: peter-evans/create-or-update-comment@3383acd359705b10cb1eeef05c0e88c056ea4666 # v3.0.0 + uses: peter-evans/create-or-update-comment@ca08ebd5dc95aa0cd97021e9708fcd6b87138c9b # v3.0.1 if: failure() with: token: ${{ secrets.COMMAND_BOT_PAT }} -- GitLab From fbe34bbd09e160b7a50c69803b79ff74cbca4070 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 11 May 2023 02:01:33 +0000 Subject: [PATCH 117/163] build(deps): Bump androidx.core:core-ktx from 1.10.0 to 1.10.1 Bumps androidx.core:core-ktx from 1.10.0 to 1.10.1. --- updated-dependencies: - dependency-name: androidx.core:core-ktx dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index c0edb3f3c..6e3a53038 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -91,7 +91,7 @@ dependencies { // Android X implementation 'androidx.appcompat:appcompat:1.6.1' - implementation 'androidx.core:core-ktx:1.10.0' + implementation 'androidx.core:core-ktx:1.10.1' implementation 'androidx.core:core-splashscreen:1.0.0' implementation 'androidx.fragment:fragment:1.5.6' implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.1' -- GitLab From d32acf871f6c40af7c3c1fd0832b1c4500f78048 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 May 2023 02:09:17 +0000 Subject: [PATCH 118/163] build(deps): Bump com.github.nextcloud.android-common:ui Bumps [com.github.nextcloud.android-common:ui](https://github.com/nextcloud/android-common) from 0.8.0 to 0.10.0. - [Release notes](https://github.com/nextcloud/android-common/releases) - [Commits](https://github.com/nextcloud/android-common/compare/0.8.0...0.10.0) --- updated-dependencies: - dependency-name: com.github.nextcloud.android-common:ui dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index c0edb3f3c..4176a55e1 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -76,7 +76,7 @@ dependencies { coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.3' // Nextcloud SSO - implementation 'com.github.nextcloud.android-common:ui:0.8.0' + implementation 'com.github.nextcloud.android-common:ui:0.10.0' implementation 'com.github.nextcloud:Android-SingleSignOn:0.7.0' implementation 'com.github.stefan-niedermann:android-commons:0.2.9' implementation "com.github.stefan-niedermann.nextcloud-commons:sso-glide:$commonsVersion" -- GitLab From 75fec90c618741699f6f6be2cc2bf1749dec4fb9 Mon Sep 17 00:00:00 2001 From: nextcloud-android-bot Date: Tue, 16 May 2023 02:31:48 +0000 Subject: [PATCH 119/163] =?UTF-8?q?=F0=9F=94=84=20synced=20local=20'.githu?= =?UTF-8?q?b/workflows/'=20with=20remote=20'config/workflows/'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: nextcloud-android-bot --- .github/workflows/codeql.yml | 6 +++--- .github/workflows/scorecard.yml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 83ea2c1c2..3cda0501e 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -32,18 +32,18 @@ jobs: with: swap-size-gb: 10 - name: Initialize CodeQL - uses: github/codeql-action/init@7df0ce34898d659f95c0c4a09eaa8d4e32ee64db # v2.2.12 + uses: github/codeql-action/init@29b1f65c5e92e24fe6b6647da1eaabe529cec70f # v2.3.3 with: languages: ${{ matrix.language }} - name: Set up JDK uses: actions/setup-java@5ffc13f4174014e2d4d4572b3d74c3fa61aeb2c2 # v3.11.0 with: distribution: "temurin" - java-version: 11 + java-version: 17 - name: Assemble run: | mkdir -p "$HOME/.gradle" echo "org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError" > "$HOME/.gradle/gradle.properties" ./gradlew assembleDebug - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@7df0ce34898d659f95c0c4a09eaa8d4e32ee64db # v2.2.12 + uses: github/codeql-action/analyze@29b1f65c5e92e24fe6b6647da1eaabe529cec70f # v2.3.3 diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index be01ef331..6585f8be6 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -33,6 +33,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@7df0ce34898d659f95c0c4a09eaa8d4e32ee64db # v2.2.12 + uses: github/codeql-action/upload-sarif@29b1f65c5e92e24fe6b6647da1eaabe529cec70f # v2.3.3 with: sarif_file: results.sarif -- GitLab From 74e65d196308e97c2adfc4bbf656fbebb6f9ab55 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 21 Apr 2023 02:02:21 +0000 Subject: [PATCH 120/163] build(deps): Bump androidx.core:core-splashscreen from 1.0.0 to 1.0.1 Bumps androidx.core:core-splashscreen from 1.0.0 to 1.0.1. --- updated-dependencies: - dependency-name: androidx.core:core-splashscreen dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 90860ee85..d3d8ee434 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -92,7 +92,7 @@ dependencies { // Android X implementation 'androidx.appcompat:appcompat:1.6.1' implementation 'androidx.core:core-ktx:1.10.1' - implementation 'androidx.core:core-splashscreen:1.0.0' + implementation 'androidx.core:core-splashscreen:1.0.1' implementation 'androidx.fragment:fragment:1.5.6' implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.1' implementation 'androidx.preference:preference:1.2.0' -- GitLab From baec4126a980c4c9a06ec4a4de06865a844ac562 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 21 Apr 2023 02:02:27 +0000 Subject: [PATCH 121/163] build(deps): Bump androidx.fragment:fragment from 1.5.6 to 1.5.7 Bumps androidx.fragment:fragment from 1.5.6 to 1.5.7. --- updated-dependencies: - dependency-name: androidx.fragment:fragment dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index d3d8ee434..7c9febde4 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -93,7 +93,7 @@ dependencies { implementation 'androidx.appcompat:appcompat:1.6.1' implementation 'androidx.core:core-ktx:1.10.1' implementation 'androidx.core:core-splashscreen:1.0.1' - implementation 'androidx.fragment:fragment:1.5.6' + implementation 'androidx.fragment:fragment:1.5.7' implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.1' implementation 'androidx.preference:preference:1.2.0' implementation 'androidx.recyclerview:recyclerview-selection:1.1.0' -- GitLab From 9661b627b5dda0ab54639334973416d51695f7aa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 5 May 2023 02:01:37 +0000 Subject: [PATCH 122/163] build(deps): Bump org.robolectric:robolectric from 4.10 to 4.10.2 Bumps [org.robolectric:robolectric](https://github.com/robolectric/robolectric) from 4.10 to 4.10.2. - [Release notes](https://github.com/robolectric/robolectric/releases) - [Commits](https://github.com/robolectric/robolectric/compare/robolectric-4.10...robolectric-4.10.2) --- updated-dependencies: - dependency-name: org.robolectric:robolectric dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 928a3a21a..bdbffa5ad 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -121,7 +121,7 @@ dependencies { testImplementation 'androidx.arch.core:core-testing:2.2.0' testImplementation 'junit:junit:4.13.2' testImplementation 'org.mockito:mockito-core:5.3.1' - testImplementation 'org.robolectric:robolectric:4.10' + testImplementation 'org.robolectric:robolectric:4.10.2' implementation fileTree(dir: 'libs', include: ['*.jar']) } -- GitLab From 2dbc1681f82d8aaffdef472fb175b3f38e2059ae Mon Sep 17 00:00:00 2001 From: Nextcloud bot Date: Thu, 18 May 2023 02:31:20 +0000 Subject: [PATCH 123/163] Fix(l10n): Update translations from Transifex Signed-off-by: Nextcloud bot --- app/src/main/res/values-ar/strings.xml | 8 +- app/src/main/res/values-b+en+001/strings.xml | 17 ++-- app/src/main/res/values-bg-rBG/strings.xml | 17 ++-- app/src/main/res/values-ca/strings.xml | 10 +-- app/src/main/res/values-cs-rCZ/strings.xml | 17 ++-- app/src/main/res/values-da/strings.xml | 42 ++++++--- app/src/main/res/values-de/strings.xml | 17 ++-- app/src/main/res/values-el/strings.xml | 8 +- app/src/main/res/values-es/strings.xml | 19 ++-- app/src/main/res/values-eu/strings.xml | 17 ++-- app/src/main/res/values-fa/strings.xml | 8 +- app/src/main/res/values-fi-rFI/strings.xml | 10 +-- app/src/main/res/values-fr/strings.xml | 19 ++-- app/src/main/res/values-gl/strings.xml | 57 +++++++----- app/src/main/res/values-he/strings.xml | 8 +- app/src/main/res/values-hr/strings.xml | 10 +-- app/src/main/res/values-hu-rHU/strings.xml | 17 ++-- app/src/main/res/values-it/strings.xml | 10 +-- app/src/main/res/values-ja-rJP/strings.xml | 10 +-- app/src/main/res/values-ko/strings.xml | 10 +-- app/src/main/res/values-lt-rLT/strings.xml | 8 +- app/src/main/res/values-nb-rNO/strings.xml | 93 +++++++++++++++++--- app/src/main/res/values-nl/strings.xml | 13 ++- app/src/main/res/values-oc/strings.xml | 1 + app/src/main/res/values-pl/strings.xml | 17 ++-- app/src/main/res/values-pt-rBR/strings.xml | 17 ++-- app/src/main/res/values-ro/strings.xml | 10 +-- app/src/main/res/values-ru/strings.xml | 17 ++-- app/src/main/res/values-sc/strings.xml | 8 +- app/src/main/res/values-sk-rSK/strings.xml | 10 +-- app/src/main/res/values-sl/strings.xml | 14 +-- app/src/main/res/values-sr/strings.xml | 79 +++++++++++++++-- app/src/main/res/values-sv/strings.xml | 17 ++-- app/src/main/res/values-tr/strings.xml | 19 ++-- app/src/main/res/values-uk/strings.xml | 27 +++--- app/src/main/res/values-vi/strings.xml | 15 ++-- app/src/main/res/values-zh-rCN/strings.xml | 10 +-- app/src/main/res/values-zh-rHK/strings.xml | 17 ++-- app/src/main/res/values-zh-rTW/strings.xml | 10 +-- 39 files changed, 469 insertions(+), 264 deletions(-) diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index c0d35a647..5de414901 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -153,11 +153,8 @@ إدارة الحسابات التنسيق - - فتح في وضع التحرير - فتح في وضع المعاينة - تذكر آخر ما أخترته - + + تذكر آخر ما أخترته صغير @@ -235,4 +232,5 @@ التالي السابق النسخ الاحتياطي + العودة diff --git a/app/src/main/res/values-b+en+001/strings.xml b/app/src/main/res/values-b+en+001/strings.xml index 76db2177b..f18305508 100644 --- a/app/src/main/res/values-b+en+001/strings.xml +++ b/app/src/main/res/values-b+en+001/strings.xml @@ -41,6 +41,7 @@ Last month Display mode for notes + Notes opening behaviour Theme Monospace font Font size @@ -63,6 +64,7 @@ You are currently using %1$s Maintainer Developers + original author Translators Nextcloud community on %1$s Testers @@ -177,11 +179,11 @@ Manage accounts Formatting - - Open in edit mode - Open in preview mode - Remember my last selection - + + Plain edit mode + Plain preview + Rich edit mode + Remember my last selection Small @@ -302,4 +304,7 @@ Importing notes… Importing note %1$d of %2$d… Account imported. - + Error while loading rich editing + Switch to plain editing + Back + diff --git a/app/src/main/res/values-bg-rBG/strings.xml b/app/src/main/res/values-bg-rBG/strings.xml index c38873423..3515961f1 100644 --- a/app/src/main/res/values-bg-rBG/strings.xml +++ b/app/src/main/res/values-bg-rBG/strings.xml @@ -41,6 +41,7 @@ Миналия месец Режим на показване на бележки + Поведение при отваряне на бележките Тема Monospace/Монопространствен/ шрифт Размер на шрифта @@ -63,6 +64,7 @@ В момента използвате%1$s Отговорник Разработчици + оригинален автор Преводачи Nextcloud общност на %1$s Тестери @@ -177,11 +179,11 @@ Управление на профилите Форматиране - - Отваряне в режим за редактиране - Отваряне в режим на визуализация - Запаметяване на последният ми избор - + + Режим на обикновено редактиране + Обикновен преглед + Режим на богато редактиране + Запаметяване на последният ми избор Малък @@ -302,4 +304,7 @@ Импортиране на бележки... Импортиране на бележка%1$d от %2$d... Профилът е импортиран. - + Грешка при зареждане на богато редактиране + Превключване към обикновено редактиране + Назад + diff --git a/app/src/main/res/values-ca/strings.xml b/app/src/main/res/values-ca/strings.xml index 7a1a01a2d..491b49ba0 100644 --- a/app/src/main/res/values-ca/strings.xml +++ b/app/src/main/res/values-ca/strings.xml @@ -177,11 +177,8 @@ Gestiona els comptes Format - - Obre en mode d\'edició - Obre en mode de previsualització - Recorda la darrera selecció - + + Recorda la darrera selecció Petita @@ -302,4 +299,5 @@ S\'estan important les notes... S\'està important la nota %1$d/%2$d... S\'ha importat el compte. - + Torna + diff --git a/app/src/main/res/values-cs-rCZ/strings.xml b/app/src/main/res/values-cs-rCZ/strings.xml index b713fdfd9..7dfe70f4c 100644 --- a/app/src/main/res/values-cs-rCZ/strings.xml +++ b/app/src/main/res/values-cs-rCZ/strings.xml @@ -41,6 +41,7 @@ Minulý měsíc Režim zobrazení poznámek + Chování Poznámek při otevírání Motiv vzhledu Písmo se všemi znaky stejně širokými Velikost písmen @@ -63,6 +64,7 @@ Nyní používáte %1$s Vývoj spravuje Vývojáři + původní autor Překladatelé Nextcloud komunita na portálu %1$s Testeři @@ -177,11 +179,11 @@ Spravovat účty Formátování - - Otevřít v režimu úprav - Otevřít v náhledovém režimu - Zapamatovat si můj poslední výběr - + + Režim upravování neformátovaného textu + Náhled neformátovaného textu + Režim upravování formátovaného textu + Zapamatovat si můj poslední výběr Malé @@ -312,4 +314,7 @@ Importují se poznámky… Importuje se poznámka %1$d z %2$d… Účet naimportován. - + Chyba při načítání upravování formátovaného textu + Přepnout do upravování neformátovaného textu + Zpět + diff --git a/app/src/main/res/values-da/strings.xml b/app/src/main/res/values-da/strings.xml index 322be1ef2..56c49e542 100644 --- a/app/src/main/res/values-da/strings.xml +++ b/app/src/main/res/values-da/strings.xml @@ -11,7 +11,7 @@ Slettede noter Søg Sorteringsmetode - Annuller + Annullér Byt rundt Rediger Fjern @@ -41,13 +41,18 @@ Seneste måned Visningstilstand for noter + Ved åbning af note Tema Monospace font Skriftstørrelse - Synk kun på Wi-Fi + Synkronisér kun på Wi-Fi Enheds legitimationsoplysninger Synkronisering i baggrunden + Forhindr skærmoptagelse Grid visning + Hold skærmen tændt + Mens du læser eller redigerer en note + Synkronisering fejlede: %1$s Synkroniseringen mislykkedes Ingen netværksforbindelse @@ -88,12 +93,12 @@ Opret en ny note Normal - Synk på Wi-Fi og mobil data + Synkronisér på Wi-Fi og mobil data Password protection Fejl Luk - Kopier + Kopiér Undtagelse Fastgør til hjemmeskærm Denne note er blevet slettet @@ -103,7 +108,9 @@ Film Film Arbejde + Tjeklister Opgaver + Opskrift Opskrifter Adgangskode Adgangskoder @@ -118,7 +125,7 @@ Skrivebeskyttet Ingen kategori Tilføj %1$s - Afkrydsningsfeldt + Afkrydsningsfelt Lås noter op Åh nej - hvad nu? 🙁 Forsøg venligst at tvinge app\'en til at lukke og start den påny igen. Der kan have været en ukorrekt forbindelse til Nextcloud-app\'en. @@ -139,17 +146,15 @@ Den delte tekst var tom Tilføj til note Skift titel på note - Rediger titel + Redigér titel Sikkerhed - Synchronization - Administrer konti + Udseende og adfærd + Synkronisering + Administrér konti Formatering - - Åbn i redigeringstilstand - Åbn forhåndsvisning - Husk mine sidste selektion - + + Husk mit sidste valg Lille @@ -190,6 +195,7 @@ Tre Afkrydsningsfelter Kode + Tabeller Billeder Andet Sortér efter dato ændret @@ -197,10 +203,18 @@ Batteriindstillinger Åbn App info Netværksindstillinger - Opdater + Opdatér Vælg konto + Fjern %1$s + Du skal være koblet på en internetforbindelse for at tilføje en konto. + Sæt mappe + Næste Tidligere Backup + Mappe for nye noter: %1$s + Fil-endelse + Fil-endelse for nye noter i Nextcloud + Tilbage diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index bf3414adf..d55684fab 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -41,6 +41,7 @@ Letzten Monat Anzeigemodus für Notizen + Verhalten beim Öffnen von Notizen Design Nichtproportionale Schriftart Schriftgröße @@ -63,6 +64,7 @@ Sie benutzen aktuell %1$s Maintainer Entwickler + Ursprünglicher Autor Übersetzer Nextcloud-Gemeinschaft auf %1$s Tester @@ -177,11 +179,11 @@ Konten verwalten Formatierung - - Im Bearbeitungsmodus öffnen - Im Vorschaumodus öffnen - Letzte Auswahl merken - + + Einfacher Bearbeitungsmodus + Einfache Vorschau + Rich-Bearbeitungsmodus + Letzte Auswahl merken Klein @@ -302,4 +304,7 @@ Importiere Notizen… Importiere Notiz %1$d von %2$d… Konto importiert. - + Fehler beim Laden des Rich-Bearbeitungsmodus + Zum einfachen Bearbeitungsmodus wechseln + Zurück + diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index 457940c29..ca7cbc845 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -159,11 +159,8 @@ Διαχείριση λογαριασμών Διαμόρφωση σε εξέλιξη - - Άνοιγμα σε λειτουργία τροποποίησης - Άνοιγμα σε λειτουργία προεπισκόπισης - Να θυμάσαι την τελευταία μου επιλογή - + + Να θυμάσαι την τελευταία μου επιλογή Μικρό @@ -260,4 +257,5 @@ Επόμενο Προηγούμενο Αντίγραφο ασφαλείας + Πίσω diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index fb47cad1f..2cce5af8f 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -41,6 +41,7 @@ El mes pasado Modo de visualización para notas + Comportamiento de apertura de las notas Tema Tipo de letra monoespaciado Tamaño de fuente @@ -63,6 +64,7 @@ Actualmente está utilizando %1$s Mantenedor Desarrolladores + autor original Traductores Comunidad Nextcloud en %1$s Testers @@ -165,7 +167,7 @@ Por favor, asegúrate de que has instalado y activado la app «Notas» en tu servidor. Tu servidor respondió con el código de estado HTTP 302, lo que implica que no está instalada la aplicación Notas en su servidor o que algo está mal configurado. Esto puede estar causado por anulaciones personalizadas en un archivo .htaccess o por aplicaciones de Nextcloud como OID Client. Por favor, desactiva todas las optimizaciones de la batería para Nextcloud y la app de Notas. - La aplicación de Android Notas necesita la versión 3.18 o superior de la aplicación Android Nextcloud + La aplicación de Notas de Android requiere que la la aplicación Nextcloud de Android sea al menos la versión 3.18. Se ha añadido «%1$s» El texto compartido estaba vacío Añadir a la nota @@ -177,11 +179,11 @@ Gestionar cuentas Formato - - Abrir en modo edición - Abrir en modo visualización - Recordar mi última selección - + + Modo de edición plano + Vista previa en plano + Modo de edición enriquecido + Recordar mi última selección Pequeña @@ -307,4 +309,7 @@ Importando notas… Importando nota %1$d de %2$d… Cuenta importada. - + Error al cargar el modo de edición enriquecido + Cambiar a edición plana + Atrás + diff --git a/app/src/main/res/values-eu/strings.xml b/app/src/main/res/values-eu/strings.xml index 38861b350..91cd82385 100644 --- a/app/src/main/res/values-eu/strings.xml +++ b/app/src/main/res/values-eu/strings.xml @@ -41,6 +41,7 @@ Joan den hilabetean Erakutsi oharren modua + Oharrak irekitzeko portaera Gaia Zabalera bakarreko letra mota Letra tamaina @@ -63,6 +64,7 @@ %1$s erabiltzen ari zara Mantentzailea Garatzaileak + jatorrizko egilea Itzultzaileak %1$s Nextcloud komunitatea Probatzaileak @@ -177,11 +179,11 @@ Kudeatu kontuak Formatua - - Ireki edizio moduan - Ireki aurrebista moduan - Gogoratu nire azken hautaketa - + + Edizio modu arrunta + Aurrebista arrunta + Edizio modu aberatsa + Gogoratu nire azken hautaketa Txikia @@ -302,4 +304,7 @@ Oharrak inportatzen... %2$dtik %1$doharra inportatzen... Kontua inportatuta. - + Errore bat gertatu da edizio aberatsa kargatzean + Aldatu edizio arruntera + Atzera + diff --git a/app/src/main/res/values-fa/strings.xml b/app/src/main/res/values-fa/strings.xml index e77333c67..4286174df 100644 --- a/app/src/main/res/values-fa/strings.xml +++ b/app/src/main/res/values-fa/strings.xml @@ -149,11 +149,8 @@ مدیریت حساب‌ها قالب‌بندی - - یادداشت را در حالت «ویرایش» باز کنید - یادداشت را در حالت پیش نمایش باز کنید - آخرین انتخاب من را به خاطر بسپار - + + آخرین انتخاب من را به خاطر بسپار کوچک @@ -225,4 +222,5 @@ بعدی قبلی پشتیبان‌گیری + بازگشت diff --git a/app/src/main/res/values-fi-rFI/strings.xml b/app/src/main/res/values-fi-rFI/strings.xml index ebc99b240..b0e3a3ae5 100644 --- a/app/src/main/res/values-fi-rFI/strings.xml +++ b/app/src/main/res/values-fi-rFI/strings.xml @@ -173,11 +173,8 @@ Tilien hallinta Muotoilu - - Avaa muokkaustilassa - Avaa esikatselutilassa - Muista viimeisin valintani - + + Muista viimeisin valintani Pieni @@ -295,4 +292,5 @@ Tuodaan muistiinpanoja... Tuodaan muistiinpanoa %1$d/%2$d… Tili tuotu. - + Takaisin + diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 2ebed3264..97fd77e77 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -41,6 +41,7 @@ Mois dernier Mode d\'affichage des notes + Comportement à l\'ouverture de Notes Thème Texte monospace Taille des caractères @@ -63,6 +64,7 @@ Vous utilisez actuellement %1$s Responsable Développeurs + auteur original Traducteurs Communauté Nextcloud sur %1$s Testeurs @@ -177,11 +179,11 @@ Gérer les comptes Formatage - - Ouvrir en mode édition - Ouvrir en mode aperçu - Mémoriser ma dernière sélection - + + Édition simple + Prévisualization simple + Édition texte enrichi + Mémoriser ma dernière sélection Petit @@ -305,6 +307,9 @@ Nouveau suffixe de fichier : %1$s État HTTP : %1$d Importation des notes... - Importation de la note %1$dsur %2$d... + Importation de la note %1$d sur %2$d... Compte importé. - + Erreur lors du chargement de l\'édition enrichie + Bascule vers l\'édition simple + Retour + diff --git a/app/src/main/res/values-gl/strings.xml b/app/src/main/res/values-gl/strings.xml index 1bd89f0f3..8d67935ff 100644 --- a/app/src/main/res/values-gl/strings.xml +++ b/app/src/main/res/values-gl/strings.xml @@ -41,6 +41,7 @@ O mes pasado Modo de vista das notas + Comportamento de apertura das notas Tema Letra monoespazada Tamaño da letra @@ -63,6 +64,7 @@ Agora está a empregar %1$s Mantedor Desenvolvedores + autor orixinal Tradutores Comunidade Nextcloud en %1$s Probadores @@ -73,11 +75,11 @@ Traducir Únase ao equipo Nextcloud en Transifex e axúdenos a traducir esta aplicación: %1$s Licenza da apli - Esta apli está licenciada baixo a LICENZA XERAL PUBLICA GNU v3+. + Esta aplicación está licenciada baixo a LICENZA XERAL PUBLICA GNU v3+. Ver a licenza Iconas Para a icona orixinal, vexa %1$s. - Todas as iconas usadas nesta aplicación son %1$s feitas por Google Inc. e licenciadas baixo unha Licenza Apache 2.0. + Todas as iconas usadas nesta aplicación %1$sforon feitas por Google Inc. e licenciadas baixo unha Licenza Apache 2.0. Iconas Material Desig Recoñecementos Colaboración @@ -102,7 +104,7 @@ Pechar Copiar Excepción - Ancorar na pantalla de inicio + Fixar na pantalla de Inicio Esta nota foi eliminada Engadir unha conta @@ -110,8 +112,8 @@ Filmes Filme Traballo - Tarefa - Tarefas + Tarefa pendente + Tarefas pendentes Listas de verificación Tarefas Receita @@ -121,9 +123,9 @@ Comida Enfornar - Chave + Clave - Chaves + Claves Contrasinal Contrasinais Credencial @@ -134,9 +136,9 @@ Agasallo Agasallos - Presentar + Presente - Agasallos + Presentes A conta xa foi importada Aínda non hai notas @@ -165,7 +167,7 @@ Asegúrese de ter instalada e activada a aplicación «Notas» no seu servidor. O seu servidor respondeu cun código de estado HTTP 302, o que implica que non ten instalada a aplicación Notas no servidor ou que algo está mal configurado. Isto pode ser causado por substitucións personalizadas nun ficheiro .htaccess ou por aplicacións Nextcloud como Client OID. Desactive todas as optimizacións de batería para Nextcloud e a apli Notas. - A aplicación de Android Notes require que a aplicación de Android Nextcloud teña como mínimo a versión 3.18. + A aplicación de Notas para Android require que a aplicación de Android Nextcloud teña como mínimo a versión 3.18. Engadido «%1$s» O texto compartido estaba baleiro Anexo á nota @@ -177,11 +179,11 @@ Xestionar contas Formatado - - Abrir en modo de edición - Abrir en modo de vista previa - Lembrar a miña última selección - + + Modo de edición simple + Vista previa simple + Modo de edición enriquecido + Lembrar a miña última selección Pequena @@ -276,26 +278,33 @@ Aínda non ten configurada ningunha outra conta. Escolla unha conta Xanela emerxente de formato baseado no contexto - Eliminar %1$s + + Retirar a conta %1$s tamén eliminará de xeito irrecuperábel un cambio non sincronizado. + Retirar a conta %1$s tamén eliminará de xeito irrecuperábel %2$d cambios non sincronizados. + + Retirar %1$s - Para engadir unha conta tes que estar conectado a internet. - Establecer cartafol + Para engadir unha conta ten que estar conectado a Internet. + Estabelecer cartafol Seguinte Anterior Copia de seguridade - Detectamos un estado irrecuperable da aplicación. Fai unha copia de seguranza dos cambios non sincronizados e limpa o almacenamento da aplicación Notes. - Cartafol para almacenar as túas notas no teu Nextcloud + Detectamos un estado irrecuperábel da aplicación. Faga unha copia de seguridade dos cambios non sincronizados e limpe o almacenamento da apli de Notas. + Cartafol para almacenar as súas notas no seu Nextcloud .txt .md Novo cartafol de notas: %1$s Extensión de ficheiro - Extensión de ficheiro para novas notas no teu Nextcloud + Extensión de ficheiro para novas notas no seu Nextcloud Novo sufixo de ficheiro: %1$s Código de estado HTTP: %1$d - A importar notas... - A importar a nota %1$d de %2$d... + Importando notas… + Importando a nota %1$d de %2$d… Conta importada. - + Produciuse un erro ao cargar a edición mellorada + Cambiar á edición simple + Atrás + diff --git a/app/src/main/res/values-he/strings.xml b/app/src/main/res/values-he/strings.xml index bee675e20..50ed248c6 100644 --- a/app/src/main/res/values-he/strings.xml +++ b/app/src/main/res/values-he/strings.xml @@ -138,11 +138,8 @@ ניהול חשבונות עיצוב - - פתיחה במצב עריכה - פתיחה במצב תצוגה מקדימה - שמירת הבחירה האחרונה שלי - + + שמירת הבחירה האחרונה שלי קטן @@ -202,4 +199,5 @@ על המכשיר שלך להיות מחובר לאינטרנט כדי שיתאפשר לך להוסיף חשבון. הבא הקודם + חזרה diff --git a/app/src/main/res/values-hr/strings.xml b/app/src/main/res/values-hr/strings.xml index 5c89d7a13..e3ccfd796 100644 --- a/app/src/main/res/values-hr/strings.xml +++ b/app/src/main/res/values-hr/strings.xml @@ -173,11 +173,8 @@ Upravljaj računima Oblikovanje - - Otvori u načinu uređivanja - Otvori u načinu pregleda - Zapamti moj posljednji izbor - + + Zapamti moj posljednji izbor Mali @@ -303,4 +300,5 @@ Uvoz bilješki... Uvoz bilješke %1$d od %2$d... Račun je uvezen. - + Natrag + diff --git a/app/src/main/res/values-hu-rHU/strings.xml b/app/src/main/res/values-hu-rHU/strings.xml index 2c5c1b753..991801055 100644 --- a/app/src/main/res/values-hu-rHU/strings.xml +++ b/app/src/main/res/values-hu-rHU/strings.xml @@ -41,6 +41,7 @@ Előző hónap Jegyzet módok megjelenítés + Jegyzetek megnyitási viselkedése Téma Fix szélességű betűkészlet Betűméret @@ -63,6 +64,7 @@ Jelenleg ezt a verziót használja: %1$s Karbantartó Fejlesztők + eredeti szerző Fordítók Nextcloud közösség a %1$s Tesztelők @@ -177,11 +179,11 @@ Fiókok kezelése Formázás - - Megnyitás szerkesztésre - Megnyitás előnézetre - A legutóbbi döntés megjegyzése - + + Egyszerű szerkesztési mód + Egyszerű előnézet + Formázott szöveges mód + A legutóbbi döntés megjegyzése Kicsi @@ -302,4 +304,7 @@ Jegyzetek importálása… %1$d. / %2$d jegyzet importálása… Fiók importálva. - + Hiba a formázott szöveges szerkesztő betöltése során + Átváltás az egyszerű szerkesztésre + Vissza + diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index c72b045ea..e8386a658 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -174,11 +174,8 @@ Gestisci account Formattazione - - Apri in modalità modifica - Apri in modalità anteprima - Ricorda la mia ultima selezione - + + Ricorda la mia ultima selezione Piccola @@ -304,4 +301,5 @@ Importazione note in corso... Importazione nota %1$d di %2$d ... Account importato - + Indietro + diff --git a/app/src/main/res/values-ja-rJP/strings.xml b/app/src/main/res/values-ja-rJP/strings.xml index f81c68861..24fcbf30b 100644 --- a/app/src/main/res/values-ja-rJP/strings.xml +++ b/app/src/main/res/values-ja-rJP/strings.xml @@ -174,11 +174,8 @@ アカウント管理 フォーマット - - 編集モードで開く - プレビューモードで開く - 最後に使用したモードで開く - + + 最後に使用したモードで開く @@ -294,4 +291,5 @@ ノートを導入しています… %2$d中%1$dのノートをインポート中... アカウントを導入しました。 - + 戻る + diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index ab67024ef..b56ab2075 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -176,11 +176,8 @@ 계정 관리 서식 - - 편집 모드로 열기 - 미리 보기 모드로 열기 - 마지막 선택 기억하기 - + + 마지막 선택 기억하기 작게 @@ -291,4 +288,5 @@ 노트 불러오는 중... %2$d의 노트 %1$d 불러오는 중... 계정을 불러왔습니다. - + 뒤로 + diff --git a/app/src/main/res/values-lt-rLT/strings.xml b/app/src/main/res/values-lt-rLT/strings.xml index d4e8a7e1a..70ae063ae 100644 --- a/app/src/main/res/values-lt-rLT/strings.xml +++ b/app/src/main/res/values-lt-rLT/strings.xml @@ -144,11 +144,8 @@ Tvarkyti paskyras Formatavimas - - Atverti redagavimo veiksenoje - Atverti peržiūros veiksenoje - Prisiminti paskutinį pasirinkimą - + + Prisiminti paskutinį pasirinkimą Mažas @@ -224,4 +221,5 @@ Norėdami pridėti paskyrą, turite būti prisijungę prie interneto. Kitas Ankstesnis + Atgal diff --git a/app/src/main/res/values-nb-rNO/strings.xml b/app/src/main/res/values-nb-rNO/strings.xml index df8d92bd8..db0a02c52 100644 --- a/app/src/main/res/values-nb-rNO/strings.xml +++ b/app/src/main/res/values-nb-rNO/strings.xml @@ -2,7 +2,7 @@ Notater - Nextcloud Notes + Nextcloud Notater Alle notater Favoritter Nytt notat @@ -45,19 +45,25 @@ Monospace font Skriftstørrelse Synkroniser kun med WiFi + Applås (beta) Enhetens legitimasjon Synkronisering i bakgrunnen + Forhindre skjermopptak Rutenett-visning + Hold skjermen på + Når du viser eller redigerer et notat + Synkronisering mislyktes: %1$s Synkronisering mislyktes Ingen nettverkstilkobling Server i vedlikeholdsmodus - En ukjent feil oppstod. + En ukjent feil oppsto. Versjon Du bruker forøyeblikket %1$s Vedlikeholder Utviklere + original forfatter Oversettere Nextcloud-fellesskapet på %1$s Testere @@ -105,16 +111,34 @@ Filmer Film Arbeid + Gjøremål + Gjøremål + Sjekklister Oppgaver + Oppskrift Oppskrifter Restaurant - PassordP + Restauranter + Mat + Bake + + Nøkkel + + Nøkler + Passord Passord + Påloggingsdetalj + Spill Spill Spill + Gave + Gaver Gave + + Gavepakker + Kontoen har allerede blitt importert Ingen notater enda Trykk + knappen for å opprette et nytt notat @@ -127,9 +151,10 @@ Lås opp notater Å nei - Hva nå? 🙁 Prøv å tvinge avslutning av appen og start den på nytt. Det kan ha vært en feiltilkobling til Nextcloud-appen. - Hvis problemet vedvarer, prøv å tømme lageret for begge disse appene for å løse problemet: Nextcloud og Nextcloud Notes. + Hvis problemet vedvarer, prøv å tømme lageret for begge disse appene for å løse problemet: Nextcloud og Nextcloud Notater. + Du kan tømme lagringen ved å åpne appinformasjonen og velge Lagring → Tøm lagring. ⚠️ Advarsel: Dette vil slette notater som ikke er synkronisert ennå! Det virker som Nextcloud appen er utdatert. Venligst besøk Play Sore eller F-Droid for å finne siste versjon. - Det virker som noe er galt med Nextcloud appen. Vennligst prøv å tvinge avslutning av Nextcloud appen og Nextcloud Notes appen. + Det virker som noe er galt med Nextcloud-appen. Vennligst prøv å tvinge avslutning av Nextcloud-appen og Nextcloud Notater-appen. Hvis det ikke hjelper med tving avslutt, så kan du prøve å tømme lageret for begge appene. Serveren svarer ikke innen en gitt tid. Vennligst påse at serveren er tilgjengelig. Sjekk nettverkstilkoblingen. Noen ganger hjelper det å skru av og på mobil data eller WI-FI tilkoblingen. @@ -138,9 +163,10 @@ Vennligst sjekk at Nextcloud instansen ikke er i vedlikeholdsmodus for øyeblikket. Nextcloud instansen har ikke mer ledig lagringsplass. Vennligst slett noen filer for å synkronisere de lokale endringen til skyen din. Vi trenger følgende teknisk informasjon for å kunne hjelpe deg: - Vennligst påse at du har installert og aktivert \"Notes\" appen på serveren. - Serveren din svarte med en HTTP 302-statuskode, noe som antyder at du ikke har installert Notes-appen på serveren din, eller at noe er feilkonfigurert. Dette kan være forårsaket av tilpassede overstyringer i en .htaccess-fil eller av Nextcloud-apper som OID Client. - Deaktiver alle batterioptimaliseringer for Nextcloud og Notes-appen. + Vennligst påse at du har installert og aktivert \"Notes\"-appen på serveren. + Serveren din svarte med en HTTP 302-statuskode, noe som antyder at du ikke har installert Notater-appen på serveren din, eller at noe er feilkonfigurert. Dette kan være forårsaket av tilpassede overstyringer i en .htaccess-fil eller av Nextcloud-apper som OID Client. + Deaktiver alle batterioptimaliseringer for Nextcloud og Notater-appen. + Notater-androidappen krever at Nextcloud-androidappen er minst versjon 3.18. Lagt til \"%1$s\" Delt tekst var tom Legg til i notat @@ -152,11 +178,8 @@ Håndter kontoer Formatering - - Åpne i redigeringsmodus - Åpne i forhåndsvisningsmodus - Husk mitt siste valg - + + Husk mitt siste valg Liten @@ -174,13 +197,27 @@ %d er valgt %d valgt + + Slettet ett notat + Slettet %1$d notater + + + Gjenopprettet ett notat + Gjenopprettet %1$d notater + + + Del innhold i %1$d notat + Del innhold av %1$d notater + + --- `%1$s` \\`%1$s\\` ``` + ```` ```javascript Kontekstbasert formatering - Et viktig designmål for Notes-appen er å tilby et distraksjonsfritt verktøy. Selv om du vil kunne formatere tekstene dine med Markdown. For de forskjellige eksemplene nedenfor, kan du bruke snarveier slik at du kan formatere notatene dine uten å skrive inn kodene nedenfor. + Et viktig designmål for Notater-appen er å tilby et distraksjonsfritt verktøy. Selv om du vil kunne formatere tekstene dine med Markdown. For de forskjellige eksemplene nedenfor, kan du bruke snarveier slik at du kan formatere notatene dine uten å skrive inn kodene nedenfor. Bare velg et tekstområde eller trykk på markøren når som helst, så får du en popup-meny som inneholder ved siden av standardoppføringene %1$s, %2$s, %3$s oppføringer som %4$s eller %5$s. Tekst @@ -221,7 +258,11 @@ Verdi %1d + Koblinger må enten være komplette URL-er som starter med en protokoll og domene eller absolutte stier som starter med et %1$s-tegn. + For å samsvare med Markdown-formatet, vennligst bruk escape-tegn i bildets URL. Dette betyr for eksempel å erstatte mellomrom med %1$s i URL-en. Bilder + Fancy bilde + Annet Sorter etter dato endret Sorter alfabetisk @@ -232,8 +273,32 @@ Ingen konto er konfigurert Du har ikke konfigurert noen konto enda. Velg konto + Popover for kontekstbasert formatering + + Fjerning av kontoen %1$s vil også uopprettelig slette en usynkronisert endring. + Fjerning av kontoen %1$s vil også uopprettelig slette %2$d usynkroniserte endringer. + + Fjern %1$s + Du må være koblet til internett for å kunne legge til en konto. + Sett mappe + Neste Forrige Sikkerhetskopi + Vi oppdaget en uopprettelig tilstand i appen. Ta sikkerhetskopi av usynkroniserte endringer og tøm lagringen av Notater-appen. + Mappe for å lagre notatene dine i Nextcloud + + .txt + .md + + Ny notatmappe: %1$s + Filetternavn + Filetternavn for nye notater i Nextcloud + Nytt filsuffiks: %1$s + HTTP-statuskode: %1$d + Importerer notater… + Importerer notat %1$d av %2$d… + Konto importert. + Tilbake diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 55d169349..3c2db5d19 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -63,6 +63,7 @@ Je gebruikt nu %1$s Projectleider Ontwikkelaars + oorspronkelijke ontwikkelaar Vertalers Nextcloud-gemeenschap op %1$s Testers @@ -177,11 +178,8 @@ Accounts beheren Opmaak - - Open in bewerkingsmodus - Open in voorbeeldmodus - Onthoud je laatste selectie - + + Onthoud je laatste selectie Klein @@ -300,6 +298,7 @@ Nieuwe bestandsachtervoegsel: %1$s HTTP status code: %1$d Notities importeren... - Notitie %1$dvan %2$dimporteren + Notitie %1$d van %2$d importeren Account geïmporteerd - + Terug + diff --git a/app/src/main/res/values-oc/strings.xml b/app/src/main/res/values-oc/strings.xml index a82cde215..da8bd1293 100644 --- a/app/src/main/res/values-oc/strings.xml +++ b/app/src/main/res/values-oc/strings.xml @@ -151,4 +151,5 @@ Seguent Precedent Salvagarda + Retorn diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 283f44a23..658aa1e23 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -41,6 +41,7 @@ W zeszłym miesiącu Tryb wyświetlania notatek + Zachowanie otwierania notatek Motyw Czcionka monospace Rozmiar czcionki @@ -63,6 +64,7 @@ Aktualnie używasz %1$s Opiekun Deweloperzy + oryginalny autor Tłumacze Społeczność Nextcloud na %1$s Testerzy @@ -177,11 +179,11 @@ Zarządzaj kontami Formatowanie - - Otwórz w trybie edycji - Otwórz w trybie podglądu - Zapamiętaj ostatni wybór - + + Prosta modyfikacja + Prosty podgląd + Bogata modyfikacja + Zapamiętaj ostatni wybór Mała @@ -312,4 +314,7 @@ Importuję notatki… Importuję notatkę %1$d z %2$d… Konto zaimportowane. - + Błąd podczas ładowania bogatej modyfikacji + Przełącz na prostą modyfikację + Poprzednia + diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index 6882a296c..b5aca4d85 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -41,6 +41,7 @@ Último mês Modo de exibição de notas + Notes opening behaviour Tema Fonte monospaçada Tamanho da fonte @@ -63,6 +64,7 @@ Você está atualmente usando %1$s Mantenedor Desenvolvedores + autor original Tradutores Comunidade Nextcloud em %1$s Testadores @@ -177,11 +179,11 @@ Gerenciar contas Formatação - - Abrir em modo de edição - Abrir em modo de visualização - Lembrar minha última escolha - + + Plain edit mode + Plain preview + Rich edit mode + Lembrar minha última escolha Pequena @@ -307,4 +309,7 @@ Importando notas… Importando notas %1$d de %2$d… Conta importada. - + Error while loading rich editing + Switch to plain editing + Voltar + diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index 4a2141533..fb532ceac 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -177,11 +177,8 @@ Administrare conturi Formatare - - Deschide în modul editare - Deschide în modul de previzualizare - Amintește-ți ultima mea selecție - + + Amintește-ți ultima mea selecție Mic @@ -307,4 +304,5 @@ Se importă notiţe... Se importă notiţele %1$d din %2$d ... Cont importat. - + Înapoi + diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 9a7d05e80..49c12b176 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -41,6 +41,7 @@ За последний месяц Режим показа заметок + Поведение при открытии приложения Заметки Тема Моноширинный шрифт Размер шрифта @@ -63,6 +64,7 @@ В данный момент вы используете %1$s Сопроводитель Разработчики + первый автор Переводчики Сообщество Nextcloud на сайте %1$s Тестировщики @@ -177,11 +179,11 @@ Управление аккаунтами Форматирование - - Открывать в режиме правки - Открывать в режиме просмотра - Запоминать выбранный режим - + + Режим простого редактирования + Режим простого просмотра + Режим форматированного редактирования + Запоминать выбранный режим Маленький @@ -312,4 +314,7 @@ Импорт заметок... Импортировано заметок %1$d из %2$d... Учетная запись импортирована. - + Ошибка при загрузке форматированного редактирования + Переключиться на простое редактирование + Назад + diff --git a/app/src/main/res/values-sc/strings.xml b/app/src/main/res/values-sc/strings.xml index a4872cc3a..bad18c59c 100644 --- a/app/src/main/res/values-sc/strings.xml +++ b/app/src/main/res/values-sc/strings.xml @@ -151,11 +151,8 @@ Gesti contos Formatatzione - - Aberi in modalidade modìfica - Aberi in modalidade anteprima - Regorda s\'ùrtimu sèberu - + + Regorda s\'ùrtimu sèberu Piticu @@ -271,4 +268,5 @@ Estensione de archìviu pro notas noas in su Nextcloud tuo Sufissu de archìviu nou: %1$s Còdighe de istadu HTTP: %1$d + In segus diff --git a/app/src/main/res/values-sk-rSK/strings.xml b/app/src/main/res/values-sk-rSK/strings.xml index cf820fb6b..8e59ef99c 100644 --- a/app/src/main/res/values-sk-rSK/strings.xml +++ b/app/src/main/res/values-sk-rSK/strings.xml @@ -177,11 +177,8 @@ Spravovať účty Formátovanie - - Otvoriť v režime úprav - Otvoriť v režime ukážky - Zapamätať si môj posledný výber - + + Zapamätať si môj posledný výber Malá @@ -312,4 +309,5 @@ Import poznámok… Importuje sa poznámka %1$d of %2$d… Účet bol importovaný. - + Späť + diff --git a/app/src/main/res/values-sl/strings.xml b/app/src/main/res/values-sl/strings.xml index 691fcf7af..ba464fafe 100644 --- a/app/src/main/res/values-sl/strings.xml +++ b/app/src/main/res/values-sl/strings.xml @@ -50,6 +50,9 @@ Usklajevanje v ozadju Prepreči zajem zaslona Mrežni pogled + Ohrani zaslon prižgan + Med pregledovanjem in urejanjem zabeležk + Usklajevanje je spodletelo: %1$s Usklajevanje je spodletelo Ni omrežne povezave @@ -60,6 +63,7 @@ Trenutno je v uporabi %1$s Vzdrževalec Razvijalci + izvorni avtor Prevajalci Skupnost Nextcloud na %1$s Preizkuševalci @@ -174,11 +178,8 @@ Upravljanje z računi Oblikovanje - - Zabeležka se odpre v urejevalnem načinu - Zabeležka se odpre v predogledu - Zapomni si zadnjo izbiro - + + Zapomni si zadnjo izbiro Majhna @@ -309,4 +310,5 @@ Poteka uvažanje sporočilc ... Poteka uvažanje sporočilca %1$d od %2$d… Račun je uspešno uvožen. - + Nazaj + diff --git a/app/src/main/res/values-sr/strings.xml b/app/src/main/res/values-sr/strings.xml index b008f86e9..294671ffb 100644 --- a/app/src/main/res/values-sr/strings.xml +++ b/app/src/main/res/values-sr/strings.xml @@ -41,13 +41,19 @@ Прошлог месеца Режим приказа белешки + Понашање отварања белешке Тема Фонт фиксне ширине Величина фонта Синхронизуј само преко бежичне везе + Закључавање апликације (бета) Акредитиве уређаја Позадинска синхронизација + Спречи снимак екрана Приказ мреже + Задржи укључен екран + Када се прегледа или уређује белешка + Синхронизација није успела%1$s Синхронизација није успела Нема мрежне везе @@ -58,6 +64,7 @@ Тренутно користите %1$s Одржаваоц Програмери + оригинални аутор Преводиоци Некстклауд заједница на %1$s Тестери @@ -105,14 +112,34 @@ Филмови Филм Посао + Обавеза + Обавезе + Листе за потврду Задаци + Рецепт Рецепти Ресторан + Ресторани + Храна + Пекара + + Кључ + + Кључеви Лозинка Лозинке + Креденцијал + Игра Игрице Пусти + Поклон + Поклони + + Дар + + Дарови + Налог је већ увезен Још нема белешки Притисните + дугме да направите нову белешку @@ -126,6 +153,7 @@ О, не - шта сад? 🙁 Покушајте да форсирано затворите апликацију и стартујете је поново. Можда је била неисправна конекција ка Некстклауд апликацији. Ако проблем настави да се дешава, пробајте да очистите податке од обе апликације: и Некстклауд и Некстклауд Белешки да бисте решили проблем. + Складиште можете да обришете тако што отворите информације о апликацији и изаберете Storage → Clear storage. ⚠️ Упозорење: Ово ће да обрише белешке које још увек нису синхронизоване! Изгледа да је верзија Некстклауд апликације стара. Посетите Play Store или Ф-дроид да скинете најновију верзију. Нешто није у реду да Вашом Некстклауд апликацијом. Пробајте да форсирано зауставите обе, и Некстклауд апликацију и апликацију Некстклауд Белешки. Ако ово заустављање не помогне, очистите податке за обе апликације. @@ -139,21 +167,23 @@ Проверите да ли сте инсталирали и укључили апликацију „Белешке” на Вашем серверу. Сервер је одговорио са HTTP 302 кодом, што значи да немате инсталирану апликацију Белешке или да Вам сервер није правилно конфигурисан. Ово може да буде проузорковано произвољним додавањима у .htaccess фајлу или другим Некстклауд апликацијама као што је OID Client. Искључите све оптимизације батерије за Некстаклауд и Белешке апликације. + The Андроид апликација Белешке захтева да је верзија Nextcloud Андроид апликације барем 3.18. Додата „%1$s” Дељени текст је празан Додај на белешку Промени назив белешке Измени наслов Безбедност + Изглед и понашање Синхронизација Управљање налозима Форматирање - - Отвори у режиму уређивања - Отвори у режиму прегледа - Запамти мој последњи избор - + + Режим простог уређивања + Прости преглед + Режим детаљног уређивања + Запамти мој последњи избор Мали @@ -192,6 +222,7 @@ `%1$s` \\`%1$s\\` ``` + ```` ```javascript Форматирање у зависности од контекста Главни циљ дизајна апликације Белешки је био да пружи алат који не стаје на пут. А моћи ћете и да форматирате текст Markdown синтактом. За разне од долепоменутих примера можете да користите и пречице, па можете форматирати белешке без куцања кодова испод. @@ -230,7 +261,16 @@ А ако желите бојење синтакте, додајте и језик: Табеле + + Колона %1d + + Вредност %1d + + Линкови морају бити или комплетне URL адресе које почињу протоколом и доменом или апсолутне путање које почињу карактером %1$s. + Да би сте били сагласни са Markdown форматом, молимо вас да користите означавајуће карактере у URL слика. Ово значи, на пример, да се размаци у URL замењују са %1$s. Слике + Фенси слика + Остало Сортирај по времену измене Сортирај абецедно @@ -238,9 +278,38 @@ Отвори инфо о апликацији Поставке мреже Ажурирај + Још увек није подешен ниједан налог Нисте подесили ниједан други налог. Одаберите налог + Искачући облачић форматирања у зависности од контекста + + Уклањање налога %1$s ће такође неповратно да обрише једну несинхронизовану измену. + Уклањање налога %1$s ће такође неповратно да обрише %2$d несинхронизоване измене. + Уклањање налога %1$s ће такође неповратно да обрише %2$d несинхронизованих измена. + + Уклони %1$s + Морате бити повезани на интернет да бисте додали налог. + Постави фолдер + Следећа Претходно + Резервна копија + Открили смо стање апликације које не може да се опорави. Молимо вас да направите резервну копију ваших несихронизованих измена и очистите складиште Notes апликације. + Фолдер у којем се на вашем Nextcloud серверу чувају белешке + + .txt + .md + + Нови фолдер за белешке: %1$s + Екстензија фајла + Екстензија фајла за нове белешке на вашем Nextcloud серверу + Суфикс новог фајла: %1$s + HTTP статусни кôд: %1$d + Белешке се увозе... + Увози се белешка %1$d од укупно %2$d… + Налог је увезен. + Грешка приликом учитавања детаљног уређивања + Пређи на просто уређивање + Назад diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml index c04250719..e3cb4df74 100644 --- a/app/src/main/res/values-sv/strings.xml +++ b/app/src/main/res/values-sv/strings.xml @@ -41,6 +41,7 @@ Förra månaden Visningsläge för anteckningar + Notes startfunktion Tema Monospace font Teckenstorlek @@ -63,6 +64,7 @@ Du använder %1$s för närvarande Underhållare Utvecklare + Ursprungsskribent Översättare Nextcloud community på %1$s Testare @@ -177,11 +179,11 @@ Hantera konton Formatering - - Öppna i redigera-läge - Öppna i förhandsvisningsläge - Kom ihåg mitt sista val - + + Enkel redigeringsfunktion + Enkel förhandsvisning + Rich redigeringsfunktion + Kom ihåg mitt sista val Liten @@ -223,6 +225,8 @@ Markera bara ett stycke text eller tryck på din markör vid valfri position och du kommer få en popup-meny som utöver standardposterna såsom %1$s, %2$s, %3$s även innehåller poster som %4$s eller %5$s. Text + Med Markdown är det enkelt att sätta en del ord i %1$sfetstil%1$s och andra %2$skursiva%2$s. Du kan %3$söverstyka%3$s ord och även [länka till Nextcloud](https://nextcloud.com). + Listor Ibland vill du ha en numrerad lista: En @@ -294,4 +298,5 @@ Importerar anteckningar... Importerar anteckning %1$d av %2$d... Konto importerat. - + Tillbaka + diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index 1878de2ae..1fcc6a8cf 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -41,6 +41,7 @@ Geçen ay Notların görüntülenme kipi + Not açılma davranışı Tema Sabit aralıklı yazı türü Yazı boyutu @@ -63,6 +64,7 @@ Şu anda %1$s kullanıyorsunuz Sorumlu Geliştiriciler + özgün yazar Çevirmenler %1$s üzerindeki Nextcloud topluluğu Deneyenler @@ -157,7 +159,7 @@ Zorla durdurmak sorunu çözmediyse iki uygulamanın da depolamalarını temizlemeyi deneyebilirsiniz. Belirtilen sürede sunucunuzdan bir yanıt alınamadı. Lütfen kopyanızın düzgün çalıştığından emin olun. Ağ bağlantınızı denetleyin. Mobil veriye geçmek ya da Wi-Fi bağlantısını kapatıp açmak yardımcı olabilir. - Sunucunuz doğru şekilde yanıt vermedi. Lütfen notlarınıza web arayüzü üzerinden erişebiliyor musunuz diye bakın. + Sunucunuz doğru şekilde yanıt vermedi. Lütfen notlarınıza site arayüzü üzerinden erişebiliyor musunuz diye bakın. Nextcloud kurulumunuz ile ilgili bir sorun var. Lütfen sunucu günlük dosyalarını inceleyin. Nextcloud kopyanızın bakım kipinde olmadığından emin olun. Nextcloud kopyanızda boş depolama alanı kalmamış. Lütfen yerel değişikliklerinizi bulut ile eşitlemek için bazı dosyaları silerek yer açın. @@ -177,11 +179,11 @@ Hesap yönetimi Biçimlendirme - - Düzenleme kipinde aç - Ön izleme kipinde aç - Son seçimim hatırlansın - + + Yalın düzenleme kipi + Yalın ön izleme + Zengin metin düzenleme kipi + Son seçimim hatırlansın Küçük @@ -302,4 +304,7 @@ Notlar içe aktarılıyor… Not %1$d / %2$d içe aktarılıyor… Hesap içe aktarıldı. - + Zengin düzenleme yüklenirken sorun çıktı + Yalın düzenlemeye geç + Geri + diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index 2d72afd8f..fa946d538 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -41,6 +41,7 @@ Минулого місяця Показувати нотатки + Поведінка під час відкриття застосунку Нотатки Тема Моноширинний шрифт Розмір шрифту @@ -63,6 +64,7 @@ Ви використовуєте %1$s Утримувач Розробники + перший автор Перекладачі Спільнота Nextcloud на %1$s Тестувальники @@ -110,8 +112,8 @@ Відео Фільм Робочий - До роботи - До роботи + Завдання + Завдання Контрольні списки Завдання Рецепт @@ -157,7 +159,7 @@ Якщо примусове їх завершення не допомагає, спробуйте очистити сховище обох застосунків. За відведений час відповіді від вашого сервера не надійшло. Переконайтесь, що ваш сервер працює добре. Перевірте підключення до мережі. Іноді може допомогти вимкнення та ввімкнення мобільного передавання даних або Wi-Fi. - Відповідь вашого сервера була неправильною. Перевірте, чи можете ви отримати доступ до своїх нотаток через веб-інтерфейс. + Отримано неправильну відповідь від сервера. Перевірте, чи ви маєте доступ до вашіх нотаток через вебінтерфейс. Виникла проблема з налаштуванням Nextcloud. Будь ласка, подивіться файли журналу сервера. Будь ласка, перевірте, чи ваш сервер Nextcloud наразі не перебуває в режимі обслуговування. Ваш сервер Nextcloud не має вільного місця. Будь ласка, вилучіть непотрібні файлі, щоби можна було виконувати синхронізацію змін на пристрої з хмарою. @@ -167,21 +169,21 @@ Вимкніть усі оптимізації батареї для застосунків Nextcloud та Нотатки Nextcloud. Застосунок \"Нотатки\" для Android вимагає версію не менше 3.18 застосунку Nextcloud для Android. Додано \"%1$s\" - Поширений текст був порожнім + Поширений текст порожній Доповнити нотатку Змінити заголовок нотатки - Редагувати нотатку + Редагувати Безпека Вигляд і поведінка Синхронізація Облікові записи Форматування - - Відкривати у режимі редагування - Відкривати у режимі перегляду - Запам\'ятовувати останній вибір - + + Режим простого редагування + Режим простого перегляду + Режим форматованого редагування + Запам\'ятовувати останній вибір Малий @@ -312,4 +314,7 @@ Імпортування нотаток... Імпортування нотатки %1$d з %2$d... Обліковий запис імпортовано. - + Помилка під час завантаження форматованого редагування + Перемкнутися до простого редагування + Назад + diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml index 9aa6bee4f..65078d7de 100644 --- a/app/src/main/res/values-vi/strings.xml +++ b/app/src/main/res/values-vi/strings.xml @@ -50,6 +50,9 @@ Đồng bộ hoá trong nền Ngăn chặn chụp màn hình Hiển thị dạng lưới + Giữ màn hình luôn mở + Khi đang xem hoặc sửa ghi chú + Đồng bộ hoá thất bại: %1$s Đồng bộ hoá thất bại Không có kết nối mạng @@ -85,6 +88,8 @@ Ghi chú đơn Không tìm thấy ghi chú Vui lòng đăng nhập vào Ghi chú trước khi sử dụng tiện ích này + Biểu tượng ngôi sao thể hiện mục được yêu thích + Chọn ghi chú Tạo một ghi chú mới @@ -154,11 +159,8 @@ Quản lý tài khoản Định dạng - - Mở trong chế độ chỉnh sửa - Mở trong chế độ xem trước - Nhớ sự lựa chọn cuối của tôi - + + Nhớ sự lựa chọn cuối của tôi Nhỏ @@ -269,4 +271,5 @@ Đang nhập các ghi chú... Đang nhập ghi chú %1$d trong số %2$d... Đã nhập tài khoản. - + Quay lại + diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index b95c1b56d..6121dee72 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -177,11 +177,8 @@ 管理账号 格式 - - 以编辑模式打开 - 以预览模式打开 - 记住我上一次的选择 - + + 记住我上一次的选择 @@ -297,4 +294,5 @@ 导入笔记中… 正导入 %2$d 中的笔记 %1$d … 账号已导入 - + 返回 + diff --git a/app/src/main/res/values-zh-rHK/strings.xml b/app/src/main/res/values-zh-rHK/strings.xml index 66a4877a4..c28db2286 100644 --- a/app/src/main/res/values-zh-rHK/strings.xml +++ b/app/src/main/res/values-zh-rHK/strings.xml @@ -41,6 +41,7 @@ 上個月 筆記顯示模式 + Notes 打開行為 佈景主題 等寬字體 字體大小 @@ -63,6 +64,7 @@ 你目前使用 %1$s 保養員 開發員 + 原作者 翻譯員 %1$s 上的 Nextcloud 社群 測試員 @@ -177,11 +179,11 @@ 賬戶管理 正在格式化 - - 以編輯模式開啟 - 以預覽模式開啟 - 記住上次選擇 - + + 普通編輯模式 + 普通預覽 + 增強編輯模式 + 記住上次選擇 @@ -297,4 +299,7 @@ 正在導入筆記... 正導入筆記 %2$d 之 %1$d ... 已導入賬戶。 - + 載入增強編輯模式時發生錯誤 + 切換到普通編輯模式 + 返回 + diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 61a77c0bb..b6c48a564 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -177,11 +177,8 @@ 帳戶管理 文字樣式 - - 以編輯模式開啟 - 以預覽模式開啟 - 記住上次選擇 - + + 記住上次選擇 @@ -297,4 +294,5 @@ 匯入筆記中... 匯入筆記 %2$d 之 %1$d 中... 已匯入賬戶。 - + 返回 + -- GitLab From 60b7a645a924a9d97e4bef0c554439af586eeb65 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 18 May 2023 08:14:28 +0000 Subject: [PATCH 124/163] build(deps): Bump org.robolectric:robolectric from 4.10.2 to 4.10.3 Bumps [org.robolectric:robolectric](https://github.com/robolectric/robolectric) from 4.10.2 to 4.10.3. - [Release notes](https://github.com/robolectric/robolectric/releases) - [Commits](https://github.com/robolectric/robolectric/compare/robolectric-4.10.2...robolectric-4.10.3) --- updated-dependencies: - dependency-name: org.robolectric:robolectric dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index bdbffa5ad..60d2d69ef 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -121,7 +121,7 @@ dependencies { testImplementation 'androidx.arch.core:core-testing:2.2.0' testImplementation 'junit:junit:4.13.2' testImplementation 'org.mockito:mockito-core:5.3.1' - testImplementation 'org.robolectric:robolectric:4.10.2' + testImplementation 'org.robolectric:robolectric:4.10.3' implementation fileTree(dir: 'libs', include: ['*.jar']) } -- GitLab From eceec7d32ba8120f69d51900b3015dbc813b913b Mon Sep 17 00:00:00 2001 From: Nextcloud bot Date: Sun, 21 May 2023 02:27:39 +0000 Subject: [PATCH 125/163] Fix(l10n): Update translations from Transifex Signed-off-by: Nextcloud bot --- app/src/main/res/values-ar/strings.xml | 4 ++-- app/src/main/res/values-zh-rCN/strings.xml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index 5de414901..ce14cd7c4 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -24,7 +24,7 @@ تراجع غير مصنف حذف - الفئة + التصنيف المفضلة معاينة شارك @@ -46,7 +46,7 @@ خط أحادي المسافة حجم الخط المزامنة فقط على الوايفاي - بيانات اعتماد الجهاز + معلومات تسجيل الدخول إلى الجهاز مزامنة في خلفية النظام عرض كمخطط المزامنة فشلت \'%1$s\' diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 6121dee72..8ecf4c17f 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -67,9 +67,9 @@ %1$s 上的 Nextcloud 社区 测试人员 源代码 - 此项目托管在 Github 上:%1$s + 此项目托管在GitHub上:%1$s 问题 - 你可以通过 GitHub 问题跟踪器报告 bug、提议增强已有功能和请求新功能:%1$s + 你可以通过GitHub议题跟踪器报告bug、提议增强已有功能和请求新功能:%1$s 翻译 加入 Transifex 上的 Nextcloud 团队,帮助我们翻译这个应用程序:%1$s 应用授权 -- GitLab From e740895255232a8faf62f503f22ba09fdf2286c8 Mon Sep 17 00:00:00 2001 From: Nextcloud bot Date: Mon, 22 May 2023 02:30:41 +0000 Subject: [PATCH 126/163] Fix(l10n): Update translations from Transifex Signed-off-by: Nextcloud bot --- app/src/main/res/values-tr/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index 1fcc6a8cf..b29c641da 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -151,7 +151,7 @@ İşaret kutusu Kilidi açma notları Hayıır. Şimdi ne olacak? 🙁 - Lütfen uygulamayı kapanmaya zorlayıp yeniden başlatın. Yanlış bir Nextcloud uygulaması bağlantısı olmalı. + Lütfen uygulamayı zorla kapatıp yeniden başlatın. Yanlış bir Nextcloud uygulaması bağlantısı olmalı. Sorun sürerse, çözmek için hem Nextcloud uygulamasının hem de Nextcloud Notlar uygulamasının depolamalarını temizlemeyi deneyin. Depolamayı temizlemek için uygulama bilgilerini açın ve Depolama (Hafıza) → Depolamayı temizle (Veriyi sil) seçin. ⚠️ Uyarı: Bu işlem henüz eşitlenmemiş notları silmeyecek! Nextcloud uygulamanız eski görünüyor. Lütfen son sürümü almak için Play Store ya da F-Droid mağazalarına gidin. -- GitLab From 13717fac929414c0b5d0abce8b97e0b9da7a05cf Mon Sep 17 00:00:00 2001 From: Nextcloud bot Date: Fri, 26 May 2023 02:26:26 +0000 Subject: [PATCH 127/163] Fix(l10n): Update translations from Transifex Signed-off-by: Nextcloud bot --- app/src/main/res/values-sl/strings.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/src/main/res/values-sl/strings.xml b/app/src/main/res/values-sl/strings.xml index ba464fafe..df4e9772a 100644 --- a/app/src/main/res/values-sl/strings.xml +++ b/app/src/main/res/values-sl/strings.xml @@ -41,6 +41,7 @@ Zadnji mesec Način odpiranja zabeležk + Obnašanje odpiranja beležk Tema Pisava enotne širine Velikost pisave @@ -179,6 +180,9 @@ Oblikovanje + Besedilni urejevalni način + Predogled urejevalnega načina + Oblikovni urejevalni način Zapomni si zadnjo izbiro @@ -310,5 +314,7 @@ Poteka uvažanje sporočilc ... Poteka uvažanje sporočilca %1$d od %2$d… Račun je uspešno uvožen. + Napaka nalaganja oblikovnega urejevalnika + Preklopi na besedilno urejanje Nazaj -- GitLab From e2535822be9fe307f2455110c44b21a0f816d920 Mon Sep 17 00:00:00 2001 From: Nextcloud bot Date: Mon, 29 May 2023 02:48:30 +0000 Subject: [PATCH 128/163] Fix(l10n): Update translations from Transifex Signed-off-by: Nextcloud bot --- app/src/main/res/values-da/strings.xml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/app/src/main/res/values-da/strings.xml b/app/src/main/res/values-da/strings.xml index 56c49e542..60369970f 100644 --- a/app/src/main/res/values-da/strings.xml +++ b/app/src/main/res/values-da/strings.xml @@ -112,11 +112,15 @@ Opgaver Opskrift Opskrifter + Mad Adgangskode Adgangskoder + Spil Spil Afspil + Gave + Gaver Kontoen er allerede importeret Ingen noter endnu Tryk på + for at oprette en ny note @@ -196,6 +200,11 @@ Afkrydsningsfelter Kode Tabeller + + Kolonne %1d + + Værdi %1d + Billeder Andet Sortér efter dato ændret -- GitLab From a7b479d8af628ecf168ba4e64143846c8a3bec55 Mon Sep 17 00:00:00 2001 From: Nextcloud bot Date: Tue, 30 May 2023 02:28:30 +0000 Subject: [PATCH 129/163] Fix(l10n): Update translations from Transifex Signed-off-by: Nextcloud bot --- app/src/main/res/values-ca/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/values-ca/strings.xml b/app/src/main/res/values-ca/strings.xml index 491b49ba0..56cabbfe8 100644 --- a/app/src/main/res/values-ca/strings.xml +++ b/app/src/main/res/values-ca/strings.xml @@ -296,8 +296,8 @@ Extensió de fitxer per a les notes noves al Nextcloud Sufix dels fitxers nous: %1$s Codi d\'estat HTTP: %1$d - S\'estan important les notes... - S\'està important la nota %1$d/%2$d... + S\'estan important les notes… + S\'està important la nota %1$d/%2$d… S\'ha importat el compte. Torna -- GitLab From 48cb02911b9aa3b36ec454ed88f40f72f2335780 Mon Sep 17 00:00:00 2001 From: nextcloud-android-bot Date: Tue, 30 May 2023 02:36:55 +0000 Subject: [PATCH 130/163] =?UTF-8?q?=F0=9F=94=84=20synced=20local=20'.githu?= =?UTF-8?q?b/workflows/'=20with=20remote=20'config/workflows/'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: nextcloud-android-bot --- .github/workflows/codeql.yml | 4 ++-- .github/workflows/scorecard.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 3cda0501e..a2d8b19dd 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -32,7 +32,7 @@ jobs: with: swap-size-gb: 10 - name: Initialize CodeQL - uses: github/codeql-action/init@29b1f65c5e92e24fe6b6647da1eaabe529cec70f # v2.3.3 + uses: github/codeql-action/init@0225834cc549ee0ca93cb085b92954821a145866 # v2.3.5 with: languages: ${{ matrix.language }} - name: Set up JDK @@ -46,4 +46,4 @@ jobs: echo "org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError" > "$HOME/.gradle/gradle.properties" ./gradlew assembleDebug - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@29b1f65c5e92e24fe6b6647da1eaabe529cec70f # v2.3.3 + uses: github/codeql-action/analyze@0225834cc549ee0ca93cb085b92954821a145866 # v2.3.5 diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 6585f8be6..4b1c7b345 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -33,6 +33,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@29b1f65c5e92e24fe6b6647da1eaabe529cec70f # v2.3.3 + uses: github/codeql-action/upload-sarif@0225834cc549ee0ca93cb085b92954821a145866 # v2.3.5 with: sarif_file: results.sarif -- GitLab From c7dd1c33757d93e42a2ad1c18f73e59c12df2440 Mon Sep 17 00:00:00 2001 From: nextcloud-android-bot Date: Wed, 7 Jun 2023 02:51:12 +0000 Subject: [PATCH 131/163] =?UTF-8?q?=F0=9F=94=84=20synced=20local=20'.githu?= =?UTF-8?q?b/workflows/'=20with=20remote=20'config/workflows/'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: nextcloud-android-bot --- .github/workflows/codeql.yml | 6 +++--- .github/workflows/scorecard.yml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index a2d8b19dd..396fa26aa 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -32,10 +32,10 @@ jobs: with: swap-size-gb: 10 - name: Initialize CodeQL - uses: github/codeql-action/init@0225834cc549ee0ca93cb085b92954821a145866 # v2.3.5 + uses: github/codeql-action/init@83f0fe6c4988d98a455712a27f0255212bba9bd4 # v2.3.6 with: languages: ${{ matrix.language }} - - name: Set up JDK + - name: Set up JDK 17 uses: actions/setup-java@5ffc13f4174014e2d4d4572b3d74c3fa61aeb2c2 # v3.11.0 with: distribution: "temurin" @@ -46,4 +46,4 @@ jobs: echo "org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError" > "$HOME/.gradle/gradle.properties" ./gradlew assembleDebug - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@0225834cc549ee0ca93cb085b92954821a145866 # v2.3.5 + uses: github/codeql-action/analyze@83f0fe6c4988d98a455712a27f0255212bba9bd4 # v2.3.6 diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 4b1c7b345..e774cebe8 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -33,6 +33,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@0225834cc549ee0ca93cb085b92954821a145866 # v2.3.5 + uses: github/codeql-action/upload-sarif@83f0fe6c4988d98a455712a27f0255212bba9bd4 # v2.3.6 with: sarif_file: results.sarif -- GitLab From be9e6ba58e141984f9a645e586febfbea74dac4d Mon Sep 17 00:00:00 2001 From: Nextcloud bot Date: Thu, 8 Jun 2023 02:26:33 +0000 Subject: [PATCH 132/163] Fix(l10n): Update translations from Transifex Signed-off-by: Nextcloud bot --- app/src/main/res/values-fa/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/values-fa/strings.xml b/app/src/main/res/values-fa/strings.xml index 4286174df..c4ea3de43 100644 --- a/app/src/main/res/values-fa/strings.xml +++ b/app/src/main/res/values-fa/strings.xml @@ -133,7 +133,7 @@ اتصال اینترنت خود را بررسی کنید. خاموش کردن اینترنت همراه و وای‌فای و روشن کردن مجدد آنها در برخی از مواقع می‌تواند کارساز باشد. پاسخ درستی از سرور شما دریافت نشد. لطفا دسترسی به یادداشت‌های خود را از طریق وب بررسی کنید. مشکلی در نصب ابر Nextcloud وجود دارد. لطفا لاگ‌های سرور را بررسی کنید. - لطفا بررسی کنید که نسخه Nextcloud شما در حال حاضر در حالت تعمیر و نگهداری نباشد. + لطفا بررسی کنید که نسخه نکست‌کلود شما در حال حاضر در حالت تعمیر و نگهداری نباشد. فضای برنامک نکست‌کلود شما پر شده است.لطفا یعضی از فایل‌های خود در را فضای ابری برای همگام‌سازی تغییرات محلی پاک کنید. ما برای کمک به شما احتیاج به دنبال کردن اطلاعات فنی داریم: لطفا از نصب و فعال بودن برنامک یادداشت بر روی سرور، اطمینان حاصل کنید. -- GitLab From 6827b32f78fae0c69bfd5b578168da769441ebb9 Mon Sep 17 00:00:00 2001 From: Nextcloud bot Date: Mon, 12 Jun 2023 02:29:22 +0000 Subject: [PATCH 133/163] Fix(l10n): Update translations from Transifex Signed-off-by: Nextcloud bot --- app/src/main/res/values-gl/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/values-gl/strings.xml b/app/src/main/res/values-gl/strings.xml index 8d67935ff..900cad3ca 100644 --- a/app/src/main/res/values-gl/strings.xml +++ b/app/src/main/res/values-gl/strings.xml @@ -51,7 +51,7 @@ Sincronización do traballo en segundo plano Evitar a captura da pantalla Ver como grella - Mantén a pantalla acesa + Mantér a pantalla acesa Ao ver ou editar unha nota Produciuse un fallo na sincronización: %1$s @@ -263,7 +263,7 @@ Valor %1d As ligazóns teñen que ser URL completos que comezan cun protocolo e dominio ou camiños absolutos que comezan cun carácter %1$s. - Para axustarse ao formato Markdown, utiliza caracteres de escape no URL da imaxe. Isto significa, por exemplo, substituír espazos por %1$s no URL. + Para axustarse ao formato Markdown, utilice caracteres de escape no URL da imaxe. Isto significa, por exemplo, substituír espazos por %1$s no URL. Imaxes Imaxe elegante -- GitLab From e92f489df4fcb5bac5c40a457f344f2182687690 Mon Sep 17 00:00:00 2001 From: Nextcloud bot Date: Fri, 16 Jun 2023 02:28:04 +0000 Subject: [PATCH 134/163] Fix(l10n): Update translations from Transifex Signed-off-by: Nextcloud bot --- app/src/main/res/values-gl/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/values-gl/strings.xml b/app/src/main/res/values-gl/strings.xml index 900cad3ca..818277bd8 100644 --- a/app/src/main/res/values-gl/strings.xml +++ b/app/src/main/res/values-gl/strings.xml @@ -123,9 +123,9 @@ Comida Enfornar - Clave + Chave - Claves + Chaves Contrasinal Contrasinais Credencial -- GitLab From 4bb55a0f71001d09deb7d5ee37c0171fe81b20e9 Mon Sep 17 00:00:00 2001 From: Nextcloud bot Date: Sun, 18 Jun 2023 02:26:46 +0000 Subject: [PATCH 135/163] Fix(l10n): Update translations from Transifex Signed-off-by: Nextcloud bot --- app/src/main/res/values-gl/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/values-gl/strings.xml b/app/src/main/res/values-gl/strings.xml index 818277bd8..7aace169c 100644 --- a/app/src/main/res/values-gl/strings.xml +++ b/app/src/main/res/values-gl/strings.xml @@ -71,7 +71,7 @@ Código fonte Este proxecto está aloxado en GitHub: %1$s Incidencias - Vostede pode informar de fallos, propoñer melloras e solicitar funcionalidades na ferramenta de seguimento de erros do GitHub: %1$s + Vostede pode informar de fallos, propoñer melloras e solicitar funcionalidades na ferramenta de seguimento de incidencias do GitHub: %1$s Traducir Únase ao equipo Nextcloud en Transifex e axúdenos a traducir esta aplicación: %1$s Licenza da apli -- GitLab From a1d37a4f78ca7fb2318b055d6a84b65641b4c5cc Mon Sep 17 00:00:00 2001 From: Nextcloud bot Date: Mon, 19 Jun 2023 02:33:08 +0000 Subject: [PATCH 136/163] Fix(l10n): Update translations from Transifex Signed-off-by: Nextcloud bot --- app/src/main/res/values-gl/strings.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/res/values-gl/strings.xml b/app/src/main/res/values-gl/strings.xml index 7aace169c..7904e7921 100644 --- a/app/src/main/res/values-gl/strings.xml +++ b/app/src/main/res/values-gl/strings.xml @@ -173,7 +173,7 @@ Anexo á nota Cambiar o título da nota Editar o título - Seguridade + Seguranza Aparencia e comportamento Sincronización Xestionar contas @@ -289,8 +289,8 @@ Seguinte Anterior - Copia de seguridade - Detectamos un estado irrecuperábel da aplicación. Faga unha copia de seguridade dos cambios non sincronizados e limpe o almacenamento da apli de Notas. + Copia de seguranza + Detectamos un estado irrecuperábel da aplicación. Faga unha copia de seguranza dos cambios non sincronizados e limpe o almacenamento da apli de Notas. Cartafol para almacenar as súas notas no seu Nextcloud .txt -- GitLab From b8795bd68aac2232dad8f8d69535b8f11d84f151 Mon Sep 17 00:00:00 2001 From: Nextcloud bot Date: Tue, 20 Jun 2023 02:39:06 +0000 Subject: [PATCH 137/163] Fix(l10n): Update translations from Transifex Signed-off-by: Nextcloud bot --- app/src/main/res/values-gl/strings.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/res/values-gl/strings.xml b/app/src/main/res/values-gl/strings.xml index 7904e7921..0b3ef35b9 100644 --- a/app/src/main/res/values-gl/strings.xml +++ b/app/src/main/res/values-gl/strings.xml @@ -2,7 +2,7 @@ Notas - Notas do Nextcloud + Notas de Nextcloud Todas as notas Favoritas Nova nota @@ -160,7 +160,7 @@ Non houbo resposta do seu servidor no tempo dado. Asegúrese de que a súa instancia funciona correctamente. Comprobe a súa conexión de rede. Ás veces apagar e volver acender os datos móbiles ou a wifi pode axudar. A resposta do servidor non foi correcta. Comprobe se pode acceder a Notas a través de interface web. - Hai un problema coa configuración do Nextcloud. Bótelle un ollo aos ficheiros de rexistro do servidor. + Hai un problema coa configuración de Nextcloud. Bótelle un ollo aos ficheiros de rexistro do servidor. Comprobe que a súa instancia Nextcloud non se atope en modo de mantemento. A súa instancia Nextcloud non dispón de espazo de almacenamento libre. Elimine algúns ficheiros para sincronizar os seus cambios locais na súa nube. Necesitamos a seguinte información técnica para axudarlle: @@ -225,7 +225,7 @@ Só ten que seleccionar un intervalo de texto ou tocar no cursor en calquera posición e obterá un menú emerxente que contén xunto ás entradas predeterminadas %1$s, %2$s, %3$s entradas como %4$s ou %5$s. Texto - É moi sinxelo facer algunhas palabras en %1$snegriña%1$s e outras palabras en %2$scursiva%2$s con Markdown. Pode %3$sriscar%3$s algunhas palabras e incluso [ligar ao Nextcloud](https://nextcloud.com). + É moi sinxelo facer algunhas palabras en %1$snegriña%1$s e outras palabras en %2$scursiva%2$s con Markdown. Pode %3$sriscar%3$s algunhas palabras e incluso [ligar a Nextcloud](https://nextcloud.com). Listas Ás veces quere listas numeradas: -- GitLab From 30e21243653939b86ceebe58cd9852a07b8c635a Mon Sep 17 00:00:00 2001 From: tobiasKaminsky Date: Wed, 21 Jun 2023 08:46:13 +0200 Subject: [PATCH 138/163] Bump main to 4.1 RC1 Signed-off-by: tobiasKaminsky --- app/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 60d2d69ef..efbab6461 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -14,8 +14,8 @@ android { applicationId "it.niedermann.owncloud.notes" minSdkVersion 24 targetSdkVersion 33 - versionCode 40010000 - versionName "4.1.0 Alpha1" + versionCode 40010051 + versionName "4.1.0 RC1" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" javaCompileOptions { annotationProcessorOptions { -- GitLab From bc579db084ecc8f80928d85d9e8009580ca12eea Mon Sep 17 00:00:00 2001 From: Nextcloud bot Date: Thu, 22 Jun 2023 02:45:35 +0000 Subject: [PATCH 139/163] Fix(l10n): Update translations from Transifex Signed-off-by: Nextcloud bot --- app/src/main/res/values-gl/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/values-gl/strings.xml b/app/src/main/res/values-gl/strings.xml index 0b3ef35b9..ee1660ee1 100644 --- a/app/src/main/res/values-gl/strings.xml +++ b/app/src/main/res/values-gl/strings.xml @@ -155,7 +155,7 @@ Se o problema continúa, tente limpar o almacenamento de ambas as aplis: Nextcloud e Nextcloud Notas para resolver este problema. Pode limpar o almacenamento abrindo a información da apli e seleccionando Almacenamento → Limpar o almacenamento.⚠️ Advertencia: Isto eliminará as notas que aínda non estean sincronizadas. A súa apli Nextcloud semella estar desactualizada. Visite Play Store ou F-Droid para obter a última versión. - Semella que algo está mal na súa apli Nextcloud. Tente forzar a parar ambas, a apli Nextcloud e a apli Nextcloud Notes. + Semella que algo foi mal na súa apli Nextcloud. Tente forzar a parar ambas, a apli Nextcloud e a apli Nextcloud Notes. Se detelos pola forza non axuda, pode tentar limpar o almacenamento de ambas as aplicacións. Non houbo resposta do seu servidor no tempo dado. Asegúrese de que a súa instancia funciona correctamente. Comprobe a súa conexión de rede. Ás veces apagar e volver acender os datos móbiles ou a wifi pode axudar. @@ -182,7 +182,7 @@ Modo de edición simple Vista previa simple - Modo de edición enriquecido + Modo de edición mellorada Lembrar a miña última selección -- GitLab From ccedcb1a040870ab28365c73844f6a48470ce6e6 Mon Sep 17 00:00:00 2001 From: Nextcloud bot Date: Sat, 1 Jul 2023 02:38:27 +0000 Subject: [PATCH 140/163] Fix(l10n): Update translations from Transifex Signed-off-by: Nextcloud bot --- app/src/main/res/values-ar/strings.xml | 268 +++++++++++++++---------- 1 file changed, 166 insertions(+), 102 deletions(-) diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index ce14cd7c4..67a79c1d3 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -1,16 +1,15 @@ - الملاحظات - ملاحظات نيكست كلاود - جميع الملاحظات - - المفضلات - ملاحظة جديدة + الملاحظات Notes + ملاحظات Notes نيكست كلاود + جميع الملاحظات + المُفضّلة + ملاحظة Note جديدة مرحبًا بك في %1$s الإعدادات - مسح الملاحظات - البحث + ملاحظات محذوفة + بحث طريقة الترتيب إلغاء تبديل @@ -18,8 +17,8 @@ حذف حفظ عن - الرابط - حُذف \'%1$s\' + رابط + محذوف \'%1$s\' أُسترجع \'%1$s\' تراجع غير مصنف @@ -42,119 +41,151 @@ الشهر الماضي وضع العرض للملاحظات - المظهر - خط أحادي المسافة + السلوك عند فتح الملاحظات + الثيمة + خط font أحادي المسافة حجم الخط - المزامنة فقط على الوايفاي - معلومات تسجيل الدخول إلى الجهاز - مزامنة في خلفية النظام + المزامنة فقط على الواي فاي + قفل التطبيق (بيتا) + حيثيات الدخول للجهاز + مزامنة في الخلفية + منع التقاط صورة للشاشة عرض كمخطط - المزامنة فشلت \'%1$s\' - المزامنة فشلت + حافظ على الشاشة قيد العمل + عند عرض أو تحرير ملاحظة + + إخفاق في المزامنة: \'%1$s\' + إخفاق في المزامنة لا يتوفر اتصال - الخادم في وضع الصيانة - حدث خطأ غير معروف. + الخادوم في وضع الصيانة + حدث خطأ غير مُحدّدٍ الإصدار - استهلكتَ حاليا %1$s - مشرف -  المطورون -  المترجِمون + أنت حاليّاً تستعمل %1$s + مُنسّق + المُطوّرون + الكاتب الأصلي + المترجِمون مجتمع نكست كلاود على %1$s -  المجَرِّبون - الشفرة المصدرية - هذا المشروع مستضاف على جيت هب: %1$s + المجَرِّبون + الكود المصدري + هذا المشروع مستضاف على Github: %1$s المشاكل - يمكنك الإبلاغ عن الأخطاء، ترشيح مزايا أو طلب تحسين على GitHub issue tracker:%1$s + يمكنك الإبلاغ عن الأخطاء، ترشيح مزايا أو طلب تحسينات على GitHub issue tracker:%1$s تَرجِم إنضم إلى فريق نكست كلاود على Transifex وساعد في ترجمة هذا التطبيق: %1$s -  رخصة التطبيق - التطبيق مسجل تحت شهادة جنو العامة الاصدار 3+ + رخصة التطبيق + التطبيق مسجل تحت شهادة GNU العامة الاصدار 3+ عرض الرخصة -  الأيقونات + الأيقونات لرؤية الأيقونة الأصلية %1$s. - جميع الأيقونات الأخرى التي يستخدمها هذا التطبيق %1$s من صنع Google Inc. ومرخصة بموجب ترخيص Apache 2.0. - مادة تصميم الأيقونات - الشكر ل - المساهمة -  الرخصة + جميع الأيقونات الأخرى التي يستخدمها هذا التطبيق %1$s هي من إنتاج Google Inc. ومرخصة بموجب ترخيص Apache 2.0. + أيقونات من طراز Material Design + شكرٌ و تقديرٌ + مساهمة + الرخصة قائمة الملاحظات لا ملاحظات - ملاحظة مفردة - - الملاحظة غير موجودة - - الرجاء تسجيل الدخول قبل إستخدامك لهذه الأداة - اختيار الملاحظة + ملاحظة مفردة + الملاحظة غير موجودة + الرجاء تسجيل الدخول إلى تطبيق الملاحظات Notes قبل إستخدامك لهذه الوَدْجَة Widget + أيقونة النجمة تستخدم لتسجيل عنصر كمُفضّل favorite + + إختيار ملاحظة انشاء ملاحظة جديدة عادي - مزامنة على الوايفاي و بيانات الهاتف - الحماية بكلمة السر + مزامنة على الواي فاي Wi-Fi، و بيانات الهاتف النقّال mobile data + محمي بكلمة مرور خطأ إغلاق - أنسخ + إنسخ استثناء - تثبيت الى الشاشة الرئيسية - هذه الملاحظة مُسحت + تثبيت في الشاشة الرئيسية + هذه الملاحظة تمّ مسحها أضف حسابا - الموسيقى - الأفلام + موسيقى + أفلام فلم - العمل + عمل + مَهَمّة + مَهَام + قائمة مراجعة المهام + وصفة أكل + وصفات أكل مطعم - كلمة السر - الكلمات السرية + مطاعم + طعام + خَبْز + + مفتاح + + مفاتيح + كلمة مرور + كلمات مرور + حيثيّات الدخول credentials لعبة - الألعاب + ألعاب تشغيل + هدية + هدايا + + جائزة - حاضر - تم بالفعل استيراد الحساب - لا ملاحظات حاليا - اضغط علامة + لانشاء ملاحظة جديدة + جوائز + + سبق استيراد الحساب + لا ملاحظات بعدُ + اضغط + لانشاء ملاحظة جديدة المزيد نقل - القراءة فقط + للقراءة فقط لا تصنيف - اضف %1$s - مربع + أضف %1$s + مربع اختيار فتح قفل الملاحظات آه لا، ماذا الان؟🙁 - الرجاء محاولة اجبار اغلاق التطبيق واعادة تشغيله، ربما هنالك خطأ في الاتصال مع تطبيق نيكست كلاود nextcloud + رجاءً، إفرض غلق التطبيق ثم أعد تشغيله، ربما هنالك خطأ في الاتصال مع تطبيق نيكست كلاود. اذا تكررت المشكلة، حاول تنظيف مساحة التخزين في التطبيقين كلاهما: نيكست كلاود nextcloud، نيكست كلاود ملاحظات nextcloud notes لحل هذه المشكلة. - تطبيقك نيكست كلاود (Nexcloud) يبدو انه مهمل (لم يحدث منذ زمن). رجاءا زُر بلي ستور او اف-درويد (f-droid) لتحصل على اخر اصدار. - يبدو أن هناك خطأ ما في تطبيق Nextcloud الخاص بك. يرجى محاولة فرض إيقاف كلا من تطبيق Nextcloud وتطبيق Nextcloud Notes. + يمكنك تنظيف ذاكرة التطبيق بفتح \"معلومات التطبيق\" app info ثم اختيار \"التخزين\" ثم \"محو التخزين\" Storage → Clear storage. +⚠️ تحذير: هذا سيؤدي إلى حذف الملاحظات التي لم تتم مزامنتها بعدُ. + تطبيقك نيكست كلاود يبدو انه لم يتم تحديثه منذ وقت طويل. رجاءً، قم بزيارةمتجر تطبيقات \"إف-درويد\" f-droid للحصول على آخر إصدار منه. + يبدو أن هناك خطأ ما في تطبيقك نكست كلاود. يرجى محاولة فرض إيقاف كلا التطبيقين: Nextcloud و Nextcloud Notes. إذا لم يساعد إيقافهم بالقوة ، فيمكنك محاولة مسح تخزين كلا التطبيقين. - لم يكن هناك استجابة من الخادم الخاص بك في الوقت المحدد. يرجى التأكد من أن الخادم الخاص بك يعمل بشكل جيد. - تحقق من اتصالك بالشبكة. أحياناُ، يمكن أن يساعد إيقاف بيانات الهاتف المحمول أو إيقاف تشغيل Wi-Fi وتشغيله مرة أخرى. - لم تكن استجابة الخادم الخاص بك صحيحة. يرجى التحقق مما إذا كان يمكنك الوصول إلى ملاحظاتك عبر واجهة الويب. - هناك مشكلة في إعداد Nextcloud الخاص بك. يرجى إلقاء نظرة على ملفات سجل الخادم. - يرجى التحقق مما إذا كان خادم Nextcloud الخاص بك ليس في وضع الصيانة حاليًا. - خادم Nextcloud الخاص بك ليس لديه مساحة تخزين فارغة متبقية. يرجى حذف بعض الملفات لمزامنة التغييرات المحلية الخاصة بك في السحابة الخاصة بك. + لم يكن هناك استجابة من خادومك في الوقت المحدد. يرجى التأكد من أنه يعمل بشكل جيد. + تحقق من اتصالك بالشبكة. أحياناُ، يمكن لإيقاف ثم إعادة تشغيل بيانات الهاتف المحمول أو الواي فاي Wi-Fi أن يحل المشكل. + لم تكن استجابة خادومك صحيحة. يرجى التحقق مما إذا كان يمكنك الوصول إلى ملاحظاتك عبر واجهة الويب. + هناك مشكلة في إعداد خادومك. يرجى مراجعة سجل حركات الخادوم log. + يرجى التحقق من أن خادومك ليس في وضع الصيانة حاليًا. + خادومك ليس لديه مساحة تخزين فارغة متبقية. يرجى حذف بعض الملفات لمزامنة تغييراتك المحلية في سحابتك. نحتاج إلى المعلومات الفنية التالية لمساعدتك: - يرجى التأكد من تثبيت وتمكين تطبيق \"Notes\" على خادمك. - استجاب خادمك برمز حالة HTTP 302 ، مما يعني أنك لم تقم بتثبيت تطبيق Notes على الخادم الخاص بك أو أنه تم تكوين شيء ما بشكل خاطئ. يمكن أن يحدث هذا بسبب التجاوزات المخصصة في ملف htaccess أو تطبيقات Nextcloud مثل عميل OID. + يرجى التأكد من تنصيب و تفعيل تطبيق \"Notes\" على خادومك. + استجاب خادومك برمز حالة HTTP 302 ، مما يعني أنك لم تقم بتثبيت تطبيق Notes عليه أو أنه تم تكوين شيء ما بشكل خاطئ. يمكن أن يحدث هذا بسبب بعض التخصيصات في ملف htaccess أو تطبيقات Nextcloud مثل عميل OID. يرجى تعطيل جميع تحسينات البطارية لـ Nextcloud وتطبيق Notes. + تطبيق الملاحظات Notes على الأندرويد يلزمه تطبيق Notes على نكست كلاود بإصدار لا يقل عن 3,18. \"%1$s\" أضيفت - كان النص المشارك فارغًا - إلحاق بالملاحظة - تغيير عنوان الملاحظة - تحرير العنوان + كان النصّ المُشارًك فارغًا + إلحاق بملاحظة + تغيير عنوان ملاحظة + تحرير عنوان الأمان + المظهر و التّصرُّف المزامنة إدارة الحسابات التنسيق - تذكر آخر ما أخترته + وضعية التحرير العادي plain + معاينة عادية + وضعية التحرير الغني rich + تذكر آخر ما اخترْتُهُ صغير @@ -164,7 +195,7 @@ فاتح - ليلي + داكن إفتراضي النظام @@ -174,63 +205,96 @@ %d محددان %d محددين %d محددين - %d محدد + %d مُحدّد --- `%1$s` \\`%1$s\\` ``` + ```` ```javascript - التنسيق القائم على السياق (المحتوى) - يتمثل أحد أهداف التصميم الرئيسية لتطبيق Notes في توفير أداة خالية من التشتيت. على الرغم من أنك ستتمكن من تنسيق النصوص الخاصة بك باستخدام Markdown. بالنسبة للعديد من الأمثلة المذكورة أدناه ، يمكنك استخدام الاختصارات حتى تتمكن من تنسيق ملاحظاتك دون كتابة الرموز أدناه. - ما عليك سوى تحديد نطاق من النص أو النقر على المؤشر في أي موضع وستحصل على قائمة منبثقة تحتوي على بجوار الإدخالات الافتراضية %1$s, %2$s, %3$s إدخالات مثل %4$s أو %5$s. + تنسيق بحسب السياق + يتمثل أحد أهداف التصميم الرئيسية لتطبيق Notes في توفير أداة خالية من التشتيت. على الرغم من أنك ستتمكن من تنسيق النصوص الخاصة بك باستخدام Markdown. بالنسبة للعديد من الأمثلة المذكورة أدناه ، يمكنك استخدام الاختصارات حتى تتمكن من تنسيق ملاحظاتك دون كتابة الرموز أدناه. + ما عليك سوى تحديد نطاق من النص أو النقر على المؤشر في أي موضع وستحصل على قائمة منبثقة تحتوي بالإضافة إلى مُداخلها الافتراضية %1$s, %2$s, %3$s مداخل مثل %4$s أو %5$s. نص - من السهل جدًا كتابة بعض الكلمات %1$sعريضة%1$s وبعض الكلمات %2$sمائلة%2$s بإستخدام Markdown. يمكنك %3$sشخط%3$s بعض الكلمات كما يمكنك أيضا [وصل بـ Nextcloud](https://nextcloud.com). + من السهل جدًا كتابة بعض الكلمات %1$sثخينة bold%1$s وبعض الكلمات %2$sمائلة italic%2$s بإستخدام تنسيق مارك داون Markdown. يمكنك %3$sشطب strike%3$s بعض الكلمات. [رابط إلى نكست كلاود] (https://nextcloud.com). قوائم - في بعض الأحيان تريد قوائم مرقمة: + أحياناً تريد قوائم مرقمة numbered lists: واحد إثنان ثلاثة - في بعض الأحيان تريد نقاطًا نقطية: - ابدأ سطرًا بشرطة - وإذا كانت لديك نقاط فرعية ، فضع مسافتين قبل الشرطة أو النجمة: - هكذا - وهكذا + في بعض الأحيان تريد بنوداً مُنقّطة bullet points: + ابدأ سطرًا بشَرْطَة + وإذا كانت لديك نقاط فرعية، فضع مسافتين قبل الشَرْطَة أو النجمة: + مثل هذا + و هذا مربعات الاختيار لإنشاء مربع اختيار ، استخدم قائمة متبوعة بأقواس عنصر 1 عنصر 2 - وثائق منظمة - من المفيد أحيانًا أن يكون لديك مستويات مختلفة من العناوين لبناء مستنداتك. تبدأ الأسطر ب %1$s لإنشاء العناوين. تعدد %2$s في صف يشير إلى أحجام عناوين أصغر. + مستندات مُهَيْكَلة + من المفيد أحيانًا أن يكون لديك مستويات مختلفة من العناوين لبناء مستنداتك. إبدإ الأسطر بـ %1$s لإنشاء العناوين. %2$s متعددة في سطر يشير إلى أحجام عناوين أصغر. هذا عنوان من الدرجة الثالثة يمكنك إستخدام واحد %1$s على طول حتى %2$s ستة لأحجام العناوين المختلفة. - إذا كنت ترغب في اقتباس أحد، فاستخدم الحرف %1$s قبل السطر: - الخيال أكثر أهمية من المعرفة. المعرفة محدودة. يطوق الخيال العالم. - - البرت اينشتاين + إذا كنت ترغب في الاقتباس من أحد، فاستخدم الحرف %1$s قبل السطر: + الخيال أكثر أهمية من المعرفة. المعرفة محدودة. الخيال يُطوّق العالم. + - ألبرت أينشتاين الرمز - هناك العديد من الطرق المختلفة لتصميم التعليمات البرمجية باستخدام Markdown. إذا كان لديك كتل تعليمات برمجية مضمنة ، فلفها في backticks ( ` ) : - يدعم Markdown أيضًا شيئًا يسمى سياج الكود ، والذي يسمح بخطوط متعددة بدون مسافة بادئة: - وإذا كنت ترغب في استخدام تمييز بناء الجملة، فقم بتضمين اللغة البرمجية: + هناك العديد من الطرق المختلفة لتصميم التعليمات البرمجية باستخدام تنسيق مارك داون Markdown. إذا كان لديك كتل من الكود، فلُفّها في backticks : + يدعم Markdown أيضًا شيئًا يسمى سياج الكود، والذي يسمح بخطوط متعددة بدون مسافة بادئة: + وإذا كنت ترغب في استخدام تمييز بناء الجملة syntax highlighting، فقم بتضمين اللغة: الجداول + + عمود %1d + + قيمة %1d + + يجب أن تكون الروابط إمّا عناوين URL كاملة تبدأ ببروتوكول و نطاق، أو مسارات مطلقة تبدأ بحرف + %1$s: + من أجل التوافق مع تنسيق Markdown، يرجى استخدام أحرف الهروب escape characters في عنوان URL للصورة. هذا يعني على سبيل المثال، استبدل المسافات بـ%1$s في الـ URL. صور + صورة خيالية + آخر - ترتيب حسب تاريخ التعديل + ترتيب حسب تاريخ آخر تعديل الترتيب حسب الأبجدية إعدادات البطارية - افتح معلومات التطبيق - اعدادات الشبكة + إفتح معلومات التطبيق + إعدادات الشبكة تحديث - لا يوجد لديك أي حسابات مكونة أخرى حتى الآن. - اختر حسابًا - يجب أن تكون متصلًا بالانترنت لإضافة حساب. + لم تتم تهيئة الحساب بعدُ + أنت لم تقم بتهيئة أي حسابات أخرى بعدُ. + إختر حسابًا + نافذة منبثقة للتنسيق القائم على السياق Context based formatting + حذف %1$s + + يجب أن تكون متصلًا بالانترنت ليُمكنك إضاف حساب. + تعيين مُجلّد + التالي السابق النسخ الاحتياطي - العودة + اكتشفنا حالة غير قابلة للاسترداد للتطبيق. يرجى الاحتفاظ بنسخة احتياطية من التغييرات غير المتزامنة ومسح تخزين تطبيق Notes. + مُجلّد لتخزين ملاحظاتك في خادوم نكست كلاود + + .txt + .md + + مُجلّد ملاحظات جديدة: %1$s + إمتداد الملف + إمتداد الملف لملاحظاتك الجديدة في خادوم نكست كلاود + لاحقة الملف الجديدة suffix: %1$s + رمز حالة HTTP status code: %1$d + إستيراد ملاحظات ... + إستيراد الملاحظة %1$d من %2$d… + الحساب تمّ استيراده + خطأ في تحميل التحرير الغني rich editing + بدّل إلى التحرير العادي plain editing + عودة -- GitLab From fed30d657c6826f8421aa146067dec3922efd0ae Mon Sep 17 00:00:00 2001 From: Nextcloud bot Date: Thu, 6 Jul 2023 02:42:34 +0000 Subject: [PATCH 141/163] Fix(l10n): Update translations from Transifex Signed-off-by: Nextcloud bot --- app/src/main/res/values-uk/strings.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index fa946d538..055c70756 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -4,7 +4,7 @@ Нотатки Нотатки для Nextcloud Усі нотатки - Улюблене + Вподобане Новий запис Вітаємо у %1$s Налаштування @@ -240,7 +240,7 @@ Один Два Три - Іноді вам потрібні списки з позначками: + Іноді вам потрібні ненумеровані списки: Почніть рядок з риски А якщо у вас є підпункти, поставте два пробіли перед тире або зірочку: Ось так @@ -260,7 +260,7 @@ - Альберт Ейнштейн Код - Існує багато різних способів стилізувати код за допомогою Markdown. Якщо у вас є вбудовані блоки коду, оберніть їх у зворотні позначки: + Існує багато різних способів стилізувати код за допомогою Markdown. Якщо у вас є вбудовані блоки коду, оберніть їх символами зворотнього апострофу: Markdown також підтримує те, що називається огородженням коду, що дозволяє використовувати кілька рядків без відступу: А якщо ви хочете використовувати підсвічування синтаксису, додайте назву мови: -- GitLab From 70ca179e1891dbd47e196f9dae57bd8fc4f0c183 Mon Sep 17 00:00:00 2001 From: Nextcloud bot Date: Sun, 9 Jul 2023 02:46:04 +0000 Subject: [PATCH 142/163] Fix(l10n): Update translations from Transifex Signed-off-by: Nextcloud bot --- app/src/main/res/values-ar/strings.xml | 33 ++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index 67a79c1d3..18ee65be2 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -207,6 +207,31 @@ %d محددين %d مُحدّد + + ملاحظات %1$d محذوفة + ملاحظة واحدة محذوفة + ملاحظات %1$d محذوفة + ملاحظات %1$d محذوفة + ملاحظات %1$d محذوفة + ملاحظات %1$d محذوفة + + + ملاحظات %1$d مستعادة + ملاحظة واحدة مستعادة + ملاحظات %1$d مستعادة + ملاحظات %1$d مستعادة + ملاحظات %1$d مستعادة + ملاحظات %1$d مستعادة + + + مشاركة محتوي %1$d ملاحظات + مشاركة محتوي %1$d ملاحظة + مشاركة محتوي%1$dملاحظات + مشاركة محتوي %1$d ملاحظات + مشاركة محتوي %1$d ملاحظات + مشاركة محتوي %1$d ملاحظات + + --- `%1$s` \\`%1$s\\` @@ -272,6 +297,14 @@ أنت لم تقم بتهيئة أي حسابات أخرى بعدُ. إختر حسابًا نافذة منبثقة للتنسيق القائم على السياق Context based formatting + + سوف تؤدي إزالة الحساب%1$s أيضًا إلى حذف التغييرات غير المتزامنة الغير قابلة للاسترداد %2$d. + سوف تؤدي إزالة الحساب%1$s أيضًا إلى حذف التغيير غير المتزامن الغير قابل للاسترداد. + سوف تؤدي إزالة الحساب%1$s أيضًا إلى حذف التغييرات غير المتزامنة الغير قابلة للاسترداد %2$d. + سوف تؤدي إزالة الحساب %1$s أيضًا إلى حذف التغييرات غير المتزامنة الغير قابلة للاسترداد %2$d. + سوف تؤدي إزالة الحساب%1$s أيضًا إلى حذف التغييرات غير المتزامنة الغير قابلة للاسترداد %2$d. + سوف تؤدي إزالة الحساب %1$s أيضًا إلى حذف التغييرات غير المتزامنة الغير قابلة للاسترداد %2$d. + حذف %1$s يجب أن تكون متصلًا بالانترنت ليُمكنك إضاف حساب. -- GitLab From d543ce5511597bee451063de27f6fdc47193704f Mon Sep 17 00:00:00 2001 From: Nextcloud bot Date: Mon, 10 Jul 2023 02:45:35 +0000 Subject: [PATCH 143/163] Fix(l10n): Update translations from Transifex Signed-off-by: Nextcloud bot --- app/src/main/res/values-gl/strings.xml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/app/src/main/res/values-gl/strings.xml b/app/src/main/res/values-gl/strings.xml index ee1660ee1..808e3324c 100644 --- a/app/src/main/res/values-gl/strings.xml +++ b/app/src/main/res/values-gl/strings.xml @@ -46,7 +46,7 @@ Letra monoespazada Tamaño da letra Sincronizar só con wifi - Bloqueo de aplis (beta) + Bloqueo de aplicacións (beta) Credenciais do dispositivo Sincronización do traballo en segundo plano Evitar a captura da pantalla @@ -74,7 +74,7 @@ Vostede pode informar de fallos, propoñer melloras e solicitar funcionalidades na ferramenta de seguimento de incidencias do GitHub: %1$s Traducir Únase ao equipo Nextcloud en Transifex e axúdenos a traducir esta aplicación: %1$s - Licenza da apli + Licenza da aplicación Esta aplicación está licenciada baixo a LICENZA XERAL PUBLICA GNU v3+. Ver a licenza Iconas @@ -151,11 +151,11 @@ Caixa de selección Desbloquear notas Vaites, e agora que? 🙁 - Probe a forzar o peche da apli e reiniciala de novo. Pode haber unha conexión incorrecta coa apli Nextcloud. - Se o problema continúa, tente limpar o almacenamento de ambas as aplis: Nextcloud e Nextcloud Notas para resolver este problema. - Pode limpar o almacenamento abrindo a información da apli e seleccionando Almacenamento → Limpar o almacenamento.⚠️ Advertencia: Isto eliminará as notas que aínda non estean sincronizadas. - A súa apli Nextcloud semella estar desactualizada. Visite Play Store ou F-Droid para obter a última versión. - Semella que algo foi mal na súa apli Nextcloud. Tente forzar a parar ambas, a apli Nextcloud e a apli Nextcloud Notes. + Probe a forzar o peche da aplicación e reiniciala de novo. Pode haber unha conexión incorrecta coa aplicación Nextcloud. + Se o problema continúa, tente limpar o almacenamento de ambalas dúas aplicacións: Nextcloud e Nextcloud Notas para resolver este problema. + Pode limpar o almacenamento abrindo a información da aplicación e seleccionando Almacenamento → Limpar o almacenamento.⚠️ Advertencia: Isto eliminará as notas que aínda non estean sincronizadas. + A súa aplicación Nextcloud semella estar desactualizada. Visite a Play Store ou F-Droid para obter a última versión. + Semella que algo foi mal na súa aplicación Nextcloud. Tente forzar a parar ámbalas dúas aplicacións, Nextcloud e Nextcloud Notes. Se detelos pola forza non axuda, pode tentar limpar o almacenamento de ambas as aplicacións. Non houbo resposta do seu servidor no tempo dado. Asegúrese de que a súa instancia funciona correctamente. Comprobe a súa conexión de rede. Ás veces apagar e volver acender os datos móbiles ou a wifi pode axudar. @@ -166,7 +166,7 @@ Necesitamos a seguinte información técnica para axudarlle: Asegúrese de ter instalada e activada a aplicación «Notas» no seu servidor. O seu servidor respondeu cun código de estado HTTP 302, o que implica que non ten instalada a aplicación Notas no servidor ou que algo está mal configurado. Isto pode ser causado por substitucións personalizadas nun ficheiro .htaccess ou por aplicacións Nextcloud como Client OID. - Desactive todas as optimizacións de batería para Nextcloud e a apli Notas. + Desactive todas as optimizacións de batería para Nextcloud e a aplicación Notas. A aplicación de Notas para Android require que a aplicación de Android Nextcloud teña como mínimo a versión 3.18. Engadido «%1$s» O texto compartido estaba baleiro @@ -271,7 +271,7 @@ Ordenar por data de modificación Ordenar alfabéticamente Axustes da batería - Abrir a info da apli + Abrir a info da aplicación Axustes da rede Actualizar Aínda non hai ningunha conta configurada -- GitLab From f32df040694db78530c603a282a6c20fd29a637b Mon Sep 17 00:00:00 2001 From: Nextcloud bot Date: Wed, 12 Jul 2023 02:32:13 +0000 Subject: [PATCH 144/163] Fix(l10n): Update translations from Transifex Signed-off-by: Nextcloud bot --- app/src/main/res/values-zh-rCN/strings.xml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 8ecf4c17f..6c4be0b8f 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -41,6 +41,7 @@ 上月 笔记的显示模式 + 笔记打开行为 主题 等宽字体 字体大小 @@ -63,6 +64,7 @@ 您正使用 %1$s 维护者 开发者 + 原作者 翻译人员 %1$s 上的 Nextcloud 社区 测试人员 @@ -178,6 +180,9 @@ 格式 + 普通编辑模式 + 普通预览模式 + 富文本编辑模式 记住我上一次的选择 @@ -294,5 +299,7 @@ 导入笔记中… 正导入 %2$d 中的笔记 %1$d … 账号已导入 + 加载富文本编辑时出错 + 切换到普通编辑模式 返回 -- GitLab From d0e4bcdaee7578f8939023adce01cdc71c593778 Mon Sep 17 00:00:00 2001 From: Nextcloud bot Date: Thu, 13 Jul 2023 02:44:32 +0000 Subject: [PATCH 145/163] Fix(l10n): Update translations from Transifex Signed-off-by: Nextcloud bot --- app/src/main/res/values-gl/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/values-gl/strings.xml b/app/src/main/res/values-gl/strings.xml index 808e3324c..3dd48862a 100644 --- a/app/src/main/res/values-gl/strings.xml +++ b/app/src/main/res/values-gl/strings.xml @@ -71,7 +71,7 @@ Código fonte Este proxecto está aloxado en GitHub: %1$s Incidencias - Vostede pode informar de fallos, propoñer melloras e solicitar funcionalidades na ferramenta de seguimento de incidencias do GitHub: %1$s + Vde. pode informar de fallos, propoñer melloras e solicitar funcionalidades na ferramenta de seguimento de incidencias do GitHub: %1$s Traducir Únase ao equipo Nextcloud en Transifex e axúdenos a traducir esta aplicación: %1$s Licenza da aplicación -- GitLab From 8154b49533ae603391fa02e17a3ede4f708affd0 Mon Sep 17 00:00:00 2001 From: Nextcloud bot Date: Sat, 15 Jul 2023 02:38:00 +0000 Subject: [PATCH 146/163] Fix(l10n): Update translations from Transifex Signed-off-by: Nextcloud bot --- app/src/main/res/values-gl/strings.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/res/values-gl/strings.xml b/app/src/main/res/values-gl/strings.xml index 3dd48862a..957d61ba4 100644 --- a/app/src/main/res/values-gl/strings.xml +++ b/app/src/main/res/values-gl/strings.xml @@ -155,11 +155,11 @@ Se o problema continúa, tente limpar o almacenamento de ambalas dúas aplicacións: Nextcloud e Nextcloud Notas para resolver este problema. Pode limpar o almacenamento abrindo a información da aplicación e seleccionando Almacenamento → Limpar o almacenamento.⚠️ Advertencia: Isto eliminará as notas que aínda non estean sincronizadas. A súa aplicación Nextcloud semella estar desactualizada. Visite a Play Store ou F-Droid para obter a última versión. - Semella que algo foi mal na súa aplicación Nextcloud. Tente forzar a parar ámbalas dúas aplicacións, Nextcloud e Nextcloud Notes. + Semella que algo foi mal na súa aplicación Nextcloud. Tente forzar a parar ámbalas dúas aplicacións, Nextcloud e Nextcloud Notas. Se detelos pola forza non axuda, pode tentar limpar o almacenamento de ambas as aplicacións. Non houbo resposta do seu servidor no tempo dado. Asegúrese de que a súa instancia funciona correctamente. Comprobe a súa conexión de rede. Ás veces apagar e volver acender os datos móbiles ou a wifi pode axudar. - A resposta do servidor non foi correcta. Comprobe se pode acceder a Notas a través de interface web. + A resposta do servidor non foi correcta. Comprobe se pode acceder a Notas a través da interface web. Hai un problema coa configuración de Nextcloud. Bótelle un ollo aos ficheiros de rexistro do servidor. Comprobe que a súa instancia Nextcloud non se atope en modo de mantemento. A súa instancia Nextcloud non dispón de espazo de almacenamento libre. Elimine algúns ficheiros para sincronizar os seus cambios locais na súa nube. @@ -167,7 +167,7 @@ Asegúrese de ter instalada e activada a aplicación «Notas» no seu servidor. O seu servidor respondeu cun código de estado HTTP 302, o que implica que non ten instalada a aplicación Notas no servidor ou que algo está mal configurado. Isto pode ser causado por substitucións personalizadas nun ficheiro .htaccess ou por aplicacións Nextcloud como Client OID. Desactive todas as optimizacións de batería para Nextcloud e a aplicación Notas. - A aplicación de Notas para Android require que a aplicación de Android Nextcloud teña como mínimo a versión 3.18. + A aplicación de Notas para Android necesita que a aplicación de Android Nextcloud teña como mínimo a versión 3.18. Engadido «%1$s» O texto compartido estaba baleiro Anexo á nota -- GitLab From 207c65a03bb61ac506c9f37a727073e16f05804c Mon Sep 17 00:00:00 2001 From: Nextcloud bot Date: Wed, 19 Jul 2023 02:39:53 +0000 Subject: [PATCH 147/163] Fix(l10n): Update translations from Transifex Signed-off-by: Nextcloud bot --- app/src/main/res/values-es-rEC/strings.xml | 315 +++++++++++++++++++++ 1 file changed, 315 insertions(+) create mode 100644 app/src/main/res/values-es-rEC/strings.xml diff --git a/app/src/main/res/values-es-rEC/strings.xml b/app/src/main/res/values-es-rEC/strings.xml new file mode 100644 index 000000000..3464d81c2 --- /dev/null +++ b/app/src/main/res/values-es-rEC/strings.xml @@ -0,0 +1,315 @@ + + + + Notas + Nextcloud Notes + Todas las notas + Favoritos + Nota nueva + Bienvenido a %1$s + Configuraciones + Notas borradas + Buscar + Método de ordenación + Cancelar + Cambiar + Editar + Eliminar + Guardar + Acerca de + Liga + %1$s eliminado + %1$s restaurado + Deshacer + Sin categoría + Borrar + Categoría + Favorito + Vista previa + Compartir + + Buscar en %1$s + Buscar todas las notas + + Elige una categoría + + Hoy + Ayer + Esta semana + La semana pasada + Este mes + El mes pasado + + Modo de visualización de las notas + Comportamiento de apertura de las notas + Tema + Fuente monoespaciada + Tamaño de fuente + Sincronizar solo con Wi-Fi + Bloqueo de la aplicación (Beta) + Credenciales del dispositivo + Sincronización en segundo plano + Evitar la captura de pantalla + Vista de cuadrícula + Mantener la pantalla encendida + Cuando se visualiza o edita una nota + + Falló la sincronización: %1$s + Error de sincronización + No hay conexión de red + El servidor está en modo de mantenimiento + Ha ocurrido un error desconocido. + + Versión + Actualmente estás usando %1$s + Equipo de mantenimiento + Desarrolladores + autor original + Traductores + Comunidad de Nextcloud en %1$s + Equipo de pruebas + Código fuente + Este proyecto está alojado en GitHub: %1$s + Temas + Puedes informar errores, propuestas de mejora y solicitudes de funciones en el rastreador de problemas de GitHub: %1$s + Traducir + Únete al equipo de Nextcloud en Transifex y ayúdanos a traducir esta aplicación: %1$s + Licencia de la aplicación + Esta aplicación está licenciada bajo la LICENCIA GENERAL PUBLICA GNU v3+ + Ver licencia + Íconos + Para el ícono original, consulta %1$s. + Todos los demás íconos utilizados por esta aplicación son %1$s creados por Google Inc. y con licencia Apache 2.0. + Material Design Icons + Créditos + Contribución + Licencia + + Lista de notas + No hay notas + Única nota + Nota no encontrada + Por favor inica sesión en Notes antes de usar este widget + El icono de estrella se utiliza para indicar un elemento como favorito + + Seleccionar nota + + Crear una nota nueva + + Normal + Sincronizar con Wi-Fi y datos móviles + Protección con contraseña + + Error + Cerrar + Copiar + Excepción + Anclar a la pantalla de inicio + Esta nota ha sido eliminada + Agregar cuenta + + Música + Películas + Película + Trabajo + Pendiente + Pendientes + Listas de verificación + Tareas + Receta + Recetas + Restaurante + Restaurantes + Comida + Hornear + + Llave + + Llaves + Contraseña + Contraseñas + Credencial + Juego + Juegos + + Reproducir + Regalo + Regalos + + Presente + + Regalos + + La cuenta ya ha sido importada + Aún no hay notas + Pulsa el botón + para crear una nueva nota + Más + Mover + Sólo lectura + Sin categoría + Agregar %1$s + Casilla de verificación + Desbloquear notas + ¡Oh no! ¿Y ahora? 🙁 + Por favor, intenta cerrar forzosamente la aplicación y reiniciarla nuevamente. Puede haber habido una conexión incorrecta con la aplicación Nextcloud. + Si el problema persiste, intenta borrar el almacenamiento de ambas aplicaciones: Nextcloud y Nextcloud Notes para solucionar este problema. + Puedes borrar el almacenamiento abriendo la información de la aplicación y seleccionando Almacenamiento → Borrar almacenamiento. ⚠️ Advertencia: ¡Esto eliminará las notas aún no sincronizadas! + Tu aplicación de Nextcloud parece estar desactualizada. Visita Play Store o F-Droid para obtener la última versión. + Algo parece estar mal con tu aplicación de Nextcloud. Intenta detener forzosamente tanto la aplicación de Nextcloud como la aplicación de Nextcloud Notes. + Si detenerlas forzosamente no ayuda, puedes intentar borrar el almacenamiento de ambas aplicaciones. + No hubo respuesta de tu servidor en el tiempo indicado. Asegúrate de que tu instancia esté funcionando correctamente. + Verifica tu conexión de red. A veces, activar y desactivar los datos móviles o Wi-Fi puede ayudar. + La respuesta de tu servidor no fue correcta. Verifica si puedes acceder a tus notas a través de la interfaz web. + Hay un problema con tu configuración de Nextcloud. Por favor, revisa los archivos de registro del servidor. + Por favor, verifica si tu instancia de Nextcloud no está actualmente en modo de mantenimiento. + Tu instancia de Nextcloud no tiene espacio de almacenamiento libre. Por favor, elimina algunos archivos para sincronizar tus cambios locales en tu nube. + Necesitamos la siguiente información técnica para ayudarte: + Asegúrate de haber instalado y habilitado la aplicación \"Notes\" en tu servidor. + Tu servidor respondió con un código de estado HTTP 302, lo que implica que no tienes instalada la aplicación Notes en tu servidor o algo está mal configurado. Esto puede ser causado por anulaciones personalizadas en un archivo .htaccess o por aplicaciones de Nextcloud como OID Client. + Desactiva todas las optimizaciones de batería para Nextcloud y la aplicación de Notas. + La aplicación Notas de Android requiere que la aplicación de Nextcloud para Android sea al menos la versión 3.18. + Añadido \"%1$s\" + El texto compartido estaba vacío + Anexar a la nota + Cambiar el título de la nota + Editar título + Seguridad + Apariencia y comportamiento + Sincronización + Administrar cuentas + Formato + + + Modo de edición simple + Vista previa simple + Modo de edición enriquecida + Recordar mi última selección + + + Pequeño + Medio + Grande + + + + Claro + Oscuro + Configuración predeterminada del sistema + + + + %d seleccionado + %d seleccionados + %d seleccionados + + + Eliminada una nota + Eliminadas %1$d notas + Eliminadas %1$d notas + + + Restaurada una nota + Restauradas %1$d notas + Restauradas %1$d notas + + + Compartir contenido de %1$d nota + Compartir contenido de %1$d notas + Compartir contenido de %1$d notas + + + --- + `%1$s` + \\`%1$s\\` + ``` + ```` + ```javascript + Formato contextual basado en el contexto + Uno de los principales objetivos de diseño de la aplicación Notes es proporcionar una herramienta libre de distracciones. Aunque podrás dar formato a tus textos con Markdown. Para varios de los ejemplos mencionados a continuación, puedes utilizar atajos para dar formato a tus notas sin escribir los códigos a continuación. + Solo selecciona un rango de texto o toca tu cursor en cualquier posición y aparecerá un menú emergente que contiene, además de las entradas predeterminadas %1$s, %2$s, %3$s, entradas como %4$s o %5$s. + + Texto + Es muy fácil hacer que algunas palabras estén %1$s negrita%1$s y otras palabras %2$s cursiva%2$s con Markdown. Puedes %3$stachar%3$s algunas palabras e incluso [enlazar a Nextcloud](https://nextcloud.com). + + Listas + A veces, quieres listas numeradas: + Uno + Dos + Tres + A veces, quieres puntos: + Empieza una línea con un guión + Y si tienes puntos secundarios, coloca dos espacios antes del guión o del asterisco: + Así + Y esto + + Casillas de verificación + Para crear una casilla de verificación, utiliza una lista seguida de corchetes + Elemento 1 + Elemento 2 + + Documentos estructurados + A veces es útil tener diferentes niveles de encabezados para estructurar tus documentos. Comienza las líneas con un %1$s para crear encabezados. Múltiples %2$s seguidos indican tamaños de encabezado más pequeños. + Este es un encabezado de tercer nivel + Puedes utilizar un %1$s desde uno hasta %2$s seis para diferentes tamaños de encabezado. + Si deseas citar a alguien, utiliza el carácter %1$s antes de la línea: + La imaginación es más importante que el conocimiento. El conocimiento está limitado. La imaginación rodea el mundo. + - Albert Einstein + + Código + Hay muchas formas diferentes de estilizar el código con Markdown. Si tienes bloques de código en línea, colócalos entre comillas invertidas: + Markdown también admite algo llamado cercas de código, que permite múltiples líneas sin sangría: + Y si deseas utilizar resaltado de sintaxis, incluye el lenguaje: + + Tablas + + Columna %1d + + Valor %1d + + Los enlaces deben ser URL completas que comiencen con un protocolo y un dominio o rutas absolutas que comiencen con un carácter %1$s. + Para cumplir con el formato Markdown, utiliza caracteres de escape en la URL de la imagen. Esto significa, por ejemplo, reemplazar los espacios con %1$s en la URL. + Imágenes + Imagen sofisticada + + Otro + Ordenar por fecha de modificación + Ordenar por orden alfabético + Configuración de la batería + Abrir información de la aplicación + Configuración de red + Actualizar + Aún no se ha configurado ninguna cuenta + Aún no has configurado ninguna otra cuenta. + Elige la cuenta + Popover de formato contextual + + Eliminar la cuenta %1$s también eliminará un cambio no sincronizado irrecuperable. + Eliminar la cuenta %1$s también eliminará %2$d cambios no sincronizados irrecuperables. + Eliminar la cuenta %1$s también eliminará %2$d cambios no sincronizados irrecuperables. + + Eliminar %1$s + + Debes estar conectado a Internet para agregar una cuenta. + Establecer carpeta + + Siguiente + Previo + Copia de seguridad + Detectamos un estado irreparable de la aplicación. Realiza una copia de seguridad de los cambios no sincronizados y borra el almacenamiento de la aplicación Notes. + Carpeta para almacenar tus notas en tu Nextcloud + + .txt + .md + + Nueva carpeta de notas: %1$s + Extensión de archivo + Extensión de archivo para nuevas notas en tu Nextcloud + Nuevo sufijo de archivo: %1$s + Código de estado HTTP: %1$d + Importando notas... + Importando nota %1$d de %2$d... + Cuenta importada. + Error al cargar la edición enriquecida + Cambiar a edición simple + Atrás + -- GitLab From e3662fb52b6978464885f38b541e71b9fc2f06eb Mon Sep 17 00:00:00 2001 From: Nextcloud bot Date: Thu, 20 Jul 2023 02:40:04 +0000 Subject: [PATCH 148/163] Fix(l10n): Update translations from Transifex Signed-off-by: Nextcloud bot --- app/src/main/res/values-gl/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/values-gl/strings.xml b/app/src/main/res/values-gl/strings.xml index 957d61ba4..03c7d0e8c 100644 --- a/app/src/main/res/values-gl/strings.xml +++ b/app/src/main/res/values-gl/strings.xml @@ -167,7 +167,7 @@ Asegúrese de ter instalada e activada a aplicación «Notas» no seu servidor. O seu servidor respondeu cun código de estado HTTP 302, o que implica que non ten instalada a aplicación Notas no servidor ou que algo está mal configurado. Isto pode ser causado por substitucións personalizadas nun ficheiro .htaccess ou por aplicacións Nextcloud como Client OID. Desactive todas as optimizacións de batería para Nextcloud e a aplicación Notas. - A aplicación de Notas para Android necesita que a aplicación de Android Nextcloud teña como mínimo a versión 3.18. + A aplicación de Notas para Android precisa que a aplicación de Android Nextcloud teña como mínimo a versión 3.18. Engadido «%1$s» O texto compartido estaba baleiro Anexo á nota -- GitLab From f4e6703ab2875add14892e1747d59a2e72e9e002 Mon Sep 17 00:00:00 2001 From: Nextcloud bot Date: Wed, 26 Jul 2023 03:14:28 +0000 Subject: [PATCH 149/163] Fix(l10n): Update translations from Transifex Signed-off-by: Nextcloud bot --- app/src/main/res/values-gl/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/values-gl/strings.xml b/app/src/main/res/values-gl/strings.xml index 03c7d0e8c..1d68795ff 100644 --- a/app/src/main/res/values-gl/strings.xml +++ b/app/src/main/res/values-gl/strings.xml @@ -31,7 +31,7 @@ Buscar en %1$s Buscar todas as notas - Escolla unha categoría + Escoller unha categoría Hoxe Onte @@ -276,7 +276,7 @@ Actualizar Aínda non hai ningunha conta configurada Aínda non ten configurada ningunha outra conta. - Escolla unha conta + Escoller unha conta Xanela emerxente de formato baseado no contexto Retirar a conta %1$s tamén eliminará de xeito irrecuperábel un cambio non sincronizado. -- GitLab From 0775411e8e941a57ea32f2d471c1cd4437a5fe2a Mon Sep 17 00:00:00 2001 From: Nextcloud bot Date: Thu, 27 Jul 2023 02:36:00 +0000 Subject: [PATCH 150/163] Fix(l10n): Update translations from Transifex Signed-off-by: Nextcloud bot --- app/src/main/res/values-eu/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/values-eu/strings.xml b/app/src/main/res/values-eu/strings.xml index 91cd82385..ed57e86d3 100644 --- a/app/src/main/res/values-eu/strings.xml +++ b/app/src/main/res/values-eu/strings.xml @@ -29,7 +29,7 @@ Partekatu Bilatu %1$s(e)n - Bilatu nota guztiak + Bilatu ohar guztiak Hautatu kategoria bat -- GitLab From 0d7be6ccd75b3ed11e006457c30071d36bb98074 Mon Sep 17 00:00:00 2001 From: Nextcloud bot Date: Sun, 30 Jul 2023 02:38:30 +0000 Subject: [PATCH 151/163] Fix(l10n): Update translations from Transifex Signed-off-by: Nextcloud bot --- app/src/main/res/values-de/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index d55684fab..6d33c434b 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -222,7 +222,7 @@ ```javascript Kontextbasierte Formatierung Ein wichtiges Designziel der Notes-App ist die Bereitstellung eines ablenkungsfreien Werkzeugs. Sie können Ihre Texte mit Markdown formatieren. Für verschiedene der unten genannten Beispiele können Sie Verknüpfungen verwenden, um Ihre Notizen zu formatieren, ohne die folgenden Codes eingeben zu müssen. - Wählen Sie einfach einen Textbereich aus oder tippen Sie an einer beliebigen Stelle auf den Cursor und Sie erhalten ein Popup-Menü, das neben den Standardeinträgen %1$s, %2$s, %3$s auch Einträge wie %4$s oder %5$s enthält. + Wählen Sie einfach einen Textbereich aus oder tippen Sie an einer beliebigen Stelle auf den Cursor und Sie erhalten ein Pop-up-Menü, das neben den Standardeinträgen %1$s, %2$s, %3$s auch Einträge wie %4$s oder %5$s enthält. Text Es ist sehr einfach, einige Wörter %1$sfett%1$s und andere Wörter %2$skursiv%2$s mit Markdown zu versehen. Sie können einige Wörter %3$sdurchstreichen%3$s und sogar zu Nextcloud [verlinken](https://nextcloud.com). @@ -277,7 +277,7 @@ Bislang kein Konto eingerichtet Sie haben bislang keine weiteren Konten eingerichtet. Konto auswählen - Popup für die kontextbasierte Formatierung + Pop-up für die kontextbasierte Formatierung Beim Entfernen des Kontos %1$s wird auch eine unsynchronisierte Änderung unwiderruflich gelöscht werden. Beim Entfernen des Kontos %1$s werden auch %2$d unsynchronisierte Änderungen unwiderruflich gelöscht werden. -- GitLab From ddc26cbc20d8ad35b58a538a512605b09d6821e9 Mon Sep 17 00:00:00 2001 From: Nextcloud bot Date: Sun, 6 Aug 2023 02:41:49 +0000 Subject: [PATCH 152/163] Fix(l10n): Update translations from Transifex Signed-off-by: Nextcloud bot --- app/src/main/res/values-gl/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/values-gl/strings.xml b/app/src/main/res/values-gl/strings.xml index 1d68795ff..16667631b 100644 --- a/app/src/main/res/values-gl/strings.xml +++ b/app/src/main/res/values-gl/strings.xml @@ -290,7 +290,7 @@ Seguinte Anterior Copia de seguranza - Detectamos un estado irrecuperábel da aplicación. Faga unha copia de seguranza dos cambios non sincronizados e limpe o almacenamento da apli de Notas. + Detectamos un estado irrecuperábel da aplicación. Faga unha copia de seguranza dos cambios non sincronizados e limpe o almacenamento da aplicación Notas. Cartafol para almacenar as súas notas no seu Nextcloud .txt -- GitLab From 9f5b9cce26b9a23b4b8be9dc1449d3659a1fd73d Mon Sep 17 00:00:00 2001 From: Nextcloud bot Date: Wed, 9 Aug 2023 03:08:43 +0000 Subject: [PATCH 153/163] Fix(l10n): Update translations from Transifex Signed-off-by: Nextcloud bot --- app/src/main/res/values-nb-rNO/strings.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/src/main/res/values-nb-rNO/strings.xml b/app/src/main/res/values-nb-rNO/strings.xml index db0a02c52..43555cd4e 100644 --- a/app/src/main/res/values-nb-rNO/strings.xml +++ b/app/src/main/res/values-nb-rNO/strings.xml @@ -41,6 +41,7 @@ Forrige måned Visningsmodus for notater + Åpningsoppførsel fra Notes Tema Monospace font Skriftstørrelse @@ -179,6 +180,9 @@ Formatering + Ren endringsmodus + Ren forhåndsvisning + Rik endringsmodus Husk mitt siste valg @@ -300,5 +304,7 @@ Importerer notater… Importerer notat %1$d av %2$d… Konto importert. + Feil ved lasting av rik endringsmodus + Bytt til ren endringsmodus Tilbake -- GitLab From 014ad5035f14e6329f7addb9c996c8681e780ac5 Mon Sep 17 00:00:00 2001 From: Nextcloud bot Date: Sat, 12 Aug 2023 02:46:39 +0000 Subject: [PATCH 154/163] Fix(l10n): Update translations from Transifex Signed-off-by: Nextcloud bot --- app/src/main/res/values-fa/strings.xml | 84 ++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) diff --git a/app/src/main/res/values-fa/strings.xml b/app/src/main/res/values-fa/strings.xml index c4ea3de43..b160e67ff 100644 --- a/app/src/main/res/values-fa/strings.xml +++ b/app/src/main/res/values-fa/strings.xml @@ -41,13 +41,19 @@ ماه گذشته حالت نمایش یادداشت‌ها + Notes opening behaviour "تم " قلم Monospace اندازهٔ قلم همگام‌سازی فقط در Wi-Fi + App lock (Beta) اعتبارنامه‌های دستگاه همگام‌سازی پس زمینه + Prevent screen capture نمایش گرید + Keep screen on + When viewing or editing a note + همگام‌سازی انجام نشد:%1$s همگام‌سازی انجام نشد هیچ ارتباطی با شبکه برقرار نیست @@ -58,6 +64,7 @@ شما در حال استفاده %1$s هستید نگاه‌دارنده توسعه دهندگان + original author مترجم انجمن نکست کلود در %1$s آزمایش کنندگان @@ -83,6 +90,8 @@ یادداشت واحد یادداشت یافت نشد لطفاً قبل از استفاده از این ویجت، به یادداشت‌ها وارد شوید + Star icon is used to denote an item as a favorite + انتخاب یادداشت ساختن یادداشت جدید @@ -103,16 +112,34 @@ فیلم‌ها فیلم کار + ToDo + ToDos + Checklists وظایف + Recipe + Recipes رستوران + Restaurants + Food + Bake + + Key + + Keys کلمه عبور کلمات عبور + Credential بازی بازی ها پخش کردن + Gift + Gifts حاضر + + Presents + حساب قبلاً وارد شده است هنوز هیچ یادداشتی وجود ندارد دکمه + را فشار دهید تا یک یادداشت جدید ایجاد کنید @@ -126,6 +153,7 @@ وای نه - حالا چی کار کنیم؟ لطفا از طریق توقف اجباری برنامه را بسته و دوباره اجرا کنید. ممکن است یک اتصال نادرست با نکست‌کلود ایجاد شده باشد. اگر این مشکل استمرار داشت، سعی کنید با پاک کردن فضای ذخیره‌سازی هردو برنامک : Nextcloud و Nextcloud Notes این مورد را برطرف کنید. + You can clear the storage by opening the app info and selecting Storage → Clear storage. ⚠️ Warning: This will delete not yet synchronized notes! ظاهرا برنامک یادداشت منسوخ شده است. لطفا آخرین نسخه را از Play Store یا F-Droid دانلود کنید. به نظر می‌رسد که مشکلی در برنامک نکست‌کلود ایجاد شده است. لطفا سعی کنید با توقف اجباری هر دو برنامک Nextcloud app و Nextcloud Notes را ببندید. "اگر توقف اجباری برنامه‌ها کمکی نکرد، می‌توانید پاک‌کردن فضای ذخیره‌سازی هردو برنامه را پاک کنید. " @@ -139,17 +167,22 @@ لطفا از نصب و فعال بودن برنامک یادداشت بر روی سرور، اطمینان حاصل کنید. پاسخ سرور شما کد حالت HTTP 302 است. که دلالت بر عدم نصب برنامک یادداشت بر روی سرور و یا پیکربندی نامناسب دارد. این مشکل می‌تواند به دلیل تغییرات نامناسب ایجاد شده در فایل .htaccess و یا به دلیل برنامه‌های مرتبط با Nextcloud مثل OID Client رخ دهد. لطفا تمامی فرایند‌های بهینه‌سازی مصرف باتری برای Nextcloud و Notes app را غیر فعال کنید. + The Notes Android app requires the Nextcloud Android app to be at least version 3.18. اضافه ‌شده %1$s متن به اشتراک گذاشته‌شده خالی است به یادداشت اضافه کنید عوض‌کردن عنوان یادداشت ویرایش عنوان امنیت + Appearance and behavior همگام‌سازی مدیریت حساب‌ها قالب‌بندی + Plain edit mode + Plain preview + Rich edit mode آخرین انتخاب من را به خاطر بسپار @@ -168,6 +201,25 @@ %d انتخاب شد %d انتخاب شد + + Deleted one note + Deleted %1$d notes + + + Restored one note + Restored %1$d notes + + + Share content of %1$d note + Share content of %1$d notes + + + --- + `%1$s` + \\`%1$s\\` + ``` + ```` + ```javascript قالب‌بندی مبتنی بر متن هدف اصلی از طراحی برنامک یادداشت، ارائه دادن یک ابزار رایگان یادداشت کارها است. همچنین شما قادر خواهید بود متن‌ها را با Markdown قالب‌بندی کنید. برای انواع مختلفی از مثالهای ذکر شده در زیر ، می توانید از میانبرها استفاده کنید تا بتوانید یادداشت های خود را بدون تایپ کد، قالب بندی کنید. فقط کافی است یک دامنه متن را انتخاب کنید یا روی مکان نما در هر موقعیتی ضربه بزنید و یک منوی بازشونده دریافت می کنید که در کنار ورودی‌های پیش‌فرض %1$s و %2$s و %3$s شامل ورودی‌‌هایی مانند %4$s و %5$s می‌باشد. @@ -205,6 +257,13 @@ اگر شما نیاز به مشخص کردن syntax در یک زبان دارید: جدول‌ها + + Column %1d + + Value %1d + + Links have to be either complete URLs starting with a protocol and domain or absolute paths starting with a %1$s character. + In order to conform to the Markdown format, please use escape characters in the image URL. This means for example, replace spaces with %1$s in the URL. تصاویر تصویر فانتزی @@ -215,12 +274,37 @@ باز کردن اطلاعات برنامه تنظیمات شبکه یه‌روزرسانی + No account configured yet شما تاکنون هیچ حساب کاربری دیگری را ایجاد نکرده‌اید. حساب کاربری را انتخاب کنید بازپخش قالب بندی مبتنی بر متن + + Removing the account %1$s will also delete irrecoverable one unsynchronized change. + Removing the account %1$s will also delete irrecoverable %2$d unsynchronized changes. + + Remove %1$s + برای اضافه کردن حساب باید به اینترنت متصل شوید. + Set folder + بعدی قبلی پشتیبان‌گیری + We detected an irrecoverably state of the app. Please backup your unsynchronized changes and clear the storage of the Notes app. + Folder to store your notes in your Nextcloud + + .txt + .md + + New notes folder: %1$s + File extension + File extension for new notes in your Nextcloud + New file suffix: %1$s + HTTP status code: %1$d + Importing notes… + Importing note %1$d of %2$d… + Account imported. + Error while loading rich editing + Switch to plain editing بازگشت -- GitLab From c0240767a92325885065855231c60bea27319af1 Mon Sep 17 00:00:00 2001 From: Nextcloud bot Date: Fri, 25 Aug 2023 03:03:19 +0000 Subject: [PATCH 155/163] Fix(l10n): Update translations from Transifex Signed-off-by: Nextcloud bot --- app/src/main/res/values-uk/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index 055c70756..bf8a2d9b5 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -10,7 +10,7 @@ Налаштування Вилучені нотатки Пошук - Метод сортування + Спосіб впорядкування Скасувати Перемкнути Редагувати -- GitLab From 46a500690c458e07becd121f166cd01e86b1289c Mon Sep 17 00:00:00 2001 From: Nextcloud bot Date: Thu, 31 Aug 2023 02:55:11 +0000 Subject: [PATCH 156/163] Fix(l10n): Update translations from Transifex Signed-off-by: Nextcloud bot --- app/src/main/res/values-gl/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/values-gl/strings.xml b/app/src/main/res/values-gl/strings.xml index 16667631b..eff9f5e59 100644 --- a/app/src/main/res/values-gl/strings.xml +++ b/app/src/main/res/values-gl/strings.xml @@ -165,7 +165,7 @@ A súa instancia Nextcloud non dispón de espazo de almacenamento libre. Elimine algúns ficheiros para sincronizar os seus cambios locais na súa nube. Necesitamos a seguinte información técnica para axudarlle: Asegúrese de ter instalada e activada a aplicación «Notas» no seu servidor. - O seu servidor respondeu cun código de estado HTTP 302, o que implica que non ten instalada a aplicación Notas no servidor ou que algo está mal configurado. Isto pode ser causado por substitucións personalizadas nun ficheiro .htaccess ou por aplicacións Nextcloud como Client OID. + O seu servidor respondeu cun código de estado HTTP 302, o que implica que non ten instalada a aplicación Notas no servidor ou que algo está mal configurado. Isto pode ser causado por substitucións personalizadas nun ficheiro .htaccess ou por aplicacións Nextcloud como Cliente OID. Desactive todas as optimizacións de batería para Nextcloud e a aplicación Notas. A aplicación de Notas para Android precisa que a aplicación de Android Nextcloud teña como mínimo a versión 3.18. Engadido «%1$s» -- GitLab From 755e384127d7ac94b3f967c52918ce116e028ef0 Mon Sep 17 00:00:00 2001 From: Nextcloud bot Date: Mon, 4 Sep 2023 02:53:43 +0000 Subject: [PATCH 157/163] Fix(l10n): Update translations from Transifex Signed-off-by: Nextcloud bot --- app/src/main/res/values-gl/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/values-gl/strings.xml b/app/src/main/res/values-gl/strings.xml index eff9f5e59..b4102161f 100644 --- a/app/src/main/res/values-gl/strings.xml +++ b/app/src/main/res/values-gl/strings.xml @@ -50,7 +50,7 @@ Credenciais do dispositivo Sincronización do traballo en segundo plano Evitar a captura da pantalla - Ver como grella + Ver como grade Mantér a pantalla acesa Ao ver ou editar unha nota -- GitLab From 4cf451f4d1870514f1f4222917b890772ecefb4e Mon Sep 17 00:00:00 2001 From: Nextcloud bot Date: Tue, 5 Sep 2023 02:44:07 +0000 Subject: [PATCH 158/163] Fix(l10n): Update translations from Transifex Signed-off-by: Nextcloud bot --- app/src/main/res/values-el/strings.xml | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index ca7cbc845..8df521f36 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -49,6 +49,7 @@ Διαπιστευτήρια συσκευής Συγχρονισμός στο παρασκήνιο Προβολή πλέγματος + Διατήρηση της οθόνης ενεργή Αποτυχία συγχρονισμού: %1$s Αποτυχία συγχρονισμού Δεν υπάρχει σύνδεση στο δίκτυο @@ -59,6 +60,7 @@ Αυτή τη στιγμή χρησιμοποιείτε %1$s Συντηρητής Προγραμματιστές + αρχικός συγγραφέας Μεταφραστές Η κοινότητα του Nextcloud στο %1$s Δοκιμαστές @@ -112,13 +114,19 @@ Εστιατόριο Εστιατόρια Φαγητό + + Κλειδί + + Κλειδία Συνθηματικό Συνθηματικά + Διαπιστευτήρια Παιχνίδι Παιχνίδια Αναπαραγωγή Δώρο + Δώρα Παρόν Ο λογαριασμός έχει εισαχθεί ήδη @@ -253,9 +261,27 @@ Δεν έχετε ρυθμίσει ακόμη άλλους λογαριασμούς. Επιλογή λογαριασμού Μορφοποίηση βάσει περιεχομένου popover + + Η αφαίρεση του λογαριασμού %1$sθα διαγράψει μόνιμα μια μη συγχρονισμένη αλλαγή. + Η αφαίρεση του λογαριασμού %1$s θα διαγράψει μόνιμα %2$dμη συγχρονισμένες αλλαγές. + + Αφαίρεση%1$s + Πρέπει να είστε συνδεμένοι στο ιντερνετ για να προσθέσετε λογαριασμό. Επόμενο Προηγούμενο Αντίγραφο ασφαλείας + Φάκελος για την αποθήκευση σημειώσεων στο Nextcloud + + .txt + .md + + Φάκελος νέων σημειώσεων: %1$s + Προέκταση αρχείου + Εισαγωγή σημειώσεων... + Γίνεται εισαγωγή της σημείωσης %1$d από %2$d... + Έγινε εισαγωγή του Λογαριασμού + Σφάλμα κατά την φόρτωση της πλούσιας επεξεργασίας + Αλλαγή σε απλή επεξεργασία Πίσω -- GitLab From 6ce3effde73f9f520f2154ff45a62fef5313d6cf Mon Sep 17 00:00:00 2001 From: Nextcloud bot Date: Fri, 15 Sep 2023 02:45:23 +0000 Subject: [PATCH 159/163] Fix(l10n): Update translations from Transifex Signed-off-by: Nextcloud bot --- app/src/main/res/values-da/strings.xml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/values-da/strings.xml b/app/src/main/res/values-da/strings.xml index 60369970f..12ef139d3 100644 --- a/app/src/main/res/values-da/strings.xml +++ b/app/src/main/res/values-da/strings.xml @@ -63,6 +63,7 @@ Du bruger lige nu %1$s Maintainer Udviklere + original forfatter Oversættere Nextcloud fællesskabet på %1$s Testere @@ -71,7 +72,7 @@ Problemer Du kan rapportere fejl, foreslå forbedringer og ønske nye funktioner på Github: %1$s Oversæt - Bliv en dal af Nextcloudholdet på Transifex, og hjælp os med at oversætte denne app: %1$s + Bliv en del af Nextcloudholdet på Transifex, og hjælp os med at oversætte denne app: %1$s App licens Denne applikation er licenseret under GNU GENERAL PUBLIC LICENSE v3+. Vis licens @@ -191,6 +192,7 @@ --- `%1$s` + ```javascript Kontekstbaseret formatering Tekst Lister @@ -222,8 +224,14 @@ Næste Tidligere Backup + Mappe for dine noter i Nextcloud + + .txt + .md + Mappe for nye noter: %1$s Fil-endelse Fil-endelse for nye noter i Nextcloud + Importerer noter... Tilbage -- GitLab From fe59c5aa7cf47e20276549153eb7a0a8299b8298 Mon Sep 17 00:00:00 2001 From: tobiasKaminsky Date: Tue, 27 Jun 2023 10:53:18 +0200 Subject: [PATCH 160/163] Bump to 4.1.0 final Signed-off-by: tobiasKaminsky --- app/build.gradle | 4 ++-- fastlane/metadata/android/en-US/changelogs/40010090.txt | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) create mode 100644 fastlane/metadata/android/en-US/changelogs/40010090.txt diff --git a/app/build.gradle b/app/build.gradle index efbab6461..507283988 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -14,8 +14,8 @@ android { applicationId "it.niedermann.owncloud.notes" minSdkVersion 24 targetSdkVersion 33 - versionCode 40010051 - versionName "4.1.0 RC1" + versionCode 40010090 + versionName "4.1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" javaCompileOptions { annotationProcessorOptions { diff --git a/fastlane/metadata/android/en-US/changelogs/40010090.txt b/fastlane/metadata/android/en-US/changelogs/40010090.txt new file mode 100644 index 000000000..9ddbd5488 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/40010090.txt @@ -0,0 +1,3 @@ +- theming improvements +- min Server NC24 +- dependency updates -- GitLab From 05a477af3ae928306d964d20b39268711bd8453e Mon Sep 17 00:00:00 2001 From: tobiasKaminsky Date: Mon, 18 Sep 2023 20:25:46 +0200 Subject: [PATCH 161/163] Backport fix Signed-off-by: tobiasKaminsky --- app/build.gradle | 2 +- build.gradle | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 507283988..021cb7c70 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -76,7 +76,7 @@ dependencies { coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.3' // Nextcloud SSO - implementation 'com.github.nextcloud.android-common:ui:0.10.0' + implementation 'com.github.nextcloud.android-common:ui:0.12.0' implementation 'com.github.nextcloud:Android-SingleSignOn:0.7.0' implementation 'com.github.stefan-niedermann:android-commons:0.2.9' implementation "com.github.stefan-niedermann.nextcloud-commons:sso-glide:$commonsVersion" diff --git a/build.gradle b/build.gradle index 1ccfb64c8..bca30b59e 100644 --- a/build.gradle +++ b/build.gradle @@ -3,7 +3,7 @@ buildscript { ext { kotlinVersion = '1.8.21' - commonsVersion = '1.7.0' + commonsVersion = '1.8.2' } repositories { mavenCentral() -- GitLab From e1f3cc396d8f10e1541c0e76c8a6e6ec3225a764 Mon Sep 17 00:00:00 2001 From: Nextcloud bot Date: Tue, 19 Sep 2023 02:43:09 +0000 Subject: [PATCH 162/163] Fix(l10n): Update translations from Transifex Signed-off-by: Nextcloud bot --- app/src/main/res/values-es/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 2cce5af8f..4fd067674 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -165,7 +165,7 @@ Su instancia de Nextcloud no tiene espacio libre de almacenamiento. Por favor elimine algunos archivos para sincronizar sus cambios locales con su nube. Necesitamos la siguiente información técnica para ayudarle: Por favor, asegúrate de que has instalado y activado la app «Notas» en tu servidor. - Tu servidor respondió con el código de estado HTTP 302, lo que implica que no está instalada la aplicación Notas en su servidor o que algo está mal configurado. Esto puede estar causado por anulaciones personalizadas en un archivo .htaccess o por aplicaciones de Nextcloud como OID Client. + Su servidor respondió con el código de estado HTTP 302, lo que implica que no está instalada la aplicación Notas en su servidor o que algo está mal configurado. Esto puede estar causado por anulaciones personalizadas en un archivo .htaccess o por aplicaciones de Nextcloud como OID Client. Por favor, desactiva todas las optimizaciones de la batería para Nextcloud y la app de Notas. La aplicación de Notas de Android requiere que la la aplicación Nextcloud de Android sea al menos la versión 3.18. Se ha añadido «%1$s» -- GitLab From 052e5e77378a2b2e2c1ff9a9583bf3d3ec146967 Mon Sep 17 00:00:00 2001 From: Fahim Salam Chowdhury Date: Fri, 29 Dec 2023 13:09:34 +0600 Subject: [PATCH 163/163] update CI to re-enable autoupdate --- .gitlab-ci.yml | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index bfbbba567..3f61ce459 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -50,21 +50,16 @@ build: - git config --global http.sslverify false # update $UPSTREAM_BRANCH & tags - git fetch origin - - git checkout $UPSTREAM_BRANCH - git remote add upstream $UPSTREAM_URL - git fetch upstream - - git pull upstream $UPSTREAM_DEFAULT_BRANCH - - git push origin $UPSTREAM_BRANCH - - git push origin --tags # checkout to latest tag commit to $TEMP_LATEST_TAG_BRANCH - - git checkout $(git describe --tags --abbrev=0) + - git checkout $(git ls-remote --tags upstream | grep -o 'refs/tags/[0-9]*\.[0-9]*\.[0-9]*' | sort -r | head -n 1 | grep -o '[^\/]*$') - git checkout -b $TEMP_LATEST_TAG_BRANCH # merge $LOCAL_BRANCH with $TEMP_LATEST_TAG_BRANCH & push - git checkout $LOCAL_BRANCH - - git submodule sync - - git submodule update --init --recursive --force - git merge $TEMP_LATEST_TAG_BRANCH - git push origin $LOCAL_BRANCH + - git push origin --tags # remove unwanted local branch & remote - git branch -D $TEMP_LATEST_TAG_BRANCH - git remote remove upstream @@ -74,7 +69,5 @@ update-default-branch: extends: .update-from-upstream variables: LOCAL_BRANCH: main - UPSTREAM_BRANCH: upstream/master - UPSTREAM_DEFAULT_BRANCH: main UPSTREAM_URL: https://github.com/nextcloud/notes-android.git TEMP_LATEST_TAG_BRANCH: latest_upstream_tag_branch \ No newline at end of file -- GitLab