Skip to content

Commit 470e677

Browse files
author
NightShiftNexus
committed
fix: code review #1
1 parent 1b044a7 commit 470e677

File tree

2 files changed

+110
-97
lines changed

2 files changed

+110
-97
lines changed

app/src/main/java/protect/card_locker/cardview/LoyaltyCardViewActivity.java

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,8 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
8383
LoyaltyCardImageNavigator cardNavigator = new LoyaltyCardImageNavigator(new ArrayList<>(), 0);
8484
private LoyaltyCardMainImageRenderer mainImageRenderer;
8585
private final LoyaltyCardViewDialogs dialogs = new LoyaltyCardViewDialogs();
86-
private int pendingImageIndex = 0;
86+
// Used only to seed the first navigator after recreation, before card data has been reloaded.
87+
private Integer restoredImageIndex = null;
8788

8889
public static final String STATE_IMAGEINDEX = "imageIndex";
8990
public static final String STATE_FULLSCREEN = "isFullscreen";
@@ -93,21 +94,25 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
9394
public static final String BUNDLE_TRANSITION_RIGHT = "transition_right";
9495

9596
final private TaskHandler mTasks = new TaskHandler();
96-
Runnable barcodeImageGenerationFinishedCallback;
9797

9898
private long initTime = System.currentTimeMillis();
9999

