From 49ce39ba7d50c4bbe2aa320476422ab969fd40d4 Mon Sep 17 00:00:00 2001 From: alperozturk Date: Wed, 22 Oct 2025 16:41:37 +0200 Subject: [PATCH 1/6] fix: json syntax exceptions Signed-off-by: alperozturk --- .../notes/persistence/CapabilitiesClient.java | 7 ------- .../notes/persistence/NotesServerSyncTask.java | 18 +++++++++++++++++- .../sync/CapabilitiesDeserializer.java | 14 +++++++++++++- 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/CapabilitiesClient.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/CapabilitiesClient.java index bd3d66027..520d74265 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/persistence/CapabilitiesClient.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/CapabilitiesClient.java @@ -13,16 +13,9 @@ import androidx.annotation.Nullable; import androidx.annotation.WorkerThread; -import com.nextcloud.android.sso.api.ParsedResponse; import com.nextcloud.android.sso.model.SingleSignOnAccount; -import java.util.Map; - -import it.niedermann.owncloud.notes.persistence.sync.OcsAPI; import it.niedermann.owncloud.notes.shared.model.Capabilities; -import it.niedermann.owncloud.notes.shared.model.OcsResponse; -import it.niedermann.owncloud.notes.shared.model.OcsUser; -import retrofit2.Response; @WorkerThread public class CapabilitiesClient { diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/NotesServerSyncTask.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/NotesServerSyncTask.java index 03d151a77..ceef8ff26 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/persistence/NotesServerSyncTask.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/NotesServerSyncTask.java @@ -17,6 +17,7 @@ import androidx.annotation.NonNull; +import com.google.gson.JsonSyntaxException; import com.nextcloud.android.sso.AccountImporter; import com.nextcloud.android.sso.exceptions.NextcloudApiNotRespondingException; import com.nextcloud.android.sso.exceptions.NextcloudFilesAppAccountNotFoundException; @@ -34,6 +35,7 @@ import java.util.List; import java.util.Map; +import io.reactivex.Observable; import it.niedermann.owncloud.notes.BuildConfig; import it.niedermann.owncloud.notes.persistence.entity.Account; import it.niedermann.owncloud.notes.persistence.entity.Note; @@ -226,7 +228,21 @@ private boolean pullRemoteChanges() { return false; } - final var fetchResponse = notesAPI.getNotes(modified, localAccount.getETag()).blockingSingle(); + final var fetchResponse = notesAPI.getNotes(modified, localAccount.getETag()) + .onErrorResumeNext(error -> { + if (error instanceof JsonSyntaxException || + (error.getCause() != null && error.getCause() instanceof JsonSyntaxException)) { + Log.w(TAG, "JSON parse error, likely 304 Not Modified"); + return Observable.empty(); + } + return Observable.error(error); + }) + .blockingFirst(null); + + if (fetchResponse == null) { + Log.d(TAG, "No changes from server"); + return true; + } final var remoteNotes = fetchResponse.getResponse(); final var remoteIDs = new HashSet(); // pull remote changes: update or create each remote note 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 7e158363d..65c26d7eb 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 @@ -17,6 +17,8 @@ import com.google.gson.JsonParseException; import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.List; import it.niedermann.android.util.ColorUtil; import it.niedermann.owncloud.notes.shared.model.Capabilities; @@ -89,9 +91,19 @@ public Capabilities deserialize(JsonElement json, Type typeOfT, JsonDeserializat if (capabilities.has(CAPABILITIES_NOTES)) { final var notes = capabilities.getAsJsonObject(CAPABILITIES_NOTES); if (notes.has(CAPABILITIES_NOTES_API_VERSION)) { - response.setApiVersion(notes.get(CAPABILITIES_NOTES_API_VERSION).toString()); + final var apiVersionElem = notes.get(CAPABILITIES_NOTES_API_VERSION); + if (apiVersionElem.isJsonArray()) { + List versions = new ArrayList<>(); + for (JsonElement e : apiVersionElem.getAsJsonArray()) { + versions.add(e.getAsString()); + } + response.setApiVersion(String.join(",", versions)); + } else if (apiVersionElem.isJsonPrimitive()) { + response.setApiVersion(apiVersionElem.getAsString()); + } } } + if (capabilities.has(CAPABILITIES_THEMING)) { final var theming = capabilities.getAsJsonObject(CAPABILITIES_THEMING); if (theming.has(CAPABILITIES_THEMING_COLOR)) { From 46b75588fdbb18b8a9195a24f57b68cb38e9deb6 Mon Sep 17 00:00:00 2001 From: alperozturk Date: Wed, 22 Oct 2025 16:45:39 +0200 Subject: [PATCH 2/6] fix: json syntax exceptions Signed-off-by: alperozturk --- .../notes/persistence/CapabilitiesClient.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/CapabilitiesClient.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/CapabilitiesClient.java index 520d74265..cda709e16 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/persistence/CapabilitiesClient.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/CapabilitiesClient.java @@ -13,8 +13,10 @@ import androidx.annotation.Nullable; import androidx.annotation.WorkerThread; +import com.google.gson.JsonSyntaxException; import com.nextcloud.android.sso.model.SingleSignOnAccount; +import io.reactivex.Observable; import it.niedermann.owncloud.notes.shared.model.Capabilities; @WorkerThread @@ -27,6 +29,8 @@ public class CapabilitiesClient { @WorkerThread public static Capabilities getCapabilities(@NonNull Context context, @NonNull SingleSignOnAccount ssoAccount, @Nullable String lastETag, @NonNull ApiProvider apiProvider) throws Throwable { final var ocsAPI = apiProvider.getOcsAPI(context, ssoAccount); + final var repository = NotesRepository.getInstance(context); + try { final var response = ocsAPI.getCapabilities(lastETag).blockingSingle(); final var capabilities = response.getResponse().ocs.data; @@ -37,12 +41,16 @@ public static Capabilities getCapabilities(@NonNull Context context, @NonNull Si Log.w(TAG, "Response headers of capabilities are null"); } - final var repository = NotesRepository.getInstance(context); repository.insertCapabilities(capabilities); - return capabilities; } catch (RuntimeException e) { final var cause = e.getCause(); + + if (e instanceof JsonSyntaxException || (cause instanceof JsonSyntaxException)) { + Log.w(TAG, "JSON parse error, likely 304 Not Modified"); + return repository.getCapabilities(); + } + if (cause != null) { throw cause; } else { From 06328e21e90d9bebc512911b4d05236fed4b44c4 Mon Sep 17 00:00:00 2001 From: alperozturk Date: Thu, 23 Oct 2025 13:20:03 +0200 Subject: [PATCH 3/6] check empty response Signed-off-by: alperozturk --- .../notes/persistence/CapabilitiesClient.java | 17 +++++++------ .../persistence/NotesServerSyncTask.java | 25 ++++++------------- 2 files changed, 17 insertions(+), 25 deletions(-) diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/CapabilitiesClient.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/CapabilitiesClient.java index cda709e16..97e45e9a1 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/persistence/CapabilitiesClient.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/CapabilitiesClient.java @@ -13,10 +13,11 @@ import androidx.annotation.Nullable; import androidx.annotation.WorkerThread; -import com.google.gson.JsonSyntaxException; +import com.nextcloud.android.sso.api.EmptyResponse; import com.nextcloud.android.sso.model.SingleSignOnAccount; -import io.reactivex.Observable; +import java.util.Objects; + import it.niedermann.owncloud.notes.shared.model.Capabilities; @WorkerThread @@ -42,19 +43,19 @@ public static Capabilities getCapabilities(@NonNull Context context, @NonNull Si } repository.insertCapabilities(capabilities); - return capabilities; - } catch (RuntimeException e) { - final var cause = e.getCause(); - if (e instanceof JsonSyntaxException || (cause instanceof JsonSyntaxException)) { - Log.w(TAG, "JSON parse error, likely 304 Not Modified"); + return capabilities; + } catch (Throwable t) { + if (t instanceof ClassCastException castException && Objects.requireNonNull(castException.getMessage()).contains(EmptyResponse.class.getSimpleName())) { + Log.d(TAG, "Server returned empty response - Notes not modified."); return repository.getCapabilities(); } + final var cause = t.getCause(); if (cause != null) { throw cause; } else { - throw e; + throw t; } } } diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/NotesServerSyncTask.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/NotesServerSyncTask.java index ceef8ff26..19e1336f3 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/persistence/NotesServerSyncTask.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/NotesServerSyncTask.java @@ -17,8 +17,8 @@ import androidx.annotation.NonNull; -import com.google.gson.JsonSyntaxException; import com.nextcloud.android.sso.AccountImporter; +import com.nextcloud.android.sso.api.EmptyResponse; import com.nextcloud.android.sso.exceptions.NextcloudApiNotRespondingException; import com.nextcloud.android.sso.exceptions.NextcloudFilesAppAccountNotFoundException; import com.nextcloud.android.sso.exceptions.NextcloudHttpRequestFailedException; @@ -34,8 +34,8 @@ import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Objects; -import io.reactivex.Observable; import it.niedermann.owncloud.notes.BuildConfig; import it.niedermann.owncloud.notes.persistence.entity.Account; import it.niedermann.owncloud.notes.persistence.entity.Note; @@ -228,21 +228,7 @@ private boolean pullRemoteChanges() { return false; } - final var fetchResponse = notesAPI.getNotes(modified, localAccount.getETag()) - .onErrorResumeNext(error -> { - if (error instanceof JsonSyntaxException || - (error.getCause() != null && error.getCause() instanceof JsonSyntaxException)) { - Log.w(TAG, "JSON parse error, likely 304 Not Modified"); - return Observable.empty(); - } - return Observable.error(error); - }) - .blockingFirst(null); - - if (fetchResponse == null) { - Log.d(TAG, "No changes from server"); - return true; - } + final var fetchResponse = notesAPI.getNotes(modified, localAccount.getETag()).blockingSingle(); final var remoteNotes = fetchResponse.getResponse(); final var remoteIDs = new HashSet(); // pull remote changes: update or create each remote note @@ -296,6 +282,11 @@ private boolean pullRemoteChanges() { return true; } catch (Throwable t) { final Throwable cause = t.getCause(); + if (t instanceof ClassCastException castException && Objects.requireNonNull(castException.getMessage()).contains(EmptyResponse.class.getSimpleName())) { + Log.d(TAG, "Server returned empty response - Notes not modified."); + return true; + } + if (t.getClass() == RuntimeException.class && cause != null) { if (cause.getClass() == NextcloudHttpRequestFailedException.class || cause instanceof NextcloudHttpRequestFailedException) { final NextcloudHttpRequestFailedException httpException = (NextcloudHttpRequestFailedException) cause; From 90a4eff3ae2fdecdc755009f1432a7e3b7a834f9 Mon Sep 17 00:00:00 2001 From: alperozturk Date: Thu, 23 Oct 2025 15:25:51 +0200 Subject: [PATCH 4/6] fix: single note widget Signed-off-by: alperozturk --- .../owncloud/notes/edit/EditNoteActivity.java | 17 ++-- .../notes/widget/notelist/NoteListWidget.kt | 5 - .../widget/singlenote/SingleNoteWidget.kt | 91 ++++++++++++------- .../singlenote/SingleNoteWidgetFactory.java | 31 ++++--- 4 files changed, 85 insertions(+), 59 deletions(-) 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 3abd1ad2f..bde93aeaf 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 @@ -77,15 +77,16 @@ protected void onCreate(final Bundle savedInstanceState) { repo = NotesRepository.getInstance(getApplicationContext()); - try { - if (SingleAccountHelper.getCurrentSingleSignOnAccount(this) == null) { - throw new NoCurrentAccountSelectedException(this); + new Thread(() -> { + try { + if (SingleAccountHelper.getCurrentSingleSignOnAccount(EditNoteActivity.this) == null) { + throw new NoCurrentAccountSelectedException(EditNoteActivity.this); + } + } catch (Exception e) { + Toast.makeText(this, R.string.no_account_configured_yet, Toast.LENGTH_LONG).show(); + finish(); } - } catch (NextcloudFilesAppAccountNotFoundException | NoCurrentAccountSelectedException e) { - Toast.makeText(this, R.string.no_account_configured_yet, Toast.LENGTH_LONG).show(); - finish(); - return; - } + }).start(); final var preferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); new SharedPreferenceBooleanLiveData(preferences, getString(R.string.pref_key_keep_screen_on), true).observe(this, keepScreenOn -> { diff --git a/app/src/main/java/it/niedermann/owncloud/notes/widget/notelist/NoteListWidget.kt b/app/src/main/java/it/niedermann/owncloud/notes/widget/notelist/NoteListWidget.kt index cab4ab972..fd15fa597 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/widget/notelist/NoteListWidget.kt +++ b/app/src/main/java/it/niedermann/owncloud/notes/widget/notelist/NoteListWidget.kt @@ -59,11 +59,6 @@ class NoteListWidget : AppWidgetProvider() { ) } - if (intent.extras == null) { - Log.w(TAG, "Intent doesn't have bundle") - return - } - Log.w(TAG, "Update widget via given appWidgetIds") val appWidgetIds = intArrayOf(intent.extras?.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, -1) ?: -1) diff --git a/app/src/main/java/it/niedermann/owncloud/notes/widget/singlenote/SingleNoteWidget.kt b/app/src/main/java/it/niedermann/owncloud/notes/widget/singlenote/SingleNoteWidget.kt index 8c2cd829a..3c7c87e19 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/widget/singlenote/SingleNoteWidget.kt +++ b/app/src/main/java/it/niedermann/owncloud/notes/widget/singlenote/SingleNoteWidget.kt @@ -13,14 +13,12 @@ import android.content.ComponentName import android.content.Context import android.content.Intent import android.widget.RemoteViews +import androidx.core.net.toUri import it.niedermann.owncloud.notes.R -import it.niedermann.owncloud.notes.edit.BaseNoteFragment import it.niedermann.owncloud.notes.edit.EditNoteActivity import it.niedermann.owncloud.notes.persistence.NotesRepository -import it.niedermann.owncloud.notes.shared.util.WidgetUtil import java.util.concurrent.ExecutorService import java.util.concurrent.Executors -import androidx.core.net.toUri class SingleNoteWidget : AppWidgetProvider() { private val executor: ExecutorService = Executors.newCachedThreadPool() @@ -52,44 +50,69 @@ class SingleNoteWidget : AppWidgetProvider() { super.onDeleted(context, appWidgetIds) } - companion object { - private val TAG: String = SingleNoteWidget::class.java.getSimpleName() - fun updateAppWidget(context: Context, awm: AppWidgetManager, appWidgetIds: IntArray) { - val templateIntent = Intent(context, EditNoteActivity::class.java) - val repo = NotesRepository.getInstance(context) + private fun updateAppWidget(context: Context, awm: AppWidgetManager, appWidgetIds: IntArray) { + val repo = NotesRepository.getInstance(context) + appWidgetIds.forEach { appWidgetId -> + repo.getSingleNoteWidgetData(appWidgetId)?.let { data -> + val pendingIntent = getPendingIntent(context, appWidgetId) + val serviceIntent = getServiceIntent(context, appWidgetId) + val views = getRemoteViews(context, pendingIntent, serviceIntent) + awm.run { + updateAppWidget(appWidgetId, views) + notifyAppWidgetViewDataChanged(appWidgetId, R.id.single_note_widget_lv) + } + } + } + } - appWidgetIds.forEach { appWidgetId -> - repo.getSingleNoteWidgetData(appWidgetId)?.let { data -> - templateIntent.putExtra(BaseNoteFragment.PARAM_ACCOUNT_ID, data.accountId) + private fun getPendingIntent( + context: Context, + id: Int + ): PendingIntent { + val intent = Intent(context, EditNoteActivity::class.java).apply { + setPackage(context.packageName) + } - val serviceIntent = Intent(context, SingleNoteWidgetService::class.java).apply { - putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId) - setData(toUri(Intent.URI_INTENT_SCHEME).toUri()) - } + val pendingIntentFlags = PendingIntent.FLAG_UPDATE_CURRENT or + PendingIntent.FLAG_MUTABLE or + Intent.FILL_IN_COMPONENT + return PendingIntent.getActivity( + context, + id, + intent, + pendingIntentFlags + ) + } - val views = RemoteViews(context.packageName, R.layout.widget_single_note).apply { - setPendingIntentTemplate( - R.id.single_note_widget_lv, PendingIntent.getActivity( - context, appWidgetId, templateIntent, - WidgetUtil.pendingIntentFlagCompat(PendingIntent.FLAG_UPDATE_CURRENT) - ) - ) - setRemoteAdapter(R.id.single_note_widget_lv, serviceIntent) - setEmptyView( - R.id.single_note_widget_lv, - R.id.widget_single_note_placeholder_tv - ) - } + private fun getServiceIntent(context: Context, id: Int): Intent { + return Intent(context, SingleNoteWidgetService::class.java).apply { + putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, id) + val dataFlag = toUri(Intent.URI_INTENT_SCHEME) + id + val dataUri = dataFlag.toUri() + setData(dataUri) + } + } - awm.run { - updateAppWidget(appWidgetId, views) - notifyAppWidgetViewDataChanged(appWidgetId, R.id.single_note_widget_lv) - } - } - } + private fun getRemoteViews( + context: Context, + pendingIntent: PendingIntent, + serviceIntent: Intent + ): RemoteViews { + return RemoteViews( + context.packageName, + R.layout.widget_single_note + ).apply { + setPendingIntentTemplate(R.id.single_note_widget_lv, pendingIntent) + setEmptyView( + R.id.single_note_widget_lv, + R.id.widget_single_note_placeholder_tv + ) + setRemoteAdapter(R.id.single_note_widget_lv, serviceIntent) } + } + companion object { @JvmStatic fun updateSingleNoteWidgets(context: Context) { val intent = Intent(context, SingleNoteWidget::class.java).apply { diff --git a/app/src/main/java/it/niedermann/owncloud/notes/widget/singlenote/SingleNoteWidgetFactory.java b/app/src/main/java/it/niedermann/owncloud/notes/widget/singlenote/SingleNoteWidgetFactory.java index 1aa0fe722..d588d121d 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/widget/singlenote/SingleNoteWidgetFactory.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/widget/singlenote/SingleNoteWidgetFactory.java @@ -9,19 +9,19 @@ import android.appwidget.AppWidgetManager; import android.content.Context; import android.content.Intent; -import android.os.Bundle; import android.util.Log; import android.widget.RemoteViews; import android.widget.RemoteViewsService; import androidx.annotation.Nullable; +import com.owncloud.android.lib.common.utils.Log_OC; + import it.niedermann.android.markdown.MarkdownUtil; import it.niedermann.owncloud.notes.R; import it.niedermann.owncloud.notes.edit.EditNoteActivity; import it.niedermann.owncloud.notes.persistence.NotesRepository; import it.niedermann.owncloud.notes.persistence.entity.Note; -import it.niedermann.owncloud.notes.persistence.entity.SingleNoteWidgetData; public class SingleNoteWidgetFactory implements RemoteViewsService.RemoteViewsFactory { @@ -89,17 +89,24 @@ public RemoteViews getViewAt(int position) { } final var fillInIntent = new Intent(); - final var args = new Bundle(); - - args.putLong(EditNoteActivity.PARAM_NOTE_ID, note.getId()); - args.putLong(EditNoteActivity.PARAM_ACCOUNT_ID, note.getAccountId()); - fillInIntent.putExtras(args); + fillInIntent.putExtra(EditNoteActivity.PARAM_NOTE_ID, note.getId()); + fillInIntent.putExtra(EditNoteActivity.PARAM_ACCOUNT_ID, note.getAccountId()); - final var note_content = new RemoteViews(context.getPackageName(), R.layout.widget_single_note_content); - note_content.setOnClickFillInIntent(R.id.single_note_content_tv, fillInIntent); - note_content.setTextViewText(R.id.single_note_content_tv, MarkdownUtil.renderForRemoteView(context, note.getContent())); + final var noteContent = new RemoteViews(context.getPackageName(), R.layout.widget_single_note_content); + noteContent.setOnClickFillInIntent(R.id.single_note_content_tv, fillInIntent); - return note_content; + CharSequence rendered; + try { + rendered = MarkdownUtil.renderForRemoteView(context, note.getContent()); + if (rendered == null) { + rendered = ""; + } + } catch (Exception e) { + Log_OC.e(TAG, "Markdown rendering failed", e); + rendered = note.getContent(); + } + noteContent.setTextViewText(R.id.single_note_content_tv, rendered); + return noteContent; } @@ -116,7 +123,7 @@ public int getViewTypeCount() { @Override public long getItemId(int position) { - return position; + return note != null ? note.getId() : position; } @Override From a256d342536e5f25bedab3cde825f8768589e63a Mon Sep 17 00:00:00 2001 From: alperozturk Date: Thu, 23 Oct 2025 15:50:23 +0200 Subject: [PATCH 5/6] revert unrelated changes Signed-off-by: alperozturk --- .../notes/persistence/CapabilitiesClient.java | 22 +++++++++---------- .../persistence/NotesServerSyncTask.java | 7 ------ .../sync/CapabilitiesDeserializer.java | 14 +----------- 3 files changed, 11 insertions(+), 32 deletions(-) diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/CapabilitiesClient.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/CapabilitiesClient.java index 97e45e9a1..bd3d66027 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/persistence/CapabilitiesClient.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/CapabilitiesClient.java @@ -13,12 +13,16 @@ import androidx.annotation.Nullable; import androidx.annotation.WorkerThread; -import com.nextcloud.android.sso.api.EmptyResponse; +import com.nextcloud.android.sso.api.ParsedResponse; import com.nextcloud.android.sso.model.SingleSignOnAccount; -import java.util.Objects; +import java.util.Map; +import it.niedermann.owncloud.notes.persistence.sync.OcsAPI; import it.niedermann.owncloud.notes.shared.model.Capabilities; +import it.niedermann.owncloud.notes.shared.model.OcsResponse; +import it.niedermann.owncloud.notes.shared.model.OcsUser; +import retrofit2.Response; @WorkerThread public class CapabilitiesClient { @@ -30,8 +34,6 @@ public class CapabilitiesClient { @WorkerThread public static Capabilities getCapabilities(@NonNull Context context, @NonNull SingleSignOnAccount ssoAccount, @Nullable String lastETag, @NonNull ApiProvider apiProvider) throws Throwable { final var ocsAPI = apiProvider.getOcsAPI(context, ssoAccount); - final var repository = NotesRepository.getInstance(context); - try { final var response = ocsAPI.getCapabilities(lastETag).blockingSingle(); final var capabilities = response.getResponse().ocs.data; @@ -42,20 +44,16 @@ public static Capabilities getCapabilities(@NonNull Context context, @NonNull Si Log.w(TAG, "Response headers of capabilities are null"); } + final var repository = NotesRepository.getInstance(context); repository.insertCapabilities(capabilities); return capabilities; - } catch (Throwable t) { - if (t instanceof ClassCastException castException && Objects.requireNonNull(castException.getMessage()).contains(EmptyResponse.class.getSimpleName())) { - Log.d(TAG, "Server returned empty response - Notes not modified."); - return repository.getCapabilities(); - } - - final var cause = t.getCause(); + } catch (RuntimeException e) { + final var cause = e.getCause(); if (cause != null) { throw cause; } else { - throw t; + throw e; } } } diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/NotesServerSyncTask.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/NotesServerSyncTask.java index 19e1336f3..03d151a77 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/persistence/NotesServerSyncTask.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/NotesServerSyncTask.java @@ -18,7 +18,6 @@ import androidx.annotation.NonNull; import com.nextcloud.android.sso.AccountImporter; -import com.nextcloud.android.sso.api.EmptyResponse; import com.nextcloud.android.sso.exceptions.NextcloudApiNotRespondingException; import com.nextcloud.android.sso.exceptions.NextcloudFilesAppAccountNotFoundException; import com.nextcloud.android.sso.exceptions.NextcloudHttpRequestFailedException; @@ -34,7 +33,6 @@ import java.util.HashSet; import java.util.List; import java.util.Map; -import java.util.Objects; import it.niedermann.owncloud.notes.BuildConfig; import it.niedermann.owncloud.notes.persistence.entity.Account; @@ -282,11 +280,6 @@ private boolean pullRemoteChanges() { return true; } catch (Throwable t) { final Throwable cause = t.getCause(); - if (t instanceof ClassCastException castException && Objects.requireNonNull(castException.getMessage()).contains(EmptyResponse.class.getSimpleName())) { - Log.d(TAG, "Server returned empty response - Notes not modified."); - return true; - } - if (t.getClass() == RuntimeException.class && cause != null) { if (cause.getClass() == NextcloudHttpRequestFailedException.class || cause instanceof NextcloudHttpRequestFailedException) { final NextcloudHttpRequestFailedException httpException = (NextcloudHttpRequestFailedException) cause; 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 65c26d7eb..7e158363d 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 @@ -17,8 +17,6 @@ import com.google.gson.JsonParseException; import java.lang.reflect.Type; -import java.util.ArrayList; -import java.util.List; import it.niedermann.android.util.ColorUtil; import it.niedermann.owncloud.notes.shared.model.Capabilities; @@ -91,19 +89,9 @@ public Capabilities deserialize(JsonElement json, Type typeOfT, JsonDeserializat if (capabilities.has(CAPABILITIES_NOTES)) { final var notes = capabilities.getAsJsonObject(CAPABILITIES_NOTES); if (notes.has(CAPABILITIES_NOTES_API_VERSION)) { - final var apiVersionElem = notes.get(CAPABILITIES_NOTES_API_VERSION); - if (apiVersionElem.isJsonArray()) { - List versions = new ArrayList<>(); - for (JsonElement e : apiVersionElem.getAsJsonArray()) { - versions.add(e.getAsString()); - } - response.setApiVersion(String.join(",", versions)); - } else if (apiVersionElem.isJsonPrimitive()) { - response.setApiVersion(apiVersionElem.getAsString()); - } + response.setApiVersion(notes.get(CAPABILITIES_NOTES_API_VERSION).toString()); } } - if (capabilities.has(CAPABILITIES_THEMING)) { final var theming = capabilities.getAsJsonObject(CAPABILITIES_THEMING); if (theming.has(CAPABILITIES_THEMING_COLOR)) { From 9f450f5335459f53227a274959453ba1dd6a32e2 Mon Sep 17 00:00:00 2001 From: alperozturk Date: Thu, 23 Oct 2025 15:51:51 +0200 Subject: [PATCH 6/6] show toast on main thread Signed-off-by: alperozturk --- .../it/niedermann/owncloud/notes/edit/EditNoteActivity.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) 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 bde93aeaf..1a669e615 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 @@ -83,8 +83,10 @@ protected void onCreate(final Bundle savedInstanceState) { throw new NoCurrentAccountSelectedException(EditNoteActivity.this); } } catch (Exception e) { - Toast.makeText(this, R.string.no_account_configured_yet, Toast.LENGTH_LONG).show(); - finish(); + runOnUiThread(() -> { + Toast.makeText(EditNoteActivity.this, R.string.no_account_configured_yet, Toast.LENGTH_LONG).show(); + finish(); + }); } }).start();