165 Commits

Author SHA1 Message Date
Felix Atsma
fdcd141f23 Merge branch 'felix' into 'master'
Add logboek

See merge request !35
2017-06-30 10:10:54 +02:00
Felix Atsma
5f5269ceb8 Add logboek 2017-06-30 10:10:26 +02:00
Marijn Jansen
d7b2e54306 Merge branch 'marijn-logboek' into 'master'
Logboek

See merge request !34
2017-06-30 10:07:53 +02:00
Marijn Jansen
8ea692c5a8 Logboek 2017-06-30 10:07:14 +02:00
Felix Atsma
d4bfe0206b Merge branch 'felix' into 'master'
comments

See merge request !33
2017-06-30 00:02:04 +02:00
Felix Atsma
d61b058d0e Merge remote-tracking branch 'origin/master' into felix 2017-06-30 00:01:22 +02:00
Felix Atsma
979f1aab9a Add comments 2017-06-29 16:46:34 +02:00
Niels Zwemmer
69bbfeaacd Merge branch 'niels-profile' into 'master'
Fixed sepia filter uploading black pictures.

See merge request !32
2017-06-29 16:22:15 +02:00
Niels Zwemmer
1f4fa4c768 Fixed sepia filter uploading black pictures. 2017-06-29 16:21:18 +02:00
Marijn Jansen
dc7690e183 Merge branch 'marijn-fixdingen' into 'master'
Fixed double things in timeline :)

See merge request !31
2017-06-29 16:02:00 +02:00
Marijn Jansen
a4108e9e19 Fixed double things in timeline :) 2017-06-29 16:01:04 +02:00
Niels Zwemmer
dc3db134c0 Merge branch 'niels-profile' into 'master'
Niels profile

See merge request !30
2017-06-29 15:51:29 +02:00
Niels Zwemmer
32f39a35db Profile timeline button remade. 2017-06-29 15:51:00 +02:00
Niels Zwemmer
98f986fc0a Merge conflict fixed 2017-06-29 15:45:22 +02:00
Felix Atsma
5a6abe85f1 Timeline layout now with imagebutton 2017-06-29 15:41:16 +02:00
Niels Zwemmer
ab54ffb9ec Merge conflict resolved. 2017-06-29 15:23:36 +02:00
Niels Zwemmer
6258c2a91a Fixed the refresh combined with the progressBar. 2017-06-29 15:20:40 +02:00
Paul Lagerweij
0a7c49b3a3 added animation 2017-06-29 15:18:12 +02:00
Felix Atsma
63236c5895 Merge remote-tracking branch 'origin/niels-profile' into felix 2017-06-29 14:43:34 +02:00
Felix Atsma
d8c04c78ea Fix keyboard hiding crash + prettify findviewbyid's in camerafragment 2017-06-29 14:32:03 +02:00
Niels Zwemmer
9d016b8c65 Added a progressBar to the profilepage aswell. 2017-06-29 14:01:27 +02:00
Niels Zwemmer
7895054743 Merge remote-tracking branch 'origin/felix' into niels-profile 2017-06-29 13:44:08 +02:00
Felix Atsma
c38cc026fc Add progress bar for timeline 2017-06-29 13:42:44 +02:00
Niels Zwemmer
bd4149ccb1 Added rotate restriction. Merge-prep with Felix. 2017-06-29 13:41:23 +02:00
Marijn Jansen
27b005930f Merge branch 'marijn-appje' into 'master'
Fix!

See merge request !29
2017-06-29 13:36:15 +02:00
Marijn Jansen
7936350ede Fix! 2017-06-29 13:35:49 +02:00
Marijn Jansen
c517c2ef10 Merge branch 'marijn-appje' into 'master'
Marijn appje

See merge request !28
2017-06-29 13:34:34 +02:00
Marijn Jansen
c9eb4b62a1 Merge remote-tracking branch 'origin/master' into marijn-appje 2017-06-29 13:34:20 +02:00
Marijn Jansen
71d412beac Date works 2017-06-29 13:28:19 +02:00
Marijn Jansen
af47900288 Better name for niet slechts. 2017-06-29 13:21:58 +02:00
Marijn Jansen
5ae1d1f964 Added NietSlechts! 2017-06-29 13:19:12 +02:00
Niels Zwemmer
4eed601b7d WIP: for Felix 2017-06-29 12:50:29 +02:00
Niels Zwemmer
26a7239caa Much cleaner code. Known bugs seem to be fixed. Added extra progressDialog for posts downloading. 2017-06-29 00:35:55 +02:00
Niels Zwemmer
1fdd21440b Potentially fixed Felix' bug in the camera. Also made some changes for better readability of my own code. 2017-06-28 19:46:38 +02:00
Niels Zwemmer
2315d58598 Changed some appearances of the personal posts. 2017-06-28 18:02:28 +02:00
Niels Zwemmer
ab79fa7d7c Changed some appearances of the personal posts. 2017-06-28 17:58:32 +02:00
Niels Zwemmer
52d15a80ca Working refresh, working user-specific posts in profile. 2017-06-28 17:44:27 +02:00
Felix Atsma
c8f65c0dca Merge branch 'felix' into 'master'
Fix front facing + layout profile

See merge request !27
2017-06-28 16:04:01 +02:00
Felix Atsma
0560e6a0fb Fix front facing camera 2017-06-28 16:03:16 +02:00
Felix Atsma
93434a981f Layout profile changes + half of a reloader 2017-06-28 15:28:40 +02:00
Niels Zwemmer
2621062c60 Merge branch 'niels-profile' into 'master'
Niels profile

See merge request !26
2017-06-28 13:16:12 +02:00
Niels Zwemmer
43a1fcd52c Merge remote-tracking branch 'origin/master' into niels-profile 2017-06-28 13:15:19 +02:00
Niels Zwemmer
982d7d4279 Merge remote-tracking branch 'origin/master' into niels-profile 2017-06-28 13:14:10 +02:00
Felix Atsma
a04866ba3f Merge branch 'felix' into 'master'
Timeline improvements

See merge request !25
2017-06-28 13:14:09 +02:00
Felix Atsma
f1befdd21c Merge remote-tracking branch 'origin/master' into felix 2017-06-28 13:13:34 +02:00
Felix Atsma
cab6728a54 Improve timeline layout 2017-06-28 13:12:48 +02:00
Niels Zwemmer
017b5890c2 Neated up the code. 2017-06-28 13:11:30 +02:00
Marijn Jansen
fe15764d2b Merge branch 'marijn-appje' into 'master'
Option to get own posts.

See merge request !24
2017-06-28 12:47:33 +02:00
Marijn Jansen
bfd018ad4a Option to get own posts. 2017-06-28 12:46:57 +02:00
Felix Atsma
ba832682bf Merge branch 'felix' into 'master'
Image preview + cancel + change icons

See merge request !23
2017-06-28 12:05:34 +02:00
Felix Atsma
f0719c51f9 Add cancel button, fix button switching, change icons to vector 2017-06-28 12:01:05 +02:00
Niels Zwemmer
3aab463143 Added error message-shows and mail_successful/mail_failed to the error messages. 2017-06-28 11:13:39 +02:00
Felix Atsma
2db1254750 Image preview working 2017-06-28 10:25:54 +02:00
Niels Zwemmer
16c3b727fc Working profile page with Adapter. Need Marijn to fix the downloadclass to show user-only content instead of entire timeline. 2017-06-27 16:12:42 +02:00
Felix Atsma
d3395f3e9b Add negative filter + rotate half working 2017-06-27 15:06:20 +02:00
Niels Zwemmer
7ed5c36884 Merge remote-tracking branch 'origin/paul-profile' into niels-profile 2017-06-27 13:22:40 +02:00
Paul Lagerweij
0c3ed94bb7 put back profile naming 2017-06-27 13:21:30 +02:00
Niels Zwemmer
744ab1a9c0 Merge remote-tracking branch 'origin/paul-profile' into niels-profile 2017-06-27 13:20:29 +02:00
Paul Lagerweij
b11cc95000 put back 'niet slecht count profile' 2017-06-27 13:19:25 +02:00
Niels Zwemmer
cebc1bd59b Merge remote-tracking branch 'origin/paul-profile' into niels-profile 2017-06-27 13:16:26 +02:00
Niels Zwemmer
1d3537cdde First attempt at ProfileAdapter. Not in working state. 2017-06-27 13:15:55 +02:00
Paul Lagerweij
6851009e4b Added new files for profile fragment
new file:   fragment_profile_header.xml
 new file:   fragment_profile_timeline.xml
 new file:   list_item_timeline_profile.xml
2017-06-27 13:13:43 +02:00
Felix Atsma
08849521e1 Fix comment box clickable + prettify 2017-06-27 12:37:23 +02:00
Marijn Jansen
046e3f9400 Merge branch 'marijn-appje' into 'master'
Marijn appje

See merge request !22
2017-06-27 12:12:45 +02:00
Marijn Jansen
ab0b105640 Fix for timeline 2017-06-27 12:11:52 +02:00
Marijn Jansen
2b7965ad61 Fix for timeline scrolling 2017-06-27 12:10:56 +02:00
Niels Zwemmer
726129db5b Merge branch 'niels-profile' into 'master'
Niels profile

See merge request !21
2017-06-27 11:33:29 +02:00
Niels Zwemmer
f60005c29d Merge remote-tracking branch 'origin/master' into niels-profile 2017-06-27 11:33:02 +02:00
Niels Zwemmer
9322840d10 Minor changes to picture. 2017-06-27 11:29:48 +02:00
Marijn Jansen
1c9da2c8dc Merge branch 'marijn-appje' into 'master'
Marijn appje

See merge request !20
2017-06-27 11:18:32 +02:00
Marijn Jansen
0b943e3a1a Fixed a crash when switching fast to profile after loading the app. 2017-06-27 11:17:31 +02:00
Niels Zwemmer
84353046a5 Fixed implement runtime error for Felix. Made some minor changes to both strings.xml and ProfilePictureUploader (error when old picture not present). 2017-06-27 11:11:29 +02:00
Marijn Jansen
2ad161049a Merge remote-tracking branch 'origin/master' into marijn-appje 2017-06-27 09:10:20 +02:00
Niels Zwemmer
d3558b6344 Merge branch 'niels-notulen' into 'master'
Added today's counsil minutes.

See merge request !19
2017-06-26 23:39:06 +02:00
Niels Zwemmer
41bacb3b4f Added today's counsil minutes. 2017-06-26 23:38:14 +02:00
Felix Atsma
2db99500af Merge branch 'felix' into 'master'
Make camera (mostly) fullscreen + add comment function

See merge request !18
2017-06-26 23:37:29 +02:00
Felix Atsma
350e55271e Make camera (mostly) fullscreen + add comment function 2017-06-26 23:36:03 +02:00
Marijn Jansen
3f00e09592 fix for permissions. 2017-06-26 18:54:45 +02:00
Marijn Jansen
2c40a1b8da Merge remote-tracking branch 'origin/master' into marijn-appje 2017-06-26 16:23:26 +02:00
Niels Zwemmer
0136868ea8 Merge branch 'niels-profile' into 'master'
Niels profile

See merge request !17
2017-06-26 16:21:08 +02:00
Niels Zwemmer
b20534aaec Merge branch 'master' into 'niels-profile'
# Conflicts:
#   app/MyHyvesBookPlusStagram/app/src/main/java/nl/myhyvesbookplus/tagram/MainActivity.java
#   app/MyHyvesBookPlusStagram/app/src/main/res/values-nl/strings.xml
#   app/MyHyvesBookPlusStagram/app/src/main/res/values/strings.xml
2017-06-26 16:20:45 +02:00
Marijn Jansen
507fac220c Merge branch 'marijn-appje' into 'master'
Timeline things working right now Woohoo!

See merge request !16
2017-06-26 16:16:12 +02:00
Niels Zwemmer
d4d10e3f6f Profile page working, better quality picture aswell. Only needs personal feed. 2017-06-26 16:13:44 +02:00
Marijn Jansen
035f94ec66 Merge remote-tracking branch 'origin/master' into marijn-appje
# Conflicts:
#	app/MyHyvesBookPlusStagram/app/src/main/res/values/strings.xml
2017-06-26 15:23:17 +02:00
Marijn Jansen
6142e93957 Merge branch 'master' into 'marijn-appje'
# Conflicts:
#   app/MyHyvesBookPlusStagram/app/src/main/res/values/strings.xml
2017-06-26 15:21:20 +02:00
Marijn Jansen
247a443aba Timeline things working right now Woohoo! 2017-06-26 15:20:18 +02:00
Niels Zwemmer
e54e423847 Made some changes to process gitmerge. 2017-06-26 11:53:04 +02:00
Marijn Jansen
03d4244daf Merge branch 'marijn-appje' into 'master'
Marijn appje

See merge request !15
2017-06-26 11:37:03 +02:00
Marijn Jansen
766711faee Merge branch 'niels-notulen' into 'master'
Niels notulen

See merge request !14
2017-06-26 10:54:12 +02:00
Marijn Jansen
046b04e83a Merge branch 'niels-logboek' into 'master'
Niels logboek

See merge request !13
2017-06-26 10:53:27 +02:00
Felix Atsma
801acc24fa Merge branch 'felix' into 'master'
Camera filter switching and uploading

See merge request !12
2017-06-26 10:51:41 +02:00
Felix Atsma
d3d5a41037 Merge remote-tracking branch 'origin/master' into felix 2017-06-26 10:51:36 +02:00
Felix Atsma
d90a878a58 Camera filter switching and uploading 2017-06-26 10:43:59 +02:00
Marijn Jansen
a9ad130866 Added failure messages. 2017-06-25 15:06:13 +02:00
Marijn Jansen
c2582c128a Spilt UploadClass in two classes.
Posts are now obtainable from firebase.
2017-06-25 15:01:52 +02:00
Niels Zwemmer
8678cc9111 Added today and yesterday's entries. Forgot about adding the meeting. It is now added. 2017-06-24 20:58:00 +02:00
Niels Zwemmer
cc1b83b0e0 Added today and yesterday's entries. 2017-06-24 20:24:09 +02:00
Niels Zwemmer
5181128504 Committed files for others to look at and improve: Photo upload does not work properly. 2017-06-24 13:40:02 +02:00
Niels Zwemmer
83d2bda5c1 Resolved conflicts. 2017-06-23 20:39:57 +02:00
Marijn Jansen
a71fc80f59 Added ProgressDialog to upload. 2017-06-23 20:35:47 +02:00
Niels Zwemmer
da765832f1 Merge remote-tracking branch 'origin/marijn-appje' into niels-profile 2017-06-23 19:19:48 +02:00
Niels Zwemmer
3855d9d917 Cleared up code and made first (failed) attempt at progressDialog. 2017-06-23 17:30:29 +02:00
Marijn Jansen
8ba9f7f8e3 Delete profile pics on replace. 2017-06-23 16:40:34 +02:00
Niels Zwemmer
6aeacbfc8a Merge remote-tracking branch 'origin/master' into niels-profile 2017-06-23 16:11:53 +02:00
Marijn Jansen
6d7930ee03 Merge branch 'marijn-appje' into 'master'
Marijn appje

See merge request !11
2017-06-23 16:08:47 +02:00
Marijn Jansen
c056d96138 Profile photo update things. 2017-06-23 16:08:07 +02:00
Niels Zwemmer
a8a026d18f Merge remote-tracking branch 'origin/marijn-appje' into niels-profile 2017-06-23 15:27:46 +02:00
Marijn Jansen
6e55954dde Made a listener! 2017-06-23 15:24:57 +02:00
Niels Zwemmer
c78f01dbfe Merge remote-tracking branch 'origin/marijn-appje' into niels-profile 2017-06-23 14:35:50 +02:00
Niels Zwemmer
0e25ff63cc Cleaned code, added an invalidate. Needs testing. 2017-06-23 14:35:25 +02:00
Marijn Jansen
b570e5ef21 Unique Profile pic name. 2017-06-23 14:35:20 +02:00
Niels Zwemmer
06eb90bc9f Added council minutes of today. 2017-06-23 13:14:15 +02:00
Marijn Jansen
c5c6ba7a47 Merge branch 'marijn-appje' into 'master'
Marijn appje

See merge request !10
2017-06-23 12:45:10 +02:00
Marijn Jansen
d8eea0bb70 Profile pics working! 2017-06-23 12:44:25 +02:00
Marijn Jansen
0f98bdb5ea Merge remote-tracking branch 'origin/niels-profile' into marijn-appje 2017-06-23 11:50:04 +02:00
Marijn Jansen
2a89827b63 Added Post classess enz. 2017-06-23 11:46:30 +02:00
Niels Zwemmer
b0a99b3ab1 Bugprone version of Profilefragment. 2017-06-23 11:44:43 +02:00
Niels Zwemmer
d7dcaa6c29 Added today's log entry. 2017-06-22 20:53:01 +02:00
Felix Atsma
66221c4393 Merge branch 'felix' into 'master'
Add error strings

See merge request !9
2017-06-22 12:45:46 +02:00
Felix Atsma
a93f8a500d Add error strings 2017-06-22 12:44:56 +02:00
Felix Atsma
95bb92930e Merge branch 'felix' into 'master'
Felix camera

