diff --git a/app/build.gradle b/app/build.gradle index 5a14cdd49..81e8c2684 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -83,6 +83,7 @@ dependencies { implementation 'androidx.appcompat:appcompat:1.3.1' implementation 'androidx.constraintlayout:constraintlayout:2.1.1' implementation 'androidx.exifinterface:exifinterface:1.3.3' + implementation 'androidx.palette:palette:1.0.0' implementation 'androidx.preference:preference:1.1.1' implementation 'com.google.android.material:material:1.4.0' implementation 'com.github.yalantis:ucrop:2.2.6' diff --git a/app/src/main/java/protect/card_locker/DBHelper.java b/app/src/main/java/protect/card_locker/DBHelper.java index eba29d9f1..6b9aa515d 100644 --- a/app/src/main/java/protect/card_locker/DBHelper.java +++ b/app/src/main/java/protect/card_locker/DBHelper.java @@ -601,11 +601,12 @@ public class DBHelper extends SQLiteOpenHelper { withArgs(id)); // Also wipe card images associated with this card - try { - Utils.saveCardImage(mContext, null, id, true); - Utils.saveCardImage(mContext, null, id, false); - } catch (FileNotFoundException e) { - e.printStackTrace(); + for (ImageLocationType imageLocationType : ImageLocationType.values()) { + try { + Utils.saveCardImage(mContext, null, id, imageLocationType); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } } return (rowsDeleted == 1); diff --git a/app/src/main/java/protect/card_locker/ImageLocationType.java b/app/src/main/java/protect/card_locker/ImageLocationType.java new file mode 100644 index 000000000..457a03bdd --- /dev/null +++ b/app/src/main/java/protect/card_locker/ImageLocationType.java @@ -0,0 +1,7 @@ +package protect.card_locker; + +public enum ImageLocationType { + front, + back, + icon +} diff --git a/app/src/main/java/protect/card_locker/LoyaltyCardCursorAdapter.java b/app/src/main/java/protect/card_locker/LoyaltyCardCursorAdapter.java index 413028ee1..4f08c1250 100644 --- a/app/src/main/java/protect/card_locker/LoyaltyCardCursorAdapter.java +++ b/app/src/main/java/protect/card_locker/LoyaltyCardCursorAdapter.java @@ -3,6 +3,7 @@ package protect.card_locker; import android.content.Context; import android.content.res.Resources; import android.database.Cursor; +import android.graphics.Bitmap; import android.graphics.Color; import android.graphics.drawable.Drawable; import android.util.SparseBooleanArray; @@ -125,8 +126,18 @@ public class LoyaltyCardCursorAdapter extends BaseCursorAdapter { + if (palette != null) { + updateTempState(LoyaltyCardField.headerColor, palette.getDominantColor(tempLoyaltyCard.headerColor != null ? tempLoyaltyCard.headerColor : getResources().getColor(R.color.colorPrimary))); + } + }); + } else if (applyFallback) { imageView.setImageResource(R.drawable.ic_camera_white); } } @@ -895,8 +945,10 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity { try { if (requestCode == PERMISSION_REQUEST_CAMERA_IMAGE_FRONT) { takePhotoForCard(Utils.CARD_IMAGE_FROM_CAMERA_FRONT); - } else { + } else if (requestCode == PERMISSION_REQUEST_CAMERA_IMAGE_BACK) { takePhotoForCard(Utils.CARD_IMAGE_FROM_CAMERA_BACK); + } else if (requestCode == PERMISSION_REQUEST_CAMERA_IMAGE_ICON) { + takePhotoForCard(Utils.CARD_IMAGE_FROM_CAMERA_ICON); } } catch (Exception e) { e.printStackTrace(); @@ -925,9 +977,7 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity { dialog.dismiss(); }) - .setNegativeButton(R.string.no, (dialog, which) -> { - dialog.dismiss(); - }) + .setNegativeButton(R.string.no, (dialog, which) -> dialog.dismiss()) .setOnDismissListener(dialogInterface -> { if (tempStoredOldBarcodeValue != null) { barcodeIdField.setText(tempStoredOldBarcodeValue); @@ -956,26 +1006,18 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle(R.string.leaveWithoutSaveTitle); builder.setMessage(R.string.leaveWithoutSaveConfirmation); - builder.setPositiveButton(R.string.confirm, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - finish(); - dialog.dismiss(); - } - }); - builder.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - dialog.dismiss(); - } + builder.setPositiveButton(R.string.confirm, (dialog, which) -> { + finish(); + dialog.dismiss(); }); + builder.setNegativeButton(R.string.cancel, (dialog, which) -> dialog.dismiss()); confirmExitDialog = builder.create(); } confirmExitDialog.show(); } - private void takePhotoForCard(int type) throws IOException { + private void takePhotoForCard(int type) { Uri photoURI = FileProvider.getUriForFile(LoyaltyCardEditActivity.this, BuildConfig.APPLICATION_ID, Utils.createTempFile(this, TEMP_CAMERA_IMAGE_NAME)); mRequestedImage = type; @@ -995,13 +1037,23 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity { class ChooseCardImage implements View.OnClickListener { @Override - public void onClick(View v) throws NoSuchElementException { - ImageView targetView = v.getId() == ID_IMAGE_FRONT ? cardImageFront : cardImageBack; + public void onClick(View v) throws NoSuchElementException + { + ImageView targetView; + + if (v.getId() == R.id.frontImageHolder) { + targetView = cardImageFront; + } else if (v.getId() == R.id.backImageHolder) { + targetView = cardImageBack; + } else if (v.getId() == R.id.thumbnail) { + targetView = thumbnail; + } else { + throw new IllegalArgumentException("Invalid IMAGE ID " + v.getId()); + } LinkedHashMap> cardOptions = new LinkedHashMap<>(); - if (targetView.getTag() != null) { + if (targetView.getTag() != null && v.getId() != R.id.thumbnail) { cardOptions.put(getString(R.string.removeImage), () -> { - setCardImage(targetView, null); if (targetView == cardImageFront) { mFrontImageRemoved = true; mFrontImageUnsaved = false; @@ -1009,29 +1061,114 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity { mBackImageRemoved = true; mBackImageUnsaved = false; } + + setCardImage(targetView, null, true); + return null; + }); + } + + if (v.getId() == R.id.thumbnail) { + cardOptions.put(getString(R.string.selectColor), () -> { + ColorPickerDialog.Builder dialogBuilder = ColorPickerDialog.newBuilder(); + + if (tempLoyaltyCard.headerColor != null) { + dialogBuilder.setColor(tempLoyaltyCard.headerColor); + } + + ColorPickerDialog dialog = dialogBuilder.create(); + dialog.setColorPickerDialogListener(new ColorPickerDialogListener() + { + @Override + public void onColorSelected(int dialogId, int color) + { + updateTempState(LoyaltyCardField.headerColor, color); + + // Unset image if set + thumbnail.setTag(null); + + generateIcon(storeFieldEdit.getText().toString()); + } + + @Override + public void onDialogDismissed(int dialogId) + { + // Nothing to do, no change made + } + }); + dialog.show(getSupportFragmentManager(), "color-picker-dialog"); + + setCardImage(targetView, null, false); + mIconRemoved = true; + mIconUnsaved = false; + return null; }); } cardOptions.put(getString(R.string.takePhoto), () -> { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - requestPermissions(new String[]{Manifest.permission.CAMERA}, v.getId() == ID_IMAGE_FRONT ? PERMISSION_REQUEST_CAMERA_IMAGE_FRONT : PERMISSION_REQUEST_CAMERA_IMAGE_BACK); + int permissionRequestType; + + if (v.getId() == R.id.frontImageHolder) { + permissionRequestType = PERMISSION_REQUEST_CAMERA_IMAGE_FRONT; + } else if (v.getId() == R.id.backImageHolder) { + permissionRequestType = PERMISSION_REQUEST_CAMERA_IMAGE_BACK; + } else if (v.getId() == R.id.thumbnail) { + permissionRequestType = PERMISSION_REQUEST_CAMERA_IMAGE_ICON; + } else { + throw new IllegalArgumentException("Unknown ID type " + v.getId()); + } + + requestPermissions(new String[]{Manifest.permission.CAMERA}, permissionRequestType); } else { - takePhotoForCard(v.getId() == ID_IMAGE_FRONT ? Utils.CARD_IMAGE_FROM_CAMERA_FRONT : Utils.CARD_IMAGE_FROM_CAMERA_BACK); + int cardImageType; + + if (v.getId() == R.id.frontImageHolder) { + cardImageType = Utils.CARD_IMAGE_FROM_CAMERA_FRONT; + } else if (v.getId() == R.id.backImageHolder) { + cardImageType = Utils.CARD_IMAGE_FROM_CAMERA_BACK; + } else if (v.getId() == R.id.thumbnail) { + cardImageType = Utils.CARD_IMAGE_FROM_CAMERA_ICON; + } else { + throw new IllegalArgumentException("Unknown ID type " + v.getId()); + } + + takePhotoForCard(cardImageType); } return null; }); cardOptions.put(getString(R.string.addFromImage), () -> { + if (v.getId() == R.id.frontImageHolder) { + mRequestedImage = Utils.CARD_IMAGE_FROM_FILE_FRONT; + } else if (v.getId() == R.id.backImageHolder) { + mRequestedImage = Utils.CARD_IMAGE_FROM_FILE_BACK; + } else if (v.getId() == R.id.thumbnail) { + mRequestedImage = Utils.CARD_IMAGE_FROM_FILE_ICON; + } else { + throw new IllegalArgumentException("Unknown ID type " + v.getId()); + } + Intent i = new Intent(Intent.ACTION_PICK); i.setType("image/*"); - mRequestedImage = v.getId() == ID_IMAGE_FRONT ? Utils.CARD_IMAGE_FROM_FILE_FRONT : Utils.CARD_IMAGE_FROM_FILE_BACK; mPhotoPickerLauncher.launch(i); return null; }); + int titleResource; + + if (v.getId() == R.id.frontImageHolder) { + titleResource = R.string.setFrontImage; + } else if (v.getId() == R.id.backImageHolder) { + titleResource = R.string.setBackImage; + } else if (v.getId() == R.id.thumbnail) { + titleResource = R.string.setIcon; + } else { + throw new IllegalArgumentException("Unknown ID type " + v.getId()); + } + new AlertDialog.Builder(LoyaltyCardEditActivity.this) - .setTitle(v.getId() == ID_IMAGE_FRONT ? getString(R.string.setFrontImage) : getString(R.string.setBackImage)) + .setTitle(getString(titleResource)) .setItems(cardOptions.keySet().toArray(new CharSequence[cardOptions.size()]), (dialog, which) -> { Iterator> callables = cardOptions.values().iterator(); Callable callable = callables.next(); @@ -1050,33 +1187,6 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity { } } - class ColorSelectListener implements View.OnClickListener { - @Override - public void onClick(View v) { - ColorPickerDialog.Builder dialogBuilder = ColorPickerDialog.newBuilder(); - - if (tempLoyaltyCard.headerColor != null) { - dialogBuilder.setColor(tempLoyaltyCard.headerColor); - } - - ColorPickerDialog dialog = dialogBuilder.create(); - dialog.setColorPickerDialogListener(new ColorPickerDialogListener() { - @Override - public void onColorSelected(int dialogId, int color) { - updateTempState(LoyaltyCardField.headerColor, color); - - generateIcon(storeFieldEdit.getText().toString()); - } - - @Override - public void onDialogDismissed(int dialogId) { - // Nothing to do, no change made - } - }); - dialog.show(getSupportFragmentManager(), "color-picker-dialog"); - } - } - public static class DatePickerFragment extends DialogFragment implements DatePickerDialog.OnDateSetListener { @@ -1088,6 +1198,7 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity { this.expiryFieldEdit = expiryFieldEdit; } + @NonNull @Override public Dialog onCreateDialog(Bundle savedInstanceState) { // Use the current date as the default date in the picker @@ -1155,8 +1266,9 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity { if (updateLoyaltyCard) { //update of "starStatus" not necessary, since it cannot be changed in this activity (only in ViewActivity) db.updateLoyaltyCard(loyaltyCardId, tempLoyaltyCard.store, tempLoyaltyCard.note, tempLoyaltyCard.expiry, tempLoyaltyCard.balance, tempLoyaltyCard.balanceType, tempLoyaltyCard.cardId, tempLoyaltyCard.barcodeId, tempLoyaltyCard.barcodeType, tempLoyaltyCard.headerColor); try { - Utils.saveCardImage(this, (Bitmap) cardImageFront.getTag(), loyaltyCardId, true); - Utils.saveCardImage(this, (Bitmap) cardImageBack.getTag(), loyaltyCardId, false); + Utils.saveCardImage(this, (Bitmap) cardImageFront.getTag(), loyaltyCardId, ImageLocationType.front); + Utils.saveCardImage(this, (Bitmap) cardImageBack.getTag(), loyaltyCardId, ImageLocationType.back); + Utils.saveCardImage(this, (Bitmap) thumbnail.getTag(), loyaltyCardId, ImageLocationType.icon); } catch (FileNotFoundException e) { e.printStackTrace(); } @@ -1164,8 +1276,9 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity { } else { loyaltyCardId = (int) db.insertLoyaltyCard(tempLoyaltyCard.store, tempLoyaltyCard.note, tempLoyaltyCard.expiry, tempLoyaltyCard.balance, tempLoyaltyCard.balanceType, tempLoyaltyCard.cardId, tempLoyaltyCard.barcodeId, tempLoyaltyCard.barcodeType, tempLoyaltyCard.headerColor, 0, tempLoyaltyCard.lastUsed); try { - Utils.saveCardImage(this, (Bitmap) cardImageFront.getTag(), loyaltyCardId, true); - Utils.saveCardImage(this, (Bitmap) cardImageBack.getTag(), loyaltyCardId, false); + Utils.saveCardImage(this, (Bitmap) cardImageFront.getTag(), loyaltyCardId, ImageLocationType.front); + Utils.saveCardImage(this, (Bitmap) cardImageBack.getTag(), loyaltyCardId, ImageLocationType.back); + Utils.saveCardImage(this, (Bitmap) thumbnail.getTag(), loyaltyCardId, ImageLocationType.icon); } catch (FileNotFoundException e) { e.printStackTrace(); } @@ -1233,8 +1346,10 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity { if (mRequestedImage == Utils.CARD_IMAGE_FROM_CAMERA_FRONT || mRequestedImage == Utils.CARD_IMAGE_FROM_FILE_FRONT) { mCropperOptions.setToolbarTitle(getResources().getString(R.string.setFrontImage)); - } else { + } else if (mRequestedImage == Utils.CARD_IMAGE_FROM_CAMERA_BACK || mRequestedImage == Utils.CARD_IMAGE_FROM_FILE_BACK) { mCropperOptions.setToolbarTitle(getResources().getString(R.string.setBackImage)); + } else { + mCropperOptions.setToolbarTitle(getResources().getString(R.string.setIcon)); } // sniff the input image for width and height to work around a ucrop bug @@ -1270,7 +1385,6 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity { ).withOptions(mCropperOptions) .getIntent(this) ); - return; } private void showBarcode() { @@ -1324,14 +1438,16 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity { return; } - thumbnail.setBackgroundColor(tempLoyaltyCard.headerColor); + if (thumbnail.getTag() == null) { + thumbnail.setBackgroundColor(tempLoyaltyCard.headerColor); - LetterBitmap letterBitmap = Utils.generateIcon(this, store, tempLoyaltyCard.headerColor); + LetterBitmap letterBitmap = Utils.generateIcon(this, store, tempLoyaltyCard.headerColor); - if (letterBitmap != null) { - thumbnail.setImageBitmap(letterBitmap.getLetterTile()); - } else { - thumbnail.setImageBitmap(null); + if (letterBitmap != null) { + thumbnail.setImageBitmap(letterBitmap.getLetterTile()); + } else { + thumbnail.setImageBitmap(null); + } } thumbnail.setMinimumWidth(thumbnail.getHeight()); diff --git a/app/src/main/java/protect/card_locker/LoyaltyCardViewActivity.java b/app/src/main/java/protect/card_locker/LoyaltyCardViewActivity.java index 15c0c26b9..f6e3ecfa6 100644 --- a/app/src/main/java/protect/card_locker/LoyaltyCardViewActivity.java +++ b/app/src/main/java/protect/card_locker/LoyaltyCardViewActivity.java @@ -543,13 +543,12 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements imageTypes.add(ImageType.BARCODE); } - frontImageBitmap = Utils.retrieveCardImage(this, loyaltyCard.id, true); - backImageBitmap = Utils.retrieveCardImage(this, loyaltyCard.id, false); - + frontImageBitmap = Utils.retrieveCardImage(this, loyaltyCard.id, ImageLocationType.front); if (frontImageBitmap != null) { imageTypes.add(ImageType.IMAGE_FRONT); } + backImageBitmap = Utils.retrieveCardImage(this, loyaltyCard.id, ImageLocationType.back); if (backImageBitmap != null) { imageTypes.add(ImageType.IMAGE_BACK); } diff --git a/app/src/main/java/protect/card_locker/ShortcutHelper.java b/app/src/main/java/protect/card_locker/ShortcutHelper.java index 8c3ae2e53..beada64d3 100644 --- a/app/src/main/java/protect/card_locker/ShortcutHelper.java +++ b/app/src/main/java/protect/card_locker/ShortcutHelper.java @@ -117,7 +117,10 @@ class ShortcutHelper { bundle.putBoolean("view", true); intent.putExtras(bundle); - Bitmap iconBitmap = Utils.generateIcon(context, loyaltyCard, true).getLetterTile(); + Bitmap iconBitmap = Utils.retrieveCardImage(context, loyaltyCard.id, ImageLocationType.icon); + if (iconBitmap == null) { + iconBitmap = Utils.generateIcon(context, loyaltyCard, true).getLetterTile(); + } IconCompat icon = IconCompat.createWithAdaptiveBitmap(iconBitmap); diff --git a/app/src/main/java/protect/card_locker/Utils.java b/app/src/main/java/protect/card_locker/Utils.java index 51fb34fa0..6c3d0680f 100644 --- a/app/src/main/java/protect/card_locker/Utils.java +++ b/app/src/main/java/protect/card_locker/Utils.java @@ -54,11 +54,14 @@ public class Utils { public static final int BARCODE_IMPORT_FROM_IMAGE_FILE = 4; public static final int CARD_IMAGE_FROM_CAMERA_FRONT = 5; public static final int CARD_IMAGE_FROM_CAMERA_BACK = 6; - public static final int CARD_IMAGE_FROM_FILE_FRONT = 7; - public static final int CARD_IMAGE_FROM_FILE_BACK = 8; + public static final int CARD_IMAGE_FROM_CAMERA_ICON = 7; + public static final int CARD_IMAGE_FROM_FILE_FRONT = 8; + public static final int CARD_IMAGE_FROM_FILE_BACK = 9; + public static final int CARD_IMAGE_FROM_FILE_ICON = 10; static final double LUMINANCE_MIDPOINT = 0.5; + static final int BITMAP_SIZE_SMALL = 64; static final int BITMAP_SIZE_BIG = 512; static public LetterBitmap generateIcon(Context context, LoyaltyCard loyaltyCard, boolean forShortcut) { @@ -266,13 +269,11 @@ public class Utils { return bos.toByteArray(); } - static public Bitmap resizeBitmap(Bitmap bitmap) { + static public Bitmap resizeBitmap(Bitmap bitmap, double maxSize) { if (bitmap == null) { return null; } - double maxSize = BITMAP_SIZE_BIG; - double width = bitmap.getWidth(); double height = bitmap.getHeight(); @@ -315,16 +316,20 @@ public class Utils { return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); } - static public String getCardImageFileName(int loyaltyCardId, boolean front) { + static public String getCardImageFileName(int loyaltyCardId, ImageLocationType type) { StringBuilder cardImageFileNameBuilder = new StringBuilder(); cardImageFileNameBuilder.append("card_"); cardImageFileNameBuilder.append(loyaltyCardId); cardImageFileNameBuilder.append("_"); - if (front) { + if (type == ImageLocationType.front) { cardImageFileNameBuilder.append("front"); - } else { + } else if (type == ImageLocationType.back) { cardImageFileNameBuilder.append("back"); + } else if (type == ImageLocationType.icon) { + cardImageFileNameBuilder.append("icon"); + } else { + throw new IllegalArgumentException("Unknown image type"); } cardImageFileNameBuilder.append(".png"); @@ -342,8 +347,8 @@ public class Utils { bitmap.compress(Bitmap.CompressFormat.PNG, 100, out); } - static public void saveCardImage(Context context, Bitmap bitmap, int loyaltyCardId, boolean front) throws FileNotFoundException { - saveCardImage(context, bitmap, getCardImageFileName(loyaltyCardId, front)); + static public void saveCardImage(Context context, Bitmap bitmap, int loyaltyCardId, ImageLocationType type) throws FileNotFoundException { + saveCardImage(context, bitmap, getCardImageFileName(loyaltyCardId, type)); } static public Bitmap retrieveCardImage(Context context, String fileName) { @@ -357,8 +362,8 @@ public class Utils { return BitmapFactory.decodeStream(in); } - static public Bitmap retrieveCardImage(Context context, int loyaltyCardId, boolean front) { - return retrieveCardImage(context, getCardImageFileName(loyaltyCardId, front)); + static public Bitmap retrieveCardImage(Context context, int loyaltyCardId, ImageLocationType type) { + return retrieveCardImage(context, getCardImageFileName(loyaltyCardId, type)); } static public U mapGetOrDefault(Map map, T key, U defaultValue) { diff --git a/app/src/main/java/protect/card_locker/importexport/CatimaExporter.java b/app/src/main/java/protect/card_locker/importexport/CatimaExporter.java index 060a93e50..ace6068b2 100644 --- a/app/src/main/java/protect/card_locker/importexport/CatimaExporter.java +++ b/app/src/main/java/protect/card_locker/importexport/CatimaExporter.java @@ -22,6 +22,7 @@ import java.nio.charset.StandardCharsets; import protect.card_locker.DBHelper; import protect.card_locker.Group; +import protect.card_locker.ImageLocationType; import protect.card_locker.LoyaltyCard; import protect.card_locker.Utils; @@ -64,17 +65,12 @@ public class CatimaExporter implements Exporter { // For each card LoyaltyCard card = LoyaltyCard.toLoyaltyCard(cardCursor); - // Prepare looping over both front and back image - boolean[] frontValues = new boolean[2]; - frontValues[0] = true; - frontValues[1] = false; - // For each image - for (boolean front : frontValues) { + for (ImageLocationType imageLocationType : ImageLocationType.values()) { // If it exists, add to the .zip file - Bitmap image = Utils.retrieveCardImage(context, card.id, front); + Bitmap image = Utils.retrieveCardImage(context, card.id, imageLocationType); if (image != null) { - ZipParameters imageZipParameters = createZipParameters(Utils.getCardImageFileName(card.id, front), password); + ZipParameters imageZipParameters = createZipParameters(Utils.getCardImageFileName(card.id, imageLocationType) ,password); zipOutputStream.putNextEntry(imageZipParameters); InputStream imageInputStream = new ByteArrayInputStream(Utils.bitmapToByteArray(image)); while ((readLen = imageInputStream.read(readBuffer)) != -1) { diff --git a/app/src/main/java/protect/card_locker/importexport/StocardImporter.java b/app/src/main/java/protect/card_locker/importexport/StocardImporter.java index 6d46d4045..2f8280285 100644 --- a/app/src/main/java/protect/card_locker/importexport/StocardImporter.java +++ b/app/src/main/java/protect/card_locker/importexport/StocardImporter.java @@ -26,6 +26,7 @@ import java.util.HashMap; import protect.card_locker.CatimaBarcode; import protect.card_locker.DBHelper; import protect.card_locker.FormatException; +import protect.card_locker.ImageLocationType; import protect.card_locker.R; import protect.card_locker.Utils; import protect.card_locker.ZipUtils; @@ -175,10 +176,10 @@ public class StocardImporter implements Importer { long loyaltyCardInternalId = db.insertLoyaltyCard(database, store, note, null, BigDecimal.valueOf(0), null, cardId, null, barcodeType, null, 0, null); if (loyaltyCardData.containsKey("frontImage")) { - Utils.saveCardImage(context, (Bitmap) loyaltyCardData.get("frontImage"), (int) loyaltyCardInternalId, true); + Utils.saveCardImage(context, (Bitmap) loyaltyCardData.get("frontImage"), (int) loyaltyCardInternalId, ImageLocationType.front); } if (loyaltyCardData.containsKey("backImage")) { - Utils.saveCardImage(context, (Bitmap) loyaltyCardData.get("backImage"), (int) loyaltyCardInternalId, false); + Utils.saveCardImage(context, (Bitmap) loyaltyCardData.get("backImage"), (int) loyaltyCardInternalId, ImageLocationType.back); } } diff --git a/app/src/main/res/layout/loyalty_card_edit_activity.xml b/app/src/main/res/layout/loyalty_card_edit_activity.xml index 631eacc70..cbc3e5aa8 100644 --- a/app/src/main/res/layout/loyalty_card_edit_activity.xml +++ b/app/src/main/res/layout/loyalty_card_edit_activity.xml @@ -75,7 +75,9 @@ android:layout_gravity="center_vertical" app:cardCornerRadius="4dp" android:paddingHorizontal="@dimen/inputPadding" - app:cardElevation="0dp"> + app:cardElevation="0dp" + app:cardBackgroundColor="@android:color/transparent" + android:outlineProvider="none"> + app:cardBackgroundColor="@android:color/transparent" + android:outlineProvider="none"> - Language pref_locale System + Select color + Set icon pref_theme_color Theme color Catima diff --git a/app/src/test/java/protect/card_locker/ImportExportTest.java b/app/src/test/java/protect/card_locker/ImportExportTest.java index 48c2d9fdc..cded58db9 100644 --- a/app/src/test/java/protect/card_locker/ImportExportTest.java +++ b/app/src/test/java/protect/card_locker/ImportExportTest.java @@ -894,6 +894,7 @@ public class ImportExportTest { HashMap> loyaltyCardGroups = new HashMap<>(); HashMap loyaltyCardFrontImages = new HashMap<>(); HashMap loyaltyCardBackImages = new HashMap<>(); + HashMap loyaltyCardIconImages = new HashMap<>(); // Create card 1 int loyaltyCardId = (int) db.insertLoyaltyCard("Card 1", "Note 1", new Date(1618053234), new BigDecimal("100"), Currency.getInstance("USD"), "1234", "5432", CatimaBarcode.fromBarcode(BarcodeFormat.QR_CODE), 1, 0, null); @@ -902,10 +903,12 @@ public class ImportExportTest { List groups = Arrays.asList(db.getGroup("One")); db.setLoyaltyCardGroups(loyaltyCardId, groups); loyaltyCardGroups.put(loyaltyCardId, groups); - Utils.saveCardImage(activity.getApplicationContext(), launcherBitmap, loyaltyCardId, true); - Utils.saveCardImage(activity.getApplicationContext(), roundLauncherBitmap, loyaltyCardId, false); + Utils.saveCardImage(activity.getApplicationContext(), launcherBitmap, loyaltyCardId, ImageLocationType.front); + Utils.saveCardImage(activity.getApplicationContext(), roundLauncherBitmap, loyaltyCardId, ImageLocationType.back); + Utils.saveCardImage(activity.getApplicationContext(), launcherBitmap, loyaltyCardId, ImageLocationType.icon); loyaltyCardFrontImages.put(loyaltyCardId, launcherBitmap); loyaltyCardBackImages.put(loyaltyCardId, roundLauncherBitmap); + loyaltyCardIconImages.put(loyaltyCardId, launcherBitmap); // Create card 2 loyaltyCardId = (int) db.insertLoyaltyCard("Card 2", "", null, new BigDecimal(0), null, "123456", null, null, 2, 1, null); @@ -960,8 +963,10 @@ public class ImportExportTest { Bitmap expectedFrontImage = loyaltyCardFrontImages.get(loyaltyCardID); Bitmap expectedBackImage = loyaltyCardBackImages.get(loyaltyCardID); - Bitmap actualFrontImage = Utils.retrieveCardImage(activity.getApplicationContext(), Utils.getCardImageFileName(loyaltyCardID, true)); - Bitmap actualBackImage = Utils.retrieveCardImage(activity.getApplicationContext(), Utils.getCardImageFileName(loyaltyCardID, false)); + Bitmap expectedIconImage = loyaltyCardIconImages.get(loyaltyCardID); + Bitmap actualFrontImage = Utils.retrieveCardImage(activity.getApplicationContext(), Utils.getCardImageFileName(loyaltyCardID, ImageLocationType.front)); + Bitmap actualBackImage = Utils.retrieveCardImage(activity.getApplicationContext(), Utils.getCardImageFileName(loyaltyCardID, ImageLocationType.back)); + Bitmap actualIconImage = Utils.retrieveCardImage(activity.getApplicationContext(), Utils.getCardImageFileName(loyaltyCardID, ImageLocationType.icon)); if (expectedFrontImage != null) { assertTrue(expectedFrontImage.sameAs(actualFrontImage)); @@ -974,6 +979,12 @@ public class ImportExportTest { } else { assertNull(actualBackImage); } + + if (expectedIconImage != null) { + assertTrue(expectedIconImage.sameAs(actualIconImage)); + } else { + assertNull(actualIconImage); + } } } @@ -1041,8 +1052,9 @@ public class ImportExportTest { assertEquals(BarcodeFormat.QR_CODE, card1.barcodeType.format()); assertEquals(1, (long) card1.headerColor); assertEquals(0, card1.starStatus); - assertEquals(null, Utils.retrieveCardImage(activity.getApplicationContext(), card1.id, true)); - assertEquals(null, Utils.retrieveCardImage(activity.getApplicationContext(), card1.id, false)); + assertEquals(null, Utils.retrieveCardImage(activity.getApplicationContext(), card1.id, ImageLocationType.front)); + assertEquals(null, Utils.retrieveCardImage(activity.getApplicationContext(), card1.id, ImageLocationType.back)); + assertEquals(null, Utils.retrieveCardImage(activity.getApplicationContext(), card1.id, ImageLocationType.icon)); LoyaltyCard card8 = db.getLoyaltyCard(8); @@ -1056,8 +1068,9 @@ public class ImportExportTest { assertEquals(null, card8.barcodeType); assertEquals(-5317, (long) card8.headerColor); assertEquals(0, card8.starStatus); - assertEquals(null, Utils.retrieveCardImage(activity.getApplicationContext(), card8.id, true)); - assertEquals(null, Utils.retrieveCardImage(activity.getApplicationContext(), card8.id, false)); + assertEquals(null, Utils.retrieveCardImage(activity.getApplicationContext(), card8.id, ImageLocationType.front)); + assertEquals(null, Utils.retrieveCardImage(activity.getApplicationContext(), card8.id, ImageLocationType.back)); + assertEquals(null, Utils.retrieveCardImage(activity.getApplicationContext(), card8.id, ImageLocationType.icon)); LoyaltyCard card2 = db.getLoyaltyCard(2); @@ -1071,8 +1084,9 @@ public class ImportExportTest { assertEquals(null, card2.barcodeType); assertEquals(-9977996, (long) card2.headerColor); assertEquals(0, card2.starStatus); - assertEquals(null, Utils.retrieveCardImage(activity.getApplicationContext(), card2.id, true)); - assertEquals(null, Utils.retrieveCardImage(activity.getApplicationContext(), card2.id, false)); + assertEquals(null, Utils.retrieveCardImage(activity.getApplicationContext(), card2.id, ImageLocationType.front)); + assertEquals(null, Utils.retrieveCardImage(activity.getApplicationContext(), card2.id, ImageLocationType.back)); + assertEquals(null, Utils.retrieveCardImage(activity.getApplicationContext(), card2.id, ImageLocationType.icon)); LoyaltyCard card3 = db.getLoyaltyCard(3); @@ -1086,8 +1100,9 @@ public class ImportExportTest { assertEquals(null, card3.barcodeType); assertEquals(-9977996, (long) card3.headerColor); assertEquals(0, card3.starStatus); - assertEquals(null, Utils.retrieveCardImage(activity.getApplicationContext(), card3.id, true)); - assertEquals(null, Utils.retrieveCardImage(activity.getApplicationContext(), card3.id, false)); + assertEquals(null, Utils.retrieveCardImage(activity.getApplicationContext(), card3.id, ImageLocationType.front)); + assertEquals(null, Utils.retrieveCardImage(activity.getApplicationContext(), card3.id, ImageLocationType.back)); + assertEquals(null, Utils.retrieveCardImage(activity.getApplicationContext(), card3.id, ImageLocationType.icon)); LoyaltyCard card4 = db.getLoyaltyCard(4); @@ -1101,8 +1116,9 @@ public class ImportExportTest { assertEquals(null, card4.barcodeType); assertEquals(-10902850, (long) card4.headerColor); assertEquals(1, card4.starStatus); - assertEquals(null, Utils.retrieveCardImage(activity.getApplicationContext(), card4.id, true)); - assertEquals(null, Utils.retrieveCardImage(activity.getApplicationContext(), card4.id, false)); + assertEquals(null, Utils.retrieveCardImage(activity.getApplicationContext(), card4.id, ImageLocationType.front)); + assertEquals(null, Utils.retrieveCardImage(activity.getApplicationContext(), card4.id, ImageLocationType.back)); + assertEquals(null, Utils.retrieveCardImage(activity.getApplicationContext(), card4.id, ImageLocationType.icon)); LoyaltyCard card5 = db.getLoyaltyCard(5); @@ -1116,8 +1132,9 @@ public class ImportExportTest { assertEquals(BarcodeFormat.CODE_128, card5.barcodeType.format()); assertEquals(-10902850, (long) card5.headerColor); assertEquals(0, card5.starStatus); - assertEquals(null, Utils.retrieveCardImage(activity.getApplicationContext(), card5.id, true)); - assertEquals(null, Utils.retrieveCardImage(activity.getApplicationContext(), card5.id, false)); + assertEquals(null, Utils.retrieveCardImage(activity.getApplicationContext(), card5.id, ImageLocationType.front)); + assertEquals(null, Utils.retrieveCardImage(activity.getApplicationContext(), card5.id, ImageLocationType.back)); + assertEquals(null, Utils.retrieveCardImage(activity.getApplicationContext(), card5.id, ImageLocationType.icon)); LoyaltyCard card6 = db.getLoyaltyCard(6); @@ -1131,8 +1148,9 @@ public class ImportExportTest { assertEquals(BarcodeFormat.AZTEC, card6.barcodeType.format()); assertEquals(null, card6.headerColor); assertEquals(0, card6.starStatus); - assertEquals(null, Utils.retrieveCardImage(activity.getApplicationContext(), card6.id, true)); - assertEquals(null, Utils.retrieveCardImage(activity.getApplicationContext(), card6.id, false)); + assertEquals(null, Utils.retrieveCardImage(activity.getApplicationContext(), card6.id, ImageLocationType.front)); + assertEquals(null, Utils.retrieveCardImage(activity.getApplicationContext(), card6.id, ImageLocationType.back)); + assertEquals(null, Utils.retrieveCardImage(activity.getApplicationContext(), card6.id, ImageLocationType.icon)); TestHelpers.getEmptyDb(activity); } @@ -1212,8 +1230,9 @@ public class ImportExportTest { assertEquals(BarcodeFormat.EAN_13, card.barcodeType.format()); assertEquals(0, card.starStatus); - assertNull(Utils.retrieveCardImage(activity.getApplicationContext(), 1, true)); - assertNull(Utils.retrieveCardImage(activity.getApplicationContext(), 1, false)); + assertNull(Utils.retrieveCardImage(activity.getApplicationContext(), 1, ImageLocationType.front)); + assertNull(Utils.retrieveCardImage(activity.getApplicationContext(), 1, ImageLocationType.back)); + assertNull(Utils.retrieveCardImage(activity.getApplicationContext(), 1, ImageLocationType.icon)); card = db.getLoyaltyCard(2); @@ -1227,8 +1246,9 @@ public class ImportExportTest { assertEquals(BarcodeFormat.EAN_13, card.barcodeType.format()); assertEquals(0, card.starStatus); - assertTrue(BitmapFactory.decodeStream(getClass().getResourceAsStream("stocard-front.jpg")).sameAs(Utils.retrieveCardImage(activity.getApplicationContext(), 2, true))); - assertTrue(BitmapFactory.decodeStream(getClass().getResourceAsStream("stocard-back.jpg")).sameAs(Utils.retrieveCardImage(activity.getApplicationContext(), 2, false))); + assertTrue(BitmapFactory.decodeStream(getClass().getResourceAsStream("stocard-front.jpg")).sameAs(Utils.retrieveCardImage(activity.getApplicationContext(), 2, ImageLocationType.front))); + assertTrue(BitmapFactory.decodeStream(getClass().getResourceAsStream("stocard-back.jpg")).sameAs(Utils.retrieveCardImage(activity.getApplicationContext(), 2, ImageLocationType.back))); + assertNull(Utils.retrieveCardImage(activity.getApplicationContext(), 2, ImageLocationType.icon)); card = db.getLoyaltyCard(3); @@ -1243,8 +1263,9 @@ public class ImportExportTest { assertEquals(BarcodeFormat.RSS_EXPANDED, card.barcodeType.format()); assertEquals(0, card.starStatus); - assertNull(Utils.retrieveCardImage(activity.getApplicationContext(), 3, true)); - assertNull(Utils.retrieveCardImage(activity.getApplicationContext(), 3, false)); + assertNull(Utils.retrieveCardImage(activity.getApplicationContext(), 3, ImageLocationType.front)); + assertNull(Utils.retrieveCardImage(activity.getApplicationContext(), 3, ImageLocationType.back)); + assertNull(Utils.retrieveCardImage(activity.getApplicationContext(), 3, ImageLocationType.icon)); TestHelpers.getEmptyDb(activity); } diff --git a/app/src/test/java/protect/card_locker/LoyaltyCardViewActivityTest.java b/app/src/test/java/protect/card_locker/LoyaltyCardViewActivityTest.java index d305b908a..76fcbc8f4 100644 --- a/app/src/test/java/protect/card_locker/LoyaltyCardViewActivityTest.java +++ b/app/src/test/java/protect/card_locker/LoyaltyCardViewActivityTest.java @@ -359,7 +359,7 @@ public class LoyaltyCardViewActivityTest activityController = Robolectric.buildActivity(LoyaltyCardEditActivity.class).create(); } - Activity activity = (Activity) activityController.get(); + LoyaltyCardEditActivity activity = (LoyaltyCardEditActivity) activityController.get(); final Context context = activity.getApplicationContext(); DBHelper db = TestHelpers.getEmptyDb(activity); @@ -401,8 +401,8 @@ public class LoyaltyCardViewActivityTest cardIdField.setText("12345678"); barcodeField.setText("87654321"); barcodeTypeField.setText(CatimaBarcode.fromBarcode(BarcodeFormat.QR_CODE).prettyName()); - LoyaltyCardEditActivity.setCardImage(frontImageView, frontBitmap); - LoyaltyCardEditActivity.setCardImage(backImageView, backBitmap); + activity.setCardImage(frontImageView, frontBitmap, true); + activity.setCardImage(backImageView, backBitmap, true); shadowOf(getMainLooper()).idle(); @@ -1412,7 +1412,7 @@ public class LoyaltyCardViewActivityTest { Date date = new Date(); - Uri importUri = Uri.parse("https://thelastproject.github.io/Catima/share?store=Example%20Store¬e=&expiry=" + date.getTime() + "&balance=10&balancetype=USD&cardid=123456&barcodetype=AZTEC&headercolor=-416706&headertextcolor=-1"); + Uri importUri = Uri.parse("https://catima.app/share#store%3DExample%2BStore%26note%3D%26expiry%3D" + date.getTime() + "%26balance%3D10.00%26balancetype%3DUSD%26cardid%3D123456%26barcodetype%3DAZTEC%26headercolor%3D-416706"); Intent intent = new Intent(); intent.setData(importUri); @@ -1433,7 +1433,7 @@ public class LoyaltyCardViewActivityTest } @Test - public void importCardOldURL() + public void importCardOldFormat() { Uri importUri = Uri.parse("https://brarcher.github.io/loyalty-card-locker/share?store=Example%20Store¬e=&cardid=123456&barcodetype=AZTEC&headercolor=-416706&headertextcolor=-1"); diff --git a/app/src/test/java/protect/card_locker/TestHelpers.java b/app/src/test/java/protect/card_locker/TestHelpers.java index 4ed45ce8f..9daa6b08f 100644 --- a/app/src/test/java/protect/card_locker/TestHelpers.java +++ b/app/src/test/java/protect/card_locker/TestHelpers.java @@ -16,12 +16,11 @@ public class TestHelpers { while (!cursor.isAfterLast()) { int cardID = cursor.getColumnIndex(DBHelper.LoyaltyCardDbIds.ID); - try { - Utils.saveCardImage(activity.getApplicationContext(), null, cardID, true); - } catch (FileNotFoundException ignored) {} - try { - Utils.saveCardImage(activity.getApplicationContext(), null, cardID, false); - } catch (FileNotFoundException ignored) {} + for (ImageLocationType imageLocationType : ImageLocationType.values()) { + try { + Utils.saveCardImage(activity.getApplicationContext(), null, cardID, imageLocationType); + } catch (FileNotFoundException ignored) {} + } cursor.moveToNext(); }