diff --git a/app/build.gradle b/app/build.gradle index 0a2a308..6f6c4f9 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,12 +1,12 @@ apply plugin: 'com.android.application' android { - compileSdkVersion 24 - buildToolsVersion "24.0.3" + compileSdkVersion 25 + buildToolsVersion "25.0.0" defaultConfig { applicationId "me.kevinkang.timecapsule" minSdkVersion 21 - targetSdkVersion 24 + targetSdkVersion 25 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" @@ -24,14 +24,14 @@ dependencies { 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.google.firebase:firebase-auth:9.6.1' - compile 'com.google.android.gms:play-services-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:design:24.2.1' + compile 'com.android.support:appcompat-v7:25.0.0' + compile 'com.android.support:design:25.0.0' compile 'de.hdodenhof:circleimageview:2.0.0' compile 'com.afollestad.material-dialogs:core:0.9.0.2' + compile 'com.google.firebase:firebase-auth:9.6.0' + compile 'com.google.android.gms:play-services-auth:9.6.0' + compile 'com.google.firebase:firebase-database:9.6.0' + compile 'com.google.firebase:firebase-storage:9.6.0' testCompile 'junit:junit:4.12' } diff --git a/app/src/main/java/me/kevinkang/timecapsule/Validator.java b/app/src/main/java/me/kevinkang/timecapsule/Validator.java new file mode 100644 index 0000000..b827b51 --- /dev/null +++ b/app/src/main/java/me/kevinkang/timecapsule/Validator.java @@ -0,0 +1,8 @@ +package me.kevinkang.timecapsule; + +/** + * Created by Ethan on 10/23/2016. + */ + +public class Validator { +} diff --git a/app/src/main/java/me/kevinkang/timecapsule/activities/MainActivity.java b/app/src/main/java/me/kevinkang/timecapsule/activities/MainActivity.java index 15dd168..031fa43 100644 --- a/app/src/main/java/me/kevinkang/timecapsule/activities/MainActivity.java +++ b/app/src/main/java/me/kevinkang/timecapsule/activities/MainActivity.java @@ -8,15 +8,18 @@ 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.View; import java.util.ArrayList; import java.util.List; import me.kevinkang.timecapsule.R; +import me.kevinkang.timecapsule.data.CurrentUser; import me.kevinkang.timecapsule.data.firebase.TimeCapsuleUser; import me.kevinkang.timecapsule.data.mock.MockCapsule; import me.kevinkang.timecapsule.data.models.Capsule; +import me.kevinkang.timecapsule.data.models.User; public class MainActivity extends AppCompatActivity { @@ -24,7 +27,7 @@ public class MainActivity extends AppCompatActivity { private SwipeRefreshLayout swipeRefreshLayout; private LinearLayoutManager layoutManager; private CapsuleAdapter capsuleAdapter; - private TimeCapsuleUser capsuleUser; + private User capsuleUser; @Override protected void onCreate(Bundle savedInstanceState) { @@ -35,15 +38,10 @@ protected void onCreate(Bundle savedInstanceState) { layoutManager = new LinearLayoutManager(this); recyclerView.setLayoutManager(layoutManager); - List capsuleList = new ArrayList<>(); + capsuleUser = CurrentUser.getInstance(); - for(int i = 0; i < 10; i++){ - capsuleList.add(new MockCapsule()); - } - - capsuleAdapter = new CapsuleAdapter(capsuleList); + capsuleAdapter = new CapsuleAdapter(capsuleUser.getCapsules()); recyclerView.setAdapter(capsuleAdapter); - capsuleUser = new TimeCapsuleUser(); FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab); fab.setOnClickListener(new View.OnClickListener() { @@ -59,4 +57,12 @@ public void onCapsuleClick(View view){ Intent mainIntent = new Intent(this, CapsuleDetailActivity.class); this.startActivity(mainIntent); } + + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + // Inflate the menu; this adds items to the action bar if it is present. + getMenuInflater().inflate(R.menu.menu_main_activity, menu); + return true; + } } diff --git a/app/src/main/java/me/kevinkang/timecapsule/activities/NewCapsuleActivity.java b/app/src/main/java/me/kevinkang/timecapsule/activities/NewCapsuleActivity.java index 676e736..31196e0 100644 --- a/app/src/main/java/me/kevinkang/timecapsule/activities/NewCapsuleActivity.java +++ b/app/src/main/java/me/kevinkang/timecapsule/activities/NewCapsuleActivity.java @@ -14,7 +14,6 @@ import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.view.LayoutInflater; -import android.view.View; import android.widget.EditText; import com.afollestad.materialdialogs.DialogAction; @@ -25,9 +24,6 @@ import com.google.firebase.database.FirebaseDatabase; import java.io.File; -import java.io.FileNotFoundException; -import java.io.InputStream; -import java.net.URI; import java.net.URLConnection; import java.util.ArrayList; import java.util.HashMap; @@ -36,7 +32,6 @@ import java.util.UUID; import me.kevinkang.timecapsule.R; -import me.kevinkang.timecapsule.data.firebase.FbUser; import me.kevinkang.timecapsule.data.firebase.FirebaseAttachment; import me.kevinkang.timecapsule.data.firebase.FirebaseCapsule; import me.kevinkang.timecapsule.data.firebase.FirebaseCapsuleRecipient; @@ -46,7 +41,6 @@ public class NewCapsuleActivity extends AppCompatActivity { private static final int PICK_IMAGE = 24; private static final int PICKFILE_REQUEST_CODE = 12; // TODO: retrieve uid to get user - private FbUser user; private static final String TAG = "NewCapsuleActivity"; List recipients; diff --git a/app/src/main/java/me/kevinkang/timecapsule/data/CurrentUser.java b/app/src/main/java/me/kevinkang/timecapsule/data/CurrentUser.java new file mode 100644 index 0000000..1c8192c --- /dev/null +++ b/app/src/main/java/me/kevinkang/timecapsule/data/CurrentUser.java @@ -0,0 +1,15 @@ +package me.kevinkang.timecapsule.data; + +import me.kevinkang.timecapsule.data.firebase.TimeCapsuleUser; +import me.kevinkang.timecapsule.data.models.User; + +/** + * Created by Ethan on 10/23/2016. + */ + +public class CurrentUser { + + public static User getInstance(){ + return TimeCapsuleUser.getCurrentUser(); + } +} diff --git a/app/src/main/java/me/kevinkang/timecapsule/data/firebase/FbUser.java b/app/src/main/java/me/kevinkang/timecapsule/data/firebase/FbUser.java deleted file mode 100644 index ec6da9d..0000000 --- a/app/src/main/java/me/kevinkang/timecapsule/data/firebase/FbUser.java +++ /dev/null @@ -1,38 +0,0 @@ -package me.kevinkang.timecapsule.data.firebase; - -import java.util.Set; -import java.util.TreeSet; - -import me.kevinkang.timecapsule.data.models.User; - -/** - * Created by Work on 10/15/2016. - */ - -public class FbUser implements User { - - private String name; - private TreeSet capsules; - - public FbUser() { - this.capsules = new TreeSet<>(); - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - @Override - public void addCapsules(FirebaseCapsule capsule) { - capsules.add(capsule); - } - - @Override - public Set getCapsules() { - return capsules; - } -} diff --git a/app/src/main/java/me/kevinkang/timecapsule/data/firebase/FirebaseCapsule.java b/app/src/main/java/me/kevinkang/timecapsule/data/firebase/FirebaseCapsule.java index 7ec98b4..c539aaa 100644 --- a/app/src/main/java/me/kevinkang/timecapsule/data/firebase/FirebaseCapsule.java +++ b/app/src/main/java/me/kevinkang/timecapsule/data/firebase/FirebaseCapsule.java @@ -2,7 +2,6 @@ import android.util.Log; -import com.google.firebase.database.ChildEventListener; import com.google.firebase.database.DataSnapshot; import com.google.firebase.database.DatabaseError; import com.google.firebase.database.DatabaseReference; @@ -22,6 +21,7 @@ */ public class FirebaseCapsule extends Capsule implements Comparable { + private static final String LOG_TAG = FirebaseCapsule.class.getSimpleName(); private UUID id = null; private String name; private String message; @@ -29,7 +29,7 @@ public class FirebaseCapsule extends Capsule implements Comparable recipients; private List attachments; - private boolean hidden; + private boolean isHidden; private DatabaseReference mDatabase; /** @@ -49,8 +49,8 @@ private FirebaseCapsule(String name, long openDate, List recipients) this.openDate = openDate; this.creationDate = System.currentTimeMillis(); this.recipients = recipients; - attachments = new ArrayList(); - hidden = false; + attachments = new ArrayList<>(); + isHidden = false; mDatabase = FirebaseDatabase.getInstance().getReference(); } @@ -101,34 +101,14 @@ public FirebaseCapsule(String name, long openDate, List recipients, S this.attachments.addAll(attachments); } - public FirebaseCapsule(final String key) { + public FirebaseCapsule(String key) { mDatabase = FirebaseDatabase.getInstance().getReference().child("capsules"); // get capsule with matching key mDatabase.addListenerForSingleValueEvent(new ValueEventListener() { @Override public void onDataChange(DataSnapshot data) { - String searchKey = key.replaceAll("\"", "").trim(); - - for(DataSnapshot d: data.getChildren()) { - - if (searchKey.equals(d.getKey().toString())) { - Log.d("Success!", d.child("message").toString()); - - id = UUID.fromString(searchKey); - name = d.child("name").getValue().toString(); - message = d.child("message").getValue().toString(); - openDate = Long.parseLong(d.child("date_to_open").getValue().toString()); - creationDate = Long.parseLong(d.child("date_created").getValue().toString()); - recipients = new ArrayList(); - for (DataSnapshot r: d.child("recipients").getChildren()) { - //recipients.add() - recipients.add(new FirebaseCapsuleRecipient(r.getValue().toString())); - } - } else { - Log.d("FB Capsule", d.getKey().toString() + " " + searchKey); - } - } + update(data); } @Override @@ -137,75 +117,99 @@ public void onCancelled(DatabaseError databaseError) { }); } + private void update(DataSnapshot data) { + try { + if(data.child("name").exists()) + this.name = (String) data.child("name").getValue(); - ChildEventListener childListener = new ChildEventListener() { - - @Override - public void onChildAdded(DataSnapshot dataSnapshot, String s) { - Log.d("FB Capsule", dataSnapshot.getKey()); - } - - @Override - public void onChildChanged(DataSnapshot dataSnapshot, String s) { - - } - - @Override - public void onChildRemoved(DataSnapshot dataSnapshot) { - - } + if(data.child("message").exists()) + this.message = (String) data.child("message").getValue(); - @Override - public void onChildMoved(DataSnapshot dataSnapshot, String s) { + if(data.child("openDate").exists()) + this.openDate = (long) data.child("openDate").getValue(); + updateRecipients(data); + updateAttachments(data); + } catch (ClassCastException e){ + e.printStackTrace(); + Log.d(LOG_TAG, "The firebase backend's data model has a different type than this version!"); } + } - @Override - public void onCancelled(DatabaseError databaseError) { - + /** + * Updates the local copy of the recipients from the firebase update + * @param data + */ + private void updateRecipients(DataSnapshot data){ + if(!data.child("recipients").exists()) + return; + + for(DataSnapshot recipient : data.child("recipients").getChildren()){ + String recipientId = recipient.getKey(); + for(Recipient localRecipient: this.recipients){ + if (localRecipient.getId().equals(recipientId)) { + localRecipient.update(recipient); + } + } } - }; + } - ChildEventListener recipientListener = new ChildEventListener() { - @Override - public void onChildAdded(DataSnapshot dataSnapshot, String s) { - Log.d("FB capsule", dataSnapshot.getValue().toString()); - recipients.add(new FirebaseCapsuleRecipient(dataSnapshot.getKey())); + /** + * Updates the local copy of the attachmetns from the firebase update + * @param data + */ + private void updateAttachments(DataSnapshot data){ + if(!data.child("attachments").exists()) + return; + + for(DataSnapshot recipient : data.child("attachments").getChildren()){ + String attachmentId = recipient.getKey(); + for(Attachment localAttachment: this.attachments){ + if (localAttachment.getId().equals(attachmentId)) { + localAttachment.update(recipient); + } + } } + } - @Override - public void onChildChanged(DataSnapshot dataSnapshot, String s) { - - } + /** + * Saves this FirebaseCapsule to the backend. + */ + public void save(){ + FirebaseDatabase database = FirebaseDatabase.getInstance(); - @Override - public void onChildRemoved(DataSnapshot dataSnapshot) { + //Retrieve the DatabaseReference for this capsule + DatabaseReference ref = database.getReference("capsules").child(id.toString()); + ref.child("name").setValue(this.getName()); + ref.child("message").setValue(this.getMessage()); + ref.child("openDate").setValue(this.getOpenDate()); + for(Recipient recipient: this.getRecipients()){ + recipient.save(); } - @Override - public void onChildMoved(DataSnapshot dataSnapshot, String s) { - + for(Attachment attachment : this.getAttachments()){ + attachment.save(); } - @Override - public void onCancelled(DatabaseError databaseError) { + } - } - }; + public boolean isHidden(){ + return isHidden; + } /** - * Flags the capsule as hidden + * Flags the capsule as isHidden */ public void setHidden() { - hidden = true; + isHidden = true; } /** * Flags the capsule as visible (this is the default setting) */ public void setVisible() { - hidden = false; + isHidden = false; } public void setMessage(String message) { @@ -229,6 +233,14 @@ public void setRecipients(List recipients) { public void addRecipients(Recipient r) { if (r == null) throw new IllegalArgumentException("cannot add null recipient"); + recipients.add(r); + } + + public void removeRecipient(Recipient r){ + if(r == null) + throw new IllegalArgumentException("Cannot remove a null recipient"); + recipients.remove(r); + r.delete(); } public void setAttachments(List attachments) { @@ -243,6 +255,13 @@ public void addAttachments(Attachment a) { this.attachments.add(a); } + public void removeAttachment(Attachment a){ + if(a == null) + throw new IllegalArgumentException("Cannot remove a null recipient"); + attachments.remove(a); + a.delete(); + } + /** * @return The capsule's name */ diff --git a/app/src/main/java/me/kevinkang/timecapsule/data/firebase/FirebaseCapsuleRecipient.java b/app/src/main/java/me/kevinkang/timecapsule/data/firebase/FirebaseCapsuleRecipient.java index e2919d6..263cc19 100644 --- a/app/src/main/java/me/kevinkang/timecapsule/data/firebase/FirebaseCapsuleRecipient.java +++ b/app/src/main/java/me/kevinkang/timecapsule/data/firebase/FirebaseCapsuleRecipient.java @@ -2,6 +2,7 @@ import android.telephony.PhoneNumberUtils; +import com.google.firebase.database.DataSnapshot; import com.google.firebase.database.DatabaseReference; import com.google.firebase.database.FirebaseDatabase; @@ -92,6 +93,26 @@ public String getType() { return type; } + @Override + public void update(DataSnapshot recipient) { + + } + + @Override + public String getId() { + return null; + } + + @Override + public void save() { + + } + + @Override + public void delete() { + + } + /** * Indicates whether email is a valid email address * @param email The email address to validate diff --git a/app/src/main/java/me/kevinkang/timecapsule/data/firebase/TimeCapsuleUser.java b/app/src/main/java/me/kevinkang/timecapsule/data/firebase/TimeCapsuleUser.java index 275320e..7ae1326 100644 --- a/app/src/main/java/me/kevinkang/timecapsule/data/firebase/TimeCapsuleUser.java +++ b/app/src/main/java/me/kevinkang/timecapsule/data/firebase/TimeCapsuleUser.java @@ -13,28 +13,39 @@ import java.util.ArrayList; import java.util.List; +import me.kevinkang.timecapsule.data.models.Capsule; +import me.kevinkang.timecapsule.data.models.User; + /** * Created by Work on 10/15/2016. */ -public class TimeCapsuleUser { +public class TimeCapsuleUser extends User{ private static final String DEFAULT_ID = "0d5508b7-9131-4115-a9be-3878febb38fe"; private static final String TAG = "TimeCapsuleUser"; private String id = null; private String name = null; - private List capsules; + private List capsules; private DatabaseReference mDatabase; + private static TimeCapsuleUser currentUser; + + public static TimeCapsuleUser getCurrentUser(){ + if(currentUser == null) + currentUser = new TimeCapsuleUser(); + return currentUser; + } + public TimeCapsuleUser() { - capsules = new ArrayList(); + capsules = new ArrayList<>(); mDatabase = FirebaseDatabase.getInstance().getReference(); FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser(); + currentUser = this; if (user != null) { id = user.getUid(); } else { - // No user is signed in, use default - id = DEFAULT_ID; + return; } // get the user's name, replace with default if nobody is signed in @@ -83,4 +94,13 @@ public void onCancelled(DatabaseError databaseError) { } }; + @Override + public void addCapsules(FirebaseCapsule capsule) { + + } + + @Override + public List getCapsules() { + return capsules; + } } diff --git a/app/src/main/java/me/kevinkang/timecapsule/data/models/Attachment.java b/app/src/main/java/me/kevinkang/timecapsule/data/models/Attachment.java index 1682d03..c9a2007 100644 --- a/app/src/main/java/me/kevinkang/timecapsule/data/models/Attachment.java +++ b/app/src/main/java/me/kevinkang/timecapsule/data/models/Attachment.java @@ -1,5 +1,7 @@ package me.kevinkang.timecapsule.data.models; +import com.google.firebase.database.DataSnapshot; + /** * Created by Work on 10/15/2016. */ @@ -8,4 +10,12 @@ public abstract class Attachment { public abstract String getType(); public abstract String getExtension(); + + public abstract String getId(); + + public abstract void update(DataSnapshot recipient); + + public abstract void save(); + + public abstract void delete(); } diff --git a/app/src/main/java/me/kevinkang/timecapsule/data/models/Recipient.java b/app/src/main/java/me/kevinkang/timecapsule/data/models/Recipient.java index 9446642..ecd9633 100644 --- a/app/src/main/java/me/kevinkang/timecapsule/data/models/Recipient.java +++ b/app/src/main/java/me/kevinkang/timecapsule/data/models/Recipient.java @@ -1,5 +1,7 @@ package me.kevinkang.timecapsule.data.models; +import com.google.firebase.database.DataSnapshot; + /** * Created by Work on 10/15/2016. */ @@ -12,4 +14,13 @@ public abstract class Recipient { // indicates how to send the message public abstract String getType(); + + + public abstract void update(DataSnapshot recipient); + + public abstract String getId(); + + public abstract void save(); + + public abstract void delete(); } \ No newline at end of file diff --git a/app/src/main/java/me/kevinkang/timecapsule/data/models/User.java b/app/src/main/java/me/kevinkang/timecapsule/data/models/User.java index d70f780..a180feb 100644 --- a/app/src/main/java/me/kevinkang/timecapsule/data/models/User.java +++ b/app/src/main/java/me/kevinkang/timecapsule/data/models/User.java @@ -1,5 +1,6 @@ package me.kevinkang.timecapsule.data.models; +import java.util.List; import java.util.Set; import me.kevinkang.timecapsule.data.firebase.FirebaseCapsule; @@ -8,17 +9,17 @@ * Created by Work on 10/15/2016. */ -public interface User { +public abstract class User { /** * Adds capsule to an ordered Set * @param capsule capsule that will be inserted */ - void addCapsules(FirebaseCapsule capsule); + public abstract void addCapsules(FirebaseCapsule capsule); /** - * Gets capsule to an ordered Set - * @return returns an ordered Set of Capsules. + * Returns a user's capsules + * @return returns an ordered List of Capsules. */ - Set getCapsules(); + public abstract List getCapsules(); } diff --git a/app/src/main/res/drawable-hdpi/ic_add_white_24dp.png b/app/src/main/res/drawable-hdpi/ic_add_white_24dp.png new file mode 100644 index 0000000..694179b Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_add_white_24dp.png differ diff --git a/app/src/main/res/drawable-mdpi/ic_add_white_24dp.png b/app/src/main/res/drawable-mdpi/ic_add_white_24dp.png new file mode 100644 index 0000000..3856041 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_add_white_24dp.png differ diff --git a/app/src/main/res/drawable-xhdpi/ic_add_white_24dp.png b/app/src/main/res/drawable-xhdpi/ic_add_white_24dp.png new file mode 100644 index 0000000..67bb598 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_add_white_24dp.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_add_white_24dp.png b/app/src/main/res/drawable-xxhdpi/ic_add_white_24dp.png new file mode 100644 index 0000000..0fdced8 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_add_white_24dp.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_add_white_24dp.png b/app/src/main/res/drawable-xxxhdpi/ic_add_white_24dp.png new file mode 100644 index 0000000..d64c22e Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_add_white_24dp.png differ diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 81bc51a..101b961 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -7,10 +7,6 @@ android:layout_height="match_parent" tools:context="me.kevinkang.timecapsule.activities.MainActivity"> -<<<<<<< HEAD - -======= ->>>>>>> eb0abc691c4e49b33828c0fd949fdff682bc3580 -<<<<<<< HEAD -======= ->>>>>>> eb0abc691c4e49b33828c0fd949fdff682bc3580 + app:srcCompat="@drawable/ic_add_white_24dp" /> diff --git a/app/src/main/res/menu/menu_main_activity.xml b/app/src/main/res/menu/menu_main_activity.xml new file mode 100644 index 0000000..3ee0461 --- /dev/null +++ b/app/src/main/res/menu/menu_main_activity.xml @@ -0,0 +1,12 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 56d9479..be4a411 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -21,4 +21,5 @@ What would you like to attach? Image or Video File + Log out diff --git a/build.gradle b/build.gradle index 5793b18..72c61ce 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:2.2.1' + classpath 'com.android.tools.build:gradle:2.2.2' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files