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 9b6c2554c83d8228018b9b9628a88f8c16262ffa Mon Sep 17 00:00:00 2001 From: Radhika Dhomse Date: Sat, 25 Feb 2017 23:12:54 -0800 Subject: [PATCH 2/3] Lots of bugs fam --- .gitignore | 9 + .idea/compiler.xml | 22 +++ .idea/copyright/profiles_settings.xml | 3 + .idea/gradle.xml | 19 +++ .idea/misc.xml | 46 +++++ .idea/modules.xml | 9 + .idea/runConfigurations.xml | 12 ++ .idea/vcs.xml | 6 + app/.gitignore | 1 + app/build.gradle | 40 +++++ app/google-services.json | 55 ++++++ app/proguard-rules.pro | 17 ++ .../mdbsocials/ExampleInstrumentedTest.java | 26 +++ app/src/main/AndroidManifest.xml | 30 ++++ .../mdbsocials/InterestedFeedActivity.java | 66 ++++++++ .../mdbsocials/InterestedFeedAdapter.java | 68 ++++++++ .../radhika/mdbsocials/NewSocialActivity.java | 131 ++++++++++++++ .../radhika/mdbsocials/SignInActivity.java | 95 +++++++++++ .../radhika/mdbsocials/SignUpActivity.java | 149 ++++++++++++++++ .../example/radhika/mdbsocials/Social.java | 110 ++++++++++++ .../mdbsocials/SocialDetailsActivity.java | 132 +++++++++++++++ .../mdbsocials/SocialFeedActivity.java | 93 ++++++++++ .../radhika/mdbsocials/SocialFeedAdapter.java | 86 ++++++++++ .../com/example/radhika/mdbsocials/User.java | 49 ++++++ .../com/example/radhika/mdbsocials/Utils.java | 69 ++++++++ .../main/res/drawable/edit_text_border.xml | 7 + .../main/res/drawable/edit_text_border2.xml | 7 + app/src/main/res/drawable/plus.jpg | Bin 0 -> 29667 bytes .../res/layout/activity_interested_feed.xml | 22 +++ .../main/res/layout/activity_new_social.xml | 109 ++++++++++++ app/src/main/res/layout/activity_sign_in.xml | 96 +++++++++++ app/src/main/res/layout/activity_sign_up.xml | 86 ++++++++++ .../res/layout/activity_social_details.xml | 98 +++++++++++ .../main/res/layout/activity_social_feed.xml | 77 +++++++++ .../res/layout/content_social_details.xml | 16 ++ app/src/main/res/layout/row_view.xml | 94 ++++++++++ app/src/main/res/layout/row_view_2.xml | 67 ++++++++ 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-v21/styles.xml | 9 + app/src/main/res/values-w820dp/dimens.xml | 6 + app/src/main/res/values/colors.xml | 11 ++ app/src/main/res/values/dimens.xml | 6 + app/src/main/res/values/strings.xml | 7 + app/src/main/res/values/styles.xml | 20 +++ .../radhika/mdbsocials/ExampleUnitTest.java | 17 ++ build.gradle | 23 +++ 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 + 56 files changed, 2395 insertions(+) create mode 100644 .gitignore create mode 100644 .idea/compiler.xml create mode 100644 .idea/copyright/profiles_settings.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 .idea/vcs.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/radhika/mdbsocials/ExampleInstrumentedTest.java create mode 100644 app/src/main/AndroidManifest.xml create mode 100644 app/src/main/java/com/example/radhika/mdbsocials/InterestedFeedActivity.java create mode 100644 app/src/main/java/com/example/radhika/mdbsocials/InterestedFeedAdapter.java create mode 100644 app/src/main/java/com/example/radhika/mdbsocials/NewSocialActivity.java create mode 100644 app/src/main/java/com/example/radhika/mdbsocials/SignInActivity.java create mode 100644 app/src/main/java/com/example/radhika/mdbsocials/SignUpActivity.java create mode 100644 app/src/main/java/com/example/radhika/mdbsocials/Social.java create mode 100644 app/src/main/java/com/example/radhika/mdbsocials/SocialDetailsActivity.java create mode 100644 app/src/main/java/com/example/radhika/mdbsocials/SocialFeedActivity.java create mode 100644 app/src/main/java/com/example/radhika/mdbsocials/SocialFeedAdapter.java create mode 100644 app/src/main/java/com/example/radhika/mdbsocials/User.java create mode 100644 app/src/main/java/com/example/radhika/mdbsocials/Utils.java create mode 100644 app/src/main/res/drawable/edit_text_border.xml create mode 100644 app/src/main/res/drawable/edit_text_border2.xml create mode 100644 app/src/main/res/drawable/plus.jpg create mode 100644 app/src/main/res/layout/activity_interested_feed.xml create mode 100644 app/src/main/res/layout/activity_new_social.xml create mode 100644 app/src/main/res/layout/activity_sign_in.xml create mode 100644 app/src/main/res/layout/activity_sign_up.xml create mode 100644 app/src/main/res/layout/activity_social_details.xml create mode 100644 app/src/main/res/layout/activity_social_feed.xml create mode 100644 app/src/main/res/layout/content_social_details.xml create mode 100644 app/src/main/res/layout/row_view.xml create mode 100644 app/src/main/res/layout/row_view_2.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-v21/styles.xml 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/radhika/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/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/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..c70467e --- /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); + + 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) {} + }); + recyclerView.setAdapter(adapter); + } +} 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..da26fab --- /dev/null +++ b/app/src/main/java/com/example/radhika/mdbsocials/NewSocialActivity.java @@ -0,0 +1,131 @@ +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.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.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(); + 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..dd7f520 --- /dev/null +++ b/app/src/main/java/com/example/radhika/mdbsocials/SignInActivity.java @@ -0,0 +1,95 @@ +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.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..ccb2a58 --- /dev/null +++ b/app/src/main/java/com/example/radhika/mdbsocials/SocialDetailsActivity.java @@ -0,0 +1,132 @@ +package com.example.radhika.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.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(); + 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 { + @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; + } + } + + @Override + protected void onPostExecute(Bitmap bitmap) { + if (bitmap != null) { + eventImage.setImageBitmap(bitmap); + } + super.onPostExecute(bitmap); + } + } +} 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..da79480 --- /dev/null +++ b/app/src/main/java/com/example/radhika/mdbsocials/SocialFeedActivity.java @@ -0,0 +1,93 @@ +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; + + @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); + + RecyclerView 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()); + final ArrayList socials = new ArrayList<>(); + adapter = new SocialFeedAdapter(getApplicationContext(), socials); + db.child("Socials").addValueEventListener(new ValueEventListener() { + @Override + public void onDataChange(DataSnapshot snapshot) { + 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; + adapter.notifyDataSetChanged(); + } + + @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 0000000000000000000000000000000000000000..5f55216b364df74d432b496efe372990c12a8e4f GIT binary patch literal 29667 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 literal 0 HcmV?d00001 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 @@ + + + + + + + + + + + + + + + +