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 b2edf0a..881ce02 100644 --- a/Listify/app/src/main/java/com/example/listify/MainActivity.java +++ b/Listify/app/src/main/java/com/example/listify/MainActivity.java @@ -67,7 +67,6 @@ public class MainActivity extends AppCompatActivity implements CreateListDialogF startActivity(intent); } - //------------------------------Auth Testing---------------------------------------------// boolean testAuth = false; @@ -89,14 +88,10 @@ public class MainActivity extends AppCompatActivity implements CreateListDialogF } } } - //NOTE: deleteUser is slightly unusual in that it requires a Requestor. See below for building one - //authManager.deleteUser(requestor); - - //------------------------------------------------------------------------------------------// + //----------------------------------API Testing---------------------------------------------// boolean testAPI = false; - //----------------------------------API Testing---------------------------------------------// if (testAPI) { AuthManager authManager = new AuthManager(); @@ -114,10 +109,7 @@ public class MainActivity extends AppCompatActivity implements CreateListDialogF Requestor requestor = new Requestor(authManager, configs.getProperty("apiKey")); - - //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 idReceiver = new SynchronousReceiver<>(); @@ -148,37 +140,26 @@ public class MainActivity extends AppCompatActivity implements CreateListDialogF receiverError.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(); - } - });*/ 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. mAppBarConfiguration = new AppBarConfiguration.Builder( - R.id.nav_home, R.id.nav_lists) + R.id.nav_home, R.id.nav_profile) .setDrawerLayout(drawer) .build(); 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); @@ -186,13 +167,6 @@ public class MainActivity extends AppCompatActivity implements CreateListDialogF }); } - /*@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() { NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment); 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 989a48a..bd44ea3 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 @@ -1,101 +1,191 @@ package com.example.listify.ui.home; -import android.app.AlertDialog; -import android.content.DialogInterface; -import android.content.Intent; import android.os.Bundle; -import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.Button; -import android.widget.EditText; +import android.widget.ListView; +import android.widget.ProgressBar; +import android.widget.TextView; +import android.widget.Toast; + import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; import com.example.listify.AuthManager; +import com.example.listify.CreateListDialogFragment; +import com.example.listify.LoadingCircleDialog; import com.example.listify.R; import com.example.listify.Requestor; +import com.example.listify.SynchronousReceiver; +import com.example.listify.adapter.ShoppingListsSwipeableAdapter; +import com.example.listify.data.List; +import com.google.android.material.floatingactionbutton.FloatingActionButton; + import org.json.JSONException; import java.io.IOException; +import java.time.Instant; +import java.util.ArrayList; import java.util.Properties; import static com.example.listify.MainActivity.am; -public class HomeFragment extends Fragment { - private Button toDeleteAccountPage; +public class HomeFragment extends Fragment implements CreateListDialogFragment.OnNewListListener, Requestor.Receiver { + ArrayList shoppingLists = new ArrayList<>(); + ShoppingListsSwipeableAdapter shoppingListsSwipeableAdapter; + Requestor requestor; + ListView shoppingListsView; + ProgressBar loadingLists; + TextView emptyMessage; public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View root = inflater.inflate(R.layout.fragment_home, container, false); + shoppingListsView = root.findViewById(R.id.shopping_lists); + loadingLists = (ProgressBar) root.findViewById(R.id.progress_loading_lists); + loadingLists.setVisibility(View.VISIBLE); + emptyMessage = (TextView) root.findViewById(R.id.textViewEmpty); - toDeleteAccountPage = (Button) root.findViewById(R.id.button); - toDeleteAccountPage.setOnClickListener(new View.OnClickListener() { + Properties configs = new Properties(); + try { + configs = AuthManager.loadProperties(getContext(), "android.resource://" + getActivity().getPackageName() + "/raw/auths.json"); + } catch (IOException | JSONException e) { + e.printStackTrace(); + } + + requestor = new Requestor(am, configs.getProperty("apiKey")); + SynchronousReceiver listIdsReceiver = new SynchronousReceiver<>(); + + final Requestor.Receiver recv = this; + requestor.getListOfIds(List.class, recv, null); + + + FloatingActionButton fab = (FloatingActionButton) root.findViewById(R.id.new_list_fab); + Fragment thisFragment = this; + fab.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - View passwordView = getLayoutInflater().inflate(R.layout.activity_code, null); - AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); - builder.setView(passwordView); - builder.setTitle("Account deletion verification"); - builder.setMessage("Are you sure you want to delete your account? If so, enter your password below and hit \"Yes\"."); - builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - EditText passwordText = (EditText) passwordView.findViewById(R.id.editTextCode); - String password = passwordText.getText().toString(); - if(password.equals(am.getPassword())) { - try { - Properties configs = new Properties(); - try { - configs = AuthManager.loadProperties(getContext(), "android.resource://" + getActivity().getPackageName() + "/raw/auths.json"); - } catch (IOException | JSONException e) { - e.printStackTrace(); - } - Requestor requestor = new Requestor(am, configs.getProperty("apiKey")); - -// try { -// am.changePassword(am.getEmail()); -// } -// catch (Exception e) {} - /*try { - am.confirmPasswordReset("", ""); - } - - String[] TO = {am.getEmail()}; - Intent emailIntent = new Intent(Intent.ACTION_SEND); - emailIntent.setData(Uri.parse("mailto:")); - emailIntent.setType("text/plain"); - emailIntent.putExtra(Intent.EXTRA_EMAIL, TO); - emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Listify account deleted"); - emailIntent.putExtra(Intent.EXTRA_TEXT, "Hello, this email is to confirm that you have deleted your Listify account."); - try { - startActivity(Intent.createChooser(emailIntent, "Send mail...")); - Log.i("Finished sending email...", ""); - System.out.println("A"); - } catch (Exception e) { - e.printStackTrace(); - System.out.println("B"); - }*/ - - am.deleteUser(requestor); - am.nullify(); - Intent intent = new Intent(getActivity(), com.example.listify.ui.LoginPage.class); - startActivity(intent); - } - catch (Exception e) { - Log.i("Authentication", e.toString()); - } - } - } - }); - builder.setNegativeButton("No", new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) {} - }); - AlertDialog dialog = builder.create(); - dialog.show(); + CreateListDialogFragment createListDialogFragment = new CreateListDialogFragment(); + createListDialogFragment.show(getFragmentManager(), "Create New List"); + createListDialogFragment.setTargetFragment(thisFragment, 0); } }); return root; } + + + @Override + public void sendNewListName(String name) { + LoadingCircleDialog loadingDialog = new LoadingCircleDialog(getActivity()); + loadingDialog.show(); + + Properties configs = new Properties(); + try { + configs = AuthManager.loadProperties(getContext(), "android.resource://" + getActivity().getPackageName() + "/raw/auths.json"); + } catch (IOException | JSONException e) { + e.printStackTrace(); + } + Requestor requestor = new Requestor(am, configs.getProperty("apiKey")); + SynchronousReceiver idReceiver = new SynchronousReceiver<>(); + + List newList = new List(-1, name, "user filled by lambda", Instant.now().toEpochMilli()); + + try { + requestor.postObject(newList, idReceiver, idReceiver); + emptyMessage.setVisibility(View.GONE); + } catch (Exception e) { + Toast.makeText(getContext(), "An error occurred", Toast.LENGTH_LONG).show(); + e.printStackTrace(); + } + Thread t = new Thread(new Runnable() { + @Override + public void run() { + try { + newList.setItemID(idReceiver.await()); + } catch (Exception e) { + getActivity().runOnUiThread(new Runnable() { + @Override + public void run() { + Toast.makeText(getContext(), "An error occurred", Toast.LENGTH_LONG).show(); + loadingDialog.cancel(); + } + }); + e.printStackTrace(); + + } + shoppingLists.add(newList); + + getActivity().runOnUiThread(new Runnable() { + @Override + public void run() { + shoppingListsSwipeableAdapter.notifyDataSetChanged(); + loadingDialog.cancel(); + Toast.makeText(getContext(), String.format("%s created", name), Toast.LENGTH_LONG).show(); + } + }); + } + }); + t.start(); + } + + @Override + public void acceptDelivery(Object delivered) { + Integer[] listIds = (Integer[]) delivered; + // Create threads and add them to a list + Thread[] threads = new Thread[listIds.length]; + List[] results = new List[listIds.length]; + for (int i = 0; i < listIds.length; i++) { + SynchronousReceiver listReceiver = new SynchronousReceiver<>(); + requestor.getObject(Integer.toString(listIds[i]), List.class, listReceiver, listReceiver); + final int finalI = i; + Thread t = new Thread(new Runnable() { + @Override + public void run() { + try { + results[finalI] = listReceiver.await(); + } catch (Exception e) { + e.printStackTrace(); + } + } + }); + threads[i] = t; + t.start(); + } + + // Wait for each thread to finish and add results to shoppingLists + for (int i = 0; i < threads.length; i++) { + try { + threads[i].join(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + shoppingLists.add(results[i]); + } + + // Set adapter and display this users lists + shoppingListsSwipeableAdapter = new ShoppingListsSwipeableAdapter(getActivity(), shoppingLists); + + getActivity().runOnUiThread(new Runnable() { + @Override + public void run() { + shoppingListsView.setAdapter(shoppingListsSwipeableAdapter); +// shoppingListsView.setOnItemClickListener(new AdapterView.OnItemClickListener() { +// @Override +// public void onItemClick(AdapterView parent, View view, int position, long id) { +// Intent listPage = new Intent(getContext(), ListPage.class); +// +// // Send the list ID +// listPage.putExtra("listID", shoppingLists.get(position).getItemID()); +// startActivity(listPage); +// } +// }); + loadingLists.setVisibility(View.GONE); + + if(listIds.length == 0) { + emptyMessage.setVisibility(View.VISIBLE); + } + } + }); + + } } \ No newline at end of file diff --git a/Listify/app/src/main/java/com/example/listify/ui/lists/ListsFragment.java b/Listify/app/src/main/java/com/example/listify/ui/lists/ListsFragment.java deleted file mode 100644 index ce8411f..0000000 --- a/Listify/app/src/main/java/com/example/listify/ui/lists/ListsFragment.java +++ /dev/null @@ -1,183 +0,0 @@ -package com.example.listify.ui.lists; - -import android.os.Bundle; -import android.view.View; -import android.view.ViewGroup; -import android.view.LayoutInflater; -import android.widget.ListView; -import android.widget.ProgressBar; -import android.widget.Toast; -import androidx.annotation.NonNull; -import androidx.fragment.app.Fragment; - -import com.example.listify.AuthManager; -import com.example.listify.CreateListDialogFragment; -import com.example.listify.LoadingCircleDialog; -import com.example.listify.R; -import com.example.listify.Requestor; -import com.example.listify.SynchronousReceiver; -import com.example.listify.adapter.ShoppingListsSwipeableAdapter; -import com.example.listify.data.List; -import com.google.android.material.floatingactionbutton.FloatingActionButton; - -import org.json.JSONException; - -import java.io.IOException; -import java.time.Instant; -import java.util.ArrayList; -import java.util.Properties; - -import static com.example.listify.MainActivity.am; - -public class ListsFragment extends Fragment implements CreateListDialogFragment.OnNewListListener, Requestor.Receiver { - ArrayList shoppingLists = new ArrayList<>(); - ShoppingListsSwipeableAdapter shoppingListsSwipeableAdapter; - Requestor requestor; - ListView shoppingListsView; - ProgressBar loadingLists; - int resultsIndex; - - public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - View root = inflater.inflate(R.layout.fragment_lists, container, false); - shoppingListsView = root.findViewById(R.id.shopping_lists); - loadingLists = (ProgressBar) root.findViewById(R.id.progress_loading_lists); - loadingLists.setVisibility(View.VISIBLE); - - Properties configs = new Properties(); - try { - configs = AuthManager.loadProperties(getContext(), "android.resource://" + getActivity().getPackageName() + "/raw/auths.json"); - } catch (IOException | JSONException e) { - e.printStackTrace(); - } - - requestor = new Requestor(am, configs.getProperty("apiKey")); - SynchronousReceiver listIdsReceiver = new SynchronousReceiver<>(); - - final Requestor.Receiver recv = this; - requestor.getListOfIds(List.class, recv, null); - - - FloatingActionButton fab = (FloatingActionButton) root.findViewById(R.id.new_list_fab); - Fragment thisFragment = this; - fab.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - CreateListDialogFragment createListDialogFragment = new CreateListDialogFragment(); - createListDialogFragment.show(getFragmentManager(), "Create New List"); - createListDialogFragment.setTargetFragment(thisFragment, 0); - } - }); - - return root; - } - - @Override - public void sendNewListName(String name) { - LoadingCircleDialog loadingDialog = new LoadingCircleDialog(getActivity()); - loadingDialog.show(); - - Properties configs = new Properties(); - try { - configs = AuthManager.loadProperties(getContext(), "android.resource://" + getActivity().getPackageName() + "/raw/auths.json"); - } catch (IOException | JSONException e) { - e.printStackTrace(); - } - Requestor requestor = new Requestor(am, configs.getProperty("apiKey")); - SynchronousReceiver idReceiver = new SynchronousReceiver<>(); - - List newList = new List(-1, name, "user filled by lambda", Instant.now().toEpochMilli()); - - try { - requestor.postObject(newList, idReceiver, idReceiver); - } catch (Exception e) { - Toast.makeText(getContext(), "An error occurred", Toast.LENGTH_LONG).show(); - e.printStackTrace(); - } - Thread t = new Thread(new Runnable() { - @Override - public void run() { - try { - newList.setItemID(idReceiver.await()); - } catch (Exception e) { - getActivity().runOnUiThread(new Runnable() { - @Override - public void run() { - Toast.makeText(getContext(), "An error occurred", Toast.LENGTH_LONG).show(); - loadingDialog.cancel(); - } - }); - e.printStackTrace(); - - } - shoppingLists.add(newList); - - getActivity().runOnUiThread(new Runnable() { - @Override - public void run() { - shoppingListsSwipeableAdapter.notifyDataSetChanged(); - loadingDialog.cancel(); - Toast.makeText(getContext(), String.format("%s created", name), Toast.LENGTH_LONG).show(); - } - }); - } - }); - t.start(); - } - - @Override - public void acceptDelivery(Object delivered) { - Integer[] listIds = (Integer[]) delivered; - // Create threads and add them to a list - Thread[] threads = new Thread[listIds.length]; - List[] results = new List[listIds.length]; - for (int i = 0; i < listIds.length; i++) { - SynchronousReceiver listReceiver = new SynchronousReceiver<>(); - requestor.getObject(Integer.toString(listIds[i]), List.class, listReceiver, listReceiver); - final int finalI = i; - Thread t = new Thread(new Runnable() { - @Override - public void run() { - try { - results[finalI] = listReceiver.await(); - } catch (Exception e) { - e.printStackTrace(); - } - } - }); - threads[i] = t; - t.start(); - } - - // Wait for each thread to finish and add results to shoppingLists - for (int i = 0; i < threads.length; i++) { - try { - threads[i].join(); - } catch (InterruptedException e) { - e.printStackTrace(); - } - shoppingLists.add(results[i]); - } - - // Set adapter and display this users lists - shoppingListsSwipeableAdapter = new ShoppingListsSwipeableAdapter(getActivity(), shoppingLists); - - getActivity().runOnUiThread(new Runnable() { - @Override - public void run() { - shoppingListsView.setAdapter(shoppingListsSwipeableAdapter); -// shoppingListsView.setOnItemClickListener(new AdapterView.OnItemClickListener() { -// @Override -// public void onItemClick(AdapterView parent, View view, int position, long id) { -// Intent listPage = new Intent(getContext(), ListPage.class); -// -// // Send the list ID -// listPage.putExtra("listID", shoppingLists.get(position).getItemID()); -// startActivity(listPage); -// } -// }); - loadingLists.setVisibility(View.GONE); - } - }); - - } -} \ No newline at end of file diff --git a/Listify/app/src/main/java/com/example/listify/ui/profile/ProfileFragment.java b/Listify/app/src/main/java/com/example/listify/ui/profile/ProfileFragment.java new file mode 100644 index 0000000..134cd18 --- /dev/null +++ b/Listify/app/src/main/java/com/example/listify/ui/profile/ProfileFragment.java @@ -0,0 +1,83 @@ +package com.example.listify.ui.profile; + +import android.app.AlertDialog; +import android.content.DialogInterface; +import android.content.Intent; +import android.os.Bundle; +import android.util.Log; +import android.view.View; +import android.view.ViewGroup; +import android.view.LayoutInflater; +import android.widget.Button; +import android.widget.EditText; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; + +import com.example.listify.AuthManager; +import com.example.listify.R; +import com.example.listify.Requestor; + +import org.json.JSONException; + +import java.io.IOException; +import java.util.Properties; + +import static com.example.listify.MainActivity.am; + +public class ProfileFragment extends Fragment { + private Button toDeleteAccountPage; + + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + View root = inflater.inflate(R.layout.fragment_profile, container, false); + + TextView emailText = (TextView) root.findViewById(R.id.textViewEmail); + emailText.setText(am.getEmail()); + + toDeleteAccountPage = (Button) root.findViewById(R.id.button); + toDeleteAccountPage.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + View passwordView = getLayoutInflater().inflate(R.layout.activity_code, null); + AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); + builder.setView(passwordView); + builder.setTitle("Account deletion verification"); + builder.setMessage("Are you sure you want to delete your account? If so, enter your password below and hit \"Yes\"."); + builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + EditText passwordText = (EditText) passwordView.findViewById(R.id.editTextCode); + String password = passwordText.getText().toString(); + if(password.equals(am.getPassword())) { + try { + Properties configs = new Properties(); + try { + configs = AuthManager.loadProperties(getContext(), "android.resource://" + getActivity().getPackageName() + "/raw/auths.json"); + } catch (IOException | JSONException e) { + e.printStackTrace(); + } + Requestor requestor = new Requestor(am, configs.getProperty("apiKey")); + am.deleteUser(requestor); + am.nullify(); + Intent intent = new Intent(getActivity(), com.example.listify.ui.LoginPage.class); + startActivity(intent); + } + catch (Exception e) { + Log.i("Authentication", e.toString()); + } + } + } + }); + builder.setNegativeButton("No", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) {} + }); + AlertDialog dialog = builder.create(); + dialog.show(); + } + }); + + return root; + } +} diff --git a/Listify/app/src/main/res/drawable/bananas.png b/Listify/app/src/main/res/drawable/bananas.png deleted file mode 100644 index ff750c7..0000000 Binary files a/Listify/app/src/main/res/drawable/bananas.png and /dev/null differ diff --git a/Listify/app/src/main/res/drawable/ic_baseline_person_24.xml b/Listify/app/src/main/res/drawable/ic_baseline_person_24.xml new file mode 100644 index 0000000..6bdced2 --- /dev/null +++ b/Listify/app/src/main/res/drawable/ic_baseline_person_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/Listify/app/src/main/res/drawable/milk.png b/Listify/app/src/main/res/drawable/milk.png deleted file mode 100644 index 5ebd687..0000000 Binary files a/Listify/app/src/main/res/drawable/milk.png and /dev/null differ diff --git a/Listify/app/src/main/res/drawable/peanutbutter.png b/Listify/app/src/main/res/drawable/peanutbutter.png deleted file mode 100644 index 74dff48..0000000 Binary files a/Listify/app/src/main/res/drawable/peanutbutter.png and /dev/null differ diff --git a/Listify/app/src/main/res/layout/app_bar_lists.xml b/Listify/app/src/main/res/layout/app_bar_profile.xml similarity index 100% rename from Listify/app/src/main/res/layout/app_bar_lists.xml rename to Listify/app/src/main/res/layout/app_bar_profile.xml diff --git a/Listify/app/src/main/res/layout/fragment_home.xml b/Listify/app/src/main/res/layout/fragment_home.xml index a938244..40a1b88 100644 --- a/Listify/app/src/main/res/layout/fragment_home.xml +++ b/Listify/app/src/main/res/layout/fragment_home.xml @@ -1,19 +1,49 @@ - -