See merge request !8
2017-06-22 11:40:27 +02:00
Marijn Jansen
e5285f91d5 Merge branch 'paul-profile' into 'master'
Paul profile

See merge request !6
2017-06-22 11:39:34 +02:00
Marijn Jansen
37507c3f5f Merge branch 'master' into 'paul-profile'
# Conflicts:
#   app/MyHyvesBookPlusStagram/app/src/main/res/values-nl/strings.xml
#   app/MyHyvesBookPlusStagram/app/src/main/res/values/strings.xml
2017-06-22 11:39:07 +02:00
Marijn Jansen
6e08558769 Merge branch 'marijn-appje' into 'master'
Paul wanted to merge

See merge request !7
2017-06-22 11:37:40 +02:00
Felix Atsma
a2d333c627 Camera switching working 2017-06-22 11:36:56 +02:00
Marijn Jansen
aabe207594 Because Paul wanted to Merge 2017-06-22 11:36:17 +02:00
Paul Lagerweij
9a8feee49f small improvement to ProfileFragment.java 2017-06-22 11:11:50 +02:00
Paul Lagerweij
cd45463f6a improved some code layout ProfileFragment.java 2017-06-22 11:07:33 +02:00
Niels Zwemmer
60e58b40bc Added password reset functionality as well as username display in the app. Also, round launcher icons have been uploaded. 2017-06-21 20:54:14 +02:00
Niels Zwemmer
08ec6e3ee8 Added updated log file. 2017-06-21 15:52:15 +02:00
Niels Zwemmer
cafe39d045 Minor changes. 2017-06-21 15:47:45 +02:00
Niels Zwemmer
84a2c75c85 Merge remote-tracking branch 'origin/paul-profile' into niels-profile 2017-06-21 14:40:32 +02:00
Paul Lagerweij
63bef257da overlay change profile picture button 2017-06-21 14:39:40 +02:00
Niels Zwemmer
fa3f42da7e Added password change functions. 2017-06-21 14:38:05 +02:00
Paul Lagerweij
6faf1c9400 add padding to profile fragment 2017-06-21 14:12:32 +02:00
Niels Zwemmer
d0386a533f Added a new default profile picture. Tested and working, changed filename of avatar 2017-06-21 14:10:13 +02:00
Niels Zwemmer
d326785082 Added a new default profile picture. Tested and working, changed filename of avatar 2017-06-21 14:09:59 +02:00
Niels Zwemmer
fe1960fdce Merge remote-tracking branch 'origin/paul-profile' into niels-profile 2017-06-21 14:06:49 +02:00
Paul Lagerweij
4005bef38c added change psw button to profile fragment 2017-06-21 14:06:05 +02:00
Niels Zwemmer
1a944364c4 Added a new default profile picture. 2017-06-21 14:06:00 +02:00
Niels Zwemmer
e48ddd6b82 Merge remote-tracking branch 'origin/paul-profile' into niels-profile 2017-06-21 13:43:09 +02:00
Niels Zwemmer
80e2935b23 Added new launcher logo, made some minor changes to ProfileFragment.java 2017-06-21 13:42:42 +02:00
Paul Lagerweij
d982c8ba49 change layout profile fragment 2017-06-21 13:42:32 +02:00
Paul Lagerweij
6db7ca20ae default picture if no profile photo in firebase 2017-06-21 13:07:29 +02:00
Niels Zwemmer
e787204ce7 Fixed bugs in profile fragment. 2017-06-21 12:32:06 +02:00
Niels Zwemmer
72003c75ff Merge remote-tracking branch 'origin/paul-profile' into niels-profile 2017-06-21 12:22:39 +02:00
Niels Zwemmer
92bf29dd84 Small changes made to appearance. 2017-06-21 12:17:23 +02:00
Paul Lagerweij
bb69d3f695 first implementation of profile picture 2017-06-21 12:16:00 +02:00
Niels Zwemmer
27416aae85 Added functionality framework for the profile pic button for Paul. He can now bind actions to the button. 2017-06-21 12:04:26 +02:00
Niels Zwemmer
86ab31a681 Merge branch 'master' of ssh://gitlab-fnwi.uva.nl:1337/11166932/TheReturnOfTheMyHyvesBookPlus into niels-notulen 2017-06-21 11:08:10 +02:00
Marijn Jansen
c040ef495f Merge remote-tracking branch 'origin/master' into marijn-appje 2017-06-20 22:19:24 +02:00
Marijn Jansen
75d1e6b4ed Deleted some files 2017-06-20 22:00:43 +02:00
Marijn Jansen
442c5bd642 Added dialogs and checks to login en register, also started working on Uploads 2017-06-20 21:59:53 +02:00
Felix Atsma
1e5239921a Camera preview working, with non working picture button 2017-06-20 21:20:54 +02:00
Niels Zwemmer
39a48044d3 Removed produced PDF of counsil minutes and replaced it with .tex file. Also, added a new .tex file for today's meeting. 2017-06-20 19:53:56 +02:00
Niels Zwemmer
f3ee792d22 Added today's log 2017-06-20 19:21:30 +02:00
Niels Zwemmer
01a27d8a95 Added logboek template 2017-06-20 14:39:37 +02:00
Paul Lagerweij
291261fcee fragment_profile.xml test 2017-06-20 13:39:07 +02:00
Paul Lagerweij
3aac4fc96d login-, picture-button to fragment_profile.xml
button's are next to each other
2017-06-20 13:01:51 +02:00
Paul Lagerweij
b9ab2676a6 Merge remote-tracking branch 'origin/niels-profile' into paul-profile 2017-06-20 11:40:43 +02:00
Niels Zwemmer
bd2b69a330 Added some changes to form a baseline for Paul 2017-06-20 11:39:50 +02:00
Paul Lagerweij
c27b608168 Merge remote-tracking branch 'origin/marijn-appje' into paul-profile 2017-06-20 11:29:03 +02:00
Niels Zwemmer
720865fd7e Merge remote-tracking branch 'origin/marijn-appje' into niels-profile 2017-06-20 11:28:24 +02:00
Marijn Jansen
23db910b92 New OnClick and icons 2017-06-20 11:27:38 +02:00
Niels Zwemmer
7eab8f2257 First, unofficial council minutes. 2017-06-13 20:10:26 +02:00
63 changed files with 3225 additions and 443 deletions

View File

@@ -6,7 +6,7 @@ android {
defaultConfig {
applicationId "nl.myhyvesbookplus.tagram"
minSdkVersion 21
targetSdkVersion 25
targetSdkVersion 21
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
@@ -26,10 +26,15 @@ dependencies {
})
compile 'com.android.support:appcompat-v7:25.3.1'
compile 'com.android.support:design:25.3.1'
compile 'com.google.firebase:firebase-database:10.0.1'
compile 'com.google.firebase:firebase-auth:10.0.1'
compile 'com.android.support.constraint:constraint-layout:1.0.2'
compile 'com.android.support:support-v4:25.3.1'
compile 'com.google.firebase:firebase-database:11.0.1'
compile 'com.google.firebase:firebase-auth:11.0.1'
compile 'com.google.firebase:firebase-storage:11.0.1'
// FirebaseUI Storage only
compile 'com.firebaseui:firebase-ui-storage:2.0.1'
testCompile 'junit:junit:4.12'
}
@@ -42,4 +47,5 @@ dependencies {
apply plugin: 'com.google.gms.google-services'

View File

@@ -14,6 +14,14 @@
}
},
"oauth_client": [
{
"client_id": "1078950034345-k3mcuf1bkf9ehg7vi09cp16lcdrrpf3a.apps.googleusercontent.com",
"client_type": 1,
"android_info": {
"package_name": "nl.myhyvesbookplus.tagram",
"certificate_hash": "02b894113a27cc0c4b6025a382c826477fc8543a"
}
},
{
"client_id": "1078950034345-dmsbu0066sfqgqthn2mldlauvdef98u9.apps.googleusercontent.com",
"client_type": 3
@@ -29,8 +37,13 @@
"status": 1
},
"appinvite_service": {
"status": 1,
"other_platform_oauth_client": []
"status": 2,
"other_platform_oauth_client": [
{
"client_id": "1078950034345-dmsbu0066sfqgqthn2mldlauvdef98u9.apps.googleusercontent.com",
"client_type": 3
}
]
},
"ads_service": {
"status": 2

View File

@@ -2,6 +2,10 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="nl.myhyvesbookplus.tagram">
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
@@ -9,7 +13,20 @@
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="nl.myhyvesbookplus.tagram.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths"/>
</provider>
<activity
android:screenOrientation="portrait"
android:name=".MainActivity"
android:label="@string/app_name">
<intent-filter>
@@ -18,7 +35,9 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".LoginActivity">
<activity
android:screenOrientation="portrait"
android:name=".LoginActivity">
</activity>
</application>

View File

@@ -1,108 +1,293 @@
package nl.myhyvesbookplus.tagram;
import android.content.Context;
import android.net.Uri;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;
import android.os.Bundle;
import android.app.Fragment;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import nl.myhyvesbookplus.tagram.controller.PostUploader;
import nl.myhyvesbookplus.tagram.model.BitmapPost;
/**
* A simple {@link Fragment} subclass.
* Activities that contain this fragment must implement the
* {@link CameraFragment.OnFragmentInteractionListener} interface
* to handle interaction events.
* Use the {@link CameraFragment#newInstance} factory method to
* create an instance of this fragment.
*/
public class CameraFragment extends Fragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
public class CameraFragment extends Fragment implements PostUploader.PostUploadListener{
private static final String TAG = "CameraFragment";
private Camera mCamera;
private CameraPreview mPreview;
private Bitmap mPhoto;
private int facing = Camera.CameraInfo.CAMERA_FACING_BACK;
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
private OnFragmentInteractionListener mListener;
public CameraFragment() {
// Required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* @param param1 Parameter 1.
* @param param2 Parameter 2.
* @return A new instance of fragment CameraFragment.
*/
// TODO: Rename and change types and number of parameters
public static CameraFragment newInstance(String param1, String param2) {
CameraFragment fragment = new CameraFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
/* Required empty public constructor */
public CameraFragment() { }
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_camera, container, false);
}
final View view = inflater.inflate(R.layout.fragment_camera, container, false);
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
final RelativeLayout filterButtons = (RelativeLayout) view.findViewById(R.id.filter_buttons);
final RelativeLayout mCameraLayout = (RelativeLayout) view.findViewById(R.id.camera_preview);
final LinearLayout commentBox = (LinearLayout) view.findViewById(R.id.comment_box);
final ImageButton pictureButton = (ImageButton) view.findViewById(R.id.picture_button);
final ImageButton switchButton = (ImageButton) view.findViewById(R.id.switch_camera_button);
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
// Hide the action bar
((AppCompatActivity)getActivity()).getSupportActionBar().hide();
@Override
public void onDetach() {
super.onDetach();
mListener = null;
mCamera = getCameraInstance(facing);
mPreview = new CameraPreview(getActivity().getBaseContext(), mCamera);
mCameraLayout.addView(mPreview);
// Draw initial buttons over preview
pictureButton.bringToFront();
switchButton.bringToFront();
filterButtons.bringToFront();
/* Upon pressing the switch camera facing button: */
switchButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
switchFacing();
mCameraLayout.removeView(mPreview);
mCamera = getCameraInstance(facing);
mPreview = new CameraPreview(getActivity().getBaseContext(), mCamera);
mCameraLayout.addView(mPreview);
pictureButton.bringToFront();
switchButton.bringToFront();
}
});
/* Upon pressing the take photo button: */
pictureButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mCamera.takePicture(null, null, new PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
mPhoto = BitmapFactory.decodeByteArray(data, 0, data.length, null);
PicturePreview mPicPreview = new PicturePreview(getActivity().getBaseContext(), mPhoto, facing);
mPicPreview.setId(R.id.pic_preview);
mCameraLayout.addView(mPicPreview);
filterButtons.setVisibility(View.VISIBLE);
filterButtons.bringToFront();
switchButtons(view);
}
});
}
});
/* Upon pressing the upload button: */
(view.findViewById(R.id.upload_button)).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
commentBox.setClickable(true);
commentBox.setVisibility(View.VISIBLE);
commentBox.bringToFront();
filterButtons.setVisibility(View.GONE);
((FloatingActionButton)view.findViewById(R.id.upload_button)).hide();
}
});
/* Upon pressing the enter button on the virtual keyboard: */
(view.findViewById(R.id.comment_submit)).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
EditText mComment = (EditText) view.findViewById(R.id.comment_text);
String comment = mComment.getText().toString();
mComment.setText("");
PostUploader upload = new PostUploader(getActivity());
upload.uploadPicture(new BitmapPost(((PicturePreview)view.findViewById(R.id.pic_preview)).getPicture(), comment));
mPhoto.recycle();
filterButtons.setVisibility(View.GONE);
switchButtons(view);
mCameraLayout.removeView(mPreview);
mCamera = getCameraInstance(facing);
mPreview = new CameraPreview(getActivity().getBaseContext(), mCamera);
mCameraLayout.addView(mPreview);
pictureButton.bringToFront();
switchButton.bringToFront();
mCameraLayout.removeView(view.findViewById(R.id.pic_preview));
hideKeyboard();
}
});
/* Upon pressing the cancel button: */
(view.findViewById(R.id.comment_cancel)).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
((EditText) view.findViewById(R.id.comment_text)).setText("");
mPhoto.recycle();
filterButtons.setVisibility(View.GONE);
switchButtons(view);
mCameraLayout.removeView(mPreview);
mCamera = getCameraInstance(facing);
mPreview = new CameraPreview(getActivity().getBaseContext(), mCamera);
mCameraLayout.addView(mPreview);
pictureButton.bringToFront();
switchButton.bringToFront();
mCameraLayout.removeView(view.findViewById(R.id.pic_preview));
hideKeyboard();
}
});
/* Upon pressing the left arrow filter change button: */
(view.findViewById(R.id.filter_left)).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mCameraLayout.removeView(view.findViewById(R.id.pic_preview));
PicturePreview.filterPrev();
PicturePreview mPicPreview = new PicturePreview(getActivity().getBaseContext(), mPhoto, facing);
mPicPreview.setId(R.id.pic_preview);
mCameraLayout.addView(mPicPreview);
view.findViewById(R.id.upload_button).bringToFront();
filterButtons.setVisibility(View.VISIBLE);
filterButtons.bringToFront();
}
});
/* Upon pressing the right arrow filter change button: */
(view.findViewById(R.id.filter_right)).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mCameraLayout.removeView(view.findViewById(R.id.pic_preview));
PicturePreview.filterNext();
PicturePreview mPicPreview = new PicturePreview(getActivity().getBaseContext(), mPhoto, facing);
mPicPreview.setId(R.id.pic_preview);
mCameraLayout.addView(mPicPreview);
view.findViewById(R.id.upload_button).bringToFront();
filterButtons.setVisibility(View.VISIBLE);
filterButtons.bringToFront();
}
});
return view;
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
* Hides keyboard after submit, upload or cancel button gets pressed.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
public void hideKeyboard() {
((InputMethodManager) getActivity().getSystemService(Activity.INPUT_METHOD_SERVICE))
.toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, 0);
}
/**
* Restores the action bar when exiting the fragment.
*/
@Override
public void onDestroyView() {
super.onDestroyView();
((AppCompatActivity)getActivity()).getSupportActionBar().show();
}
/**
* Start the camera.
* @param facing The direction in which the camera should be initialized (back by default).
* @return the result of the opened camera, if successful.
*/
public static Camera getCameraInstance(int facing) {
Camera c = null;
try {
c = Camera.open(facing);
} catch (Exception e) {
e.getStackTrace();
}
return c;
}
/**
* Switch between front facing camera and the back camera.
*/
public void switchFacing() {
if (facing == Camera.CameraInfo.CAMERA_FACING_FRONT)
facing = Camera.CameraInfo.CAMERA_FACING_BACK;
else
facing = Camera.CameraInfo.CAMERA_FACING_FRONT;
// TODO
// facing =
// facing == Camera.CameraInfo.CAMERA_FACING_FRONT ?
// Camera.CameraInfo.CAMERA_FACING_BACK :
// Camera.CameraInfo.CAMERA_FACING_FRONT;
}
/**
* Change which buttons are visible during the different stages on the camera fragment.
*
* @param view The current view upon which the buttons need to be placed or removed.
*/
public void switchButtons(View view) {
FloatingActionButton upload = (FloatingActionButton) view.findViewById(R.id.upload_button);
ImageButton picButton = (ImageButton) view.findViewById(R.id.picture_button);
ImageButton switchButton = (ImageButton) view.findViewById(R.id.switch_camera_button);
if (((Integer)picButton.getVisibility()).equals(View.GONE)) {
Log.d(TAG, "switchButtons: GONE");
upload.hide();
picButton.setVisibility(View.VISIBLE);
switchButton.setVisibility(View.VISIBLE);
picButton.bringToFront();
switchButton.bringToFront();
} else {
Log.d(TAG, "switchButtons: VISIBLE");
upload.bringToFront();
upload.show();
picButton.setVisibility(View.GONE);
switchButton.setVisibility(View.GONE);
}
}
@Override
public void PostUploadComplete(Boolean success) {
}
}

