Merge branch 'master' into hamburger-menu-additions

This commit is contained in:
Clayton Wilson 2020-10-07 21:08:44 -04:00 committed by GitHub
commit 55f8cf60d2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
72 changed files with 2132 additions and 451 deletions

View File

@ -0,0 +1,78 @@
import netscape.javascript.JSObject;
import java.io.*;
import java.net.ProtocolException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.HashMap;
public class KroggerAPITester {
final static String client_id = "listify-f6e083b133a87ab8a98b2ec4f580dedb9125180887245441161";
final static String client_secret = "hM88WJ3cJGou5jX1vNRZBqKKVmmcMMktTcTbvkRD";
final static String redirect_uri = "https://example.com/callback"; //subject to change as needed
final static String scope = "product.compact";
final static String authString = "listify-f6e083b133a87ab8a98b2ec4f580dedb9125180887245441161:hM88WJ3cJGou5jX1vNRZBqKKVmmcMMktTcTbvkRD";
public static String getKroggerAuthKey() {
String token = "not found";
try {
StringBuilder sb = new StringBuilder("https://api.kroger.com/v1/connect/oauth2/token");
String urlParameters = "grant_type=client_credentials&scope=product.compact";
byte[] postData = urlParameters.getBytes( StandardCharsets.UTF_8 );
int postDataLength = postData.length;
URL url = new URL(sb.toString());
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.setRequestProperty("Authorization", "Basic " + Base64.getEncoder().encodeToString(authString.getBytes()));
connection.setRequestProperty("charset", "UTF-8");
connection.setRequestProperty("Content-Length", Integer.toString( postDataLength ));
try( DataOutputStream wr = new DataOutputStream( connection.getOutputStream())) { //write body into POST request
wr.write( postData );
}
int responseStatus = connection.getResponseCode();
if(responseStatus == 200) {
System.out.println("Success");
try(BufferedReader br = new BufferedReader(
new InputStreamReader(connection.getInputStream(), "utf-8"))) {
StringBuilder response = new StringBuilder();
String responseLine;
while ((responseLine = br.readLine()) != null) {
response.append(responseLine.trim());
}
String jsonString = response.toString();
jsonString = jsonString.substring(1, jsonString.length() - 1);
HashMap<String, String> map = new HashMap<>();
String[] responses = jsonString.split(",");
for(int i = 0; i < responses.length; i++) {
String[] keyValue = responses[i].split(":");
map.put(keyValue[0], keyValue[1]);
}
if(map.containsKey("\"access_token\"")) {
token = map.get("\"access_token\"");
token = token.substring(1, token.length() - 1); //removes quotes at start and end
}
}
} else {
System.out.println(responseStatus);
}
connection.disconnect();
System.out.println(responseStatus);
} catch (IOException e) {
e.printStackTrace();
}
return token;
}
}

View File

