mirror of
https://github.com/CatimaLoyalty/Android.git
synced 2025-12-24 15:47:53 -05:00
Compare commits
17 Commits
v2.22.1
...
feature/mu
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0547fb9949 | ||
|
|
d092cbe930 | ||
|
|
67383a7f10 | ||
|
|
5b5ade0edc | ||
|
|
efd0f4ef39 | ||
|
|
67ada5c027 | ||
|
|
520f0da983 | ||
|
|
343d710b2a | ||
|
|
1c71dc964f | ||
|
|
524d649523 | ||
|
|
e39593228d | ||
|
|
27d718b461 | ||
|
|
490281bff9 | ||
|
|
5030e4c67a | ||
|
|
29eac68e3f | ||
|
|
422501da3e | ||
|
|
23bd60b476 |
@@ -7,6 +7,9 @@ import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.database.sqlite.SQLiteOpenHelper;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class DBHelper extends SQLiteOpenHelper
|
||||
{
|
||||
public static final String DATABASE_NAME = "LoyaltyCards.db";
|
||||
@@ -170,6 +173,57 @@ public class DBHelper extends SQLiteOpenHelper
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a cursor only containing the first loyalty card of the given store.
|
||||
*
|
||||
* @param filter
|
||||
* @return Cursor
|
||||
*/
|
||||
public Cursor getOneLoyaltyCardPerStoreCursor(final String filter)
|
||||
{
|
||||
String actualFilter = String.format("%%%s%%", filter);
|
||||
String[] selectionArgs = { actualFilter, actualFilter };
|
||||
|
||||
SQLiteDatabase db = getReadableDatabase();
|
||||
|
||||
Cursor res = db.rawQuery("select * from " + LoyaltyCardDbIds.TABLE +
|
||||
" WHERE " + LoyaltyCardDbIds.STORE + " LIKE ? " +
|
||||
" OR " + LoyaltyCardDbIds.NOTE + " LIKE ? " +
|
||||
" GROUP BY " + LoyaltyCardDbIds.STORE +
|
||||
" HAVING MIN(" + LoyaltyCardDbIds.ID + ")" +
|
||||
" ORDER BY " + LoyaltyCardDbIds.STORE + " COLLATE NOCASE ASC", selectionArgs, null);
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of all loyalty cards of the given store.
|
||||
*
|
||||
* @param store
|
||||
* @return List<LoyaltyCard>
|
||||
*/
|
||||
public List<LoyaltyCard> getLoyaltyCardsForStore(String store)
|
||||
{
|
||||
List<LoyaltyCard> loyaltyCards = new ArrayList<>();
|
||||
|
||||
SQLiteDatabase db = getReadableDatabase();
|
||||
String[] selectionArgs = { store };
|
||||
|
||||
Cursor res = db.rawQuery("select * from " + LoyaltyCardDbIds.TABLE +
|
||||
" WHERE " + LoyaltyCardDbIds.STORE + " IS ? " +
|
||||
" ORDER BY " + LoyaltyCardDbIds.STORE + " COLLATE NOCASE ASC", selectionArgs, null);
|
||||
|
||||
try
|
||||
{
|
||||
while (res.moveToNext()) {
|
||||
loyaltyCards.add(LoyaltyCard.toLoyaltyCard(res));
|
||||
}
|
||||
} finally {
|
||||
res.close();
|
||||
}
|
||||
|
||||
return loyaltyCards;
|
||||
}
|
||||
|
||||
public int getLoyaltyCardCount()
|
||||
{
|
||||
// An empty string will match everything
|
||||
|
||||
@@ -14,11 +14,13 @@ import protect.card_locker.preferences.Settings;
|
||||
class LoyaltyCardCursorAdapter extends CursorAdapter
|
||||
{
|
||||
Settings settings;
|
||||
DBHelper dbHelper;
|
||||
|
||||
public LoyaltyCardCursorAdapter(Context context, Cursor cursor)
|
||||
{
|
||||
super(context, cursor, 0);
|
||||
settings = new Settings(context);
|
||||
dbHelper = new DBHelper(context);
|
||||
}
|
||||
|
||||
// The newView method is used to inflate a new view and return it,
|
||||
@@ -42,15 +44,25 @@ class LoyaltyCardCursorAdapter extends CursorAdapter
|
||||
// Extract properties from cursor
|
||||
LoyaltyCard loyaltyCard = LoyaltyCard.toLoyaltyCard(cursor);
|
||||
|
||||
// Get amount of cards for this store
|
||||
int cardCount = dbHelper.getLoyaltyCardsForStore(loyaltyCard.store).size();
|
||||
|
||||
// Populate fields with extracted properties
|
||||
storeField.setText(loyaltyCard.store);
|
||||
|
||||
storeField.setTextSize(settings.getCardTitleListFontSize());
|
||||
|
||||
if(loyaltyCard.note.isEmpty() == false)
|
||||
if(cardCount > 1 || !loyaltyCard.note.isEmpty())
|
||||
{
|
||||
noteField.setVisibility(View.VISIBLE);
|
||||
noteField.setText(loyaltyCard.note);
|
||||
if(cardCount > 1)
|
||||
{
|
||||
noteField.setText(context.getResources().getString(R.string.cardCount, cardCount));
|
||||
}
|
||||
else
|
||||
{
|
||||
noteField.setText(loyaltyCard.note);
|
||||
}
|
||||
noteField.setTextSize(settings.getCardNoteListFontSize());
|
||||
}
|
||||
else
|
||||
|
||||
@@ -8,6 +8,8 @@ import android.graphics.Color;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||
import com.google.android.material.snackbar.Snackbar;
|
||||
import androidx.appcompat.app.ActionBar;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
@@ -39,6 +41,7 @@ public class LoyaltyCardEditActivity extends AppCompatActivity
|
||||
|
||||
protected static final int SELECT_BARCODE_REQUEST = 1;
|
||||
|
||||
FloatingActionButton fabSave;
|
||||
EditText storeFieldEdit;
|
||||
EditText noteFieldEdit;
|
||||
ImageView headingColorSample;
|
||||
@@ -58,6 +61,7 @@ public class LoyaltyCardEditActivity extends AppCompatActivity
|
||||
|
||||
int loyaltyCardId;
|
||||
boolean updateLoyaltyCard;
|
||||
String loyaltyCardStorePrefill = "";
|
||||
Uri importLoyaltyCardUri = null;
|
||||
Integer headingColorValue = null;
|
||||
Integer headingStoreTextColorValue = null;
|
||||
@@ -70,6 +74,7 @@ public class LoyaltyCardEditActivity extends AppCompatActivity
|
||||
final Bundle b = intent.getExtras();
|
||||
loyaltyCardId = b != null ? b.getInt("id") : 0;
|
||||
updateLoyaltyCard = b != null && b.getBoolean("update", false);
|
||||
loyaltyCardStorePrefill = b != null ? b.getString("store", "") : "";
|
||||
importLoyaltyCardUri = intent.getData();
|
||||
|
||||
Log.d(TAG, "View activity: id=" + loyaltyCardId
|
||||
@@ -95,6 +100,7 @@ public class LoyaltyCardEditActivity extends AppCompatActivity
|
||||
db = new DBHelper(this);
|
||||
importUriHelper = new ImportURIHelper(this);
|
||||
|
||||
fabSave = findViewById(R.id.fabSave);
|
||||
storeFieldEdit = findViewById(R.id.storeNameEdit);
|
||||
noteFieldEdit = findViewById(R.id.noteEdit);
|
||||
headingColorSample = findViewById(R.id.headingColorSample);
|
||||
@@ -135,6 +141,14 @@ public class LoyaltyCardEditActivity extends AppCompatActivity
|
||||
|
||||
Log.i(TAG, "To view card: " + loyaltyCardId);
|
||||
|
||||
fabSave.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
doSave();
|
||||
}
|
||||
});
|
||||
|
||||
if(updateLoyaltyCard)
|
||||
{
|
||||
final LoyaltyCard loyaltyCard = db.getLoyaltyCard(loyaltyCardId);
|
||||
@@ -210,6 +224,12 @@ public class LoyaltyCardEditActivity extends AppCompatActivity
|
||||
setTitle(R.string.addCardTitle);
|
||||
}
|
||||
|
||||
// Set prefill values if nothing is set
|
||||
if(storeFieldEdit.getText().length() == 0 && !loyaltyCardStorePrefill.isEmpty())
|
||||
{
|
||||
storeFieldEdit.setText(loyaltyCardStorePrefill);
|
||||
}
|
||||
|
||||
if(headingColorValue == null)
|
||||
{
|
||||
// Select a random color to start out with.
|
||||
@@ -413,10 +433,6 @@ public class LoyaltyCardEditActivity extends AppCompatActivity
|
||||
{
|
||||
getMenuInflater().inflate(R.menu.card_update_menu, menu);
|
||||
}
|
||||
else
|
||||
{
|
||||
getMenuInflater().inflate(R.menu.card_add_menu, menu);
|
||||
}
|
||||
|
||||
return super.onCreateOptionsMenu(menu);
|
||||
}
|
||||
@@ -464,10 +480,6 @@ public class LoyaltyCardEditActivity extends AppCompatActivity
|
||||
dialog.show();
|
||||
|
||||
return true;
|
||||
|
||||
case R.id.action_save:
|
||||
doSave();
|
||||
return true;
|
||||
}
|
||||
|
||||
return super.onOptionsItemSelected(item);
|
||||
|
||||
@@ -11,6 +11,8 @@ import android.os.Bundle;
|
||||
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||
import androidx.core.graphics.ColorUtils;
|
||||
import androidx.core.graphics.drawable.DrawableCompat;
|
||||
import androidx.core.view.GestureDetectorCompat;
|
||||
import androidx.core.view.MotionEventCompat;
|
||||
import androidx.core.widget.TextViewCompat;
|
||||
import androidx.appcompat.app.ActionBar;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
@@ -18,8 +20,10 @@ import androidx.appcompat.content.res.AppCompatResources;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import android.util.Log;
|
||||
import android.util.TypedValue;
|
||||
import android.view.GestureDetector;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewTreeObserver;
|
||||
@@ -29,16 +33,23 @@ import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||
import com.google.android.material.tabs.TabLayout;
|
||||
import com.google.zxing.BarcodeFormat;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import protect.card_locker.preferences.Settings;
|
||||
|
||||
|
||||
public class LoyaltyCardViewActivity extends AppCompatActivity
|
||||
public class LoyaltyCardViewActivity extends AppCompatActivity implements GestureDetector.OnGestureListener
|
||||
{
|
||||
private static final String TAG = "CardLocker";
|
||||
private static final double LUMINANCE_MIDPOINT = 0.5;
|
||||
|
||||
FloatingActionButton FabAdd;
|
||||
TabLayout tabLayout;
|
||||
TabLayout.OnTabSelectedListener onTabSelectedListener;
|
||||
TextView cardIdFieldView;
|
||||
TextView noteView;
|
||||
View noteViewDivider;
|
||||
@@ -47,6 +58,8 @@ public class LoyaltyCardViewActivity extends AppCompatActivity
|
||||
View collapsingToolbarLayout;
|
||||
int loyaltyCardId;
|
||||
LoyaltyCard loyaltyCard;
|
||||
List<LoyaltyCard> storeCards;
|
||||
GestureDetectorCompat gestureDetector;
|
||||
boolean rotationEnabled;
|
||||
DBHelper db;
|
||||
ImportURIHelper importURIHelper;
|
||||
@@ -104,6 +117,33 @@ public class LoyaltyCardViewActivity extends AppCompatActivity
|
||||
db = new DBHelper(this);
|
||||
importURIHelper = new ImportURIHelper(this);
|
||||
|
||||
FabAdd = findViewById(R.id.fabAdd);
|
||||
FabAdd.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view)
|
||||
{
|
||||
Intent intent = new Intent(getApplicationContext(), LoyaltyCardEditActivity.class);
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putString("store", loyaltyCard.store);
|
||||
intent.putExtras(bundle);
|
||||
startActivity(intent);
|
||||
finish();
|
||||
}
|
||||
});
|
||||
tabLayout = findViewById(R.id.tabLayout);
|
||||
onTabSelectedListener = new TabLayout.OnTabSelectedListener() {
|
||||
@Override
|
||||
public void onTabSelected(TabLayout.Tab tab) {
|
||||
loyaltyCardId = storeCards.get(tab.getPosition()).id;
|
||||
onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTabUnselected(TabLayout.Tab tab) {}
|
||||
|
||||
@Override
|
||||
public void onTabReselected(TabLayout.Tab tab) {}
|
||||
};
|
||||
cardIdFieldView = findViewById(R.id.cardIdView);
|
||||
noteView = findViewById(R.id.noteView);
|
||||
noteViewDivider = findViewById(R.id.noteViewDivider);
|
||||
@@ -113,6 +153,23 @@ public class LoyaltyCardViewActivity extends AppCompatActivity
|
||||
|
||||
rotationEnabled = true;
|
||||
|
||||
gestureDetector = new GestureDetectorCompat(this, this);
|
||||
|
||||
// Restore active card id after rotation
|
||||
if(savedInstanceState != null)
|
||||
{
|
||||
loyaltyCardId = savedInstanceState.getInt("id");
|
||||
onResume();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(Bundle savedInstanceState) {
|
||||
// Save active card id before rotation
|
||||
savedInstanceState.putInt("id", loyaltyCardId);
|
||||
|
||||
super.onSaveInstanceState(savedInstanceState);
|
||||
|
||||
// Allow making barcode fullscreen on tap
|
||||
barcodeImage.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
@@ -174,6 +231,38 @@ public class LoyaltyCardViewActivity extends AppCompatActivity
|
||||
return;
|
||||
}
|
||||
|
||||
storeCards = db.getLoyaltyCardsForStore(loyaltyCard.store);
|
||||
tabLayout.removeOnTabSelectedListener(onTabSelectedListener);
|
||||
tabLayout.removeAllTabs();
|
||||
for(int i = 0; i < storeCards.size(); i++)
|
||||
{
|
||||
LoyaltyCard storeCard = storeCards.get(i);
|
||||
|
||||
// Use only first line of note
|
||||
String loyaltyCardText = storeCard.note.split("\\r?\\n")[0].trim();
|
||||
if(loyaltyCardText.isEmpty())
|
||||
{
|
||||
loyaltyCardText = String.valueOf(i + 1);
|
||||
}
|
||||
else if(loyaltyCardText.length() > 15)
|
||||
{
|
||||
// Shorten long notes
|
||||
loyaltyCardText = loyaltyCardText.substring(0, 15).trim() + "…";
|
||||
}
|
||||
|
||||
tabLayout.addTab(tabLayout.newTab().setText(loyaltyCardText));
|
||||
|
||||
if(storeCard.id == loyaltyCardId)
|
||||
{
|
||||
tabLayout.getTabAt(i).select();
|
||||
}
|
||||
}
|
||||
tabLayout.addOnTabSelectedListener(onTabSelectedListener);
|
||||
if(tabLayout.getTabCount() > 1)
|
||||
{
|
||||
tabLayout.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
String formatString = loyaltyCard.barcodeType;
|
||||
format = !formatString.isEmpty() ? BarcodeFormat.valueOf(formatString) : null;
|
||||
cardIdString = loyaltyCard.cardId;
|
||||
@@ -189,6 +278,8 @@ public class LoyaltyCardViewActivity extends AppCompatActivity
|
||||
TextViewCompat.setAutoSizeTextTypeUniformWithConfiguration(noteView,
|
||||
getResources().getInteger(R.integer.settings_card_note_min_font_size_sp)-1,
|
||||
settings.getCardNoteFontSize(), 1, TypedValue.COMPLEX_UNIT_SP);
|
||||
noteView.setVisibility(View.VISIBLE);
|
||||
noteViewDivider.setVisibility(View.VISIBLE);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -272,7 +363,7 @@ public class LoyaltyCardViewActivity extends AppCompatActivity
|
||||
}
|
||||
else
|
||||
{
|
||||
findViewById(R.id.barcode).setVisibility(View.GONE);
|
||||
findViewById(R.id.barcode).setVisibility(View.INVISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -366,6 +457,55 @@ public class LoyaltyCardViewActivity extends AppCompatActivity
|
||||
}
|
||||
}
|
||||
|
||||
// Gesture detection
|
||||
@Override
|
||||
public boolean onDown(MotionEvent motionEvent) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShowPress(MotionEvent motionEvent) {}
|
||||
|
||||
@Override
|
||||
public boolean onSingleTapUp(MotionEvent motionEvent) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onScroll(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLongPress(MotionEvent motionEvent) { }
|
||||
|
||||
@Override
|
||||
public boolean onFling(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1) {
|
||||
int currentTab = tabLayout.getSelectedTabPosition();
|
||||
|
||||
if (motionEvent1.getX() > motionEvent.getX())
|
||||
{
|
||||
// Swipe left
|
||||
int nextTab = currentTab == 0 ? tabLayout.getTabCount() - 1 : currentTab - 1;
|
||||
tabLayout.getTabAt(nextTab).select();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Swipe right
|
||||
int nextTab = currentTab < (tabLayout.getTabCount() - 1) ? currentTab + 1 : 0;
|
||||
tabLayout.getTabAt(nextTab).select();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent motionEvent)
|
||||
{
|
||||
gestureDetector.onTouchEvent(motionEvent);
|
||||
return super.onTouchEvent(motionEvent);
|
||||
}
|
||||
|
||||
/**
|
||||
* When enabled, hides the status bar and moves the barcode to the top of the screen.
|
||||
*
|
||||
|
||||
@@ -29,6 +29,7 @@ import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
import java.util.Calendar;
|
||||
@@ -43,6 +44,7 @@ public class MainActivity extends AppCompatActivity
|
||||
private static final int MAIN_REQUEST_CODE = 1;
|
||||
|
||||
private Menu menu;
|
||||
private FloatingActionButton fabAdd;
|
||||
protected String filter = "";
|
||||
|
||||
@Override
|
||||
@@ -53,6 +55,15 @@ public class MainActivity extends AppCompatActivity
|
||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||
setSupportActionBar(toolbar);
|
||||
|
||||
fabAdd = findViewById(R.id.fabAdd);
|
||||
fabAdd.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
Intent i = new Intent(getApplicationContext(), LoyaltyCardEditActivity.class);
|
||||
startActivityForResult(i, MAIN_REQUEST_CODE);
|
||||
}
|
||||
});
|
||||
|
||||
updateLoyaltyCardList("");
|
||||
|
||||
SharedPreferences prefs = getSharedPreferences("protect.card_locker", MODE_PRIVATE);
|
||||
@@ -145,7 +156,7 @@ public class MainActivity extends AppCompatActivity
|
||||
noMatchingCardsText.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
Cursor cardCursor = db.getLoyaltyCardCursor(filterText);
|
||||
Cursor cardCursor = db.getOneLoyaltyCardPerStoreCursor(filterText);
|
||||
|
||||
final LoyaltyCardCursorAdapter adapter = new LoyaltyCardCursorAdapter(this, cardCursor);
|
||||
cardList.setAdapter(adapter);
|
||||
@@ -259,13 +270,6 @@ public class MainActivity extends AppCompatActivity
|
||||
{
|
||||
int id = item.getItemId();
|
||||
|
||||
if (id == R.id.action_add)
|
||||
{
|
||||
Intent i = new Intent(getApplicationContext(), LoyaltyCardEditActivity.class);
|
||||
startActivityForResult(i, MAIN_REQUEST_CODE);
|
||||
return true;
|
||||
}
|
||||
|
||||
if(id == R.id.action_import_export)
|
||||
{
|
||||
Intent i = new Intent(getApplicationContext(), ImportExportActivity.class);
|
||||
|
||||
@@ -5,6 +5,15 @@
|
||||
android:layout_height="match_parent"
|
||||
android:fitsSystemWindows="true">
|
||||
|
||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
android:id="@+id/fabSave"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end|bottom"
|
||||
android:src="@drawable/save_24dp"
|
||||
android:contentDescription="@string/save"
|
||||
android:layout_margin="16dp" />
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
||||
@@ -8,6 +8,15 @@
|
||||
android:fitsSystemWindows="true"
|
||||
>
|
||||
|
||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
android:id="@+id/fabAdd"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end|bottom"
|
||||
android:src="@drawable/ic_add_white_24dp"
|
||||
android:contentDescription="@string/action_add"
|
||||
android:layout_margin="16dp" />
|
||||
|
||||
<FrameLayout
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
@@ -35,12 +44,12 @@
|
||||
android:layout_marginBottom="10.0dip"
|
||||
android:layout_marginStart="15.0dip"
|
||||
android:layout_marginEnd="15.0dip"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
android:padding="10.0dp"
|
||||
android:background="#ffffff"
|
||||
app:layout_constraintBottom_toTopOf="@+id/centerGuideline"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
android:contentDescription="@string/barcodeImageDescription"/>
|
||||
|
||||
<TextView
|
||||
@@ -141,6 +150,15 @@
|
||||
android:layout_height="?actionBarSize"
|
||||
app:contentInsetStart="72.0dip"
|
||||
app:layout_collapseMode="pin" />
|
||||
<com.google.android.material.tabs.TabLayout
|
||||
android:visibility="gone"
|
||||
android:id="@+id/tabLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom"
|
||||
app:tabGravity="fill"
|
||||
app:tabIndicatorAnimationDuration="0"
|
||||
app:tabMode="scrollable"/>
|
||||
</com.google.android.material.appbar.CollapsingToolbarLayout>
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
@@ -8,6 +8,15 @@
|
||||
android:fitsSystemWindows="true"
|
||||
tools:context="protect.card_locker.MainActivity">
|
||||
|
||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
android:id="@+id/fabAdd"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end|bottom"
|
||||
android:src="@drawable/ic_add_white_24dp"
|
||||
android:contentDescription="@string/action_add"
|
||||
android:layout_margin="16dp" />
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<item
|
||||
android:id="@+id/action_save"
|
||||
android:icon="@drawable/save_24dp"
|
||||
android:title="@string/save"
|
||||
app:showAsAction="always"/>
|
||||
</menu>
|
||||
@@ -2,15 +2,9 @@
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<item
|
||||
android:id="@+id/action_save"
|
||||
android:icon="@drawable/save_24dp"
|
||||
android:title="@string/save"
|
||||
app:showAsAction="always"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/action_delete"
|
||||
android:icon="@drawable/ic_delete_white_24dp"
|
||||
android:title="@string/delete"
|
||||
app:showAsAction="never"/>
|
||||
app:showAsAction="always"/>
|
||||
</menu>
|
||||
@@ -8,11 +8,6 @@
|
||||
android:icon="@drawable/ic_search_white"
|
||||
app:actionViewClass="androidx.appcompat.widget.SearchView"
|
||||
app:showAsAction="always|collapseActionView"/>
|
||||
<item
|
||||
android:id="@+id/action_add"
|
||||
android:icon="@drawable/ic_add_white_24dp"
|
||||
android:title="@string/action_add"
|
||||
app:showAsAction="always"/>
|
||||
<item
|
||||
android:id="@+id/action_import_export"
|
||||
android:icon="@drawable/ic_import_export_white_24dp"
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
<string name="noGiftCards">You don\'t have any loyalty cards at the moment. Click the "+" (plus) button up top to get started.\n\nLoyalty Card Locker lets you carry your loyalty cards on your phone, so they are always within reach.</string>
|
||||
<string name="noMatchingGiftCards">No loyalty cards match the search filter. Please try some different terms.</string>
|
||||
<string name="cardCount">%1$d cards</string>
|
||||
|
||||
<string name="storeName">Store</string>
|
||||
<string name="note">Note</string>
|
||||
|
||||
@@ -26,6 +26,8 @@ import android.widget.EditText;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import androidx.core.widget.TextViewCompat;
|
||||
|
||||
import com.google.android.material.tabs.TabLayout;
|
||||
import com.google.zxing.BarcodeFormat;
|
||||
import com.google.zxing.client.android.Intents;
|
||||
import java.io.IOException;
|
||||
@@ -118,7 +120,7 @@ public class LoyaltyCardViewActivityTest
|
||||
barcodeTypeField.setText(barcodeType);
|
||||
|
||||
assertEquals(false, activity.isFinishing());
|
||||
shadowOf(activity).clickMenuItem(R.id.action_save);
|
||||
activity.findViewById(R.id.fabSave).performClick();
|
||||
assertEquals(true, activity.isFinishing());
|
||||
|
||||
assertEquals(1, db.getLoyaltyCardCount());
|
||||
@@ -274,17 +276,16 @@ public class LoyaltyCardViewActivityTest
|
||||
|
||||
final EditText storeField = activity.findViewById(R.id.storeNameEdit);
|
||||
final EditText noteField = activity.findViewById(R.id.noteEdit);
|
||||
final TextView cardIdField = activity.findViewById(R.id.cardIdView);
|
||||
|
||||
shadowOf(activity).clickMenuItem(R.id.action_save);
|
||||
activity.findViewById(R.id.fabSave).performClick();
|
||||
assertEquals(0, db.getLoyaltyCardCount());
|
||||
|
||||
storeField.setText("store");
|
||||
shadowOf(activity).clickMenuItem(R.id.action_save);
|
||||
activity.findViewById(R.id.fabSave).performClick();
|
||||
assertEquals(0, db.getLoyaltyCardCount());
|
||||
|
||||
noteField.setText("note");
|
||||
shadowOf(activity).clickMenuItem(R.id.action_save);
|
||||
activity.findViewById(R.id.fabSave).performClick();
|
||||
assertEquals(0, db.getLoyaltyCardCount());
|
||||
}
|
||||
|
||||
@@ -687,6 +688,49 @@ public class LoyaltyCardViewActivityTest
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkNoTabViewOnSingleCardFromStore()
|
||||
{
|
||||
ActivityController activityController = createActivityWithLoyaltyCard(false);
|
||||
Activity activity = (Activity)activityController.get();
|
||||
DBHelper db = new DBHelper(activity);
|
||||
|
||||
db.insertLoyaltyCard("store", "note", BARCODE_DATA, BARCODE_TYPE, Color.BLACK, Color.WHITE);
|
||||
|
||||
activityController.start();
|
||||
activityController.visible();
|
||||
activityController.resume();
|
||||
|
||||
final TabLayout tabLayout = activity.findViewById(R.id.tabLayout);
|
||||
assertEquals(1, tabLayout.getTabCount());
|
||||
assertEquals(View.GONE, tabLayout.getVisibility());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkTabViewOnMultipleCardsFromSameStore()
|
||||
{
|
||||
ActivityController activityController = createActivityWithLoyaltyCard(false);
|
||||
Activity activity = (Activity)activityController.get();
|
||||
DBHelper db = new DBHelper(activity);
|
||||
|
||||
db.insertLoyaltyCard("store", "note", BARCODE_DATA, BARCODE_TYPE, Color.BLACK, Color.WHITE);
|
||||
db.insertLoyaltyCard("store", "note2", BARCODE_DATA, BARCODE_TYPE, Color.BLACK, Color.WHITE);
|
||||
|
||||
activityController.start();
|
||||
activityController.visible();
|
||||
activityController.resume();
|
||||
|
||||
final TabLayout tabLayout = activity.findViewById(R.id.tabLayout);
|
||||
assertEquals(2, tabLayout.getTabCount());
|
||||
assertEquals(View.VISIBLE, tabLayout.getVisibility());
|
||||
checkAllFields(activity, ViewMode.VIEW_CARD, "store", "note", BARCODE_DATA, BARCODE_TYPE);
|
||||
|
||||
// Check if the card switches correctly
|
||||
tabLayout.getTabAt(1).select();
|
||||
|
||||
checkAllFields(activity, ViewMode.VIEW_CARD, "store", "note2", BARCODE_DATA, BARCODE_TYPE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkBarcodeFullscreenWorkflow()
|
||||
{
|
||||
|
||||
@@ -7,6 +7,7 @@ import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.database.Cursor;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.os.Bundle;
|
||||
import androidx.appcompat.widget.SearchView;
|
||||
import android.view.Menu;
|
||||
@@ -22,8 +23,10 @@ import org.junit.runner.RunWith;
|
||||
import org.robolectric.Robolectric;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.Shadows;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.android.controller.ActivityController;
|
||||
import org.robolectric.shadows.ShadowListView;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
@@ -70,10 +73,9 @@ public class MainActivityTest
|
||||
assertTrue(menu != null);
|
||||
|
||||
// The settings, search and add button should be present
|
||||
assertEquals(menu.size(), 6);
|
||||
assertEquals(menu.size(), 5);
|
||||
|
||||
assertEquals("Search", menu.findItem(R.id.action_search).getTitle().toString());
|
||||
assertEquals("Add", menu.findItem(R.id.action_add).getTitle().toString());
|
||||
assertEquals("Import/Export", menu.findItem(R.id.action_import_export).getTitle().toString());
|
||||
assertEquals("Start Intro", menu.findItem(R.id.action_intro).getTitle().toString());
|
||||
assertEquals("About", menu.findItem(R.id.action_about).getTitle().toString());
|
||||
@@ -85,7 +87,7 @@ public class MainActivityTest
|
||||
{
|
||||
final MainActivity activity = Robolectric.setupActivity(MainActivity.class);
|
||||
|
||||
shadowOf(activity).clickMenuItem(R.id.action_add);
|
||||
activity.findViewById(R.id.fabAdd).performClick();
|
||||
|
||||
Intent intent = shadowOf(activity).peekNextStartedActivityForResult().intent;
|
||||
|
||||
@@ -127,6 +129,49 @@ public class MainActivityTest
|
||||
assertNotNull(cursor);
|
||||
}
|
||||
|
||||
public void AddTwoLoyaltyCardsFromSameStore()
|
||||
{
|
||||
ActivityController activityController = Robolectric.buildActivity(MainActivity.class).create();
|
||||
|
||||
Activity mainActivity = (Activity)activityController.get();
|
||||
activityController.start();
|
||||
activityController.resume();
|
||||
|
||||
TextView helpText = mainActivity.findViewById(R.id.helpText);
|
||||
TextView noMatchingCardsText = mainActivity.findViewById(R.id.noMatchingCardsText);
|
||||
ListView list = mainActivity.findViewById(R.id.list);
|
||||
|
||||
assertEquals(0, list.getCount());
|
||||
|
||||
DBHelper db = new DBHelper(mainActivity);
|
||||
db.insertLoyaltyCard("store", "note", "cardId", BarcodeFormat.UPC_A.toString(), Color.BLACK, Color.WHITE);
|
||||
db.insertLoyaltyCard("store", "note2", "cardId2", BarcodeFormat.MAXICODE.toString(), Color.YELLOW, Color.GRAY);
|
||||
db.insertLoyaltyCard("store2", "note2", "cardId2", BarcodeFormat.UPC_E.toString(), Color.BLUE, Color.MAGENTA);
|
||||
|
||||
assertEquals(View.VISIBLE, helpText.getVisibility());
|
||||
assertEquals(View.GONE, noMatchingCardsText.getVisibility());
|
||||
assertEquals(View.GONE, list.getVisibility());
|
||||
|
||||
activityController.pause();
|
||||
activityController.resume();
|
||||
|
||||
assertEquals(View.GONE, helpText.getVisibility());
|
||||
assertEquals(View.GONE, noMatchingCardsText.getVisibility());
|
||||
assertEquals(View.VISIBLE, list.getVisibility());
|
||||
|
||||
// We expect to see only 2 "cards" because the first store should be merged
|
||||
assertEquals(2, list.getAdapter().getCount());
|
||||
Cursor cursor = (Cursor)list.getAdapter().getItem(0);
|
||||
assertNotNull(cursor);
|
||||
|
||||
// Check if this returns the first loyalty card
|
||||
LoyaltyCard card = LoyaltyCard.toLoyaltyCard(cursor);
|
||||
assertEquals("store", card.store);
|
||||
assertEquals("note", card.note);
|
||||
assertEquals("cardId", card.cardId);
|
||||
assertEquals(BarcodeFormat.UPC_A.toString(), card.barcodeType);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFiltering()
|
||||
{
|
||||
@@ -220,6 +265,100 @@ public class MainActivityTest
|
||||
assertEquals(2, list.getCount());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFilteringWithGroupedCards()
|
||||
{
|
||||
ActivityController activityController = Robolectric.buildActivity(MainActivity.class).create();
|
||||
|
||||
MainActivity mainActivity = (MainActivity)activityController.get();
|
||||
activityController.start();
|
||||
activityController.resume();
|
||||
|
||||
TextView helpText = mainActivity.findViewById(R.id.helpText);
|
||||
TextView noMatchingCardsText = mainActivity.findViewById(R.id.noMatchingCardsText);
|
||||
ListView list = mainActivity.findViewById(R.id.list);
|
||||
|
||||
DBHelper db = new DBHelper(mainActivity);
|
||||
db.insertLoyaltyCard("The First Store", "Initial note", "cardId", BarcodeFormat.UPC_A.toString(), Color.BLACK, Color.WHITE);
|
||||
db.insertLoyaltyCard("The First Store", "Tertiary note", "cardId", BarcodeFormat.UPC_A.toString(), Color.BLACK, Color.WHITE);
|
||||
db.insertLoyaltyCard("The Second Store", "Secondary note", "cardId", BarcodeFormat.UPC_A.toString(), Color.BLACK, Color.WHITE);
|
||||
|
||||
activityController.pause();
|
||||
activityController.resume();
|
||||
|
||||
assertEquals(View.GONE, helpText.getVisibility());
|
||||
assertEquals(View.GONE, noMatchingCardsText.getVisibility());
|
||||
assertEquals(View.VISIBLE, list.getVisibility());
|
||||
|
||||
assertEquals(2, list.getCount());
|
||||
|
||||
mainActivity.filter = "store";
|
||||
|
||||
activityController.pause();
|
||||
activityController.resume();
|
||||
|
||||
assertEquals(View.GONE, helpText.getVisibility());
|
||||
assertEquals(View.GONE, noMatchingCardsText.getVisibility());
|
||||
assertEquals(View.VISIBLE, list.getVisibility());
|
||||
|
||||
assertEquals(2, list.getCount());
|
||||
|
||||
mainActivity.filter = "first";
|
||||
|
||||
activityController.pause();
|
||||
activityController.resume();
|
||||
|
||||
assertEquals(View.GONE, helpText.getVisibility());
|
||||
assertEquals(View.GONE, noMatchingCardsText.getVisibility());
|
||||
assertEquals(View.VISIBLE, list.getVisibility());
|
||||
|
||||
assertEquals(1, list.getCount());
|
||||
|
||||
mainActivity.filter = "initial";
|
||||
|
||||
activityController.pause();
|
||||
activityController.resume();
|
||||
|
||||
assertEquals(View.GONE, helpText.getVisibility());
|
||||
assertEquals(View.GONE, noMatchingCardsText.getVisibility());
|
||||
assertEquals(View.VISIBLE, list.getVisibility());
|
||||
|
||||
assertEquals(1, list.getCount());
|
||||
|
||||
mainActivity.filter = "second";
|
||||
|
||||
activityController.pause();
|
||||
activityController.resume();
|
||||
|
||||
assertEquals(View.GONE, helpText.getVisibility());
|
||||
assertEquals(View.GONE, noMatchingCardsText.getVisibility());
|
||||
assertEquals(View.VISIBLE, list.getVisibility());
|
||||
|
||||
assertEquals(1, list.getCount());
|
||||
|
||||
mainActivity.filter = "company";
|
||||
|
||||
activityController.pause();
|
||||
activityController.resume();
|
||||
|
||||
assertEquals(View.GONE, helpText.getVisibility());
|
||||
assertEquals(View.VISIBLE, noMatchingCardsText.getVisibility());
|
||||
assertEquals(View.VISIBLE, list.getVisibility());
|
||||
|
||||
assertEquals(0, list.getCount());
|
||||
|
||||
mainActivity.filter = "";
|
||||
|
||||
activityController.pause();
|
||||
activityController.resume();
|
||||
|
||||
assertEquals(View.GONE, helpText.getVisibility());
|
||||
assertEquals(View.GONE, noMatchingCardsText.getVisibility());
|
||||
assertEquals(View.VISIBLE, list.getVisibility());
|
||||
|
||||
assertEquals(2, list.getCount());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFirstRunStartsIntro()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user