Skip to content

Commit

Permalink
Merge pull request #76 from muun/49.1-release-branch
Browse files Browse the repository at this point in the history
Release source code for 49.1
  • Loading branch information
acrespo authored Mar 22, 2022
2 parents 86e4b74 + 82575d7 commit 7c08f92
Show file tree
Hide file tree
Showing 19 changed files with 153 additions and 85 deletions.
21 changes: 21 additions & 0 deletions android/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,34 @@ follow [https://changelog.md/](https://changelog.md/) guidelines.

## [Unreleased]


## [49.1] - 2022-03-17

### FIXED
- Bug when fetching legacy Contact model after SQLDelight upgrade (on 49)
- Use of Math.toIntExact() which isn't supported on lower api levels (introduced in SQLDelight
upgrade)
- MuunAmountInput handling of SATs (currencies without decimals)
- Incorrect handling of changeCurrency and useAllFunds in send flow, introduced in our send payment
flow rewrite (48.2)
- Minor copy change when copying a LN payment hash to clipboard

## [49] - 2022-03-16

### ADDED
- Option to select SAT as input currency for receive and send screens' amount input
- Extra metadata for rare crash scenario
- Multiple route hints support in our invoices

### CHANGED
- Upgrade gradle to 7.3.3 to support JDK17 (ARM support)
- Upgrade AGP to 7.0.4 for gradle 7.3 compat
- Upgrade SQDelight to 1.5.3 for gradle 7.3 compat (hughe refactor and rework of data layer)
- Upgrade Kotlin to 1.6.10 for gradle 7.3 compat
- Upgrade Dagger to 2.40.5 for gradle 7.3 compat
- Upgrade checkstyle to 9.2.1
- Make libwallet it's own gradle project to work nicely with AndroidStudio

### FIXED
- Show new outgoing operation badge animation when using deeplink + process death/app not started
- Rare crash probably due to quick flurry of click events
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,8 @@ private Contact fromAllFields(
lastName,
profilePictureUrl
),
Math.toIntExact(maxAddressVersion),
PublicKey.deserializeFromBase58(publicKeyPath, publicKeyPath),
(int) maxAddressVersion,
PublicKey.deserializeFromBase58(publicKeyPath, serializedPublicKey),
cosigningPublicKey,
lastDerivationIndex
);
Expand Down
4 changes: 2 additions & 2 deletions android/apolloui/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,8 @@ android {
applicationId "io.muun.apollo"
minSdkVersion 19
targetSdkVersion 30
versionCode 900
versionName "49"
versionCode 901
versionName "49.1"

// Needed to make sure these classes are available in the main DEX file for API 19
// See: https://spin.atomicobject.com/2018/07/16/support-kitkat-multidex/
Expand Down
4 changes: 2 additions & 2 deletions android/apolloui/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -363,8 +363,8 @@
</provider>

<!--
Disable WorkManagerInitializer to avoid auto workmanager initialization (use custom). See:
https://developer.android.com/topic/libraries/architecture/workmanager/advanced/custom-configuration
Disable WorkManagerInitializer to avoid auto workmanager initialization (use custom). See:
https://developer.android.com/topic/libraries/architecture/workmanager/advanced/custom-configuration
-->
<provider
android:name="androidx.work.impl.WorkManagerInitializer"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,12 +110,11 @@ public void afterTextChanged(StringBuilder s) {
s.replace(indexOfDecimalComma, indexOfDecimalComma + decimalsCount + 1, "");
target.setSelection(target.getSelectionStart() - 1 - decimalsCount);
}
target.setText(s);
return;
} else {
// Android Supreme localization bug only happens when dealing with decimal separator
handleAndroidSupremeLocalizationBug(s, target);
}

handleAndroidSupremeLocalizationBug(s, target);