@ -0,0 +1,123 @@
import java.math.BigDecimal;
import java.sql.ResultSet;
import java.sql.SQLException;
public class Item {
Integer productID;
Integer chainID;
String upc;
String description;
BigDecimal price;
String imageURL;
String department;
long retrievedDate;
Integer fetchCounts;
public Item(ResultSet itemRow) throws SQLException {
this.productID = itemRow.getInt(1);
System.out.println(this.productID);
this.chainID = itemRow.getInt(2);
System.out.println(this.chainID);
this.upc = itemRow.getString(3);
System.out.println(this.upc);
this.description = itemRow.getString(4);
System.out.println(this.description);
this.price = itemRow.getBigDecimal(5);
System.out.println(this.price);
this.imageURL = itemRow.getString(6);
System.out.println(imageURL);
this.department = itemRow.getString(7);
System.out.println(department);
this.retrievedDate = itemRow.getTimestamp(8).toInstant().toEpochMilli();
System.out.println(retrievedDate);
this.fetchCounts = itemRow.getInt(9);
System.out.println(fetchCounts);
}
@Override
public String toString() {
return "Item{" +
"productID=" + productID +
", chainID=" + chainID +
", upc='" + upc + '\'' +
", description='" + description + '\'' +
", price=" + price +
", imageURL='" + imageURL + '\'' +
", department='" + department + '\'' +
", retrievedDate=" + retrievedDate +
", fetchCounts=" + fetchCounts +
'}';
}
public Integer getProductID() {
return productID;
}
public void setProductID(Integer productID) {
this.productID = productID;
}
public Integer getChainID() {
return chainID;
}
public void setChainID(Integer chainID) {
this.chainID = chainID;
}
public String getUpc() {
return upc;
}
public void setUpc(String upc) {
this.upc = upc;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public BigDecimal getPrice() {
return price;
}
public void setPrice(BigDecimal price) {
this.price = price;
}
public String getImageURL() {
return imageURL;
}
public void setImageURL(String imageURL) {
this.imageURL = imageURL;
}
public String getDepartment() {
return department;
}
public void setDepartment(String department) {
this.department = department;
}
public long getRetrievedDate() {
return retrievedDate;
}
public void setRetrievedDate(long retrievedDate) {
this.retrievedDate = retrievedDate;
}
public Integer getFetchCounts() {
return fetchCounts;
}
public void setFetchCounts(Integer fetchCounts) {
this.fetchCounts = fetchCounts;
}
}

View File

@ -0,0 +1,11 @@
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import java.util.Map;
public class ItemGET implements RequestHandler<Map<String,Object>, Object> {
public Object handleRequest(Map<String, Object> inputMap, Context unfilled) {
return BasicHandler.handleRequest(inputMap, unfilled, ItemGetter.class);
}
}

View File

@ -0,0 +1,36 @@
import com.google.gson.Gson;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
public class ItemGetter implements CallHandler{
private final DBConnector connector;
private final String GET_ITEM = "SELECT * FROM Product WHERE productID = ?;";
public ItemGetter(DBConnector connector, String cognitoID) {
this.connector = connector;
}
@Override
public Object conductAction(Map<String, Object> bodyMap, HashMap<String, String> queryMap, String cognitoID) throws SQLException {
Connection connection = connector.getConnection();
try {
PreparedStatement statement = connection.prepareStatement(GET_ITEM);
statement.setInt(1, Integer.parseInt(queryMap.get("id")));
System.out.println(statement);
ResultSet queryResults = statement.executeQuery();
queryResults.first();
System.out.println(queryResults);
Item retrievedItem = new Item(queryResults);
System.out.println(retrievedItem);
return retrievedItem;
} finally {
connection.close();
}
}
}

View File

@ -0,0 +1,29 @@
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
public class ItemSearch {
ArrayList<Item> results;
ItemSearch(ResultSet searchResults) throws SQLException {
results = new ArrayList<>();
while (searchResults.next()) {
results.add(new Item(searchResults));
}
}
@Override
public String toString() {
return "ItemSearch{" +
"results=" + results +
'}';
}
public ArrayList<Item> getResults() {
return results;
}
public void setResults(ArrayList<Item> results) {
this.results = results;
}
}

View File

@ -0,0 +1,11 @@
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import java.util.Map;
public class ItemSearchGET implements RequestHandler<Map<String,Object>, Object> {
public Object handleRequest(Map<String, Object> inputMap, Context unfilled) {
return BasicHandler.handleRequest(inputMap, unfilled, ItemSearcher.class);
}
}

View File

@ -0,0 +1,32 @@
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
public class ItemSearcher implements CallHandler {
DBConnector connector;
String cognitoID;
private final String GET_ITEM_MATCHES = "SELECT * FROM Product WHERE description LIKE ?";
public ItemSearcher(DBConnector connector, String cognitoID) {
this.connector = connector;
this.cognitoID = cognitoID;
}
@Override
public Object conductAction(Map<String, Object> body, HashMap<String, String> queryParams, String s) throws SQLException {
try (Connection connection = connector.getConnection()) {
PreparedStatement getItemMatches = connection.prepareStatement(GET_ITEM_MATCHES);
getItemMatches.setString(1, "%" + queryParams.get("id") + "%");
System.out.println(getItemMatches);
ResultSet searchResults = getItemMatches.executeQuery();
ItemSearch searchResultsObject = new ItemSearch(searchResults);
System.out.println(searchResultsObject);
return searchResultsObject;
}
}
}

View File

@ -0,0 +1,50 @@
import java.sql.ResultSet;
import java.sql.SQLException;
import java.time.LocalDateTime;
public class ItemEntry {
Integer listID;
Integer productID;
Integer quantity;
long addedDate;
Boolean purchased;
public ItemEntry(Integer listID, ResultSet listRow) throws SQLException {
this.listID = listID;
productID = listRow.getInt(1);
quantity = listRow.getInt(2);
addedDate = listRow.getTimestamp(3).toInstant().toEpochMilli();
purchased = listRow.getBoolean(4);
}
public Integer getProductID() {
return productID;
}
public void setProductID(Integer productID) {
this.productID = productID;
}
public Integer getQuantity() {
return quantity;
}
public void setQuantity(Integer quantity) {
this.quantity = quantity;
}
public long getAddedDate() {
return addedDate;
}
public void setAddedDate(long addedDate) {
this.addedDate = addedDate;
}
public Boolean getPurchased() {
return purchased;
}
public void setPurchased(Boolean purchased) {
this.purchased = purchased;
}
}

View File

@ -0,0 +1,72 @@
import java.sql.ResultSet;
import java.sql.SQLException;
import java.time.Instant;
import java.time.LocalDateTime;
import java.util.ArrayList;
public class List {
Integer itemID;
String name;
String owner;
long lastUpdated;
ArrayList<ItemEntry> entries;
public List(ResultSet listRow) throws SQLException {
itemID = listRow.getInt("listID");
name = listRow.getString("name");
owner = listRow.getString("owner");
lastUpdated = listRow.getTimestamp("lastUpdated").toInstant().toEpochMilli();
entries = new ArrayList<>();
}
public void addItemEntry(ItemEntry entry) {
entries.add(entry);
}
@Override
public String toString() {
return "List{" +
"itemID=" + itemID +
", name='" + name + '\'' +
", owner='" + owner + '\'' +
", lastUpdated=" + lastUpdated +
", entries=" + entries +
'}';
}
public ItemEntry[] getEntries() {
return entries.toArray(new ItemEntry[entries.size()]);
}
public Integer getItemID() {
return itemID;
}
public void setItemID(Integer itemID) {
this.itemID = itemID;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getOwner() {
return owner;
}
public void setOwner(String owner) {
this.owner = owner;
}
public long getLastUpdated() {
return lastUpdated;
}
public void setLastUpdated(long lastUpdated) {
this.lastUpdated = lastUpdated;
}
}

View File

@ -0,0 +1,33 @@
import java.sql.*;
import java.time.Instant;
import java.time.ZoneOffset;
import java.util.HashMap;
import java.util.Map;
public class ListAdder implements CallHandler {
private DBConnector connector;
private String cognitoID;
private final String LIST_CREATE = "INSERT INTO List (name, owner, lastUpdated) VALUES (?, ?, ?)";
public ListAdder(DBConnector connector, String cognitoID) {
this.connector = connector;
this.cognitoID = cognitoID;
}
public Object conductAction(Map<String, Object> bodyMap, HashMap<String, String> queryString, String cognitoID) throws SQLException {
Connection connection = connector.getConnection();
PreparedStatement statement = connection.prepareStatement(LIST_CREATE, Statement.RETURN_GENERATED_KEYS);
statement.setString(1, bodyMap.get("name").toString());//Needs safe checking
statement.setString(2, cognitoID);
statement.setTimestamp(3, Timestamp.from(Instant.now()));
System.out.println(statement);
statement.executeUpdate();
ResultSet newIDRS = statement.getGeneratedKeys();
newIDRS.first();
Integer newID = newIDRS.getInt(1);
connection.commit();
return newID;
}
}

View File

@ -0,0 +1,12 @@
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import java.util.Map;
public class ListGET implements RequestHandler<Map<String,Object>, Object> {
public Object handleRequest(Map<String, Object> inputMap, Context unfilled) {
return BasicHandler.handleRequest(inputMap, unfilled, ListGetter.class);
}
}

View File

@ -0,0 +1,58 @@
import com.google.gson.Gson;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
public class ListGetter implements CallHandler{
private final DBConnector connector;
private final String cognitoID;
private final String GET_LIST = "SELECT * FROM List WHERE listID = ?;";
private final String GET_LISTS = "SELECT listID FROM List WHERE owner = ?;";
private final String GET_ENTRIES = "SELECT * FROM ListProduct WHERE listID = ?;";
public ListGetter(DBConnector connector, String cognitoID) {
this.connector = connector;
this.cognitoID = cognitoID;
}
@Override
public Object conductAction(Map<String, Object> bodyMap, HashMap<String, String> queryMap, String cognitoID) throws SQLException {
try (Connection connection = connector.getConnection()) {
Integer id = Integer.parseInt(queryMap.get("id"));
if (id == -1) {
PreparedStatement getLists = connection.prepareStatement(GET_LISTS);
getLists.setString(1, cognitoID);
System.out.println(getLists);
ResultSet getListsResults = getLists.executeQuery();
System.out.println(getListsResults);
ArrayList<Integer> listIds = new ArrayList<>();
while (getListsResults.next()) {
listIds.add(getListsResults.getInt(1));
}
return listIds;
}
PreparedStatement getList = connection.prepareStatement(GET_LIST);
getList.setInt(1, id);
System.out.println(getList);
ResultSet getListResults = getList.executeQuery();
getListResults.first();
System.out.println(getListResults);
List retrievedList = new List(getListResults);
System.out.println(retrievedList);
PreparedStatement getListEntries = connection.prepareStatement(GET_ENTRIES);
getListEntries.setInt(1, id);
ResultSet getEntryResults = getListEntries.executeQuery();
while (getEntryResults.next()) {
retrievedList.addItemEntry(new ItemEntry(id, getEntryResults));
}
System.out.println(retrievedList);
return retrievedList;
}
}
}

View File

@ -0,0 +1,11 @@
import java.util.Map;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
public class ListPOST implements RequestHandler<Map<String,Object>, Object>{
public Object handleRequest(Map<String, Object> inputMap, Context unfilled) {
return BasicHandler.handleRequest(inputMap, unfilled, ListAdder.class);
}
}

View File

@ -0,0 +1,39 @@
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.time.Instant;
import java.time.ZoneOffset;
import java.util.HashMap;
import java.util.Map;
public class ListEntryAdder implements CallHandler {
private DBConnector connector;
private String cognitoID;
private final String ITEM_TO_LIST = "INSERT INTO ListProduct (productID, listID, quantity, addedDate, purchased) VALUES (?, ?, ?, ?, ?)";
public ListEntryAdder(DBConnector connector, String cognitoID) {
this.connector = connector;
this.cognitoID = cognitoID;
}
public Object conductAction(Map<String, Object> bodyMap, HashMap<String, String> queryString, String cognitoID) throws SQLException {
Connection connection = connector.getConnection();
try {
PreparedStatement statement = connection.prepareStatement(ITEM_TO_LIST);
statement.setInt(1, (Integer) bodyMap.get("productID"));
statement.setInt(2, (Integer) bodyMap.get("listID"));
statement.setInt(3, (Integer) bodyMap.get("quantity"));
statement.setTimestamp(4, Timestamp.from(Instant.now()));
statement.setBoolean(5, (Boolean) bodyMap.get("purchased"));
System.out.println(statement);
statement.executeUpdate();
connection.commit();
} finally {
connection.close();
}
return null;
}
}

View File

@ -0,0 +1,11 @@
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import java.util.Map;
public class ListEntryDELETE implements RequestHandler<Map<String,Object>, Object> {
public Object handleRequest(Map<String, Object> inputMap, Context unfilled) {
return BasicHandler.handleRequest(inputMap, unfilled, ListEntryDeleter.class);
}
}

View File

@ -0,0 +1,33 @@
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
public class ListEntryDeleter implements CallHandler {
private DBConnector connector;
private String cognitoID;
private final String REMOVE_FROM_LIST = "DELETE FROM ListProduct WHERE (ProductID = ? AND ListID = ?);";
public ListEntryDeleter(DBConnector connector, String cognitoID) {
this.connector = connector;
this.cognitoID = cognitoID;
}
public Object conductAction(Map<String, Object> bodyMap, HashMap<String, String> queryString, String cognitoID) throws SQLException {
Connection connection = connector.getConnection();
try {
PreparedStatement statement = connection.prepareStatement(REMOVE_FROM_LIST);
statement.setInt(1, (Integer) bodyMap.get("ProductID"));
statement.setInt(2, (Integer) bodyMap.get("ListID"));
System.out.println(statement);
statement.executeUpdate();
connection.commit();
} finally {
connection.close();
}
return null;
}
}

View File

@ -0,0 +1,11 @@
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import java.util.Map;
public class ListEntryPOST implements RequestHandler<Map<String,Object>, Object> {
public Object handleRequest(Map<String, Object> inputMap, Context unfilled) {
return BasicHandler.handleRequest(inputMap, unfilled, ListEntryAdder.class);
}
}

View File

@ -0,0 +1,3 @@
{
"userPoolId": "us-east-2_MFgSVKQMd",
}

View File

@ -0,0 +1,11 @@
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import java.util.Map;
public class UserDELETE implements RequestHandler<Map<String,Object>, Object> {
public Object handleRequest(Map<String, Object> inputMap, Context unfilled) {
return BasicHandler.handleRequest(inputMap, unfilled, UserDeleter.class);
}
}

View File

@ -0,0 +1,58 @@
import com.amazonaws.services.cognitoidp.AWSCognitoIdentityProvider;
import com.amazonaws.services.cognitoidp.AWSCognitoIdentityProviderClientBuilder;
import com.amazonaws.services.cognitoidp.model.AdminDeleteUserRequest;
import com.amazonaws.services.cognitoidp.model.AdminUserGlobalSignOutRequest;
import java.io.IOException;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
public class UserDeleter implements CallHandler {
private DBConnector connector;
private String cognitoID;
//private final String REMOVE_FROM_LIST = "DELETE FROM ListProduct WHERE (ProductID = ? AND ListID = ?);";
public UserDeleter(DBConnector connector, String cognitoID) {
this.connector = connector;
this.cognitoID = cognitoID;
}
public Object conductAction(Map<String, Object> bodyMap, HashMap<String, String> queryString, String cognitoID) throws SQLException {
AWSCognitoIdentityProvider awsCognitoIdentityProvider = AWSCognitoIdentityProviderClientBuilder.defaultClient();
Properties cognitoProperties;
try {
cognitoProperties = DBConnector.loadProperties("cognitoProperties.json");
} catch (IOException e) {
e.printStackTrace();
return null;
}
String userPoolId = cognitoProperties.get("userPoolId").toString();
System.out.println(userPoolId);
AdminUserGlobalSignOutRequest adminUserGlobalSignOutRequest = new AdminUserGlobalSignOutRequest().withUserPoolId(userPoolId);
adminUserGlobalSignOutRequest.setUsername(cognitoID);
System.out.println(adminUserGlobalSignOutRequest);
awsCognitoIdentityProvider.adminUserGlobalSignOut(adminUserGlobalSignOutRequest);
AdminDeleteUserRequest adminDeleteUserRequest = new AdminDeleteUserRequest().withUserPoolId(userPoolId);
adminDeleteUserRequest.setUsername(cognitoID);
System.out.println(adminDeleteUserRequest);
awsCognitoIdentityProvider.adminDeleteUser(adminDeleteUserRequest);
return null;
// Connection connection = connector.getConnection();
// try {
// PreparedStatement statement = connection.prepareStatement(REMOVE_FROM_LIST);
// statement.setInt(1, (Integer) bodyMap.get("ProductID"));
// statement.setInt(2, (Integer) bodyMap.get("ListID"));
// System.out.println(statement);
// statement.executeUpdate();
// connection.commit();
// } finally {
// connection.close();
// }
// return null;
}
}

View File

@ -39,6 +39,56 @@
<artifactId>mariadb-java-client</artifactId> <artifactId>mariadb-java-client</artifactId>
<version>2.7.0</version> <version>2.7.0</version>
</dependency> </dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.12</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.6</version>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-cognitoidentity</artifactId>
<version>1.11.875</version>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-cognitoidp</artifactId>
<version>1.11.875</version>
</dependency>
<dependency>
<groupId>software.amazon.ion</groupId>
<artifactId>ion-java</artifactId>
<version>1.5.1</version>
</dependency>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.10.6</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-cbor</artifactId>
<version>2.11.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>2.8.5</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.11.3</version>
</dependency>
</dependencies> </dependencies>
<properties> <properties>
<maven.compiler.source>1.11</maven.compiler.source> <maven.compiler.source>1.11</maven.compiler.source>

View File

@ -0,0 +1,31 @@
import com.amazonaws.services.lambda.runtime.Context;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
public class BasicHandler {
public static <T extends CallHandler> Object handleRequest(Map<String, Object> inputMap, Context unfilled, Class<T> toCall) {
String cognitoID = InputUtils.getCognitoIDFromBody(inputMap);
HashMap<String, String> queryMap = InputUtils.getQueryParams(inputMap);
try {
DBConnector connector = new DBConnector();
try {
Constructor<T> constructor = toCall.getConstructor(DBConnector.class, String.class);
CallHandler callHandler = constructor.newInstance(connector, cognitoID);
return callHandler.conductAction(InputUtils.getBody(inputMap), queryMap, cognitoID);
} catch (SQLException | NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
} finally {
connector.close();
}
} catch (IOException |SQLException|ClassNotFoundException e) {
e.printStackTrace();
throw new RuntimeException(e.getLocalizedMessage());
}
return null;
}
}

View File

@ -0,0 +1,7 @@
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
public interface CallHandler {
Object conductAction(Map<String, Object> bodyMap, HashMap<String, String> queryString, String cognitoID) throws SQLException;
}

View File

@ -12,11 +12,11 @@ public class DBConnector {
Connection connection; Connection connection;
DBConnector() throws IOException, SQLException, ClassNotFoundException { public DBConnector() throws IOException, SQLException, ClassNotFoundException {
this(loadProperties("dbProperties.json")); this(loadProperties("dbProperties.json"));
} }
DBConnector(Properties dbProperties) throws SQLException, ClassNotFoundException { public DBConnector(Properties dbProperties) throws SQLException, ClassNotFoundException {
Class.forName("org.mariadb.jdbc.Driver"); Class.forName("org.mariadb.jdbc.Driver");
System.out.println(dbProperties); System.out.println(dbProperties);
System.out.println(DBConnector.buildURL(dbProperties)); System.out.println(DBConnector.buildURL(dbProperties));

View File

@ -1,3 +1,9 @@
import org.apache.http.NameValuePair;
import org.apache.http.client.utils.URLEncodedUtils;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
public class InputUtils { public class InputUtils {
@ -19,6 +25,24 @@ public class InputUtils {
return getMap(inputMap, "body"); return getMap(inputMap, "body");
} }
private static String getQueryString(Map<String, Object> inputMap) {
return (String) (getMap(inputMap, "params").get("querystring"));
}
public static HashMap<String, String> getQueryParams(Map<String, Object> inputMap) {
return (HashMap<String, String>) (getMap(inputMap, "params").get("querystring"));
// String queryString = getQueryString(inputMap);
// List<NameValuePair> queryparams = URLEncodedUtils.parse(queryString, StandardCharsets.UTF_8);
// HashMap<String, String> mappedParams = new HashMap<>();
// for (NameValuePair param : queryparams) {
// mappedParams.put(param.getName(), param.getValue());
// }
// return mappedParams;
}
public static Map<String, Object> getMap(Map<String, Object> parentMap, String childKey) { public static Map<String, Object> getMap(Map<String, Object> parentMap, String childKey) {
if ((parentMap.get(childKey) != null) && (parentMap.get(childKey) instanceof Map<?, ?>)) { if ((parentMap.get(childKey) != null) && (parentMap.get(childKey) instanceof Map<?, ?>)) {
return ((Map<String, Object>) parentMap.get(childKey)); return ((Map<String, Object>) parentMap.get(childKey));

View File

@ -1,27 +0,0 @@
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Map;
public class ListAdder {
private DBConnector connector;
private String cognitoID;
private final String LIST_CREATE = "INSERT INTO Lists (Name, Owner) VALUES (?, ?)";
ListAdder(DBConnector connector, String cognitoID) {
this.connector = connector;
this.cognitoID = cognitoID;
}
public void add(Map<String, Object> bodyMap) throws SQLException {
Connection connection = connector.getConnection();
PreparedStatement statement = connection.prepareStatement(LIST_CREATE);
statement.setString(1, bodyMap.get("name").toString());//Needs safe checking
statement.setString(2, cognitoID);
System.out.println(statement);
statement.executeUpdate();
connection.commit();
}
}

View File

@ -1,28 +0,0 @@
import java.io.IOException;
import java.sql.SQLException;
import java.util.Map;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
public class ListPOST implements RequestHandler<Map<String,Object>, String>{
public String handleRequest(Map<String, Object> inputMap, Context unfilled) {
String cognitoID = InputUtils.getCognitoIDFromBody(inputMap);
try {
DBConnector connector = new DBConnector();
try {
new ListAdder(connector, cognitoID).add(InputUtils.getBody(inputMap));
} catch (SQLException e) {
e.printStackTrace();
} finally {
connector.close();
}
} catch (IOException|SQLException|ClassNotFoundException e) {
e.printStackTrace();
throw new RuntimeException(e.getMessage());
}
return null;
}
}

Binary file not shown.

View File

@ -0,0 +1,5 @@
#Generated by Maven
#Mon Oct 05 10:19:24 EDT 2020
groupId=groupId
artifactId=Lists
version=1.0-SNAPSHOT

View File

@ -0,0 +1,4 @@
/Users/MNM/Documents/GitHub/Listify/Lambdas/Lists/src/main/java/CallHandler.java
/Users/MNM/Documents/GitHub/Listify/Lambdas/Lists/src/main/java/DBConnector.java
/Users/MNM/Documents/GitHub/Listify/Lambdas/Lists/src/main/java/BasicHandler.java
/Users/MNM/Documents/GitHub/Listify/Lambdas/Lists/src/main/java/InputUtils.java

View File

@ -50,5 +50,6 @@ dependencies {
implementation 'org.json:json:20200518' implementation 'org.json:json:20200518'
implementation 'com.github.bumptech.glide:glide:4.11.0' implementation 'com.github.bumptech.glide:glide:4.11.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0' annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'
implementation 'com.squareup.okhttp3:okhttp:4.8.1'
} }

View File

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.listify"> package="com.example.listify">
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<application <application
@ -12,22 +13,27 @@
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/AppTheme" android:theme="@style/AppTheme"
android:usesCleartextTraffic="true"> android:usesCleartextTraffic="true">
<activity <activity
android:name=".MainActivity" android:name=".MainActivity"
android:label="@string/app_name" android:label="@string/app_name"
android:theme="@style/AppTheme.NoActionBar"> android:theme="@style/AppTheme.NoActionBar">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter> </intent-filter>
</activity> </activity>
<activity
android:name=".ItemDetails"
android:label=""
android:theme="@style/AppTheme.NoActionBar">
</activity>
<activity <activity
android:name=".SearchResults" android:name=".SearchResults"
android:label="" android:label=""
android:theme="@style/AppTheme.NoActionBar" android:theme="@style/AppTheme.NoActionBar">
>
</activity> </activity>
<activity android:name="com.example.listify.ui.SignupPage" /> <activity android:name="com.example.listify.ui.SignupPage" />
@ -35,6 +41,7 @@
<activity android:name="com.example.listify.ui.ForgotPasswordPage" /> <activity android:name="com.example.listify.ui.ForgotPasswordPage" />
<activity android:name="com.example.listify.ui.ResetPasswordPage" /> <activity android:name="com.example.listify.ui.ResetPasswordPage" />
<activity android:name="com.example.listify.List" /> <activity android:name="com.example.listify.List" />
</application> </application>
</manifest> </manifest>

View File

@ -8,6 +8,7 @@ import com.amplifyframework.auth.options.AuthSignUpOptions;
import com.amplifyframework.auth.result.AuthSignInResult; import com.amplifyframework.auth.result.AuthSignInResult;
import com.amplifyframework.auth.result.AuthSignUpResult; import com.amplifyframework.auth.result.AuthSignUpResult;
import com.amplifyframework.core.Amplify; import com.amplifyframework.core.Amplify;
import com.example.listify.data.User;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
@ -44,6 +45,17 @@ public class AuthManager {
} }
public String getUserToken() { public String getUserToken() {
if (authSession == null) {
try {
fetchAuthSession();
} catch (AuthException e) {
e.printStackTrace();
return "";
}
}
if (authSession.isSignedIn() == false) {
return "";
}
return authSession.getUserPoolTokens().getValue().getIdToken(); return authSession.getUserPoolTokens().getValue().getIdToken();
} }
@ -78,6 +90,10 @@ public class AuthManager {
waiting = false; waiting = false;
} }
public void signOutSuccess() {
waiting = false;
}
public void startSignUp(String email, String password) throws AuthException { public void startSignUp(String email, String password) throws AuthException {
this.email = email; this.email = email;
this.password = password; this.password = password;
@ -117,7 +133,17 @@ public class AuthManager {
throwIfAuthError(); throwIfAuthError();
} }
public void deleteUser(Requestor requestor) throws AuthException {
requestor.deleteObject("N/A", User.class);
signOutUser();
}
public void signOutUser() throws AuthException {
authSession = null;
waiting = true;
Amplify.Auth.signOut(this::signOutSuccess, error -> setAuthError(error));
throwIfAuthError();
}
public static Properties loadProperties(Context context, String path) throws IOException, JSONException { public static Properties loadProperties(Context context, String path) throws IOException, JSONException {
Properties toReturn = new Properties(); Properties toReturn = new Properties();

View File

@ -0,0 +1,68 @@
package com.example.listify;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.EditText;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.DialogFragment;
public class CreateListDialogFragment extends DialogFragment {
public interface OnNewListListener {
void sendNewListName(String name);
}
public OnNewListListener onNewListListener;
EditText etNewListName;
public CreateListDialogFragment() {}
@Override
public Dialog onCreateDialog(final Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
// Get the layout inflater
LayoutInflater inflater = requireActivity().getLayoutInflater();
// Inflate and set the layout for the dialog
// Pass null as the parent view because its going in the dialog layout
View root = inflater.inflate(R.layout.dialog_create_list, null);
builder.setView(root)
// Add action buttons
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
onNewListListener.sendNewListName(etNewListName.getText().toString());
}
})
.setNegativeButton("cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
CreateListDialogFragment.this.getDialog().cancel();
}
});
etNewListName = (EditText) root.findViewById(R.id.et_new_list_name);
return builder.create();
}
// Required to extend DialogFragment
@Override
public void onAttach(@NonNull Context context) {
super.onAttach(context);
try {
onNewListListener = (OnNewListListener) getActivity();
} catch (ClassCastException e) {
Log.e("CreateListDialogFragment", "onAttach: ClassCastException: " + e.getMessage());
}
}
}

View File

@ -1,34 +0,0 @@
package com.example.listify;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;
public class First2Fragment extends Fragment {
@Override
public View onCreateView(
LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState
) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_first2, container, false);
}
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
view.findViewById(R.id.button_first).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
NavHostFragment.findNavController(First2Fragment.this)
.navigate(R.id.action_First2Fragment_to_Second2Fragment);
}
});
}
}