100+
private enum AdjacentCardDirection {
101+
PREVIOUS,
102+
NEXT
103+
}
104+
100105
@Override
101106
public boolean onKeyDown(int keyCode, KeyEvent event) {
102107
if (settings.useVolumeKeysForNavigation()) {
103108
if (keyCode == KeyEvent.KEYCODE_VOLUME_UP) {
104109
if (initTime < (System.currentTimeMillis() - 1000)) {
105-
prevNextCard(false);
110+
navigateToAdjacentCard(AdjacentCardDirection.PREVIOUS);
106111
}
107112
return true;
108113
} else if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {
109114
if (initTime < (System.currentTimeMillis() - 1000)) {
110-
prevNextCard(true);
115+
navigateToAdjacentCard(AdjacentCardDirection.NEXT);
111116
}
112117
return true;
113118
}
@@ -137,6 +142,8 @@ private void openImageInGallery(LoyaltyCardImageType imageType) {
137142
File file = null;
138143

139144
switch (imageType) {
145+
case NONE:
146+
return;
140147
case ICON:
141148
file = Utils.retrieveCardImageAsFile(this, loyaltyCardId, ImageLocationType.icon);
142149
break;
@@ -150,6 +157,7 @@ private void openImageInGallery(LoyaltyCardImageType imageType) {
150157
Toast.makeText(this, R.string.barcodeLongPressMessage, Toast.LENGTH_SHORT).show();
151158
return;
152159
default:
160+
throw new IllegalArgumentException("Unknown image type: " + imageType);
153161
}
154162

155163
if (file == null) {
@@ -173,7 +181,6 @@ public void onBarcodeImageWriterResult(boolean success) {
173181
if (!success) {
174182
// If barcode rendering fails, drop that slot so the user falls back to working content.
175183
cardNavigator.remove(LoyaltyCardImageType.BARCODE);
176-
pendingImageIndex = cardNavigator.getCurrentIndex();
177184

178185
setStateBasedOnImageTypes();
179186

@@ -238,7 +245,7 @@ protected void onCreate(Bundle savedInstanceState) {
238245
settings = new Settings(this);
239246

240247
if (savedInstanceState != null) {
241-
pendingImageIndex = savedInstanceState.getInt(STATE_IMAGEINDEX, 0);
248+
restoredImageIndex = savedInstanceState.getInt(STATE_IMAGEINDEX, 0);
242249
isFullscreen = savedInstanceState.getBoolean(STATE_FULLSCREEN);
243250
}
244251

@@ -268,8 +275,12 @@ protected void onCreate(Bundle savedInstanceState) {
268275
binding.bottomAppBarInfoButton.setOnClickListener(view ->
269276
dialogs.showInfoDialog(this, loyaltyCard, loyaltyCardGroups)
270277
);
271-
binding.bottomAppBarPreviousButton.setOnClickListener(view -> prevNextCard(false));
272-
binding.bottomAppBarNextButton.setOnClickListener(view -> prevNextCard(true));
278+
binding.bottomAppBarPreviousButton.setOnClickListener(view ->
279+
navigateToAdjacentCard(AdjacentCardDirection.PREVIOUS)
280+
);
281+
binding.bottomAppBarNextButton.setOnClickListener(view ->
282+
navigateToAdjacentCard(AdjacentCardDirection.NEXT)
283+
);
273284
binding.bottomAppBarUpdateBalanceButton.setOnClickListener(view ->
274285
dialogs.showBalanceUpdateDialog(this, loyaltyCard, newBalance -> {
275286
DBHelper.updateLoyaltyCardBalance(database, loyaltyCardId, newBalance);
@@ -379,11 +390,12 @@ private void setBottomAppBarButtonState() {
379390
binding.bottomAppBarUpdateBalanceButton.setVisibility(hasBalance(loyaltyCard) ? View.VISIBLE : View.GONE);
380391
}
381392

382-
private void prevNextCard(boolean next) {
393+
private void navigateToAdjacentCard(AdjacentCardDirection direction) {
383394
if (cardList == null || cardList.size() == 1) {
384395
return;
385396
}
386397

398+
boolean next = direction == AdjacentCardDirection.NEXT;
387399
boolean transitionRight = next;
388400
if (getResources().getConfiguration().getLayoutDirection() == View.LAYOUT_DIRECTION_RTL) {
389401
next = !next;
@@ -626,9 +638,12 @@ private LoyaltyCardImageNavigator createCardNavigator(boolean isBarcodeSupported
626638
}
627639

628640
// Card edits may remove barcode/front/back images, so keep the previously selected index in range.
641+
int initialIndex = cardNavigator.isEmpty()
642+
? (restoredImageIndex != null ? restoredImageIndex : 0)
643+
: cardNavigator.getCurrentIndex();
629644
LoyaltyCardImageNavigator navigator =
630-
new LoyaltyCardImageNavigator(availableImageTypes, cardNavigator.isEmpty() ? pendingImageIndex : cardNavigator.getCurrentIndex());
631-
pendingImageIndex = navigator.getCurrentIndex();
645+
new LoyaltyCardImageNavigator(availableImageTypes, initialIndex);
646+
restoredImageIndex = null;
632647
return navigator;
633648
}
634649

@@ -792,8 +807,6 @@ private void setMainImage(boolean next, boolean overflow) {
792807
return;
793808
}
794809

795-
pendingImageIndex = cardNavigator.getCurrentIndex();
796-
797810
renderCurrentMainImage(false);
798811

799812
updateMainImageUiState();

app/src/test/java/protect/card_locker/LoyaltyCardViewActivityTest.java

Lines changed: 84 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -436,95 +436,95 @@ public void noDataLossOnResumeOrRotate() {
436436
Integer cardId;
437437

438438
for (boolean newCard : new boolean[]{false, true}) {
439-
System.out.println();
440-
System.out.println("=====");
441-
System.out.println("New card? " + newCard);
442-
System.out.println("=====");
443-
System.out.println();
444-
445-
if (!newCard) {
446-
cardId = (int) DBHelper.insertLoyaltyCard(database, "store", "note", null, null, new BigDecimal("0"), null, EAN_BARCODE_DATA, null, EAN_BARCODE_TYPE, StandardCharsets.UTF_8, Color.BLACK, 0, null, 0);
447-
} else {
448-
cardId = null;
449-
}
439+
System.out.println();
440+
System.out.println("=====");
441+
System.out.println("New card? " + newCard);
442+
System.out.println("=====");
443+
System.out.println();
444+
445+
if (!newCard) {
446+
cardId = (int) DBHelper.insertLoyaltyCard(database, "store", "note", null, null, new BigDecimal("0"), null, EAN_BARCODE_DATA, null, EAN_BARCODE_TYPE, StandardCharsets.UTF_8, Color.BLACK, 0, null, 0);
447+
} else {
448+
cardId = null;
449+
}
450450

451-
ActivityController activityController = createActivityWithLoyaltyCard(true, cardId);
452-
LoyaltyCardEditActivity activity = (LoyaltyCardEditActivity) activityController.get();
451+
ActivityController activityController = createActivityWithLoyaltyCard(true, cardId);
452+
LoyaltyCardEditActivity activity = (LoyaltyCardEditActivity) activityController.get();
453453

454-
activityController.start();
455-
activityController.visible();
456-
activityController.resume();
454+
activityController.start();
455+
activityController.visible();
456+
activityController.resume();
457457

458-
shadowOf(getMainLooper()).idle();
458+
shadowOf(getMainLooper()).idle();
459459

460-
// Check default settings
461-
checkAllFields(activity, newCard ? ViewMode.ADD_CARD : ViewMode.UPDATE_CARD, newCard ? "" : "store", newCard ? "" : "note", context.getString(R.string.anyDate), context.getString(R.string.never), "0", context.getString(R.string.points), newCard ? "" : EAN_BARCODE_DATA, context.getString(R.string.sameAsCardId), newCard ? context.getString(R.string.noBarcode) : EAN_BARCODE_TYPE.prettyName(), newCard ? "ISO-8859-1" : "UTF-8", null, null);
460+
// Check default settings
461+
checkAllFields(activity, newCard ? ViewMode.ADD_CARD : ViewMode.UPDATE_CARD, newCard ? "" : "store", newCard ? "" : "note", context.getString(R.string.anyDate), context.getString(R.string.never), "0", context.getString(R.string.points), newCard ? "" : EAN_BARCODE_DATA, context.getString(R.string.sameAsCardId), newCard ? context.getString(R.string.noBarcode) : EAN_BARCODE_TYPE.prettyName(), newCard ? "ISO-8859-1" : "UTF-8", null, null);
462+
463+
// Change everything
464+
final EditText storeField = activity.findViewById(R.id.storeNameEdit);
465+
final EditText noteField = activity.findViewById(R.id.noteEdit);
466+
final EditText validFromField = activity.findViewById(R.id.validFromField);
467+
final EditText expiryField = activity.findViewById(R.id.expiryField);
468+
final EditText balanceField = activity.findViewById(R.id.balanceField);
469+
final EditText balanceTypeField = activity.findViewById(R.id.balanceCurrencyField);
470+
final EditText cardIdField = activity.findViewById(R.id.cardIdView);
471+
final EditText barcodeField = activity.findViewById(R.id.barcodeIdField);
472+
final EditText barcodeTypeField = activity.findViewById(R.id.barcodeTypeField);
473+
final EditText barcodeEncodingField = activity.findViewById(R.id.barcodeEncodingField);
474+
final ImageView frontImageView = activity.findViewById(R.id.frontImage);
475+
final ImageView backImageView = activity.findViewById(R.id.backImage);
476+
477+
Currency currency = Currency.getInstance("EUR");
478+
Date validFromDate = Date.from(Instant.now().minus(20, ChronoUnit.DAYS));
479+
Date expiryDate = new Date();
480+
Bitmap frontBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.circle);
481+
Bitmap backBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_done);
482+
483+
storeField.setText("correct store");
484+
noteField.setText("correct note");
485+
LoyaltyCardEditActivity.formatDateField(context, validFromField, validFromDate);
486+
activity.setLoyaltyCardValidFrom(validFromDate);
487+
LoyaltyCardEditActivity.formatDateField(context, expiryField, expiryDate);
488+
activity.setLoyaltyCardExpiry(expiryDate);
489+
balanceField.setText("100");
490+
balanceTypeField.setText(currency.getSymbol());
491+
cardIdField.setText("12345678");
492+
barcodeField.setText("87654321");
493+
barcodeTypeField.setText(CatimaBarcode.fromBarcode(BarcodeFormat.QR_CODE).prettyName());
494+
barcodeEncodingField.setText(StandardCharsets.ISO_8859_1.name());
495+
activity.setCardImage(ImageLocationType.front, frontImageView, frontBitmap, true);
496+
activity.setCardImage(ImageLocationType.back, backImageView, backBitmap, true);
462497

463-
// Change everything
464-
final EditText storeField = activity.findViewById(R.id.storeNameEdit);
465-
final EditText noteField = activity.findViewById(R.id.noteEdit);
466-
final EditText validFromField = activity.findViewById(R.id.validFromField);
467-
final EditText expiryField = activity.findViewById(R.id.expiryField);
468-
final EditText balanceField = activity.findViewById(R.id.balanceField);
469-
final EditText balanceTypeField = activity.findViewById(R.id.balanceCurrencyField);
470-
final EditText cardIdField = activity.findViewById(R.id.cardIdView);
471-
final EditText barcodeField = activity.findViewById(R.id.barcodeIdField);
472-
final EditText barcodeTypeField = activity.findViewById(R.id.barcodeTypeField);
473-
final EditText barcodeEncodingField = activity.findViewById(R.id.barcodeEncodingField);
474-
final ImageView frontImageView = activity.findViewById(R.id.frontImage);
475-
final ImageView backImageView = activity.findViewById(R.id.backImage);
476-
477-
Currency currency = Currency.getInstance("EUR");
478-
Date validFromDate = Date.from(Instant.now().minus(20, ChronoUnit.DAYS));
479-
Date expiryDate = new Date();
480-
Bitmap frontBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.circle);
481-
Bitmap backBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_done);
482-
483-
storeField.setText("correct store");
484-
noteField.setText("correct note");
485-
LoyaltyCardEditActivity.formatDateField(context, validFromField, validFromDate);
486-
activity.setLoyaltyCardValidFrom(validFromDate);
487-
LoyaltyCardEditActivity.formatDateField(context, expiryField, expiryDate);
488-
activity.setLoyaltyCardExpiry(expiryDate);
489-
balanceField.setText("100");
490-
balanceTypeField.setText(currency.getSymbol());
491-
cardIdField.setText("12345678");
492-
barcodeField.setText("87654321");
493-
barcodeTypeField.setText(CatimaBarcode.fromBarcode(BarcodeFormat.QR_CODE).prettyName());
494-
barcodeEncodingField.setText(StandardCharsets.ISO_8859_1.name());
495-
activity.setCardImage(ImageLocationType.front, frontImageView, frontBitmap, true);
496-
activity.setCardImage(ImageLocationType.back, backImageView, backBitmap, true);
497-
498-
shadowOf(getMainLooper()).idle();
499-
500-
// Check if changed
501-
checkAllFields(activity, newCard ? ViewMode.ADD_CARD : ViewMode.UPDATE_CARD, "correct store", "correct note", DateFormat.getDateInstance(DateFormat.LONG).format(validFromDate), DateFormat.getDateInstance(DateFormat.LONG).format(expiryDate), "100.00", currency.getSymbol(), "12345678", "87654321", CatimaBarcode.fromBarcode(BarcodeFormat.QR_CODE).prettyName(), StandardCharsets.ISO_8859_1.name(), frontBitmap, backBitmap);
502-
503-
// Resume
504-
activityController.pause();
505-
activityController.resume();
506-
507-
shadowOf(getMainLooper()).idle();
508-
509-
// Check if no changes lost
510-
checkAllFields(activity, newCard ? ViewMode.ADD_CARD : ViewMode.UPDATE_CARD, "correct store", "correct note", DateFormat.getDateInstance(DateFormat.LONG).format(validFromDate), DateFormat.getDateInstance(DateFormat.LONG).format(expiryDate), "100.00", currency.getSymbol(), "12345678", "87654321", CatimaBarcode.fromBarcode(BarcodeFormat.QR_CODE).prettyName(), StandardCharsets.ISO_8859_1.name(), frontBitmap, backBitmap);
511-
512-
// Rotate to landscape
513-
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
514-
activity.recreate();
515-
shadowOf(getMainLooper()).idle();
516-
517-
// Check if no changes lost
518-
checkAllFields(activity, newCard ? ViewMode.ADD_CARD : ViewMode.UPDATE_CARD, "correct store", "correct note", DateFormat.getDateInstance(DateFormat.LONG).format(validFromDate), DateFormat.getDateInstance(DateFormat.LONG).format(expiryDate), "100.00", currency.getSymbol(), "12345678", "87654321", CatimaBarcode.fromBarcode(BarcodeFormat.QR_CODE).prettyName(), StandardCharsets.ISO_8859_1.name(), frontBitmap, backBitmap);
519-
520-
// Rotate to portrait
521-
shadowOf(getMainLooper()).idle();
522-
activity.recreate();
523-
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
524-
525-
// Check if no changes lost
526-
checkAllFields(activity, newCard ? ViewMode.ADD_CARD : ViewMode.UPDATE_CARD, "correct store", "correct note", DateFormat.getDateInstance(DateFormat.LONG).format(validFromDate), DateFormat.getDateInstance(DateFormat.LONG).format(expiryDate), "100.00", currency.getSymbol(), "12345678", "87654321", CatimaBarcode.fromBarcode(BarcodeFormat.QR_CODE).prettyName(), StandardCharsets.ISO_8859_1.name(), frontBitmap, backBitmap);
527-
}
498+
shadowOf(getMainLooper()).idle();
499+
500+
// Check if changed
501+
checkAllFields(activity, newCard ? ViewMode.ADD_CARD : ViewMode.UPDATE_CARD, "correct store", "correct note", DateFormat.getDateInstance(DateFormat.LONG).format(validFromDate), DateFormat.getDateInstance(DateFormat.LONG).format(expiryDate), "100.00", currency.getSymbol(), "12345678", "87654321", CatimaBarcode.fromBarcode(BarcodeFormat.QR_CODE).prettyName(), StandardCharsets.ISO_8859_1.name(), frontBitmap, backBitmap);
502+
503+
// Resume
504+
activityController.pause();
505+
activityController.resume();
506+
507+
shadowOf(getMainLooper()).idle();
508+
509+
// Check if no changes lost
510+
checkAllFields(activity, newCard ? ViewMode.ADD_CARD : ViewMode.UPDATE_CARD, "correct store", "correct note", DateFormat.getDateInstance(DateFormat.LONG).format(validFromDate), DateFormat.getDateInstance(DateFormat.LONG).format(expiryDate), "100.00", currency.getSymbol(), "12345678", "87654321", CatimaBarcode.fromBarcode(BarcodeFormat.QR_CODE).prettyName(), StandardCharsets.ISO_8859_1.name(), frontBitmap, backBitmap);
511+
512+
// Rotate to landscape
513+
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
514+
activity.recreate();
515+
shadowOf(getMainLooper()).idle();
516+
517+
// Check if no changes lost
518+
checkAllFields(activity, newCard ? ViewMode.ADD_CARD : ViewMode.UPDATE_CARD, "correct store", "correct note", DateFormat.getDateInstance(DateFormat.LONG).format(validFromDate), DateFormat.getDateInstance(DateFormat.LONG).format(expiryDate), "100.00", currency.getSymbol(), "12345678", "87654321", CatimaBarcode.fromBarcode(BarcodeFormat.QR_CODE).prettyName(), StandardCharsets.ISO_8859_1.name(), frontBitmap, backBitmap);
519+
520+
// Rotate to portrait
521+
shadowOf(getMainLooper()).idle();
522+
activity.recreate();
523+
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
524+
525+
// Check if no changes lost
526+
checkAllFields(activity, newCard ? ViewMode.ADD_CARD : ViewMode.UPDATE_CARD, "correct store", "correct note", DateFormat.getDateInstance(DateFormat.LONG).format(validFromDate), DateFormat.getDateInstance(DateFormat.LONG).format(expiryDate), "100.00", currency.getSymbol(), "12345678", "87654321", CatimaBarcode.fromBarcode(BarcodeFormat.QR_CODE).prettyName(), StandardCharsets.ISO_8859_1.name(), frontBitmap, backBitmap);
527+
}
528528
} finally {
529529
database.close();
530530
}

0 commit comments

Comments
 (0)