View File

@@ -0,0 +1,60 @@
package nl.myhyvesbookplus.tagram;
import android.content.Context;
import android.hardware.Camera;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import java.io.IOException;
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private static String TAG = "CameraPreview";
private SurfaceHolder mHolder;
private Camera mCamera;
public CameraPreview(Context context, Camera camera) {
super(context);
mCamera = camera;
mCamera.setDisplayOrientation(90);
mHolder = getHolder();
mHolder.addCallback(this);
}
@Override
public void surfaceCreated(SurfaceHolder mHolder) {
try {
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (IOException e) {
e.getStackTrace();
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
if (mHolder.getSurface() == null){
return;
}
try {
mCamera.stopPreview();
} catch (Exception e){
}
try {
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (Exception e){
Log.d("camera", "Error starting camera preview: " + e.getMessage());
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
Log.d(TAG, "surfaceDestroyed: CAMERA DESTROYED");
mCamera.stopPreview();
mCamera.release();
}
}

View File

@@ -1,9 +1,10 @@
package nl.myhyvesbookplus.tagram;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.Bundle;
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;
@@ -18,7 +19,7 @@ import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.auth.UserProfileChangeRequest;
public class LoginActivity extends AppCompatActivity {
public class LoginActivity extends AppCompatActivity implements View.OnClickListener {
public static final String TAG = "Login";
/// Views ///
@@ -29,6 +30,8 @@ public class LoginActivity extends AppCompatActivity {
protected FirebaseAuth mAuth;
private ProgressDialog progressDialog;
/// Setup ///
@Override
@@ -38,11 +41,7 @@ public class LoginActivity extends AppCompatActivity {
mAuth = FirebaseAuth.getInstance();
findViews();
}
@Override
protected void onStart() {
super.onStart();
bindOnClick();
}
/**
@@ -63,44 +62,81 @@ public class LoginActivity extends AppCompatActivity {
emailField = (EditText) findViewById(R.id.email);
}
protected void bindOnClick() {
registerButton.setOnClickListener(this);
backToLoginButton.setOnClickListener(this);
goToRegisterButton.setOnClickListener(this);
logInButton.setOnClickListener(this);
}
/// OnClick ///
/**
* Performs the logon action.
* Called when a view has been clicked.
*
* @param view
* @param v The view that was clicked.
*/
public void logInOnClick(View view) {
String emailSting = emailField.getText().toString();
String passwordSting = passwordField.getText().toString();
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.register_button:
registerOnClick();
break;
case R.id.go_to_register_button:
goToRegisterOnClick();
break;
case R.id.login_button:
logInOnClick();
break;
case R.id.back_to_login_button:
backToLoginOnClick();
break;
}
}
logIn(emailSting, passwordSting);
/**
* Performs the logon action.
*/
public void logInOnClick() {
String emailString = emailField.getText().toString();
String passwordString = passwordField.getText().toString();
if (!emailString.isEmpty() && !passwordString.isEmpty()) {
logIn(emailString, passwordString);
} else {
Toast.makeText(LoginActivity.this, R.string.login_error, Toast.LENGTH_SHORT).show();
}
}
/**
* Performs the register action.
* @param view
*/
public void registerOnClick(View view) {
Log.d(TAG, "registerOnClick: ");
public void registerOnClick() {
String emailString = emailField.getText().toString();
String usernameString = usernameField.getText().toString();
String passwordString = passwordField.getText().toString();
String passwordConfirmString = passwordConfirmField.getText().toString();
if (passwordField.getText().toString().equals(passwordConfirmField.getText().toString())) {
registerUser(emailField.getText().toString(), passwordField.getText().toString());
if (!emailString.isEmpty() && !usernameString.isEmpty()
&& !passwordString.isEmpty() && !passwordConfirmString.isEmpty()) {
if (passwordField.getText().toString().equals(passwordConfirmField.getText().toString())) {
registerUser(emailField.getText().toString(), passwordField.getText().toString());
} else {
Toast.makeText(LoginActivity.this, R.string.password_match_error,
Toast.LENGTH_SHORT).show();
Log.d(TAG, "registerOnClick: Passwords do not match");
}
} else {
Toast.makeText(LoginActivity.this, "Passwords do not match",
Toast.LENGTH_SHORT).show();
Log.d(TAG, "registerOnClick: Passwords do not match");
Toast.makeText(LoginActivity.this, R.string.register_error, Toast.LENGTH_SHORT).show();
}
}
/// UI-changes ///
/**
* Changes the Activity for registering.
* @param view
*/
public void goToRegisterOnClick(View view) {
public void goToRegisterOnClick() {
passwordConfirmField.setVisibility(View.VISIBLE);
passwordConfirmLabel.setVisibility(View.VISIBLE);
registerButton.setVisibility(View.VISIBLE);
@@ -114,9 +150,8 @@ public class LoginActivity extends AppCompatActivity {
/**
* Changes the Activity for logging in.
* @param view
*/
public void backToLoginOnClick(View view) {
public void backToLoginOnClick() {
passwordConfirmField.setVisibility(View.GONE);
passwordConfirmLabel.setVisibility(View.GONE);
registerButton.setVisibility(View.GONE);
@@ -134,6 +169,7 @@ public class LoginActivity extends AppCompatActivity {
protected void goToMainScreen() {
Intent intent = new Intent(this, MainActivity.class);
startActivity(intent);
progressDialog.dismiss();
this.finish();
}
@@ -141,11 +177,13 @@ public class LoginActivity extends AppCompatActivity {
/**
* Performs the actual login action.
* @param emailSting email address
* @param passwordSting the entered password
* @param emailString email address
* @param passwordString the entered password
*/
protected void logIn(String emailSting, String passwordSting) {
mAuth.signInWithEmailAndPassword(emailSting, passwordSting)
protected void logIn(String emailString, String passwordString) {
progressDialog = ProgressDialog.show(LoginActivity.this, getString(R.string.please_wait), getString(R.string.logging_in), true, false);
mAuth.signInWithEmailAndPassword(emailString, passwordString)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
@@ -159,6 +197,7 @@ public class LoginActivity extends AppCompatActivity {
} else {
// If sign in fails, display a message to the user.
Log.w(TAG, "signInWithEmail:failure", task.getException());
progressDialog.dismiss();
Toast.makeText(LoginActivity.this, task.getException().getLocalizedMessage(),
Toast.LENGTH_SHORT).show();
}
@@ -172,6 +211,7 @@ public class LoginActivity extends AppCompatActivity {
* @param password the entered password
*/
protected void registerUser(String email, String password) {
this.progressDialog = ProgressDialog.show(LoginActivity.this, getString(R.string.please_wait), getString(R.string.registering), true, false);
mAuth.createUserWithEmailAndPassword(email, password)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
@Override
@@ -186,6 +226,7 @@ public class LoginActivity extends AppCompatActivity {
// If sign in fails, display a message to the user.
Log.w(TAG, "createUserWithEmail:failure", task.getException());
if (task.getException() != null) {
progressDialog.dismiss();
Toast.makeText(LoginActivity.this, task.getException().getLocalizedMessage(),
Toast.LENGTH_SHORT).show();
}
@@ -194,6 +235,7 @@ public class LoginActivity extends AppCompatActivity {
});
}
//TODO Make modular for use with Profile fragment.
/**
* Saves the Username to Firebase
* @param user The User object that needs to be updated

View File

@@ -1,5 +1,6 @@
package nl.myhyvesbookplus.tagram;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.content.Intent;
@@ -7,7 +8,6 @@ import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.design.widget.BottomNavigationView;
import android.app.Fragment;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.MenuItem;
@@ -15,7 +15,15 @@ import android.view.View;
import com.google.firebase.auth.FirebaseAuth;
public class MainActivity extends AppCompatActivity implements CameraFragment.OnFragmentInteractionListener, ProfileFragment.OnFragmentInteractionListener, TimelineFragment.OnFragmentInteractionListener {
import nl.myhyvesbookplus.tagram.controller.DownloadClass;
import nl.myhyvesbookplus.tagram.controller.PostUploader;
import nl.myhyvesbookplus.tagram.controller.ProfilePictureUploader;
public class MainActivity extends AppCompatActivity implements
ProfilePictureUploader.ProfilePictureUpdatedListener,
DownloadClass.PostDownloadListener,
PostUploader.PostUploadListener {
final static private String TAG = "MainScreen";
FirebaseAuth mAuth;
@@ -31,25 +39,25 @@ public class MainActivity extends AppCompatActivity implements CameraFragment.On
case nl.myhyvesbookplus.tagram.R.id.navigation_timeline:
Log.d(TAG, "onNavigationItemSelected: Timeline");
TimelineFragment timeline = new TimelineFragment();
transaction.replace(R.id.content, timeline);
transaction.addToBackStack(null);
transaction.commit();
transaction.replace(R.id.content, timeline)
.addToBackStack(null)
.commit();
return true;
case nl.myhyvesbookplus.tagram.R.id.navigation_camera:
Log.d(TAG, "onNavigationItemSelected: Camera");
CameraFragment camera = new CameraFragment();
transaction.replace(R.id.content, camera);
transaction.addToBackStack(null);
transaction.commit();
transaction.replace(R.id.content, camera)
.addToBackStack(null)
.commit();
return true;
case nl.myhyvesbookplus.tagram.R.id.navigation_profile:
Log.d(TAG, "onNavigationItemSelected: Profile");
ProfileFragment profile = new ProfileFragment();
transaction.replace(R.id.content, profile);
transaction.addToBackStack(null);
transaction.commit();
transaction.replace(R.id.content, profile)
.addToBackStack(null)
.commit();
return true;
}
return false;
@@ -75,7 +83,6 @@ public class MainActivity extends AppCompatActivity implements CameraFragment.On
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.content, fragment);
transaction.commit();
}
@Override
@@ -83,19 +90,46 @@ public class MainActivity extends AppCompatActivity implements CameraFragment.On
finish();
}
@Override
public void onFragmentInteraction(Uri uri) {
}
public void logOutOnClick(View view) {
FirebaseAuth.getInstance().signOut();
goToLogin();
this.finish();
}
protected void goToLogin() {
Intent goToLogIn = new Intent(this, LoginActivity.class);
startActivity(goToLogIn);
this.finish();
}
@Override
public void ProfilePictureUpdated(Boolean success) {
FragmentManager man = getFragmentManager();
ProfileFragment frag = (ProfileFragment) man.findFragmentById(R.id.content);
FragmentTransaction transaction = man.beginTransaction();
frag.progressDialog.dismiss();
transaction.detach(frag)
.attach(frag)
.commit();
Log.d(TAG, "ProfilePictureUpdated: Done reloading fragment");
}
@Override
public void PostDownloaded() {
FragmentManager fragmentManager = getFragmentManager();
Fragment frag = fragmentManager.findFragmentById(R.id.content);
if (frag instanceof ProfileFragment) {
((ProfileFragment) frag).startList();
} else if (frag instanceof TimelineFragment) {
// ((TimelineFragment) frag).progressDialog.dismiss();
((TimelineFragment) frag).startList();
}
}
@Override
public void PostUploadComplete(Boolean success) {
}
}

View File

@@ -0,0 +1,193 @@
package nl.myhyvesbookplus.tagram;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.hardware.Camera;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
/**
* Draws the picture taken and applies filters, which can be switched.
*/
public class PicturePreview extends SurfaceView implements SurfaceHolder.Callback {
private static final String TAG = "PicturePreview";
private static final int FILTER_NONE = 0;
private static final int FILTER_SEPIA = 1;
private static final int FILTER_BW = 2;
private static final int FILTER_NEG = 3;
private static int currentFilter = FILTER_NONE;
private int facing;
private int rotate;
private Bitmap picture;
private Bitmap filterPicture;
/**
* Constructor: changes image based on current direction the camera is facing.
* @param context
* @param bmp Image to be previewed.
* @param facing Direction camera is facing.
*/
public PicturePreview(Context context, Bitmap bmp, int facing) {
super(context);
setWillNotDraw(false);
this.facing = facing;
if (((Integer)facing).equals(Camera.CameraInfo.CAMERA_FACING_FRONT)) {
picture = Bitmap.createBitmap(bmp);
rotate = 270;
} else {
picture = Bitmap.createScaledBitmap(bmp, bmp.getWidth() / 2, bmp.getHeight() / 2, false);
rotate = 90;
}
}
/**
* Checks the current filter and draws and saves the image with altered colours.
* @param canvas
*/
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
ColorMatrix cm = new ColorMatrix();
Paint paint = new Paint();
ColorMatrixColorFilter filter;
Canvas saveCanvas = new Canvas();
switch (currentFilter) {
case FILTER_NONE:
canvas.drawBitmap(rotate(picture, rotate), 0, 0, null);
filterPicture = rotate(picture, rotate);
break;
case FILTER_SEPIA:
filterPicture = Bitmap.createBitmap(canvas.getWidth(), canvas.getHeight(), Bitmap.Config.ARGB_8888);
Log.d(TAG, "onDraw: " + Integer.toString(canvas.getWidth()));
float[] sepia = {0.393f,0.769f,0.189f,0f,0f,
0.349f,0.686f,0.168f,0f,0f,
0.272f,0.534f,0.131f,0f,0f,
0f, 0f, 0f, 1f, 0f};
cm.set(sepia);
filter = new ColorMatrixColorFilter(cm);
paint.setColorFilter(filter);
saveCanvas.setBitmap(filterPicture);
saveCanvas.drawBitmap(rotate(picture, rotate), 0, 0, paint);
canvas.drawBitmap(rotate(picture, rotate), 0, 0, paint);
break;
case FILTER_BW:
filterPicture = Bitmap.createBitmap(canvas.getWidth(), canvas.getHeight(), Bitmap.Config.ARGB_8888);
cm.setSaturation(0);
filter = new ColorMatrixColorFilter(cm);
paint.setColorFilter(filter);
saveCanvas.setBitmap(filterPicture);
saveCanvas.drawBitmap(rotate(picture, rotate), 0, 0, paint);
canvas.drawBitmap(rotate(picture, rotate), 0, 0, paint);
break;
case FILTER_NEG:
filterPicture = Bitmap.createBitmap(canvas.getWidth(), canvas.getHeight(), Bitmap.Config.ARGB_8888);
float[] neg = {-1f,0f,0f,0f,255f,
0f,-1f,0f,0f,255f,
0f,0f,-1f,0f,255f,
0f,0f,0f,1f,0f};
cm.set(neg);
filter = new ColorMatrixColorFilter(cm);
paint.setColorFilter(filter);
saveCanvas.setBitmap(filterPicture);
saveCanvas.drawBitmap(rotate(picture, rotate), 0, 0, paint);
canvas.drawBitmap(rotate(picture, rotate), 0, 0, paint);
break;
}
}
/**
* Switches filter to the left.
*/
public static void filterPrev() {
switch (currentFilter) {
case FILTER_NONE:
currentFilter = FILTER_NEG;
break;
case FILTER_SEPIA:
currentFilter = FILTER_NONE;
break;
case FILTER_BW:
currentFilter = FILTER_SEPIA;
break;
case FILTER_NEG:
currentFilter = FILTER_BW;
break;
}
}
/**
* Switches filter to the right.
*/
public static void filterNext() {
switch (currentFilter) {
case FILTER_NONE:
currentFilter = FILTER_SEPIA;
break;
case FILTER_SEPIA:
currentFilter = FILTER_BW;
break;
case FILTER_BW:
currentFilter = FILTER_NEG;
break;
case FILTER_NEG:
currentFilter = FILTER_NONE;
break;
}
}
/**
* Rotates an image by a specified amount of degrees by matrix.
* @param bmp Image to be rotated.
* @param degree Amount of degrees to rotate
* @return Rotated image.
*/
public static Bitmap rotate(Bitmap bmp, int degree) {
Matrix mtx = new Matrix();
mtx.postRotate(degree);
return Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), mtx, true);
}
public Bitmap getPicture() {
picture.recycle();
return filterPicture;
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
/**
* Recycles pictures to free memory.
* @param holder
*/
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
picture.recycle();
filterPicture.recycle();
}
}

View File

@@ -0,0 +1,231 @@
package nl.myhyvesbookplus.tagram;
import android.content.Context;
import android.graphics.Point;
import android.graphics.Rect;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.DecelerateInterpolator;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import com.bumptech.glide.Glide;
import com.firebase.ui.storage.images.FirebaseImageLoader;
import com.google.firebase.storage.FirebaseStorage;
import com.google.firebase.storage.StorageReference;
import java.util.ArrayList;
import nl.myhyvesbookplus.tagram.model.UriPost;
/**
* Created by niels on 27-6-17.
*/
public class ProfileAdapter extends BaseAdapter {
private static final String TAG = "ProfileAdapter";
private LayoutInflater mInflater;
private Context mContext;
private ArrayList<UriPost> mData;
private TextView comment;
private TextView nietSlechts;
private ImageView photo;
private Animator mCurrentAnimator;
ProfileAdapter(Context context, ArrayList<UriPost> data) {
mContext = context;
mInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mData = data;
}
@Override
public int getCount() {
return mData.size();
}
@Override
public Object getItem(int position) {
return mData.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View rowView = mInflater.inflate(R.layout.list_item_timeline_profile, parent, false);
View newRowView = findViews(rowView);
UriPost post = (UriPost) getItem(position);
comment.setText(post.getComment());
final StorageReference ref = FirebaseStorage.getInstance().getReferenceFromUrl(post.getUri());
Glide.with(mContext)
.using(new FirebaseImageLoader())
.load(ref)
.into(photo);
photo.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
zoomImageFromThumb(photo, ref);
}
});
return newRowView;
}
private View findViews(View rowView) {
comment = (TextView) rowView.findViewById(R.id.comment_timeline_profile);
nietSlechts = (TextView) rowView.findViewById(R.id.niet_slecht_count_profile);
photo = (ImageView) rowView.findViewById(R.id.timeline_image_profile);
return rowView;
}
/**
* https://developer.android.com/training/animation/zoom.html
* "Zooms" in a thumbnail view by assigning the high resolution image to a hidden "zoomed-in"
* image view and animating its bounds to fit the entire activity content area.
*
* @param thumbView The thumbnail view to zoom in.
* @param imageRef The high-resolution version of the image represented by the thumbnail.
*/
private void zoomImageFromThumb(final View thumbView, StorageReference imageRef) {
// If there's an animation in progress, cancel it immediately and proceed with this one.
if (mCurrentAnimator != null) {
mCurrentAnimator.cancel();
}
// Load the high-resolution "zoomed-in" image.
final ImageView hiddenView = (ImageView) ((MainActivity) mContext).findViewById(R.id.expanded_image_profile);
Glide.with(mContext)
.using(new FirebaseImageLoader())
.load(imageRef)
.into(hiddenView);
// Calculate the starting and ending bounds for the zoomed-in image. This step
// involves lots of math. Yay, math.
final Rect startBounds = new Rect();
final Rect finalBounds = new Rect();
final Point globalOffset = new Point();
// The start bounds are the global visible rectangle of the thumbnail, and the
// final bounds are the global visible rectangle of the container view. Also
// set the container view's offset as the origin for the bounds, since that's
// the origin for the positioning animation properties (X, Y).
thumbView.getGlobalVisibleRect(startBounds);
((MainActivity) mContext).findViewById(R.id.relative_layout_timeline_profile).getGlobalVisibleRect(finalBounds, globalOffset);
startBounds.offset(-globalOffset.x, -globalOffset.y);
finalBounds.offset(-globalOffset.x, -globalOffset.y);
// Adjust the start bounds to be the same aspect ratio as the final bounds using the
// "center crop" technique. This prevents undesirable stretching during the animation.
// Also calculate the start scaling factor (the end scaling factor is always 1.0).
float startScale;
if ((float) finalBounds.width() / finalBounds.height()
> (float) startBounds.width() / startBounds.height()) {
// Extend start bounds horizontally
startScale = (float) startBounds.height() / finalBounds.height();
float startWidth = startScale * finalBounds.width();
float deltaWidth = (startWidth - startBounds.width()) / 2;
startBounds.left -= deltaWidth;
startBounds.right += deltaWidth;
} else {
// Extend start bounds vertically
startScale = (float) startBounds.width() / finalBounds.width();
float startHeight = startScale * finalBounds.height();
float deltaHeight = (startHeight - startBounds.height()) / 2;
startBounds.top -= deltaHeight;
startBounds.bottom += deltaHeight;
}
// Hide the thumbnail and show the zoomed-in view. When the animation begins,
// it will position the zoomed-in view in the place of the thumbnail.
thumbView.setAlpha(0f);
hiddenView.setVisibility(View.VISIBLE);
// Set the pivot point for SCALE_X and SCALE_Y transformations to the top-left corner of
// the zoomed-in view (the default is the center of the view).
hiddenView.setPivotX(0f);
hiddenView.setPivotY(0f);
// Construct and run the parallel animation of the four translation and scale properties
// (X, Y, SCALE_X, and SCALE_Y).
AnimatorSet set = new AnimatorSet();
set
.play(ObjectAnimator.ofFloat(hiddenView, View.X, startBounds.left,
finalBounds.left))
.with(ObjectAnimator.ofFloat(hiddenView, View.Y, startBounds.top,
finalBounds.top))
.with(ObjectAnimator.ofFloat(hiddenView, View.SCALE_X, startScale, 1f))
.with(ObjectAnimator.ofFloat(hiddenView, View.SCALE_Y, startScale, 1f));
set.setDuration(200);
set.setInterpolator(new DecelerateInterpolator());
set.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
mCurrentAnimator = null;
}
@Override
public void onAnimationCancel(Animator animation) {
mCurrentAnimator = null;
}
});
set.start();
mCurrentAnimator = set;
// Upon clicking the zoomed-in image, it should zoom back down to the original bounds
// and show the thumbnail instead of the expanded image.
final float startScaleFinal = startScale;
hiddenView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (mCurrentAnimator != null) {
mCurrentAnimator.cancel();
}
// Animate the four positioning/sizing properties in parallel, back to their
// original values.
AnimatorSet set = new AnimatorSet();
set
.play(ObjectAnimator.ofFloat(hiddenView, View.X, startBounds.left))
.with(ObjectAnimator.ofFloat(hiddenView, View.Y, startBounds.top))
.with(ObjectAnimator
.ofFloat(hiddenView, View.SCALE_X, startScaleFinal))
.with(ObjectAnimator
.ofFloat(hiddenView, View.SCALE_Y, startScaleFinal));
set.setDuration(200);
set.setInterpolator(new DecelerateInterpolator());
set.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
thumbView.setAlpha(1f);
hiddenView.setVisibility(View.GONE);
mCurrentAnimator = null;
}
@Override
public void onAnimationCancel(Animator animation) {
thumbView.setAlpha(1f);
hiddenView.setVisibility(View.GONE);
mCurrentAnimator = null;
}
});
set.start();
mCurrentAnimator = set;
}
});
}
}

View File

@@ -1,108 +1,240 @@
package nl.myhyvesbookplus.tagram;
import android.content.Context;
import android.app.Fragment;
import android.app.ProgressDialog;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.app.Fragment;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.v4.content.FileProvider;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import com.bumptech.glide.Glide;
import com.firebase.ui.storage.images.FirebaseImageLoader;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.storage.FirebaseStorage;
import com.google.firebase.storage.StorageReference;
import java.io.File;
import java.io.IOException;
/**
* A simple {@link Fragment} subclass.
* Activities that contain this fragment must implement the
* {@link ProfileFragment.OnFragmentInteractionListener} interface
* to handle interaction events.
* Use the {@link ProfileFragment#newInstance} factory method to
* create an instance of this fragment.
*/
public class ProfileFragment extends Fragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
import nl.myhyvesbookplus.tagram.controller.DownloadClass;
import nl.myhyvesbookplus.tagram.controller.ProfilePictureUploader;
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
import static android.app.Activity.RESULT_OK;
private OnFragmentInteractionListener mListener;
public class ProfileFragment extends Fragment implements View.OnClickListener {
static final int REQUEST_TAKE_PHOTO = 1;
ProgressDialog progressDialog;
public ProfileFragment() {
// Required empty public constructor
}
/* Views, buttons and other protected and private inits */
protected Button changePwdButton;
protected ImageButton profilePicButton;
protected StorageReference httpsReference;
protected TextView profileName;
protected ImageView profilePicture;
protected FirebaseUser user;
protected File photoFile;
private ListView listView;
private DownloadClass downloadClass;
private View headerInflater;
private View timeLineInflater;
private ProgressBar progressBar;
/* Required empty public constructor */
public ProfileFragment() {}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* @param param1 Parameter 1.
* @param param2 Parameter 2.
* @return A new instance of fragment ProfileFragment.
* Overridden onCreate which initializes a user and sets the default photoFile to null.
* @param savedInstanceState The standard return of the onCreate method.
*/
// TODO: Rename and change types and number of parameters
public static ProfileFragment newInstance(String param1, String param2) {
ProfileFragment fragment = new ProfileFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
user = FirebaseAuth.getInstance().getCurrentUser();
photoFile = null;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_profile, container, false);
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
/**
* Assigns all views and buttons for the header.
*/
protected void findHeaderViews() {
profilePicButton = (ImageButton) headerInflater.findViewById(R.id.profile_pic_button);
profilePicture = (ImageView) headerInflater.findViewById(R.id.imageView_profile_picture);
profileName = (TextView) headerInflater.findViewById(R.id.profile_name);
changePwdButton = (Button) headerInflater.findViewById(R.id.change_psw_button);
bindOnClick();
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
* Assign the ListView and add the header to it.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
protected void findTimelineViews() {
listView = (ListView) timeLineInflater.findViewById(R.id.list);
listView.addHeaderView(headerInflater);
}
/**
* Bind the buttons to their listeners.
*/
protected void bindOnClick() {
profilePicButton.setOnClickListener(this);
changePwdButton.setOnClickListener(this);
}
/**
* Overridden onCreateView which serves as a fragment content creator.
* Checks for user data to be displayed.
*
* @param inflater The inflater used for the fragment.
* @param container The container which holds this fragment.
* @param savedInstanceState The state which was provided by onCreate.
* @return the timeLineInflater View which is required for the ListView to be updated.
*/
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
timeLineInflater = inflater.inflate(R.layout.fragment_profile_timeline, container, false);
headerInflater = inflater.inflate(R.layout.fragment_profile_header, listView, false);
progressBar = (ProgressBar) timeLineInflater.findViewById(R.id.progressbar_timeline);
progressBar.setVisibility(View.VISIBLE);
findHeaderViews();
findTimelineViews();
profilePicture.invalidate();
if (user != null) {
if(user.getPhotoUrl() != null) {
httpsReference = FirebaseStorage.getInstance().getReferenceFromUrl(user.getPhotoUrl().toString());
}
if (user.getDisplayName() != null) {
profileName.setText(user.getDisplayName());
}
}
if (httpsReference != null) {
Glide.with(this).using(new FirebaseImageLoader()).load(httpsReference).into(profilePicture);
}
downloadClass = new DownloadClass(getActivity());
downloadClass.getPostsFromServer();
return timeLineInflater;
}
/**
* Called when a view has been clicked.
*
* @param view The view that was clicked.
*/
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.profile_pic_button:
profilePicOnClick();
break;
case R.id.change_psw_button:
changePwdOnClick();
break;
}
}
/**
* Starts new intent for access to the built-in camera of device.
*/
private void profilePicOnClick() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getActivity().getPackageManager()) != null) {
try {
photoFile = createImageFile();
} catch (IOException ex) {
Toast.makeText(getActivity(), getString(R.string.image_save_error),
Toast.LENGTH_LONG).show();
}
if (photoFile != null) {
Uri photoURI = FileProvider.getUriForFile(getActivity(),
"nl.myhyvesbookplus.tagram.fileprovider",
photoFile);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
}
}
}
/**
* Start display of the list; uses an adapter and listener in the main activity.
*/
public void startList() {
ProfileAdapter adapter = new ProfileAdapter(getActivity(), downloadClass.getOwnPosts());
listView.setAdapter(adapter);
progressBar.setVisibility(View.GONE);
}
/**
* Grabs the image just taken by the built-in camera and pushes this image to the user account.
*
* @param requestCode The code which corresponds to REQUEST_TAKE_PHOTO. Used as indicator.
* @param resultCode Code should be RESULT_OK to allow camera to proceed.
* @param data The image data from the camera.
*/
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_TAKE_PHOTO && resultCode == RESULT_OK) {
progressDialog = ProgressDialog.show(getActivity(), getString(R.string.please_wait), getString(R.string.upload_profile_pic), false, false);
ProfilePictureUploader profilePictureUploader = new ProfilePictureUploader(getActivity());
profilePictureUploader.uploadProfilePicture(photoFile);
}
}
/**
* Create the file which the camera requires to save a proper quality picture to.
*
* @return The new file.
* @throws IOException when insufficient permission or storage available.
*/
private File createImageFile() throws IOException {
String imageFileName = "JPEG_" + user.getUid();
File storageDir = getActivity().getExternalFilesDir(Environment.DIRECTORY_PICTURES);
return File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
}
/**
* Performs password reset action.
*/
public void changePwdOnClick() {
if (user != null && user.getEmail() != null) {
FirebaseAuth.getInstance().sendPasswordResetEmail(user.getEmail())
.addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
Toast.makeText(getActivity(), task.isSuccessful()
? getString(R.string.mail_successful)
: getString(R.string.mail_failed),
Toast.LENGTH_SHORT).show();
}
});
}
}
}