View File

@ -1,34 +0,0 @@
package com.example.listify;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;
public class FirstFragment extends Fragment {
@Override
public View onCreateView(
LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState
) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_first, container, false);
}
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
view.findViewById(R.id.button_first).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
NavHostFragment.findNavController(FirstFragment.this)
.navigate(R.id.action_FirstFragment_to_SecondFragment);
}
});
}
}

View File

@ -0,0 +1,142 @@
package com.example.listify;
import android.os.Bundle;
import com.bumptech.glide.Glide;
import com.example.listify.model.Product;
import com.example.listify.model.ShoppingList;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import android.view.View;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
public class ItemDetails extends AppCompatActivity implements ListPickerDialogFragment.OnListPickListener, CreateListDialogFragment.OnNewListListener {
private Product curProduct;
private LinearLayout linAddItem;
private LinearLayout linCreateList;
private TextView tvCreateNew;
private TextView tvAddItem;
private TextView tvItemName;
private TextView tvStoreName;
private ImageView itemImage;
private TextView tvItemPrice;
private TextView tvItemDesc;
private ImageButton backToSearchbutton;
ArrayList<ShoppingList> shoppingLists = new ArrayList<>();
private boolean isFABOpen = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_item_details);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// Load Product object from search results activity
curProduct = (Product) getIntent().getSerializableExtra("SelectedProduct");
// Set up floating action buttons
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
linAddItem = (LinearLayout) findViewById(R.id.lin_add_item);
linCreateList = (LinearLayout) findViewById(R.id.lin_create_list);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (!isFABOpen) {
showFABMenu();
} else {
closeFABMenu();
}
}
});
linAddItem.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
closeFABMenu();
// Hardcode shopping lists to demonstrate displaying lists
for (int i = 0; i < 10; i++) {
shoppingLists.add(new ShoppingList(Integer.toString(i)));
}
ListPickerDialogFragment listPickerDialog = new ListPickerDialogFragment(shoppingLists);
listPickerDialog.show(getSupportFragmentManager(), "User Lists");
}
});
linCreateList.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
closeFABMenu();
CreateListDialogFragment createListDialogFragment = new CreateListDialogFragment();
createListDialogFragment.show(getSupportFragmentManager(), "Create New List");
}
});
// Set data
tvItemName = (TextView) findViewById(R.id.item_name);
tvItemName.setText(curProduct.getItemName());
itemImage = (ImageView) findViewById(R.id.item_image);
Glide.with(this).load(curProduct.getImageUrl()).into(itemImage);
tvStoreName = (TextView) findViewById(R.id.store_name);
tvStoreName.setText(curProduct.getChainName());
tvItemPrice = (TextView) findViewById(R.id.item_price);
tvItemPrice.setText(String.format("$%.2f", curProduct.getPrice()));
tvItemDesc = (TextView) findViewById(R.id.item_desc);
tvItemDesc.setText(curProduct.getDescription());
tvCreateNew = (TextView) findViewById(R.id.create_new_list);
tvCreateNew.setVisibility(View.INVISIBLE);
tvAddItem = (TextView) findViewById(R.id.add_item_to_list);
tvAddItem.setVisibility(View.INVISIBLE);
backToSearchbutton = (ImageButton) findViewById(R.id.back_to_search_results_button);
backToSearchbutton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
}
private void showFABMenu(){
isFABOpen=true;
linAddItem.animate().translationY(-getResources().getDimension(R.dimen.standard_55));
linCreateList.animate().translationY(-getResources().getDimension(R.dimen.standard_105));
tvAddItem.setVisibility(View.VISIBLE);
tvCreateNew.setVisibility(View.VISIBLE);
}
private void closeFABMenu(){
isFABOpen=false;
linAddItem.animate().translationY(0);
linCreateList.animate().translationY(0);
tvAddItem.setVisibility(View.INVISIBLE);
tvCreateNew.setVisibility(View.INVISIBLE);
}
@Override
public void sendListSelection(int selectedListIndex, int quantity) {
Toast.makeText(this, String.format("%d of Item added to %s", quantity, shoppingLists.get(selectedListIndex).getName()), Toast.LENGTH_LONG).show();
}
@Override
public void sendNewListName(String name) {
Toast.makeText(this, String.format("%s created", name), Toast.LENGTH_LONG).show();
}
}

