From 09c400e5ecef470575f98fcfde330ef5d3785a70 Mon Sep 17 00:00:00 2001 From: alperozturk Date: Mon, 7 Jul 2025 16:29:50 +0200 Subject: [PATCH 1/7] add update note call Signed-off-by: alperozturk --- .../owncloud/notes/edit/BaseNoteFragment.java | 2 +- .../owncloud/notes/main/MainActivity.java | 2 +- .../owncloud/notes/main/MainViewModel.java | 11 ++++----- .../list/NotesListViewItemTouchHelper.java | 2 +- .../notes/persistence/NotesRepository.java | 23 ++++++++++++++++--- .../notes/persistence/sync/NotesAPI.java | 17 ++++++++++++++ .../notes/persistence/sync/NotesAPI_0_2.java | 4 ++++ .../notes/persistence/sync/NotesAPI_1_0.java | 4 ++++ 8 files changed, 53 insertions(+), 12 deletions(-) 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 54f23cf50..01acdda3c 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 @@ -248,7 +248,7 @@ public boolean onOptionsItemSelected(MenuItem item) { return true; } else if (itemId == R.id.menu_favorite) { note.setFavorite(!note.getFavorite()); - repo.toggleFavoriteAndSync(localAccount, note.getId()); + repo.toggleFavoriteAndSync(localAccount, note); listener.onNoteUpdated(note); prepareFavoriteOption(item); return true; 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 c94f2ba44..1d769f72b 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 @@ -783,7 +783,7 @@ public void onNoteClick(int position, View v) { @Override public void onNoteFavoriteClick(int position, View view) { - final var toggleLiveData = mainViewModel.toggleFavoriteAndSync(((Note) adapter.getItem(position)).getId()); + final var toggleLiveData = mainViewModel.toggleFavoriteAndSync(((Note) adapter.getItem(position))); toggleLiveData.observe(this, (next) -> toggleLiveData.removeObservers(this)); } 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 a40a6f715..09cda5f70 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 @@ -513,15 +513,14 @@ public LiveData moveNoteToAnotherAccount(Account account, long noteId) { }); } - public LiveData toggleFavoriteAndSync(long noteId) { + public LiveData toggleFavoriteAndSync(Note note) { return switchMap(getCurrentAccount(), currentAccount -> { - if (currentAccount == null) { - return new MutableLiveData<>(null); - } else { + if (currentAccount != null) { Log.v(TAG, "[toggleFavoriteAndSync] - currentAccount: " + currentAccount.getAccountName()); - repo.toggleFavoriteAndSync(currentAccount, noteId); - return new MutableLiveData<>(null); + repo.toggleFavoriteAndSync(currentAccount, note); } + + return new MutableLiveData<>(null); }); } diff --git a/app/src/main/java/it/niedermann/owncloud/notes/main/items/list/NotesListViewItemTouchHelper.java b/app/src/main/java/it/niedermann/owncloud/notes/main/items/list/NotesListViewItemTouchHelper.java index 4b9734d7f..05b7c4d34 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/main/items/list/NotesListViewItemTouchHelper.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/main/items/list/NotesListViewItemTouchHelper.java @@ -101,7 +101,7 @@ public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) case ItemTouchHelper.RIGHT -> { viewHolder.setIsRecyclable(false); final var adapterNote = (Note) adapter.getItem(viewHolder.getLayoutPosition()); - final var toggleLiveData = mainViewModel.toggleFavoriteAndSync(adapterNote.getId()); + final var toggleLiveData = mainViewModel.toggleFavoriteAndSync(adapterNote); toggleLiveData.observe(lifecycleOwner, (next) -> toggleLiveData.removeObservers(lifecycleOwner)); } default -> { 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 172ebc5f9..d02dd4d2a 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 @@ -12,6 +12,7 @@ import static androidx.lifecycle.Transformations.map; import static java.util.stream.Collectors.toMap; import static it.niedermann.owncloud.notes.edit.EditNoteActivity.ACTION_SHORTCUT; +import static it.niedermann.owncloud.notes.shared.util.ApiVersionUtil.getPreferredApiVersion; import static it.niedermann.owncloud.notes.shared.util.NoteUtil.generateNoteExcerpt; import static it.niedermann.owncloud.notes.widget.notelist.NoteListWidget.updateNoteListWidgets; import static it.niedermann.owncloud.notes.widget.singlenote.SingleNoteWidget.updateSingleNoteWidgets; @@ -47,6 +48,7 @@ import com.nextcloud.android.sso.exceptions.NoCurrentAccountSelectedException; import com.nextcloud.android.sso.helper.SingleAccountHelper; import com.nextcloud.android.sso.model.SingleSignOnAccount; +import com.owncloud.android.lib.common.utils.Log_OC; import java.util.ArrayList; import java.util.Calendar; @@ -538,11 +540,26 @@ public Map getIdMap(long accountId) { .collect(toMap(Note::getRemoteId, Note::getId)); } + // FIXME: RACE CONDITION @AnyThread - public void toggleFavoriteAndSync(Account account, long noteId) { + public void toggleFavoriteAndSync(Account account, Note note) { executor.submit(() -> { - db.getNoteDao().toggleFavorite(noteId); - scheduleSync(account, true); + try { + final var ssoAccount = AccountImporter.getSingleSignOnAccount(context, account.getAccountName()); + final var notesAPI = apiProvider.getNotesAPI(context, ssoAccount, getPreferredApiVersion(account.getApiVersion())); + note.setFavorite(!note.getFavorite()); + final var result = notesAPI.updateNote(note); + final var response = result.execute(); + if (response.isSuccessful()) { + final var updatedNote = response.body(); + if (updatedNote != null) { + db.getNoteDao().updateNote(updatedNote); + scheduleSync(account, true); + } + } + } catch (Exception e) { + Log_OC.e(TAG, "toggleFavoriteAndSync: " + e); + } }); } diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/sync/NotesAPI.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/sync/NotesAPI.java index 2cf077b90..9f0189931 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/persistence/sync/NotesAPI.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/sync/NotesAPI.java @@ -17,7 +17,9 @@ import com.nextcloud.android.sso.api.ParsedResponse; import java.util.Calendar; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.stream.Collectors; import io.reactivex.Observable; @@ -106,6 +108,21 @@ public Call createNote(Note note) { } } + public Call updateNote(@NonNull Note note) { + final Long remoteId = note.getRemoteId(); + if (remoteId == null) { + return null; + } + + if (ApiVersion.API_VERSION_1_0.equals(usedApiVersion)) { + return notesAPI_1_0.updateNote(remoteId, note); + } else if (ApiVersion.API_VERSION_0_2.equals(usedApiVersion)) { + return notesAPI_0_2.updateNote(remoteId, new Note_0_2(note)); + } else { + return null; + } + } + public Call editNote(@NonNull Note note) { final Long remoteId = note.getRemoteId(); if (remoteId == null) { diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/sync/NotesAPI_0_2.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/sync/NotesAPI_0_2.java index 060cae353..9a26c0e83 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/persistence/sync/NotesAPI_0_2.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/sync/NotesAPI_0_2.java @@ -10,6 +10,7 @@ import com.nextcloud.android.sso.api.ParsedResponse; import java.util.List; +import java.util.Map; import io.reactivex.Observable; import it.niedermann.owncloud.notes.persistence.entity.Note; @@ -46,4 +47,7 @@ public interface NotesAPI_0_2 { @DELETE("notes/{remoteId}") Call deleteNote(@Path("remoteId") long noteId); + + @PUT("notes/{id}") + Call updateNote(@Path("id") long id, @Body NotesAPI.Note_0_2 note); } diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/sync/NotesAPI_1_0.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/sync/NotesAPI_1_0.java index ea5d822c7..2a857c98f 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/persistence/sync/NotesAPI_1_0.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/sync/NotesAPI_1_0.java @@ -10,6 +10,7 @@ import com.nextcloud.android.sso.api.ParsedResponse; import java.util.List; +import java.util.Map; import io.reactivex.Observable; import it.niedermann.owncloud.notes.persistence.entity.Note; @@ -52,4 +53,7 @@ public interface NotesAPI_1_0 { @PUT("settings") Call putSettings(@Body NotesSettings settings); + + @PUT("notes/{id}") + Call updateNote(@Path("id") long id, @Body Note note); } From 663fdc492e90d27a947f7f40c660878a53da2b91 Mon Sep 17 00:00:00 2001 From: alperozturk Date: Tue, 8 Jul 2025 10:41:09 +0200 Subject: [PATCH 2/7] fix race condition & update Signed-off-by: alperozturk --- .../owncloud/notes/main/MainActivity.java | 11 +++++++++-- .../owncloud/notes/main/MainViewModel.java | 14 +++++++------- .../notes/persistence/NotesRepository.java | 5 ++--- 3 files changed, 18 insertions(+), 12 deletions(-) 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 1d769f72b..29f40c5e9 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 @@ -783,8 +783,15 @@ public void onNoteClick(int position, View v) { @Override public void onNoteFavoriteClick(int position, View view) { - final var toggleLiveData = mainViewModel.toggleFavoriteAndSync(((Note) adapter.getItem(position))); - toggleLiveData.observe(this, (next) -> toggleLiveData.removeObservers(this)); + if (!(adapter.getItem(position) instanceof Note note)) { + return; + } + + final var toggleLiveData = mainViewModel.toggleFavoriteAndSync(note); + toggleLiveData.observe(this, (next) -> {{ + toggleLiveData.removeObservers(this); + adapter.notifyItemChanged(position); + }}); } @Override 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 09cda5f70..183e659ea 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 @@ -514,14 +514,14 @@ public LiveData moveNoteToAnotherAccount(Account account, long noteId) { } public LiveData toggleFavoriteAndSync(Note note) { - return switchMap(getCurrentAccount(), currentAccount -> { - if (currentAccount != null) { - Log.v(TAG, "[toggleFavoriteAndSync] - currentAccount: " + currentAccount.getAccountName()); - repo.toggleFavoriteAndSync(currentAccount, note); - } + final var currentAccount = getCurrentAccount().getValue(); - return new MutableLiveData<>(null); - }); + if (currentAccount != null) { + Log.v(TAG, "[toggleFavoriteAndSync] - currentAccount: " + currentAccount.getAccountName()); + repo.toggleFavoriteAndSync(currentAccount, note); + } + + return new MutableLiveData<>(null); } public LiveData deleteNoteAndSync(long id) { diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/NotesRepository.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/NotesRepository.java index d02dd4d2a..a19992216 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 @@ -540,7 +540,6 @@ public Map getIdMap(long accountId) { .collect(toMap(Note::getRemoteId, Note::getId)); } - // FIXME: RACE CONDITION @AnyThread public void toggleFavoriteAndSync(Account account, Note note) { executor.submit(() -> { @@ -553,8 +552,8 @@ public void toggleFavoriteAndSync(Account account, Note note) { if (response.isSuccessful()) { final var updatedNote = response.body(); if (updatedNote != null) { - db.getNoteDao().updateNote(updatedNote); - scheduleSync(account, true); + //db.getNoteDao().updateNote(note); + scheduleSync(account, false); } } } catch (Exception e) { From 431441451b729ce73e35117ac7b0dede55ebfac7 Mon Sep 17 00:00:00 2001 From: alperozturk Date: Wed, 9 Jul 2025 09:14:34 +0200 Subject: [PATCH 3/7] remove comment Signed-off-by: alperozturk --- .../niedermann/owncloud/notes/persistence/NotesRepository.java | 1 - 1 file changed, 1 deletion(-) 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 a19992216..5bd57540f 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 @@ -552,7 +552,6 @@ public void toggleFavoriteAndSync(Account account, Note note) { if (response.isSuccessful()) { final var updatedNote = response.body(); if (updatedNote != null) { - //db.getNoteDao().updateNote(note); scheduleSync(account, false); } } From c8c74fdcecd52bc4829ace58679845671c3ffc1c Mon Sep 17 00:00:00 2001 From: alperozturk Date: Wed, 16 Jul 2025 16:44:58 +0200 Subject: [PATCH 4/7] check db status Signed-off-by: alperozturk --- .../owncloud/notes/persistence/NotesRepository.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) 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 5bd57540f..c85cdea68 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 @@ -546,7 +546,16 @@ public void toggleFavoriteAndSync(Account account, Note note) { try { final var ssoAccount = AccountImporter.getSingleSignOnAccount(context, account.getAccountName()); final var notesAPI = apiProvider.getNotesAPI(context, ssoAccount, getPreferredApiVersion(account.getApiVersion())); - note.setFavorite(!note.getFavorite()); + + boolean newFavoriteValue = !note.getFavorite(); + DBStatus newDBStatus = DBStatus.VOID; + + if (newFavoriteValue) { + newDBStatus = DBStatus.LOCAL_EDITED; + } + + note.setFavorite(newFavoriteValue); + note.setStatus(newDBStatus); final var result = notesAPI.updateNote(note); final var response = result.execute(); if (response.isSuccessful()) { From acb52161d1b2935dcbf18299a2230d51324b10f5 Mon Sep 17 00:00:00 2001 From: alperozturk Date: Wed, 16 Jul 2025 16:48:44 +0200 Subject: [PATCH 5/7] check db status Signed-off-by: alperozturk --- .../owncloud/notes/persistence/NotesRepository.java | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) 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 c85cdea68..75c4d87bd 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 @@ -546,16 +546,8 @@ public void toggleFavoriteAndSync(Account account, Note note) { try { final var ssoAccount = AccountImporter.getSingleSignOnAccount(context, account.getAccountName()); final var notesAPI = apiProvider.getNotesAPI(context, ssoAccount, getPreferredApiVersion(account.getApiVersion())); - - boolean newFavoriteValue = !note.getFavorite(); - DBStatus newDBStatus = DBStatus.VOID; - - if (newFavoriteValue) { - newDBStatus = DBStatus.LOCAL_EDITED; - } - - note.setFavorite(newFavoriteValue); - note.setStatus(newDBStatus); + note.setFavorite(!note.getFavorite()); + note.setStatus(DBStatus.LOCAL_EDITED); final var result = notesAPI.updateNote(note); final var response = result.execute(); if (response.isSuccessful()) { From eee054cd7f04c1d3215419f0699aba5557ef348b Mon Sep 17 00:00:00 2001 From: alperozturk Date: Thu, 17 Jul 2025 08:56:03 +0200 Subject: [PATCH 6/7] revert db status changes Signed-off-by: alperozturk --- .../niedermann/owncloud/notes/persistence/NotesRepository.java | 1 - 1 file changed, 1 deletion(-) 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 75c4d87bd..5bd57540f 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 @@ -547,7 +547,6 @@ public void toggleFavoriteAndSync(Account account, Note note) { final var ssoAccount = AccountImporter.getSingleSignOnAccount(context, account.getAccountName()); final var notesAPI = apiProvider.getNotesAPI(context, ssoAccount, getPreferredApiVersion(account.getApiVersion())); note.setFavorite(!note.getFavorite()); - note.setStatus(DBStatus.LOCAL_EDITED); final var result = notesAPI.updateNote(note); final var response = result.execute(); if (response.isSuccessful()) { From bfd08e335ab2a1951509e3c2aa5838b6b341cb1c Mon Sep 17 00:00:00 2001 From: Andy Scherzinger Date: Thu, 17 Jul 2025 10:14:50 +0200 Subject: [PATCH 7/7] ci(chksm): Ignore module file Signed-off-by: Andy Scherzinger --- gradle/verification-metadata.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml index 4af2b4973..c3f1deec2 100644 --- a/gradle/verification-metadata.xml +++ b/gradle/verification-metadata.xml @@ -6,6 +6,7 @@ +