From e8d869e4a9a325928d9eecbfca56437c6cd7a54d Mon Sep 17 00:00:00 2001 From: Aneesh Jindal Date: Sat, 25 Feb 2017 15:09:35 -0800 Subject: [PATCH 1/3] Created README --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..3b182f0 --- /dev/null +++ b/README.md @@ -0,0 +1,7 @@ +# sp17proj3android + +Repository for Spring 2017 MDB Android Training Program Mini-Project 3 Submissions + +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. + +When pushing code to this repo, DO NOT push to master. Create a new branch and open a pull request. From b727ad40a615e93e372cb15c88d3e466ebfaca3e Mon Sep 17 00:00:00 2001 From: Shivendra Kushwah Date: Sat, 25 Feb 2017 17:02:30 -0800 Subject: [PATCH 2/3] submitting mdbsocials rip --- .gitignore | 9 + .idea/compiler.xml | 22 ++ .idea/copyright/profiles_settings.xml | 3 + .idea/encodings.xml | 6 + .idea/gradle.xml | 19 ++ .idea/misc.xml | 46 +++ .idea/modules.xml | 9 + .idea/runConfigurations.xml | 12 + app/.gitignore | 1 + app/build.gradle | 42 +++ app/google-services.json | 55 ++++ app/proguard-rules.pro | 17 ++ .../mdbsocials/ExampleInstrumentedTest.java | 26 ++ app/src/main/AndroidManifest.xml | 31 ++ .../shiv/mdbsocials/DetailActivity.java | 284 ++++++++++++++++++ .../com/example/shiv/mdbsocials/Event.java | 29 ++ .../example/shiv/mdbsocials/EventAdapter.java | 156 ++++++++++ .../example/shiv/mdbsocials/FeedActivity.java | 184 ++++++++++++ .../example/shiv/mdbsocials/MainActivity.java | 146 +++++++++ .../shiv/mdbsocials/NewSocialActivity.java | 244 +++++++++++++++ .../shiv/mdbsocials/RegisterActivity.java | 99 ++++++ .../com/example/shiv/mdbsocials/User.java | 14 + .../example/shiv/mdbsocials/UserAdapter.java | 88 ++++++ .../mdbsocials/UsersInterestedActivity.java | 94 ++++++ app/src/main/res/drawable/logo.png | Bin 0 -> 17715 bytes app/src/main/res/drawable/mdb.jpg | Bin 0 -> 30685 bytes app/src/main/res/layout/activity_detail.xml | 131 ++++++++ app/src/main/res/layout/activity_feed.xml | 42 +++ app/src/main/res/layout/activity_main.xml | 102 +++++++ .../main/res/layout/activity_new_social.xml | 101 +++++++ app/src/main/res/layout/activity_register.xml | 89 ++++++ .../res/layout/activity_users_interested.xml | 18 ++ app/src/main/res/layout/row_view_feed.xml | 92 ++++++ .../res/layout/row_view_usersinterested.xml | 33 ++ app/src/main/res/mipmap-hdpi/ic_launcher.png | Bin 0 -> 3418 bytes app/src/main/res/mipmap-mdpi/ic_launcher.png | Bin 0 -> 2206 bytes app/src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 0 -> 4842 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 0 -> 7718 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 0 -> 10486 bytes app/src/main/res/values-w820dp/dimens.xml | 6 + app/src/main/res/values/colors.xml | 6 + app/src/main/res/values/dimens.xml | 5 + app/src/main/res/values/strings.xml | 3 + app/src/main/res/values/styles.xml | 11 + .../shiv/mdbsocials/ExampleUnitTest.java | 17 ++ build.gradle | 24 ++ gradle.properties | 17 ++ gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 53636 bytes gradle/wrapper/gradle-wrapper.properties | 6 + gradlew | 160 ++++++++++ gradlew.bat | 90 ++++++ settings.gradle | 1 + 52 files changed, 2590 insertions(+) create mode 100644 .gitignore create mode 100644 .idea/compiler.xml create mode 100644 .idea/copyright/profiles_settings.xml create mode 100644 .idea/encodings.xml create mode 100644 .idea/gradle.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/runConfigurations.xml create mode 100644 app/.gitignore create mode 100644 app/build.gradle create mode 100644 app/google-services.json create mode 100644 app/proguard-rules.pro create mode 100644 app/src/androidTest/java/com/example/shiv/mdbsocials/ExampleInstrumentedTest.java create mode 100644 app/src/main/AndroidManifest.xml create mode 100644 app/src/main/java/com/example/shiv/mdbsocials/DetailActivity.java create mode 100644 app/src/main/java/com/example/shiv/mdbsocials/Event.java create mode 100644 app/src/main/java/com/example/shiv/mdbsocials/EventAdapter.java create mode 100644 app/src/main/java/com/example/shiv/mdbsocials/FeedActivity.java create mode 100644 app/src/main/java/com/example/shiv/mdbsocials/MainActivity.java create mode 100644 app/src/main/java/com/example/shiv/mdbsocials/NewSocialActivity.java create mode 100644 app/src/main/java/com/example/shiv/mdbsocials/RegisterActivity.java create mode 100644 app/src/main/java/com/example/shiv/mdbsocials/User.java create mode 100644 app/src/main/java/com/example/shiv/mdbsocials/UserAdapter.java create mode 100644 app/src/main/java/com/example/shiv/mdbsocials/UsersInterestedActivity.java create mode 100644 app/src/main/res/drawable/logo.png create mode 100644 app/src/main/res/drawable/mdb.jpg create mode 100644 app/src/main/res/layout/activity_detail.xml create mode 100644 app/src/main/res/layout/activity_feed.xml create mode 100644 app/src/main/res/layout/activity_main.xml create mode 100644 app/src/main/res/layout/activity_new_social.xml create mode 100644 app/src/main/res/layout/activity_register.xml create mode 100644 app/src/main/res/layout/activity_users_interested.xml create mode 100644 app/src/main/res/layout/row_view_feed.xml create mode 100644 app/src/main/res/layout/row_view_usersinterested.xml create mode 100644 app/src/main/res/mipmap-hdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-mdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-xhdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-xxxhdpi/ic_launcher.png create mode 100644 app/src/main/res/values-w820dp/dimens.xml create mode 100644 app/src/main/res/values/colors.xml create mode 100644 app/src/main/res/values/dimens.xml create mode 100644 app/src/main/res/values/strings.xml create mode 100644 app/src/main/res/values/styles.xml create mode 100644 app/src/test/java/com/example/shiv/mdbsocials/ExampleUnitTest.java create mode 100644 build.gradle create mode 100644 gradle.properties create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100755 gradlew create mode 100644 gradlew.bat create mode 100644 settings.gradle 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/encodings.xml b/.idea/encodings.xml new file mode 100644 index 0000000..97626ba --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,6 @@ + + + + + + \ 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..f5e9010 --- /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/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..e70d098 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,42 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 25 + buildToolsVersion "25.0.2" + defaultConfig { + applicationId "com.example.shiv.mdbsocials" + 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.google.firebase:firebase-auth:10.0.1' + compile 'com.android.support.constraint:constraint-layout:1.0.0-beta4' + compile 'com.google.firebase:firebase-database:10.0.1' + compile 'com.google.firebase:firebase-core:10.0.1' + compile 'com.google.firebase:firebase-storage:10.0.1' + testCompile 'junit:junit:4.12' + compile 'com.android.support:recyclerview-v7:25.1.1' + compile 'com.android.support:cardview-v7:25.1.1' + compile 'com.github.bumptech.glide:glide:3.7.0' +} + + + + +apply plugin: 'com.google.gms.google-services' \ No newline at end of file diff --git a/app/google-services.json b/app/google-services.json new file mode 100644 index 0000000..3f904e2 --- /dev/null +++ b/app/google-services.json @@ -0,0 +1,55 @@ +{ + "project_info": { + "project_number": "354113820268", + "firebase_url": "https://mdbsocials-56ed5.firebaseio.com", + "project_id": "mdbsocials-56ed5", + "storage_bucket": "mdbsocials-56ed5.appspot.com" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:354113820268:android:6466447b4db7db8b", + "android_client_info": { + "package_name": "com.example.shiv.mdbsocials" + } + }, + "oauth_client": [ + { + "client_id": "354113820268-ndhfu3eu6jr9e0edo6ppttj8g2ae8atg.apps.googleusercontent.com", + "client_type": 1, + "android_info": { + "package_name": "com.example.shiv.mdbsocials", + "certificate_hash": "A4C1F515078A1CF9A4EF9D1963EC038EEB1BD309" + } + }, + { + "client_id": "354113820268-9q4pheohaqoma2habsv7tcfu4m4jkm7v.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyBvHuNi9DVa_Ud9O0Ae7yV0hpy2UmOweN8" + } + ], + "services": { + "analytics_service": { + "status": 1 + }, + "appinvite_service": { + "status": 2, + "other_platform_oauth_client": [ + { + "client_id": "354113820268-9q4pheohaqoma2habsv7tcfu4m4jkm7v.apps.googleusercontent.com", + "client_type": 3 + } + ] + }, + "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..4205a12 --- /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 /Users/Shiv/Library/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/shiv/mdbsocials/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/example/shiv/mdbsocials/ExampleInstrumentedTest.java new file mode 100644 index 0000000..a4a87f5 --- /dev/null +++ b/app/src/androidTest/java/com/example/shiv/mdbsocials/ExampleInstrumentedTest.java @@ -0,0 +1,26 @@ +package com.example.shiv.mdbsocials; + +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.shiv.mdbsocials", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..def57ef --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/example/shiv/mdbsocials/DetailActivity.java b/app/src/main/java/com/example/shiv/mdbsocials/DetailActivity.java new file mode 100644 index 0000000..e8b6515 --- /dev/null +++ b/app/src/main/java/com/example/shiv/mdbsocials/DetailActivity.java @@ -0,0 +1,284 @@ +package com.example.shiv.mdbsocials; + +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.app.AppCompatActivity; +import android.os.Bundle; +import android.util.Log; +import android.view.View; +import android.widget.Button; +import android.widget.ImageView; +import android.widget.TextView; +import android.widget.Toast; + +import com.bumptech.glide.Glide; +import com.google.android.gms.tasks.OnFailureListener; +import com.google.android.gms.tasks.OnSuccessListener; +import com.google.firebase.database.ChildEventListener; +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.MutableData; +import com.google.firebase.database.Transaction; +import com.google.firebase.storage.FirebaseStorage; +import com.google.firebase.storage.StorageReference; + +import java.util.ArrayList; + +public class DetailActivity extends AppCompatActivity { + + public Context context; + String firebaseKey; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_detail); + context = getApplicationContext(); + + TextView eventName = (TextView) findViewById(R.id.textView7); + final ImageView img = (ImageView) findViewById(R.id.imageView2); + TextView date = (TextView) findViewById(R.id.textView8); + TextView description = (TextView) findViewById(R.id.textView9); + TextView email = (TextView) findViewById(R.id.textView10); + Button interested = (Button) findViewById(R.id.button10); + Button numPeopleGoing = (Button) findViewById(R.id.button9); + //numPeopleGoing.setText(); + + Intent intent = getIntent(); + + String emailExtra = intent.getStringExtra("email"); + email.setText(emailExtra); + String eventNameExtra = intent.getStringExtra("name"); + eventName.setText(eventNameExtra); + String dateExtra = intent.getStringExtra("date"); + date.setText(dateExtra); + String descriptionExtra = intent.getStringExtra("description"); + description.setText(descriptionExtra); + firebaseKey = intent.getStringExtra("key"); + final int numPeople = intent.getStringArrayListExtra("peopleInterested").size(); + + final ArrayList interestedPeople = new ArrayList<>(); + + DatabaseReference ref = FirebaseDatabase.getInstance().getReference("/events"); + ref.addChildEventListener(new ChildEventListener() { + @Override + public void onChildAdded(DataSnapshot dataSnapshot, String s) { + if (dataSnapshot.getKey().equals(firebaseKey)) { + ArrayList a = (ArrayList) dataSnapshot.child("peopleinterested").getValue(); + displayNumPeopleButton(a.size()); + } + } + + @Override + public void onChildChanged(DataSnapshot dataSnapshot, String s) { + + } + + @Override + public void onChildRemoved(DataSnapshot dataSnapshot) { + + } + + @Override + public void onChildMoved(DataSnapshot dataSnapshot, String s) { + + } + + @Override + public void onCancelled(DatabaseError databaseError) { + + } + }); + + + + + interested.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + addInterested(); + Toast.makeText(getApplicationContext(), "Marked as Interested", Toast.LENGTH_SHORT).show(); + } + }); + + numPeopleGoing.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + Intent intent = new Intent(getApplicationContext(), UsersInterestedActivity.class); + intent.putExtra("key",firebaseKey); + startActivity(intent); + } + }); + + + + class DownloadFilesTask extends AsyncTask { + 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) { + img.setImageBitmap(result); + } + } + String imageURLExtra = intent.getStringExtra("imageURL"); + FirebaseStorage.getInstance().getReferenceFromUrl("gs://mdbsocials-56ed5.appspot.com").child(imageURLExtra+ ".png").getDownloadUrl().addOnSuccessListener(new OnSuccessListener() { + @Override + public void onSuccess(Uri uri) { + new DownloadFilesTask().execute(uri.toString()); Log.d("ye", uri.toString()); + } + }).addOnFailureListener(new OnFailureListener() { + @Override + public void onFailure(@NonNull Exception exception) { + Log.d("sad", exception.toString()); + } + }); + + + + + + + } + + + private void addInterested() { + + //NOTE, also add self email to people interested arraylist + + final DatabaseReference ref = FirebaseDatabase.getInstance().getReference("/events"); + + ref.child(firebaseKey).runTransaction(new Transaction.Handler() { + @Override + public Transaction.Result doTransaction(MutableData mutableData) { + String numStringInterested = mutableData.child("interested").getValue().toString(); + int numInterested = Integer.parseInt(numStringInterested); + numInterested++; + + DetailActivity.addInterestedToDatabase(numInterested,firebaseKey); + + ArrayList a = (ArrayList) mutableData.child("peopleinterested").getValue(); + if (!a.contains(MainActivity.email)) { + a.add(MainActivity.email); + ref.child(firebaseKey).child("peopleinterested").setValue(a); + + } + + return Transaction.success(mutableData); + } + + @Override + public void onComplete(DatabaseError databaseError, boolean b, DataSnapshot dataSnapshot) { + + } + }); + + + + //maybe try to add data change listener to get numInterested + + //String numStringInterested = ref.child(firebaseKey).child("interested").toString(); + //final String numStringInterested; + + /* Legit stuff + + ref.addChildEventListener(new ChildEventListener() { + @Override + public void onChildAdded(DataSnapshot dataSnapshot, String s) { + if (dataSnapshot.getKey().equals(firebaseKey)) { + String numStringInterested = dataSnapshot.child("interested").getValue().toString(); + int numInterested = Integer.parseInt(numStringInterested); + numInterested++; + DetailActivity.addInterestedToDatabase(numInterested,firebaseKey); + + + ArrayList a = (ArrayList) dataSnapshot.child("peopleinterested").getValue(); + if (!a.contains(MainActivity.email)) { + a.add(MainActivity.email); + ref.child(firebaseKey).child("peopleinterested").setValue(a); + + } + + //ref.child(firebaseKey).child("interested").setValue(Integer.toString(numInterested)); + + + } + } + + @Override + public void onChildChanged(DataSnapshot dataSnapshot, String s) { + + } + + @Override + public void onChildRemoved(DataSnapshot dataSnapshot) { + + } + + @Override + public void onChildMoved(DataSnapshot dataSnapshot, String s) { + + } + + @Override + public void onCancelled(DatabaseError databaseError) { + + } + }); + + */ + + + + + + // Log.d("NOTICE", numStringInterested); + //int numInterested = Integer.parseInt(numStringInterested); + //numInterested++; + + + //numStringInterested = "7";//Integer.toString(numInterested); + //ref.child(firebaseKey).child("interested").setValue(numStringInterested); + + + + + + + + + + + } + + public static void addInterestedToDatabase(int interested, String firekey) { + DatabaseReference ref = FirebaseDatabase.getInstance().getReference("/events"); + ref.child(firekey).child("interested").setValue(Integer.toString(interested)); + + } + public void displayNumPeopleButton(int num) { + Button numPeopleGoing = (Button) findViewById(R.id.button9); + if (num > 0) { + numPeopleGoing.setText(num + " People Going"); + } + else { + numPeopleGoing.setText("0 People Going"); + } + + + } +} diff --git a/app/src/main/java/com/example/shiv/mdbsocials/Event.java b/app/src/main/java/com/example/shiv/mdbsocials/Event.java new file mode 100644 index 0000000..8e1357c --- /dev/null +++ b/app/src/main/java/com/example/shiv/mdbsocials/Event.java @@ -0,0 +1,29 @@ +package com.example.shiv.mdbsocials; + +import android.net.Uri; + +import java.util.ArrayList; + +/** + * Created by Shiv on 2/20/17. + */ + +public class Event { + + String date; + String description; + String email; + String eventName; + String emailAddress; + String imageURL; + String key; + int ImageID; + String numInterested; + ArrayList peopleInterested; + + public Event() { + //numInterested = "0"; + peopleInterested = new ArrayList<>(); + + } +} diff --git a/app/src/main/java/com/example/shiv/mdbsocials/EventAdapter.java b/app/src/main/java/com/example/shiv/mdbsocials/EventAdapter.java new file mode 100644 index 0000000..05b614c --- /dev/null +++ b/app/src/main/java/com/example/shiv/mdbsocials/EventAdapter.java @@ -0,0 +1,156 @@ +package com.example.shiv.mdbsocials; + +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.CardView; +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.RatingBar; +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 org.w3c.dom.Text; + +import java.util.ArrayList; + +/** + * Created by Shiv on 2/20/17. + */ + +public class EventAdapter extends RecyclerView.Adapter { + Context context; + public static ArrayList events; + + public EventAdapter(Context context, ArrayList events) { + this.context = context; + this.events = events; + } + + + @Override + public EventAdapter.CustomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + + View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_view_feed, parent, false); + return new CustomViewHolder(view); + } + + @Override + public void onBindViewHolder(final EventAdapter.CustomViewHolder holder, int position) { + Event currentEvent = events.get(events.size() - position - 1); + + //In the onBindViewHolder, you want to set each of the parameters of ComputerCompanies very similiar + //to what you did to the layout manager. + + //holder.pic.setImageResource(currentEvent.ImageID); + holder.eventName.setText(currentEvent.eventName); + holder.email.setText(currentEvent.email); + holder.numInterested.setText(currentEvent.numInterested); + holder.date = currentEvent.date; + holder.description = currentEvent.description; + holder.imageURL = currentEvent.imageURL; + holder.key = currentEvent.key; + holder.pplInterested = currentEvent.peopleInterested; + + + + class DownloadFilesTask extends AsyncTask { + 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.pic.setImageBitmap(result); + } + } + FirebaseStorage.getInstance().getReferenceFromUrl("gs://mdbsocials-56ed5.appspot.com").child(currentEvent.imageURL+ ".png").getDownloadUrl().addOnSuccessListener(new OnSuccessListener() { + @Override + public void onSuccess(Uri uri) { + new DownloadFilesTask().execute(uri.toString()); Log.d("ye", uri.toString()); + } + }).addOnFailureListener(new OnFailureListener() { + @Override + public void onFailure(@NonNull Exception exception) { + Log.d("sad", exception.toString()); + } + }); + + + + + } + + @Override + public int getItemCount() { + return events.size(); + } + + public void clearList() { events = new ArrayList();} + + public class CustomViewHolder extends RecyclerView.ViewHolder { + + //Set up the variables of Computer Companies here + + TextView eventName; + TextView email; + TextView numInterested; + ImageView pic; + String date; + String description; + String imageURL; + String key; + ArrayList pplInterested; + + public CustomViewHolder(View view) { + super(view); + + //Here, think about what you have to "find..." + eventName = (TextView) view.findViewById(R.id.textView13); + email = (TextView) view.findViewById(R.id.textView12); + numInterested = (TextView) view.findViewById(R.id.textView14); + pic = (ImageView) view.findViewById(R.id.imageView5); + + CardView cardView = (CardView) view.findViewById(R.id.cardView); + cardView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + Intent intent = new Intent(context, DetailActivity.class); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + //put extras such as this specific card values maybe + intent.putExtra("email",email.getText().toString()); + intent.putExtra("name",eventName.getText().toString()); + intent.putExtra("number",numInterested.getText().toString()); + intent.putExtra("description", description); + intent.putExtra("date", date); + intent.putExtra("imageURL",imageURL); + intent.putExtra("key",key); + intent.putExtra("peopleInterested",pplInterested); + + context.startActivity(intent); + } + }); + + + } + } + +} diff --git a/app/src/main/java/com/example/shiv/mdbsocials/FeedActivity.java b/app/src/main/java/com/example/shiv/mdbsocials/FeedActivity.java new file mode 100644 index 0000000..0e619a4 --- /dev/null +++ b/app/src/main/java/com/example/shiv/mdbsocials/FeedActivity.java @@ -0,0 +1,184 @@ +package com.example.shiv.mdbsocials; + +import android.content.Context; +import android.content.Intent; +import android.support.annotation.MainThread; +import android.support.annotation.NonNull; +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.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; +import com.google.firebase.database.ChildEventListener; +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.ValueEventListener; + +import java.util.ArrayList; + +public class FeedActivity extends AppCompatActivity { + + RecyclerView rview; + EventAdapter eventAdapter; + + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_feed); + Button logout = (Button) findViewById(R.id.button5); + Button newsocial = (Button) findViewById(R.id.button6); + + + rview = (RecyclerView) findViewById(R.id.recyclableView); + rview.setLayoutManager(new LinearLayoutManager(getApplicationContext())); + /* + ArrayList events = new ArrayList<>(); + Event party = new Event(); + party.eventName = "partay"; + party.email = "ksidhu@gmail.com"; + party.numInterested = 7; + Event party2 = new Event(); + party2.eventName = "partayyyyy"; + party2.email = "ksidhu@gmailllll.com"; + party2.numInterested = 17; + events.add(party); + events.add(party2); + */ + + eventAdapter = new EventAdapter(getApplicationContext(), getList());//events); + //eventAdapter.clearList(); + //eventAdapter.events = getList(); + rview.setAdapter(eventAdapter); + + logout.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + FirebaseAuth.getInstance().signOut(); + Intent intent = new Intent(getApplicationContext(),MainActivity.class); + startActivity(intent); + } + }); + + newsocial.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + Intent intent = new Intent(getApplicationContext(),NewSocialActivity.class); + startActivity(intent); + } + }); + + + } + + private ArrayList getList() { + final ArrayList currEvents = new ArrayList<>(); + DatabaseReference ref = FirebaseDatabase.getInstance().getReference("/events"); + + + + ref.orderByChild("timestamp").addValueEventListener(new ValueEventListener() { + @Override + public void onDataChange(DataSnapshot dataSnapshot) { + + //eventAdapter.clearList(); + currEvents.clear(); + + for (DataSnapshot x : dataSnapshot.getChildren()) { + + Log.d(x.getKey(), x.getValue().toString()); + //would normally getKey here + Event e = new Event(); + e.date = x.child("date").getValue(String.class); + e.description = x.child("description").getValue(String.class); + e.eventName = x.child("name").getValue(String.class); + e.imageURL = x.child("url").getValue(String.class); + e.email = x.child("email").getValue(String.class); + + e.numInterested = x.child("interested").getValue(String.class); + e.key = x.getKey(); + //e.peopleInterested = dataSnapshot.child("peopleinterested").getValue(ArrayList.class); //breaking here + + currEvents.add(e); + //EventAdapter.events.add(e); + eventAdapter.notifyDataSetChanged(); + //rview.setAdapter(eventAdapter); + } + + } + + @Override + public void onCancelled(DatabaseError databaseError) { + + } + }); + return currEvents; + /* + ref.addChildEventListener(new ChildEventListener() { + @Override + public void onChildAdded(DataSnapshot dataSnapshot, String s) { + Log.d(dataSnapshot.getKey(), dataSnapshot.getValue().toString()); + //would normally getKey here + Event e = new Event(); + e.date = dataSnapshot.child("date").getValue(String.class); + e.description = dataSnapshot.child("description").getValue(String.class); + e.eventName = dataSnapshot.child("name").getValue(String.class); + e.imageURL = dataSnapshot.child("url").getValue(String.class); + e.email = dataSnapshot.child("email").getValue(String.class);; + e.numInterested = dataSnapshot.child("interested").getValue(String.class); + e.key = dataSnapshot.getKey(); + //e.peopleInterested = dataSnapshot.child("peopleinterested").getValue(ArrayList.class); //breaking here + + currEvents.add(e); + //EventAdapter.events.add(e); + rview.setAdapter(eventAdapter); + + } + + @Override + public void onChildChanged(DataSnapshot dataSnapshot, String s) { + + } + + @Override + public void onChildRemoved(DataSnapshot dataSnapshot) { + + } + + @Override + public void onChildMoved(DataSnapshot dataSnapshot, String s) { + + } + + @Override + public void onCancelled(DatabaseError databaseError) { + + } + }); + return currEvents; + */ + } + + @Override + protected void onResume() { + super.onResume(); + } +} + + + + + + diff --git a/app/src/main/java/com/example/shiv/mdbsocials/MainActivity.java b/app/src/main/java/com/example/shiv/mdbsocials/MainActivity.java new file mode 100644 index 0000000..03782cd --- /dev/null +++ b/app/src/main/java/com/example/shiv/mdbsocials/MainActivity.java @@ -0,0 +1,146 @@ +package com.example.shiv.mdbsocials; + +import android.content.Intent; +import android.content.SharedPreferences; +import android.graphics.Paint; +import android.preference.PreferenceManager; +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.ImageView; +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 MainActivity extends AppCompatActivity { + + private FirebaseAuth mAuth; + private FirebaseAuth.AuthStateListener mAuthListener; + private boolean IsLogin; + public static String email; + //private EditText username = (EditText) findViewById(R.id.editText); + //private EditText Password = (EditText) findViewById(R.id.editText2); + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + + + + Button loginButton = (Button) findViewById(R.id.button2); + Button signUpButton = (Button) findViewById(R.id.button3); + signUpButton.setPaintFlags(signUpButton.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG); + + ImageView logo = (ImageView) findViewById(R.id.imageView); + logo.setImageResource(R.drawable.logo); + + + mAuth = FirebaseAuth.getInstance(); + +// if (mAuth.getCurrentUser() == null) { +// Log.d("LOOK","Kirat"); +// } + + + + mAuthListener = new FirebaseAuth.AuthStateListener() { + @Override + public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) { + FirebaseUser user = firebaseAuth.getCurrentUser(); + if (user != null) { + // User is signed in + + Log.d("Login Status", "onAuthStateChanged:signed_in:" + user.getUid()); + email = user.getEmail(); + Intent intent = new Intent(getApplicationContext(),FeedActivity.class); + startActivity(intent); + //Below is sign out code + /* + FirebaseAuth.getInstance().signOut(); + + */ + + } else { + // User is signed out + Log.d("Login Status", "onAuthStateChanged:signed_out"); + } + // ... + } + }; + + loginButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + attemptLogin(); + } + }); + + + signUpButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + attemptSignup(); + } + }); + + } + + + private void attemptLogin() { + String email = ((EditText) findViewById(R.id.editText)).getText().toString(); + String password = ((EditText) findViewById(R.id.editText2)).getText().toString(); + if (!email.equals("") && !password.equals("")) { + //Question 4: add sign in capability. If it is successful, go to the listactivity, else display a Toast + mAuth.signInWithEmailAndPassword(email, password) + .addOnCompleteListener(this, new OnCompleteListener() { + @Override + public void onComplete(@NonNull Task task) { + Log.d("SignIn Status", "signInWithEmail:onComplete:" + task.isSuccessful()); + + // If sign in fails, display a message to the user. If sign in succeeds + // the auth state listener will be notified and logic to handle the + // signed in user can be handled in the listener. + if (!task.isSuccessful()) { + Log.w("SignIn Status", "signInWithEmail", task.getException()); + Toast.makeText(getApplicationContext(), "Authentication failed.", + Toast.LENGTH_SHORT).show(); + } + else { + Intent intent = new Intent(getApplicationContext(), FeedActivity.class); + startActivity(intent); + } + + // ... + } + }); + } + } + + private void attemptSignup() { + Intent intent = new Intent(getApplicationContext(), RegisterActivity.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/shiv/mdbsocials/NewSocialActivity.java b/app/src/main/java/com/example/shiv/mdbsocials/NewSocialActivity.java new file mode 100644 index 0000000..9117e28 --- /dev/null +++ b/app/src/main/java/com/example/shiv/mdbsocials/NewSocialActivity.java @@ -0,0 +1,244 @@ +package com.example.shiv.mdbsocials; + +import android.app.Activity; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.graphics.Bitmap; +import android.graphics.drawable.BitmapDrawable; +import android.net.Uri; +import android.provider.MediaStore; +import android.support.annotation.MainThread; +import android.support.annotation.NonNull; +import android.support.v7.app.AlertDialog; +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.ImageButton; +import android.widget.ImageView; +import android.widget.Switch; +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.FirebaseUser; +import com.google.firebase.database.DatabaseReference; +import com.google.firebase.database.FirebaseDatabase; +import com.google.firebase.database.ServerValue; +import com.google.firebase.storage.FirebaseStorage; +import com.google.firebase.storage.StorageReference; +import com.google.firebase.storage.UploadTask; + +import java.io.ByteArrayOutputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.ArrayList; + +public class NewSocialActivity extends AppCompatActivity { + + public static final int GET_FROM_GALLERY = 3; + public static final int GET_FROM_CAMERA = 4; + public Uri currentImage = null; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_new_social); + + EditText eventName = (EditText) findViewById(R.id.editText3); + ImageButton imgButton = (ImageButton) findViewById(R.id.imageButton); + Button add = (Button) findViewById(R.id.button7); + Button butt = (Button) findViewById(R.id.button8); + EditText eventDate = (EditText) findViewById(R.id.editText4); + EditText eventDescription = (EditText) findViewById(R.id.editText7); + + + + + + + add.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + + Toast.makeText(getApplicationContext(), "Adding Event",Toast.LENGTH_SHORT).show(); + sendToServer(); + Toast.makeText(getApplicationContext(), "Event Saved!",Toast.LENGTH_SHORT).show(); + + } + }); + + butt.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + AlertDialog alertDialog = new AlertDialog.Builder(NewSocialActivity.this).create(); + alertDialog.setTitle("Set a Photo"); + alertDialog.setButton(AlertDialog.BUTTON_POSITIVE, "Take a Photo", + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + //Open Camera + Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); + if (takePictureIntent.resolveActivity(getPackageManager()) != null) { + startActivityForResult(takePictureIntent, GET_FROM_CAMERA); + } + + +// Bundle extras = takePictureIntent.getExtras(); +// Bitmap imageBitmap = (Bitmap) extras.get("data"); +// mImageView.setImageBitmap(imageBitmap); + dialog.dismiss(); + } + }); + alertDialog.setButton(AlertDialog.BUTTON_NEGATIVE, "Upload from Gallery", + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + //launch gallery + dialog.dismiss(); + startActivityForResult(new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.INTERNAL_CONTENT_URI), GET_FROM_GALLERY); + } + }); + alertDialog.show(); + + } + }); + + + + + + +// imgButton.setOnClickListener(new View.OnClickListener() { +// @Override +// public void onClick(View view) { +// startActivityForResult(new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.INTERNAL_CONTENT_URI), GET_FROM_GALLERY); +// } +// }); + + + + } + + + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + + super.onActivityResult(requestCode, resultCode, data); + + + //Detects request codes + if(requestCode==GET_FROM_GALLERY && resultCode == Activity.RESULT_OK) { + Uri selectedImage = data.getData(); + currentImage = data.getData(); + Bitmap bitmap = null; + try { + bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), selectedImage); + BitmapDrawable bitmapDrawable = new BitmapDrawable(getResources(), bitmap); + ((ImageButton) findViewById(R.id.imageButton)).setBackgroundDrawable(bitmapDrawable); + + } catch (FileNotFoundException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + else if (requestCode == GET_FROM_CAMERA) { + + Uri selectedImage = data.getData(); + Bitmap bitmap = null; + try { + bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), selectedImage); + //BitmapDrawable bitmapDrawable = new BitmapDrawable(getResources(), bitmap); + ((ImageView) findViewById(R.id.imageButton)).setImageBitmap(bitmap); + } catch (FileNotFoundException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + /* + + Bundle extras = data.getExtras(); + Bitmap imageBitmap = (Bitmap) extras.get("data"); + + Uri selectedImage = getImageUri(getApplicationContext(), imageBitmap); //data.getData(); + currentImage = selectedImage;//data.getData(); + Bitmap bitmap = null; + + + try { + bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), selectedImage); + + bitmap = imageBitmap; + + BitmapDrawable bitmapDrawable = new BitmapDrawable(getResources(), bitmap); + ((ImageButton) findViewById(R.id.imageButton)).setBackgroundDrawable(bitmapDrawable); + + } catch (FileNotFoundException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + */ + + } + } + + private void sendToServer(){ + + final DatabaseReference ref = FirebaseDatabase.getInstance().getReference(); + final String key = ref.child("events").push().getKey(); + StorageReference storageRef = FirebaseStorage.getInstance().getReferenceFromUrl("gs://mdbsocials-56ed5.appspot.com"); + StorageReference riversRef = storageRef.child(key + ".png"); + + //issue with camera + riversRef.putFile(currentImage).addOnFailureListener(new OnFailureListener() { + @Override + public void onFailure(@NonNull Exception exception) { + Toast.makeText(NewSocialActivity.this, "need an image!", Toast.LENGTH_SHORT).show(); + } + }).addOnSuccessListener(new OnSuccessListener() { + @Override + public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) { + String description = ((EditText) findViewById(R.id.editText7)).getText().toString(); + String date = ((EditText) findViewById(R.id.editText4)).getText().toString(); + String name = ((EditText) findViewById(R.id.editText3)).getText().toString(); + String email = MainActivity.email; + ref.child("events").child(key).child("name").setValue(name); + ref.child("events").child(key).child("url").setValue(key); + ref.child("events").child(key).child("date").setValue(date); + ref.child("events").child(key).child("description").setValue(description); + ref.child("events").child(key).child("email").setValue(email); + ref.child("events").child(key).child("interested").setValue("1"); + ArrayList temp = new ArrayList(); + temp.add(email); + + ref.child("events").child(key).child("peopleinterested").setValue(temp); + ref.child("events").child(key).child("timestamp").setValue(ServerValue.TIMESTAMP); + + + Intent intent = new Intent(getApplicationContext(), FeedActivity.class); + startActivity(intent); + } + }); + + + } + + public Uri getImageUri(Context inContext, Bitmap inImage) { + ByteArrayOutputStream bytes = new ByteArrayOutputStream(); + inImage.compress(Bitmap.CompressFormat.JPEG, 100, bytes); + String path = MediaStore.Images.Media.insertImage(inContext.getContentResolver(), inImage, "Title", null); + return Uri.parse(path); + } +} diff --git a/app/src/main/java/com/example/shiv/mdbsocials/RegisterActivity.java b/app/src/main/java/com/example/shiv/mdbsocials/RegisterActivity.java new file mode 100644 index 0000000..e20bb8f --- /dev/null +++ b/app/src/main/java/com/example/shiv/mdbsocials/RegisterActivity.java @@ -0,0 +1,99 @@ +package com.example.shiv.mdbsocials; + +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 RegisterActivity extends AppCompatActivity { + + private FirebaseAuth mAuth; + private FirebaseAuth.AuthStateListener mAuthListener; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_register); + + Button register = (Button) findViewById(R.id.button4); + Button loginButton = (Button) findViewById(R.id.button2); + mAuth = FirebaseAuth.getInstance(); + mAuthListener = new FirebaseAuth.AuthStateListener() { + @Override + public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) { + FirebaseUser user = firebaseAuth.getCurrentUser(); + if (user != null) { + // User is signed in + Log.d("Register Status", "onAuthStateChanged:signed_in:" + user.getUid()); + } else { + // User is signed out + Log.d("Register Status", "onAuthStateChanged:signed_out"); + } + // ... + } + }; + + register.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + attemptRegister(); + } + }); + + } + + private void attemptRegister() { + String email = ((EditText) findViewById(R.id.editText6)).getText().toString(); + String password = ((EditText) findViewById(R.id.editText5)).getText().toString(); + + if (!email.equals("") && !password.equals("")) { + //Question 5: add sign up capability. Same results as log in. + mAuth.createUserWithEmailAndPassword(email, password) + .addOnCompleteListener(this, new OnCompleteListener() { + @Override + public void onComplete(@NonNull Task task) { + Log.d("SignUp Status", "createUserWithEmail:onComplete:" + task.isSuccessful()); + + // If sign in fails, display a message to the user. If sign in succeeds + // the auth state listener will be notified and logic to handle the + // signed in user can be handled in the listener. + if (!task.isSuccessful()) { + Toast.makeText(getApplicationContext(), "Authentication failed.", + Toast.LENGTH_SHORT).show(); + } + else { + 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/shiv/mdbsocials/User.java b/app/src/main/java/com/example/shiv/mdbsocials/User.java new file mode 100644 index 0000000..979c7d7 --- /dev/null +++ b/app/src/main/java/com/example/shiv/mdbsocials/User.java @@ -0,0 +1,14 @@ +package com.example.shiv.mdbsocials; + +/** + * Created by Shiv on 2/23/17. + */ + +public class User { + String email; + String img; + public User(String x, String y) { + email = x; + img = y; + } +} diff --git a/app/src/main/java/com/example/shiv/mdbsocials/UserAdapter.java b/app/src/main/java/com/example/shiv/mdbsocials/UserAdapter.java new file mode 100644 index 0000000..5e4a78a --- /dev/null +++ b/app/src/main/java/com/example/shiv/mdbsocials/UserAdapter.java @@ -0,0 +1,88 @@ +package com.example.shiv.mdbsocials; + +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.CardView; +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.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 Shiv on 2/23/17. + */ + +public class UserAdapter extends RecyclerView.Adapter{ + + Context context; + public static ArrayList users; + + public UserAdapter(Context context, ArrayList users) { + this.context = context; + this.users = users; + } + @Override + public UserAdapter.CustomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + + View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_view_usersinterested, parent, false); + return new CustomViewHolder(view); + } + @Override + public void onBindViewHolder(final UserAdapter.CustomViewHolder holder, int position) { + User currentUser = users.get(position); + + //In the onBindViewHolder, you want to set each of the parameters of ComputerCompanies very similiar + //to what you did to the layout manager. + + holder.emailText.setText(currentUser.email); + holder.imgView = currentUser.img; + + + + + } + + @Override + public int getItemCount() { + return users.size(); + } + + public void updateUsers(ArrayList arr) { + users = arr; + notifyDataSetChanged(); + } + + public class CustomViewHolder extends RecyclerView.ViewHolder { + + //Set up the variables of Computer Companies here + + TextView emailText; + String imgView; + + public CustomViewHolder(View view) { + super(view); + + //Here, think about what you have to "find..." + emailText = (TextView) view.findViewById(R.id.textView5); + //imgView = (ImageView) view.findViewById(R.id.imageView3); + } + } + + + + +} diff --git a/app/src/main/java/com/example/shiv/mdbsocials/UsersInterestedActivity.java b/app/src/main/java/com/example/shiv/mdbsocials/UsersInterestedActivity.java new file mode 100644 index 0000000..46e5570 --- /dev/null +++ b/app/src/main/java/com/example/shiv/mdbsocials/UsersInterestedActivity.java @@ -0,0 +1,94 @@ +package com.example.shiv.mdbsocials; + +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.Log; + +import com.google.firebase.database.ChildEventListener; +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 java.util.ArrayList; + +public class UsersInterestedActivity extends AppCompatActivity { + + RecyclerView rview; + UserAdapter userAdapter; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_users_interested); + rview = (RecyclerView) findViewById(R.id.rview2); + rview.setLayoutManager(new LinearLayoutManager(getApplicationContext())); + Intent intent = getIntent(); + + userAdapter = new UserAdapter(getApplicationContext(), new ArrayList()); + rview.setAdapter(userAdapter); + final String firebasekey = intent.getStringExtra("key"); + + final ArrayList interestedPeople = new ArrayList<>(); + + DatabaseReference ref = FirebaseDatabase.getInstance().getReference("/events"); + ref.addChildEventListener(new ChildEventListener() { + @Override + public void onChildAdded(DataSnapshot dataSnapshot, String s) { + if (dataSnapshot.getKey().equals(firebasekey)) { + ArrayList a = (ArrayList) dataSnapshot.child("peopleinterested").getValue(); + for (int i = 0; i < a.size(); i++) { + interestedPeople.add(a.get(i)); + } + ArrayList arr = new ArrayList<>(); + for (int i = 0; i < interestedPeople.size(); i++) { + arr.add(new User(interestedPeople.get(i),"temp")); + } + + userAdapter.updateUsers(arr); + userAdapter.notifyDataSetChanged(); + } + } + + @Override + public void onChildChanged(DataSnapshot dataSnapshot, String s) { + + } + + @Override + public void onChildRemoved(DataSnapshot dataSnapshot) { + + } + + @Override + public void onChildMoved(DataSnapshot dataSnapshot, String s) { + + } + + @Override + public void onCancelled(DatabaseError databaseError) { + + } + }); + + //Why does this not work? //ArrayList interestedPeople = ref.child(firebasekey).child("peopleinterested").valueOf(ArrayList.class); + //ArrayList interestedPeople = ref.child(firebasekey).child("peopleinterested").getValue(String.class); + /* + User x = new User("hello","dsf"); + + User y = new User("durr","dsfsdf"); + ArrayList d = new ArrayList<>(); + for (int i = 0; i < interestedPeople.size(); i++) { + d.add(new User(interestedPeople.get(i),"temp")); + } + */ + //d.add(x); + //d.add(y); + + + + } +} diff --git a/app/src/main/res/drawable/logo.png b/app/src/main/res/drawable/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..3ba8982e914f5489d0b82accf1ac416f8919c816 GIT binary patch literal 17715 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 + + + + + + + + + + + + +