View File

@ -1,15 +1,19 @@
package com.example.listify; package com.example.listify;
import android.content.Context; import android.content.Context;
import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.AdapterView; import android.widget.AdapterView;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.ListView; import android.widget.ListView;
import android.widget.TextView; import android.widget.TextView;
import java.util.ArrayList;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
@ -17,40 +21,64 @@ import androidx.appcompat.app.AppCompatActivity;
public class List extends AppCompatActivity { public class List extends AppCompatActivity {
ListView listView; ListView listView;
String listName = "Sample List"; MyAdapter myAdapter;
String[] pNames = {"Half-gallon organic whole milk"};
String[] pStores = {"Kroger"};
String[] pPrices = {"$5.00"};
int[] pImages = {R.drawable.milk};
//List(String name) { Button incrQuan;
// listName = name; Button decrQuan;
//} Button removeItem;
ArrayList<String> pNames = new ArrayList<>(); //String[] pNames = {"Half-gallon organic whole milk"};
ArrayList<String> pStores = new ArrayList<>(); //String[] pStores = {"Kroger"};
ArrayList<String> pPrices = new ArrayList<>(); //String[] pPrices = {"$5.00"};
ArrayList<String> pQuantity = new ArrayList<>(); //String[] pQuantity = {"1"};
ArrayList<Integer> pImages = new ArrayList<>(); //int[] pImages = {R.drawable.milk};
@Override @Override
protected void onCreate(@Nullable Bundle savedInstanceState) { protected void onCreate(@Nullable Bundle savedInstanceState) {
pNames.add("Half-gallon organic whole milk");
pStores.add("Kroger");
pPrices.add("$5.00");
pQuantity.add("1");
pImages.add(R.drawable.milk);
pNames.add("5-bunch medium bananas");
pStores.add("Kroger");
pPrices.add("$3.00");
pQuantity.add("1");
pImages.add(R.drawable.bananas);
pNames.add("JIF 40-oz creamy peanut butter");
pStores.add("Kroger");
pPrices.add("$7.00");
pQuantity.add("1");
pImages.add(R.drawable.peanutbutter);
int currSize = pNames.size();
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list); setContentView(R.layout.activity_list);
listView = findViewById(R.id.listView); listView = findViewById(R.id.listView);
myAdapter = new MyAdapter(this, pNames, pStores, pPrices, pQuantity, pImages);
MyAdapter myAdapter = new MyAdapter(this, pNames, pStores, pPrices, pImages);
listView.setAdapter(myAdapter); listView.setAdapter(myAdapter);
} }
class MyAdapter extends ArrayAdapter<String> { class MyAdapter extends ArrayAdapter<String> {
Context context; Context context;
String[] pNames; ArrayList<String> pNames; //String[] pNames;
String[] pStores; ArrayList<String> pStores; //String[] pStores;
String[] pPrices; ArrayList<String> pPrices; //String[] pPrices;
int[] pImages; ArrayList<String> pQuantity; //String[] pQuantity;
ArrayList<Integer> pImages; //int[] pImages;
MyAdapter (Context c, String[] names, String[] stores, String[] prices, int[] images) { MyAdapter (Context c, ArrayList<String> names, ArrayList<String> stores, ArrayList<String> prices, ArrayList<String> quantity, ArrayList<Integer> images) {
super(c, R.layout.listproduct, R.id.productView, names); super(c, R.layout.listproduct, R.id.productView, names);
context = c; context = c;
pNames = names; pNames = names;
pStores = stores; pStores = stores;
pPrices = prices; pPrices = prices;
pQuantity = quantity;
pImages = images; pImages = images;
} }
@ -60,15 +88,65 @@ public class List extends AppCompatActivity {
LayoutInflater layoutInflater = (LayoutInflater) getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); LayoutInflater layoutInflater = (LayoutInflater) getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View listproduct = layoutInflater.inflate(R.layout.listproduct, parent,false); View listproduct = layoutInflater.inflate(R.layout.listproduct, parent,false);
ImageView image = listproduct.findViewById(R.id.imageView); decrQuan = (Button) listproduct.findViewById(R.id.buttonDecr);
incrQuan = (Button) listproduct.findViewById(R.id.buttonIncr);
removeItem = (Button) listproduct.findViewById(R.id.buttonDel);
decrQuan.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int q = Integer.parseInt(pQuantity.get(position)) - 1;
pQuantity.set(position, Integer.toString(q));
listView.setAdapter(myAdapter);
}
});
if(Integer.parseInt(pQuantity.get(position)) <= 1) {
decrQuan.setEnabled(false);
}
if(Integer.parseInt(pQuantity.get(position)) < 10) {
incrQuan.setEnabled(true);
}
incrQuan.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int q = Integer.parseInt(pQuantity.get(position)) + 1;
pQuantity.set(position, Integer.toString(q));
listView.setAdapter(myAdapter);
}
});
if(Integer.parseInt(pQuantity.get(position)) > 1) {
decrQuan.setEnabled(true);
}
if(Integer.parseInt(pQuantity.get(position)) >= 10) {
incrQuan.setEnabled(false);
}
removeItem.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
pNames.remove(position);
pStores.remove(position);
pPrices.remove(position);
pQuantity.remove(position);
pImages.remove(position);
listView.setAdapter(myAdapter);
}
});
TextView name = listproduct.findViewById(R.id.productView); TextView name = listproduct.findViewById(R.id.productView);
TextView store = listproduct.findViewById(R.id.storeView); TextView store = listproduct.findViewById(R.id.storeView);
TextView price = listproduct.findViewById(R.id.priceView); TextView price = listproduct.findViewById(R.id.priceView);
TextView quantity = listproduct.findViewById(R.id.quantityView);
ImageView image = listproduct.findViewById(R.id.imageView);
image.setImageResource(pImages[position]); if(!pNames.isEmpty()) {
name.setText(pNames[position]); name.setText(pNames.get(position));
store.setText(pStores[position]); store.setText(pStores.get(position));
price.setText(pPrices[position]); price.setText(pPrices.get(position));
quantity.setText(pQuantity.get(position));
image.setImageResource(pImages.get(position));
}
return listproduct; return listproduct;
} }

View File

