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..4818a23 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/README.md b/README.md index 4a040e1..fc9599d 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,9 @@ +<<<<<<< HEAD +# mdbsocials +======= Repository for MDB Training Program Mini-Project 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. \ No newline at end of file +When pushing code to this repo, DO NOT push to master. Create a new branch and open a pull request. +>>>>>>> e4b4b334b11749aa357bd2044b075854227e9e86 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..8258679 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,44 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 24 + buildToolsVersion "24.0.2" + defaultConfig { + applicationId "com.mdb.training.katharine.mdbsocials" + minSdkVersion 14 + targetSdkVersion 24 + 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:24.2.1' + compile 'com.android.support:design:24.2.1' + compile 'com.google.firebase:firebase-core:9.6.1' + compile 'com.google.firebase:firebase-auth:9.6.1' + compile 'com.google.firebase:firebase-database:9.6.1' + compile 'com.google.firebase:firebase-storage:9.6.1' + compile 'com.android.support.constraint:constraint-layout:1.0.0-alpha8' + compile 'com.google.android.gms:play-services-auth:9.6.1' + compile 'com.google.android.gms:play-services-gcm:9.6.1' + compile 'com.android.support:recyclerview-v7:24.2.1' + compile 'com.android.support:cardview-v7:24.2.1' + compile 'com.android.support:support-v4:24.2.1' + compile 'com.github.bumptech.glide:glide:3.7.0' + compile 'com.android.support:palette-v7:24.2.1' + testCompile 'junit:junit:4.12' +} + +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..fe7e9f5 --- /dev/null +++ b/app/google-services.json @@ -0,0 +1,42 @@ +{ + "project_info": { + "project_number": "510160351055", + "firebase_url": "https://mdbsocial-app.firebaseio.com", + "project_id": "mdbsocial-app", + "storage_bucket": "mdbsocial-app.appspot.com" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:510160351055:android:5ac4a500e2a0ef22", + "android_client_info": { + "package_name": "com.mdb.training.katharine.mdbsocials" + } + }, + "oauth_client": [ + { + "client_id": "510160351055-otm9a3teg2fb2m3csmd560d0tel17nq1.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyAl5BtrHgba8PDjaq0t_7rOKnU7gydWwa4" + } + ], + "services": { + "analytics_service": { + "status": 1 + }, + "appinvite_service": { + "status": 1, + "other_platform_oauth_client": [] + }, + "ads_service": { + "status": 2 + } + } + } + ], + "configuration_version": "1" +} \ No newline at end of file diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..ee53402 --- /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/KJ/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/mdb/training/katharine/mdbsocials/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/mdb/training/katharine/mdbsocials/ExampleInstrumentedTest.java new file mode 100644 index 0000000..fc1055c --- /dev/null +++ b/app/src/androidTest/java/com/mdb/training/katharine/mdbsocials/ExampleInstrumentedTest.java @@ -0,0 +1,26 @@ +package com.mdb.training.katharine.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.mdb.training.katharine.mdbsocials", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..c77728f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/mdb/training/katharine/mdbsocials/CreateNewSocial.java b/app/src/main/java/com/mdb/training/katharine/mdbsocials/CreateNewSocial.java new file mode 100644 index 0000000..a84d89b --- /dev/null +++ b/app/src/main/java/com/mdb/training/katharine/mdbsocials/CreateNewSocial.java @@ -0,0 +1,106 @@ +package com.mdb.training.katharine.mdbsocials; + +import android.content.Intent; +import android.net.Uri; +import android.os.Bundle; +import android.provider.MediaStore; +import android.support.v7.app.AppCompatActivity; +import android.view.View; +import android.widget.Button; +import android.widget.EditText; +import android.widget.Toast; + +import com.google.firebase.auth.FirebaseAuth; +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.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +public class CreateNewSocial extends AppCompatActivity implements View.OnClickListener { + + private EditText name; + private EditText date; + private EditText description; + private Button choosePic; + private Button createSocial; + private Uri selectedImage; + + private FirebaseAuth mAuth; + private DatabaseReference mDatabase; + private StorageReference storageReference; + private String firebasePath; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_create_new_social); + + name = (EditText) findViewById(R.id.name); + date = (EditText) findViewById(R.id.date); + description = (EditText) findViewById(R.id.description); + choosePic = (Button) findViewById(R.id.pic); + createSocial = (Button) findViewById(R.id.create); + mAuth = FirebaseAuth.getInstance(); + mDatabase = FirebaseDatabase.getInstance().getReference(); + + createSocial.setOnClickListener(this); + choosePic.setOnClickListener(this); + } + + @Override + public void onClick(View view) { + switch (view.getId()) { + case R.id.create: + createSocial(); + break; + case R.id.pic: + Intent pickPhoto = new Intent(Intent.ACTION_PICK, + MediaStore.Images.Media.EXTERNAL_CONTENT_URI); + startActivityForResult(pickPhoto, 0); + break; + } + } + + protected void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent) { + super.onActivityResult(requestCode, resultCode, imageReturnedIntent); + if (resultCode == RESULT_OK && requestCode==0) { + int numSocials = getIntent().getExtras().getInt("numSocials") + 1; + firebasePath = "socialPics/" + numSocials + ".jpg"; + StorageReference storageRef = FirebaseStorage.getInstance() + .getReference().child(firebasePath); + selectedImage = imageReturnedIntent.getData(); + UploadTask uploadTask = storageRef.putFile(selectedImage); + } + } + + /* Creates a social and returns to the FeedActivity after creation */ + public void createSocial() { + String n = name.getText().toString(); + String d = date.getText().toString(); + String descrip = description.getText().toString(); + String author = mAuth.getCurrentUser().getEmail(); + ArrayList interested = new ArrayList<>(); + Map post = new HashMap<>(); + post.put("name", n); + post.put("author", author); + post.put("description", descrip); + post.put("date", d); + post.put("interested", interested); + post.put("path", firebasePath); + if (n.length() == 0 || d.length() == 0 || descrip.length() == 0 + || firebasePath.length() == 0) { + Toast.makeText(getApplicationContext(), "Social not created. Please fill in all " + + "fields and upload a picture.", Toast.LENGTH_LONG).show(); + } else { + mDatabase.child("Socials").push().setValue(post); + Toast.makeText(getApplicationContext(), "Social created.", Toast.LENGTH_SHORT).show(); + startActivity(new Intent(this, FeedActivity.class)); + } + + } +} diff --git a/app/src/main/java/com/mdb/training/katharine/mdbsocials/DetailsActivity.java b/app/src/main/java/com/mdb/training/katharine/mdbsocials/DetailsActivity.java new file mode 100644 index 0000000..0d5ed77 --- /dev/null +++ b/app/src/main/java/com/mdb/training/katharine/mdbsocials/DetailsActivity.java @@ -0,0 +1,319 @@ +package com.mdb.training.katharine.mdbsocials; + +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.v7.app.AppCompatActivity; +import android.support.v7.graphics.Palette; +import android.support.v7.widget.Toolbar; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.widget.Button; +import android.widget.CheckBox; +import android.widget.ImageView; +import android.widget.TextView; + +import com.google.android.gms.tasks.OnSuccessListener; +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 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; +import java.util.ArrayList; +import java.util.HashMap; + +public class DetailsActivity extends AppCompatActivity implements View.OnClickListener { + + private TextView eventName, date, author, description; + private Button numInterested; + private int numInt; + private ImageView eventPic; + private CheckBox interested; + private String uid; + private Toolbar toolbar; + private ArrayList interestedNames; + private ArrayList interestedEmails; + private ArrayList interestedUids; + public int color; + public Bitmap bitmap; + public android.app.ActionBar actionbar; + + private DatabaseReference dbRef; + private FirebaseAuth mAuth; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_details); + toolbar = (Toolbar) findViewById(R.id.toolbar); + setSupportActionBar(toolbar); + actionbar = getActionBar(); + + dbRef = FirebaseDatabase.getInstance().getReference(); + mAuth = FirebaseAuth.getInstance(); + uid = FirebaseAuth.getInstance().getCurrentUser().getUid(); + interestedNames = new ArrayList<>(); + interestedEmails = new ArrayList<>(); + interestedUids = new ArrayList<>(); + eventPic = (ImageView) findViewById(R.id.picture); + + /* Async task */ + StorageReference storageRef = FirebaseStorage.getInstance().getReference() + .child(getIntent().getExtras().getString("firebasePath")); + storageRef.getDownloadUrl().addOnSuccessListener(new OnSuccessListener() { + @Override + public void onSuccess(final Uri downloadUrl) { + + AsyncTask asyncTask = new AsyncTask() { + + @Override + protected Bitmap doInBackground(Void... params) { + return getBitmapFromURL(downloadUrl.toString()); + } + + public Bitmap getBitmapFromURL(String src) { + try { + URL url = new URL(src); + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setDoInput(true); + connection.connect(); + InputStream input = connection.getInputStream(); + bitmap = BitmapFactory.decodeStream(input); + return bitmap; + } catch (IOException e) { + // Log exception + return null; + } + } + + @Override + protected void onPostExecute(Bitmap result) { + eventPic.setImageBitmap(result); + Palette.from(result).generate(new Palette.PaletteAsyncListener() { + public void onGenerated(Palette p) { + Palette.Swatch vibrant = p.getVibrantSwatch(); + if (vibrant != null) { + // Set the background color of a layout based on color + getWindow().getDecorView().setBackgroundColor(vibrant.getRgb()); + } + } + }); + + } + }.execute(); + } + + }); + + setData(); + checkInterestedBox(); + } + + /* Gets and sets data from intents passed from FeedActivity */ + public void setData() { + eventName = (TextView) findViewById(R.id.eventName); + eventName.setText(getIntent().getExtras().getString("title")); + + date = (TextView) findViewById(R.id.textView); + date.setText("Date: " + getIntent().getExtras().getString("date")); + + author = (TextView) findViewById(R.id.textView2); + author.setText("Created by: " + getIntent().getExtras().getString("author")); + + description = (TextView) findViewById(R.id.textView3); + description.setText("Event details: " + getIntent().getExtras().getString("description")); + + numInterested = (Button) findViewById(R.id.button); + numInt = getIntent().getExtras().getInt("interested"); + numInterested.setText("Interested: " + numInt); + numInterested.setOnClickListener(this); + + interested = (CheckBox) findViewById(R.id.interested); + + } + + /* * Checks if current user is interested in current social + * Sets interestedUids to initial list of interested users + */ + public void checkInterestedBox() { + dbRef.child("Socials").addValueEventListener(new ValueEventListener() { + @Override + public void onDataChange(DataSnapshot dataSnapshot) { + for(DataSnapshot dsp: dataSnapshot.getChildren()) { + HashMap map = (HashMap) dsp.getValue(); + ArrayList interestedList = (ArrayList) map.get("interested"); + if(interestedList == null){ + interestedList = new ArrayList(); + } + if(map.get("name").equals(eventName.getText().toString())){ + if(interestedList.contains(uid)) { + interested.setChecked(true); + } + interestedUids = interestedList; + } + } + } + + @Override + public void onCancelled(DatabaseError databaseError) { + + } + }); + } + + /* Handles pressing the Interested people button */ + @Override + public void onClick(View view) { + switch (view.getId()) { + /* If the Interested button is clicked, put all the interested people and their + emails in intents and send to InterestedActivity */ + case R.id.button: + dbRef.child("Users").addValueEventListener(new ValueEventListener() { + @Override + public void onDataChange(DataSnapshot dataSnapshot) { + interestedNames = new ArrayList(); + interestedEmails = new ArrayList(); + for (DataSnapshot dsp: dataSnapshot.getChildren()) { + HashMap map = (HashMap) dsp.getValue(); + if (interestedUids.contains(map.get("uid"))) { + interestedNames.add((String) map.get("name")); + interestedEmails.add((String) map.get("email")); + } + } + Intent intent = new Intent(DetailsActivity.this, InterestedActivity.class); + intent.putExtra("interestedName", interestedNames); + intent.putExtra("interestedEmail", interestedEmails); + startActivity(intent); + } + + @Override + public void onCancelled(DatabaseError databaseError) { + + } + }); + break; + } + } + + /* * Handles checking and unchecking the interested box + * * Updates the number of interested people when you check/uncheck */ + public void onCheckboxClicked(View view) { + // Is the view now checked? + boolean checked = ((CheckBox) view).isChecked(); + // Check which checkbox was clicked + switch(view.getId()) { + case R.id.interested: + if (checked) { + checkInterested(); + } else { + uncheckInterested(); + } + break; + } + } + + /* Helper function for when a user checks the interested box */ + public void checkInterested() { + dbRef.child("Socials").addListenerForSingleValueEvent(new ValueEventListener() { + @Override + public void onDataChange(DataSnapshot dataSnapshot) { + for (DataSnapshot dsp: dataSnapshot.getChildren()) { + HashMap map = (HashMap) dsp.getValue(); + // list of interested people for the current social + ArrayList interestedList = (ArrayList) map.get("interested"); + if (interestedList == null) { + interestedList = new ArrayList(); + } + /* If the social's name matches the current social's name and the + current user is not already included in interestedList, + add the current user's uid to the social's list of interested users */ + if (map.get("name").equals(eventName.getText().toString()) && + !interestedList.contains(uid)) { + interestedList.add(uid); + dbRef.child("Socials").child(dsp.getKey()).child("interested") + .setValue(interestedList); + numInt += 1; + numInterested.setText("Interested: " + numInt); + } + } + } + + @Override + public void onCancelled(DatabaseError databaseError) { + + } + }); + } + + /* Helper function for when a user unchecks the interested box */ + public void uncheckInterested() { + dbRef.child("Socials").addListenerForSingleValueEvent(new ValueEventListener() { + @Override + public void onDataChange(DataSnapshot dataSnapshot) { + for (DataSnapshot dsp: dataSnapshot.getChildren()) { + HashMap map = (HashMap) dsp.getValue(); + ArrayList interestedList = (ArrayList) map.get("interested"); + if (interestedList == null) { + interestedList = new ArrayList(); + } + /* If the social's name == current social's name and + current user is in interestedList, + remove the current user's uid from interestedList */ + if (map.get("name").equals(eventName.getText().toString()) && + interestedList.contains(uid)) { + interestedList.remove(uid); + dbRef.child("Socials").child(dsp.getKey()).child("interested") + .setValue(interestedList); + numInt -= 1; + numInterested.setText("Interested: " + numInt); + } + } + } + + @Override + public void onCancelled(DatabaseError databaseError) { + + } + }); + + } + + /* When a user presses back, recycle to fix memory issues */ + public void onBackPressed(){ + bitmap.recycle(); + bitmap=null; + super.onBackPressed(); + } + + /* Inflates menu bar */ + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.activity_details, menu); + return super.onCreateOptionsMenu(menu); + } + + /* Handles logout from menu bar */ + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.logout: + FirebaseUtils fb = new FirebaseUtils(mAuth); + fb.signOut(); + startActivity(new Intent(this, MainActivity.class)); + } + return super.onOptionsItemSelected(item); + } + +} diff --git a/app/src/main/java/com/mdb/training/katharine/mdbsocials/FeedActivity.java b/app/src/main/java/com/mdb/training/katharine/mdbsocials/FeedActivity.java new file mode 100644 index 0000000..4ec24a3 --- /dev/null +++ b/app/src/main/java/com/mdb/training/katharine/mdbsocials/FeedActivity.java @@ -0,0 +1,115 @@ +package com.mdb.training.katharine.mdbsocials; + +import android.content.Intent; +import android.os.Bundle; +import android.support.design.widget.FloatingActionButton; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.util.Log; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.widget.Toast; + +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.HashMap; + +public class FeedActivity extends AppCompatActivity implements View.OnClickListener { + + private FirebaseAuth mAuth; + private RecyclerView rv; + public FeedAdapter adapter; + public ArrayList socials; // list of total socials + private FloatingActionButton createSocial; + private DatabaseReference mDatabase; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_feed); + + socials = new ArrayList(); + createSocial = (FloatingActionButton) findViewById(R.id.createSocial); + mDatabase = FirebaseDatabase.getInstance().getReference(); + mAuth = FirebaseAuth.getInstance(); + + rv = (RecyclerView) findViewById(R.id.rv); + rv.setLayoutManager(new LinearLayoutManager(this)); + adapter = new FeedAdapter(getApplicationContext(), socials); + rv.setAdapter(adapter); + + /* Render the list of socials on the screen */ + mDatabase.child("Socials").addValueEventListener(new ValueEventListener() { + @Override + public void onDataChange(DataSnapshot dataSnapshot) { + socials = new ArrayList(); + for(DataSnapshot dsp: dataSnapshot.getChildren()){ + HashMap map = (HashMap) dsp.getValue(); + String name = (String) map.get("name"); + String author = (String) map.get("author"); + String description = (String) map.get("description"); + String date = (String) map.get("date"); + String firebasePath = (String) map.get("path"); + ArrayList interested = (ArrayList) map.get("interested"); + if(interested == null){ + interested = new ArrayList(); + } + SocialsList.Social social = new SocialsList.Social(name, author, description, + date, firebasePath); + social.setInterested(interested); + socials.add(social); + } + adapter.setSocials(socials); + rv.setAdapter(adapter); + } + + @Override + public void onCancelled(DatabaseError databaseError) { + Log.w("TAG", "loadPost:onCancelled", databaseError.toException()); + } + + }); + + createSocial.setOnClickListener(this); + + } + + @Override + public void onClick(View view) { + switch (view.getId()) { + case R.id.createSocial: + Intent intent = new Intent(FeedActivity.this, CreateNewSocial.class); + intent.putExtra("numSocials", socials.size()); + startActivity(intent); + break; + } + } + + /* Sets menu bar with logout */ + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.activity_details, menu); + return super.onCreateOptionsMenu(menu); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.logout: + FirebaseUtils fb = new FirebaseUtils(mAuth); + fb.signOut(); + startActivity(new Intent(this, MainActivity.class)); + break; + } + return super.onOptionsItemSelected(item); + } + +} diff --git a/app/src/main/java/com/mdb/training/katharine/mdbsocials/FeedAdapter.java b/app/src/main/java/com/mdb/training/katharine/mdbsocials/FeedAdapter.java new file mode 100644 index 0000000..3835738 --- /dev/null +++ b/app/src/main/java/com/mdb/training/katharine/mdbsocials/FeedAdapter.java @@ -0,0 +1,149 @@ +package com.mdb.training.katharine.mdbsocials; + +import android.content.Context; +import android.content.Intent; +import android.net.Uri; +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.OnSuccessListener; +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.util.ArrayList; +import java.util.HashMap; + +import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; + +/** + * Created by KJ on 10/4/16. + */ + +public class FeedAdapter extends RecyclerView.Adapter { + + private Context context; + private ArrayList socials = new ArrayList<>(); + private DatabaseReference mDatabase = FirebaseDatabase.getInstance().getReference();; + + + public FeedAdapter(Context context, ArrayList socials) { + this.context = context; + this.socials = socials; + } + + public void setSocials(ArrayList socials) { + this.socials = socials; + } + + @Override + public int getItemCount() { + return socials.size(); + } + + @Override + public CustomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + View view; + view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_view, parent, false); + return new CustomViewHolder(view); + } + + @Override + public void onBindViewHolder(final CustomViewHolder holder, int position) { + SocialsList.Social social = socials.get(position); + holder.titleView.setText(social.title); + holder.authorView.setText(social.author); + if(social.interested == null){ + social.interested = new ArrayList<>(); + } + + holder.numinterestedView.setText(Integer.toString(social.interested.size())); + + StorageReference storageRef = FirebaseStorage.getInstance().getReference() + .child(socials.get(position).firebasePath); + storageRef.getDownloadUrl().addOnSuccessListener(new OnSuccessListener() + { + @Override + public void onSuccess(Uri downloadUrl) + { + Glide.with(context).load(downloadUrl).into(holder.imageView); + } + + }); + + } + + class CustomViewHolder extends RecyclerView.ViewHolder { + TextView titleView; + ImageView imageView; + TextView authorView; + TextView numinterestedView; + ArrayList interestedName = new ArrayList(); + ArrayList interestedEmail = new ArrayList(); + String firebasePath; + + public CustomViewHolder (View view) { + super(view); + this.titleView = (TextView) view.findViewById(R.id.title); + this.imageView = (ImageView) view.findViewById(R.id.eventpic); + this.authorView = (TextView) view.findViewById(R.id.author); + this.numinterestedView = (TextView) view.findViewById(R.id.number); + + view.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + /*Get adapter position is getting the number of the row that was clicked, + starting at 0 + */ + final SocialsList.Social s = socials.get(getAdapterPosition()); + Intent intent = new Intent(context, DetailsActivity.class); + + ValueEventListener postListener = new ValueEventListener() { + @Override + public void onDataChange(DataSnapshot dataSnapshot) { + ArrayList interested = s.getInterested(); + for (DataSnapshot dsp: dataSnapshot.getChildren()) { + HashMap map = + (HashMap) dsp.getValue(); + if (interested.contains(map.get("uid"))) { + String name = (String) map.get("name"); + String email = (String) map.get("email"); + interestedName.add(name); + interestedEmail.add(email); + } + } + } + @Override + public void onCancelled(DatabaseError databaseError) { + Log.w("TAG", "loadPost:onCancelled", databaseError.toException()); + } + + }; + mDatabase.child("Users").addValueEventListener(postListener); + + intent.putExtra("title", s.title); + intent.putExtra("author", s.author); + intent.putExtra("description", s.description); + intent.putExtra("date", s.date); + intent.putExtra("interested", s.interested.size()); + intent.putExtra("firebasePath", s.firebasePath); + + intent.putStringArrayListExtra("interestedName", interestedName); + intent.putStringArrayListExtra("interestedEmail", interestedEmail); + intent.addFlags(FLAG_ACTIVITY_NEW_TASK); + context.startActivity(intent); + } + }); + } + } +} diff --git a/app/src/main/java/com/mdb/training/katharine/mdbsocials/FirebaseUtils.java b/app/src/main/java/com/mdb/training/katharine/mdbsocials/FirebaseUtils.java new file mode 100644 index 0000000..a90a77a --- /dev/null +++ b/app/src/main/java/com/mdb/training/katharine/mdbsocials/FirebaseUtils.java @@ -0,0 +1,44 @@ +package com.mdb.training.katharine.mdbsocials; + +import android.content.Context; +import android.content.Intent; +import android.support.annotation.NonNull; +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; + +/** + * Created by KJ on 10/21/16. + */ + +public class FirebaseUtils { + + private FirebaseAuth mAuth; + + public FirebaseUtils(FirebaseAuth mAuth) { + this.mAuth = mAuth; + } + + public void signIn(final Context context, String email, String pass) { + if(email.length()==0 || pass.length()==0){ + Toast.makeText(context, "Sign in problem", Toast.LENGTH_LONG).show(); + return; + } + mAuth.signInWithEmailAndPassword(email, pass) + .addOnCompleteListener(new OnCompleteListener() { + @Override + public void onComplete(@NonNull Task task) { + if (!task.isSuccessful()) { + Toast.makeText(context, "Sign in problem", Toast.LENGTH_LONG).show(); + } + } + }); + } + + public void signOut() { + mAuth.signOut(); + } +} diff --git a/app/src/main/java/com/mdb/training/katharine/mdbsocials/InterestedActivity.java b/app/src/main/java/com/mdb/training/katharine/mdbsocials/InterestedActivity.java new file mode 100644 index 0000000..34c3e8a --- /dev/null +++ b/app/src/main/java/com/mdb/training/katharine/mdbsocials/InterestedActivity.java @@ -0,0 +1,55 @@ +package com.mdb.training.katharine.mdbsocials; + +import android.content.Intent; +import android.os.Bundle; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.view.Menu; +import android.view.MenuItem; + +import com.google.firebase.auth.FirebaseAuth; + +import java.util.ArrayList; + +public class InterestedActivity extends AppCompatActivity { + private ArrayList interestedNames; + private ArrayList interestedEmails; + private FirebaseAuth mAuth; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_interested); + + RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerView); + recyclerView.setLayoutManager(new LinearLayoutManager(this)); + + interestedNames = getIntent().getStringArrayListExtra("interestedName"); + interestedEmails = getIntent().getStringArrayListExtra("interestedEmail"); + + InterestedAdapter interestedAdapter = new InterestedAdapter(getApplicationContext(), + interestedNames, interestedEmails); + + recyclerView.setAdapter(interestedAdapter); + + mAuth = FirebaseAuth.getInstance(); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.activity_details, menu); + return super.onCreateOptionsMenu(menu); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.logout: + FirebaseUtils fb = new FirebaseUtils(mAuth); + fb.signOut(); + startActivity(new Intent(this, MainActivity.class)); + } + return super.onOptionsItemSelected(item); + } +} diff --git a/app/src/main/java/com/mdb/training/katharine/mdbsocials/InterestedAdapter.java b/app/src/main/java/com/mdb/training/katharine/mdbsocials/InterestedAdapter.java new file mode 100644 index 0000000..f5cbba9 --- /dev/null +++ b/app/src/main/java/com/mdb/training/katharine/mdbsocials/InterestedAdapter.java @@ -0,0 +1,55 @@ +package com.mdb.training.katharine.mdbsocials; + +import android.content.Context; +import android.support.annotation.NonNull; +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import java.util.ArrayList; + +/** + * Created by victorsun on 10/5/16. + */ + +public class InterestedAdapter extends RecyclerView.Adapter { + + private Context context; + public ArrayList names; + public ArrayList emails; + + public InterestedAdapter(Context context, @NonNull ArrayList interestedName, + @NonNull ArrayList interestedEmail) { + this.context = context; + names = interestedName; + emails = interestedEmail; + } + + @Override + public CustomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_view_members, + parent, false); + return new CustomViewHolder(view); + } + + @Override + public void onBindViewHolder(CustomViewHolder holder, int position) { + holder.name.setText(names.get(position)); + holder.email.setText(emails.get(position)); + } + + public int getItemCount() { + return names.size(); + } + + class CustomViewHolder extends RecyclerView.ViewHolder { + TextView name, email; + public CustomViewHolder(View view) { + super(view); + this.name = (TextView) view.findViewById(R.id.name); + this.email = (TextView) view.findViewById(R.id.email); + } + } +} diff --git a/app/src/main/java/com/mdb/training/katharine/mdbsocials/MainActivity.java b/app/src/main/java/com/mdb/training/katharine/mdbsocials/MainActivity.java new file mode 100644 index 0000000..772d87e --- /dev/null +++ b/app/src/main/java/com/mdb/training/katharine/mdbsocials/MainActivity.java @@ -0,0 +1,88 @@ +package com.mdb.training.katharine.mdbsocials; + +import android.content.Intent; +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.v7.app.AppCompatActivity; +import android.view.View; +import android.widget.Button; +import android.widget.EditText; +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; + +public class MainActivity extends AppCompatActivity implements View.OnClickListener { + + private FirebaseAuth mAuth; + private FirebaseAuth.AuthStateListener mAuthListener; + private FirebaseUser user; + + private EditText email; + private EditText password; + private Button login; + private TextView signup; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + + email = (EditText) findViewById(R.id.email); + password = (EditText) findViewById(R.id.password); + login = (Button) findViewById(R.id.login); + signup = (TextView) findViewById(R.id.signup); + + mAuth = FirebaseAuth.getInstance(); + mAuthListener = new FirebaseAuth.AuthStateListener() { + @Override + public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) { + user = firebaseAuth.getCurrentUser(); + // If user is already signed in, go to the feed activity + if (user != null) { + startActivity(new Intent(MainActivity.this, FeedActivity.class)); + } + } + }; + + login.setOnClickListener(this); + signup.setOnClickListener(this); + + } + + @Override + public void onClick(View view) { + switch (view.getId()) { + case R.id.login: signIn(); + break; + case R.id.signup: startActivity(new Intent(MainActivity.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); + } + } + + private void signIn() { + String em = email.getText().toString(); + String pass = password.getText().toString(); + FirebaseUtils fb = new FirebaseUtils(mAuth); + fb.signIn(this, em, pass); + } + +} diff --git a/app/src/main/java/com/mdb/training/katharine/mdbsocials/SignupActivity.java b/app/src/main/java/com/mdb/training/katharine/mdbsocials/SignupActivity.java new file mode 100644 index 0000000..9831bf2 --- /dev/null +++ b/app/src/main/java/com/mdb/training/katharine/mdbsocials/SignupActivity.java @@ -0,0 +1,86 @@ +package com.mdb.training.katharine.mdbsocials; + +import android.content.Intent; +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.v7.app.AppCompatActivity; +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.database.DatabaseReference; +import com.google.firebase.database.FirebaseDatabase; + +import java.util.HashMap; +import java.util.Map; + +public class SignupActivity extends AppCompatActivity { + + private EditText name; + private EditText email; + private EditText password; + private Button signup; + + private FirebaseAuth mAuth; + + private DatabaseReference mDatabase; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_signup); + + name = (EditText) findViewById(R.id.name); + email = (EditText) findViewById(R.id.email); + password = (EditText) findViewById(R.id.password); + signup = (Button) findViewById(R.id.signup); + + mAuth = FirebaseAuth.getInstance(); + mDatabase = FirebaseDatabase.getInstance().getReference(); + + signup.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + signup(); + } + }); + } + + private void signup() { + final String n = name.getText().toString(); + final String em = email.getText().toString(); + String pass = password.getText().toString(); + + if(n.length()==0 || em.length()==0 || password.length()==0){ + Toast.makeText(SignupActivity.this, "Sign up failed, please fill in all blanks.", + Toast.LENGTH_LONG).show(); + return; + } + final User user = new User(n, em); + mAuth.createUserWithEmailAndPassword(em, pass) + .addOnCompleteListener(this, new OnCompleteListener() { + @Override + public void onComplete(@NonNull Task task) { + if (task.isSuccessful()) { + String uid = mAuth.getCurrentUser().getUid(); + Map post = new HashMap<>(); + post.put("uid", uid); + post.put("name", n); + post.put("email", em); + mDatabase.child("Users").push().setValue(post); + startActivity(new Intent(SignupActivity.this, FeedActivity.class)); + } else if (!(task.isSuccessful())) { + Toast.makeText(SignupActivity.this, "Sign up problem", + Toast.LENGTH_LONG).show(); + } + } + }); + + } + +} diff --git a/app/src/main/java/com/mdb/training/katharine/mdbsocials/SocialsList.java b/app/src/main/java/com/mdb/training/katharine/mdbsocials/SocialsList.java new file mode 100644 index 0000000..c47f3a4 --- /dev/null +++ b/app/src/main/java/com/mdb/training/katharine/mdbsocials/SocialsList.java @@ -0,0 +1,59 @@ +package com.mdb.training.katharine.mdbsocials; + +import java.util.ArrayList; + +/** + * Created by KJ on 10/4/16. + */ + +public class SocialsList { + + public ArrayList socials; + + public SocialsList() { + socials = new ArrayList<>(); + } + + public void addSocial(String title, String author, String descrip, String date, String firebasePath) { + Social social = new Social(title, author, descrip, date, firebasePath); + socials.add(social); + } + + public ArrayList getSocials() { + return socials; + } + + + public static class Social { + public String title; + public String author; + public String description; + public ArrayList interested; + public String date; + public String firebasePath; + + public Social(String title, String author, String description, String date, String firebasePath) { + this.title = title; + this.author = author; + this.description = description; + this.date = date; + this.firebasePath = firebasePath; + this.interested = new ArrayList<>(); + } + + public void setInterested(ArrayList list) { + interested = list; + } + + public void addInterested(String uid) { + interested.add(uid); + } + + public ArrayList getInterested(){ + return interested; + } + } + + + +} diff --git a/app/src/main/java/com/mdb/training/katharine/mdbsocials/SplashActivity.java b/app/src/main/java/com/mdb/training/katharine/mdbsocials/SplashActivity.java new file mode 100644 index 0000000..6f7a114 --- /dev/null +++ b/app/src/main/java/com/mdb/training/katharine/mdbsocials/SplashActivity.java @@ -0,0 +1,18 @@ +package com.mdb.training.katharine.mdbsocials; + +import android.content.Intent; +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; + +public class SplashActivity extends AppCompatActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_splash); + + Intent intent = new Intent(this, MainActivity.class); + startActivity(intent); + finish(); + } +} diff --git a/app/src/main/java/com/mdb/training/katharine/mdbsocials/User.java b/app/src/main/java/com/mdb/training/katharine/mdbsocials/User.java new file mode 100644 index 0000000..a64d22d --- /dev/null +++ b/app/src/main/java/com/mdb/training/katharine/mdbsocials/User.java @@ -0,0 +1,22 @@ +package com.mdb.training.katharine.mdbsocials; + +/** + * Created by KJ on 10/4/16. + */ + +public class User { + + public String name; + public String email; + //public String password; + + public User() { + + } + + public User(String name, String email) { + this.name = name; + this.email = email; +// this.password = password; + } +} diff --git a/app/src/main/res/drawable/mdblogo.png b/app/src/main/res/drawable/mdblogo.png new file mode 100644 index 0000000..566ae01 Binary files /dev/null and b/app/src/main/res/drawable/mdblogo.png differ diff --git a/app/src/main/res/drawable/splashscreen.xml b/app/src/main/res/drawable/splashscreen.xml new file mode 100644 index 0000000..325530e --- /dev/null +++ b/app/src/main/res/drawable/splashscreen.xml @@ -0,0 +1,13 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_create_new_social.xml b/app/src/main/res/layout/activity_create_new_social.xml new file mode 100644 index 0000000..efea513 --- /dev/null +++ b/app/src/main/res/layout/activity_create_new_social.xml @@ -0,0 +1,110 @@ + + + + + +