diff --git a/Lambdas/APIs/src/main/java/KroggerAPICaller.java b/Lambdas/APIs/src/main/java/KroggerAPICaller.java new file mode 100644 index 0000000..9b0b22d --- /dev/null +++ b/Lambdas/APIs/src/main/java/KroggerAPICaller.java @@ -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 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; + } + +} diff --git a/Listify/app/src/main/AndroidManifest.xml b/Listify/app/src/main/AndroidManifest.xml index 170664e..cfa6d82 100644 --- a/Listify/app/src/main/AndroidManifest.xml +++ b/Listify/app/src/main/AndroidManifest.xml @@ -35,11 +35,13 @@ android:theme="@style/AppTheme.NoActionBar"> - - - - - + + + + + + + \ No newline at end of file diff --git a/Listify/app/src/main/java/com/example/listify/AuthManager.java b/Listify/app/src/main/java/com/example/listify/AuthManager.java index c067fd7..4e67ed3 100644 --- a/Listify/app/src/main/java/com/example/listify/AuthManager.java +++ b/Listify/app/src/main/java/com/example/listify/AuthManager.java @@ -70,6 +70,7 @@ public class AuthManager { public void setAuthSignUpResult(AuthSignUpResult toSet) { authSignUpResult = toSet; + waiting = false; } public void setAuthSignInResult(AuthSignInResult toSet) { diff --git a/Listify/app/src/main/java/com/example/listify/List.java b/Listify/app/src/main/java/com/example/listify/List.java index 3a828b1..ae251ea 100644 --- a/Listify/app/src/main/java/com/example/listify/List.java +++ b/Listify/app/src/main/java/com/example/listify/List.java @@ -1,8 +1,76 @@ package com.example.listify; -public class List { - String name; - List(String name) { - this.name = name; +import android.content.Context; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.ImageView; +import android.widget.ListView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +public class List extends AppCompatActivity { + ListView listView; + String listName = "Sample List"; + String[] pNames = {"Half-gallon organic whole milk"}; + String[] pStores = {"Kroger"}; + String[] pPrices = {"$5.00"}; + int[] pImages = {R.drawable.milk}; + + //List(String name) { + // listName = name; + //} + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_list); + + listView = findViewById(R.id.listView); + + MyAdapter myAdapter = new MyAdapter(this, pNames, pStores, pPrices, pImages); + listView.setAdapter(myAdapter); + } + + class MyAdapter extends ArrayAdapter { + Context context; + String[] pNames; + String[] pStores; + String[] pPrices; + int[] pImages; + + MyAdapter (Context c, String[] names, String[] stores, String[] prices, int[] images) { + super(c, R.layout.listproduct, R.id.productView, names); + context = c; + pNames = names; + pStores = stores; + pPrices = prices; + pImages = images; + } + + @NonNull + @Override + public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) { + LayoutInflater layoutInflater = (LayoutInflater) getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); + View listproduct = layoutInflater.inflate(R.layout.listproduct, parent,false); + + ImageView image = listproduct.findViewById(R.id.imageView); + TextView name = listproduct.findViewById(R.id.productView); + TextView store = listproduct.findViewById(R.id.storeView); + TextView price = listproduct.findViewById(R.id.priceView); + + image.setImageResource(pImages[position]); + name.setText(pNames[position]); + store.setText(pStores[position]); + price.setText(pPrices[position]); + + return listproduct; + } } } diff --git a/Listify/app/src/main/java/com/example/listify/MainActivity.java b/Listify/app/src/main/java/com/example/listify/MainActivity.java index 8260ed5..0549e08 100644 --- a/Listify/app/src/main/java/com/example/listify/MainActivity.java +++ b/Listify/app/src/main/java/com/example/listify/MainActivity.java @@ -27,12 +27,13 @@ public class MainActivity extends AppCompatActivity { super.onCreate(savedInstanceState); //------------------------------Auth Testing---------------------------------------------// - AuthManager authManager = new AuthManager(); + /*AuthManager authManager = new AuthManager(); try { authManager.signIn("merzn@purdue.edu", "Password123"); Log.i("Authentication", authManager.getAuthSession().toString()); 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()); try { authManager.startSignUp("merzn@purdue.edu", "Password123"); @@ -40,46 +41,40 @@ public class MainActivity extends AppCompatActivity { } catch (AuthException signUpError) { Log.e("Authentication", "SignUp error: " + signUpError.getMessage()); } - } - - - - //------------------------------------------------------------------------------------------// + }*/ //----------------------------------API Testing---------------------------------------------// - Properties configs = new Properties(); + + /*Properties configs = new Properties(); try { configs = AuthManager.loadProperties(this, "android.resource://" + getPackageName() + "/raw/auths.json"); - } catch (IOException|JSONException e) { - e.printStackTrace(); } + catch (IOException|JSONException e) { + e.printStackTrace(); + }*/ - Requestor requestor = new Requestor(this, authManager,configs.getProperty("apiKey")); + /*Requestor requestor = new Requestor(this, authManager,configs.getProperty("apiKey")); List testList = new List("IAmATestList"); try { requestor.postObject(testList); - } catch (JSONException e) { - e.printStackTrace(); } - - //------------------------------------------------------------------------------------------// - + catch (JSONException e) { + e.printStackTrace(); + }*/ setContentView(R.layout.activity_main); Toolbar toolbar = findViewById(R.id.toolbar); setSupportActionBar(toolbar); -// FloatingActionButton fab = findViewById(R.id.fab); -// fab.setOnClickListener(new View.OnClickListener() { -// @Override -// public void onClick(View view) { -// Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG) -// .setAction("Action", null).show(); -// } -// }); + /*FloatingActionButton fab = findViewById(R.id.fab); + fab.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG).setAction("Action", null).show(); + } + });*/ DrawerLayout drawer = findViewById(R.id.drawer_layout); NavigationView navigationView = findViewById(R.id.nav_view); - // Passing each menu ID as a set of Ids because each - // menu should be considered as top level destinations. + // Passing each menu ID as a set of Ids because each menu should be considered as top level destinations. mAppBarConfiguration = new AppBarConfiguration.Builder( R.id.nav_home, R.id.nav_gallery, R.id.nav_slideshow) .setDrawerLayout(drawer) @@ -87,14 +82,12 @@ public class MainActivity extends AppCompatActivity { NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment); NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration); NavigationUI.setupWithNavController(navigationView, navController); - // Handle search button click ImageButton searchButton = (ImageButton) findViewById(R.id.searchButton); searchButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(MainActivity.this, SearchResults.class); - // Send user to SearchResults activity startActivity(intent); overridePendingTransition(R.anim.enter_from_left, R.anim.exit_from_left); @@ -103,13 +96,12 @@ public class MainActivity extends AppCompatActivity { }); } -// @Override -// public boolean onCreateOptionsMenu(Menu menu) { -// // Inflate the menu; this adds items to the action bar if it is present. -// getMenuInflater().inflate(R.menu.main, menu); -// return true; -// } - + /*@Override + public boolean onCreateOptionsMenu(Menu menu) { + //Inflate the menu; this adds items to the action bar if it is present. + getMenuInflater().inflate(R.menu.main, menu); + return true; + }*/ @Override public boolean onSupportNavigateUp() { diff --git a/Listify/app/src/main/java/com/example/listify/ui/CodePage.java b/Listify/app/src/main/java/com/example/listify/ui/CodePage.java index 121c992..d2f9e81 100644 --- a/Listify/app/src/main/java/com/example/listify/ui/CodePage.java +++ b/Listify/app/src/main/java/com/example/listify/ui/CodePage.java @@ -1,39 +1,70 @@ package com.example.listify.ui; +import android.app.AlertDialog; +import android.app.Dialog; +import android.content.Context; +import android.content.DialogInterface; import android.content.Intent; import android.os.Bundle; +import android.view.LayoutInflater; import android.view.View; import android.widget.Button; +import android.widget.EditText; +import com.example.listify.AuthManager; import com.example.listify.R; +import com.example.listify.MainActivity; +import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.app.AppCompatDialog; +import androidx.appcompat.app.AppCompatDialogFragment; -public class CodePage extends AppCompatActivity { - private Button button1; //Reset password page button - private Button button2; //Cancel button +public class CodePage extends AppCompatDialogFragment { + private EditText ediTextCode; + + private CodeDialogListener listener; @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_code); + public Dialog onCreateDialog(Bundle savedInstanceState) { + AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); + LayoutInflater inflater = getActivity().getLayoutInflater(); + View view = inflater.inflate(R.layout.activity_code, null); - button1 = (Button) findViewById(R.id.button1); - button1.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - Intent intent = new Intent(CodePage.this, ResetPasswordPage.class); - startActivity(intent); - } - }); + builder.setView(view) + .setTitle("Verification code") + .setPositiveButton("Submit", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + String code = ediTextCode.getText().toString(); + listener.sendCode("" + code + "", false); + } + }) + .setNegativeButton("Cancel", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + String code = ediTextCode.getText().toString(); + listener.sendCode("" + code + "", true); + } + }); - button2 = (Button) findViewById(R.id.button2); - button2.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - Intent intent = new Intent(CodePage.this, LoginPage.class); - startActivity(intent); - } - }); + ediTextCode = view.findViewById(R.id.editTextCode); + + return builder.create(); + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + + try { + listener = (CodeDialogListener) context; + } catch (ClassCastException e) { + throw new ClassCastException("CodeDialogListener not implemented."); + } + } + + public interface CodeDialogListener { + void sendCode(String code, boolean cancel); } } \ No newline at end of file diff --git a/Listify/app/src/main/java/com/example/listify/ui/ForgotPasswordPage.java b/Listify/app/src/main/java/com/example/listify/ui/ForgotPasswordPage.java index bd2194a..24af29e 100644 --- a/Listify/app/src/main/java/com/example/listify/ui/ForgotPasswordPage.java +++ b/Listify/app/src/main/java/com/example/listify/ui/ForgotPasswordPage.java @@ -2,6 +2,7 @@ package com.example.listify.ui; import android.content.Intent; import android.os.Bundle; +import android.util.Log; import android.view.View; import android.widget.Button; @@ -9,7 +10,7 @@ import com.example.listify.R; import androidx.appcompat.app.AppCompatActivity; -public class ForgotPasswordPage extends AppCompatActivity { +public class ForgotPasswordPage extends AppCompatActivity implements CodePage.CodeDialogListener { private Button button1; //Code page button @Override @@ -21,9 +22,27 @@ public class ForgotPasswordPage extends AppCompatActivity { button1.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - Intent intent = new Intent(ForgotPasswordPage.this, CodePage.class); - startActivity(intent); + openDialog(); } }); } + + public void openDialog() { + CodePage codePage = new CodePage(); + codePage.show(getSupportFragmentManager(), "Verification code"); + } + + @Override + public void sendCode(String code, boolean cancel) { + Intent intent; + + if(cancel) { + intent = new Intent(ForgotPasswordPage.this, LoginPage.class); + } + else { + intent = new Intent(ForgotPasswordPage.this, ResetPasswordPage.class); + } + + startActivity(intent); + } } \ No newline at end of file diff --git a/Listify/app/src/main/java/com/example/listify/ui/LoginPage.java b/Listify/app/src/main/java/com/example/listify/ui/LoginPage.java index ed1e006..04682b0 100644 --- a/Listify/app/src/main/java/com/example/listify/ui/LoginPage.java +++ b/Listify/app/src/main/java/com/example/listify/ui/LoginPage.java @@ -2,10 +2,13 @@ package com.example.listify.ui; import android.content.Intent; import android.os.Bundle; +import android.util.Log; import android.view.View; import android.widget.Button; +import android.widget.EditText; import com.example.listify.R; +import com.example.listify.AuthManager; import com.example.listify.MainActivity; import androidx.appcompat.app.AppCompatActivity; @@ -42,8 +45,22 @@ public class LoginPage extends AppCompatActivity { button3.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - Intent intent = new Intent(LoginPage.this, MainActivity.class); - startActivity(intent); + EditText emailText = (EditText) findViewById(R.id.editTextTextPersonName); + EditText passwordText = (EditText) findViewById(R.id.editTextTextPassword); + + String email = emailText.getText().toString(); + String password = passwordText.getText().toString(); + + AuthManager authManager = new AuthManager(); + + try { + authManager.signIn(email, password); + Intent intent = new Intent(LoginPage.this, MainActivity.class); + startActivity(intent); + } + catch(Exception ex) { + //Display "Incorrect email or password" message + } } }); } diff --git a/Listify/app/src/main/java/com/example/listify/ui/SignupPage.java b/Listify/app/src/main/java/com/example/listify/ui/SignupPage.java index d211d8f..ac9aa3c 100644 --- a/Listify/app/src/main/java/com/example/listify/ui/SignupPage.java +++ b/Listify/app/src/main/java/com/example/listify/ui/SignupPage.java @@ -2,18 +2,23 @@ package com.example.listify.ui; import android.content.Intent; import android.os.Bundle; +import android.util.Log; import android.view.View; import android.widget.Button; +import android.widget.EditText; import com.example.listify.R; +import com.example.listify.AuthManager; import com.example.listify.MainActivity; import androidx.appcompat.app.AppCompatActivity; -public class SignupPage extends AppCompatActivity { +public class SignupPage extends AppCompatActivity implements CodePage.CodeDialogListener { private Button button1; //Log in page button private Button button2; //Sign up button + AuthManager authManager = new AuthManager(); + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -32,9 +37,43 @@ public class SignupPage extends AppCompatActivity { button2.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - Intent intent = new Intent(SignupPage.this, MainActivity.class); - startActivity(intent); + EditText emailText = (EditText) findViewById(R.id.editTextTextEmailAddress); + EditText passwordText = (EditText) findViewById(R.id.editTextTextPassword); + + String email = emailText.getText().toString(); + String password = passwordText.getText().toString(); + + try { + authManager.startSignUp(email, password); + } + catch(Exception e) { + return; + } + + openDialog(); } }); } + + public void openDialog() { + CodePage codePage = new CodePage(); + codePage.show(getSupportFragmentManager(), "Verification code"); + } + + @Override + public void sendCode(String code, boolean cancel) { + if(cancel) { + //Remove user from database + } + else { + try { + authManager.confirmSignUp(code); + Intent intent = new Intent(SignupPage.this, MainActivity.class); + startActivity(intent); + } + catch (Exception e) { + //Remove user from database + } + } + } } \ No newline at end of file diff --git a/Listify/app/src/main/java/com/example/listify/ui/home/HomeFragment.java b/Listify/app/src/main/java/com/example/listify/ui/home/HomeFragment.java index 46dcb73..2bb4814 100644 --- a/Listify/app/src/main/java/com/example/listify/ui/home/HomeFragment.java +++ b/Listify/app/src/main/java/com/example/listify/ui/home/HomeFragment.java @@ -14,17 +14,29 @@ import com.example.listify.R; public class HomeFragment extends Fragment { private Button toLoginPage; + private Button toListPage; public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View root = inflater.inflate(R.layout.fragment_home, container, false); + toLoginPage = (Button) root.findViewById(R.id.button1); toLoginPage.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - Intent intent = new Intent(HomeFragment.this.getActivity(), com.example.listify.ui.SignupPage.class); + Intent intent = new Intent(HomeFragment.this.getActivity(), com.example.listify.ui.LoginPage.class); startActivity(intent); } }); + + toListPage = (Button) root.findViewById(R.id.button2); + toListPage.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Intent intent = new Intent(HomeFragment.this.getActivity(), com.example.listify.List.class); + startActivity(intent); + } + }); + return root; } } \ No newline at end of file diff --git a/Listify/app/src/main/res/drawable/milk.png b/Listify/app/src/main/res/drawable/milk.png new file mode 100644 index 0000000..5ebd687 Binary files /dev/null and b/Listify/app/src/main/res/drawable/milk.png differ diff --git a/Listify/app/src/main/res/drawable/placeholder.png b/Listify/app/src/main/res/drawable/placeholder.png new file mode 100644 index 0000000..9db0c3a Binary files /dev/null and b/Listify/app/src/main/res/drawable/placeholder.png differ diff --git a/Listify/app/src/main/res/layout/activity_code.xml b/Listify/app/src/main/res/layout/activity_code.xml index dc50709..2c06f6a 100644 --- a/Listify/app/src/main/res/layout/activity_code.xml +++ b/Listify/app/src/main/res/layout/activity_code.xml @@ -5,44 +5,16 @@ android:layout_width="match_parent" android:layout_height="match_parent"> -