@ -0,0 +1,121 @@
package com.example.listify;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.DialogFragment;
import com.example.listify.adapter.DisplayShoppingListsAdapter;
import com.example.listify.model.ShoppingList;
import java.util.ArrayList;
public class ListPickerDialogFragment extends DialogFragment {
public interface OnListPickListener {
void sendListSelection(int selectedListIndex, int quantity);
}
public OnListPickListener onListPickListener;
ListView userListsView;
DisplayShoppingListsAdapter displayShoppingListsAdapter;
Button btnMinus;
Button btnPlus;
EditText etQuantity;
private ArrayList<ShoppingList> userLists;
private int selectedListIndex;
public ListPickerDialogFragment(ArrayList<ShoppingList> userLists) {
this.userLists = userLists;
}
@Override
public Dialog onCreateDialog(final Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
// Get the layout inflater
LayoutInflater inflater = requireActivity().getLayoutInflater();
// Inflate and set the layout for the dialog
// Pass null as the parent view because its going in the dialog layout
View root = inflater.inflate(R.layout.dialog_add_to_list, null);
builder.setView(root)
// Add action buttons
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
onListPickListener.sendListSelection(selectedListIndex, Integer.parseInt(etQuantity.getText().toString()));
}
})
.setNegativeButton("cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
ListPickerDialogFragment.this.getDialog().cancel();
}
});
// Display user's shopping lists
userListsView = (ListView) root.findViewById(R.id.user_lists);
displayShoppingListsAdapter = new DisplayShoppingListsAdapter(getActivity(), userLists);
userListsView.setAdapter(displayShoppingListsAdapter);
userListsView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
for (int i = 0; i < parent.getChildCount(); i++) {
parent.getChildAt(i).setBackgroundColor(Color.TRANSPARENT);
}
view.setBackgroundColor(Color.GREEN);
selectedListIndex = position;
}
});
// Set up quantity selection
etQuantity = (EditText) root.findViewById(R.id.et_quantity);
btnMinus = (Button) root.findViewById(R.id.btn_minus);
btnMinus.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int curQauntity = Integer.parseInt(etQuantity.getText().toString());
if (curQauntity > 0) {
curQauntity--;
etQuantity.setText(String.format("%d", curQauntity));
}
}
});
btnPlus = (Button) root.findViewById(R.id.btn_plus);
btnPlus.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int curQauntity = Integer.parseInt(etQuantity.getText().toString());
curQauntity++;
etQuantity.setText(String.format("%d", curQauntity));
}
});
return builder.create();
}
// Required to extend DialogFragment
@Override
public void onAttach(@NonNull Context context) {
super.onAttach(context);
try {
onListPickListener = (OnListPickListener) getActivity();
} catch (ClassCastException e) {
Log.e("ListPickerDialogFragment", "onAttach: ClassCastException: " + e.getMessage());
}
}
}

View File

@ -13,11 +13,18 @@ import androidx.navigation.Navigation;
import androidx.navigation.ui.AppBarConfiguration; import androidx.navigation.ui.AppBarConfiguration;
import androidx.navigation.ui.NavigationUI; import androidx.navigation.ui.NavigationUI;
import com.amplifyframework.auth.AuthException; import com.amplifyframework.auth.AuthException;
import com.example.listify.data.Item;
import com.example.listify.data.ItemSearch;
import com.example.listify.data.List;
import com.example.listify.data.ListEntry;
import com.google.android.material.navigation.NavigationView; import com.google.android.material.navigation.NavigationView;
import org.json.JSONException; import org.json.JSONException;
import java.io.IOException; import java.io.IOException;
import java.time.Instant;
import java.util.Arrays;
import java.util.Properties; import java.util.Properties;
import java.util.Random;
public class MainActivity extends AppCompatActivity { public class MainActivity extends AppCompatActivity {
private AppBarConfiguration mAppBarConfiguration; private AppBarConfiguration mAppBarConfiguration;
@ -25,15 +32,20 @@ public class MainActivity extends AppCompatActivity {
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
//------------------------------Auth Testing---------------------------------------------// //------------------------------Auth Testing---------------------------------------------//
/*AuthManager authManager = new AuthManager(); boolean testAuth = false;
if (testAuth) {
AuthManager authManager = new AuthManager();
try { try {
authManager.signIn("merzn@purdue.edu", "Password123"); authManager.signIn("merzn@purdue.edu", "Password123");
Log.i("Authentication", authManager.getAuthSession().toString()); Log.i("Authentication", authManager.getAuthSession().toString());
Log.i("Token", authManager.getAuthSession().getUserPoolTokens().getValue().getIdToken()); Log.i("Token", authManager.getAuthSession().getUserPoolTokens().getValue().getIdToken());
} } catch (AuthException e) {
catch (AuthException e) {
Log.i("Authentication", "Login failed. User probably needs to register. Exact error: " + e.getMessage()); Log.i("Authentication", "Login failed. User probably needs to register. Exact error: " + e.getMessage());
try { try {
authManager.startSignUp("merzn@purdue.edu", "Password123"); authManager.startSignUp("merzn@purdue.edu", "Password123");
@ -41,26 +53,66 @@ public class MainActivity extends AppCompatActivity {
} catch (AuthException signUpError) { } catch (AuthException signUpError) {
Log.e("Authentication", "SignUp error: " + signUpError.getMessage()); Log.e("Authentication", "SignUp error: " + signUpError.getMessage());
} }
}*/ }
}
//NOTE: deleteUser is slightly unusual in that it requires a Requestor. See below for building one
//authManager.deleteUser(requestor);
//------------------------------------------------------------------------------------------//
boolean testAPI = false;
//----------------------------------API Testing---------------------------------------------// //----------------------------------API Testing---------------------------------------------//
/*Properties configs = new Properties(); if (testAPI) {
AuthManager authManager = new AuthManager();
try {
authManager.signIn("merzn@purdue.edu", "Password123");
} catch (AuthException e) {
e.printStackTrace();
}
Properties configs = new Properties();
try { try {
configs = AuthManager.loadProperties(this, "android.resource://" + getPackageName() + "/raw/auths.json"); configs = AuthManager.loadProperties(this, "android.resource://" + getPackageName() + "/raw/auths.json");
} } catch (IOException | JSONException e) {
catch (IOException|JSONException e) {
e.printStackTrace(); e.printStackTrace();
}*/ }
/*Requestor requestor = new Requestor(this, authManager,configs.getProperty("apiKey")); Requestor requestor = new Requestor(authManager, configs.getProperty("apiKey"));
List testList = new List("IAmATestList");
//The name is the only part of this that is used, the rest is generated by the Lambda.
List testList = new List(-1, "New List", "user filled by lambda", Instant.now().toEpochMilli());
//Everything except addedDate is used for ItemEntry
ListEntry entry = new ListEntry(1, 4, Math.abs(new Random().nextInt()), Instant.now().toEpochMilli(),false);
SynchronousReceiver<Integer> idReceiver = new SynchronousReceiver<>();
try { try {
requestor.postObject(testList); requestor.postObject(testList, idReceiver, idReceiver);
} System.out.println(idReceiver.await());
catch (JSONException e) { requestor.postObject(entry);
} catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
}*/ }
SynchronousReceiver<Item> itemReceiver = new SynchronousReceiver<>();
requestor.getObject("1", Item.class, itemReceiver, itemReceiver);
SynchronousReceiver<List> listReceiver = new SynchronousReceiver<>();
requestor.getObject("39", List.class, listReceiver, listReceiver);
SynchronousReceiver<Integer[]> listIdsReceiver = new SynchronousReceiver<>();
requestor.getListOfIds(List.class, listIdsReceiver, listIdsReceiver);
SynchronousReceiver<ItemSearch> itemSearchReceiver = new SynchronousReceiver<>();
requestor.getObject("r", ItemSearch.class, itemSearchReceiver, itemSearchReceiver);
try {
System.out.println(itemReceiver.await());
System.out.println(listReceiver.await());
System.out.println(Arrays.toString(listIdsReceiver.await()));
System.out.println(itemSearchReceiver.await());
} catch (Exception receiverError) {
receiverError.printStackTrace();
}
}
//------------------------------------------------------------------------------------------//
setContentView(R.layout.activity_main); setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar); Toolbar toolbar = findViewById(R.id.toolbar);

View File

@ -1,66 +1,130 @@
package com.example.listify; package com.example.listify;
import android.content.Context; import android.util.Log;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.toolbox.JsonObjectRequest;
import com.android.volley.toolbox.Volley;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
import okhttp3.*;
import org.jetbrains.annotations.NotNull;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject;
import java.util.HashMap; import java.io.IOException;
import java.util.Map;
public class Requestor { public class Requestor {
private final String DEV_BASEURL = "https://datoh7woc9.execute-api.us-east-2.amazonaws.com/Development"; private final String DEV_BASEURL = "https://datoh7woc9.execute-api.us-east-2.amazonaws.com/Development";
AuthManager authManager; AuthManager authManager;
RequestQueue queue;
String apiKey; String apiKey;
OkHttpClient client;
Requestor(Context context, AuthManager authManager, String apiKey) { Requestor(AuthManager authManager, String apiKey) {
queue = Volley.newRequestQueue(context);
this.authManager = authManager; this.authManager = authManager;
this.apiKey = apiKey; this.apiKey = apiKey;
client = new OkHttpClient();
}
public <T> void getListOfIds(Class<T> ofType, Receiver<Integer[]> successHandler, RequestErrorHandler failureHandler) {
String getURL = DEV_BASEURL + "/" + ofType.getSimpleName() + "?id=-1";
Request postRequest = buildBaseRequest(getURL, "GET", null);
launchCall(postRequest, successHandler, Integer[].class, failureHandler);
} }
public <T> void getObject(String id, Class<T> classType, Receiver<T> receiver) { public <T> void getObject(String id, Class<T> classType, Receiver<T> receiver) {
String getURL = DEV_BASEURL + "/" + classType.getSimpleName() + "?id=" + id; getObject(id, classType, receiver, null);
} }
public void postObject(Object toPost, Response.ErrorListener failureHandler) throws JSONException { public <T> void getObject(String id, Class<T> classType, Receiver<T> successHandler, RequestErrorHandler failureHandler) {
String postURL = DEV_BASEURL + "/" + toPost.getClass().getSimpleName(); String getURL = DEV_BASEURL + "/" + classType.getSimpleName() + "?id=" + id;
queue.add(buildRequest(postURL, toPost, null, failureHandler)); Request getRequest = buildBaseRequest(getURL, "GET", null);
launchCall(getRequest, successHandler, classType, failureHandler);
}
public void deleteObject(String id, Class classType) {
deleteObject(id, classType, null);
}
public void deleteObject(String id, Class classType, RequestErrorHandler failureHandler) {
String deleteURL = DEV_BASEURL + "/" + classType.getSimpleName() + "?id=" + id;
Request deleteRequest = buildBaseRequest(deleteURL, "DELETE", "{}");
launchCall(deleteRequest, null, classType, failureHandler);
} }
public void postObject(Object toPost) throws JSONException { public void postObject(Object toPost) throws JSONException {
postObject(toPost, null); postObject(toPost, (RequestErrorHandler) null);
} }
private JsonObjectRequest buildRequest(String url, Object toJSONify, Response.Listener<JSONObject> successHandler, Response.ErrorListener failureHandler) throws JSONException { public void postObject(Object toPost, RequestErrorHandler failureHandler) throws JSONException {
return buildRequest(url, new JSONObject(new Gson().toJson(toJSONify)), successHandler, failureHandler); postObject(toPost, null, failureHandler);
} }
private JsonObjectRequest buildRequest(String url, JSONObject jsonBody, Response.Listener<JSONObject> successHandler, Response.ErrorListener failureHandler) { public void postObject(Object toPost, Receiver<Integer> idReceiver) throws JSONException {
return new JsonObjectRequest(url, jsonBody, successHandler, failureHandler) { postObject(toPost, idReceiver, null);
}
public void postObject(Object toPost, Receiver<Integer> idReceiver, RequestErrorHandler failureHandler) throws JSONException {
String postURL = DEV_BASEURL + "/" + toPost.getClass().getSimpleName();
Request postRequest = buildBaseRequest(postURL, "POST", new Gson().toJson(toPost));
launchCall(postRequest, idReceiver, Integer.class, failureHandler);
}
private void launchCall(Request toLaunch, Receiver receiver, Class classType, RequestErrorHandler failureHandler) {
client.newCall(toLaunch).enqueue(new Callback() {
@Override @Override
public Map<String, String> getHeaders() { public void onResponse(@NotNull Call call, @NotNull okhttp3.Response response) throws IOException {
HashMap<String, String> headers = new HashMap<>(); String responseString = response.body().string();
System.out.println(authManager.getUserToken()); if (receiver != null) {
headers.put("Authorization", authManager.getUserToken()); if (classType == null) {
headers.put("Content-Type", "application/json"); Log.e("Requestor Contract Error", "classType while receiver populated");
headers.put("X-API-Key", apiKey);
return headers;
} }
}; try {
receiver.acceptDelivery(new Gson().fromJson(responseString, classType));
} catch (JsonSyntaxException e) {
System.out.println(e);
Log.e("API response was not proper JSON", responseString);
if (failureHandler != null) {
failureHandler.acceptError(e);
}
//throw new JsonSyntaxException(e);
}
}
Log.d("API Response", responseString);
}
@Override
public void onFailure(@NotNull Call call, IOException e) {
if (failureHandler != null) {
failureHandler.acceptError(e);
} else {
Log.e("Network Error", e.getLocalizedMessage());
}
}
});
} }
public class Receiver<T> { public static final MediaType JSON
public void acceptDelivery(T delivered) { = MediaType.parse("application/json; charset=utf-8");
} private Request buildBaseRequest(String url, String method, String bodyJSON) {
Request.Builder requestBase = addAuthHeaders(new Request.Builder().url(url));
if (method == "GET") {
requestBase.get();
} else {
requestBase.method(method, RequestBody.create(bodyJSON, JSON));
}
return requestBase.build();
}
private Request.Builder addAuthHeaders(Request.Builder toAuthorize) {
toAuthorize.addHeader("Authorization", authManager.getUserToken());
toAuthorize.addHeader("X-API-Key", apiKey);
return toAuthorize;
}
public interface Receiver<T> {
void acceptDelivery(T delivered);
}
public interface RequestErrorHandler {
void acceptError(Exception error);
} }
} }

