diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..39fb081 --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +*.iml +.gradle +/local.properties +/.idea/workspace.xml +/.idea/libraries +.DS_Store +/build +/captures +.externalNativeBuild diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..96cc43e --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml new file mode 100644 index 0000000..e7bedf3 --- /dev/null +++ b/.idea/copyright/profiles_settings.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..0e23f8e --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,19 @@ + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..5d19981 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..e455c7c --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/README.md b/README.md index fe059e5..820d909 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,12 @@ +<<<<<<< HEAD # sp17proj4android Repository for Spring 2017 MDB Android Training Program Mini-Project 4 Submissions +======= +# sp17proj3android + +Repository for Spring 2017 MDB Android Training Program Mini-Project 3 Submissions +>>>>>>> 3a401a6afcca5bcd9e9a97689a5783443ea32dbd Finalized mini-projects should be stored in personal portfolios, but this repository will be used for providing feedback on code quality using the GitHub code review features. diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..6538c6f --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,39 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 25 + buildToolsVersion "25.0.2" + defaultConfig { + applicationId "com.example.eric.socials" + minSdkVersion 15 + targetSdkVersion 25 + versionCode 1 + versionName "1.0" + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } +} + +dependencies { + compile fileTree(dir: 'libs', include: ['*.jar']) + androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { + exclude group: 'com.android.support', module: 'support-annotations' + }) + compile 'com.android.support:appcompat-v7:25.1.1' + compile 'com.android.support.constraint:constraint-layout:1.0.0-beta4' + compile 'com.android.support:cardview-v7:25.1.1' + compile 'com.android.support:design:25.1.1' + compile 'com.github.bumptech.glide:glide:3.7.0' + compile 'com.google.firebase:firebase-auth:10.0.1' + compile 'com.google.firebase:firebase-database:10.0.1' + compile 'com.google.firebase:firebase-storage:10.0.1' + compile 'com.google.firebase:firebase-core:10.0.1' + testCompile 'junit:junit:4.12' + compile 'com.android.support:recyclerview-v7:25.1.1' +} +apply plugin: 'com.google.gms.google-services' diff --git a/app/google-services.json b/app/google-services.json new file mode 100644 index 0000000..b4e6711 --- /dev/null +++ b/app/google-services.json @@ -0,0 +1,42 @@ +{ + "project_info": { + "project_number": "390076906806", + "firebase_url": "https://mdb-socials-47b33.firebaseio.com", + "project_id": "mdb-socials-47b33", + "storage_bucket": "mdb-socials-47b33.appspot.com" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:390076906806:android:882cd173d8533738", + "android_client_info": { + "package_name": "com.example.eric.socials" + } + }, + "oauth_client": [ + { + "client_id": "390076906806-d9i57ejp3qskfluavt8np4v0muof7tjj.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyD4v6Q7uG0KXhOoA1h9Qj1DYojFRLxT_10" + } + ], + "services": { + "analytics_service": { + "status": 1 + }, + "appinvite_service": { + "status": 1, + "other_platform_oauth_client": [] + }, + "ads_service": { + "status": 2 + } + } + } + ], + "configuration_version": "1" +} \ No newline at end of file diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..19be167 --- /dev/null +++ b/app/proguard-rules.pro @@ -0,0 +1,17 @@ +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in /home/eric/Android/Sdk/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the proguardFiles +# directive in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} diff --git a/app/src/androidTest/java/com/example/eric/socials/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/example/eric/socials/ExampleInstrumentedTest.java new file mode 100644 index 0000000..8c1e91d --- /dev/null +++ b/app/src/androidTest/java/com/example/eric/socials/ExampleInstrumentedTest.java @@ -0,0 +1,26 @@ +package com.example.eric.socials; + +import android.content.Context; +import android.support.test.InstrumentationRegistry; +import android.support.test.runner.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumentation test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() throws Exception { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getTargetContext(); + + assertEquals("com.example.eric.socials", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..d615532 --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/example/eric/socials/AddEvent.java b/app/src/main/java/com/example/eric/socials/AddEvent.java new file mode 100644 index 0000000..144f4d9 --- /dev/null +++ b/app/src/main/java/com/example/eric/socials/AddEvent.java @@ -0,0 +1,133 @@ +package com.example.eric.socials; + +import android.app.Activity; +import android.content.DialogInterface; +import android.content.Intent; +import android.graphics.Bitmap; +import android.net.Uri; +import android.provider.MediaStore; +import android.support.annotation.NonNull; +import android.support.v7.app.AlertDialog; +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; +import android.view.View; +import android.widget.Button; +import android.widget.EditText; +import android.widget.ImageView; +import android.widget.Toast; + +import com.google.android.gms.tasks.OnFailureListener; +import com.google.android.gms.tasks.OnSuccessListener; +import com.google.firebase.database.DatabaseReference; +import com.google.firebase.database.FirebaseDatabase; +import com.google.firebase.storage.FirebaseStorage; +import com.google.firebase.storage.StorageReference; +import com.google.firebase.storage.UploadTask; +import com.google.firebase.auth.FirebaseAuth; +import com.google.firebase.auth.FirebaseUser; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.ArrayList; + +public class AddEvent extends AppCompatActivity implements View.OnClickListener{ + + EditText eventName; + EditText date; + EditText description; + Button createSocial; + ImageView eventImage; + + private Intent data; + + FirebaseDatabase database = FirebaseDatabase.getInstance(); + DatabaseReference myRef = database.getReference("/socials"); + private StorageReference mStorageRef; + + private static FirebaseAuth mAuth; + private static FirebaseUser mUser; + + @Override + public void onClick(View v){ + switch (v.getId()) { + case R.id.createEventButton: + mStorageRef = FirebaseStorage.getInstance().getReferenceFromUrl(getString(R.string.firebase_link)); + final String key = myRef.child("socials").push().getKey(); + StorageReference imageRef = mStorageRef.child(key + ".png"); + + imageRef.putFile(data.getData()).addOnFailureListener(new OnFailureListener() { + @Override + public void onFailure(@NonNull Exception exception) { + Toast.makeText(getApplicationContext(), "need an image!", Toast.LENGTH_SHORT).show(); + } + }).addOnSuccessListener(new OnSuccessListener() { + @Override + public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) { + ArrayList users = new ArrayList(); + users.add(mUser.getUid()); + Social s = new Social(eventName.getText().toString(), key + ".png", mUser.getEmail() , description.getText().toString(), + 1, date.getText().toString(), users); + myRef.child(key).setValue(s); + Toast.makeText(getApplicationContext(), "Post Successful!", Toast.LENGTH_SHORT).show(); + Intent intent = new Intent(getApplicationContext(), FeedActivity.class); + startActivity(intent); + } + }); + Utils.progressBar(this, getString(R.string.create_social_progressbar)); + break; + default: + } + } + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_add_event); + + eventName = (EditText) findViewById(R.id.eventName); + date = (EditText) findViewById(R.id.eventDate); + description = (EditText) findViewById(R.id.description); + createSocial = (Button) findViewById(R.id.createEventButton); + eventImage = (ImageView) findViewById(R.id.eventImage); + + eventImage.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + AlertDialog alertDialog = new AlertDialog.Builder(AddEvent.this).create(); + alertDialog.setTitle("Set a Photo"); + alertDialog.setButton(AlertDialog.BUTTON_NEGATIVE, "Upload from Gallery", + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + //launch gallery + startActivityForResult(new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.INTERNAL_CONTENT_URI), 3); + dialog.dismiss(); + } + }); + alertDialog.show(); + } + }); + + mAuth = FirebaseAuth.getInstance(); + mUser = mAuth.getCurrentUser(); + + createSocial.setOnClickListener(this); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + //Detects request codes + if ((requestCode == 3 || requestCode == 1) && resultCode == Activity.RESULT_OK) { + Uri selectedImage = data.getData(); + Bitmap bitmap = null; + try { + bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), selectedImage); + ((ImageView) findViewById(R.id.eventImage)).setImageBitmap(bitmap); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } + this.data = data; + } +} diff --git a/app/src/main/java/com/example/eric/socials/DetailActivity.java b/app/src/main/java/com/example/eric/socials/DetailActivity.java new file mode 100644 index 0000000..c12a37e --- /dev/null +++ b/app/src/main/java/com/example/eric/socials/DetailActivity.java @@ -0,0 +1,181 @@ +package com.example.eric.socials; + +import android.content.Intent; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.net.Uri; +import android.os.AsyncTask; +import android.support.annotation.NonNull; +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; +import android.view.Display; +import android.view.View; +import android.widget.Button; +import android.widget.ImageView; +import android.widget.ProgressBar; +import android.widget.TextView; +import android.widget.Toast; + +import com.google.android.gms.tasks.OnFailureListener; +import com.google.android.gms.tasks.OnSuccessListener; +import com.google.firebase.auth.FirebaseAuth; +import com.google.firebase.auth.FirebaseUser; +import com.google.firebase.database.DatabaseReference; +import com.google.firebase.database.FirebaseDatabase; +import com.google.firebase.storage.FirebaseStorage; + +import java.io.InputStream; +import java.net.URL; +import java.util.ArrayList; + +public class DetailActivity extends AppCompatActivity implements View.OnClickListener{ + + TextView socialName; + TextView emailAddress; + TextView socialDescription; + + ImageView socialImage; + + Button interestedButton; + Button numRSVPButton; + + DatabaseReference myRef; + + private static FirebaseAuth mAuth; + private static FirebaseUser mUser; + + Intent grabIntent; + + ArrayList usersInterested; + + boolean isInterested = false; + int intNumRSVP; + + @Override + public void onClick(View v){ // Handles Cases for clicking Interested & Num RSVP Buttons + switch (v.getId()) { + case R.id.numRSVPButton: + if(usersInterested == null || usersInterested.size() == 0){ + Toast.makeText(getApplicationContext(), "There is no one interested in this event", Toast.LENGTH_SHORT).show(); + } else { + Intent intent = new Intent(getApplicationContext(), Interested.class); + intent.putExtra(getString(R.string.email), emailAddress.getText().toString()); // On Click, go to new activity with recylcer view of users interested + startActivity(intent); + } + break; + + case R.id.interestedButton: + final String userUID = mUser.getUid(); + final String socialId = grabIntent.getStringExtra("socialID"); + + if (!isInterested && (usersInterested == null || !usersInterested.contains(userUID))) { + if(usersInterested == null) { + ArrayList tempUsers = new ArrayList<>(); + tempUsers.add(userUID); + myRef.child(socialId).child(getString(R.string.usersInterested)).setValue(tempUsers); // On click, increment num of users interested + } else { // and add the user to the arraylist field + usersInterested.add(userUID); + myRef.child(socialId).child(getString(R.string.usersInterested)).setValue(usersInterested); + } + + intNumRSVP += 1; + myRef.child(socialId).child(getString(R.string.numRSVP)).setValue(intNumRSVP); + numRSVPButton.setText(Integer.toString(intNumRSVP) + " People Interested!"); + + Toast.makeText(getApplicationContext(), getString(R.string.marked_interested), Toast.LENGTH_SHORT).show(); + isInterested = true; + + } else { + usersInterested.remove(userUID); + myRef.child(socialId).child(getString(R.string.usersInterested)).setValue(usersInterested); + + intNumRSVP -= 1; + myRef.child(socialId).child(getString(R.string.numRSVP)).setValue(intNumRSVP); + numRSVPButton.setText(Integer.toString(intNumRSVP) + " People Interested!"); + + Toast.makeText(getApplicationContext(), getString(R.string.unmarked_interested), Toast.LENGTH_SHORT).show(); + isInterested = false; + } + break; + + default: + } + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_detail2); + + grabIntent = getIntent(); + + socialName = (TextView) findViewById(R.id.socialName); + socialDescription = (TextView) findViewById(R.id.socialDescription); + emailAddress = (TextView) findViewById(R.id.emailAddress); + + socialImage = (ImageView) findViewById(R.id.socialImage); + + interestedButton = (Button) findViewById(R.id.interestedButton); + numRSVPButton = (Button) findViewById(R.id.numRSVPButton); + + socialName.setText(grabIntent.getStringExtra("name")); + emailAddress.setText(grabIntent.getStringExtra("email")); // Can't use Strings because these values come from the Adapter + socialDescription.setText(grabIntent.getStringExtra("desc")); + + final String numrsvp = grabIntent.getStringExtra(getString(R.string.numRSVP)); // Case for 1 vs Multiple people interested + if (Integer.parseInt(numrsvp) == 1) { + numRSVPButton.setText("1 Person Interested!"); + } else { + numRSVPButton.setText(numrsvp + " People Interested!"); + } + + intNumRSVP = Integer.parseInt(numrsvp); + + myRef = FirebaseDatabase.getInstance().getReference("/socials"); + + String imageUrl = grabIntent.getStringExtra("image"); + usersInterested = grabIntent.getStringArrayListExtra(getString(R.string.usersInterested)); + + mAuth = FirebaseAuth.getInstance(); + mUser = mAuth.getCurrentUser(); + + + interestedButton.setOnClickListener(this); + numRSVPButton.setOnClickListener(this); //Listeners for both buttons + + final AsyncTask asyncTask = new AsyncTask() { + @Override + protected Bitmap doInBackground(String... params) { + Display display = getWindowManager().getDefaultDisplay(); + int width = display.getWidth(); // Download the image in the background and place it into the imageView + int height = display.getHeight(); + Bitmap bit = null; + try { + bit = BitmapFactory.decodeStream((InputStream) new URL(params[0].toString()).getContent()); + + } catch (Exception e) {} + Bitmap sc = Bitmap.createScaledBitmap(bit,width,height,true); + return sc; + } + + @Override + protected void onPostExecute(Bitmap bitmap) { + super.onPostExecute(bitmap); + socialImage.setImageBitmap(bitmap); + } + }; + + + FirebaseStorage.getInstance().getReferenceFromUrl(getString(R.string.firebase_link)).child(imageUrl).getDownloadUrl().addOnSuccessListener(new OnSuccessListener() { + @Override + public void onSuccess(Uri uri) { + asyncTask.execute(uri.toString()); + } + }).addOnFailureListener(new OnFailureListener() { + @Override + public void onFailure(@NonNull Exception exception) { + + } + }); + } +} diff --git a/app/src/main/java/com/example/eric/socials/FeedActivity.java b/app/src/main/java/com/example/eric/socials/FeedActivity.java new file mode 100644 index 0000000..571964b --- /dev/null +++ b/app/src/main/java/com/example/eric/socials/FeedActivity.java @@ -0,0 +1,118 @@ +package com.example.eric.socials; + +import android.content.Intent; +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.util.SparseBooleanArray; +import android.view.View; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.ListView; + +import com.google.firebase.auth.FirebaseAuth; +import com.google.firebase.database.DataSnapshot; +import com.google.firebase.database.DatabaseError; +import com.google.firebase.database.DatabaseReference; +import com.google.firebase.database.FirebaseDatabase; +import com.google.firebase.database.GenericTypeIndicator; +import com.google.firebase.database.ValueEventListener; + +import java.util.ArrayList; + +public class FeedActivity extends AppCompatActivity { + + private ListView mDrawerList; + private ArrayAdapter mAdapter; + private String[]optionsArray = {"Update Profile", "Create New Social", "Logout"}; + RecyclerView recyclerView; + FeedAdapter feedAdapter; + private ArrayList mSocials = new ArrayList<>(); + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_feed); + + recyclerView = (RecyclerView)findViewById(R.id.recylcerView); + recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext())); + + mDrawerList = (ListView) findViewById(R.id.navList); + mAdapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, optionsArray); + mDrawerList.setAdapter(mAdapter); + + mDrawerList.setOnItemClickListener(new AdapterView.OnItemClickListener() { // Listener for clicking an Item on the Side Drawer + @Override + public void onItemClick(AdapterView adapterView, View view, int i, long l) { + SparseBooleanArray clickedItemPositions = mDrawerList.getCheckedItemPositions(); + mAdapter.notifyDataSetChanged(); + + for(int j = 0;j < clickedItemPositions.size(); j ++){ + boolean checked = clickedItemPositions.valueAt(j); + + if(checked){ + int key = clickedItemPositions.keyAt(j); + String item = (String) mDrawerList.getItemAtPosition(key); + + if(item.equalsIgnoreCase(getString(R.string.update_profile_button))){ + Intent intent = new Intent(getApplicationContext(), UpdateProfile.class); + startActivity(intent); + } + if(item.equalsIgnoreCase(getString(R.string.logout_button))){ + FirebaseAuth.getInstance().signOut(); + Intent intent = new Intent(getApplicationContext(), LoginActivity.class); + startActivity(intent); + } + if(item.equalsIgnoreCase(getString(R.string.create_new_social_button))){ + Intent intent = new Intent(getApplicationContext(), AddEvent.class); + startActivity(intent); + } + } + } + } + }); + + DatabaseReference myRef = FirebaseDatabase.getInstance().getReference(getString(R.string.socials_db_tree)); // DB Reference to the socials tree + myRef.addValueEventListener(new ValueEventListener() { + @Override + public void onDataChange(DataSnapshot dataSnapshot) { + mSocials.clear(); + for (DataSnapshot socialSnapShot: dataSnapshot.getChildren()) { + GenericTypeIndicator> t = new GenericTypeIndicator>() {}; + Social social = new Social(socialSnapShot.child(getString(R.string.eventName)).getValue(String.class), + socialSnapShot.child(getString(R.string.eventImage)).getValue(String.class), + socialSnapShot.child(getString(R.string.emailOfCreator)).getValue(String.class), // Adding socials to an arraylist so the adapter can use the data + socialSnapShot.child(getString(R.string.description)).getValue(String.class), + socialSnapShot.child(getString(R.string.numRSVP)).getValue(Integer.class), + socialSnapShot.child(getString(R.string.date)).getValue(String.class), + socialSnapShot.child(getString(R.string.usersInterested)).getValue(t) + ); + mSocials.add(social); + } + feedAdapter.notifyDataSetChanged(); + } + + @Override + public void onCancelled(DatabaseError databaseError) {} + }); + + feedAdapter = new FeedAdapter(this, mSocials); + recyclerView.setAdapter(feedAdapter); // Set adapter with arraylist of values + feedAdapter.notifyDataSetChanged(); + + } + + @Override + public void onResume(){ + super.onResume(); + feedAdapter.notifyDataSetChanged(); + } + + @Override + public void onStart(){ + super.onStart(); + feedAdapter.notifyDataSetChanged(); + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/example/eric/socials/FeedAdapter.java b/app/src/main/java/com/example/eric/socials/FeedAdapter.java new file mode 100644 index 0000000..29e63ff --- /dev/null +++ b/app/src/main/java/com/example/eric/socials/FeedAdapter.java @@ -0,0 +1,122 @@ +package com.example.eric.socials; + +import android.content.Context; +import android.content.Intent; +import android.graphics.Bitmap; +import android.net.Uri; +import android.os.AsyncTask; +import android.support.annotation.NonNull; +import android.support.v7.widget.RecyclerView; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.ProgressBar; +import android.widget.TextView; + +import com.bumptech.glide.Glide; +import com.google.android.gms.tasks.OnFailureListener; +import com.google.android.gms.tasks.OnSuccessListener; +import com.google.firebase.storage.FirebaseStorage; + +import java.util.ArrayList; + +/** + * Created by eric on 2/19/17. + */ + +public class FeedAdapter extends RecyclerView.Adapter{ + + + private Context context; + public ArrayList data; + + public FeedAdapter(Context context, ArrayList data) { + this.context = context; + this.data = data; + } + + @Override + public CustomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_view, parent, false); + return new CustomViewHolder(view); + } + @Override + public void onBindViewHolder(final CustomViewHolder holder, int position) { + final Social s = data.get(data.size()-position-1); + holder.eventName.setText("Title: " + s.eventName); + holder.email.setText("Creator: " + s.emailOfCreator); + holder.numRSVP.setText("People Interested: " + Integer.toString(s.numRSVP)); + + class DownloadFilesTaskSocial extends AsyncTask { // Download and insert images into the feed views + protected Bitmap doInBackground(String... strings) { + try { + return Glide.with(context). + load(strings[0]). + asBitmap(). + into(100, 100). // Width and height + get(); + } + catch (Exception e) { + return null; + } + } + + protected void onProgressUpdate(Void... progress) {} + + protected void onPostExecute(Bitmap result) { + holder.eventImage.setImageBitmap(result); + } + } + FirebaseStorage.getInstance().getReferenceFromUrl("gs://mdb-socials-47b33.appspot.com").child(s.eventImage).getDownloadUrl().addOnSuccessListener(new OnSuccessListener() { + @Override + public void onSuccess(Uri uri) { + new DownloadFilesTaskSocial().execute(uri.toString()); + + } + }).addOnFailureListener(new OnFailureListener() { + @Override + public void onFailure(@NonNull Exception exception) { + + } + }); + + holder.eventImage.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + Intent intent = new Intent(context, DetailActivity.class); + String socialId = s.eventImage.substring(0, s.eventImage.length() - 4); + intent.putExtra("socialID", socialId); + intent.putExtra("name",s.eventName); + intent.putExtra("image", s.eventImage); + intent.putExtra("desc", s.description); // Since this is an adapter class, we can't use strings file + intent.putExtra("numRSVP", Integer.toString(s.numRSVP)); + intent.putExtra("email", s.emailOfCreator); + intent.putExtra("usersInterested", s.usersInterested); + context.startActivity(intent); + } + }); + } + + @Override + public int getItemCount() { + return data.size(); + } + + class CustomViewHolder extends RecyclerView.ViewHolder { // Custom View Holder Class for the feed of socials + TextView eventName; + TextView email; + TextView numRSVP; + ImageView eventImage; + + public CustomViewHolder (View view) { + super(view); + this.eventName = (TextView) view.findViewById(R.id.eventName); + this.email = (TextView) view.findViewById(R.id.email); + this.numRSVP = (TextView) view.findViewById(R.id.numRSVPButton); + this.eventImage = (ImageView) view.findViewById(R.id.eventImage); + } + } + +} diff --git a/app/src/main/java/com/example/eric/socials/Interested.java b/app/src/main/java/com/example/eric/socials/Interested.java new file mode 100644 index 0000000..2f687af --- /dev/null +++ b/app/src/main/java/com/example/eric/socials/Interested.java @@ -0,0 +1,98 @@ +package com.example.eric.socials; + +import android.content.Intent; +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; + +import com.google.firebase.database.DataSnapshot; +import com.google.firebase.database.DatabaseError; +import com.google.firebase.database.DatabaseReference; +import com.google.firebase.database.FirebaseDatabase; +import com.google.firebase.database.GenericTypeIndicator; +import com.google.firebase.database.ValueEventListener; + +import java.util.ArrayList; + +public class Interested extends AppCompatActivity { + + RecyclerView recyclerView; + InterestedAdapter interestedAdapter; + + ArrayListusers = new ArrayList<>(); + ArrayListinterestedUsers = new ArrayList<>(); + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_interested); + + recyclerView = (RecyclerView)findViewById(R.id.recyclerView2); + recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext())); + + final FirebaseDatabase database = FirebaseDatabase.getInstance(); + DatabaseReference ref = database.getReference("/socials"); + DatabaseReference ref2 = database.getReference("/user"); + + Intent grabData = getIntent(); + final String socialImageId = grabData.getStringExtra(getString(R.string.email)); + + ref.addValueEventListener(new ValueEventListener() { // Get all the users who are in the arraylist of the specified social event + @Override + public void onDataChange(DataSnapshot dataSnapshot) { + for(DataSnapshot socialSnapShot: dataSnapshot.getChildren()) { + if (socialSnapShot.child(getString(R.string.emailOfCreator)).getValue(String.class).equalsIgnoreCase(socialImageId)) { + GenericTypeIndicator> t = new GenericTypeIndicator>() {}; + ArrayList listOfUsersInSocial = socialSnapShot.child(getString(R.string.usersInterested)).getValue(t); + for (String userId : listOfUsersInSocial) { + users.add(userId); + } + } + } + } + + @Override + public void onCancelled(DatabaseError databaseError) { + + } + }); + ref2.addValueEventListener(new ValueEventListener() { // Create the users who are in the arraylist for the social and send their data to the adapter to be displayed + @Override + public void onDataChange(DataSnapshot dataSnapshot) { + for(DataSnapshot userSnapShot: dataSnapshot.getChildren()){ + if(users.contains(userSnapShot.getKey())){ + User u = new User( + userSnapShot.child(getString(R.string.name)).getValue(String.class), + userSnapShot.child(getString(R.string.email)).getValue(String.class), + userSnapShot.child(getString(R.string.profilePicture)).getValue(String.class) + ); + interestedUsers.add(u); + } + } + interestedAdapter.notifyDataSetChanged(); + } + + @Override + public void onCancelled(DatabaseError databaseError) { + + } + }); + + interestedAdapter = new InterestedAdapter(getApplicationContext(), interestedUsers); + recyclerView.setAdapter(interestedAdapter); + interestedAdapter.notifyDataSetChanged(); + } + + @Override + public void onResume(){ + super.onResume(); + interestedAdapter.notifyDataSetChanged(); + } + + @Override + public void onStart(){ + super.onStart(); + interestedAdapter.notifyDataSetChanged(); + } +} diff --git a/app/src/main/java/com/example/eric/socials/InterestedAdapter.java b/app/src/main/java/com/example/eric/socials/InterestedAdapter.java new file mode 100644 index 0000000..03aa813 --- /dev/null +++ b/app/src/main/java/com/example/eric/socials/InterestedAdapter.java @@ -0,0 +1,52 @@ +package com.example.eric.socials; + +import android.content.Context; +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + + +import java.util.ArrayList; + +/** + * Created by eric on 2/24/17. + */ + +public class InterestedAdapter extends RecyclerView.Adapter { + + private Context context; + public ArrayList data; + + public InterestedAdapter(Context context, ArrayList data) { + this.context = context; + this.data = data; + } + + @Override + public InterestedAdapter.CustomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_view2, parent, false); + return new CustomViewHolder(view); + } + + @Override + public void onBindViewHolder(final InterestedAdapter.CustomViewHolder holder, int position) { + User u = data.get(position); + holder.userName.setText(u.name); + } + + @Override + public int getItemCount() { + return data.size(); + } + + class CustomViewHolder extends RecyclerView.ViewHolder { + TextView userName; + + public CustomViewHolder (View view) { + super(view); + this.userName = (TextView) view.findViewById(R.id.userName); + } + } +} diff --git a/app/src/main/java/com/example/eric/socials/LoginActivity.java b/app/src/main/java/com/example/eric/socials/LoginActivity.java new file mode 100644 index 0000000..6eee0a5 --- /dev/null +++ b/app/src/main/java/com/example/eric/socials/LoginActivity.java @@ -0,0 +1,116 @@ +package com.example.eric.socials; + +import android.app.ProgressDialog; +import android.content.Intent; +import android.support.annotation.NonNull; +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; +import android.util.Log; +import android.view.View; +import android.widget.Button; +import android.widget.EditText; +import android.widget.Toast; + +import com.google.android.gms.tasks.OnCompleteListener; +import com.google.android.gms.tasks.Task; +import com.google.firebase.auth.AuthResult; +import com.google.firebase.auth.FirebaseAuth; +import com.google.firebase.auth.FirebaseUser; + +public class LoginActivity extends AppCompatActivity implements View.OnClickListener { + + private static FirebaseAuth mAuth; + private FirebaseAuth.AuthStateListener mAuthListener; + + private Button loginButton; + private Button signUpButton; + + private EditText emailView; + private EditText passwordView; + + @Override + public void onClick(View v){ // Handles Button clicks for login and signup + switch (v.getId()) { + case R.id.loginButton: + Utils.progressBar(this, getString(R.string.login_progressbar)); + attemptLogin(); + break; + + case R.id.signUpButton: + Intent intent = new Intent(getApplicationContext(), SignUpActivity.class); + startActivity(intent); + break; + + default: + } + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_login); + + mAuth = FirebaseAuth.getInstance(); + + mAuthListener = new FirebaseAuth.AuthStateListener() { // Auth Listener to check if user is already signed in + @Override + public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) { + FirebaseUser user = firebaseAuth.getCurrentUser(); + if(user != null){ + Intent intent = new Intent(getApplicationContext(), FeedActivity.class); + startActivity(intent); + Log.d("Login Status", "onAuthChanged: signed_in" + user.getUid()); + } else { + Log.d("Login Status", "onAuthChanged: signed_out"); + } + } + }; + + loginButton = (Button) findViewById(R.id.loginButton); + loginButton.setOnClickListener(this); + + signUpButton = (Button) findViewById(R.id.signUpButton); + signUpButton.setOnClickListener(this); + + } + + private void attemptLogin(){ // Helper function for logging in a user + emailView = (EditText) findViewById(R.id.emailView); + final String email = emailView.getText().toString(); + + passwordView = (EditText) findViewById(R.id.passwordView); + String password = passwordView.getText().toString(); + + if (!email.equals("") && !password.equals("")) { + mAuth.signInWithEmailAndPassword(email, password).addOnCompleteListener(this, new OnCompleteListener() { + @Override + public void onComplete(@NonNull Task task) { + Log.d("Sign In", "signInWithEmail:onComplete:" + task.isSuccessful()); + if (!task.isSuccessful()) { + Log.w("Sign In", "signInWithEmail", task.getException()); + Toast.makeText(getApplicationContext(), getString(R.string.login_failed), Toast.LENGTH_SHORT).show(); + } else { + Toast.makeText(getApplicationContext(), getString(R.string.login_successful), Toast.LENGTH_SHORT).show(); + Intent intent = new Intent(getApplicationContext(), FeedActivity.class); + startActivity(intent); + } + } + }); + } + } + + + @Override + public void onStart() { + super.onStart(); + mAuth.addAuthStateListener(mAuthListener); + } + + @Override + public void onStop() { + super.onStop(); + if (mAuthListener != null) { + mAuth.removeAuthStateListener(mAuthListener); + } + } +} diff --git a/app/src/main/java/com/example/eric/socials/SignUpActivity.java b/app/src/main/java/com/example/eric/socials/SignUpActivity.java new file mode 100644 index 0000000..ee52119 --- /dev/null +++ b/app/src/main/java/com/example/eric/socials/SignUpActivity.java @@ -0,0 +1,101 @@ +package com.example.eric.socials; + +import android.content.Intent; +import android.support.annotation.NonNull; +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; +import android.util.Log; +import android.view.View; +import android.widget.Button; +import android.widget.EditText; +import android.widget.Toast; + +import com.google.android.gms.tasks.OnCompleteListener; +import com.google.android.gms.tasks.Task; +import com.google.firebase.auth.AuthResult; +import com.google.firebase.auth.FirebaseAuth; +import com.google.firebase.auth.FirebaseUser; + +public class SignUpActivity extends AppCompatActivity implements View.OnClickListener { + + private static FirebaseAuth mAuth; + private FirebaseAuth.AuthStateListener mAuthListener; + private Button signUpButton2; + private EditText emailView2; + private EditText passwordView2; + + @Override + public void onClick(View v){ // Handles Button clicks for signing up + switch (v.getId()) { + case R.id.signUpButton2: + attemptSignUp(); + Utils.progressBar(this, getString(R.string.signup_progressbar)); + break; + default: + } + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_sign_up); + + mAuth = FirebaseAuth.getInstance(); + mAuthListener = new FirebaseAuth.AuthStateListener() { + @Override + public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) { + FirebaseUser user = firebaseAuth.getCurrentUser(); + if(user != null){ + Log.d("Login Status", "onAuthChanged: signed_in" + user.getUid()); + } else { + Log.d("Login Status", "onAuthChanged: signed_out"); + } + } + }; + + signUpButton2 = (Button) findViewById(R.id.signUpButton2); + signUpButton2.setOnClickListener(this); + } + + private void attemptSignUp(){ // Helper Function for signing a user up + emailView2 = (EditText) findViewById(R.id.emailView2); + final String email = emailView2.getText().toString(); + + passwordView2 = (EditText) findViewById(R.id.passwordView2); + String password = passwordView2.getText().toString(); + + if (!email.equals("") && !password.equals("")) { + mAuth.createUserWithEmailAndPassword(email, password) + .addOnCompleteListener(this, new OnCompleteListener() { + @Override + public void onComplete(@NonNull Task task) { + Log.d("Sign Up", "createUserWithEmail:onComplete:" + task.isSuccessful()); + + if (!task.isSuccessful()) { + Toast.makeText(getApplicationContext(), getString(R.string.login_failed), Toast.LENGTH_SHORT).show(); + } else { + Toast.makeText(getApplicationContext(), getString(R.string.signup_successful), Toast.LENGTH_SHORT).show(); + Intent intent = new Intent(SignUpActivity.this, UpdateProfile.class); + intent.putExtra(getString(R.string.email), email); + startActivity(intent); + } + + } + }); + } + } + + @Override + public void onStart() { + super.onStart(); + mAuth.addAuthStateListener(mAuthListener); + } + + @Override + public void onStop() { + super.onStop(); + if (mAuthListener != null) { + mAuth.removeAuthStateListener(mAuthListener); + } + } +} diff --git a/app/src/main/java/com/example/eric/socials/Social.java b/app/src/main/java/com/example/eric/socials/Social.java new file mode 100644 index 0000000..87e1574 --- /dev/null +++ b/app/src/main/java/com/example/eric/socials/Social.java @@ -0,0 +1,27 @@ +package com.example.eric.socials; + +import java.util.ArrayList; + +/** + * Created by eric on 2/19/17. + */ + +public class Social { + String eventName; + String eventImage; + String emailOfCreator; + String description; + int numRSVP; + String date; + ArrayList usersInterested; + + public Social(String eventName, String eventImage, String emailOfCreator, String description, int numRSVP, String date, ArrayListusersInterested){ + this.eventName = eventName; + this.eventImage = eventImage; + this.emailOfCreator = emailOfCreator; + this.description = description; + this.numRSVP = numRSVP; + this.date = date; + this.usersInterested = usersInterested; + } +} diff --git a/app/src/main/java/com/example/eric/socials/UpdateProfile.java b/app/src/main/java/com/example/eric/socials/UpdateProfile.java new file mode 100644 index 0000000..ee3f95d --- /dev/null +++ b/app/src/main/java/com/example/eric/socials/UpdateProfile.java @@ -0,0 +1,132 @@ +package com.example.eric.socials; + +import android.app.Activity; +import android.content.DialogInterface; +import android.content.Intent; +import android.graphics.Bitmap; +import android.net.Uri; +import android.provider.MediaStore; +import android.support.annotation.NonNull; +import android.support.v7.app.AlertDialog; +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; +import android.view.View; +import android.widget.Button; +import android.widget.EditText; +import android.widget.ImageView; +import android.widget.Toast; + +import com.google.android.gms.tasks.OnFailureListener; +import com.google.android.gms.tasks.OnSuccessListener; +import com.google.firebase.database.DatabaseReference; +import com.google.firebase.database.FirebaseDatabase; +import com.google.firebase.auth.FirebaseAuth; +import com.google.firebase.auth.FirebaseUser; +import com.google.firebase.storage.FirebaseStorage; +import com.google.firebase.storage.StorageReference; +import com.google.firebase.storage.UploadTask; + +import java.io.FileNotFoundException; +import java.io.IOException; + +public class UpdateProfile extends AppCompatActivity implements View.OnClickListener{ + + EditText nameView; + ImageView profilePicture; + Button saveButton; + private Intent data; + + FirebaseDatabase database = FirebaseDatabase.getInstance(); + DatabaseReference myRef = database.getReference("/user"); + private StorageReference mStorageRef; + + private static FirebaseAuth mAuth; + private static FirebaseUser mUser; + + @Override + public void onClick(View v){ //Handles Button Clicks for profilePicture & the Save Button + switch (v.getId()) { + case R.id.profilePicture: + AlertDialog alertDialog = new AlertDialog.Builder(UpdateProfile.this).create(); + alertDialog.setTitle("Set a Photo"); + + alertDialog.setButton(AlertDialog.BUTTON_NEGATIVE, "Upload from Gallery", + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + //launch gallery + startActivityForResult(new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.INTERNAL_CONTENT_URI), 3); + dialog.dismiss(); + } + }); + + alertDialog.show(); + break; + + case R.id.saveButton: + mStorageRef = FirebaseStorage.getInstance().getReferenceFromUrl(getString(R.string.firebase_link)); + final String key = myRef.child("user").push().getKey(); + StorageReference imageRef = mStorageRef.child(key + ".png"); + + imageRef.putFile(data.getData()).addOnFailureListener(new OnFailureListener() { + @Override + public void onFailure(@NonNull Exception exception) { + Toast.makeText(getApplicationContext(), "need an image!", Toast.LENGTH_SHORT).show(); + } + }).addOnSuccessListener(new OnSuccessListener() { + @Override + public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) { + User u = new User(nameView.getText().toString(), key + ".png", mUser.getEmail()); + myRef.child(mUser.getUid()).setValue(u); + Toast.makeText(getApplicationContext(), getString(R.string.update_successful), Toast.LENGTH_SHORT).show(); + Intent intent = new Intent(getApplicationContext(), FeedActivity.class); + startActivity(intent); + } + }); + + Utils.progressBar(this, getString(R.string.updateprofile_progressbar)); + break; + + default: + } + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_update_profile); + + nameView = (EditText) findViewById(R.id.nameView); + profilePicture = (ImageView) findViewById(R.id.profilePicture); + saveButton = (Button) findViewById(R.id.saveButton); + + profilePicture.setOnClickListener(this); //Open upload image on picture click + + mAuth = FirebaseAuth.getInstance(); + mUser = mAuth.getCurrentUser(); + //Instantiate Auth & User + + saveButton.setOnClickListener(this); // Save Information to a new User Object + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + + //Detects request codes for camera/uploading a picture + if((requestCode == 3 || requestCode == 1) && resultCode == Activity.RESULT_OK) { + Uri selectedImage = data.getData(); + Bitmap bitmap = null; + try { + bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), selectedImage); + ((ImageView) findViewById(R.id.profilePicture)).setImageBitmap(bitmap); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } + this.data = data; // Pass Intent data to global variable data + } +} + + diff --git a/app/src/main/java/com/example/eric/socials/User.java b/app/src/main/java/com/example/eric/socials/User.java new file mode 100644 index 0000000..67a563f --- /dev/null +++ b/app/src/main/java/com/example/eric/socials/User.java @@ -0,0 +1,19 @@ +package com.example.eric.socials; + +import java.util.ArrayList; + +/** + * Created by eric on 2/23/17. + */ + +public class User { + String name; + String email; + String profilePicture; + + public User(String name, String profilePicture, String email){ + this.name = name; + this.profilePicture = profilePicture; + this.email = email; + } +} diff --git a/app/src/main/java/com/example/eric/socials/Utils.java b/app/src/main/java/com/example/eric/socials/Utils.java new file mode 100644 index 0000000..e2827cc --- /dev/null +++ b/app/src/main/java/com/example/eric/socials/Utils.java @@ -0,0 +1,39 @@ +package com.example.eric.socials; + +import android.app.ProgressDialog; +import android.content.Context; + +/** + * Created by eric on 3/1/17. + */ + +public class Utils { + + public static void progressBar(Context context, String message){ + final ProgressDialog progress = new ProgressDialog(context); + progress.setMessage(message); + progress.setProgressStyle(ProgressDialog.STYLE_SPINNER); + progress.setIndeterminate(true); + progress.setProgress(0); + progress.show(); + + final int totalProgressTime = 100; + final Thread t = new Thread() { + @Override + public void run() { + int jumpTime = 0; + + while(jumpTime < totalProgressTime) { + try { + sleep(1000); + jumpTime += 5; + progress.setProgress(jumpTime); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + }; + t.start(); + } +} diff --git a/app/src/main/res/layout/activity_add_event.xml b/app/src/main/res/layout/activity_add_event.xml new file mode 100644 index 0000000..e99f3c5 --- /dev/null +++ b/app/src/main/res/layout/activity_add_event.xml @@ -0,0 +1,90 @@ + + + + + + + + + + + + + +