From ef7ea1f4760b4cb15189e8496e4686a3ce0f2c36 Mon Sep 17 00:00:00 2001 From: Stefan Niedermann Date: Fri, 26 Nov 2021 10:37:00 +0100 Subject: #1165 Refactor PushNotifications Signed-off-by: Stefan Niedermann --- .../java/it/niedermann/nextcloud/deck/DeckLog.java | 9 +- .../deck/ui/PushNotificationActivity.java | 14 +-- .../deck/ui/PushNotificationViewModel.java | 103 +++++++++++++++++---- app/src/main/res/values/strings.xml | 1 + 4 files changed, 101 insertions(+), 26 deletions(-) (limited to 'app/src/main') diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/DeckLog.java b/app/src/main/java/it/niedermann/nextcloud/deck/DeckLog.java index cc2ea99f4..1fc69c3b2 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/DeckLog.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/DeckLog.java @@ -40,7 +40,7 @@ public class DeckLog { } public enum Severity { - VERBOSE, DEBUG, LOG, INFO, WARN, ERROR + VERBOSE, DEBUG, LOG, INFO, WARN, ERROR, WTF } public static void verbose(Object... message) { @@ -63,6 +63,10 @@ public class DeckLog { log(Severity.ERROR, 4, message); } + public static void wtf(Object... message) { + log(Severity.WTF, 4, message); + } + public static void log(@NonNull Severity severity, Object... message) { log(severity, 3, message); } @@ -95,6 +99,9 @@ public class DeckLog { case ERROR: Log.e(TAG, print); break; + case WTF: + Log.wtf(TAG, print); + break; default: Log.v(TAG, print); break; diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/PushNotificationActivity.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/PushNotificationActivity.java index b824ed305..7ccd237c1 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/PushNotificationActivity.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/PushNotificationActivity.java @@ -1,12 +1,8 @@ package it.niedermann.nextcloud.deck.ui; -import static it.niedermann.nextcloud.deck.ui.PushNotificationViewModel.KEY_MESSAGE; -import static it.niedermann.nextcloud.deck.ui.PushNotificationViewModel.KEY_SUBJECT; - import android.annotation.SuppressLint; import android.content.Intent; import android.net.Uri; -import android.text.TextUtils; import android.view.View; import androidx.annotation.ColorInt; @@ -43,7 +39,7 @@ public class PushNotificationActivity extends AppCompatActivity { Thread.currentThread().setUncaughtExceptionHandler(new ExceptionHandler(this)); - final Intent intent = getIntent(); + final var intent = getIntent(); if (intent == null) { throw new IllegalArgumentException("Could not retrieve intent"); } @@ -54,11 +50,11 @@ public class PushNotificationActivity extends AppCompatActivity { setContentView(binding.getRoot()); setSupportActionBar(binding.toolbar); - binding.subject.setText(intent.getStringExtra(KEY_SUBJECT)); + viewModel.extractSubject(intent.getExtras()).ifPresent(binding.subject::setText); - final String message = intent.getStringExtra(KEY_MESSAGE); - if (!TextUtils.isEmpty(message)) { - binding.message.setText(message); + final var message = viewModel.extractMessage(intent.getExtras()); + if (message.isPresent()) { + binding.message.setText(message.get()); binding.message.setVisibility(View.VISIBLE); } diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/PushNotificationViewModel.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/PushNotificationViewModel.java index 9b74c6254..f58b42272 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/PushNotificationViewModel.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/PushNotificationViewModel.java @@ -7,6 +7,7 @@ import android.annotation.SuppressLint; import android.app.Application; import android.net.Uri; import android.os.Bundle; +import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -20,6 +21,7 @@ import com.nextcloud.android.sso.helper.SingleAccountHelper; import java.util.Optional; import it.niedermann.nextcloud.deck.DeckLog; +import it.niedermann.nextcloud.deck.R; import it.niedermann.nextcloud.deck.api.IResponseCallback; import it.niedermann.nextcloud.deck.api.ResponseCallback; import it.niedermann.nextcloud.deck.model.Account; @@ -29,9 +31,9 @@ import it.niedermann.nextcloud.deck.util.ProjectUtil; public class PushNotificationViewModel extends AndroidViewModel { // Provided by Files app NotificationJob - static final String KEY_SUBJECT = "subject"; - static final String KEY_MESSAGE = "message"; - static final String KEY_LINK = "link"; + private static final String KEY_SUBJECT = "subject"; + private static final String KEY_MESSAGE = "message"; + private static final String KEY_LINK = "link"; private static final String KEY_ACCOUNT = "account"; private static final String KEY_CARD_REMOTE_ID = "objectId"; @@ -69,6 +71,7 @@ public class PushNotificationViewModel extends AndroidViewModel { if (boardLocalId.isPresent()) { callback.onResponse(new CardInformation(account, boardLocalId.get(), card.get().getLocalId())); } else { + DeckLog.wtf("Card with local ID", card.get().getLocalId(), "and remote ID", card.get().getId(), "is present, but could not find board for it."); publishErrorToCallback("Given localBoardId for cardRemoteId" + cardRemoteId + "is null.", null, callback, bundle); } } @@ -78,8 +81,10 @@ public class PushNotificationViewModel extends AndroidViewModel { super.onError(throwable); final var boardLocalId = extractBoardLocalId(syncManager, account.getId(), cardRemoteId, bundle); if (boardLocalId.isPresent()) { + Toast.makeText(getApplication(), R.string.card_outdated, Toast.LENGTH_LONG).show(); callback.onResponse(new CardInformation(account, boardLocalId.get(), card.get().getLocalId())); } else { + DeckLog.wtf("Card with local ID", card.get().getLocalId(), "and remote ID", card.get().getId(), "is present, but could not find board for it."); publishErrorToCallback("Given localBoardId for cardRemoteId" + cardRemoteId + "is null.", null, callback, bundle); } } @@ -92,7 +97,6 @@ public class PushNotificationViewModel extends AndroidViewModel { @Override public void onResponse(Boolean response) { final var card = syncManager.getCardByRemoteIDDirectly(account.getId(), cardRemoteId); - DeckLog.verbose("Card:", card); if (card.isPresent()) { callback.onResponse(new CardInformation(account, boardLocalId.get(), card.get().getLocalId())); } else { @@ -109,18 +113,59 @@ public class PushNotificationViewModel extends AndroidViewModel { } else { final var boardRemoteId = extractBoardRemoteId(bundle); if (boardRemoteId.isPresent()) { - publishErrorToCallback("Could not find local board for boardRemoteId " + boardRemoteId.get(), null, callback, bundle); - // TODO synchronize whole account / fetch board for this ID - // TODO after synchronization, try to find the local board again + // TODO It should be enough to only fetch the board with the given boardRemoteId, not sure though whether it's worth the effort + syncManager.synchronize(new ResponseCallback<>(account) { + @Override + public void onResponse(Boolean response) { + final var card = syncManager.getCardByRemoteIDDirectly(account.getId(), cardRemoteId); + if (card.isPresent()) { + final var boardLocalId = extractBoardLocalId(syncManager, account.getId(), cardRemoteId, bundle); + if (boardLocalId.isPresent()) { + callback.onResponse(new CardInformation(account, boardLocalId.get(), card.get().getLocalId())); + } else { + DeckLog.wtf("Card with local ID", card.get().getLocalId(), "and remote ID", card.get().getId(), "is present, but could not find board for it."); + publishErrorToCallback("Could not find board locally for card with remote ID" + cardRemoteId + "even after full synchronization", null, callback, bundle); + } + } else { + publishErrorToCallback("Could not find card with remote ID" + cardRemoteId + "even after full synchronization", null, callback, bundle); + } + } + + @Override + @SuppressLint("MissingSuperCall") + public void onError(Throwable throwable) { + publishErrorToCallback("Could not extract boardRemoteId", null, callback, bundle); + } + }); } else { - publishErrorToCallback("Could not extract boardRemoteId", null, callback, bundle); - // TODO synchronize whole account - // TODO after synchronization, try to find the card again + syncManager.synchronize(new ResponseCallback<>(account) { + @Override + public void onResponse(Boolean response) { + final var card = syncManager.getCardByRemoteIDDirectly(account.getId(), cardRemoteId); + if (card.isPresent()) { + final var boardLocalId = extractBoardLocalId(syncManager, account.getId(), cardRemoteId, bundle); + if (boardLocalId.isPresent()) { + callback.onResponse(new CardInformation(account, boardLocalId.get(), card.get().getLocalId())); + } else { + DeckLog.wtf("Card with local ID", card.get().getLocalId(), "and remote ID", card.get().getId(), "is present, but could not find board for it."); + publishErrorToCallback("Could not find board locally for card with remote ID" + cardRemoteId + "even after full synchronization", null, callback, bundle); + } + } else { + publishErrorToCallback("Could not find card with remote ID" + cardRemoteId + "even after full synchronization", null, callback, bundle); + } + } + + @Override + @SuppressLint("MissingSuperCall") + public void onError(Throwable throwable) { + publishErrorToCallback("Could not extract boardRemoteId", null, callback, bundle); + } + }); } } } - } catch (Throwable t) { - publishErrorToCallback("", t, callback, bundle); + } catch (Throwable throwable) { + publishErrorToCallback("", throwable, callback, bundle); } } @@ -168,10 +213,36 @@ public class PushNotificationViewModel extends AndroidViewModel { } private Optional extractBoardRemoteId(@NonNull Bundle bundle) { - final long[] ids = ProjectUtil.extractBoardIdAndCardIdFromUrl(bundle.getString(KEY_LINK)); - return ids.length > 0 - ? Optional.of(ids[0]) - : Optional.empty(); + try { + final long[] ids = ProjectUtil.extractBoardIdAndCardIdFromUrl(bundle.getString(KEY_LINK)); + return ids.length > 0 + ? Optional.of(ids[0]) + : Optional.empty(); + } catch (IllegalArgumentException e) { + return Optional.empty(); + } + } + + public Optional extractSubject(@Nullable Bundle bundle) { + return extractProperty(bundle, KEY_SUBJECT); + } + + public Optional extractMessage(@Nullable Bundle bundle) { + return extractProperty(bundle, KEY_MESSAGE); + } + + private Optional extractProperty(@Nullable Bundle bundle, @NonNull String property) { + if (bundle == null) { + return Optional.empty(); + } + final String val = bundle.getString(property); + if (val == null) { + return Optional.empty(); + } + if (val.trim().isEmpty()) { + return Optional.empty(); + } + return Optional.of(val); } public LiveData getAccount() { diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 57e865856..fbdab5862 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -350,4 +350,5 @@ Saving new card… Importing board %1$d of %2$d… Importing boards… + The content of this card might be outdated. -- cgit v1.2.3