View File

@ -1,4 +1,5 @@
package com.example.listify; package com.example.listify;
import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar; import androidx.appcompat.widget.Toolbar;
@ -77,7 +78,12 @@ public class SearchResults extends AppCompatActivity implements SortDialogFragme
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override @Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) { public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(SearchResults.this, resultsProductListSorted.get(position).getItemName(), Toast.LENGTH_SHORT).show(); // Toast.makeText(SearchResults.this, resultsProductListSorted.get(position).getItemName(), Toast.LENGTH_SHORT).show();
Intent itemDetailsPage = new Intent(SearchResults.this, ItemDetails.class);
// Send the selected product
itemDetailsPage.putExtra("SelectedProduct", resultsProductListSorted.get(position));
startActivity(itemDetailsPage);
} }
}); });
@ -129,6 +135,9 @@ public class SearchResults extends AppCompatActivity implements SortDialogFragme
// TODO: Create a new Product Object for each result // TODO: Create a new Product Object for each result
// TODO: Add each result to productList // TODO: Add each result to productList
// Clear the old search results
resultsProductList = new ArrayList<>();
// Hardcode some search results... // Hardcode some search results...
for (int i = 0; i < 2; i++) { for (int i = 0; i < 2; i++) {
Product a = new Product("Bottled Water", "0000", "Walmart", "0001", "0123456780", "Bro, it's water...", "Grocery", 13.37, "9/24/2020", "1", "http://3.bp.blogspot.com/-MfroPPQVDKo/UyhUZWqGvkI/AAAAAAAAB-I/DGk622onsvc/s1600/lettuce-b-kool-cat-meme.jpg"); Product a = new Product("Bottled Water", "0000", "Walmart", "0001", "0123456780", "Bro, it's water...", "Grocery", 13.37, "9/24/2020", "1", "http://3.bp.blogspot.com/-MfroPPQVDKo/UyhUZWqGvkI/AAAAAAAAB-I/DGk622onsvc/s1600/lettuce-b-kool-cat-meme.jpg");
@ -136,8 +145,16 @@ public class SearchResults extends AppCompatActivity implements SortDialogFragme
Product c = new Product("Lettuce", "0002", "Walmart", "0001", "0123456782", "Burger King foot lettuce", "Grocery", 0.60, "9/24/2020", "1", "https://www.cattitudedaily.com/wp-content/uploads/2019/12/white-cat-meme-feature.jpg"); Product c = new Product("Lettuce", "0002", "Walmart", "0001", "0123456782", "Burger King foot lettuce", "Grocery", 0.60, "9/24/2020", "1", "https://www.cattitudedaily.com/wp-content/uploads/2019/12/white-cat-meme-feature.jpg");
Product d = new Product("Video Game", "0003", "Walmart", "0001", "0123456783", "Fun Vidya Gaemz", "Electronics", 60.00, "9/24/2020", "1", "https://i1.wp.com/bestlifeonline.com/wp-content/uploads/2018/06/cat-meme-67.jpg?resize=1024%2C1024&ssl=1"); Product d = new Product("Video Game", "0003", "Walmart", "0001", "0123456783", "Fun Vidya Gaemz", "Electronics", 60.00, "9/24/2020", "1", "https://i1.wp.com/bestlifeonline.com/wp-content/uploads/2018/06/cat-meme-67.jpg?resize=1024%2C1024&ssl=1");
Product e = new Product("Mountain Dew", "0004", "Walmart", "0001", "0123456784", "Gamer fuel", "Grocery", 5.87, "9/24/2020", "1", "https://memeguy.com/photos/images/gaming-cat-7680.png"); Product e = new Product("Mountain Dew", "0004", "Walmart", "0001", "0123456784", "Gamer fuel", "Grocery", 5.87, "9/24/2020", "1", "https://memeguy.com/photos/images/gaming-cat-7680.png");
Product f = new Product("Tire", "0005", "Walmart", "0001", "0123456785", "30 inch rims", "Automotive", 146.97, "9/24/2020", "1", "http://cdn.sheknows.com/articles/2013/05/pet5.jpg"); Product f = new Product("Tire", "0005", "Kroger", "0002", "0123456785", "30 inch rims", "Automotive", 146.97, "9/24/2020", "1", "http://cdn.sheknows.com/articles/2013/05/pet5.jpg");
Product g = new Product("Bottled Water", "0000", "Target", "0001", "0123456780", "Bro, it's water...", "Grocery", 13.37, "9/24/2020", "1", "http://3.bp.blogspot.com/-MfroPPQVDKo/UyhUZWqGvkI/AAAAAAAAB-I/DGk622onsvc/s1600/lettuce-b-kool-cat-meme.jpg"); Product g = new Product("This is a test for a product that has a very long title to see if the text overflows", "0006", "Target", "0003", "0123456786", "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Elit ut aliquam purus sit amet luctus venenatis. Tellus orci ac auctor augue mauris augue neque gravida. Habitant morbi tristique senectus et netus. Dignissim diam quis enim lobortis. Suspendisse sed nisi lacus sed viverra tellus in. Viverra adipiscing at in tellus integer feugiat scelerisque. Volutpat consequat mauris nunc congue nisi vitae suscipit tellus. Habitant morbi tristique senectus et netus et malesuada. Quis enim lobortis scelerisque fermentum dui faucibus in ornare quam. Mattis pellentesque id nibh tortor id aliquet. Volutpat blandit aliquam etiam erat. Vestibulum lorem sed risus ultricies tristique nulla aliquet.\n" +
"\n" +
"Placerat orci nulla pellentesque dignissim. Quisque non tellus orci ac. Mattis enim ut tellus elementum sagittis vitae et. Interdum velit euismod in pellentesque massa placerat duis ultricies. Id nibh tortor id aliquet lectus. Massa placerat duis ultricies lacus sed. Convallis convallis tellus id interdum velit laoreet id donec. Amet luctus venenatis lectus magna fringilla urna porttitor rhoncus. Sodales ut eu sem integer vitae justo. Viverra ipsum nunc aliquet bibendum enim facilisis.\n" +
"\n" +
"Eget felis eget nunc lobortis mattis aliquam faucibus purus. Odio morbi quis commodo odio aenean sed adipiscing. Hac habitasse platea dictumst quisque sagittis purus sit. Nam libero justo laoreet sit. Et malesuada fames ac turpis egestas. Erat nam at lectus urna duis convallis convallis. Morbi tincidunt ornare massa eget egestas purus viverra accumsan in. Ut venenatis tellus in metus vulputate eu scelerisque felis imperdiet. At auctor urna nunc id cursus. Sed elementum tempus egestas sed. Lorem dolor sed viverra ipsum nunc aliquet bibendum. Orci eu lobortis elementum nibh tellus molestie. Porttitor leo a diam sollicitudin tempor. Adipiscing bibendum est ultricies integer quis auctor elit sed. Arcu cursus euismod quis viverra nibh. A diam sollicitudin tempor id eu nisl.\n" +
"\n" +
"Sapien eget mi proin sed libero enim sed faucibus turpis. Pharetra massa massa ultricies mi quis hendrerit dolor magna. Integer enim neque volutpat ac tincidunt vitae semper. Euismod lacinia at quis risus sed vulputate. Ut venenatis tellus in metus vulputate eu scelerisque. Etiam erat velit scelerisque in dictum non consectetur. Viverra nam libero justo laoreet sit amet cursus sit. Arcu non sodales neque sodales. Vivamus arcu felis bibendum ut tristique et egestas quis. Sed adipiscing diam donec adipiscing tristique risus. Sollicitudin tempor id eu nisl nunc mi ipsum faucibus vitae. Velit ut tortor pretium viverra suspendisse potenti nullam ac tortor. Non nisi est sit amet facilisis magna etiam. Tortor at risus viverra adipiscing. Donec ultrices tincidunt arcu non sodales neque sodales. Eget egestas purus viverra accumsan. Enim lobortis scelerisque fermentum dui faucibus in ornare. Porttitor massa id neque aliquam. Ut consequat semper viverra nam. Orci ac auctor augue mauris augue neque gravida.\n" +
"\n" +
"Lacus sed viverra tellus in hac habitasse platea dictumst. Nec ullamcorper sit amet risus nullam eget felis eget nunc. Semper feugiat nibh sed pulvinar. Consequat nisl vel pretium lectus quam id leo in. Volutpat maecenas volutpat blandit aliquam etiam erat velit scelerisque. Faucibus a pellentesque sit amet porttitor eget. Sed viverra tellus in hac habitasse platea dictumst vestibulum. Placerat vestibulum lectus mauris ultrices eros in cursus turpis. Sed tempus urna et pharetra pharetra massa massa ultricies mi. Ornare arcu odio ut sem. Ornare arcu dui vivamus arcu felis bibendum ut. Feugiat pretium nibh ipsum consequat. Consectetur adipiscing elit ut aliquam purus sit amet luctus venenatis. Felis eget velit aliquet sagittis id consectetur purus ut.", "Automotive", 45.22, "9/24/2020", "1", "http://cdn.sheknows.com/articles/2013/05/pet5.jpg");
Product h = new Product("Tin Foil", "0001", "Kroger", "0001", "0123456781", "Not aluminum foil", "Grocery", 1.00, "9/24/2020", "1", "https://i.ytimg.com/vi/q9N1doYMxR0/maxresdefault.jpg"); Product h = new Product("Tin Foil", "0001", "Kroger", "0001", "0123456781", "Not aluminum foil", "Grocery", 1.00, "9/24/2020", "1", "https://i.ytimg.com/vi/q9N1doYMxR0/maxresdefault.jpg");
resultsProductList.add(a); resultsProductList.add(a);
resultsProductList.add(b); resultsProductList.add(b);

View File

@ -1,34 +0,0 @@
package com.example.listify;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;
public class Second2Fragment extends Fragment {
@Override
public View onCreateView(
LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState
) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_second2, container, false);
}
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
view.findViewById(R.id.button_second).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
NavHostFragment.findNavController(Second2Fragment.this)
.navigate(R.id.action_Second2Fragment_to_First2Fragment);
}
});
}
}

