Merge branch 'master' into feature/dark_mode

This commit is contained in:
Sylvia van Os
2019-12-02 16:32:58 +01:00
committed by GitHub
11 changed files with 262 additions and 17 deletions

View File

@@ -11,7 +11,7 @@ android {
defaultConfig {
applicationId "protect.card_locker"
minSdkVersion 15
minSdkVersion 16
targetSdkVersion 27
versionCode 35
versionName "0.25.4"

View File

@@ -146,16 +146,52 @@ public class DBHelper extends SQLiteOpenHelper
public Cursor getLoyaltyCardCursor()
{
// An empty string will match everything
return getLoyaltyCardCursor("");
}
/**
* Returns a cursor to all loyalty cards with the filter text in either the store or note.
*
* @param filter
* @return Cursor
*/
public Cursor getLoyaltyCardCursor(final String filter)
{
String actualFilter = String.format("%%%s%%", filter);
String[] selectionArgs = { actualFilter, actualFilter };
SQLiteDatabase db = getReadableDatabase();
Cursor res = db.rawQuery("select * from " + LoyaltyCardDbIds.TABLE +
" ORDER BY " + LoyaltyCardDbIds.STORE + " COLLATE NOCASE ASC", null);
Cursor res = db.rawQuery("select * from " + LoyaltyCardDbIds.TABLE +
" WHERE " + LoyaltyCardDbIds.STORE + " LIKE ? " +
" OR " + LoyaltyCardDbIds.NOTE + " LIKE ? " +
" ORDER BY " + LoyaltyCardDbIds.STORE + " COLLATE NOCASE ASC", selectionArgs, null);
return res;
}
public int getLoyaltyCardCount()
{
// An empty string will match everything
return getLoyaltyCardCount("");
}
/**
* Returns the amount of loyalty cards with the filter text in either the store or note.
*
* @param filter
* @return Integer
*/
public int getLoyaltyCardCount(String filter)
{
String actualFilter = String.format("%%%s%%", filter);
String[] selectionArgs = { actualFilter, actualFilter };
SQLiteDatabase db = getReadableDatabase();
Cursor data = db.rawQuery("SELECT Count(*) FROM " + LoyaltyCardDbIds.TABLE, null);
Cursor data = db.rawQuery("SELECT Count(*) FROM " + LoyaltyCardDbIds.TABLE +
" WHERE " + LoyaltyCardDbIds.STORE + " LIKE ? " +
" OR " + LoyaltyCardDbIds.NOTE + " LIKE ? "
, selectionArgs, null);
int numItems = 0;

View File

@@ -1,6 +1,8 @@
package protect.card_locker;
import android.app.SearchManager;
import android.content.ClipData;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.ClipboardManager;
@@ -11,6 +13,7 @@ import android.database.Cursor;
import android.os.Bundle;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.SearchView;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.ContextMenu;
@@ -35,6 +38,10 @@ import protect.card_locker.preferences.SettingsActivity;
public class MainActivity extends AppCompatActivity
{
private static final String TAG = "LoyaltyCardLocker";
private static final int MAIN_REQUEST_CODE = 1;
private Menu menu;
protected String filter = "";
@Override
protected void onCreate(Bundle savedInstanceState)
@@ -44,7 +51,7 @@ public class MainActivity extends AppCompatActivity
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
updateLoyaltyCardList();
updateLoyaltyCardList("");
SharedPreferences prefs = getSharedPreferences("protect.card_locker", MODE_PRIVATE);
if (prefs.getBoolean("firstrun", true)) {
@@ -54,31 +61,84 @@ public class MainActivity extends AppCompatActivity
}
@Override
protected void onResume()
{
protected void onResume() {
super.onResume();
updateLoyaltyCardList();
if (menu != null)
{
SearchView searchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
if (!searchView.isIconified()) {
filter = searchView.getQuery().toString();
}
}
updateLoyaltyCardList(filter);
}
private void updateLoyaltyCardList()
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == MAIN_REQUEST_CODE)
{
// We're coming back from another view so clear the search
// We only do this now to prevent a flash of all entries right after picking one
filter = "";
if (menu != null)
{
MenuItem searchItem = menu.findItem(R.id.action_search);
searchItem.collapseActionView();
}
}
}
@Override
public void onBackPressed() {
if (menu == null)
{
super.onBackPressed();
return;
}
SearchView searchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
if (!searchView.isIconified()) {
searchView.setIconified(true);
} else {
super.onBackPressed();
}
}
private void updateLoyaltyCardList(String filterText)
{
final ListView cardList = findViewById(R.id.list);
final TextView helpText = findViewById(R.id.helpText);
final TextView noMatchingCardsText = findViewById(R.id.noMatchingCardsText);
final DBHelper db = new DBHelper(this);
if(db.getLoyaltyCardCount() > 0)
{
// We want the cardList to be visible regardless of the filtered match count
// to ensure that the noMatchingCardsText doesn't end up being shown below
// the keyboard
cardList.setVisibility(View.VISIBLE);
helpText.setVisibility(View.GONE);
if(db.getLoyaltyCardCount(filterText) > 0)
{
noMatchingCardsText.setVisibility(View.GONE);
}
else
{
noMatchingCardsText.setVisibility(View.VISIBLE);
}
}
else
{
cardList.setVisibility(View.GONE);
helpText.setVisibility(View.VISIBLE);
noMatchingCardsText.setVisibility(View.GONE);
}
Cursor cardCursor = db.getLoyaltyCardCursor();
Cursor cardCursor = db.getLoyaltyCardCursor(filterText);
final LoyaltyCardCursorAdapter adapter = new LoyaltyCardCursorAdapter(this, cardCursor);
cardList.setAdapter(adapter);
@@ -101,7 +161,7 @@ public class MainActivity extends AppCompatActivity
ShortcutHelper.updateShortcuts(MainActivity.this, loyaltyCard, i);
startActivity(i);
startActivityForResult(i, MAIN_REQUEST_CODE);
}
});
}
@@ -142,7 +202,39 @@ public class MainActivity extends AppCompatActivity
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
this.menu = menu;
getMenuInflater().inflate(R.menu.main_menu, menu);
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
if (searchManager != null) {
SearchView searchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
searchView.setSubmitButtonEnabled(false);
searchView.setOnCloseListener(new SearchView.OnCloseListener() {
@Override
public boolean onClose() {
invalidateOptionsMenu();
return false;
}
});
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
filter = newText;
updateLoyaltyCardList(newText);
return true;
}
});
}
return super.onCreateOptionsMenu(menu);
}
@@ -154,21 +246,21 @@ public class MainActivity extends AppCompatActivity
if (id == R.id.action_add)
{
Intent i = new Intent(getApplicationContext(), LoyaltyCardEditActivity.class);
startActivity(i);
startActivityForResult(i, MAIN_REQUEST_CODE);
return true;
}
if(id == R.id.action_import_export)
{
Intent i = new Intent(getApplicationContext(), ImportExportActivity.class);
startActivity(i);
startActivityForResult(i, MAIN_REQUEST_CODE);
return true;
}
if(id == R.id.action_settings)
{
Intent i = new Intent(getApplicationContext(), SettingsActivity.class);
startActivity(i);
startActivityForResult(i, MAIN_REQUEST_CODE);
return true;
}
@@ -276,6 +368,6 @@ public class MainActivity extends AppCompatActivity
private void startIntro()
{
Intent intent = new Intent(this, IntroActivity.class);
startActivity(intent);
startActivityForResult(intent, MAIN_REQUEST_CODE);
}
}

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 582 B

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 410 B

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 783 B

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -17,6 +17,14 @@
android:text="@string/noGiftCards"
android:visibility="gone"/>
<TextView
style="@style/AppTheme.TextView.NoData"
android:id="@+id/noMatchingCardsText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/noMatchingGiftCards"
android:visibility="gone"/>
<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"