View File

@@ -0,0 +1,272 @@
package nl.myhyvesbookplus.tagram;
import android.content.Context;
import android.graphics.Point;
import android.graphics.Rect;
import android.support.annotation.NonNull;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.DecelerateInterpolator;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import com.bumptech.glide.Glide;
import com.firebase.ui.storage.images.FirebaseImageLoader;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
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 java.util.ArrayList;
import nl.myhyvesbookplus.tagram.model.UriPost;
/**
* Created by marijnjansen on 26/06/2017.
*/
public class TimeLineAdapter extends BaseAdapter implements AdapterView.OnItemClickListener {
private static final String TAG = "TimeLineAdapter";
private LayoutInflater mInflater;
private Context mContext;
private ArrayList<UriPost> mData;
private DatabaseReference mRef;
private Animator mCurrentAnimator;
TimeLineAdapter(Context context, ArrayList<UriPost> data) {
mContext = context;
mInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mData = data;
mRef = FirebaseDatabase.getInstance().getReference();
}
@Override
public int getCount() {
return mData.size();
}
@Override
public Object getItem(int position) {
return mData.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
View rowView = mInflater.inflate(R.layout.list_item_timeline, parent, false);
TextView userName = (TextView) rowView.findViewById(R.id.username_timeline);
TextView comment = (TextView) rowView.findViewById(R.id.comment_timeline);
final TextView nietSlechts = (TextView) rowView.findViewById(R.id.niet_slecht_count);
TextView dateTime = (TextView) rowView.findViewById(R.id.timeline_date);
final ImageView photo = (ImageView) rowView.findViewById(R.id.timeline_image);
final ImageButton nietSlechtButton = (ImageButton) rowView.findViewById(R.id.niet_slecht_button);
final UriPost post = (UriPost) getItem(position);
nietSlechts.setText(Integer.toString(post.getNietSlechts()));
comment.setText(post.getComment());
nietSlechtButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d(TAG, "onClick: " + position);
mRef.child("posts").child(post.getDatabaseEntryName())
.child("nietSlechts").setValue(post.getNietSlechts() + 1)
.addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
nietSlechts.setText(Integer.toString(post.getNietSlechts() + 1));
}
});
}
});
dateTime.setText(post.getDate().toString());
final StorageReference ref = FirebaseStorage.getInstance().getReferenceFromUrl(post.getUri());
Glide.with(mContext)
.using(new FirebaseImageLoader())
.load(ref)
.into(photo);
photo.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
zoomImageFromThumb(photo, ref);
}
});
return rowView;
}
/**
* Callback method to be invoked when an item in this AdapterView has
* been clicked.
* <p>
* Implementers can call getItemAtPosition(position) if they need
* to access the data associated with the selected item.
*
* @param parent The AdapterView where the click happened.
* @param view The view within the AdapterView that was clicked (this
* will be a view provided by the adapter)
* @param position The position of the view in the adapter.
* @param id The row id of the item that was clicked.
*/
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Log.d(TAG, "onItemClick: rowNumber! "+ position);
}
/**
* https://developer.android.com/training/animation/zoom.html
* "Zooms" in a thumbnail view by assigning the high resolution image to a hidden "zoomed-in"
* image view and animating its bounds to fit the entire activity content area.
*
* @param thumbView The thumbnail view to zoom in.
* @param imageRef The high-resolution version of the image represented by the thumbnail.
*/
private void zoomImageFromThumb(final View thumbView, StorageReference imageRef) {
// If there's an animation in progress, cancel it immediately and proceed with this one.
if (mCurrentAnimator != null) {
mCurrentAnimator.cancel();
}
// Load the high-resolution "zoomed-in" image.
final ImageView hiddenView = (ImageView) ((MainActivity) mContext).findViewById(R.id.expanded_image);
Glide.with(mContext)
.using(new FirebaseImageLoader())
.load(imageRef)
.into(hiddenView);
// Calculate the starting and ending bounds for the zoomed-in image. This step
// involves lots of math. Yay, math.
final Rect startBounds = new Rect();
final Rect finalBounds = new Rect();
final Point globalOffset = new Point();
// The start bounds are the global visible rectangle of the thumbnail, and the
// final bounds are the global visible rectangle of the container view. Also
// set the container view's offset as the origin for the bounds, since that's
// the origin for the positioning animation properties (X, Y).
thumbView.getGlobalVisibleRect(startBounds);
((MainActivity) mContext).findViewById(R.id.relative_layout_timeline).getGlobalVisibleRect(finalBounds, globalOffset);
startBounds.offset(-globalOffset.x, -globalOffset.y);
finalBounds.offset(-globalOffset.x, -globalOffset.y);
// Adjust the start bounds to be the same aspect ratio as the final bounds using the
// "center crop" technique. This prevents undesirable stretching during the animation.
// Also calculate the start scaling factor (the end scaling factor is always 1.0).
float startScale;
if ((float) finalBounds.width() / finalBounds.height()
> (float) startBounds.width() / startBounds.height()) {
// Extend start bounds horizontally
startScale = (float) startBounds.height() / finalBounds.height();
float startWidth = startScale * finalBounds.width();
float deltaWidth = (startWidth - startBounds.width()) / 2;
startBounds.left -= deltaWidth;
startBounds.right += deltaWidth;
} else {
// Extend start bounds vertically
startScale = (float) startBounds.width() / finalBounds.width();
float startHeight = startScale * finalBounds.height();
float deltaHeight = (startHeight - startBounds.height()) / 2;
startBounds.top -= deltaHeight;
startBounds.bottom += deltaHeight;
}
// Hide the thumbnail and show the zoomed-in view. When the animation begins,
// it will position the zoomed-in view in the place of the thumbnail.
thumbView.setAlpha(0f);
hiddenView.setVisibility(View.VISIBLE);
// Set the pivot point for SCALE_X and SCALE_Y transformations to the top-left corner of
// the zoomed-in view (the default is the center of the view).
hiddenView.setPivotX(0f);
hiddenView.setPivotY(0f);
// Construct and run the parallel animation of the four translation and scale properties
// (X, Y, SCALE_X, and SCALE_Y).
AnimatorSet set = new AnimatorSet();
set
.play(ObjectAnimator.ofFloat(hiddenView, View.X, startBounds.left,
finalBounds.left))
.with(ObjectAnimator.ofFloat(hiddenView, View.Y, startBounds.top,
finalBounds.top))
.with(ObjectAnimator.ofFloat(hiddenView, View.SCALE_X, startScale, 1f))
.with(ObjectAnimator.ofFloat(hiddenView, View.SCALE_Y, startScale, 1f));
set.setDuration(200);
set.setInterpolator(new DecelerateInterpolator());
set.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
mCurrentAnimator = null;
}
@Override
public void onAnimationCancel(Animator animation) {
mCurrentAnimator = null;
}
});
set.start();
mCurrentAnimator = set;
// Upon clicking the zoomed-in image, it should zoom back down to the original bounds
// and show the thumbnail instead of the expanded image.
final float startScaleFinal = startScale;
hiddenView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (mCurrentAnimator != null) {
mCurrentAnimator.cancel();
}
// Animate the four positioning/sizing properties in parallel, back to their
// original values.
AnimatorSet set = new AnimatorSet();
set
.play(ObjectAnimator.ofFloat(hiddenView, View.X, startBounds.left))
.with(ObjectAnimator.ofFloat(hiddenView, View.Y, startBounds.top))
.with(ObjectAnimator
.ofFloat(hiddenView, View.SCALE_X, startScaleFinal))
.with(ObjectAnimator
.ofFloat(hiddenView, View.SCALE_Y, startScaleFinal));
set.setDuration(200);
set.setInterpolator(new DecelerateInterpolator());
set.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
thumbView.setAlpha(1f);
hiddenView.setVisibility(View.GONE);
mCurrentAnimator = null;
}
@Override
public void onAnimationCancel(Animator animation) {
thumbView.setAlpha(1f);
hiddenView.setVisibility(View.GONE);
mCurrentAnimator = null;
}
});
set.start();
mCurrentAnimator = set;
}
});
}
}