removeExtraDigitIfDeletingGroupingSeparator(s, target);
cleanLeadingZeros(s, target);
cleanFractionalDigits(s, target);
Expand Down Expand Up @@ -224,7 +223,7 @@ public void setMaxFractionalDigits(int maxFractionalDigits) {
* </p>
*/
private void handleAndroidSupremeLocalizationBug(StringBuilder s, DecorationHandler handler) {
if (decimalSeparator != '.') {
if (decimalSeparator != '.' && maxFractionalDigits != 0) {

replace(s, start, start + after, '.', decimalSeparator);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -208,20 +208,12 @@ class HomeFragment: SingleFragment<HomePresenter>(), HomeView {
balanceView.setBalance(homeState)
setChevronAnimation(homeState.utxoSetState)

// We want one of the cards to "occupy space" (aka be invisible not gone) to avoid visual
// jumps/glitches
taprootCard.visibility = View.GONE
securityCenterCard.visibility = View.INVISIBLE

blockClock.visibility = View.GONE

// Due to (complex) business logic reasons, only 1 of these cards is currently displayed
var displayedMuunHomeCard: MuunHomeCard? = null
val taprootStatus = homeState.taprootFeatureStatus
if (!homeState.user.isRecoverable) {
displayedMuunHomeCard = securityCenterCard

} else when (taprootStatus) {
} else when (homeState.taprootFeatureStatus) {
UserActivatedFeatureStatus.OFF -> { } // Do nothing
UserActivatedFeatureStatus.CAN_PREACTIVATE -> displayedMuunHomeCard = taprootCard
UserActivatedFeatureStatus.CAN_ACTIVATE -> displayedMuunHomeCard = taprootCard
Expand All @@ -232,12 +224,16 @@ class HomeFragment: SingleFragment<HomePresenter>(), HomeView {

blockClock.value = homeState.blocksToTaproot

displayedMuunHomeCard?.let {
it.visibility = View.VISIBLE
if (it == taprootCard) {
// Avoid having 2x height when taprootCard is shown (see visual jump comment above)
if (displayedMuunHomeCard != null) {
displayedMuunHomeCard.visibility = View.VISIBLE
if (displayedMuunHomeCard == taprootCard) {
securityCenterCard.visibility = View.GONE
} else {
taprootCard.visibility = View.GONE
}
} else {
securityCenterCard.visibility = View.GONE
taprootCard.visibility = View.GONE
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,20 +115,19 @@ protected void initializeUi() {

bottomNav.setOnNavigationItemSelectedListener(item -> {

final Bundle bundle = new Bundle();
final Bundle bundle = new Bundle();

if (item.getItemId() == R.id.security_center_fragment) {
final SecurityCenterFragmentArgs args = new SecurityCenterFragmentArgs
.Builder(SECURITY_CENTER_ORIGIN.SHIELD_BUTTON)
.build();
if (item.getItemId() == R.id.security_center_fragment) {
final SecurityCenterFragmentArgs args = new SecurityCenterFragmentArgs
.Builder(SECURITY_CENTER_ORIGIN.SHIELD_BUTTON)
.build();

bundle.putAll(args.toBundle());
}
bundle.putAll(args.toBundle());
}

navigateToItem(item.getItemId(), bundle);
return true;
}
);
navigateToItem(item.getItemId(), bundle);
return true;
});
bottomNav.setOnNavigationItemReselectedListener(item -> {
// do nothing here, it will prevent recreating same fragment
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,10 @@ public void onActivityCreated() {
fetchRealTimeData.runForced();
}

/**
* Call to report activity was destroyed.
* TODO: this should have a base presenter method associated
*/
public void onActivityDestroyed() {
operationsCache.stop();
}
Expand Down Expand Up @@ -147,10 +151,16 @@ public void navigateToOperations() {
navigator.navigateToOperations((Activity) view);
}

/**
* Navigate to send feedbback screen.
*/
public void navigateToSendFeedbackScreen() {
navigator.navigateToSendGenericFeedback(getContext());
}

/**
* Avoid showing taproot celebration again.
*/
public void reportTaprootCelebrationShown() {
userSel.setPendingTaprootCelebration(false);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -346,10 +346,10 @@ class NewOperationActivity : SingleFragmentActivity<NewOperationPresenter>(), Ne

val paymentContext = state.resolved.paymentContext
amountInput.setExchangeRateProvider(paymentContext.buildExchangeRateProvider())
amountInput.setOnChangeListener { amount: MonetaryAmount ->
amountInput.setOnChangeListener { oldAmount: MonetaryAmount, newAmount: MonetaryAmount ->
amountInput.setAmountError(false)
actionButton.isEnabled = true
presenter.updateAmount(amount, state)
presenter.updateAmount(oldAmount, newAmount, state)
}

useAllFundsView.isEnabled = !balance.isZero
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -269,15 +269,15 @@ class NewOperationPresenter @Inject constructor(
return true
}

fun updateAmount(amount: MonetaryAmount, state: EnterAmountState) {
fun updateAmount(oldAmount: MonetaryAmount, newAmount: MonetaryAmount, state: EnterAmountState) {

// This is our way of detecting a currency change. Since the feature is abstracted into
// MuunAmountInput and the exposed API reports the new amount.
if (amount.currency.currencyCode != state.amount.inInputCurrency.currency) {
state.changeCurrency(amount.currency.currencyCode)
if (newAmount.currency.currencyCode != state.amount.inInputCurrency.currency) {
state.changeCurrencyWithAmount(newAmount.currency.currencyCode, oldAmount.toLibwallet())
}

if (!state.partialValidate(amount.toLibwallet())) {
if (!state.partialValidate(newAmount.toLibwallet())) {
view.setAmountInputError()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ private void setIncomingSwapOperation(final UiOperation operation) {
swapPaymentHashItem.setVisibility(
!TextUtils.isEmpty(paymentHash) ? View.VISIBLE : View.GONE
);
swapPaymentHashItem.setOnIconClickListener(view -> onCopyPreimageToClipboard(paymentHash));
swapPaymentHashItem.setOnIconClickListener(v -> onCopyPaymentHashToClipboard(paymentHash));

final String preimage = operation.getPreimage();
swapPreimageItem.setDescription(preimage);
Expand Down Expand Up @@ -351,6 +351,11 @@ private void onCopyPreimageToClipboard(String preimage) {
showTextToast(getString(R.string.operation_detail_preimage_copied));
}

private void onCopyPaymentHashToClipboard(String paymentHash) {
presenter.copySwapPreimageToClipboard(paymentHash);
showTextToast(getString(R.string.operation_detail_preimage_copied));
}

private void onCopyTransactionIdToClipboard(String transactionId) {
presenter.copyTransactionIdToClipboard(transactionId);
showTextToast(getString(R.string.operation_detail_txid_copied));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ class SelectAmountActivity : BaseActivity<SelectAmountPresenter>(), SelectAmount

override fun setExchangeRateProvider(exchangeRateProvider: ExchangeRateProvider) {
amountInput.setExchangeRateProvider(exchangeRateProvider)
amountInput.setOnChangeListener(this::onAmountChange)
amountInput.setOnChangeListener { _, newAmount -> onAmountChange(newAmount) }
amountInput.isEnabled = true
amountInput.requestFocusInput()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ public interface OnChangeListener {

/**
* This method is called to notify you that the amount in this input has changed. The
* param value holds the new amount.
* param values hold the old and the new amount.
*/
void onChange(MonetaryAmount value);
void onChange(MonetaryAmount oldValue, MonetaryAmount newValue);
}

static final ViewProps<MuunAmountInput> viewProps
Expand Down Expand Up @@ -104,7 +104,7 @@ public interface OnChangeListener {
private DecimalFormatSymbols symbols;

private boolean isMakingInternalChange;
private boolean isCurrentyChangingCurrency;
private boolean isCurrentlyChangingCurrency;

public MuunAmountInput(Context context) {
super(context);
Expand Down Expand Up @@ -277,16 +277,17 @@ private void onNumberInputChange(String numberString) {
newValue = newValue.divide(BitcoinUtils.SATOSHIS_PER_BITCOIN);
}

final MonetaryAmount oldValue = value;
value = newValue;

// Once we start typing, text should have this color, unless overruled by setAmountError
inputAmount.setTextColor(normalNumberColor);

if (!isCurrentyChangingCurrency) {
if (!isCurrentlyChangingCurrency) {
valueBeforeCurrencyChange = newValue;
}

notifyChange();
notifyChange(oldValue, newValue);
}

private void onCurrencyInputChange(String newCode) {
Expand All @@ -309,17 +310,18 @@ private void onCurrencyInputChange(String newCode) {
newValue = Money.of(value.getNumber(), newCode);
}

final MonetaryAmount oldValue = value;
value = newValue;

adjustFractionalDigits();
updateCurrencyCodeText();
updateAmountText(true);
notifyChange();
notifyChange(oldValue, newValue);
}

private void notifyChange() {
private void notifyChange(MonetaryAmount oldValue, MonetaryAmount newValue) {
if (onChangeListener != null) {
onChangeListener.onChange(value);
onChangeListener.onChange(oldValue, newValue);
}
}

Expand Down Expand Up @@ -352,7 +354,7 @@ private void updateCurrencyCodeText(BitcoinUnit bitcoinUnit) {

private void updateAmountText(boolean isDueToCurrencyChange) {
isMakingInternalChange = true;
isCurrentyChangingCurrency = isDueToCurrencyChange;
isCurrentlyChangingCurrency = isDueToCurrencyChange;

if (value.isPositive()) {
final String text = MoneyHelper.formatInputMonetaryAmount(
Expand All @@ -372,7 +374,7 @@ private void updateAmountText(boolean isDueToCurrencyChange) {
inputAmount.setText("");
}

isCurrentyChangingCurrency = false;
isCurrentlyChangingCurrency = false;
isMakingInternalChange = false;
}

Expand Down
2 changes: 1 addition & 1 deletion android/apolloui/src/main/res/layout/fragment_home.xml
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:layout_marginBottom="64dp"
android:visibility="invisible"
android:visibility="gone"
tools:visibility="visible" />

<io.muun.apollo.presentation.ui.view.BlockClock
Expand Down
14 changes: 9 additions & 5 deletions android/apolloui/src/main/res/values-es/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,8 @@
Esta factura no incluye un monto
</string>
<string name="error_op_invoice_invalid_amount_desc">
Por el momento, sólo se puede pagar a facturas que incluyan un monto. Por favor, crea o solicita una nueva.
Por el momento, sólo se puede pagar a facturas que incluyan un monto. Por favor,
crea o solicita una nueva.
</string>

<string name="error_op_invoice_invalid_title">No es posible pagar esta factura</string>
Expand Down Expand Up @@ -295,6 +296,9 @@
<string name="operation_detail_preimage_copied">
Preimagen del pago copiada al portapapeles
</string>
<string name="operation_detail_payment_hash_copied">
Hash del pago copiado al portapapeles
</string>
<string name="operation_detail_txid_copied">
Identificador copiado al portapapeles
</string>
Expand Down Expand Up @@ -1382,10 +1386,10 @@
</string>
<string name="rbf_notice_banner_title">¿Cómo se puede cancelar esta transacción?</string>
<string name="rbf_notice_banner_desc">
Esta transacción tiene RBF (replace-by-fee) activado. RBF le permite al remitente incrementar
la comisión original para una confirmación más rápida, pero también puede usarlo para
cancelar la transacción. A menos que conozcas y confíes en el remitente, considéralo
un riesgo hasta que se confirme la transacción.
Esta transacción tiene RBF (replace-by-fee) activado. RBF le permite al remitente
incrementar la comisión original para una confirmación más rápida, pero también puede
usarlo para cancelar la transacción. A menos que conozcas y confíes en el remitente,
considéralo un riesgo hasta que se confirme la transacción.
</string>

<string name="turbo_channels">Turbo channels</string>
Expand Down
Loading

0 comments on commit 7c08f92

Please sign in to comment.