View File

@@ -2,6 +2,12 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context="protect.card_locker.MainActivity">
<item
android:id="@+id/action_search"
android:title="@string/action_search"
android:icon="@drawable/ic_search_white"
app:actionViewClass="android.support.v7.widget.SearchView"
app:showAsAction="always|collapseActionView"/>
<item
android:id="@+id/action_add"
android:icon="@drawable/ic_add_white_24dp"

View File

@@ -2,9 +2,11 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name">Loyalty Card Keychain</string>
<string name="action_search">Search</string>
<string name="action_add">Add</string>
<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="storeName">Store</string>
<string name="note">Note</string>

View File

@@ -8,6 +8,7 @@ import android.content.SharedPreferences;
import android.database.Cursor;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v7.widget.SearchView;
import android.view.Menu;
import android.view.View;
import android.widget.ListView;
@@ -53,6 +54,9 @@ public class MainActivityTest
TextView helpText = activity.findViewById(R.id.helpText);
assertEquals(View.VISIBLE, helpText.getVisibility());
TextView noMatchingCardsText = activity.findViewById(R.id.noMatchingCardsText);
assertEquals(View.GONE, noMatchingCardsText.getVisibility());
ListView list = activity.findViewById(R.id.list);
assertEquals(View.GONE, list.getVisibility());
}
@@ -65,9 +69,10 @@ public class MainActivityTest
final Menu menu = shadowOf(activity).getOptionsMenu();
assertTrue(menu != null);
// The settings and add button should be present
assertEquals(menu.size(), 5);
// The settings, search and add button should be present
assertEquals(menu.size(), 6);
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());
@@ -98,6 +103,7 @@ public class MainActivityTest
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());
@@ -106,12 +112,14 @@ public class MainActivityTest
db.insertLoyaltyCard("store", "note", "cardId", BarcodeFormat.UPC_A.toString(), Color.BLACK, Color.WHITE);
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());
assertEquals(1, list.getAdapter().getCount());
@@ -119,6 +127,99 @@ public class MainActivityTest
assertNotNull(cursor);
}
@Test
public void testFiltering()
{
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 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()
{