View File

@@ -1,108 +1,101 @@
package nl.myhyvesbookplus.tagram;
import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
import android.app.Fragment;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.widget.SwipeRefreshLayout;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.Toast;
import nl.myhyvesbookplus.tagram.controller.DownloadClass;
/**
* A simple {@link Fragment} subclass.
* Activities that contain this fragment must implement the
* {@link TimelineFragment.OnFragmentInteractionListener} interface
* to handle interaction events.
* Use the {@link TimelineFragment#newInstance} factory method to
* create an instance of this fragment.
*/
public class TimelineFragment extends Fragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
/* Some protected and private inits */
private ListView listView;
private DownloadClass downloadClass;
private ProgressBar progressBar;
private OnFragmentInteractionListener mListener;
public TimelineFragment() {
// Required empty public constructor
}
/* Required empty public constructor */
public TimelineFragment() {}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* @param param1 Parameter 1.
* @param param2 Parameter 2.
* @return A new instance of fragment TimelineFragment.
* Overridden onCreate which also starts a progress dialog for the posts being downloaded.
* @param savedInstanceState The standard return of the onCreate method.
*/
// TODO: Rename and change types and number of parameters
public static TimelineFragment newInstance(String param1, String param2) {
TimelineFragment fragment = new TimelineFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_timeline, container, false);
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
// progressDialog = ProgressDialog.show(getActivity(), getString(R.string.please_wait), getString(R.string.downloading_posts), false, false);
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
* Overridden onCreateView method which creates the ListView and contains a possible refresh
* functionality (swipe down page for result).
*
* https://www.survivingwithandroid.com/2014/05/android-swiperefreshlayout-tutorial-2.html
* Above reference was largely copied from.
* @param inflater The inflater used for the fragment.
* @param container The container which holds this fragment.
* @param savedInstanceState The state which was provided by onCreate.
* @return the timeLineInflater View which is required for the ListView to be updated.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View timeLineInflater = inflater.inflate(R.layout.fragment_timeline, container, false);
listView = (ListView) timeLineInflater.findViewById(R.id.list);
final SwipeRefreshLayout swipeView = (SwipeRefreshLayout) timeLineInflater.findViewById(R.id.swipe);
progressBar = (ProgressBar) timeLineInflater.findViewById(R.id.progressbar_timeline);
progressBar.setVisibility(View.VISIBLE);
swipeView.setEnabled(false);
downloadClass = new DownloadClass(getActivity());
downloadClass.getPostsFromServer();
swipeView.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
downloadClass.getPostsFromServer();
Toast.makeText(getActivity(), R.string.refreshing,
Toast.LENGTH_LONG).show();
swipeView.setRefreshing(true);
( new Handler()).postDelayed(new Runnable() {
@Override
public void run() {
swipeView.setRefreshing(false);
}
}, 1000);
}
});
listView.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView absListView, int i) {
}
@Override
public void onScroll(AbsListView absListView, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
swipeView.setEnabled(firstVisibleItem == 0);
}
});
return timeLineInflater;
}
/**
* Start display of the list; uses an adapter and listener in the main activity.
*/
public void startList() {
TimeLineAdapter adapter = new TimeLineAdapter(getActivity(), downloadClass.getmList());
listView.setAdapter(adapter);
progressBar.setVisibility(View.GONE);
}
}

View File

@@ -0,0 +1,82 @@
package nl.myhyvesbookplus.tagram.controller;
import android.content.Context;
import android.util.Log;
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 nl.myhyvesbookplus.tagram.model.UriPost;
/**
* Created by marijnjansen on 23/06/2017.
*/
public class DownloadClass {
private static final String TAG = "DownloadClass";
private DatabaseReference mDataRef;
private ArrayList<UriPost> mList;
private PostDownloadListener mListener;
public DownloadClass(Context context) {
if (context instanceof DownloadClass.PostDownloadListener) {
mListener = (PostDownloadListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement PostDownloadListener");
}
mDataRef = FirebaseDatabase.getInstance().getReference();
}
public void getPostsFromServer() {
mList = new ArrayList<>();
mDataRef.child("posts").addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot data : dataSnapshot.getChildren()) {
UriPost tempPost = data.getValue(UriPost.class);
tempPost.setDatabaseEntryName(data.getKey());
mList.add(tempPost);
}
Collections.reverse(mList);
mListener.PostDownloaded();
}
@Override
public void onCancelled(DatabaseError databaseError) {
Log.d(TAG, "onCancelled: " + databaseError.getDetails() + databaseError.getMessage());
}
});
}
public ArrayList<UriPost> getmList() {
return mList;
}
public ArrayList<UriPost> getOwnPosts() {
String currentUid = FirebaseAuth.getInstance().getCurrentUser().getUid();
ArrayList<UriPost> posts = new ArrayList<>();
for (UriPost post : mList) {
if (post.getPoster().equals(currentUid)) {
posts.add(post);
}
}
return posts;
}
public interface PostDownloadListener {
void PostDownloaded();
}
}

View File

@@ -0,0 +1,83 @@
package nl.myhyvesbookplus.tagram.controller;
import android.content.Context;
import android.net.Uri;
import android.support.annotation.NonNull;
import android.util.Log;
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.database.DatabaseReference;
import com.google.firebase.storage.UploadTask;
import nl.myhyvesbookplus.tagram.model.BitmapPost;
import nl.myhyvesbookplus.tagram.model.UriPost;
import static java.lang.System.currentTimeMillis;
/**
* Created by marijnjansen on 25/06/2017.
*/
public class PostUploader extends UploadClass {
final private static String TAG = "PostUploader";
private PostUploadListener mListener;
public PostUploader(Context context) {
super();
if (context instanceof PostUploadListener) {
mListener = (PostUploadListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement PostUploadListener");
}
}
public void uploadPicture(final BitmapPost post) {
final String name = currentTimeMillis() + "_" + getUserUid();
UploadTask uploadTask = mStorageRef.child("posts").child(name + ".jpg").putBytes(bitmapToBytes(post.getBitmap()));
uploadTask.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Log.d(TAG, "onFailure: Upload Failed");
mListener.PostUploadComplete(false);
}
})
.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
@Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
// Handle successful uploads on complete
Log.d(TAG, "onSuccess: Upload Success!");
Uri downloadUrl = taskSnapshot.getMetadata().getDownloadUrl();
putPostInDatabase(post.getUriPost(downloadUrl), name);
}
});
}
private void putPostInDatabase(UriPost post, String name) {
DatabaseReference ref = mDataRef.child("posts").child(name);
ref.setValue(post)
.addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()) {
Log.d(TAG, "onComplete: Added post to database");
mListener.PostUploadComplete(true);
} else {
Log.d(TAG, "onComplete: " + task.getException().getLocalizedMessage());
mListener.PostUploadComplete(false);
}
}
});
}
public interface PostUploadListener {
void PostUploadComplete(Boolean success);
}
}

View File

@@ -0,0 +1,103 @@
package nl.myhyvesbookplus.tagram.controller;
import android.content.Context;
import android.graphics.Bitmap;
import android.net.Uri;
import android.support.annotation.NonNull;
import android.util.Log;
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.UserProfileChangeRequest;
import com.google.firebase.storage.FirebaseStorage;
import com.google.firebase.storage.StorageMetadata;
import com.google.firebase.storage.StorageReference;
import com.google.firebase.storage.UploadTask;
import java.io.File;
import static java.lang.System.currentTimeMillis;
/**
* Created by marijnjansen on 25/06/2017.
*/
public class ProfilePictureUploader extends UploadClass {
final static private String TAG = "PPUploader";
private Uri oldPicture;
private ProfilePictureUpdatedListener mListener;
public ProfilePictureUploader(Context context) {
super();
if (context instanceof ProfilePictureUpdatedListener) {
mListener = (ProfilePictureUpdatedListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement ProfilePictureUpdatedListener");
}
}
public void uploadProfilePicture(File picture) {
oldPicture = mUser.getPhotoUrl();
StorageMetadata metadata = new StorageMetadata.Builder()
.setContentType("image/jpg")
.build();
UploadTask photoUpload = mStorageRef.child("profile").child(getUserUid() + "_" + currentTimeMillis()).putFile(Uri.fromFile(picture), metadata);
photoUpload.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
@Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
Uri downloadUrl = taskSnapshot.getDownloadUrl();
updateProfilePictureInUser(downloadUrl);
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
mListener.ProfilePictureUpdated(false);
}
});
}
private void updateProfilePictureInUser(Uri url) {
UserProfileChangeRequest request = new UserProfileChangeRequest.Builder()
.setPhotoUri(url)
.build();
mUser.updateProfile(request)
.addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
Log.d(TAG, "onComplete: Updated profile picture");
mListener.ProfilePictureUpdated(true);
if (oldPicture != null) {
removeOldPicture();
}
}
});
}
private void removeOldPicture() {
StorageReference ref = FirebaseStorage.getInstance().getReferenceFromUrl(oldPicture.toString());
ref.delete()
.addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()) {
Log.v(TAG, "onComplete: Delete successful");
} else {
Log.v(TAG, "onComplete: " + task.getException().getLocalizedMessage());
}
}
});
}
public interface ProfilePictureUpdatedListener {
void ProfilePictureUpdated(Boolean success);
}
}

View File

@@ -0,0 +1,44 @@
package nl.myhyvesbookplus.tagram.controller;
import android.graphics.Bitmap;
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.storage.FirebaseStorage;
import com.google.firebase.storage.StorageReference;
import java.io.ByteArrayOutputStream;
/**
* Class that does all the photo uploading things.
*/
public abstract class UploadClass {
private static final String TAG = "UploadClass";
StorageReference mStorageRef;
DatabaseReference mDataRef;
FirebaseUser mUser;
UploadClass() {
mStorageRef = FirebaseStorage.getInstance().getReference();
mDataRef = FirebaseDatabase.getInstance().getReference();
mUser = FirebaseAuth.getInstance().getCurrentUser();
}
/// Helpers ///
byte[] bitmapToBytes(Bitmap bitmap) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
return baos.toByteArray();
}
String getUserUid() {
if (mUser != null) {
return mUser.getUid();
}
return "";
}
}

View File

@@ -0,0 +1,35 @@
package nl.myhyvesbookplus.tagram.model;
import android.graphics.Bitmap;
import android.net.Uri;
import java.util.Date;
/**
* BitmapPost is a Class for a Post with a Bitmap as an image.
*/
public class BitmapPost extends Post {
private Bitmap photo;
public BitmapPost(Bitmap photo, String comment, Date date, int nietSlechts, String poster) {
super(comment, date, nietSlechts, poster);
this.photo = photo;
}
public BitmapPost(Bitmap photo, String comment) {
super(comment);
this.photo = photo;
}
public Bitmap getBitmap() {
return photo;
}
public UriPost getUriPost(Uri url) {
return new UriPost(url, getComment(), getDate(), getNietSlechts(), getPoster());
}
public void setPhoto(Bitmap photo) {
this.photo = photo;
}
}

View File

