mirror of
https://github.com/ClaytonWWilson/Listify.git
synced 2025-12-16 10:48:46 +00:00
Merge branch 'master' into aaron-branch-2
This commit is contained in:
commit
2d453612cf
@ -85,9 +85,6 @@ public class List {
|
|||||||
|
|
||||||
public void setUiPosition(Integer uiPosition) {
|
public void setUiPosition(Integer uiPosition) {
|
||||||
this.uiPosition = uiPosition;
|
this.uiPosition = uiPosition;
|
||||||
|
|
||||||
public ItemEntry[] getEntries() {
|
|
||||||
return entries.toArray(new ItemEntry[entries.size()]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addItemEntry(ItemEntry entry) {
|
public void addItemEntry(ItemEntry entry) {
|
||||||
|
|||||||
@ -1,16 +1,57 @@
|
|||||||
package com.example.listify.data;
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
public class ListShare {
|
public class ListShare {
|
||||||
Integer listID;
|
Integer listID;
|
||||||
String shareWithEmail;
|
String shareWithEmail;
|
||||||
|
Integer permissionLevel;
|
||||||
|
Integer uiPosition;
|
||||||
ArrayList<ListShare> other;
|
ArrayList<ListShare> other;
|
||||||
|
|
||||||
public ListShare(ResultSet listRow) throws SQLException {
|
public ListShare(ResultSet listRow) throws SQLException {
|
||||||
this.listID = listRow.getInt("listID");
|
this.listID = listRow.getInt("listID");
|
||||||
this.shareWithEmail = listRow.getString("userID");
|
this.shareWithEmail = listRow.getString("userID");
|
||||||
|
this.permissionLevel = listRow.getInt("permissionLevel");
|
||||||
|
this.uiPosition = listRow.getInt("uiPosition");
|
||||||
other = new ArrayList<>();
|
other = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "ListShare{" +
|
||||||
|
"listID=" + listID +
|
||||||
|
", shareWithEmail='" + shareWithEmail + '\'' +
|
||||||
|
", permissionLevel=" + permissionLevel +
|
||||||
|
", uiPosition=" + uiPosition +
|
||||||
|
", other=" + other +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getPermissionLevel() {
|
||||||
|
return permissionLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPermissionLevel(Integer permissionLevel) {
|
||||||
|
this.permissionLevel = permissionLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getUiPosition() {
|
||||||
|
return uiPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUiPosition(Integer uiPosition) {
|
||||||
|
this.uiPosition = uiPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArrayList<ListShare> getOther() {
|
||||||
|
return other;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOther(ArrayList<ListShare> other) {
|
||||||
|
this.other = other;
|
||||||
|
}
|
||||||
|
|
||||||
public Integer getListID() {
|
public Integer getListID() {
|
||||||
return listID;
|
return listID;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,65 +0,0 @@
|
|||||||
import java.security.AccessControlException;
|
|
||||||
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 ListShareDeleter implements CallHandler {
|
|
||||||
private final Connection connection;
|
|
||||||
private final String cognitoID;
|
|
||||||
|
|
||||||
private final String GET_LIST_ACCESS = "SELECT * FROM List WHERE (owner = ? AND listID = ?);";
|
|
||||||
private final String REMOVE_SHAREE = "DELETE FROM ListSharee WHERE listID = ? AND user = ?;";
|
|
||||||
|
|
||||||
public ListShareDeleter(Connection connection, String cognitoID) {
|
|
||||||
this.connection = connection;
|
|
||||||
this.cognitoID = cognitoID;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object conductAction(Map<String, Object> bodyMap, HashMap<String, String> queryMap, String cognitoID) throws SQLException {
|
|
||||||
Integer listID = Integer.parseInt(queryMap.get("id"));
|
|
||||||
|
|
||||||
InvokeRequest invokeRequest = new InvokeRequest();
|
|
||||||
invokeRequest.setFunctionName("UserGET");
|
|
||||||
invokeRequest.setPayload("{" +
|
|
||||||
" \"body\": {" +
|
|
||||||
" \"emailToCheck\": \"" + bodyMap.get("shareWithEmail").toString() + "\"" +
|
|
||||||
" }," +
|
|
||||||
" \"params\": {" +
|
|
||||||
" \"querystring\": {" +
|
|
||||||
" }" +
|
|
||||||
" }," +
|
|
||||||
" \"context\": {" +
|
|
||||||
" \"sub\": \"not used\"" +
|
|
||||||
" }" +
|
|
||||||
"}");
|
|
||||||
InvokeResult invokeResult = AWSLambdaClientBuilder.defaultClient().invoke(invokeRequest);
|
|
||||||
|
|
||||||
String shareeID = new String(invokeResult.getPayload().array()).replace("\"", "");
|
|
||||||
|
|
||||||
//Ensure that the user who is unsharing a list is the owner of that list
|
|
||||||
PreparedStatement accessCheck = connection.prepareStatement(GET_LIST_ACCESS);
|
|
||||||
accessCheck.setString(1, cognitoID);
|
|
||||||
accessCheck.setInt(2, listID);
|
|
||||||
|
|
||||||
ResultSet userLists = accessCheck.executeQuery();
|
|
||||||
|
|
||||||
//User does not own the list; unshare attempt fails
|
|
||||||
if (!userLists.next()) {
|
|
||||||
throw new AccessControlException("User does not have access to list");
|
|
||||||
}
|
|
||||||
|
|
||||||
//Unshare the list with the specified sharee
|
|
||||||
PreparedStatement unshareList = connection.prepareStatement(REMOVE_SHAREE);
|
|
||||||
unshareList.setInt(1, listID);
|
|
||||||
unshareList.setInt(2, shareeID);
|
|
||||||
|
|
||||||
cleanAccess.executeUpdate();
|
|
||||||
connection.commit();
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -2,7 +2,6 @@ import java.sql.Connection;
|
|||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@ -21,7 +20,7 @@ public class ListShareGetter implements CallHandler{
|
|||||||
public Object conductAction(Map<String, Object> bodyMap, HashMap<String, String> queryMap, String cognitoID) throws SQLException {
|
public Object conductAction(Map<String, Object> bodyMap, HashMap<String, String> queryMap, String cognitoID) throws SQLException {
|
||||||
Integer listID = Integer.parseInt(queryMap.get("id"));
|
Integer listID = Integer.parseInt(queryMap.get("id"));
|
||||||
|
|
||||||
PreparedStatement getList = connection.prepareStatement(GET_LIST);
|
PreparedStatement getList = connection.prepareStatement(GET_LISTS);
|
||||||
getList.setInt(1, listID);
|
getList.setInt(1, listID);
|
||||||
|
|
||||||
ResultSet getListResults = getList.executeQuery();
|
ResultSet getListResults = getList.executeQuery();
|
||||||
|
|||||||
34
Lambdas/Lists/Picture/src/Picture.java
Normal file
34
Lambdas/Lists/Picture/src/Picture.java
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
public class Picture {
|
||||||
|
String base64EncodedImage;
|
||||||
|
|
||||||
|
public Picture(ResultSet rs) {
|
||||||
|
try {
|
||||||
|
this.base64EncodedImage = rs.getString("base64image");
|
||||||
|
} catch (SQLException throwables) {
|
||||||
|
throwables.printStackTrace();
|
||||||
|
this.base64EncodedImage = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Picture(String base64EncodedImage) {
|
||||||
|
this.base64EncodedImage = base64EncodedImage;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Picture{" +
|
||||||
|
"base64EncodedImage='" + base64EncodedImage + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBase64EncodedImage() {
|
||||||
|
return base64EncodedImage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBase64EncodedImage(String base64EncodedImage) {
|
||||||
|
this.base64EncodedImage = base64EncodedImage;
|
||||||
|
}
|
||||||
|
}
|
||||||
12
Lambdas/Lists/Picture/src/PictureGET.java
Normal file
12
Lambdas/Lists/Picture/src/PictureGET.java
Normal 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 PictureGET implements RequestHandler<Map<String,Object>, Object> {
|
||||||
|
|
||||||
|
public Object handleRequest(Map<String, Object> inputMap, Context unfilled) {
|
||||||
|
return BasicHandler.handleRequest(inputMap, unfilled, PictureGetter.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
34
Lambdas/Lists/Picture/src/PictureGetter.java
Normal file
34
Lambdas/Lists/Picture/src/PictureGetter.java
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
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 PictureGetter implements CallHandler {
|
||||||
|
private final Connection connection;
|
||||||
|
private final String cognitoID;
|
||||||
|
|
||||||
|
private final String GET_ITEM = "SELECT * FROM Pictures WHERE cognitoID = ?;";
|
||||||
|
|
||||||
|
public PictureGetter(Connection connection, String cognitoID) {
|
||||||
|
this.connection = connection;
|
||||||
|
this.cognitoID = cognitoID;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object conductAction(Map<String, Object> bodyMap, HashMap<String, String> queryMap, String cognitoID) throws SQLException {
|
||||||
|
PreparedStatement statement = connection.prepareStatement(GET_ITEM);
|
||||||
|
if (!queryMap.get("id").toString().equals("profile")) {
|
||||||
|
throw new IllegalArgumentException("Only profile pictures are currently supported.");
|
||||||
|
}
|
||||||
|
statement.setString(1, cognitoID);
|
||||||
|
System.out.println(statement);
|
||||||
|
ResultSet queryResults = statement.executeQuery();
|
||||||
|
queryResults.first();
|
||||||
|
System.out.println(queryResults);
|
||||||
|
Picture retrievedPicture = new Picture(queryResults);
|
||||||
|
// System.out.println(retrievedPicture);
|
||||||
|
return retrievedPicture;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -3,10 +3,9 @@ import com.amazonaws.services.lambda.runtime.RequestHandler;
|
|||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class ListShareDELETE implements RequestHandler<Map<String,Object>, Object> {
|
public class PicturePUT implements RequestHandler<Map<String,Object>, Object> {
|
||||||
|
|
||||||
public Object handleRequest(Map<String, Object> inputMap, Context unfilled) {
|
public Object handleRequest(Map<String, Object> inputMap, Context unfilled) {
|
||||||
return BasicHandler.handleRequest(inputMap, unfilled, ListShareDeleter.class);
|
return BasicHandler.handleRequest(inputMap, unfilled, PicturePutter.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
28
Lambdas/Lists/Picture/src/PicturePutter.java
Normal file
28
Lambdas/Lists/Picture/src/PicturePutter.java
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class PicturePutter implements CallHandler {
|
||||||
|
|
||||||
|
private Connection connection;
|
||||||
|
private String cognitoID;
|
||||||
|
|
||||||
|
public PicturePutter(Connection connection, String cognitoID) {
|
||||||
|
this.connection = connection;
|
||||||
|
this.cognitoID = cognitoID;
|
||||||
|
}
|
||||||
|
|
||||||
|
final private String STORE_PICTURE_SQL = "REPLACE INTO Pictures(cognitoID, base64image) VALUES(?, ?);";
|
||||||
|
|
||||||
|
public Object conductAction(Map<String, Object> bodyMap, HashMap<String, String> queryString, String cognitoID) throws SQLException {
|
||||||
|
PreparedStatement storePicture = connection.prepareStatement(STORE_PICTURE_SQL);
|
||||||
|
storePicture.setString(1, cognitoID);
|
||||||
|
storePicture.setString(2, bodyMap.get("base64EncodedImage").toString());
|
||||||
|
System.out.println(storePicture);
|
||||||
|
storePicture.executeUpdate();
|
||||||
|
connection.commit();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -53,4 +53,6 @@ dependencies {
|
|||||||
implementation 'com.squareup.okhttp3:okhttp:4.8.1'
|
implementation 'com.squareup.okhttp3:okhttp:4.8.1'
|
||||||
implementation 'com.crystal:crystalrangeseekbar:1.1.3'
|
implementation 'com.crystal:crystalrangeseekbar:1.1.3'
|
||||||
implementation 'com.chauthai.swipereveallayout:swipe-reveal-layout:1.4.1'
|
implementation 'com.chauthai.swipereveallayout:swipe-reveal-layout:1.4.1'
|
||||||
|
implementation "androidx.cardview:cardview:1.0.0"
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -3,6 +3,9 @@
|
|||||||
package="com.example.listify">
|
package="com.example.listify">
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
|
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||||
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||||
|
<uses-permission android:name="android.permission.CAMERA" />
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:name=".Listify"
|
android:name=".Listify"
|
||||||
@ -13,6 +16,18 @@
|
|||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/AppTheme"
|
android:theme="@style/AppTheme"
|
||||||
android:usesCleartextTraffic="true">
|
android:usesCleartextTraffic="true">
|
||||||
|
|
||||||
|
<provider
|
||||||
|
android:name="androidx.core.content.FileProvider"
|
||||||
|
android:authorities="com.example.listify.provider"
|
||||||
|
android:exported="false"
|
||||||
|
android:grantUriPermissions="true">
|
||||||
|
<meta-data
|
||||||
|
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||||
|
android:resource="@xml/file_paths">
|
||||||
|
</meta-data>
|
||||||
|
</provider>
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".MainActivity"
|
android:name=".MainActivity"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
|
|||||||
@ -1,15 +1,17 @@
|
|||||||
package com.example.listify;
|
package com.example.listify;
|
||||||
|
|
||||||
import android.app.AlertDialog;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
|
import android.content.Intent;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.text.Editable;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.*;
|
import android.view.*;
|
||||||
import android.widget.*;
|
import android.widget.*;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.appcompat.app.AlertDialog;
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
import androidx.constraintlayout.widget.ConstraintLayout;
|
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
||||||
@ -27,7 +29,7 @@ import java.util.Properties;
|
|||||||
|
|
||||||
import static com.example.listify.MainActivity.am;
|
import static com.example.listify.MainActivity.am;
|
||||||
|
|
||||||
public class ListPage extends AppCompatActivity implements Requestor.Receiver {
|
public class ListPage extends AppCompatActivity implements Requestor.Receiver, RenameListDialogFragment.OnRenameListListener {
|
||||||
ListView listView;
|
ListView listView;
|
||||||
MyAdapter myAdapter;
|
MyAdapter myAdapter;
|
||||||
Requestor requestor;
|
Requestor requestor;
|
||||||
@ -59,15 +61,15 @@ public class ListPage extends AppCompatActivity implements Requestor.Receiver {
|
|||||||
Map<String, Integer> storeHeaderIndex = new HashMap<>();
|
Map<String, Integer> storeHeaderIndex = new HashMap<>();
|
||||||
|
|
||||||
DecimalFormat df = new DecimalFormat("0.00");
|
DecimalFormat df = new DecimalFormat("0.00");
|
||||||
|
List selectedList;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setContentView(R.layout.activity_list);
|
setContentView(R.layout.activity_list);
|
||||||
|
|
||||||
final int LIST_ID = (int) getIntent().getSerializableExtra("listID");
|
selectedList = (List) getIntent().getSerializableExtra("selectedList");
|
||||||
final String LIST_NAME = (String) getIntent().getSerializableExtra("listName");
|
setTitle(selectedList.getName());
|
||||||
setTitle(LIST_NAME);
|
|
||||||
|
|
||||||
Properties configs = new Properties();
|
Properties configs = new Properties();
|
||||||
try {
|
try {
|
||||||
@ -76,7 +78,7 @@ public class ListPage extends AppCompatActivity implements Requestor.Receiver {
|
|||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
requestor = new Requestor(am, configs.getProperty("apiKey"));
|
requestor = new Requestor(am, configs.getProperty("apiKey"));
|
||||||
requestor.getObject(Integer.toString(LIST_ID), List.class, this);
|
requestor.getObject(Integer.toString(selectedList.getListID()), List.class, this);
|
||||||
|
|
||||||
listView = findViewById(R.id.listView);
|
listView = findViewById(R.id.listView);
|
||||||
myAdapter = new MyAdapter(this, pNames, pStores, pPrices, pQuantity, pImages);
|
myAdapter = new MyAdapter(this, pNames, pStores, pPrices, pQuantity, pImages);
|
||||||
@ -158,7 +160,7 @@ public class ListPage extends AppCompatActivity implements Requestor.Receiver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
requestor = new Requestor(am, configs.getProperty("apiKey"));
|
requestor = new Requestor(am, configs.getProperty("apiKey"));
|
||||||
requestor.getObject(Integer.toString(LIST_ID), List.class, ListPage.this);
|
requestor.getObject(Integer.toString(selectedList.getListID()), List.class, ListPage.this);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -166,16 +168,16 @@ public class ListPage extends AppCompatActivity implements Requestor.Receiver {
|
|||||||
@Override
|
@Override
|
||||||
public boolean onCreateOptionsMenu(Menu menu) {
|
public boolean onCreateOptionsMenu(Menu menu) {
|
||||||
//Inflate the menu; this adds items to the action bar if it is present.
|
//Inflate the menu; this adds items to the action bar if it is present.
|
||||||
|
|
||||||
getMenuInflater().inflate(R.menu.list, menu);
|
getMenuInflater().inflate(R.menu.list, menu);
|
||||||
|
|
||||||
//return super.onCreateOptionsMenu(menu);
|
|
||||||
|
|
||||||
MenuItem renameItem = menu.findItem(R.id.action_rename_list);
|
MenuItem renameItem = menu.findItem(R.id.action_rename_list);
|
||||||
renameItem.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
|
renameItem.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public boolean onMenuItemClick(MenuItem item) {
|
public boolean onMenuItemClick(MenuItem item) {
|
||||||
Toast.makeText(ListPage.this, "Rename List", Toast.LENGTH_SHORT).show();
|
RenameListDialogFragment renameListDialog = new RenameListDialogFragment();
|
||||||
|
renameListDialog.show(getSupportFragmentManager(), "Rename List");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -193,7 +195,24 @@ public class ListPage extends AppCompatActivity implements Requestor.Receiver {
|
|||||||
duplicateItem.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
|
duplicateItem.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public boolean onMenuItemClick(MenuItem item) {
|
public boolean onMenuItemClick(MenuItem item) {
|
||||||
Toast.makeText(ListPage.this, "Duplicate List", Toast.LENGTH_SHORT).show();
|
|
||||||
|
ListDuplicate duplicate = new ListDuplicate(selectedList.getListID(), String.format("%s copy", selectedList.getName()));
|
||||||
|
|
||||||
|
Properties configs = new Properties();
|
||||||
|
try {
|
||||||
|
configs = AuthManager.loadProperties(ListPage.this, "android.resource://" + getPackageName() + "/raw/auths.json");
|
||||||
|
} catch (IOException | JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
requestor = new Requestor(am, configs.getProperty("apiKey"));
|
||||||
|
try {
|
||||||
|
requestor.postObject(duplicate);
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
Toast.makeText(ListPage.this, "List duplicated", Toast.LENGTH_SHORT).show();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -202,6 +221,24 @@ public class ListPage extends AppCompatActivity implements Requestor.Receiver {
|
|||||||
exportItem.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
|
exportItem.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public boolean onMenuItemClick(MenuItem item) {
|
public boolean onMenuItemClick(MenuItem item) {
|
||||||
|
StringBuilder listContents = new StringBuilder();
|
||||||
|
|
||||||
|
for (int i = 0; i < pNames.size(); i++) {
|
||||||
|
if (Integer.parseInt(pQuantity.get(i)) == -1) {
|
||||||
|
listContents.append(String.format("\n%s\n", pNames.get(i)));
|
||||||
|
} else {
|
||||||
|
listContents.append(String.format(" %s of %s\n", pQuantity.get(i), pNames.get(i)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Intent sendIntent = new Intent();
|
||||||
|
sendIntent.setAction(Intent.ACTION_SEND);
|
||||||
|
sendIntent.putExtra(Intent.EXTRA_TEXT, listContents.toString());
|
||||||
|
sendIntent.setType("text/plain");
|
||||||
|
|
||||||
|
Intent shareIntent = Intent.createChooser(sendIntent, null);
|
||||||
|
startActivity(shareIntent);
|
||||||
|
|
||||||
Toast.makeText(ListPage.this, "Export List", Toast.LENGTH_SHORT).show();
|
Toast.makeText(ListPage.this, "Export List", Toast.LENGTH_SHORT).show();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -213,22 +250,16 @@ public class ListPage extends AppCompatActivity implements Requestor.Receiver {
|
|||||||
@Override
|
@Override
|
||||||
public void acceptDelivery(Object delivered) {
|
public void acceptDelivery(Object delivered) {
|
||||||
// Clear out old values
|
// Clear out old values
|
||||||
runOnUiThread(new Runnable() {
|
pNames.clear();
|
||||||
@Override
|
pStores.clear();
|
||||||
public void run() {
|
pPrices.clear();
|
||||||
pNames.clear();
|
pQuantity.clear();
|
||||||
pStores.clear();
|
pImages.clear();
|
||||||
pPrices.clear();
|
totalPriceByStore.clear();
|
||||||
pQuantity.clear();
|
storeID2Name.clear();
|
||||||
pImages.clear();
|
storeHeaderIndex.clear();
|
||||||
totalPriceByStore.clear();
|
pListItemPair.clear();
|
||||||
storeID2Name.clear();
|
totalPrice = 0;
|
||||||
storeHeaderIndex.clear();
|
|
||||||
pListItemPair.clear();
|
|
||||||
totalPrice = 0;
|
|
||||||
tvTotalPrice.setText(String.format("$%.2f", totalPrice));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
List list = (List) delivered;
|
List list = (List) delivered;
|
||||||
|
|
||||||
@ -326,9 +357,44 @@ public class ListPage extends AppCompatActivity implements Requestor.Receiver {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
tvTotalPrice.setText(String.format("$%.2f", totalPrice));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
refreshList.setRefreshing(false);
|
refreshList.setRefreshing(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendRenameListName(String name) {
|
||||||
|
selectedList.setName(name);
|
||||||
|
|
||||||
|
Properties configs = new Properties();
|
||||||
|
try {
|
||||||
|
configs = AuthManager.loadProperties(ListPage.this, "android.resource://" + getPackageName() + "/raw/auths.json");
|
||||||
|
} catch (IOException | JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
requestor = new Requestor(am, configs.getProperty("apiKey"));
|
||||||
|
try {
|
||||||
|
requestor.putObject(selectedList);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
setTitle(name);
|
||||||
|
Toast.makeText(ListPage.this, "List Renamed", Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
class MyAdapter extends ArrayAdapter<String> {
|
class MyAdapter extends ArrayAdapter<String> {
|
||||||
Context context;
|
Context context;
|
||||||
ArrayList<String> pNames;
|
ArrayList<String> pNames;
|
||||||
|
|||||||
@ -1,15 +1,26 @@
|
|||||||
package com.example.listify;
|
package com.example.listify;
|
||||||
|
|
||||||
|
import android.app.AlertDialog;
|
||||||
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.database.Cursor;
|
||||||
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.Environment;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
|
import android.provider.MediaStore;
|
||||||
|
import android.util.Base64;
|
||||||
|
import android.util.Base64OutputStream;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.ImageButton;
|
import android.widget.ImageButton;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
import androidx.appcompat.widget.Toolbar;
|
import androidx.appcompat.widget.Toolbar;
|
||||||
|
import androidx.core.content.FileProvider;
|
||||||
import androidx.drawerlayout.widget.DrawerLayout;
|
import androidx.drawerlayout.widget.DrawerLayout;
|
||||||
import androidx.navigation.NavController;
|
import androidx.navigation.NavController;
|
||||||
import androidx.navigation.Navigation;
|
import androidx.navigation.Navigation;
|
||||||
@ -17,15 +28,15 @@ 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.List;
|
import com.example.listify.data.List;
|
||||||
import com.example.listify.data.ListDuplicate;
|
import com.example.listify.data.Picture;
|
||||||
import com.example.listify.data.ListReposition;
|
|
||||||
import com.example.listify.data.SearchHistory;
|
|
||||||
import com.example.listify.ui.LoginPage;
|
import com.example.listify.ui.LoginPage;
|
||||||
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.*;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
|
import java.util.Date;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
import static com.example.listify.SplashActivity.showSplash;
|
import static com.example.listify.SplashActivity.showSplash;
|
||||||
@ -33,6 +44,9 @@ import static com.example.listify.SplashActivity.showSplash;
|
|||||||
public class MainActivity extends AppCompatActivity implements CreateListDialogFragment.OnNewListListener {
|
public class MainActivity extends AppCompatActivity implements CreateListDialogFragment.OnNewListListener {
|
||||||
private AppBarConfiguration mAppBarConfiguration;
|
private AppBarConfiguration mAppBarConfiguration;
|
||||||
public static AuthManager am = new AuthManager();
|
public static AuthManager am = new AuthManager();
|
||||||
|
private File newImageFileLocation = null;
|
||||||
|
private final int CAMERA_CAPTURE = 1;
|
||||||
|
private final int IMAGE_SELECT = 2;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBackPressed() {
|
public void onBackPressed() {
|
||||||
@ -151,12 +165,62 @@ public class MainActivity extends AppCompatActivity implements CreateListDialogF
|
|||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------------------//
|
//------------------------------------------------------------------------------------------//
|
||||||
|
|
||||||
setContentView(R.layout.activity_main);
|
setContentView(R.layout.activity_main);
|
||||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||||
setSupportActionBar(toolbar);
|
setSupportActionBar(toolbar);
|
||||||
DrawerLayout drawer = findViewById(R.id.drawer_layout);
|
DrawerLayout drawer = findViewById(R.id.drawer_layout);
|
||||||
NavigationView navigationView = findViewById(R.id.nav_view);
|
NavigationView navigationView = findViewById(R.id.nav_view);
|
||||||
|
|
||||||
|
TextView emailView = navigationView.getHeaderView(0).findViewById(R.id.textViewEmailSidebar);
|
||||||
|
emailView.setText(am.getEmail());
|
||||||
|
Properties configs = new Properties();
|
||||||
|
try {
|
||||||
|
configs = AuthManager.loadProperties(this, "android.resource://" + getPackageName() + "/raw/auths.json");
|
||||||
|
} catch (IOException | JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
Requestor requestor = new Requestor(am, configs.getProperty("apiKey"));
|
||||||
|
SynchronousReceiver<Picture> profilePictureReceiver = new SynchronousReceiver<>();
|
||||||
|
ImageView profilePictureView = navigationView.getHeaderView(0).findViewById(R.id.imageViewProfilePicture);
|
||||||
|
try {
|
||||||
|
requestor.getObject("profile", Picture.class, profilePictureReceiver);
|
||||||
|
profilePictureView.setImageURI(Uri.fromFile(saveImage(profilePictureReceiver.await().getBase64EncodedImage())));
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
profilePictureView.setOnClickListener(new View.OnClickListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
|
||||||
|
// builder.setView(navigationView.getHeaderView(0));
|
||||||
|
builder.setTitle("Change picture");
|
||||||
|
builder.setMessage("Please select a method to add a new profile picture.");
|
||||||
|
builder.setCancelable(true);
|
||||||
|
builder.setPositiveButton("Take picture", (dialog, which) -> {
|
||||||
|
Intent takePicture = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
|
||||||
|
File imageFileLocation = getOutputImageFile();
|
||||||
|
Log.i("Profile Picture", "New image file at " + imageFileLocation.getAbsolutePath());
|
||||||
|
newImageFileLocation = imageFileLocation;
|
||||||
|
Uri imageUri = FileProvider.getUriForFile(
|
||||||
|
MainActivity.this,
|
||||||
|
BuildConfig.APPLICATION_ID + ".provider",
|
||||||
|
imageFileLocation);
|
||||||
|
takePicture.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
|
||||||
|
startActivityForResult(takePicture, CAMERA_CAPTURE);
|
||||||
|
});
|
||||||
|
builder.setNegativeButton("Select picture", (dialog, which) -> {
|
||||||
|
Intent pickPhoto = new Intent(Intent.ACTION_PICK,
|
||||||
|
MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
|
||||||
|
startActivityForResult(pickPhoto, IMAGE_SELECT);
|
||||||
|
});
|
||||||
|
builder.setNeutralButton("Cancel", (dialog, which) -> {
|
||||||
|
});
|
||||||
|
AlertDialog dialog = builder.create();
|
||||||
|
dialog.show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
mAppBarConfiguration = new AppBarConfiguration.Builder(
|
mAppBarConfiguration = new AppBarConfiguration.Builder(
|
||||||
R.id.nav_home, R.id.nav_profile, R.id.nav_logout)
|
R.id.nav_home, R.id.nav_profile, R.id.nav_logout)
|
||||||
.setDrawerLayout(drawer)
|
.setDrawerLayout(drawer)
|
||||||
@ -176,6 +240,144 @@ public class MainActivity extends AppCompatActivity implements CreateListDialogF
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//From: https://stackoverflow.com/questions/30005815/convert-encoded-base64-image-to-file-object-in-android
|
||||||
|
private File saveImage(final String imageData) throws IOException {
|
||||||
|
final byte[] imgBytesData = android.util.Base64.decode(imageData,
|
||||||
|
android.util.Base64.DEFAULT);
|
||||||
|
|
||||||
|
final File file = File.createTempFile("profilePicture", null, this.getCacheDir());
|
||||||
|
final FileOutputStream fileOutputStream;
|
||||||
|
try {
|
||||||
|
fileOutputStream = new FileOutputStream(file);
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
final BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(
|
||||||
|
fileOutputStream);
|
||||||
|
try {
|
||||||
|
bufferedOutputStream.write(imgBytesData);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return null;
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
bufferedOutputStream.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void onActivityResult (int requestCode,
|
||||||
|
int resultCode,
|
||||||
|
Intent data) {
|
||||||
|
Uri selectedImage = null;
|
||||||
|
Properties configs = new Properties();
|
||||||
|
try {
|
||||||
|
configs = AuthManager.loadProperties(this, "android.resource://" + getPackageName() + "/raw/auths.json");
|
||||||
|
} catch (IOException | JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
Requestor requestor = new Requestor(am, configs.getProperty("apiKey"));
|
||||||
|
switch (requestCode){
|
||||||
|
case CAMERA_CAPTURE:
|
||||||
|
Log.i("Profile Picture", "Pulling image file at " + this.newImageFileLocation.getAbsolutePath());
|
||||||
|
selectedImage = Uri.fromFile(this.newImageFileLocation);
|
||||||
|
try {
|
||||||
|
requestor.putObject(new Picture(fileToString(this.newImageFileLocation)));
|
||||||
|
} catch (JSONException | IOException jsonException) {
|
||||||
|
jsonException.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case IMAGE_SELECT:
|
||||||
|
if ((data == null) || (data.getData() == null)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
selectedImage = data.getData();
|
||||||
|
try {
|
||||||
|
requestor.putObject(new Picture(fileToString(new File(getRealPathFromUri(this, selectedImage)))));
|
||||||
|
} catch (JSONException | IOException exception) {
|
||||||
|
exception.printStackTrace();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
MainActivity.super.onActivityResult(requestCode, resultCode, data);
|
||||||
|
if (selectedImage == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
NavigationView navigationView = findViewById(R.id.nav_view);
|
||||||
|
|
||||||
|
ImageView profilePicture = navigationView.getHeaderView(0).findViewById(R.id.imageViewProfilePicture);
|
||||||
|
profilePicture.setImageURI(selectedImage);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//From: https://stackoverflow.com/questions/20028319/how-to-convert-content-media-external-images-media-y-to-file-storage-sdc
|
||||||
|
private static String getRealPathFromUri(Context context, Uri contentUri) {
|
||||||
|
Cursor cursor = null;
|
||||||
|
try {
|
||||||
|
String[] proj = { MediaStore.Images.Media.DATA };
|
||||||
|
cursor = context.getContentResolver().query(contentUri, proj, null, null, null);
|
||||||
|
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
|
||||||
|
cursor.moveToFirst();
|
||||||
|
return cursor.getString(column_index);
|
||||||
|
} finally {
|
||||||
|
if (cursor != null) {
|
||||||
|
cursor.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//From: https://stackoverflow.com/questions/27784230/convert-a-file-100mo-in-base64-on-android
|
||||||
|
private String fileToString(File toStringify) throws IOException {
|
||||||
|
InputStream inputStream = new FileInputStream(toStringify.getAbsolutePath());
|
||||||
|
byte[] buffer = new byte[8192];
|
||||||
|
int bytesRead;
|
||||||
|
ByteArrayOutputStream output = new ByteArrayOutputStream();
|
||||||
|
Base64OutputStream output64 = new Base64OutputStream(output, Base64.DEFAULT);
|
||||||
|
try {
|
||||||
|
while ((bytesRead = inputStream.read(buffer)) != -1) {
|
||||||
|
output64.write(buffer, 0, bytesRead);
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
output64.close();
|
||||||
|
|
||||||
|
return output.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
//getOutputImageFile from https://developer.android.com/guide/topics/media/camera
|
||||||
|
private static File getOutputImageFile(){
|
||||||
|
// To be safe, you should check that the SDCard is mounted
|
||||||
|
// using Environment.getExternalStorageState() before doing this.
|
||||||
|
|
||||||
|
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
|
||||||
|
Environment.DIRECTORY_PICTURES), "MyCameraApp");
|
||||||
|
// This location works best if you want the created images to be shared
|
||||||
|
// between applications and persist after your app has been uninstalled.
|
||||||
|
|
||||||
|
// Create the storage directory if it does not exist
|
||||||
|
if (! mediaStorageDir.exists()){
|
||||||
|
if (! mediaStorageDir.mkdirs()){
|
||||||
|
Log.d("File creation", "failed to create directory");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a media file name
|
||||||
|
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
|
||||||
|
File mediaFile = new File(mediaStorageDir.getPath() + File.separator +
|
||||||
|
"IMG_"+ timeStamp + ".jpg");
|
||||||
|
Log.i("File creation", mediaFile.toString());
|
||||||
|
return mediaFile;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onSupportNavigateUp() {
|
public boolean onSupportNavigateUp() {
|
||||||
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
|
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
|
||||||
@ -214,5 +416,8 @@ public class MainActivity extends AppCompatActivity implements CreateListDialogF
|
|||||||
Toast.makeText(this, "An error occurred", Toast.LENGTH_LONG).show();
|
Toast.makeText(this, "An error occurred", Toast.LENGTH_LONG).show();
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -0,0 +1,71 @@
|
|||||||
|
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 RenameListDialogFragment extends DialogFragment {
|
||||||
|
|
||||||
|
public interface OnRenameListListener {
|
||||||
|
void sendRenameListName(String name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public OnRenameListListener onRenameListListener;
|
||||||
|
|
||||||
|
EditText etRenameListName;
|
||||||
|
|
||||||
|
public RenameListDialogFragment() {}
|
||||||
|
|
||||||
|
|
||||||
|
@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_rename_list, null);
|
||||||
|
builder.setView(root)
|
||||||
|
// Add action buttons
|
||||||
|
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int id) {
|
||||||
|
onRenameListListener.sendRenameListName(etRenameListName.getText().toString());
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.setNegativeButton("cancel", new DialogInterface.OnClickListener() {
|
||||||
|
public void onClick(DialogInterface dialog, int id) {
|
||||||
|
RenameListDialogFragment.this.getDialog().cancel();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
etRenameListName = (EditText) root.findViewById(R.id.et_renamed_list_name);
|
||||||
|
|
||||||
|
return builder.create();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Required to extend DialogFragment
|
||||||
|
@Override
|
||||||
|
public void onAttach(@NonNull Context context) {
|
||||||
|
super.onAttach(context);
|
||||||
|
try {
|
||||||
|
onRenameListListener = (OnRenameListListener) getTargetFragment();
|
||||||
|
if (onRenameListListener == null) {
|
||||||
|
onRenameListListener = (OnRenameListListener) getActivity();
|
||||||
|
}
|
||||||
|
} catch (ClassCastException e) {
|
||||||
|
Log.e("CreateListDialogFragment", "onAttach: ClassCastException: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -79,7 +79,7 @@ public class ShareeSwipeableAdapter extends BaseAdapter {
|
|||||||
holder.swipeLayout = (SwipeRevealLayout)convertView.findViewById(R.id.swipe_layout);
|
holder.swipeLayout = (SwipeRevealLayout)convertView.findViewById(R.id.swipe_layout);
|
||||||
holder.frontView = convertView.findViewById(R.id.front_layout);
|
holder.frontView = convertView.findViewById(R.id.front_layout);
|
||||||
holder.deleteList = convertView.findViewById(R.id.delete_list);
|
holder.deleteList = convertView.findViewById(R.id.delete_list);
|
||||||
holder.shareList = convertView.findViewById(R.id.share_list);
|
// holder.shareList = convertView.findViewById(R.id.share_list);
|
||||||
holder.textView = (TextView) convertView.findViewById(R.id.shopping_list_name);
|
holder.textView = (TextView) convertView.findViewById(R.id.shopping_list_name);
|
||||||
|
|
||||||
convertView.setTag(holder);
|
convertView.setTag(holder);
|
||||||
@ -101,12 +101,12 @@ public class ShareeSwipeableAdapter extends BaseAdapter {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
holder.shareList.setOnClickListener(new View.OnClickListener() {
|
// holder.shareList.setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
// @Override
|
||||||
public void onClick(View v) {
|
// public void onClick(View v) {
|
||||||
|
//
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
|
|
||||||
holder.frontView.setOnClickListener(new View.OnClickListener() {
|
holder.frontView.setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -80,7 +80,7 @@ public class ShoppingListsSwipeableAdapter extends BaseAdapter {
|
|||||||
holder.swipeLayout = (SwipeRevealLayout)convertView.findViewById(R.id.swipe_layout);
|
holder.swipeLayout = (SwipeRevealLayout)convertView.findViewById(R.id.swipe_layout);
|
||||||
holder.frontView = convertView.findViewById(R.id.front_layout);
|
holder.frontView = convertView.findViewById(R.id.front_layout);
|
||||||
holder.deleteList = convertView.findViewById(R.id.delete_list);
|
holder.deleteList = convertView.findViewById(R.id.delete_list);
|
||||||
holder.shareList = convertView.findViewById(R.id.share_list);
|
// holder.shareList = convertView.findViewById(R.id.share_list);
|
||||||
holder.listName = (TextView) convertView.findViewById(R.id.shopping_list_name);
|
holder.listName = (TextView) convertView.findViewById(R.id.shopping_list_name);
|
||||||
holder.itemCount = (TextView) convertView.findViewById(R.id.shopping_list_item_count);
|
holder.itemCount = (TextView) convertView.findViewById(R.id.shopping_list_item_count);
|
||||||
|
|
||||||
@ -101,7 +101,11 @@ public class ShoppingListsSwipeableAdapter extends BaseAdapter {
|
|||||||
holder.listName.setText(curList.getName());
|
holder.listName.setText(curList.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
holder.itemCount.setText(String.format("%d items", curList.getEntries().length));
|
if (curList.getEntries() != null) {
|
||||||
|
holder.itemCount.setText(String.format("%d items", curList.getEntries().length));
|
||||||
|
} else {
|
||||||
|
holder.itemCount.setText("0 items");
|
||||||
|
}
|
||||||
|
|
||||||
holder.deleteList.setOnClickListener(new View.OnClickListener() {
|
holder.deleteList.setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
@ -139,9 +143,8 @@ public class ShoppingListsSwipeableAdapter extends BaseAdapter {
|
|||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
Intent listPage = new Intent(activity, ListPage.class);
|
Intent listPage = new Intent(activity, ListPage.class);
|
||||||
|
|
||||||
// Send the list ID and list name
|
// Send the selected list
|
||||||
listPage.putExtra("listID", curList.getListID());
|
listPage.putExtra("selectedList", curList);
|
||||||
listPage.putExtra("listName", curList.getName());
|
|
||||||
|
|
||||||
activity.startActivity(listPage);
|
activity.startActivity(listPage);
|
||||||
}
|
}
|
||||||
@ -154,7 +157,7 @@ public class ShoppingListsSwipeableAdapter extends BaseAdapter {
|
|||||||
SwipeRevealLayout swipeLayout;
|
SwipeRevealLayout swipeLayout;
|
||||||
View frontView;
|
View frontView;
|
||||||
View deleteList;
|
View deleteList;
|
||||||
View shareList;
|
// View shareList;
|
||||||
TextView listName;
|
TextView listName;
|
||||||
TextView itemCount;
|
TextView itemCount;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,8 +1,9 @@
|
|||||||
package com.example.listify.data;
|
package com.example.listify.data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
public class List {
|
public class List implements Serializable {
|
||||||
Integer listID;
|
Integer listID;
|
||||||
String name;
|
String name;
|
||||||
String owner;
|
String owner;
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
package com.example.listify.data;
|
package com.example.listify.data;
|
||||||
|
|
||||||
public class ListEntry {
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
public class ListEntry implements Serializable {
|
||||||
Integer listID;
|
Integer listID;
|
||||||
Integer productID;
|
Integer productID;
|
||||||
Integer quantity;
|
Integer quantity;
|
||||||
|
|||||||
@ -11,6 +11,7 @@ public class ListShare {
|
|||||||
String shareWithEmail;
|
String shareWithEmail;
|
||||||
final ListShare[] other;
|
final ListShare[] other;
|
||||||
Integer permissionLevel;
|
Integer permissionLevel;
|
||||||
|
Integer uiPosition;
|
||||||
private static final Map<Integer, String> keysToPerms;
|
private static final Map<Integer, String> keysToPerms;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
@ -24,11 +25,17 @@ public class ListShare {
|
|||||||
keysToPerms = Collections.unmodifiableMap(keysToPermsTemp);
|
keysToPerms = Collections.unmodifiableMap(keysToPermsTemp);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ListShare(Integer listID, String shareWithEmail, Integer permissionLevel, ListShare[] other) {
|
public ListShare(Integer listID, String shareWithEmail, Integer permissionLevel, Integer uiPosition, ListShare[] other) {
|
||||||
this.listID = listID;
|
this.listID = listID;
|
||||||
this.shareWithEmail = shareWithEmail;
|
this.shareWithEmail = shareWithEmail;
|
||||||
this.permissionLevel = permissionLevel;
|
this.permissionLevel = permissionLevel;
|
||||||
this.other = other;
|
this.other = other;
|
||||||
|
this.uiPosition = uiPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ListShare(Integer listID, String shareWithEmail, String permissionsRaw, Integer uiPosition, ListShare[] other) {
|
||||||
|
this(listID, shareWithEmail, permissionsRaw, other);
|
||||||
|
this.uiPosition = uiPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ListShare(Integer listID, String shareWithEmail, String permissionsRaw, ListShare[] other) {
|
public ListShare(Integer listID, String shareWithEmail, String permissionsRaw, ListShare[] other) {
|
||||||
@ -42,6 +49,7 @@ public class ListShare {
|
|||||||
permissionLevel *= keytoPermEntry.getKey();
|
permissionLevel *= keytoPermEntry.getKey();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
this.uiPosition = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -0,0 +1,24 @@
|
|||||||
|
package com.example.listify.data;
|
||||||
|
|
||||||
|
public class Picture {
|
||||||
|
String base64EncodedImage;
|
||||||
|
|
||||||
|
public Picture(String base64EncodedImage) {
|
||||||
|
this.base64EncodedImage = base64EncodedImage;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Picture{" +
|
||||||
|
"base64EncodedImage='" + base64EncodedImage + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBase64EncodedImage() {
|
||||||
|
return base64EncodedImage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBase64EncodedImage(String base64EncodedImage) {
|
||||||
|
this.base64EncodedImage = base64EncodedImage;
|
||||||
|
}
|
||||||
|
}
|
||||||
22
Listify/app/src/main/res/layout/dialog_rename_list.xml
Normal file
22
Listify/app/src/main/res/layout/dialog_rename_list.xml
Normal 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="Rename List"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:textSize="20sp"
|
||||||
|
android:layout_marginTop="5dp"/>
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/et_renamed_list_name"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="50dp"
|
||||||
|
android:layout_marginHorizontal="15dp"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:hint="@string/new_list_name"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
@ -1,8 +1,9 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:id="@+id/Profile_Section"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="10dp"
|
android:layout_height="@dimen/nav_header_height"
|
||||||
android:background="@drawable/side_nav_bar"
|
android:background="@drawable/side_nav_bar"
|
||||||
android:gravity="bottom"
|
android:gravity="bottom"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
@ -12,24 +13,29 @@
|
|||||||
android:paddingBottom="@dimen/activity_vertical_margin"
|
android:paddingBottom="@dimen/activity_vertical_margin"
|
||||||
android:theme="@style/ThemeOverlay.AppCompat.Dark">
|
android:theme="@style/ThemeOverlay.AppCompat.Dark">
|
||||||
|
|
||||||
<!-- <ImageView-->
|
|
||||||
<!-- android:id="@+id/imageView"-->
|
|
||||||
<!-- android:layout_width="wrap_content"-->
|
|
||||||
<!-- android:layout_height="wrap_content"-->
|
|
||||||
<!-- android:contentDescription="@string/nav_header_desc"-->
|
|
||||||
<!-- android:paddingTop="@dimen/nav_header_vertical_spacing"-->
|
|
||||||
<!-- app:srcCompat="@mipmap/ic_launcher_round" />-->
|
|
||||||
|
|
||||||
<!-- <TextView-->
|
<androidx.cardview.widget.CardView
|
||||||
<!-- android:layout_width="match_parent"-->
|
android:layout_width="96dp"
|
||||||
<!-- android:layout_height="wrap_content"-->
|
android:layout_height="96dp"
|
||||||
<!-- android:paddingTop="@dimen/nav_header_vertical_spacing"-->
|
android:elevation="12dp"
|
||||||
<!-- android:text="@string/nav_header_title"-->
|
android:id="@+id/view2"
|
||||||
<!-- android:textAppearance="@style/TextAppearance.AppCompat.Body1" />-->
|
app:cardCornerRadius="48dp"
|
||||||
|
android:layout_gravity="center_horizontal"
|
||||||
|
android:background="#80000000">
|
||||||
|
<ImageView
|
||||||
|
android:layout_height="96dp"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:id="@+id/imageViewProfilePicture"
|
||||||
|
android:src="@raw/ic_launcher_round"
|
||||||
|
android:scaleType="centerCrop"
|
||||||
|
android:background="#80000000"/>
|
||||||
|
</androidx.cardview.widget.CardView>
|
||||||
|
|
||||||
<!-- <TextView-->
|
|
||||||
<!-- android:id="@+id/textView"-->
|
<TextView
|
||||||
<!-- android:layout_width="wrap_content"-->
|
android:id="@+id/textViewEmailSidebar"
|
||||||
<!-- android:layout_height="wrap_content"-->
|
android:layout_width="wrap_content"
|
||||||
<!-- android:text="@string/nav_header_subtitle" />-->
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_horizontal"
|
||||||
|
android:text="@string/nav_header_subtitle" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
@ -17,12 +17,12 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content">
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
<ImageView
|
<!-- <ImageView-->
|
||||||
android:id="@+id/share_list"
|
<!-- android:id="@+id/share_list"-->
|
||||||
android:src="@drawable/ic_baseline_share_24"
|
<!-- android:src="@drawable/ic_baseline_share_24"-->
|
||||||
android:layout_width="50dp"
|
<!-- android:layout_width="50dp"-->
|
||||||
android:layout_height="50dp"
|
<!-- android:layout_height="50dp"-->
|
||||||
android:background="@color/colorAccent"/>
|
<!-- android:background="@color/colorAccent"/>-->
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/delete_list"
|
android:id="@+id/delete_list"
|
||||||
|
|||||||
BIN
Listify/app/src/main/res/raw/ic_launcher_round.png
Normal file
BIN
Listify/app/src/main/res/raw/ic_launcher_round.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 16 KiB |
4
Listify/app/src/main/res/xml/file_paths.xml
Normal file
4
Listify/app/src/main/res/xml/file_paths.xml
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<paths xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<external-path name="external_files" path="." />
|
||||||
|
</paths>
|
||||||
Loading…
Reference in New Issue
Block a user