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..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/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..b2bdec2 --- /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..4de11da 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 +>>>>>>> 187c53ccbdd8774efc914e15bf86a3d139b594e2 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..fcdacd8 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,40 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 25 + buildToolsVersion "25.0.2" + defaultConfig { + applicationId "com.example.radhika.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-database:10.2.0' + compile 'com.google.firebase:firebase-storage:10.2.0' + compile 'com.google.firebase:firebase-auth:10.2.0' + compile 'com.android.support.constraint:constraint-layout:1.0.0-beta5' + compile 'com.android.support:design:25.1.1' + testCompile 'junit:junit:4.12' + compile 'com.android.support:recyclerview-v7:25.1.1' + compile 'com.android.support:cardview-v7:25.1.0' + compile 'com.github.bumptech.glide:glide:3.5.2' + +} + +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..75d1e06 --- /dev/null +++ b/app/google-services.json @@ -0,0 +1,55 @@ +{ + "project_info": { + "project_number": "1098638014968", + "firebase_url": "https://mdbsocials-7d774.firebaseio.com", + "project_id": "mdbsocials-7d774", + "storage_bucket": "mdbsocials-7d774.appspot.com" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:1098638014968:android:472de4f8bae7c6b4", + "android_client_info": { + "package_name": "com.example.radhika.mdbsocials" + } + }, + "oauth_client": [ + { + "client_id": "1098638014968-73o689qtkm87ahqbhdtrun9a8lrrov1c.apps.googleusercontent.com", + "client_type": 1, + "android_info": { + "package_name": "com.example.radhika.mdbsocials", + "certificate_hash": "7aa5a0c7eb2c732903199f2d698b9aec693da1e5" + } + }, + { + "client_id": "1098638014968-8tco8eph6khenj3mii08hjc4c9kjmcb9.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyCe2zSt4b-jlxvvRcSZcq-_HN4iBe37_tU" + } + ], + "services": { + "analytics_service": { + "status": 1 + }, + "appinvite_service": { + "status": 2, + "other_platform_oauth_client": [ + { + "client_id": "1098638014968-8tco8eph6khenj3mii08hjc4c9kjmcb9.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..bf49662 --- /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/Radhika/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/radhika/mdbsocials/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/example/radhika/mdbsocials/ExampleInstrumentedTest.java new file mode 100644 index 0000000..5504469 --- /dev/null +++ b/app/src/androidTest/java/com/example/radhika/mdbsocials/ExampleInstrumentedTest.java @@ -0,0 +1,26 @@ +package com.example.radhika.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.radhika.mdbsocials", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..99725df --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/example/radhika/mdbsocials/InterestedFeedActivity.java b/app/src/main/java/com/example/radhika/mdbsocials/InterestedFeedActivity.java new file mode 100644 index 0000000..13e8779 --- /dev/null +++ b/app/src/main/java/com/example/radhika/mdbsocials/InterestedFeedActivity.java @@ -0,0 +1,66 @@ +package com.example.radhika.mdbsocials; + +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.auth.FirebaseUser; +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; +import java.util.List; + +/** + * + * TO DO : + * 1. add profile image + * 2. add take picture function + * 3. fix recycler view problem - when you cmark interested, adds new row - click on that row and CRASH + * 4. improve UI + * 5. Perform checks for all input taken!!!!!!! especially in signup + * + */ + +public class InterestedFeedActivity extends AppCompatActivity { + InterestedFeedAdapter adapter; + DatabaseReference db; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_interested_feed); + init(); + } + public void init () { + RecyclerView recyclerView = (RecyclerView) (findViewById(R.id.rv)); + recyclerView.setLayoutManager(new LinearLayoutManager(this)); + + final List interested = new ArrayList<>(); + + // Get the ID of the event from the Intent used to start the InterestedActivity + String key = getIntent().getStringExtra("Social Key"); + + db = FirebaseDatabase.getInstance().getReference(); + db = db.child("Socials").child(key); + adapter = new InterestedFeedAdapter(getApplicationContext(), interested); + recyclerView.setAdapter(adapter); + db.addValueEventListener(new ValueEventListener() { + @Override + public void onDataChange(DataSnapshot snapshot) { + Social s = snapshot.getValue(Social.class); + adapter.interested = s.getInterested(); + adapter.notifyDataSetChanged(); + } + + @Override + public void onCancelled(DatabaseError firebaseError) {} + }); + + } +} diff --git a/app/src/main/java/com/example/radhika/mdbsocials/InterestedFeedAdapter.java b/app/src/main/java/com/example/radhika/mdbsocials/InterestedFeedAdapter.java new file mode 100644 index 0000000..4ffa8a7 --- /dev/null +++ b/app/src/main/java/com/example/radhika/mdbsocials/InterestedFeedAdapter.java @@ -0,0 +1,68 @@ +package com.example.radhika.mdbsocials; + +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.ImageView; +import android.widget.TextView; + +import com.bumptech.glide.Glide; +import com.google.firebase.auth.FirebaseUser; + +import org.w3c.dom.Text; + +import java.util.List; + +/** + * Created by Radhika on 2/25/17. + */ + +public class InterestedFeedAdapter extends RecyclerView.Adapter { + Context context; + List interested; + + public InterestedFeedAdapter (Context context, List list){ + this.context = context; + this.interested = list; + } + + public CustomViewHolder onCreateViewHolder(ViewGroup parent, int viewType){ + View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_view_2, parent, false); + return new InterestedFeedAdapter.CustomViewHolder(view); + } + + @Override + public void onBindViewHolder(CustomViewHolder holder, int position){ + User u = interested.get(position); + holder.interestedTextView.setText(u.getEmail()); + holder.interestedName.setText(u.getName()); + Glide.with(context) + .load(u.getImageUrl()) + .into(holder.interestedPicture); + } + + public int getItemCount(){ + return interested.size(); + } + + public void updateList (List newList) { + this.interested = newList; + } + + class CustomViewHolder extends RecyclerView.ViewHolder { + + TextView interestedTextView; + TextView interestedName; + ImageView interestedPicture; + + public CustomViewHolder(View view){ + super(view); + this.interestedTextView = (TextView) (view.findViewById(R.id.interestedEmail)); + this.interestedName = (TextView) (view.findViewById(R.id.interestedName)); + this.interestedPicture = (ImageView) (view.findViewById(R.id.userImage)); + } + } + +} diff --git a/app/src/main/java/com/example/radhika/mdbsocials/NewSocialActivity.java b/app/src/main/java/com/example/radhika/mdbsocials/NewSocialActivity.java new file mode 100644 index 0000000..7fb39a2 --- /dev/null +++ b/app/src/main/java/com/example/radhika/mdbsocials/NewSocialActivity.java @@ -0,0 +1,148 @@ +package com.example.radhika.mdbsocials; + +import android.app.Activity; +import android.app.ProgressDialog; +import android.content.Context; +import android.content.Intent; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.net.Uri; +import android.os.AsyncTask; +import android.provider.MediaStore; +import android.support.annotation.NonNull; +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.auth.FirebaseAuth; +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.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.ArrayList; +import java.util.Map; + +/** + * Things to do + * add a date picker - check for valid dates + * USE TIMESTAMP + */ +public class NewSocialActivity extends AppCompatActivity implements View.OnClickListener { + private EditText eventName, eventDescription, eventDate; + private Button doneButton; + private ImageView eventPicture; + private Bitmap eventPictureBitmap; + private DatabaseReference db; + private FirebaseAuth mAuth; + private FirebaseStorage storage; + private Uri uri; + private boolean uploadedPicture; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_new_social); + init(); + } + + private void init () { + db = FirebaseDatabase.getInstance().getReference(); + mAuth = FirebaseAuth.getInstance(); // need to access curr user! + storage = FirebaseStorage.getInstance(); + uploadedPicture = false; + eventName = (EditText) (findViewById(R.id.eventName)); + eventDescription = (EditText) (findViewById(R.id.eventDescription)); + eventDate = (EditText) (findViewById(R.id.eventDate)); + doneButton = (Button) (findViewById(R.id.doneButton)); + eventPicture = (ImageView) (findViewById(R.id.eventPicture)); + eventPicture.setOnClickListener(this); + doneButton.setOnClickListener(this); + } + + private void getImage() { + // http://codetheory.in/android-pick-select-image-from-gallery-with-intents/ + Intent intent = new Intent(Intent.ACTION_GET_CONTENT) + .setType("image/*"); + startActivityForResult(Intent.createChooser(intent, "Select Image"), 1); + } + private void addNewSocial() { + if (mAuth.getCurrentUser() == null) + startActivity(new Intent(getApplicationContext(), SignInActivity.class)); + final String eName = eventName.getText().toString(); + final String eDesc = eventDescription.getText().toString(); + final String eDate = eventDate.getText().toString(); + if (eName.length() == 0 || eDesc.length() == 0 + || eDate.length() == 0 || !uploadedPicture) { + Toast.makeText(getApplicationContext(), "Not enough information to create a social", Toast.LENGTH_LONG).show(); + return; + } + final String email = mAuth.getCurrentUser().getEmail(); + final String key = db.child("Socials").push().getKey(); + // refer to youtube SimplifiedCoding tutorial + StorageReference sref = storage.getReference().child("images/" + key + ".jpg"); + sref.putFile(uri).addOnFailureListener(new OnFailureListener() { + @Override + public void onFailure(@NonNull Exception e) { + Toast.makeText(getApplicationContext(), "Cannot Create New Social", Toast.LENGTH_SHORT).show(); + } + }).addOnSuccessListener(new OnSuccessListener() { + @Override + public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) { + Uri img = taskSnapshot.getDownloadUrl(); + Social s = new Social (eName, email, 0, img.toString(), System.currentTimeMillis(), eDesc, eDate, new ArrayList()); + db.child("Socials").child(key).setValue(s); + startActivity(new Intent(NewSocialActivity.this, SocialFeedActivity.class)); + } + }); + } + + public void onClick (View view) { + switch (view.getId()) { + case R.id.eventPicture: + getImage(); + break; + case R.id.doneButton: + addNewSocial(); + break; + } + } +// @Override +// protected void onActivityResult(int requestCode, int resultCode, Intent data) { +// super.onActivityResult(requestCode, resultCode, data); +// // refer to http://codetheory.in/android-pick-select-image-from-gallery-with-intents/ +// if (requestCode == 1 && resultCode == RESULT_OK && +// data != null && data.getData() != null) { +// uri = data.getData(); +// uploadedPicture = true; +// } +// } + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + // refer to http://codetheory.in/android-pick-select-image-from-gallery-with-intents/ + if (requestCode == 1 && resultCode == RESULT_OK && + data != null && data.getData() != null) { + uri = data.getData(); + try { + eventPictureBitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), uri); + eventPicture.setImageBitmap(eventPictureBitmap); + uploadedPicture = true; + } catch (IOException e) { + e.printStackTrace(); + } + } + } +} diff --git a/app/src/main/java/com/example/radhika/mdbsocials/SignInActivity.java b/app/src/main/java/com/example/radhika/mdbsocials/SignInActivity.java new file mode 100644 index 0000000..b37887e --- /dev/null +++ b/app/src/main/java/com/example/radhika/mdbsocials/SignInActivity.java @@ -0,0 +1,96 @@ +package com.example.radhika.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.ProgressBar; +import android.widget.TextView; +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 java.io.FilterReader; + +public class SignInActivity extends AppCompatActivity implements View.OnClickListener{ + private FirebaseAuth mAuth; + private FirebaseAuth.AuthStateListener mAuthListener; + private EditText email; + private EditText password; + private TextView signUpText; + private Button logInButton; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_sign_in); + init(); + } + + private void init () { + email = (EditText) (findViewById(R.id.emailAddressText)); + password = (EditText) (findViewById(R.id.passwordTextView)); + logInButton = ((Button) (findViewById(R.id.signInButton))); + logInButton.setOnClickListener(this); + signUpText = ((TextView) (findViewById(R.id.signUpText))); + signUpText.setOnClickListener(this); + + mAuth = FirebaseAuth.getInstance(); + mAuthListener = new FirebaseAuth.AuthStateListener() { + public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) { + FirebaseUser user = firebaseAuth.getCurrentUser(); + if (user != null) { + startActivity(new Intent(SignInActivity.this, SocialFeedActivity.class)); + } + } + }; + } + + private void signIn(String email, String password) { + mAuth.signInWithEmailAndPassword(email, password).addOnCompleteListener(this, new OnCompleteListener() { + @Override + public void onComplete(@NonNull Task task) { + if (!task.isSuccessful()) + Toast.makeText(SignInActivity.this, "Sign In Problem", Toast.LENGTH_SHORT).show(); + } + }); + } + + @Override + public void onClick (View view) { + switch (view.getId()) { + case R.id.signInButton: + if (email.getText().toString().length() > 0 && password.getText().toString().length() > 0) { + signIn(email.getText().toString(), password.getText().toString()); + } + else + Toast.makeText(SignInActivity.this, "Sign In Problem", Toast.LENGTH_SHORT).show(); + break; + case R.id.signUpText: + startActivity(new Intent(SignInActivity.this, SignUpActivity.class)); + break; + } + } + + @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/radhika/mdbsocials/SignUpActivity.java b/app/src/main/java/com/example/radhika/mdbsocials/SignUpActivity.java new file mode 100644 index 0000000..0023be0 --- /dev/null +++ b/app/src/main/java/com/example/radhika/mdbsocials/SignUpActivity.java @@ -0,0 +1,149 @@ +package com.example.radhika.mdbsocials; + +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.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.OnFailureListener; +import com.google.android.gms.tasks.OnSuccessListener; +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.auth.UserProfileChangeRequest; +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 java.io.IOException; +import java.util.ArrayList; + +public class SignUpActivity extends AppCompatActivity implements View.OnClickListener{ + private FirebaseAuth mAuth; + private FirebaseAuth.AuthStateListener mAuthListener; + private EditText name; + private EditText email; + private EditText password; + private Button signUpButton; + private Button photoButton; + private String imageUrl ; + private Uri uri; + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_sign_up); + init(); + } + + private void init () { + name = (EditText) (findViewById(R.id.nameText)); + email = (EditText) (findViewById(R.id.emailText)); + password = (EditText) (findViewById(R.id.passwordText)); + signUpButton = (Button) (findViewById(R.id.signUpButton)); + signUpButton.setOnClickListener(this); + photoButton = (Button) (findViewById(R.id.uploadPhoto)); + photoButton.setOnClickListener(this); + + mAuth = FirebaseAuth.getInstance(); + + mAuthListener = new FirebaseAuth.AuthStateListener() { + public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) { + FirebaseUser user = firebaseAuth.getCurrentUser(); + if (user != null) + startActivity(new Intent(SignUpActivity.this, SocialFeedActivity.class)); + } + }; + + } + + private void signUp(final String name, final String email, String password) { + final String finName = name; + mAuth.createUserWithEmailAndPassword(email, password) + .addOnCompleteListener(this, new OnCompleteListener() { + @Override + public void onComplete(@NonNull Task task) { + if (!task.isSuccessful()) { + Toast.makeText(SignUpActivity.this, "Sign Up Problem", Toast.LENGTH_SHORT).show(); + } else { + FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser(); + UserProfileChangeRequest profileUpdates = new UserProfileChangeRequest.Builder() + .setDisplayName(finName) + //.setPhotoUri(Uri.parse("https://example.com/jane-q-user/profile.jpg")) + .build(); + + user.updateProfile(profileUpdates); + final DatabaseReference db = FirebaseDatabase.getInstance().getReference(); + StorageReference sref = FirebaseStorage.getInstance().getReference().child("images/" + mAuth.getCurrentUser().getUid() + ".jpg"); + sref.putFile(uri).addOnFailureListener(new OnFailureListener() { + @Override + public void onFailure(@NonNull Exception e) { + Toast.makeText(getApplicationContext(), "Cannot Create New Social", Toast.LENGTH_SHORT).show(); + } + }).addOnSuccessListener(new OnSuccessListener() { + @Override + public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) { + imageUrl= (taskSnapshot.getDownloadUrl().toString()); + final User u = new User (name, email, imageUrl); + db.child("Users").child(mAuth.getCurrentUser().getUid()).setValue(u); + } + }); + } + } + }); + } + + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.signUpButton: + if (name.getText().toString().length() > 0 && email.getText().toString().length() > 0 && password.getText().toString().length() > 0) + signUp(name.getText().toString(), email.getText().toString(), password.getText().toString()); + break; + case R.id.uploadPhoto: + Intent intent = new Intent(Intent.ACTION_GET_CONTENT) + .setType("image/*"); + startActivityForResult(Intent.createChooser(intent, "Select Image"), 2); +// // refer to youtube SimplifiedCoding tutorial + break; + } + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + // refer to http://codetheory.in/android-pick-select-image-from-gallery-with-intents/ + if (requestCode == 2 && resultCode == RESULT_OK && + data != null && data.getData() != null) { + uri = data.getData(); + } + } + + + + @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/radhika/mdbsocials/Social.java b/app/src/main/java/com/example/radhika/mdbsocials/Social.java new file mode 100644 index 0000000..9fcee44 --- /dev/null +++ b/app/src/main/java/com/example/radhika/mdbsocials/Social.java @@ -0,0 +1,110 @@ +package com.example.radhika.mdbsocials; + +import com.google.firebase.auth.FirebaseUser; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Radhika on 2/24/17. + */ +public class Social implements Comparable{ + private String name; + private String emailAddress; + private int numInterested; + private String imageUrl; + private long timestamp; + private String date; + private String description; + private List interested; + + public Social () { + + } + + public Social(String name, String hostEmail, int numInterested, String image, long timeMade, String description, String date, List interested) { + this.name = name; + this.emailAddress = hostEmail; + this.numInterested = numInterested; + this.imageUrl = image; + this.timestamp = timeMade; + this.date = date; + this.description = description; + this.interested = interested; + } + + public String getName(){ + return name; + } + + public String getEmailAddress(){ + return emailAddress; + } + + public int getNumInterested(){ + return numInterested; + } + + public String getImageUrl(){ + return imageUrl; + } + + public long getTimestamp(){ + return timestamp; + } + + public String getDate() { + return date; + } + + public List getInterested() { + return interested; + } + + public String getDescription() { + return description; + } + + public void setName(String name) { + this.name = name; + } + + public void setEmailAddress(String emailAddress) { + this.emailAddress = emailAddress; + } + + public void setNumInterested(int numInterested) { + this.numInterested = numInterested; + } + + public void setImageUrl(String imageUrl) { + this.imageUrl = imageUrl; + } + + public void setTimestamp(long timestamp) { + this.timestamp = timestamp; + } + + public void setDate(String date) { + this.date = date; + } + + public void setDescription(String description) { + this.description = description; + } + + public void setInterested(List interested ) { + this.interested = interested; + } + + public int compareTo(Social other){ + if (this.timestamp > other.timestamp) + return -1; + else if (this.timestamp < other.timestamp) + return 1; + return 0; + } + public boolean equals (Social other) { + return this.timestamp == other.timestamp; + } +} diff --git a/app/src/main/java/com/example/radhika/mdbsocials/SocialDetailsActivity.java b/app/src/main/java/com/example/radhika/mdbsocials/SocialDetailsActivity.java new file mode 100644 index 0000000..8836204 --- /dev/null +++ b/app/src/main/java/com/example/radhika/mdbsocials/SocialDetailsActivity.java @@ -0,0 +1,154 @@ +package com.example.radhika.mdbsocials; + +import android.app.Activity; +import android.app.ProgressDialog; +import android.content.Context; +import android.content.Intent; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.net.Uri; +import android.os.AsyncTask; +import android.os.Bundle; +import android.support.design.widget.FloatingActionButton; +import android.support.design.widget.Snackbar; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.Toolbar; +import android.view.View; +import android.widget.Button; +import android.widget.ImageView; +import android.widget.ScrollView; +import android.widget.TextView; +import android.widget.Toast; +import android.widget.ToggleButton; + +import com.bumptech.glide.Glide; +import com.google.android.gms.tasks.OnSuccessListener; +import com.google.firebase.auth.FirebaseAuth; +import com.google.firebase.auth.FirebaseUser; +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 com.google.firebase.storage.FirebaseStorage; +import com.google.firebase.storage.StorageReference; + +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.URL; + +public class SocialDetailsActivity extends AppCompatActivity implements View.OnClickListener{ + String key; + private TextView socialName, dateText, descriptionText; + private ImageView eventImage; + private int numInterested; + Button interestedButton; + ToggleButton interestedToggleButton; + DatabaseReference db; + FirebaseStorage storage; + FirebaseAuth mAuth; + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_social_details); + init(); + + } + public void init () { + socialName = (TextView) findViewById(R.id.socialTitleView); + dateText = (TextView) findViewById(R.id.dateTextView); + eventImage = (ImageView) findViewById(R.id.eventImageView); + descriptionText = (TextView) findViewById(R.id.descriptionTextView); + interestedButton = (Button) findViewById(R.id.interestedButton); + interestedToggleButton = (ToggleButton) findViewById(R.id.interestedToggleButton); + interestedButton.setOnClickListener(this); + interestedToggleButton.setOnClickListener(this); + + key = getIntent().getExtras().getString("Social Key"); + db = FirebaseDatabase.getInstance().getReference(); + storage = FirebaseStorage.getInstance(); + mAuth = FirebaseAuth.getInstance(); + db.child("Socials").child(key).addValueEventListener(new ValueEventListener() { + @Override + public void onDataChange(DataSnapshot dataSnapshot) { + setUp(dataSnapshot.getValue(Social.class)); + } + + @Override + public void onCancelled(DatabaseError databaseError) {} + }); + } + public void onClick (View v){ + switch(v.getId()) { + case R.id.interestedToggleButton: + Utils.update(db.child("Socials").child(key), Utils.user); + break; + case R.id.interestedButton: + if (numInterested > 0 ) { + Intent i = new Intent(SocialDetailsActivity.this, InterestedFeedActivity.class); + i.putExtra("Social Key", key); + startActivity(i); + } else { + Toast.makeText(getApplicationContext(), "Sorry, no one is interested in this event", Toast.LENGTH_LONG).show(); + } + break; + } + } + public void setUp(final Social s) { + BitmapAsyncTask b = new BitmapAsyncTask(this, getApplicationContext()); + b.execute(s.getImageUrl()); +// Glide.with(getApplicationContext()) +// .load(s.getImageUrl()) +// .into(eventImage); + socialName.setText(s.getName()); + dateText.setText(s.getDate()); + descriptionText.setText(s.getDescription()); + interestedButton.setText("" + s.getNumInterested() + " Interested"); + numInterested = s.getNumInterested(); + + } + class BitmapAsyncTask extends AsyncTask { + private ProgressDialog dialog; + public BitmapAsyncTask(Activity act, Context context) { + super(); + dialog = new ProgressDialog(act); + } + @Override + protected Bitmap doInBackground(String... params) { + try { + URL url = new URL(params[0]); + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setDoInput(true); + connection.connect(); + InputStream input = connection.getInputStream(); + return BitmapFactory.decodeStream(input); + } catch (IOException e) { + e.printStackTrace(); + return null; + } + } + + protected void onPreExecute() { + dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); + dialog.setCancelable(true); + dialog.setMessage("Loading..."); + dialog.setProgress(0); + dialog.show(); + } + + @Override + protected void onPostExecute(Bitmap bitmap) { + if (bitmap != null) { + eventImage.setImageBitmap(bitmap); + super.onPostExecute(bitmap); + } + dialog.dismiss(); + } + @Override + protected void onProgressUpdate(Integer... values) { + dialog.show(); + dialog.setProgress(values[0]); + } + } +} diff --git a/app/src/main/java/com/example/radhika/mdbsocials/SocialFeedActivity.java b/app/src/main/java/com/example/radhika/mdbsocials/SocialFeedActivity.java new file mode 100644 index 0000000..851e144 --- /dev/null +++ b/app/src/main/java/com/example/radhika/mdbsocials/SocialFeedActivity.java @@ -0,0 +1,95 @@ +package com.example.radhika.mdbsocials; + +import android.content.Intent; +import android.support.design.widget.FloatingActionButton; +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 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.ValueEventListener; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class SocialFeedActivity extends AppCompatActivity implements View.OnClickListener { + SocialFeedAdapter adapter; + DatabaseReference db; + FloatingActionButton addSocialButton; + Button signOut; + static List keys; + RecyclerView recyclerView; + ArrayList socials; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_social_feed); + + addSocialButton = (FloatingActionButton) findViewById(R.id.addSocialButton); + addSocialButton.setOnClickListener(this); + signOut = (Button) (findViewById(R.id.signOutButton)); + signOut.setOnClickListener(this); + socials = new ArrayList<>(); + recyclerView = (RecyclerView) findViewById(R.id.recView); + recyclerView.setLayoutManager(new LinearLayoutManager(this)); + + initDB(); + +// recyclerView.setAdapter(adapter); + } + + private void initDB () { + db = FirebaseDatabase.getInstance().getReference(); + Utils.getUser(db, FirebaseAuth.getInstance().getCurrentUser()); + adapter = new SocialFeedAdapter(getApplicationContext(), socials); + db.child("Socials").addValueEventListener(new ValueEventListener() { + @Override + public void onDataChange(DataSnapshot snapshot) { + socials = new ArrayList(); + Map map = new HashMap<>(); + + for (DataSnapshot p : snapshot.getChildren()) { + Social s = p.getValue(Social.class); + map.put(s, p.getKey()); + if (!socials.contains(s)) + socials.add(s); + } + + Collections.sort(socials); + + keys = new ArrayList<>(); + for (Social s : socials) + keys.add(map.get(s)); + + adapter.socials = socials; + recyclerView.setAdapter(adapter); + } + + @Override + public void onCancelled(DatabaseError firebaseError) { + } + }); + } + + public void onClick(View view) { + if (view.getId() == R.id.addSocialButton) + startActivity(new Intent(getApplicationContext(), NewSocialActivity.class)); + else if (view.getId() == R.id.signOutButton) { + FirebaseAuth.getInstance().signOut(); + Intent intent = new Intent(getApplicationContext(), SignInActivity.class); + startActivity(intent); + } + } +} diff --git a/app/src/main/java/com/example/radhika/mdbsocials/SocialFeedAdapter.java b/app/src/main/java/com/example/radhika/mdbsocials/SocialFeedAdapter.java new file mode 100644 index 0000000..af1d3fb --- /dev/null +++ b/app/src/main/java/com/example/radhika/mdbsocials/SocialFeedAdapter.java @@ -0,0 +1,86 @@ +package com.example.radhika.mdbsocials; + +import android.content.Context; +import android.content.Intent; +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.RelativeLayout; +import android.widget.TextView; + +import java.io.InputStream; +import java.net.URL; +import java.util.ArrayList; +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.animation.GlideAnimation; +import com.bumptech.glide.request.target.SimpleTarget; + +import org.w3c.dom.Text; + +/** + * Created by Radhika on 2/24/17. + * copied from pokedexadapter + */ + +public class SocialFeedAdapter extends RecyclerView.Adapter { + + private Context context; + public ArrayList socials; + + public SocialFeedAdapter(Context context, ArrayList socials) { + this.context = context; + this.socials = socials; + } + + 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(CustomViewHolder holder, int position) { + Social s = socials.get(position); + holder.hostEmailText.setText(s.getEmailAddress()); + holder.socialNameText.setText(s.getName()); + holder.numInterested.setText(s.getNumInterested() + " Interested"); + + Glide.with(context) + .load(s.getImageUrl()) + .into(holder.socialImageView); + } + + @Override + public int getItemCount() { + return socials.size(); + } + + class CustomViewHolder extends RecyclerView.ViewHolder { + TextView socialNameText, hostEmailText, numInterested; + ImageView socialImageView; + + public CustomViewHolder(View view) { + super(view); + + this.socialNameText = (TextView) view.findViewById(R.id.socialName); + this.hostEmailText = (TextView) view.findViewById(R.id.hostEmail); + this.numInterested = (TextView) view.findViewById(R.id.interested); + this.socialImageView = (ImageView) view.findViewById(R.id.socialImageView); + view.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Intent i = new Intent(context, SocialDetailsActivity.class); + i.putExtra("Social Key", SocialFeedActivity.keys.get(getAdapterPosition())); + v.getContext().startActivity(i); + } + }); + } + } + + public void updateList(ArrayList newList) + { + this.socials = newList; + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/example/radhika/mdbsocials/User.java b/app/src/main/java/com/example/radhika/mdbsocials/User.java new file mode 100644 index 0000000..d5e2e7e --- /dev/null +++ b/app/src/main/java/com/example/radhika/mdbsocials/User.java @@ -0,0 +1,49 @@ +package com.example.radhika.mdbsocials; + +/** + * Created by Radhika on 2/25/17. + */ + +public class User { + + private String name; + private String email; + private String imageUrl; + + public User () { + + } + public User(String name, String email, String imageUrl) { + this.name = name; + this.email = email; + this.imageUrl = imageUrl; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getImageUrl() { + return imageUrl; + } + + public void setImageUrl(String imageUrl) { + this.imageUrl = imageUrl; + } + @Override + public boolean equals(Object other) { + return this.getName().equals(((User)other).getName()); + } +} diff --git a/app/src/main/java/com/example/radhika/mdbsocials/Utils.java b/app/src/main/java/com/example/radhika/mdbsocials/Utils.java new file mode 100644 index 0000000..ac23683 --- /dev/null +++ b/app/src/main/java/com/example/radhika/mdbsocials/Utils.java @@ -0,0 +1,69 @@ +package com.example.radhika.mdbsocials; + +import com.google.firebase.auth.FirebaseUser; +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.database.ValueEventListener; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +/** + * Created by Radhika on 2/25/17. + */ + +public class Utils { + public static User user; + public static void update (DatabaseReference db, final User curr) { + db.runTransaction(new Transaction.Handler() { + @Override + public Transaction.Result doTransaction(MutableData mut) { + Social s = mut.getValue(Social.class); + if (s == null) + return Transaction.success(mut); + if (s.getInterested() == null) { + s.setInterested(new ArrayList()); + s.getInterested().add(curr); + s.setNumInterested(s.getNumInterested()+1); + } + else if (s.getInterested().contains(curr)) { + s.setNumInterested(s.getNumInterested()-1); + s.getInterested().remove(curr); + } else { + s.setNumInterested(s.getNumInterested()+1); + s.getInterested().add(curr); + } + mut.setValue(s); + return Transaction.success(mut); + } + @Override + public void onComplete(DatabaseError databaseError, boolean b, DataSnapshot dataSnapshot) { + + } + }); + } + public static void getUser(DatabaseReference db, FirebaseUser user) { + db.child("Users").child(user.getUid()).addValueEventListener(new ValueEventListener() { + @Override + public void onDataChange(DataSnapshot snapshot) { + Utils.user = snapshot.getValue(User.class); + } + @Override + public void onCancelled(DatabaseError firebaseError) { + } + }); + } + +// public static void addUserToDB (String name, String email, String imageUrl) { +// DatabaseReference db = FirebaseDatabase.getInstance().getReference(); +// final String key = db.child("Users").push().getKey(); +// curr = new User (name, email, imageUrl); +// db.child("Users").child(key).setValue(curr); +// } +} diff --git a/app/src/main/res/drawable/edit_text_border.xml b/app/src/main/res/drawable/edit_text_border.xml new file mode 100644 index 0000000..9ab7a3f --- /dev/null +++ b/app/src/main/res/drawable/edit_text_border.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/edit_text_border2.xml b/app/src/main/res/drawable/edit_text_border2.xml new file mode 100644 index 0000000..6133806 --- /dev/null +++ b/app/src/main/res/drawable/edit_text_border2.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/plus.jpg b/app/src/main/res/drawable/plus.jpg new file mode 100644 index 0000000..5f55216 Binary files /dev/null and b/app/src/main/res/drawable/plus.jpg differ diff --git a/app/src/main/res/layout/activity_interested_feed.xml b/app/src/main/res/layout/activity_interested_feed.xml new file mode 100644 index 0000000..8cefa7c --- /dev/null +++ b/app/src/main/res/layout/activity_interested_feed.xml @@ -0,0 +1,22 @@ + + + + + diff --git a/app/src/main/res/layout/activity_new_social.xml b/app/src/main/res/layout/activity_new_social.xml new file mode 100644 index 0000000..83ccedd --- /dev/null +++ b/app/src/main/res/layout/activity_new_social.xml @@ -0,0 +1,109 @@ + + + + + + + + + + + + + + + +