@@ -0,0 +1,63 @@
package nl.myhyvesbookplus.tagram.model;
import com.google.firebase.auth.FirebaseAuth;
import java.util.Date;
/**
* Post is a Class for a Post with a Bitmap as an image.
*/
abstract class Post {
private Date date;
private String comment;
private int nietSlechts;
private String poster;
Post() {
// Default constructor required for calls to Post.getValue(User.class)
}
Post(String comment, Date date, int nietSlechts, String poster) {
this.date = date;
this.comment = comment;
this.nietSlechts = nietSlechts;
this.poster = poster;
}
Post(String comment) {
this(comment, new Date(), 0, FirebaseAuth.getInstance().getCurrentUser().getUid());
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
public int getNietSlechts() {
return nietSlechts;
}
public void setNietSlechts(int nietSlechts) {
this.nietSlechts = nietSlechts;
}
public String getPoster() {
return poster;
}
public void setPoster(String poster) {
this.poster = poster;
}
}

View File

@@ -0,0 +1,45 @@
package nl.myhyvesbookplus.tagram.model;
import android.net.Uri;
import java.util.Date;
/**
* UriPost is a Class for a Post with a Uri as an image.
*/
public class UriPost extends Post {
private String uri;
private String databaseEntryName;
public UriPost() {
// Default constructor required for calls to DataSnapshot.getValue(UriPost.class)
}
public UriPost(Uri uri, String comment, Date date, int nietSlechts, String poster) {
super(comment, date, nietSlechts, poster);
this.uri = uri.toString();
}
public UriPost(String uri, String comment) {
super(comment);
this.uri = uri;
}
public String getUri() {
return uri;
}
public void setUri(String uri) {
this.uri = uri;
}
public String getDatabaseEntryName() {
return databaseEntryName;
}
public void setDatabaseEntryName(String databaseEntryName) {
this.databaseEntryName = databaseEntryName;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

View File

@@ -5,5 +5,5 @@
android:viewportWidth="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M3,13h8L11,3L3,3v10zM3,21h8v-6L3,15v6zM13,21h8L21,11h-8v10zM13,3v6h8L21,3h-8z" />
android:pathData="M3,5v14c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2L21,5c0,-1.1 -0.9,-2 -2,-2L5,3c-1.11,0 -2,0.9 -2,2zM15,9c0,1.66 -1.34,3 -3,3s-3,-1.34 -3,-3 1.34,-3 3,-3 3,1.34 3,3zM6,17c0,-2 4,-3.1 6,-3.1s6,1.1 6,3.1v1L6,18v-1z" />
</vector>

View File

@@ -0,0 +1,11 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:strokeColor="#AAAAAA" android:strokeWidth="0.5"
android:fillColor="#FFFFFFFF"
android:fillAlpha="0.5"
android:pathData="M20,11H7.83l5.59,-5.59L12,4l-8,8 8,8 1.41,-1.41L7.83,13H20v-2z"/>
</vector>

View File

@@ -0,0 +1,11 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:strokeColor="#AAAAAA" android:strokeWidth="0.5"
android:fillColor="#FFFFFFFF"
android:fillAlpha="0.5"
android:pathData="M12,4l-1.41,1.41L16.17,11H4v2h12.17l-5.58,5.59L12,20l8,-8z"/>
</vector>

View File

@@ -0,0 +1,11 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:strokeColor="#AAAAAA" android:strokeWidth="0.5"
android:fillColor="#FFFFFFFF"
android:fillAlpha="0.5"
android:pathData="M9.4,10.5l4.77,-8.26C13.47,2.09 12.75,2 12,2c-2.4,0 -4.6,0.85 -6.32,2.25l3.66,6.35 0.06,-0.1zM21.54,9c-0.92,-2.92 -3.15,-5.26 -6,-6.34L11.88,9h9.66zM21.8,10h-7.49l0.29,0.5 4.76,8.25C21,16.97 22,14.61 22,12c0,-0.69 -0.07,-1.35 -0.2,-2zM8.54,12l-3.9,-6.75C3.01,7.03 2,9.39 2,12c0,0.69 0.07,1.35 0.2,2h7.49l-1.15,-2zM2.46,15c0.92,2.92 3.15,5.26 6,6.34L12.12,15L2.46,15zM13.73,15l-3.9,6.76c0.7,0.15 1.42,0.24 2.17,0.24 2.4,0 4.6,-0.85 6.32,-2.25l-3.66,-6.35 -0.93,1.6z"/>
</vector>

View File

@@ -1,9 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M12,22c1.1,0 2,-0.9 2,-2h-4c0,1.1 0.89,2 2,2zM18,16v-5c0,-3.07 -1.64,-5.64 -4.5,-6.32L13.5,4c0,-0.83 -0.67,-1.5 -1.5,-1.5s-1.5,0.67 -1.5,1.5v0.68C7.63,5.36 6,7.92 6,11v5l-2,2v1h16v-1l-2,-2z" />
</vector>

View File

@@ -0,0 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M12,12m-3.2,0a3.2,3.2 0,1 1,6.4 0a3.2,3.2 0,1 1,-6.4 0" />
<path
android:fillColor="#FF000000"
android:pathData="M9,2L7.17,4L4,4c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2L22,6c0,-1.1 -0.9,-2 -2,-2h-3.17L15,2L9,2zM12,17c-2.76,0 -5,-2.24 -5,-5s2.24,-5 5,-5 5,2.24 5,5 -2.24,5 -5,5z" />
</vector>

View File

@@ -0,0 +1,11 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:strokeColor="#AAAAAA" android:strokeWidth="0.5"
android:fillColor="#FFFFFFFF"
android:fillAlpha="0.5"
android:pathData="M20,4h-3.17L15,2L9,2L7.17,4L4,4c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2L22,6c0,-1.1 -0.9,-2 -2,-2zM15,15.5L15,13L9,13v2.5L5.5,12 9,8.5L9,11h6L15,8.5l3.5,3.5 -3.5,3.5z"/>
</vector>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

View File

@@ -1,113 +1,121 @@
<?xml version="1.0" encoding="utf-8"?><!--<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"--><!--xmlns:app="http://schemas.android.com/apk/res-auto"--><!--xmlns:tools="http://schemas.android.com/tools"--><!--android:layout_width="match_parent"--><!--android:layout_height="match_parent"--><!--tools:context="nl.myhyvesbookplus.tagram.LoginActivity">-->
<!--</android.support.constraint.ConstraintLayout>-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".LoginActivity">
<ImageView
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:cropToPadding="false"
android:padding="16dp"
android:src="@drawable/logo" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:labelFor="@+id/email"
android:text="@string/email" />
android:layout_height="match_parent">
<EditText
android:id="@+id/email"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textEmailAddress" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/username_label"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:labelFor="@+id/username"
android:text="@string/username"
android:visibility="gone" />
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:contentDescription="@string/logo_text"
android:cropToPadding="false"
android:paddingEnd="@dimen/activity_horizontal_margin"
android:paddingStart="@dimen/activity_horizontal_margin"
android:src="@drawable/logo_new" />
<EditText
android:id="@+id/username"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="text"
android:visibility="gone" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:labelFor="@+id/email"
android:text="@string/email" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:labelFor="@+id/password"
android:text="@string/password" />
<EditText
android:id="@+id/email"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textEmailAddress" />
<EditText
android:id="@+id/password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPassword" />
<TextView
android:id="@+id/username_label"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:labelFor="@+id/username"
android:text="@string/username"
android:visibility="gone" />
<TextView
android:id="@+id/confirm_password_label"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/confirm_password"
android:visibility="gone" />
<EditText
android:id="@+id/username"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="text"
android:visibility="gone" />
<EditText
android:id="@+id/confirm_password_field"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPassword"
android:visibility="gone" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:labelFor="@+id/password"
android:text="@string/password" />
<Button
android:id="@+id/login_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:layout_marginStart="16dp"
android:onClick="logInOnClick"
android:text="@string/login_button" />
<EditText
android:id="@+id/password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPassword" />
<Button
android:id="@+id/go_to_register_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:layout_marginStart="16dp"
android:onClick="goToRegisterOnClick"
android:text="@string/register" />
<TextView
android:id="@+id/confirm_password_label"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/confirm_password"
android:visibility="gone" />
<Button
android:id="@+id/register_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:layout_marginStart="16dp"
android:onClick="registerOnClick"
android:text="@string/register"
android:visibility="gone" />
<EditText
android:id="@+id/confirm_password_field"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPassword"
android:visibility="gone" />
<Button
android:id="@+id/back_to_login_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:layout_marginStart="16dp"
android:onClick="backToLoginOnClick"
android:text="@string/back_to_login"
android:visibility="gone" />
<Button
android:id="@+id/login_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:layout_marginStart="16dp"
android:text="@string/login_button" />
</LinearLayout>
<Button
android:id="@+id/go_to_register_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:layout_marginStart="16dp"
android:text="@string/register" />
<Button
android:id="@+id/register_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:layout_marginStart="16dp"
android:text="@string/register"
android:visibility="gone" />
<Button
android:id="@+id/back_to_login_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:layout_marginStart="16dp"
android:text="@string/back_to_login"
android:visibility="gone" />
</LinearLayout>
</ScrollView>
</FrameLayout>

View File

@@ -13,7 +13,7 @@
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:padding="16dp">
android:padding="0dp">
</FrameLayout>
<android.support.design.widget.BottomNavigationView

View File

@@ -1,25 +1,133 @@
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="nl.myhyvesbookplus.tagram.CameraFragment">
<LinearLayout
<RelativeLayout
android:id="@+id/camera_preview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
android:layout_height="match_parent" >
<TextView
<ImageButton
android:id="@+id/picture_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:background="@android:color/transparent"
android:layout_margin="10dp"
android:padding="15dp"
android:scaleType="center"
android:scaleX="2.5"
android:scaleY="2.5"
android:src="@drawable/ic_camera_black_24dp"/>
<ImageButton
android:id="@+id/switch_camera_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:padding="10dp"
android:layout_margin="9dp"
android:scaleX="1.5"
android:scaleY="1.5"
android:background="@android:color/transparent"
android:src="@drawable/ic_switch_camera_black_24dp"/>
<RelativeLayout
android:id="@+id/filter_buttons"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/hello_camera" />
android:visibility="gone"
android:layout_marginBottom="60dp"
android:layout_centerVertical="true">
<Button
<ImageButton
android:id="@+id/filter_left"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:scaleX="2"
android:scaleY="2"
android:padding="10dp"
android:layout_margin="10dp"
android:layout_alignParentLeft="true"
android:src="@drawable/ic_arrow_back_black_24dp"/>
<ImageButton
android:id="@+id/filter_right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:scaleX="2"
android:scaleY="2"
android:padding="10dp"
android:layout_margin="10dp"
android:layout_alignParentRight="true"
android:src="@drawable/ic_arrow_forward_black_24dp"/>
</RelativeLayout>
<LinearLayout
android:id="@+id/comment_box"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="logOutOnClick"
android:text="LogOut" />
</LinearLayout>
<!-- TODO: Update blank fragment layout -->
android:visibility="gone"
android:clickable="false"
android:layout_margin="10dp"
android:padding="5dp"
android:background="@android:color/background_light"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/comment"/>
<EditText
android:id="@+id/comment_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:lines="4"
android:layout_margin="4dp"
android:padding="5dp"
android:background="@android:color/darker_gray"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/comment_submit"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/upload"/>
<Button
android:id="@+id/comment_cancel"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/cancel"/>
</LinearLayout>
</LinearLayout>
<android.support.design.widget.FloatingActionButton
android:id="@+id/upload_button"
android:visibility="gone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:scaleType="center"
android:layout_margin="15dp"
app:fabSize="normal"
android:src="@android:drawable/ic_menu_upload"/>
</RelativeLayout>
</FrameLayout>

View File

@@ -1,13 +0,0 @@
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="nl.myhyvesbookplus.tagram.ProfileFragment">
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@string/hello_blank_fragment" />
</FrameLayout>

View File

@@ -0,0 +1,76 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<Space
android:layout_width="match_parent"
android:layout_height="5dp" />
<TextView
android:id="@+id/profile_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="Name:"
android:textSize="25sp"
android:textStyle="bold" />
<Space
android:layout_width="match_parent"
android:layout_height="10dp" />
<ImageButton
android:id="@+id/profile_pic_button"
android:layout_width="60dp"
android:layout_height="80dp"
android:layout_marginStart="110dp"
android:background="@android:color/transparent"
android:elevation="1dp"
app:srcCompat="@android:drawable/ic_menu_camera" />
<ImageView
android:id="@+id/imageView_profile_picture"
android:contentDescription="@string/profile_picture_description"
android:layout_width="match_parent"
android:layout_height="300dp"
app:srcCompat="@drawable/avatar_standard"
android:layout_marginTop="-70dp"/>
<Space
android:layout_width="match_parent"
android:layout_height="25dp" />
<Button
android:id="@+id/change_psw_button"
android:layout_width="300dp"
android:layout_height="50dp"
android:background="?attr/colorPrimary"
android:text="@string/change_psw_button"
android:textColor="@android:color/white"
android:textSize="16sp" />
<Space
android:layout_width="match_parent"
android:layout_height="20dp" />
<Button
android:id="@+id/logout_button"
android:layout_width="300dp"
android:layout_height="50dp"
android:background="?attr/colorPrimary"
android:onClick="logOutOnClick"
android:text="@string/logout_button"
android:textColor="@android:color/white"
android:textSize="16sp" />
<Space
android:layout_width="match_parent"
android:layout_height="10dp" />
<Space
android:layout_width="match_parent"
android:layout_height="10dp" />
</LinearLayout>

View File

@@ -0,0 +1,35 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/relative_layout_timeline_profile"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="nl.myhyvesbookplus.tagram.TimelineFragment">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ProgressBar
android:id="@+id/progressbar_timeline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:indeterminate="true"
android:visibility="gone"/>
<ListView
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent">
</ListView>
</RelativeLayout>
<ImageView
android:id="@+id/expanded_image_profile"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="invisible" />
</RelativeLayout>

View File

@@ -1,13 +1,43 @@
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/relative_layout_timeline"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="nl.myhyvesbookplus.tagram.TimelineFragment">
<!-- TODO: Update blank fragment layout -->
<TextView
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ProgressBar
android:id="@+id/progressbar_timeline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:indeterminate="true"
android:visibility="gone"/>
<android.support.v4.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/swipe"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent">
</ListView>
</android.support.v4.widget.SwipeRefreshLayout>
</RelativeLayout>
<ImageView
android:id="@+id/expanded_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@string/hello_blank_fragment" />
android:visibility="invisible" />
</FrameLayout>
</RelativeLayout>

View File

@@ -0,0 +1,66 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<Space
android:layout_width="match_parent"
android:layout_height="15dp" />
<TextView
android:id="@+id/username_timeline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"/>
<ImageView
android:id="@+id/timeline_image"
android:layout_width="wrap_content"
android:layout_height="250dp"
android:layout_gravity="center" />
<TextView
android:id="@+id/timeline_date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:paddingBottom="5dp"
android:textColor="#AAAAAA"
android:text="date/time" />
<TextView
android:id="@+id/comment_timeline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="Hallo Ik ben een comment!" />
<LinearLayout
android:padding="5dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:orientation="horizontal">
<ImageButton
android:id="@+id/niet_slecht_button"
android:layout_width="150dp"
android:layout_height="40dp"
android:scaleType="centerInside"
android:background="@android:color/transparent"
android:src="@drawable/niet_slecht"/>
<TextView
android:id="@+id/niet_slecht_count"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
android:textSize="20sp"
android:text="10" />
</LinearLayout>
<Space
android:layout_width="match_parent"
android:layout_height="10dp" />
</LinearLayout>

View File

@@ -0,0 +1,50 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Space
android:layout_width="match_parent"
android:layout_height="15dp" />
<ImageView
android:id="@+id/timeline_image_profile"
android:layout_width="wrap_content"
android:layout_gravity="center"
android:layout_height="250dp" />
<TextView
android:id="@+id/comment_timeline_profile"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="@string/comment_placeholder" />
<LinearLayout
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageButton
android:id="@+id/niet_slecht_button"
android:layout_width="150dp"
android:layout_height="40dp"
android:scaleType="centerInside"
android:background="@android:color/transparent"
android:src="@drawable/niet_slecht"/>
<TextView
android:id="@+id/niet_slecht_count_profile"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
android:textSize="20sp"
android:text="10" />
</LinearLayout>
<Space
android:layout_width="match_parent"
android:layout_height="15dp" />
</LinearLayout>

View File

@@ -8,12 +8,12 @@
<item
android:id="@+id/navigation_camera"
android:icon="@drawable/ic_dashboard_black_24dp"
android:icon="@drawable/ic_photo_camera_black_24dp"
android:title="@string/title_dashboard" />
<item
android:id="@+id/navigation_profile"
android:icon="@drawable/ic_notifications_black_24dp"
android:icon="@drawable/ic_account_box_black_24dp"
android:title="@string/title_notifications" />
</menu>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.5 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.8 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

@@ -11,5 +11,28 @@
<string name="title_home">Tijdlijn</string>
<string name="title_notifications">Profiel</string>
<string name="username">Gebruikersnaam</string>
<string name="confirm_password_hint">bevestig wachtwoord</string>
<string name="logo_text">MyHyvesBookPlusTagram logo</string>
<string name="logout_button">Uitloggen</string>
<string name="profile_picture_button">Wijzig Profiel Foto</string>
<string name="profile_picture_description">profiel foto</string>
<string name="change_psw_button">Wachtwoord wijzigen</string>
<string name="please_wait">Momentje</string>
<string name="login_error">Voer alstublieft email en wachtwoord in</string>
<string name="mail_failed">Er is een fout opgetreden. Controleer internetverbinding.</string>
<string name="mail_successful">Er is een e-mail verzonden. Volg a.u.b. de instructies.</string>
<string name="password_match_error">Wachtwoorden komoen niet overeen</string>
<string name="register_error">Vul alstublieft alle velden in</string>
<string name="save">Opslaan</string>
<string name="upload">Uploaden</string>
<string name="image_save_error">Foto opslaan mislukt. Zorg a.u.b. dat er genoeg ruimte op uw telefoon beschikbaar is.</string>
<string name="update_profile_pic_error">Het updaten van de profielfoto is mislukt. Controleer uw internetverbinding.</string>
<string name="upload_profile_pic">Profielfoto aan het uploaden…</string>
<string name="niet_slecht">Niet Slecht.</string>
<string name="comment">Bijschrift:</string>
<string name="cancel">Annuleer</string>
<string name="comment_placeholder">Hallo Ik ben een comment!</string>
<string name="refreshing">Verversen…</string>
<string name="downloading_posts">Posts worden gedownload…</string>
<string name="logging_in">Aan het inloggen</string>
<string name="registering">Aan het registreren</string>
</resources>

View File

@@ -2,5 +2,6 @@
<resources>
<color name="colorPrimary">#fbbf2d</color>
<color name="colorPrimaryDark">#ffa70f</color>
<!--<color name="colorAccent">#4bAfe5</color>-->
<color name="colorAccent">#4CAF50</color>
</resources>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="pic_preview" type="id"/>
<item name="camera_preview" type="id"/>
</resources>

View File

@@ -3,18 +3,35 @@
<string name="title_home">Timeline</string>
<string name="title_dashboard">Camera</string>
<string name="title_notifications">Profile</string>
<!-- TODO: Remove or change this placeholder text -->
<string name="username">Username</string>
<string name="password">Password</string>
<string name="confirm_password">Confirm Password</string>
<string name="confirm_password_hint">confirm password</string>
<string name="login_button">Login</string>
<string name="register">Register</string>
<string name="back_to_login">back to Login</string>
<string name="email">Email</string>
<!-- TODO: Remove or change this placeholder text -->
<string name="hello_blank_fragment">Hello blank fragment</string>
<string name="hello_camera">Hello Camera</string>
<string name="login_error">Please fill in email and password</string>
<string name="password_match_error">Passwords do not match</string>
<string name="register_error">Please fill in all the fields</string>
<string name="logo_text">MyHyvesBookPlusTagram logo</string>
<string name="logout_button">Logout</string>
<string name="profile_picture_button">Change Profile Picture</string>
<string name="profile_picture_description">profile picture</string>
<string name="change_psw_button">Change Password</string>
<string name="please_wait">Please Wait</string>
<string name="niet_slecht">\"\"Niet slecht.\"s: \"</string>
<string name="upload">Upload</string>
<string name="save">Save</string>
<string name="mail_successful">An e-mail was sent. Please follow its instructions.</string>
<string name="mail_failed">An error occurred. Please check internet connection.</string>
<string name="image_save_error">Saving image to storage failed. Please make sure there is space available on the device.</string>
<string name="update_profile_pic_error">Updating the profile picture failed. Please check network connection.</string>
<string name="upload_profile_pic">Uploading profile picture…</string>
<string name="comment">Comment:</string>
<string name="cancel">Cancel</string>
<string name="comment_placeholder">Hello, I am a comment!</string>
<string name="refreshing">Refreshing…</string>
<string name="downloading_posts">Downloading posts…</string>
<string name="registering">Registering</string>
<string name="logging_in">Logging in</string>
</resources>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-files-path name="profile_pic_URI" path="Pictures/" />
</paths>
</resources>

2
logboek/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
logboek.pdf

117
logboek/logboek.tex Normal file
View File

@@ -0,0 +1,117 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% LATEX-TEMPLATE GENERIEK
% Voor readme en meest recente versie, zie
% https://gitlab-fnwi.uva.nl/informatica/LaTeX-template.git
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%-------------------------------------------------------------------------------
% PACKAGES EN DOCUMENT CONFIGURATIE
%-------------------------------------------------------------------------------
\documentclass{uva-inf-article}
\usepackage[dutch]{babel}
\usepackage{booktabs}
%-------------------------------------------------------------------------------
% GEGEVENS VOOR IN DE TITEL, HEADER EN FOOTER
%-------------------------------------------------------------------------------
% Vul de naam van de opdracht in.
\assignment{MyHyvesBookPlusTagram}
% Vul het soort opdracht in.
\assignmenttype{Samenvatting}
% Vul de titel van de eindopdracht in.
\title{Logboek}
% Vul de volledige namen van alle auteurs in.
\authors{Niels Zwemmer}
% Vul de corresponderende UvAnetID's in.
\uvanetids{11025980}
% Vul altijd de naam in van diegene die het nakijkt, tutor of docent.
\tutor{Youri Voet}
% Vul indien nodig de naam van de begeleider in.
\mentor{}
% Vul eventueel ook de naam van de docent of vakcoordinator toe.
\docent{}
% Vul hier de naam van de PAV-groep in.
\group{The Return Of MyHyvesBook+}
% Vul de naam van de cursus in.
\course{}
% Te vinden op onder andere Datanose.
\courseid{}
\date{\today}
% Dit is de datum die op het document komt te staan. Standaard is dat vandaag.
%-------------------------------------------------------------------------------
% VOORPAGINA EN EVENTUEEL INHOUDSOPGAVE EN ABSTRACT
%-------------------------------------------------------------------------------
\begin{document}
\maketitle
%-------------------------------------------------------------------------------
% INHOUD
%-------------------------------------------------------------------------------
\section{Algemeen}
\subsection{19-6-2017}
De dag verliep anders dan verwacht door een onverwachte opdracht die de TA's ons oplegde. Deze bestond uit een pitch van een paar minuten die ons plan en project
duidelijk moesten maken. Dit plan werd goedgekeurd door Youri. Voor de pitches stond de tijd van 13:00 tot 14:00 ingesteld. Door deze pitch is onze vergadering verplaatst naar dinsdag 20-6-2017 van 11:00 tot 12:00.
Na de pitch hebben wij nog geprogrammeerd tot ongeveer 15:00. Daarna zijn wij naar huis gegaan en heeft iedereen voor zichzelf gewerkt.
\subsection{20-6-2017}
Allereerst zijn de laatste oefenopgaven nagekeken. Daarna zijn Felix en Marijn direct begonnen aan hun onderdelen implementeren waarna Paul en Niels zich bij hen voegden. Marijn heeft het logo ge\"updatet en is begonnen met de upload-class implementeren. Felix heeft een eerste versie van de CameraView gemaakt.
Paul is begonnen aan de profielpagina en Niels heeft hem daarmee geholpen. Ook heeft Niels de notulen voor de vergadering gemaakt die vandaag van 11:00 tot 12:00 plaatsvond. Tijdens deze vergadering zijn vooral een aantal ontwerpkeuzes besproken. Tot slot is er een template gemaakt voor de logboeken van ieder persoon, zodat productiviteit zo veel mogelijk ongehinderd kan blijven door het achteraf moeten stroomlijnen van dit soort zaken.
\subsection{21-6-2017}
De dag begon om 11:00 met een bijeenkomst van Marijn, Niels en Paul. Felix kon niet aanwezig zijn vandaag maar heeft dat gecompenseerd door veel thuis gewerkt te hebben aan de opdracht. Paul en Niels hebben de profielpagina nagenoeg afgemaakt en wachten nu tot Marijn en Felix hun eerste deel hebben ge\"implementeerd zodat zij verder kunnen. Dit zijn de onderdelen foto uploaden en wachtwoord wijzigen.\\
Om 13:00 ging Marijn naar zijn Minor Programmeren groep om daar TA te zijn. Paul en Niels hebben tussen 13:00 en 15:00 gewerkt aan de interface opleuken van de profielpagina naast de functionaliteiten die eerder al waren verwerkt.
Om 15:00 ging iedereen naar huis, met uitzondering van Marijn die pas om 16:00 klaar was.
\subsection{22-6-2017}
Vandaag hebben wij om 10 uur afgesproken om alvast een eerste versie van onze poster te maken. We zijn over het algemeen al tevreden over dat resultaat maar de definitieve versie zal minder tekst en meer, grotere plaatjes moeten bevatten.
Nadat de poster klaar was, hebben wij geprogrammeerd tot 15:00; de tijd waarop de PAV bijeenkomst begon.
Marijn was vanaf 13:00 weer te vinden in het Minor Programmeren lokaal. We hebben allemaal wat progressie geboekt. Paul heeft Felix ondersteunt met zijn camera implementatie waardoor Felix nu bijna toe is aan de filterimplementatie.
Marijn is bezig geweest aan de poster ontwerpen onder het toeziend oog van Felix als hoofd-design en Niels heeft een eerste implementatie gedaan voor het updaten van de profielfoto. Na de PAV-bijeenkomst is iedereen in de stromende regen naar huis gegaan.
\subsection{23-6-2017}
De dag begon deze keer met een korte programmeersessie tussen Marijn en Niels. Felix was iets later aanwezig. Marijn heeft Niels geholpen met een aantal laatste functionaliteiten toevoegen voor het uploaden van een foto naar de Firebase storage. Felix heeft zich vooral bezig gehouden met het implementeren van de filters. Hij heeft zijn camera-deel waarbij zowel een upload -als opslagfunctie is ingebouwd nu.
Paul kon vandaag niet aanwezig zijn. Hij heeft zich echter van huis uit bezig gehouden met zijn gedeelte van de profielpagina en heeft een aantal wijzigingen met mij besproken. We hebben een vergadering gehouden van 11:30 tot ongeveer 12:30. Uit deze vergadering zijn een aantal dingen gebleken. Zo hebben wij bijvoorbeeld geconstateerd dat een bitmap niet de beste methode is om de profielfoto op te slaan, omdat deze een slechte kwaliteit biedt.
Marijn was vandaag niet nodig bij de Minor Programmeren. Hierdoor waren wij de gehele dag gezamelijk bezig aan de opdracht wat ervoor zorgde dat er een grote productiviteit was.
\subsection{24-6-2017 (Zaterdag) }
Een ieder is van huis uit bezig geweest met zijn eigen onderdelen t.b.v. Trello. Communicatieverkeer was er nauwelijks omdat iedereen nu goed gefocused kon zijn op zijn eigen werk.
\subsection{25-6-2017 (Zondag) }
Lorem Ipsum Dolor sit amet.
\subsection{26-6-2017}
Lorem Ipsum Dolor sit amet.
\subsection{27-6-2017}
Lorem Ipsum Dolor sit amet.
\subsection{28-6-2017}
Lorem Ipsum Dolor sit amet.
\subsection{29-6-2017}
Lorem Ipsum Dolor sit amet.
\subsection{30-6-2017}
Lorem Ipsum Dolor sit amet.
\section{Persoonlijk}
\subsection{19-6-2017}
Lorem Ipsum Dolor sit amet.
\subsection{20-6-2017}
Lorem Ipsum Dolor sit amet.
\subsection{21-6-2017}
Lorem Ipsum Dolor sit amet.
\subsection{22-6-2017}
Lorem Ipsum Dolor sit amet.
\subsection{23-6-2017}
Lorem Ipsum Dolor sit amet.
\subsection{24-6-2017}
Lorem Ipsum Dolor sit amet.
\subsection{25-6-2017}
Lorem Ipsum Dolor sit amet.
\subsection{26-6-2017}
Lorem Ipsum Dolor sit amet.
\subsection{27-6-2017}
Lorem Ipsum Dolor sit amet.
\subsection{28-6-2017}
Lorem Ipsum Dolor sit amet.
\subsection{29-6-2017}
Lorem Ipsum Dolor sit amet.
\subsection{30-6-2017}
Lorem Ipsum Dolor sit amet.
\end{document}

View File

@@ -0,0 +1,98 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% LATEX-TEMPLATE GENERIEK
% Voor readme en meest recente versie, zie
% https://gitlab-fnwi.uva.nl/informatica/LaTeX-template.git
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%-------------------------------------------------------------------------------
% PACKAGES EN DOCUMENT CONFIGURATIE
%-------------------------------------------------------------------------------
\documentclass{uva-inf-article}
\usepackage[dutch]{babel}
\usepackage{booktabs}
%-------------------------------------------------------------------------------
% GEGEVENS VOOR IN DE TITEL, HEADER EN FOOTER
%-------------------------------------------------------------------------------
% Vul de naam van de opdracht in.
\assignment{MyHyvesBookPlusTagram}
% Vul het soort opdracht in.
\assignmenttype{Samenvatting}
% Vul de titel van de eindopdracht in.
\title{Logboek}
% Vul de volledige namen van alle auteurs in.
\authors{Felix Atsma}
% Vul de corresponderende UvAnetID's in.
\uvanetids{11035064}
% Vul altijd de naam in van diegene die het nakijkt, tutor of docent.
\tutor{Youri Voet}
% Vul indien nodig de naam van de begeleider in.
\mentor{}
% Vul eventueel ook de naam van de docent of vakcoordinator toe.
\docent{}
% Vul hier de naam van de PAV-groep in.
\group{The Return Of MyHyvesBook+}
% Vul de naam van de cursus in.
\course{Multimedia}
% Te vinden op onder andere Datanose.
\courseid{}
\date{\today}
% Dit is de datum die op het document komt te staan. Standaard is dat vandaag.
%-------------------------------------------------------------------------------
% VOORPAGINA EN EVENTUEEL INHOUDSOPGAVE EN ABSTRACT
%-------------------------------------------------------------------------------
\begin{document}
\maketitle
%-------------------------------------------------------------------------------
% INHOUD
%-------------------------------------------------------------------------------
\section{Algemeen}
\subsection{19-6-2017}
Deze dag begon met het maken van een kleine presentatie van het projectplan
voor de TA, Youri. Het plan werdt goedgekeurd. Daarna zijn we aan de slag
gegaan met programmeren tot ongeveer 3 uur. Ik ben begonnen aan het maken van
een preview voor de camera en heb daar thuis verder aan gewerkt.
\subsection{20-6-2017}
Na de opdrachten om 9 uur laten nakijken ben ik verder gegaan met de camera
view, hiermee was ik de hele dag bezig. 's Avonds was ik klaar met een simpele
preview, nog zonder de functionaliteit van foto's maken.
\subsection{21-6-2017}
Deze dag was ik niet aanwezig op het Science Park, dit komt doordat ik de
nacht ervoor laat door heb gewerkt, en ik had werk. Ondanks dit heb ik thuis
doorgewerkt. Het wisselen van voor- en achtercamera is afgemaakt, daarnaast is
er gewerkt aan bugfixes.
\subsection{22-6-2017}
Op deze dag heb ik het nemen van foto's geïmplementeerd en gewerkt aan de
layout van de camera view. Thuis heb ik ook nog het uploaden van foto's
werkend gekregen.
Naast het programmeren hebben ik en Marijn een eerste versie van de poster
gemaakt voor PAV.
\subsection{23-6-2017}
Ik heb me vooral bezig gehouden met het implementeren van de filters.
\subsection{24/25-6-2017}
Tijdens het weekend gewerkt aan wisselen tussen filters en het uploaden van de
gefilterde foto's.
\subsection{26-6-2017}
Gewerkt aan een comment functie, en er voor gezorgd dat de camera het hele
beeld opvult.
\subsection{27-6-2017}
Deze dag veel gewerkt aan problemen oplossen, met name het roteren van het
genomen plaatje, daarnaast een probleem met de comment box opgelost. Ook heb
ik nog snel nog een filter toegevoegd.
\subsection{28-6-2017}
Wederom weer problemen opgelost, nu de layout van posts op de timeline
aangepast en een bug met de front facing camera gefixt.
\subsection{29-6-2017}
Deze dag hebben we de laatste puntjes gezet, met de timeline layout
verbeteren, een crash verhelpen en comments aan de code toevoegen.
\subsection{30-6-2017}
Lorem Ipsum Dolor sit amet.
\end{document}

23
logboek/logboek_marijn.md Normal file
View File

@@ -0,0 +1,23 @@
# Logboek Marijn
## Week 1
### Maandag
Vandaag heb gewerkt aan aan de Firebase implementatie, de login en registratie pagina's werken. Ook heb ik een begin gemaakt aan de Fragments.
### Dinsdag
Login verbeterd, er worden checks uitgevoerd en er komt een dialog die de gebruiker laat weten dat er op de achtergrond iets gebeurt.
### Woensdag
Vandaag hebben we aan profielpagina gewerkt.
### Donderdag
Fixed onClick methods.
### Vrijdag
Klasses gemaakt voor posts, deze zijn abstract gemaakt. Profielfoto's werken sinds vandaag.
## Week 2
### Maandag
Profielfotoupload listners gemaakt.
### Dinsdag
Timeline gemaakt.
### Woensdag
Poster en flyer in elkaar gezet.
### Donderdag
Laatste dingen aan de app gedaan.
### Vrijdag
Posterpresentatie

View File

@@ -0,0 +1,115 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% LATEX-TEMPLATE GENERIEK
% Voor readme en meest recente versie, zie
% https://gitlab-fnwi.uva.nl/informatica/LaTeX-template.git
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%-------------------------------------------------------------------------------
% PACKAGES EN DOCUMENT CONFIGURATIE
%-------------------------------------------------------------------------------
\documentclass{uva-inf-article}
\newcommand\tab[1][1cm]{\hspace*{#1}}
\newcommand\tabb[1][1.4cm]{\hspace*{#1}}
\usepackage[dutch]{babel}
\usepackage{booktabs}
%-------------------------------------------------------------------------------
% GEGEVENS VOOR IN DE TITEL, HEADER EN FOOTER
%-------------------------------------------------------------------------------
% Vul de naam van de opdracht in.
\assignment{Notulen: The Return Of The MyHyvesBook+}
% Vul het soort opdracht in.
\assignmenttype{Samenvatting}
% Vul de titel van de eindopdracht in.
\title{Entry 0: Eerste opzet project}
% Vul de volledige namen van alle auteurs in.
\authors{Marijn Jansen; Felix Atsma; Paul Lagerweij; Niels Zwemmer}
% Vul de corresponderende UvAnetID's in.
\uvanetids{11166932; 11035064; 11306084; 11025980}
% Vul altijd de naam in van diegene die het nakijkt, tutor of docent.
\tutor{Robin Klusman}
% Vul eventueel ook de naam van de docent of vakcoordinator toe.
\docent{drs. A. van Inge}
% Vul hier de naam van de PAV-groep in.
\group{C1 (C++)}
% Vul de naam van de cursus in.
\course{Multimedia}
% Te vinden op onder andere Datanose.
\courseid{5062MULT6Y}
% Dit is de datum die op het document komt te staan. Standaard is dat vandaag.
\date{\today}
%-------------------------------------------------------------------------------
% VOORPAGINA EN EVENTUEEL INHOUDSOPGAVE EN ABSTRACT
%-------------------------------------------------------------------------------
\begin{document}
\maketitle
\noindent
\textbf{Data Vergadering}\\\\
Datum:\tab 13-6-2017
\\
Tijd:\tabb 10:30-12:00
\\\\
\noindent
Aanwezig (fysiek):\tabb\space\space\space Marijn, Felix, Niels\\
Aanwezig (telefonisch):\tab Paul\\
Afwezig:\tabb\tabb\space\space\space\space-\\\\
\noindent
\textbf{Onderwerpen besproken}
\begin{itemize}
\item Naam bedacht: MyHyvesBook+Stagram
\item Concept bedacht: Een soort live-feed maken die openbaar zichtbaar is voor alle leden van MyHyvesBook+Stagram.
\item Projectplan opzetten: Taak voor Niels
\item Verdeling gemaakt: Taakverdelingen zijn terug te vinden in het projectplan
\item Implementatiekeuzes: We gaan werken met Firebase op verzoek van Marijn.
\end{itemize}
\pagebreak
\noindent
\textbf{Positieve punten naar voren gekomen}\\\\
We hebben nu een concept en naam bedacht. We gaan werken met firebase en willen realistische doelstellingen aannemen. We gaan zo snel mogelijk de backend opzetten en zorgen dat het esthetische gedeelte draait, daarna gaan we over op het multimedia gedeelte.
Niels gaat het projectplan opzetten in overleg met de andere groepsleden via de WhatsApp-groep en stuurt de uiteindelijk versie rond ter nakijken. Zodra deze is goedgekeurd door alle leden, wordt het projectplan z.s.m. ingeleverd.
Marijn heeft het meest gewerkt met app-development (iOS) en weet dus aardig wat concepten binnen deze wereld. Hij zal dan ook de groepsvoorzitter zijn en nauw samenwerken met alle leden uit de groep en waar nodig ondersteuning kunnen bieden op theoretisch vlak.
\\\\
\noindent
\textbf{Kort}
\begin{itemize}
\item Concept en naam bedacht
\item Backend z.s.m.
\item Projectplan z.s.m.
\item Marijn ervaring app development
\end{itemize}
\noindent
\textbf{Negatieve punten naar voren gekomen}\\\\
Paul kan minder vaak aanwezig zijn bij de vergaderingen of tijdens programmeersessies op de UvA door ziekte. Hierover zal de studieadviseur op de hoogte worden gebracht. We verwachten hier niet al te veel problemen mee te krijgen.
We zijn een groep met weinig ervaring wat betreft Android Programming. De inleidende opdrachten zullen echter voldoende zijn om ons op gang te helpen en dus zal iedereen zijn steentje kunnen bijdragen.
Felix en Marijn hebben een herkansing voor een ander vak die zij dienen te leren. Hierdoor zullen zij mogelijk tijdens de laatste paar dagen minder uren per dag kunnen besteden aan het project. Dit kunnen wij met elkaar opvangen door Felix en Marijns werkdruk iets te verdelen onder de rest van de groep.
\\\\
\noindent
\textbf{Kort}
\begin{itemize}
\item Gegronde omstandigheden Paul
\item Weinig Android ervaring
\item Herkansing Felix en Marijn
\end{itemize}
\vfill \hfill \textit{“Wer hedden dr zin oan!”}
%-------------------------------------------------------------------------------
% INHOUD
%-------------------------------------------------------------------------------
\end{document}

View File

@@ -0,0 +1,110 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% LATEX-TEMPLATE GENERIEK
% Voor readme en meest recente versie, zie
% https://gitlab-fnwi.uva.nl/informatica/LaTeX-template.git
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%-------------------------------------------------------------------------------
% PACKAGES EN DOCUMENT CONFIGURATIE
%-------------------------------------------------------------------------------
\documentclass{uva-inf-article}
\newcommand\tab[1][1cm]{\hspace*{#1}}
\newcommand\tabb[1][1.4cm]{\hspace*{#1}}
\usepackage[dutch]{babel}
\usepackage{booktabs}
%-------------------------------------------------------------------------------
% GEGEVENS VOOR IN DE TITEL, HEADER EN FOOTER
%-------------------------------------------------------------------------------
% Vul de naam van de opdracht in.
\assignment{Notulen: The Return Of The MyHyvesBook+}
% Vul het soort opdracht in.
\assignmenttype{Samenvatting}
% Vul de titel van de eindopdracht in.
\title{Entry 1: Eerste offici\"ele vergadering}
% Vul de volledige namen van alle auteurs in.
\authors{Marijn Jansen; Felix Atsma; Paul Lagerweij; Niels Zwemmer}
% Vul de corresponderende UvAnetID's in.
\uvanetids{11166932; 11035064; 11306084; 11025980}
% Vul altijd de naam in van diegene die het nakijkt, tutor of docent.
\tutor{Robin Klusman}
% Vul eventueel ook de naam van de docent of vakcoordinator toe.
\docent{drs. A. van Inge}
% Vul hier de naam van de PAV-groep in.
\group{C1 (C++)}
% Vul de naam van de cursus in.
\course{Multimedia}
% Te vinden op onder andere Datanose.
\courseid{5062MULT6Y}
% Dit is de datum die op het document komt te staan. Standaard is dat vandaag.
\date{\today}
%-------------------------------------------------------------------------------
% VOORPAGINA EN EVENTUEEL INHOUDSOPGAVE EN ABSTRACT
%-------------------------------------------------------------------------------
\begin{document}
\maketitle
\noindent
\textbf{Data Vergadering}\\\\
Datum:\tab 20-6-2017
\\
Tijd:\tabb 11:00-12:00
\\\\
\noindent
Aanwezig (fysiek):\tabb\space\space\space Marijn, Felix, Niels, Paul\\
Aanwezig (telefonisch):\tab -\\
Afwezig:\tabb\tabb\space\space\space\space-\\\\
\noindent
\textbf{Onderwerpen besproken}
\begin{itemize}
\item Naam gewijzigd: MyHyvesBookPlusTagram (was MyHyvesBook+Stagram)
\item Implementatiekeuzes: Besloten een API te gebruiken voor de feed in de stijl van Facebook die online is gevonden (indien nuttig).
\item Backend progressie besproken: Gaat de goede kant op.
\item Frontend progressie besproken: Paul is nog wat aan het stoeien met de XML, maar schiet allemaal al aardig op.
\end{itemize}
\pagebreak
\noindent
\textbf{Positieve punten naar voren gekomen}\\\\
Het tempo zit er goed in en door geen gebrek aan motivatie en een goede wil om te leren, vergaat het werk tot nu toe zeer goed. De beginselen beginnen al zichtbaar te worden en steeds meer functionaliteit komt van de grond. Iedereen leeft goed zijn deadline na en komt op tijd voor de vergadering.
\\\\
\noindent
\textbf{Kort}
\begin{itemize}
\item Goed tempo
\item Backend gaat goed
\item Frontend gaat goed
\item We liggen op schema
\end{itemize}
\noindent
\textbf{Negatieve punten naar voren gekomen}\\\\
Paul en Niels hebben door een gebrek aan ervaring nog wat moeite om de profilepage op te zetten. De oplossing daarvoor is meer hulp vragen aan Felix en Marijn en actief op internet zoeken naar bruikbare guides. Daarnaast is het implementeren van de CameraView in eenvoud tegengevallen waardoor daar wellicht meer ondersteuning voor nodig is door de rest van het team.
\\\\
\noindent
\textbf{Kort}
\begin{itemize}
\item Gebrek ervaring Paul en Niels
\item Meer hulp vragen aan teamgenoten nodig
\item Tegenvaller tijdens implementatie van de CameraView
\end{itemize}
\vfill \hfill \textit{“As `t net kin sa`t moat, dan moat `t mar sa`t kin.”}
%-------------------------------------------------------------------------------
% INHOUD
%-------------------------------------------------------------------------------
\end{document}

View File

@@ -0,0 +1,113 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% LATEX-TEMPLATE GENERIEK
% Voor readme en meest recente versie, zie
% https://gitlab-fnwi.uva.nl/informatica/LaTeX-template.git
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%-------------------------------------------------------------------------------
% PACKAGES EN DOCUMENT CONFIGURATIE
%-------------------------------------------------------------------------------
\documentclass{uva-inf-article}
\newcommand\tab[1][1cm]{\hspace*{#1}}
\newcommand\tabb[1][1.4cm]{\hspace*{#1}}
\usepackage[dutch]{babel}
\usepackage{booktabs}
%-------------------------------------------------------------------------------
% GEGEVENS VOOR IN DE TITEL, HEADER EN FOOTER
%-------------------------------------------------------------------------------
% Vul de naam van de opdracht in.
\assignment{Notulen: The Return Of The MyHyvesBook+}
% Vul het soort opdracht in.
\assignmenttype{Samenvatting}
% Vul de titel van de eindopdracht in.
\title{Entry 2: Nu komt het echte werk}
% Vul de volledige namen van alle auteurs in.
\authors{Marijn Jansen; Felix Atsma; Paul Lagerweij; Niels Zwemmer}
% Vul de corresponderende UvAnetID's in.
\uvanetids{11166932; 11035064; 11306084; 11025980}
% Vul altijd de naam in van diegene die het nakijkt, tutor of docent.
\tutor{Robin Klusman}
% Vul eventueel ook de naam van de docent of vakcoordinator toe.
\docent{drs. A. van Inge}
% Vul hier de naam van de PAV-groep in.
\group{C1 (C++)}
% Vul de naam van de cursus in.
\course{Multimedia}
% Te vinden op onder andere Datanose.
\courseid{5062MULT6Y}
% Dit is de datum die op het document komt te staan. Standaard is dat vandaag.
\date{\today}
%-------------------------------------------------------------------------------
% VOORPAGINA EN EVENTUEEL INHOUDSOPGAVE EN ABSTRACT
%-------------------------------------------------------------------------------
\begin{document}
\maketitle
\noindent
\textbf{Data Vergadering}\\\\
Datum:\tab 23-6-2017
\\
Tijd:\tabb 11:30-12:00
\\
Noot: De vergadering is iets later begonnen door een vertraging van zowel Niels als Felix.
\\\\
\noindent
Aanwezig (fysiek):\tabb\space\space\space Marijn, Felix, Niels\\
Aanwezig (telefonisch):\tab-\\
Afwezig:\tabb\tabb\space\space\space\space Paul\\\\
\noindent
\textbf{Onderwerpen besproken}
\begin{itemize}
\item Implementatiekeuzes: Ingebouwde camera voor de profielfoto, mogelijkheid tot uitbreiden met gezichtsherkenning (indien tijd).
\item Evaluatie: Hoe staan we ervoor? Back-end grotendeels af.
\item Problemen aan de kant van Multimedia-team: Niet ingedeeld in een groep, projectplan niet her-inleverbaar.
\item Verdeling aangepast: Iedereen helpt elkaar met methodes waar zij verstand van hebben.
\end{itemize}
\pagebreak
\noindent
\textbf{Positieve punten naar voren gekomen}\\\\
We maken goede vooruitgang waarbij we zowel de code als de poster in gedachten hebben. De code ziet er netjes uit en iedereen houdt een consistente stijl aan. Dit zorgt voor een goede werksfeer en weinig over en weer uitleg nodig.
Het gebruik van de ingebouwde camera voor een profielfoto (aangezien daar weinig verdere methodes voor nodig zijn zoals die nodig zijn voor een post plaatsen), zorgt ervoor dat veel werk uit handen genomen wordt en wij onszelf meer tijd gunnen voor de overige benodigde functionaliteit. We zitten goed op schema en lopen zelfs op punten wat voor. Dit moeten we zo volhouden om te zorgen dat de app ook nog daadwerkelijk volgemaakt kan worden met posts voor de oplevering volgende week.
De back-end is nu grotendeels af, wat ervoor zorgt dat we nu ook echt de filters en andere algoritmes kunnen implementeren en testen.
\\\\
\noindent
\textbf{Kort}
\begin{itemize}
\item Goede vooruitgang, zowel poster als programma.
\item Ingebouwde camera goede keuze geweest.
\item We liggen op schema; back-end bijna af.
\end{itemize}
\noindent
\textbf{Negatieve punten naar voren gekomen}\\\\
Paul heeft wat tijd nodig om te herstellen na een aantal dagen achter elkaar aanwezig te zijn geweest op de UvA. Thuis werkt hij echter wel door.
Daarnaast zijn we niet goed ingedeeld in een groep op Blackboard, hiervoor zal Niels een mailtje sturen naar Toto om te vragen voor ondersteuning.
\\\\
\noindent
\textbf{Kort}
\begin{itemize}
\item Paul moet even herstellen.
\item Geen groep op Blackboard.
\end{itemize}
\vfill \hfill \textit{“Wer hedden dr zin oan!”}
%-------------------------------------------------------------------------------
% INHOUD
%-------------------------------------------------------------------------------
\end{document}

View File

@@ -0,0 +1,110 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% LATEX-TEMPLATE GENERIEK
% Voor readme en meest recente versie, zie
% https://gitlab-fnwi.uva.nl/informatica/LaTeX-template.git
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%-------------------------------------------------------------------------------
% PACKAGES EN DOCUMENT CONFIGURATIE
%-------------------------------------------------------------------------------
\documentclass{uva-inf-article}
\newcommand\tab[1][1cm]{\hspace*{#1}}
\newcommand\tabb[1][1.4cm]{\hspace*{#1}}
\usepackage[dutch]{babel}
\usepackage{booktabs}
%-------------------------------------------------------------------------------
% GEGEVENS VOOR IN DE TITEL, HEADER EN FOOTER
%-------------------------------------------------------------------------------
% Vul de naam van de opdracht in.
\assignment{Notulen: The Return Of The MyHyvesBook+}
% Vul het soort opdracht in.
\assignmenttype{Samenvatting}
% Vul de titel van de eindopdracht in.
\title{Entry 3: Afrondende fase}
% Vul de volledige namen van alle auteurs in.
\authors{Marijn Jansen; Felix Atsma; Paul Lagerweij; Niels Zwemmer}
% Vul de corresponderende UvAnetID's in.
\uvanetids{11166932; 11035064; 11306084; 11025980}
% Vul altijd de naam in van diegene die het nakijkt, tutor of docent.
\tutor{Robin Klusman}
% Vul eventueel ook de naam van de docent of vakcoordinator toe.
\docent{drs. A. van Inge}
% Vul hier de naam van de PAV-groep in.
\group{C1 (C++)}
% Vul de naam van de cursus in.
\course{Multimedia}
% Te vinden op onder andere Datanose.
\courseid{5062MULT6Y}
% Dit is de datum die op het document komt te staan. Standaard is dat vandaag.
\date{\today}
%-------------------------------------------------------------------------------
% VOORPAGINA EN EVENTUEEL INHOUDSOPGAVE EN ABSTRACT
%-------------------------------------------------------------------------------
\begin{document}
\maketitle
\noindent
\textbf{Data Vergadering}\\\\
Datum:\tab 26-6-2017
\\
Tijd:\tabb 11:00-12:00
\\
\\
\noindent
Aanwezig (fysiek):\tabb\space\space\space Marijn, Felix, Niels\\
Aanwezig (telefonisch):\tab Paul\\
Afwezig:\tabb\tabb\space\space\space\space-\\\\
\noindent
\textbf{Onderwerpen besproken}
\begin{itemize}
\item Implementatiekeuzes: Besluit genomen de profielfoto beter te maken door file te uploaden i.p.v. thumbnail-bitmap.
\item Evaluatie: Hoe staan we ervoor? De app krijgt nu vorm. Eerste poging tot alles mergen zal morgen zijn.
\item Evaluatie: Teksten van de poster en flyers zijn nu grotendeels bedacht. Marijn en Felix zullen gezamelijk de layout verder verzorgen.
\end{itemize}
\pagebreak
\noindent
\textbf{Positieve punten naar voren gekomen}\\\\
Onze app krijgt nu vorm in de zin dat er steeds meer functionaliteit op elkaar afgestemd wordt en samenwerkt. De losse modules implementeren zoals wij hadden bedacht is een geslaagd idee. Niels heeft zijn lastige bug nu opgelost waardoor hogere resolutie foto's kunnen worden opgeslagen. Felix is bijna klaar met de filters. Marijn zal aan het einde van de middag de verschillende upload-classes en de download-class klaar hebben. Paul werkt als groepswerker op alle fronten mee aan de code.
\\\\
\noindent
\textbf{Kort}
\begin{itemize}
\item Wederom goede vooruitgang, zowel poster als programma.
\item File uploaden is nu geslaagd en profielfoto is niet meer lelijk.
\item We liggen op schema; back-end bijna af.
\end{itemize}
\noindent
\textbf{Negatieve punten naar voren gekomen}\\\\
De bugs oplossen heeft meer tijd gekost dan gehoopt. Daardoor leken we wat van het schema af te zullen wijken. Gelukkig bleek dit mee te vallen. Echter zal er toch nog even hard doorgewerkt moeten worden de laatste paar dagen.\\
Er bestaat nog steeds veel onduidelijkheid over het individuele verslag en de overige PAV onderdelen. Communicatie bij het vak laat wederom te wensen over. Niels zal een e-mail sturen naar Toto en hopelijk kan er morgen gesproken worden met Youri over een aantal zaken.
\\\\
\noindent
\textbf{Kort}
\begin{itemize}
\item Bugs oplossen heeft meer tijd gekost dan gehoopt.
\item Veel onduidelijkheid over het individuele verslag.
\item Communicatie laat te wensen over.
\item Er is nog wat werk aan de winkel, niet alles werkt nog naar behoren.
\end{itemize}
\vfill \hfill \textit{“Ik sis 't mar gewoan: ik ha in hekel oan moandeitemoarn.”}
%-------------------------------------------------------------------------------
% INHOUD
%-------------------------------------------------------------------------------
\end{document}