View File

@ -1,34 +0,0 @@
package com.example.listify;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;
public class SecondFragment extends Fragment {
@Override
public View onCreateView(
LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState
) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_second, container, false);
}
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
view.findViewById(R.id.button_second).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
NavHostFragment.findNavController(SecondFragment.this)
.navigate(R.id.action_SecondFragment_to_FirstFragment);
}
});
}
}

View File

@ -0,0 +1,37 @@
package com.example.listify;
public class SynchronousReceiver<T> implements Requestor.Receiver<T>, Requestor.RequestErrorHandler {
private volatile boolean waiting;
private volatile Exception error;
private T toReturn;
public SynchronousReceiver() {
waiting = true;
error = null;
}
public T await() throws Exception {
while (waiting) {
Thread.yield();
}
waiting = true;
if (error != null) {
Exception toThrow = error;
error = null;
throw toThrow;
}
return toReturn;
}
@Override
public void acceptDelivery(Object delivered) {
toReturn = (T) delivered;
waiting = false;
}
@Override
public void acceptError(Exception error) {
waiting = false;
this.error = error;
}
}

View File

@ -9,7 +9,6 @@ import android.widget.BaseAdapter;
import android.widget.TextView; import android.widget.TextView;
import com.example.listify.R; import com.example.listify.R;
import com.example.listify.model.ShoppingList; import com.example.listify.model.ShoppingList;
import java.util.ArrayList; import java.util.ArrayList;
public class DisplayShoppingListsAdapter extends BaseAdapter { public class DisplayShoppingListsAdapter extends BaseAdapter {

View File

@ -57,7 +57,11 @@ public class SearchResultsListAdapter extends BaseAdapter {
Product product = productList.get(position); Product product = productList.get(position);
// TODO: If image url is broken, display @drawable/ic_baseline_broken_image_600.xml // TODO: If image url is broken, display @drawable/ic_baseline_broken_image_600.xml
Glide.with(activity).load(product.getImageUrl()).into(productImage); Glide.with(activity).load(product.getImageUrl()).into(productImage);
if (product.getItemName().length() >= 35) {
itemName.setText(product.getItemName().substring(0, 35) + "...");
} else {
itemName.setText(product.getItemName()); itemName.setText(product.getItemName());
}
price.setText(String.format("$%.2f", product.getPrice())); price.setText(String.format("$%.2f", product.getPrice()));
itemStore.setText(product.getChainName()); itemStore.setText(product.getChainName());

View File

@ -0,0 +1,115 @@
package com.example.listify.data;
import java.math.BigDecimal;
public class Item {
Integer productID;
Integer chainID;
String upc;
String description;
BigDecimal price;
String imageURL;
String department;
long retrievedDate;
Integer fetchCounts;
public Item(Integer productID, Integer chainID, String upc, String description, BigDecimal price,
String imageURL, String department, long retrievedDate, Integer fetchCounts) {
this.productID = productID;
this.chainID = chainID;
this.upc = upc;
this.description = description;
this.price = price;
this.imageURL = imageURL;
this.department = department;
this.retrievedDate = retrievedDate;
this.fetchCounts = fetchCounts;
}
@Override
public String toString() {
return "Item{" +
"productID=" + productID +
", chainID=" + chainID +
", upc='" + upc + '\'' +
", description='" + description + '\'' +
", price=" + price +
", imageURL='" + imageURL + '\'' +
", department='" + department + '\'' +
", retrievedDate=" + retrievedDate +
", fetchCounts=" + fetchCounts +
'}';
}
public Integer getProductID() {
return productID;
}
public void setProductID(Integer productID) {
this.productID = productID;
}
public Integer getChainID() {
return chainID;
}
public void setChainID(Integer chainID) {
this.chainID = chainID;
}
public String getUpc() {
return upc;
}
public void setUpc(String upc) {
this.upc = upc;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public BigDecimal getPrice() {
return price;
}
public void setPrice(BigDecimal price) {
this.price = price;
}
public String getImageURL() {
return imageURL;
}
public void setImageURL(String imageURL) {
this.imageURL = imageURL;
}
public String getDepartment() {
return department;
}
public void setDepartment(String department) {
this.department = department;
}
public long getRetrievedDate() {
return retrievedDate;
}
public void setRetrievedDate(long retrievedDate) {
this.retrievedDate = retrievedDate;
}
public Integer getFetchCounts() {
return fetchCounts;
}
public void setFetchCounts(Integer fetchCounts) {
this.fetchCounts = fetchCounts;
}
}

View File

@ -0,0 +1,27 @@
package com.example.listify.data;
import java.util.ArrayList;
public class ItemSearch {
ArrayList<Item> results;
public ItemSearch(ArrayList<Item> results) {
this.results = results;
}
@Override
public String toString() {
return "ItemSearch{" +
"results=" + results +
'}';
}
public ArrayList<Item> getResults() {
return results;
}
public void setResults(ArrayList<Item> results) {
this.results = results;
}
}

View File

@ -0,0 +1,70 @@
package com.example.listify.data;
import java.util.Arrays;
public class List {
Integer itemID;
String name;
String owner;
long lastUpdated;
final ListEntry[] entries;
public List(Integer itemID, String name, String owner, long lastUpdated, ListEntry[] entries) {
this.itemID = itemID;
this.name = name;
this.owner = owner;
this.lastUpdated = lastUpdated;
this.entries = entries;
}
public List(Integer itemID, String name, String owner, long lastUpdated) {
this(itemID, name, owner, lastUpdated, null);
}
@Override
public String toString() {
return "List{" +
"itemID=" + itemID +
", name='" + name + '\'' +
", owner='" + owner + '\'' +
", lastUpdated=" + lastUpdated +
", entries=" + Arrays.toString(entries) +
'}';
}
public Integer getItemID() {
return itemID;
}
public void setItemID(Integer itemID) {
this.itemID = itemID;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getOwner() {
return owner;
}
public void setOwner(String owner) {
this.owner = owner;
}
public long getLastUpdated() {
return lastUpdated;
}
public void setLastUpdated(long lastUpdated) {
this.lastUpdated = lastUpdated;
}
public ListEntry[] getEntries() {
return entries;
}
}

View File

@ -0,0 +1,68 @@
package com.example.listify.data;
public class ListEntry {
Integer listID;
Integer productID;
Integer quantity;
long addedDate;
Boolean purchased;
public ListEntry(Integer listID, Integer productID, Integer quantity, long addedDate, Boolean purchased) {
this.listID = listID;
this.productID = productID;
this.quantity = quantity;
this.addedDate = addedDate;
this.purchased = purchased;
}
@Override
public String toString() {
return "ListEntry{" +
"listID=" + listID +
", productID=" + productID +
", quantity=" + quantity +
", addedDate=" + addedDate +
", purchased=" + purchased +
'}';
}
public Integer getListID() {
return listID;
}
public void setListID(Integer listID) {
this.listID = listID;
}
public Integer getProductID() {
return productID;
}
public void setProductID(Integer productID) {
this.productID = productID;
}
public Integer getQuantity() {
return quantity;
}
public void setQuantity(Integer quantity) {
this.quantity = quantity;
}
public long getAddedDate() {
return addedDate;
}
public void setAddedDate(long addedDate) {
this.addedDate = addedDate;
}
public Boolean getPurchased() {
return purchased;
}
public void setPurchased(Boolean purchased) {
this.purchased = purchased;
}
}

View File

@ -0,0 +1,4 @@
package com.example.listify.data;
public class User {
}

View File

@ -1,6 +1,8 @@
package com.example.listify.model; package com.example.listify.model;
public class Product { import java.io.Serializable;
public class Product implements Serializable {
private String itemName; private String itemName;
private String itemId; private String itemId;
private String chainName; private String chainName;

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

View File

@ -0,0 +1,5 @@
<vector android:height="28dp"
android:viewportHeight="24" android:viewportWidth="24"
android:width="28dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M19,13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/>
</vector>

View File

@ -0,0 +1,5 @@
<vector android:height="28dp"
android:viewportHeight="24" android:viewportWidth="24"
android:width="28dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M3,17.25V21h3.75L17.81,9.94l-3.75,-3.75L3,17.25zM20.71,7.04c0.39,-0.39 0.39,-1.02 0,-1.41l-2.34,-2.34c-0.39,-0.39 -1.02,-0.39 -1.41,0l-1.83,1.83 3.75,3.75 1.83,-1.83z"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector android:height="28dp"
android:viewportHeight="24" android:viewportWidth="24"
android:width="28dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M17,19.22H5V7h7V5H5C3.9,5 3,5.9 3,7v12c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2v-7h-2V19.22z"/>
<path android:fillColor="@android:color/white" android:pathData="M19,2h-2v3h-3c0.01,0.01 0,2 0,2h3v2.99c0.01,0.01 2,0 2,0V7h3V5h-3V2z"/>
<path android:fillColor="@android:color/white" android:pathData="M7,9h8v2h-8z"/>
<path android:fillColor="@android:color/white" android:pathData="M7,12l0,2l8,0l0,-2l-3,0z"/>
<path android:fillColor="@android:color/white" android:pathData="M7,15h8v2h-8z"/>
</vector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 KiB

View File

@ -0,0 +1,96 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ItemDetails">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/AppTheme.PopupOverlay"
>
<ImageButton
android:id="@+id/back_to_search_results_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
app:srcCompat="@drawable/abc_vector_test"
android:background="@null"
android:contentDescription="@string/backButton"/>
</androidx.appcompat.widget.Toolbar>
</com.google.android.material.appbar.AppBarLayout>
<include layout="@layout/content_item_details" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/lin_add_item"
android:layout_gravity="bottom|end"
android:layout_marginBottom="22dp">
<TextView
android:id="@+id/add_item_to_list"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/add_to_list"
android:layout_marginTop="12dp"
android:layout_marginEnd="5dp"/>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab2"
android:layout_width="45dp"
android:layout_height="45dp"
android:layout_marginEnd="22dp"
android:layout_marginStart="5dp"
app:srcCompat="@drawable/ic_baseline_post_add_28" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/lin_create_list"
android:layout_gravity="bottom|end"
android:layout_marginBottom="22dp">
<TextView
android:id="@+id/create_new_list"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/create_new_list"
android:layout_marginTop="12dp"
android:layout_marginEnd="5dp"/>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab1"
android:layout_width="45dp"
android:layout_height="45dp"
android:layout_marginEnd="22dp"
android:layout_marginStart="5dp"
app:srcCompat="@drawable/ic_baseline_create_28" />
</LinearLayout>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="@dimen/fab_margin"
app:srcCompat="@drawable/ic_baseline_add_28" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -0,0 +1,77 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<TextView
android:id="@+id/item_name"
android:layout_width="307dp"
android:layout_height="56dp"
android:layout_marginStart="50dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="50dp"
android:text="@string/default_product_name"
android:textSize="16sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/store_name"
android:layout_width="126dp"
android:layout_height="28dp"
android:layout_marginStart="52dp"
android:layout_marginTop="50dp"
android:text="@string/default_store"
app:layout_constraintBottom_toTopOf="@+id/item_image"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="1.0" />
<ImageView
android:id="@+id/item_image"
android:layout_width="307dp"
android:layout_height="224dp"
android:layout_marginStart="50dp"
android:layout_marginTop="120dp"
android:layout_marginEnd="50dp"
android:background="@color/light_gray"
android:textAlignment="center"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.75"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:contentDescription="@string/product_image_description" />
<TextView
android:id="@+id/item_price"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="50dp"
android:layout_marginTop="16dp"
android:layout_marginBottom="25dp"
android:text="@string/default__00_00"
android:textSize="16sp"
app:layout_constraintBottom_toTopOf="@+id/item_desc"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/item_image" />
<TextView
android:id="@+id/item_desc"
android:layout_width="309dp"
android:layout_height="290dp"
android:layout_marginHorizontal="50dp"
android:layout_marginStart="50dp"
android:layout_marginEnd="50dp"
android:layout_marginBottom="7dp"
android:text="@string/default_description"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<!-- app:srcCompat="@drawable/ic_baseline_arrow_downward_50"-->
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,50 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/add_item_to_list"
android:layout_gravity="center"
android:textSize="20sp"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"/>
<ListView
android:id="@+id/user_lists"
android:layout_width="fill_parent"
android:layout_height="300dp"
android:divider="@color/list_divider"
android:dividerHeight="1dp"
android:choiceMode="multipleChoiceModal"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center">
<Button
android:id="@+id/btn_minus"
android:layout_width="60dp"
android:layout_height="50dp"
android:text="@string/minus"/>
<EditText
android:id="@+id/et_quantity"
android:layout_width="60dp"
android:layout_height="50dp"
android:text="@string/_1"
android:inputType="number"/>
<Button
android:id="@+id/btn_plus"
android:layout_width="60dp"
android:layout_height="50dp"
android:text="@string/plus"/>
</LinearLayout>
</LinearLayout>

View File

@ -0,0 +1,22 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/create_a_new_list"
android:layout_gravity="center"
android:textSize="20sp"
android:layout_marginTop="5dp"/>
<EditText
android:id="@+id/et_new_list_name"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginHorizontal="15dp"
android:maxLines="1"
android:hint="@string/new_list_name"/>
</LinearLayout>

View File

@ -1,28 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".FirstFragment">
<TextView
android:id="@+id/textview_first"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_first_fragment"
app:layout_constraintBottom_toTopOf="@id/button_first"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/button_first"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/next"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/textview_first" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -1,28 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".First2Fragment">
<TextView
android:id="@+id/textview_first"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_first_fragment"
app:layout_constraintBottom_toTopOf="@id/button_first"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/button_first"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/next"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/textview_first" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -1,27 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".SecondFragment">
<TextView
android:id="@+id/textview_second"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toTopOf="@id/button_second"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/button_second"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/previous"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/textview_second" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -1,27 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Second2Fragment">
<TextView
android:id="@+id/textview_second"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toTopOf="@id/button_second"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/button_second"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/previous"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/textview_second" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -4,7 +4,8 @@
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent"
android:descendantFocusability="blocksDescendants">
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/constraintLayout" android:id="@+id/constraintLayout"
@ -15,22 +16,22 @@
app:layout_constraintTop_toTopOf="parent"> app:layout_constraintTop_toTopOf="parent">
<Button <Button
android:id="@+id/buttonIncr" android:id="@+id/buttonDecr"
android:layout_width="30dp" android:layout_width="30dp"
android:layout_height="30dp" android:layout_height="30dp"
android:layout_marginStart="25dp" android:layout_marginStart="25dp"
android:text="+" android:text="-"
android:textSize="10dp" android:textSize="10dp"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@+id/imageView" app:layout_constraintStart_toEndOf="@+id/imageView"
app:layout_constraintTop_toBottomOf="@+id/storeView" /> app:layout_constraintTop_toBottomOf="@+id/storeView" />
<Button <Button
android:id="@+id/buttonDecr" android:id="@+id/buttonIncr"
android:layout_width="30dp" android:layout_width="30dp"
android:layout_height="30dp" android:layout_height="30dp"
android:layout_marginStart="75dp" android:layout_marginStart="75dp"
android:text="-" android:text="+"
android:textSize="10dp" android:textSize="10dp"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@+id/imageView" app:layout_constraintStart_toEndOf="@+id/imageView"
@ -93,13 +94,13 @@
app:layout_constraintTop_toBottomOf="@+id/storeView" /> app:layout_constraintTop_toBottomOf="@+id/storeView" />
<TextView <TextView
android:id="@+id/textViewQuantity" android:id="@+id/quantityView"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="1" android:text="q"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/buttonDecr" app:layout_constraintEnd_toStartOf="@+id/buttonIncr"
app:layout_constraintStart_toEndOf="@+id/buttonIncr" app:layout_constraintStart_toEndOf="@+id/buttonDecr"
app:layout_constraintTop_toBottomOf="@+id/storeView" /> app:layout_constraintTop_toBottomOf="@+id/storeView" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -1,48 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/nav_graph"
app:startDestination="@id/FirstFragment">
<fragment
android:id="@+id/FirstFragment"
android:name="com.example.listify.FirstFragment"
android:label="@string/first_fragment_label"
tools:layout="@layout/fragment_first">
<action
android:id="@+id/action_FirstFragment_to_SecondFragment"
app:destination="@id/SecondFragment" />
</fragment>
<fragment
android:id="@+id/SecondFragment"
android:name="com.example.listify.SecondFragment"
android:label="@string/second_fragment_label"
tools:layout="@layout/fragment_second">
<action
android:id="@+id/action_SecondFragment_to_FirstFragment"
app:destination="@id/FirstFragment" />
</fragment>
<fragment
android:id="@+id/First2Fragment"
android:name="com.example.listify.First2Fragment"
android:label="@string/first_fragment_label"
tools:layout="@layout/fragment_first2">
<action
android:id="@+id/action_First2Fragment_to_Second2Fragment"
app:destination="@id/Second2Fragment" />
</fragment>
<fragment
android:id="@+id/Second2Fragment"
android:name="com.example.listify.Second2Fragment"
android:label="@string/second_fragment_label"
tools:layout="@layout/fragment_second2">
<action
android:id="@+id/action_Second2Fragment_to_First2Fragment"
app:destination="@id/First2Fragment" />
</fragment>
</navigation>

View File

@ -10,4 +10,5 @@
<color name="list_row_end_color">#ffffff</color> <color name="list_row_end_color">#ffffff</color>
<color name="list_row_hover_start_color">#ebeef0</color> <color name="list_row_hover_start_color">#ebeef0</color>
<color name="list_row_hover_end_color">#1c9ef4</color> <color name="list_row_hover_end_color">#1c9ef4</color>
<color name="light_gray">#e6e6e6</color>
</resources> </resources>

View File

@ -5,4 +5,9 @@
<dimen name="nav_header_vertical_spacing">8dp</dimen> <dimen name="nav_header_vertical_spacing">8dp</dimen>
<dimen name="nav_header_height">176dp</dimen> <dimen name="nav_header_height">176dp</dimen>
<dimen name="fab_margin">16dp</dimen> <dimen name="fab_margin">16dp</dimen>
<dimen name="fab_menu_item_margin">20dp</dimen>
<dimen name="standard_55">55dp</dimen>
<dimen name="standard_105">105dp</dimen>
<dimen name="standard_155">155dp</dimen>
</resources> </resources>

View File

@ -30,4 +30,18 @@
<string name="title_activity_search_results">SearchResults</string> <string name="title_activity_search_results">SearchResults</string>
<string name="store_selection">Store selection</string> <string name="store_selection">Store selection</string>
<string name="menu_lists">My Lists</string> <string name="menu_lists">My Lists</string>
<string name="title_activity_item_details">ItemDetails</string>
<string name="add_to_list">Add to list</string>
<string name="create_new_list">Create new list</string>
<string name="default_product_name">Product Name</string>
<string name="default_store">Store</string>
<string name="default__00_00">$00.00</string>
<string name="default_description">Description</string>
<string name="product_image_description">Product Image</string>
<string name="add_item_to_list">Add item to List</string>
<string name="minus">-</string>
<string name="_1">1</string>
<string name="plus">+</string>
<string name="create_a_new_list">Create a new list</string>
<string name="new_list_name">New list name</string>
</resources> </resources>

View File

@ -11,7 +11,7 @@ REL_SCRIPT_DIR=$(dirname "${BASH_SOURCE[0]}")
source ${REL_SCRIPT_DIR}/VarSetup.sh source ${REL_SCRIPT_DIR}/VarSetup.sh
RAWLAMBDA=$(aws lambda create-function --function-name ${functionName}${method} --zip-file fileb://${jarPath} --runtime ${LANGUAGE} --role ${LAMBDAROLE} --handler ${functionName}${method} 2>${DEBUGFILE}) RAWLAMBDA=$(aws lambda create-function --function-name ${functionName}${method} --zip-file fileb://${jarPath} --runtime ${LANGUAGE} --role ${LAMBDAROLE} --handler ${functionName}${method} --memory-size 512 2>${DEBUGFILE})
if [[ $? -ne 0 ]]; then if [[ $? -ne 0 ]]; then