diff options
author | Stefan Niedermann <info@niedermann.it> | 2021-11-18 15:59:47 +0300 |
---|---|---|
committer | Niedermann IT-Dienstleistungen <stefan-niedermann@users.noreply.github.com> | 2021-11-29 17:28:10 +0300 |
commit | e23e826945923ab893dce1330c5e2f71cbb6e062 (patch) | |
tree | ec5653548bb1de1130ccdc22883f7b9002c7c667 /app/src/main/java/it/niedermann/nextcloud/deck/ui | |
parent | bc8ba3465a415f41510a62aac49a558f5c786ef4 (diff) |
#1165 Refactor PushNotifications
Signed-off-by: Stefan Niedermann <info@niedermann.it>
Diffstat (limited to 'app/src/main/java/it/niedermann/nextcloud/deck/ui')
-rw-r--r-- | app/src/main/java/it/niedermann/nextcloud/deck/ui/PushNotificationActivity.java | 165 | ||||
-rw-r--r-- | app/src/main/java/it/niedermann/nextcloud/deck/ui/PushNotificationViewModel.java | 102 |
2 files changed, 127 insertions, 140 deletions
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 59f01f862..25a255aa1 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,7 +1,5 @@ package it.niedermann.nextcloud.deck.ui; -import static it.niedermann.nextcloud.deck.persistence.sync.adapters.db.util.LiveDataHelper.observeOnce; - import android.content.Intent; import android.net.Uri; import android.text.TextUtils; @@ -13,16 +11,19 @@ import androidx.annotation.UiThread; import androidx.appcompat.app.AppCompatActivity; import androidx.lifecycle.ViewModelProvider; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + import it.niedermann.android.util.ColorUtil; import it.niedermann.nextcloud.deck.DeckLog; import it.niedermann.nextcloud.deck.R; -import it.niedermann.nextcloud.deck.api.ResponseCallback; +import it.niedermann.nextcloud.deck.api.IResponseCallback; import it.niedermann.nextcloud.deck.databinding.ActivityPushNotificationBinding; import it.niedermann.nextcloud.deck.model.Account; import it.niedermann.nextcloud.deck.ui.card.EditActivity; import it.niedermann.nextcloud.deck.ui.exception.ExceptionDialogFragment; import it.niedermann.nextcloud.deck.ui.exception.ExceptionHandler; -import it.niedermann.nextcloud.deck.util.ProjectUtil; +import kotlin.Triple; /** * Warning: Do not move this class to another package or folder! @@ -32,6 +33,7 @@ public class PushNotificationActivity extends AppCompatActivity { private ActivityPushNotificationBinding binding; private PushNotificationViewModel viewModel; + private final ExecutorService executor = Executors.newSingleThreadExecutor(); // Provided by Files app NotificationJob private static final String KEY_SUBJECT = "subject"; @@ -66,107 +68,38 @@ public class PushNotificationActivity extends AppCompatActivity { binding.message.setVisibility(View.VISIBLE); } - final String link = intent.getStringExtra(KEY_LINK); - try { - final long[] ids = ProjectUtil.extractBoardIdAndCardIdFromUrl(link); - - binding.cancel.setOnClickListener((v) -> finish()); - final String accountString = intent.getStringExtra(KEY_ACCOUNT); - - if (ids.length == 2) { - final String cardRemoteIdString = intent.getExtras().getString(KEY_CARD_REMOTE_ID, String.valueOf(ids[1])); - DeckLog.verbose("cardRemoteIdString = ", cardRemoteIdString); - try { - final int cardRemoteId = Integer.parseInt(cardRemoteIdString); - observeOnce(viewModel.readAccount(accountString), this, (account -> { - if (account != null) { - viewModel.setAccount(account.getName()); - DeckLog.verbose("account:", account); - observeOnce(viewModel.getBoardByRemoteId(account.getId(), ids[0]), PushNotificationActivity.this, (board -> { - DeckLog.verbose("BoardLocalId:", board); - if (board != null) { - observeOnce(viewModel.getCardByRemoteID(account.getId(), cardRemoteId), PushNotificationActivity.this, (card -> { - DeckLog.verbose("Card:", card); - if (card != null) { - viewModel.synchronizeCard(new ResponseCallback<>(account) { - @Override - public void onResponse(Boolean response) { - openCardOnSubmit(account, board.getLocalId(), card.getLocalId()); - } - - @Override - public void onError(Throwable throwable) { - super.onError(throwable); - openCardOnSubmit(account, board.getLocalId(), card.getLocalId()); - } - }, card); - } else { - DeckLog.info("Card is not yet available locally. Synchronize board with localId", board); - - viewModel.synchronizeBoard(new ResponseCallback<>(account) { - @Override - public void onResponse(Boolean response) { - runOnUiThread(() -> observeOnce(viewModel.getCardByRemoteID(account.getId(), cardRemoteId), PushNotificationActivity.this, (card -> { - DeckLog.verbose("Card:", card); - if (card != null) { - openCardOnSubmit(account, board.getLocalId(), card.getLocalId()); - } else { - DeckLog.warn("Something went wrong while synchronizing the card", cardRemoteId, " (cardRemoteId). Given fullCard is null."); - applyBrandToSubmitButton(account); - fallbackToBrowser(link); - } - }))); - } - - @Override - public void onError(Throwable throwable) { - super.onError(throwable); - DeckLog.warn("Something went wrong while synchronizing the board with localId", board); - applyBrandToSubmitButton(account); - fallbackToBrowser(link); - } - }, board.getLocalId()); - } - })); - } else { - DeckLog.warn("Given localBoardId for cardRemoteId", cardRemoteId, "is null."); - applyBrandToSubmitButton(account); - fallbackToBrowser(link); - } - })); - } else { - DeckLog.warn("Given account for", accountString, "is null."); - fallbackToBrowser(link); - } - })); - } catch (NumberFormatException e) { - DeckLog.logError(e); - fallbackToBrowser(link); - } - } else { - DeckLog.warn("Link does not contain two IDs (expected one board id and one card id):", link); - fallbackToBrowser(link); - } - } catch (Throwable t) { - final String params = "Error while receiving push notification:\n" - + KEY_SUBJECT + ": [" + intent.getStringExtra(KEY_SUBJECT) + "]\n" - + KEY_MESSAGE + ": [" + intent.getStringExtra(KEY_MESSAGE) + "]\n" - + KEY_LINK + ": [" + intent.getStringExtra(KEY_LINK) + "]\n" - + KEY_CARD_REMOTE_ID + ": [" + intent.getStringExtra(KEY_CARD_REMOTE_ID) + "]\n" - + KEY_ACCOUNT + ": [" + intent.getStringExtra(KEY_ACCOUNT) + "]"; - ExceptionDialogFragment.newInstance(new Exception(params, t), null).show(getSupportFragmentManager(), ExceptionDialogFragment.class.getSimpleName()); - DeckLog.logError(t); - } + binding.cancel.setOnClickListener((v) -> finish()); + viewModel.getAccount().observe(this, this::applyBrandToSubmitButton); + executor.submit(() -> viewModel.getCardInformation( + intent.getStringExtra(KEY_ACCOUNT), + intent.getStringExtra(KEY_CARD_REMOTE_ID), + new IResponseCallback<>() { + @Override + public void onResponse(Triple<Account, Long, Long> response) { + runOnUiThread(() -> openCardOnSubmit(response.getFirst(), response.getSecond(), response.getThird())); + } + + @Override + public void onError(Throwable throwable) { + IResponseCallback.super.onError(throwable); + runOnUiThread(() -> fallbackToBrowser(intent.getStringExtra(KEY_LINK))); + final String params = "Error while receiving push notification:\n" + + KEY_SUBJECT + ": [" + intent.getStringExtra(KEY_SUBJECT) + "]\n" + + KEY_MESSAGE + ": [" + intent.getStringExtra(KEY_MESSAGE) + "]\n" + + KEY_LINK + ": [" + intent.getStringExtra(KEY_LINK) + "]\n" + + KEY_CARD_REMOTE_ID + ": [" + intent.getStringExtra(KEY_CARD_REMOTE_ID) + "]\n" + + KEY_ACCOUNT + ": [" + intent.getStringExtra(KEY_ACCOUNT) + "]"; + ExceptionDialogFragment.newInstance(new Exception(params, throwable), null).show(getSupportFragmentManager(), ExceptionDialogFragment.class.getSimpleName()); + } + })); } - private void openCardOnSubmit(@NonNull Account account, long boardLocalId, long cardlocalId) { - runOnUiThread(() -> { - binding.submit.setOnClickListener((v) -> launchEditActivity(account, boardLocalId, cardlocalId)); - binding.submit.setText(R.string.simple_open); - applyBrandToSubmitButton(account); - binding.submit.setEnabled(true); - binding.progress.setVisibility(View.INVISIBLE); - }); + private void openCardOnSubmit(@NonNull Account account, long boardLocalId, long cardLocalId) { + binding.submit.setOnClickListener((v) -> launchEditActivity(account, boardLocalId, cardLocalId)); + binding.submit.setText(R.string.simple_open); + applyBrandToSubmitButton(account.getColor()); + binding.submit.setEnabled(true); + binding.progress.setVisibility(View.INVISIBLE); } /** @@ -174,20 +107,15 @@ public class PushNotificationActivity extends AppCompatActivity { */ private void fallbackToBrowser(String link) { DeckLog.warn("Falling back to browser as notification handler."); - runOnUiThread(() -> { - try { - final Uri uri = Uri.parse(link); - binding.submit.setOnClickListener((v) -> { - Intent browserIntent = new Intent(Intent.ACTION_VIEW, uri); - startActivity(browserIntent); - }); - binding.submit.setText(R.string.open_in_browser); - binding.submit.setEnabled(true); - binding.progress.setVisibility(View.INVISIBLE); - } catch (Throwable t) { - DeckLog.logError(t); - } - }); + try { + final var uri = Uri.parse(link); + binding.submit.setOnClickListener((v) -> startActivity(new Intent(Intent.ACTION_VIEW, uri))); + binding.submit.setText(R.string.open_in_browser); + binding.submit.setEnabled(true); + binding.progress.setVisibility(View.INVISIBLE); + } catch (Throwable t) { + DeckLog.logError(t); + } } @UiThread @@ -205,8 +133,7 @@ public class PushNotificationActivity extends AppCompatActivity { // TODO implement Branded interface // TODO apply branding based on board color - public void applyBrandToSubmitButton(@NonNull Account account) { - @ColorInt final int mainColor = account.getColor(); + public void applyBrandToSubmitButton(@ColorInt int mainColor) { try { binding.submit.setBackgroundColor(mainColor); binding.submit.setTextColor(ColorUtil.INSTANCE.getForegroundColorForBackgroundColor(mainColor)); 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 ff640274c..42ef05d0c 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 @@ -1,52 +1,112 @@ package it.niedermann.nextcloud.deck.ui; +import static androidx.lifecycle.Transformations.distinctUntilChanged; +import static androidx.lifecycle.Transformations.map; + +import android.annotation.SuppressLint; import android.app.Application; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.annotation.WorkerThread; import androidx.lifecycle.AndroidViewModel; import androidx.lifecycle.LiveData; +import androidx.lifecycle.MutableLiveData; import com.nextcloud.android.sso.helper.SingleAccountHelper; +import it.niedermann.nextcloud.deck.DeckLog; +import it.niedermann.nextcloud.deck.api.IResponseCallback; import it.niedermann.nextcloud.deck.api.ResponseCallback; import it.niedermann.nextcloud.deck.model.Account; -import it.niedermann.nextcloud.deck.model.Board; -import it.niedermann.nextcloud.deck.model.Card; import it.niedermann.nextcloud.deck.persistence.sync.SyncManager; +import kotlin.Triple; public class PushNotificationViewModel extends AndroidViewModel { private final SyncManager readAccountSyncManager; - private SyncManager accountSpecificSyncManager; + private final MutableLiveData<Account> account = new MutableLiveData<>(); public PushNotificationViewModel(@NonNull Application application) { super(application); this.readAccountSyncManager = new SyncManager(application); } - public LiveData<Account> readAccount(@Nullable String name) { - return readAccountSyncManager.readAccount(name); - } - - public void setAccount(@NonNull String accountName) { - SingleAccountHelper.setCurrentAccount(getApplication(), accountName); - accountSpecificSyncManager = new SyncManager(getApplication()); - } + @WorkerThread + public void getCardInformation( + @Nullable String accountString, + @Nullable String cardRemoteIdString, + @NonNull IResponseCallback<Triple<Account, Long, Long>> callback) { + if (cardRemoteIdString == null) { + callback.onError(new NumberFormatException("cardRemoteIdString is null")); + return; + } + try { + final long cardRemoteId; + try { + DeckLog.verbose("cardRemoteIdString = ", cardRemoteIdString); + cardRemoteId = Long.parseLong(cardRemoteIdString); + } catch (NumberFormatException e) { + callback.onError(e); + return; + } + final var account = readAccountSyncManager.readAccountDirectly(accountString); + if (account == null) { + callback.onError(new RuntimeException("Given account for" + accountString + "is null.")); + return; + } + SingleAccountHelper.setCurrentAccount(getApplication(), account.getName()); + final var syncManager = new SyncManager(getApplication()); + DeckLog.verbose("account:", account); + final var board = syncManager.getBoardByAccountAndCardRemoteIdDirectly(account.getId(), cardRemoteId); + DeckLog.verbose("BoardLocalId:", board); + if (board == null) { + callback.onError(new RuntimeException("Given localBoardId for cardRemoteId" + cardRemoteId + "is null.")); + return; + } + final var card = syncManager.getCardByRemoteIDDirectly(account.getId(), cardRemoteId); + DeckLog.verbose("Card:", card); + if (card != null) { + syncManager.synchronizeCard(new ResponseCallback<>(account) { + @Override + public void onResponse(Boolean response) { + callback.onResponse(new Triple<>(account, board.getLocalId(), card.getLocalId())); + } - public LiveData<Board> getBoardByRemoteId(long accountId, long remoteId) { - return accountSpecificSyncManager.getBoardByRemoteId(accountId, remoteId); - } + @Override + public void onError(Throwable throwable) { + super.onError(throwable); + callback.onResponse(new Triple<>(account, board.getLocalId(), card.getLocalId())); + } + }, card); + } else { + DeckLog.info("Card is not yet available locally. Synchronize board with localId", board); - public LiveData<Card> getCardByRemoteID(long accountId, long remoteId) { - return accountSpecificSyncManager.getCardByRemoteID(accountId, remoteId); - } + syncManager.synchronizeBoard(board.getLocalId(), new ResponseCallback<>(account) { + @Override + public void onResponse(Boolean response) { + final var card = syncManager.getCardByRemoteIDDirectly(account.getId(), cardRemoteId); + DeckLog.verbose("Card:", card); + if (card != null) { + callback.onResponse(new Triple<>(account, board.getLocalId(), card.getLocalId())); + } else { + callback.onError(new RuntimeException("Something went wrong while synchronizing the card" + cardRemoteId + " (cardRemoteId). Given fullCard is null.")); + } + } - public void synchronizeCard(@NonNull ResponseCallback<Boolean> responseCallback, Card card) { - accountSpecificSyncManager.synchronizeCard(responseCallback, card); + @SuppressLint("MissingSuperCall") + @Override + public void onError(Throwable throwable) { + callback.onError(new RuntimeException("Something went wrong while synchronizing the board with localId" + board)); + } + }); + } + } catch (Throwable t) { + callback.onError(t); + } } - public void synchronizeBoard(@NonNull ResponseCallback<Boolean> responseCallback, long localBoadId) { - accountSpecificSyncManager.synchronizeBoard(responseCallback, localBoadId); + public LiveData<Integer> getAccount() { + return distinctUntilChanged(map(this.account, Account::getColor)); } } |