Compare commits
163 Commits
niels-logb
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c671674f2d | ||
|
|
fdcd141f23 | ||
|
|
5f5269ceb8 | ||
|
|
d7b2e54306 | ||
|
|
8ea692c5a8 | ||
|
|
f8265ac3aa | ||
|
|
d0bd10a854 | ||
|
|
d4bfe0206b | ||
|
|
d61b058d0e | ||
|
|
979f1aab9a | ||
|
|
250ee529fe | ||
|
|
69bbfeaacd | ||
|
|
1f4fa4c768 | ||
|
|
dc7690e183 | ||
|
|
a4108e9e19 | ||
|
|
dc3db134c0 | ||
|
|
32f39a35db | ||
|
|
98f986fc0a | ||
|
|
5a6abe85f1 | ||
|
|
ab54ffb9ec | ||
|
|
6258c2a91a | ||
|
|
0a7c49b3a3 | ||
|
|
63236c5895 | ||
|
|
d8c04c78ea | ||
|
|
9d016b8c65 | ||
|
|
7895054743 | ||
|
|
c38cc026fc | ||
|
|
bd4149ccb1 | ||
|
|
27b005930f | ||
|
|
7936350ede | ||
|
|
c517c2ef10 | ||
|
|
c9eb4b62a1 | ||
|
|
71d412beac | ||
|
|
af47900288 | ||
|
|
5ae1d1f964 | ||
|
|
4eed601b7d | ||
|
|
26a7239caa | ||
|
|
1fdd21440b | ||
|
|
2315d58598 | ||
|
|
ab79fa7d7c | ||
|
|
52d15a80ca | ||
|
|
c8f65c0dca | ||
|
|
0560e6a0fb | ||
|
|
93434a981f | ||
|
|
2621062c60 | ||
|
|
43a1fcd52c | ||
|
|
982d7d4279 | ||
|
|
a04866ba3f | ||
|
|
f1befdd21c | ||
|
|
cab6728a54 | ||
|
|
017b5890c2 | ||
|
|
fe15764d2b | ||
|
|
bfd018ad4a | ||
|
|
ba832682bf | ||
|
|
f0719c51f9 | ||
|
|
3aab463143 | ||
|
|
2db1254750 | ||
|
|
16c3b727fc | ||
|
|
d3395f3e9b | ||
|
|
7ed5c36884 | ||
|
|
0c3ed94bb7 | ||
|
|
744ab1a9c0 | ||
|
|
b11cc95000 | ||
|
|
cebc1bd59b | ||
|
|
1d3537cdde | ||
|
|
6851009e4b | ||
|
|
08849521e1 | ||
|
|
046e3f9400 | ||
|
|
ab0b105640 | ||
|
|
2b7965ad61 | ||
|
|
726129db5b | ||
|
|
f60005c29d | ||
|
|
9322840d10 | ||
|
|
1c9da2c8dc | ||
|
|
0b943e3a1a | ||
|
|
84353046a5 | ||
|
|
2ad161049a | ||
|
|
d3558b6344 | ||
|
|
41bacb3b4f | ||
|
|
2db99500af | ||
|
|
350e55271e | ||
|
|
3f00e09592 | ||
|
|
2c40a1b8da | ||
|
|
0136868ea8 | ||
|
|
b20534aaec | ||
|
|
507fac220c | ||
|
|
d4d10e3f6f | ||
|
|
035f94ec66 | ||
|
|
6142e93957 | ||
|
|
247a443aba | ||
|
|
e54e423847 | ||
|
|
03d4244daf | ||
|
|
766711faee | ||
|
|
046b04e83a | ||
|
|
801acc24fa | ||
|
|
d3d5a41037 | ||
|
|
d90a878a58 | ||
|
|
a9ad130866 | ||
|
|
c2582c128a | ||
|
|
5181128504 | ||
|
|
83d2bda5c1 | ||
|
|
a71fc80f59 | ||
|
|
da765832f1 | ||
|
|
3855d9d917 | ||
|
|
8ba9f7f8e3 | ||
|
|
6aeacbfc8a | ||
|
|
6d7930ee03 | ||
|
|
c056d96138 | ||
|
|
a8a026d18f | ||
|
|
6e55954dde | ||
|
|
c78f01dbfe | ||
|
|
0e25ff63cc | ||
|
|
b570e5ef21 | ||
|
|
06eb90bc9f | ||
|
|
c5c6ba7a47 | ||
|
|
d8eea0bb70 | ||
|
|
0f98bdb5ea | ||
|
|
2a89827b63 | ||
|
|
b0a99b3ab1 | ||
|
|
66221c4393 | ||
|
|
a93f8a500d | ||
|
|
95bb92930e | ||
|
|
e5285f91d5 | ||
|
|
37507c3f5f | ||
|
|
6e08558769 | ||
|
|
a2d333c627 | ||
|
|
aabe207594 | ||
|
|
9a8feee49f | ||
|
|
cd45463f6a | ||
|
|
60e58b40bc | ||
|
|
cafe39d045 | ||
|
|
84a2c75c85 | ||
|
|
63bef257da | ||
|
|
fa3f42da7e | ||
|
|
6faf1c9400 | ||
|
|
d0386a533f | ||
|
|
d326785082 | ||
|
|
fe1960fdce | ||
|
|
4005bef38c | ||
|
|
1a944364c4 | ||
|
|
e48ddd6b82 | ||
|
|
80e2935b23 | ||
|
|
d982c8ba49 | ||
|
|
6db7ca20ae | ||
|
|
e787204ce7 | ||
|
|
72003c75ff | ||
|
|
92bf29dd84 | ||
|
|
bb69d3f695 | ||
|
|
27416aae85 | ||
|
|
86ab31a681 | ||
|
|
c040ef495f | ||
|
|
75d1e6b4ed | ||
|
|
442c5bd642 | ||
|
|
1e5239921a | ||
|
|
39a48044d3 | ||
|
|
291261fcee | ||
|
|
3aac4fc96d | ||
|
|
b9ab2676a6 | ||
|
|
bd2b69a330 | ||
|
|
c27b608168 | ||
|
|
720865fd7e | ||
|
|
23db910b92 | ||
|
|
7eab8f2257 |
102
Individuele_Documenten/niels_zwemmer.md
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
The Return of the MyHyvesBook+ : MyHyvesBookPlusTagram
|
||||||
|
=======================================
|
||||||
|
### _Vak 'Multimedia' van Bsc Informatica leerjaar 1_
|
||||||
|
Niels Zwemmer | 11025980 | UvA | Persoonlijk logboek | Begeleider Youri Voet
|
||||||
|
|
||||||
|
## Introductie
|
||||||
|
De volgende logboek-entries zijn die van mij persoonlijk per dag genoteerd. Ik heb gekozen voor markdown omdat dit een eenvoudig te updaten document is, zonder de noodzaak tot recompilen en dan her-uploaden van het PDF bestand zoals het geval is bij LaTeX. Zodra dit logboek klaar is, zal ik proberen ook een LaTeX versie erbij te doen. Onderstaand logboek wordt verwerkt in het uiteindelijke individuele rapport. (LaTeX).
|
||||||
|
|
||||||
|
## Logboek per dag
|
||||||
|
|
||||||
|
**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 ingeplanned. Door deze pitch is onze vergadering verplaatst naar morgen van 11:00 tot 12:00 (zie hieronder).
|
||||||
|
Naast de pitch heb ik vandaag ook nog gewerkt aan het projectplan en deze afgemaakt voor het inleveren op Blackboard. Hierbij is de planning dan het enige nog ontbrekende onderdeel. Deze zal tijdens de vergadering morgen worden afgerond.
|
||||||
|
Wij hebben daarnaast gewerkt aan onze code, met hulp van zowel Marijn als de referenties hieronder.
|
||||||
|
Eenmaal weer thuis aangekomen, heb ik de laatste hand gelegd aan het projectplan en deze klaargemaakt voor het inleveren.
|
||||||
|
|
||||||
|
_Referenties_
|
||||||
|
* [Firebase-documentatie](https://firebase.google.com/docs/guides/)
|
||||||
|
* [Android-documentatie](https://developer.android.com/guide/index.html)
|
||||||
|
|
||||||
|
**20-6-2017**
|
||||||
|
Allereerst zijn de laatste oefenopgaven nagekeken. Daarna zijn Felix en Marijn direct begonnen aan hun onderdelen implementeren waarna Paul en ik zich bij hen voegden.
|
||||||
|
Paul is begonnen aan de profielpagina en ik heb hem daarmee geholpen. Daarnaast heb ik de notulen voor de vergadering gemaakt die vandaag van 11:00 tot 12:00 plaatsvond. Tijdens deze vergadering zijn vooral een aantal ontwerpkeuzes besproken, zoals het vernieuwde logo, hoe ziet de planning eruit, wat hebben we tot nu toe al werkend en hoe kunnen we dit aan elkaar gelijk houden qua ontwerp.
|
||||||
|
Tot slot heb ik een LaTeX-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.
|
||||||
|
|
||||||
|
_Note: Dit template had ik reeds gemaakt voor mijn keuze over te stappen op markdown. Ik houd nu voor mijzelf een markdown-bestand aan maar hou daarnaast per dag een algemeen logboek bij wat de overige leden kunnen gebruiken om hun persoonlijke logboek te updaten. Dit LaTeX bestand staat op gitlab en is ter beschikking gesteld voor alle TA's._
|
||||||
|
|
||||||
|
Thuis heb ik gewerkt aan mijn Firebase-kennis en heb ik het projectplan ingeleverd na de laatste wijzigingen doorgevoerd te hebben. Ook heb ik zelf even een blik geworpen op het wachtwoord-wijzig systeem. Dit leek mij niet al te moeilijk voor een beginner en dus zou ik hier morgen zelf mee aan de slag gaan.
|
||||||
|
|
||||||
|
**21-6-2017**
|
||||||
|
De dag begon om 11:00 met een bijeenkomst van Marijn, Paul en mijzelf. Felix kon niet aanwezig zijn vandaag maar heeft dat gecompenseerd door veel thuis gewerkt te hebben aan de opdracht. Paul en ik hebben de profielpagina nagenoeg afgemaakt en we wachten nu tot Marijn en Felix hun eerste deel hebben geïmplementeerd zodat wij 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 ik 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.
|
||||||
|
|
||||||
|
Wederom heb ik thuis verder gewerkt, waar ik deze keer ideëen voor de poster en flyers heb bekeken en genoteerd. Daarnaast heb ik het logboek bijgewerkt en de wachtwoord-wijzig methode geïmplementeerd. Dit beviel goed en zorgde voor een beter begrip van Fragments, Activities en Firebase.
|
||||||
|
|
||||||
|
_Referenties_
|
||||||
|
* [Fragments](https://developer.android.com/guide/components/fragments.html)
|
||||||
|
* [Activities](https://developer.android.com/guide/components/activities/index.html)
|
||||||
|
|
||||||
|
**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 ik heb een eerste implementatie gedaan voor het updaten van de profielfoto. Na de PAV-bijeenkomst is iedereen in de stromende regen naar huis gegaan. Ik heb daarbij in de trein naar huis gewerkt aan het logboek en heb de eerste versie van de profielfoto-wijziging op gitlab gezet. Marijn zal nu de upload-class moeten afmaken zodat ik deze kan gebruiken voor de profielfoto.
|
||||||
|
|
||||||
|
Voor deze eerste versie heb ik wederom alleen gebruik gemaakt van de reeds genoemde documentaties. Echter heb ik voor de "timeline" interface die wij willen implementeren, een mogelijk goede bron gevonden. Deze zal terug te vinden zijn in de referentielijst hieronder. Of wij deze bron uiteindelijk gaan gebruiken staat nog niet vast, maar voor de logboek-documentatie leek het mij een goed idee om deze bron alvast op te nemen voor toekomstige referentie.
|
||||||
|
|
||||||
|
_Referenties_
|
||||||
|
* [Android-documentatie](https://developer.android.com/guide/index.html)
|
||||||
|
* [Timeline-bron](http://www.androidhive.info/2014/06/android-facebook-like-custom-listview-feed-using-volley/)
|
||||||
|
* [Camera](https://developer.android.com/training/camera/photobasics.html)
|
||||||
|
* [Upload to Firebase](https://firebase.google.com/docs/storage/android/upload-files)
|
||||||
|
|
||||||
|
|
||||||
|
**23-6-2017**
|
||||||
|
De dag begon deze keer met een korte programmeersessie tussen Marijn en mij. Felix was iets later aanwezig. Marijn heeft mij 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 bijna af.
|
||||||
|
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.
|
||||||
|
Op de terugweg naar huis heb ik de notulen van de vergadering van vandaag verwerkt. Thuis aangekomen heb ik tot laat op de avond gewerkt aan het omschrijven van de profielfoto functionaliteit van een bitmap naar een foto-bestand. Dit kon echter niet vervolledigd worden en hier zal dan ook in het weekend of maandag met andere leden naar gekeken moeten worden. Voor het omschrijven van deze functionaliteit heb ik dezelfde bronnen gebruikt als gisteren, waar men iets verder door moet scrollen om op de juiste onderdelen uit te komen.
|
||||||
|
|
||||||
|
_Referenties_
|
||||||
|
* [Camera](https://developer.android.com/training/camera/photobasics.html)
|
||||||
|
* [Upload to Firebase](https://firebase.google.com/docs/storage/android/upload-files)
|
||||||
|
|
||||||
|
**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.
|
||||||
|
Ik ben vandaag zelf wat verder gaan inlezen in de documentatie maar heb voor nu de implementatie en upload naar Firebase even links laten liggen, zodat dit knelpunt morgen met de overige groepsleden kan worden aangepakt.
|
||||||
|
|
||||||
|
**25-6-2017 (zondag)**
|
||||||
|
Vandaag ben ik begonnen met het maken van dit markdown-bestand aan de hand van de reeds aangemaakte LaTeX-template. Daarnaast ben ik begonnen aan de finetuning van de poster en flyer inhoud. Ik heb met Marijn samen overlegt over de stickers en hij gaat ze vandaag bestellen. Als het goed is komen deze aan voordat de presentaties zijn de 30e, dus daar gaan we dan ook vanuit. Voor het opstellen van de poster en de flyers gebruiken wij het programma InDesign van Adobe. Maandag zullen wij gezamelijk onze onderdelen van de poster bij elkaar voegen zodat wij als het goed is een mooi resultaat zullen hebben. Dit komt goed uit in combinatie met onze geplande vergadering. Hier zal een en ander ook besproken worden over onze knelpunten en zal de voortgang opnieuw worden geëvalueerd.
|
||||||
|
|
||||||
|
Ik heb in de avond vooral gewerkt aan de algemene poster -en flyertekst samen met Paul. Ik had met hem overleg via Skype.
|
||||||
|
|
||||||
|
**26-7-2017**
|
||||||
|
Vandaag was een zeer productieve dag. Om 10 uur hebben wij de werkzaamheden weer opgepakt en heb ik opnieuw
|
||||||
|
gekeken naar de uploadfunctionaliteit van de profielfoto. Deze keer is het mij wel gelukt het voor elkaar te krijgen; het bleek om een simpele toevoeging van metadata te gaan wat ik was vergeten te implementeren.
|
||||||
|
Naast deze simpele toevoeging heb ik ook een stukje extra veiligheid weten in te bouwen, namelijk het gebruiken van een FileProvider voor de URI van de afbeelding. Dit zorgt ervoor dat de app ook kan blijven draaien op een Android 7.x + toestel, wat anders een
|
||||||
|
FileUriExposedException op zou gooien. (In combinatie met API level > 23).
|
||||||
|
Vandaag stond bij ons op de planning een gesprek te voeren met onze begeleider. Echter kwamen wij iets te laat met het aanvragen van dit gesprek; Youri kon vandaag namelijk niet aanwezig zijn. Deze meeting zal dus worden verplaatst naar morgen.
|
||||||
|
|
||||||
|
Ik heb naast de implementatie van de uploadfunctie wat ondersteunende taken verricht bij zowel Marijn als Felix. Paul is thuis aan het werk gegaan aan het project omdat hij niet aanwezig kon zijn vandaag.
|
||||||
|
Ook hadden wij vanaf 11:00 t/m 12:00 een vergadering gehad en hier is uit gekomen dat we eigenlijk nog aardig op schema liggen. Bij iedereen beginnen de individuele onderdelen langzaam tot een goed einde gebracht te worden en dus verwachten wij binnekort een goede versie samen te kunnen brengen. Het enige wat nu nog resteert is bugtesting en een paar laatste layout tweaks.
|
||||||
|
|
||||||
|
Voor de ietwat meer volledige versie van onze vergadering, kunnen de notulen van vandaag worden geraadpleegd. Deze zijn wederom te vinden op gitlab.
|
||||||
|
|
||||||
|
_Referenties_
|
||||||
|
* [FileProvider](https://developer.android.com/reference/android/support/v4/content/FileProvider.html)
|
||||||
|
|
||||||
|
**27-6-2017**
|
||||||
|
Vandaag begonnen wij om 10:00. Ik was echter iets later, net als Paul. Felix en Marijn waren al bezig toen wij aankwamen.
|
||||||
|
Ik ben eerst begonnen met bugtesten van de code van Felix. Deze had nog een aantal memory-problemen en ook was Felix nog niet toegekomen aan de correcte rotatie.
|
||||||
|
Nu Felix weer aan het werk kon, heb ik samen met Paul gekeken naar de ListView voor de profielpagina. Hier worden dan de posts van de gebruiker zelf weergegeven. Dit was in het begin nog wat lastig, maar gelukkig had Marijn al een implementatie van de ListView gemaakt in de Timeline-class. Hier konden Paul en ik een voorbeeld aan nemen en dat heeft uiteindelijk geresulteert in een goed werkende personal-timeline.
|
||||||
|
|
||||||
|
Naast de implementaties die geslaagd waren vandaag, hebben wij ook van 13:00 tot 13:30 een vergadering gehad met Youri vandaag. Wij hebben uitgelegd hoe ver wij waren en hebben hem onze voorlopige app laten zien. Hij was tevreden over het mogelijke eindresultaat waar wij naartoe leven en over de manier waarop wij hebben samengewerkt en onze voortgang hebben gedocumenteerd.
|
||||||
|
|
||||||
|
Voor het implementeren van ListViews aan de hand van Adapters, zijn onderstaande bronnen gebruikt.
|
||||||
|
|
||||||
|
_Referenties_
|
||||||
|
* [ListView](https://developer.android.com/reference/android/support/v4/content/FileProvider.html)
|
||||||
|
* [Adapter](https://developer.android.com/reference/android/widget/Adapter.html)
|
||||||
@@ -6,7 +6,7 @@ android {
|
|||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "nl.myhyvesbookplus.tagram"
|
applicationId "nl.myhyvesbookplus.tagram"
|
||||||
minSdkVersion 21
|
minSdkVersion 21
|
||||||
targetSdkVersion 25
|
targetSdkVersion 21
|
||||||
versionCode 1
|
versionCode 1
|
||||||
versionName "1.0"
|
versionName "1.0"
|
||||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||||
@@ -26,10 +26,15 @@ dependencies {
|
|||||||
})
|
})
|
||||||
compile 'com.android.support:appcompat-v7:25.3.1'
|
compile 'com.android.support:appcompat-v7:25.3.1'
|
||||||
compile 'com.android.support:design: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.constraint:constraint-layout:1.0.2'
|
||||||
compile 'com.android.support:support-v4:25.3.1'
|
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'
|
testCompile 'junit:junit:4.12'
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,4 +47,5 @@ dependencies {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
apply plugin: 'com.google.gms.google-services'
|
apply plugin: 'com.google.gms.google-services'
|
||||||
@@ -14,6 +14,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"oauth_client": [
|
"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_id": "1078950034345-dmsbu0066sfqgqthn2mldlauvdef98u9.apps.googleusercontent.com",
|
||||||
"client_type": 3
|
"client_type": 3
|
||||||
@@ -29,8 +37,13 @@
|
|||||||
"status": 1
|
"status": 1
|
||||||
},
|
},
|
||||||
"appinvite_service": {
|
"appinvite_service": {
|
||||||
"status": 1,
|
"status": 2,
|
||||||
"other_platform_oauth_client": []
|
"other_platform_oauth_client": [
|
||||||
|
{
|
||||||
|
"client_id": "1078950034345-dmsbu0066sfqgqthn2mldlauvdef98u9.apps.googleusercontent.com",
|
||||||
|
"client_type": 3
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"ads_service": {
|
"ads_service": {
|
||||||
"status": 2
|
"status": 2
|
||||||
|
|||||||
@@ -2,6 +2,10 @@
|
|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="nl.myhyvesbookplus.tagram">
|
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
|
<application
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
android:icon="@mipmap/ic_launcher"
|
android:icon="@mipmap/ic_launcher"
|
||||||
@@ -9,7 +13,20 @@
|
|||||||
android:roundIcon="@mipmap/ic_launcher_round"
|
android:roundIcon="@mipmap/ic_launcher_round"
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/AppTheme">
|
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
|
<activity
|
||||||
|
android:screenOrientation="portrait"
|
||||||
android:name=".MainActivity"
|
android:name=".MainActivity"
|
||||||
android:label="@string/app_name">
|
android:label="@string/app_name">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
@@ -18,7 +35,9 @@
|
|||||||
<category android:name="android.intent.category.LAUNCHER" />
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
<activity android:name=".LoginActivity">
|
<activity
|
||||||
|
android:screenOrientation="portrait"
|
||||||
|
android:name=".LoginActivity">
|
||||||
|
|
||||||
</activity>
|
</activity>
|
||||||
</application>
|
</application>
|
||||||
|
|||||||
@@ -1,108 +1,287 @@
|
|||||||
package nl.myhyvesbookplus.tagram;
|
package nl.myhyvesbookplus.tagram;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.app.Activity;
|
||||||
import android.net.Uri;
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.BitmapFactory;
|
||||||
|
import android.hardware.Camera;
|
||||||
|
import android.hardware.Camera.PictureCallback;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.app.Fragment;
|
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.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
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;
|
||||||
|
|
||||||
/**
|
public class CameraFragment extends Fragment implements PostUploader.PostUploadListener{
|
||||||
* A simple {@link Fragment} subclass.
|
private static final String TAG = "CameraFragment";
|
||||||
* Activities that contain this fragment must implement the
|
private Camera mCamera;
|
||||||
* {@link CameraFragment.OnFragmentInteractionListener} interface
|
private CameraPreview mPreview;
|
||||||
* to handle interaction events.
|
private Bitmap mPhoto;
|
||||||
* Use the {@link CameraFragment#newInstance} factory method to
|
private int facing = Camera.CameraInfo.CAMERA_FACING_BACK;
|
||||||
* 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";
|
|
||||||
|
|
||||||
// TODO: Rename and change types of parameters
|
/* Required empty public constructor */
|
||||||
private String mParam1;
|
public CameraFragment() { }
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||||
Bundle savedInstanceState) {
|
Bundle savedInstanceState) {
|
||||||
// Inflate the layout for this fragment
|
// 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
|
final RelativeLayout filterButtons = (RelativeLayout) view.findViewById(R.id.filter_buttons);
|
||||||
public void onButtonPressed(Uri uri) {
|
final RelativeLayout mCameraLayout = (RelativeLayout) view.findViewById(R.id.camera_preview);
|
||||||
if (mListener != null) {
|
final LinearLayout commentBox = (LinearLayout) view.findViewById(R.id.comment_box);
|
||||||
mListener.onFragmentInteraction(uri);
|
final ImageButton pictureButton = (ImageButton) view.findViewById(R.id.picture_button);
|
||||||
}
|
final ImageButton switchButton = (ImageButton) view.findViewById(R.id.switch_camera_button);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
// Hide the action bar
|
||||||
public void onAttach(Context context) {
|
((AppCompatActivity)getActivity()).getSupportActionBar().hide();
|
||||||
super.onAttach(context);
|
|
||||||
if (context instanceof OnFragmentInteractionListener) {
|
|
||||||
mListener = (OnFragmentInteractionListener) context;
|
|
||||||
} else {
|
|
||||||
throw new RuntimeException(context.toString()
|
|
||||||
+ " must implement OnFragmentInteractionListener");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
mCamera = getCameraInstance(facing);
|
||||||
public void onDetach() {
|
|
||||||
super.onDetach();
|
mPreview = new CameraPreview(getActivity().getBaseContext(), mCamera);
|
||||||
mListener = null;
|
|
||||||
|
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
|
* Hides keyboard after submit, upload or cancel button gets pressed.
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
public interface OnFragmentInteractionListener {
|
public void hideKeyboard() {
|
||||||
// TODO: Update argument type and name
|
((InputMethodManager) getActivity().getSystemService(Activity.INPUT_METHOD_SERVICE))
|
||||||
void onFragmentInteraction(Uri uri);
|
.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() {
|
||||||
|
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) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,9 +1,10 @@
|
|||||||
package nl.myhyvesbookplus.tagram;
|
package nl.myhyvesbookplus.tagram;
|
||||||
|
|
||||||
|
import android.app.ProgressDialog;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.os.Bundle;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
import android.support.v7.app.AppCompatActivity;
|
||||||
import android.os.Bundle;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.Button;
|
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.FirebaseUser;
|
||||||
import com.google.firebase.auth.UserProfileChangeRequest;
|
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";
|
public static final String TAG = "Login";
|
||||||
|
|
||||||
/// Views ///
|
/// Views ///
|
||||||
@@ -29,6 +30,8 @@ public class LoginActivity extends AppCompatActivity {
|
|||||||
|
|
||||||
protected FirebaseAuth mAuth;
|
protected FirebaseAuth mAuth;
|
||||||
|
|
||||||
|
private ProgressDialog progressDialog;
|
||||||
|
|
||||||
/// Setup ///
|
/// Setup ///
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -38,11 +41,7 @@ public class LoginActivity extends AppCompatActivity {
|
|||||||
mAuth = FirebaseAuth.getInstance();
|
mAuth = FirebaseAuth.getInstance();
|
||||||
|
|
||||||
findViews();
|
findViews();
|
||||||
}
|
bindOnClick();
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onStart() {
|
|
||||||
super.onStart();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -63,44 +62,81 @@ public class LoginActivity extends AppCompatActivity {
|
|||||||
emailField = (EditText) findViewById(R.id.email);
|
emailField = (EditText) findViewById(R.id.email);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void bindOnClick() {
|
||||||
|
registerButton.setOnClickListener(this);
|
||||||
|
backToLoginButton.setOnClickListener(this);
|
||||||
|
goToRegisterButton.setOnClickListener(this);
|
||||||
|
logInButton.setOnClickListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
/// OnClick ///
|
/// 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) {
|
@Override
|
||||||
String emailSting = emailField.getText().toString();
|
public void onClick(View v) {
|
||||||
String passwordSting = passwordField.getText().toString();
|
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.
|
* Performs the register action.
|
||||||
* @param view
|
|
||||||
*/
|
*/
|
||||||
public void registerOnClick(View view) {
|
public void registerOnClick() {
|
||||||
Log.d(TAG, "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())) {
|
if (!emailString.isEmpty() && !usernameString.isEmpty()
|
||||||
registerUser(emailField.getText().toString(), passwordField.getText().toString());
|
&& !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 {
|
} else {
|
||||||
Toast.makeText(LoginActivity.this, "Passwords do not match",
|
Toast.makeText(LoginActivity.this, R.string.register_error, Toast.LENGTH_SHORT).show();
|
||||||
Toast.LENGTH_SHORT).show();
|
|
||||||
Log.d(TAG, "registerOnClick: Passwords do not match");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// UI-changes ///
|
/// UI-changes ///
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Changes the Activity for registering.
|
* Changes the Activity for registering.
|
||||||
* @param view
|
|
||||||
*/
|
*/
|
||||||
public void goToRegisterOnClick(View view) {
|
public void goToRegisterOnClick() {
|
||||||
passwordConfirmField.setVisibility(View.VISIBLE);
|
passwordConfirmField.setVisibility(View.VISIBLE);
|
||||||
passwordConfirmLabel.setVisibility(View.VISIBLE);
|
passwordConfirmLabel.setVisibility(View.VISIBLE);
|
||||||
registerButton.setVisibility(View.VISIBLE);
|
registerButton.setVisibility(View.VISIBLE);
|
||||||
@@ -114,9 +150,8 @@ public class LoginActivity extends AppCompatActivity {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Changes the Activity for logging in.
|
* Changes the Activity for logging in.
|
||||||
* @param view
|
|
||||||
*/
|
*/
|
||||||
public void backToLoginOnClick(View view) {
|
public void backToLoginOnClick() {
|
||||||
passwordConfirmField.setVisibility(View.GONE);
|
passwordConfirmField.setVisibility(View.GONE);
|
||||||
passwordConfirmLabel.setVisibility(View.GONE);
|
passwordConfirmLabel.setVisibility(View.GONE);
|
||||||
registerButton.setVisibility(View.GONE);
|
registerButton.setVisibility(View.GONE);
|
||||||
@@ -134,6 +169,7 @@ public class LoginActivity extends AppCompatActivity {
|
|||||||
protected void goToMainScreen() {
|
protected void goToMainScreen() {
|
||||||
Intent intent = new Intent(this, MainActivity.class);
|
Intent intent = new Intent(this, MainActivity.class);
|
||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
|
progressDialog.dismiss();
|
||||||
this.finish();
|
this.finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,11 +177,13 @@ public class LoginActivity extends AppCompatActivity {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Performs the actual login action.
|
* Performs the actual login action.
|
||||||
* @param emailSting email address
|
* @param emailString email address
|
||||||
* @param passwordSting the entered password
|
* @param passwordString the entered password
|
||||||
*/
|
*/
|
||||||
protected void logIn(String emailSting, String passwordSting) {
|
protected void logIn(String emailString, String passwordString) {
|
||||||
mAuth.signInWithEmailAndPassword(emailSting, passwordSting)
|
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>() {
|
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
|
||||||
@Override
|
@Override
|
||||||
public void onComplete(@NonNull Task<AuthResult> task) {
|
public void onComplete(@NonNull Task<AuthResult> task) {
|
||||||
@@ -159,6 +197,7 @@ public class LoginActivity extends AppCompatActivity {
|
|||||||
} else {
|
} else {
|
||||||
// If sign in fails, display a message to the user.
|
// If sign in fails, display a message to the user.
|
||||||
Log.w(TAG, "signInWithEmail:failure", task.getException());
|
Log.w(TAG, "signInWithEmail:failure", task.getException());
|
||||||
|
progressDialog.dismiss();
|
||||||
Toast.makeText(LoginActivity.this, task.getException().getLocalizedMessage(),
|
Toast.makeText(LoginActivity.this, task.getException().getLocalizedMessage(),
|
||||||
Toast.LENGTH_SHORT).show();
|
Toast.LENGTH_SHORT).show();
|
||||||
}
|
}
|
||||||
@@ -172,6 +211,7 @@ public class LoginActivity extends AppCompatActivity {
|
|||||||
* @param password the entered password
|
* @param password the entered password
|
||||||
*/
|
*/
|
||||||
protected void registerUser(String email, String 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)
|
mAuth.createUserWithEmailAndPassword(email, password)
|
||||||
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
|
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
|
||||||
@Override
|
@Override
|
||||||
@@ -186,6 +226,7 @@ public class LoginActivity extends AppCompatActivity {
|
|||||||
// If sign in fails, display a message to the user.
|
// If sign in fails, display a message to the user.
|
||||||
Log.w(TAG, "createUserWithEmail:failure", task.getException());
|
Log.w(TAG, "createUserWithEmail:failure", task.getException());
|
||||||
if (task.getException() != null) {
|
if (task.getException() != null) {
|
||||||
|
progressDialog.dismiss();
|
||||||
Toast.makeText(LoginActivity.this, task.getException().getLocalizedMessage(),
|
Toast.makeText(LoginActivity.this, task.getException().getLocalizedMessage(),
|
||||||
Toast.LENGTH_SHORT).show();
|
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
|
* Saves the Username to Firebase
|
||||||
* @param user The User object that needs to be updated
|
* @param user The User object that needs to be updated
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package nl.myhyvesbookplus.tagram;
|
package nl.myhyvesbookplus.tagram;
|
||||||
|
|
||||||
|
import android.app.Fragment;
|
||||||
import android.app.FragmentManager;
|
import android.app.FragmentManager;
|
||||||
import android.app.FragmentTransaction;
|
import android.app.FragmentTransaction;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
@@ -7,7 +8,6 @@ import android.net.Uri;
|
|||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.design.widget.BottomNavigationView;
|
import android.support.design.widget.BottomNavigationView;
|
||||||
import android.app.Fragment;
|
|
||||||
import android.support.v7.app.AppCompatActivity;
|
import android.support.v7.app.AppCompatActivity;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
@@ -15,7 +15,15 @@ import android.view.View;
|
|||||||
|
|
||||||
import com.google.firebase.auth.FirebaseAuth;
|
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";
|
final static private String TAG = "MainScreen";
|
||||||
|
|
||||||
FirebaseAuth mAuth;
|
FirebaseAuth mAuth;
|
||||||
@@ -31,25 +39,25 @@ public class MainActivity extends AppCompatActivity implements CameraFragment.On
|
|||||||
case nl.myhyvesbookplus.tagram.R.id.navigation_timeline:
|
case nl.myhyvesbookplus.tagram.R.id.navigation_timeline:
|
||||||
Log.d(TAG, "onNavigationItemSelected: Timeline");
|
Log.d(TAG, "onNavigationItemSelected: Timeline");
|
||||||
TimelineFragment timeline = new TimelineFragment();
|
TimelineFragment timeline = new TimelineFragment();
|
||||||
transaction.replace(R.id.content, timeline);
|
transaction.replace(R.id.content, timeline)
|
||||||
transaction.addToBackStack(null);
|
.addToBackStack(null)
|
||||||
transaction.commit();
|
.commit();
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case nl.myhyvesbookplus.tagram.R.id.navigation_camera:
|
case nl.myhyvesbookplus.tagram.R.id.navigation_camera:
|
||||||
Log.d(TAG, "onNavigationItemSelected: Camera");
|
Log.d(TAG, "onNavigationItemSelected: Camera");
|
||||||
CameraFragment camera = new CameraFragment();
|
CameraFragment camera = new CameraFragment();
|
||||||
transaction.replace(R.id.content, camera);
|
transaction.replace(R.id.content, camera)
|
||||||
transaction.addToBackStack(null);
|
.addToBackStack(null)
|
||||||
transaction.commit();
|
.commit();
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case nl.myhyvesbookplus.tagram.R.id.navigation_profile:
|
case nl.myhyvesbookplus.tagram.R.id.navigation_profile:
|
||||||
Log.d(TAG, "onNavigationItemSelected: Profile");
|
Log.d(TAG, "onNavigationItemSelected: Profile");
|
||||||
ProfileFragment profile = new ProfileFragment();
|
ProfileFragment profile = new ProfileFragment();
|
||||||
transaction.replace(R.id.content, profile);
|
transaction.replace(R.id.content, profile)
|
||||||
transaction.addToBackStack(null);
|
.addToBackStack(null)
|
||||||
transaction.commit();
|
.commit();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -75,7 +83,6 @@ public class MainActivity extends AppCompatActivity implements CameraFragment.On
|
|||||||
FragmentTransaction transaction = getFragmentManager().beginTransaction();
|
FragmentTransaction transaction = getFragmentManager().beginTransaction();
|
||||||
transaction.replace(R.id.content, fragment);
|
transaction.replace(R.id.content, fragment);
|
||||||
transaction.commit();
|
transaction.commit();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -83,19 +90,46 @@ public class MainActivity extends AppCompatActivity implements CameraFragment.On
|
|||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFragmentInteraction(Uri uri) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void logOutOnClick(View view) {
|
public void logOutOnClick(View view) {
|
||||||
FirebaseAuth.getInstance().signOut();
|
FirebaseAuth.getInstance().signOut();
|
||||||
goToLogin();
|
goToLogin();
|
||||||
this.finish();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void goToLogin() {
|
protected void goToLogin() {
|
||||||
Intent goToLogIn = new Intent(this, LoginActivity.class);
|
Intent goToLogIn = new Intent(this, LoginActivity.class);
|
||||||
startActivity(goToLogIn);
|
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) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,239 @@
|
|||||||
|
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.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.firebase.storage.FirebaseStorage;
|
||||||
|
import com.google.firebase.storage.StorageReference;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import nl.myhyvesbookplus.tagram.model.UriPost;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class which creates views for the profile-page timeline. This is done with a ListView.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class ProfileAdapter extends BaseAdapter {
|
||||||
|
private LayoutInflater mInflater;
|
||||||
|
private Context mContext;
|
||||||
|
private ArrayList<UriPost> mData;
|
||||||
|
private TextView comment;
|
||||||
|
private TextView nietSlechts;
|
||||||
|
private ImageView photo;
|
||||||
|
private Animator mCurrentAnimator;
|
||||||
|
|
||||||
|
/* ProfileAdapter constructor */
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initiate a new view to be part of the ListView.
|
||||||
|
* @param position The position at which the view should start.
|
||||||
|
* @param convertView The viewconverter.
|
||||||
|
* @param parent The parent of the view.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find all views from within the row.
|
||||||
|
* @param rowView The row from which views must be found.
|
||||||
|
* @return The rowView which contains the necessary views.
|
||||||
|
*/
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,108 +1,245 @@
|
|||||||
package nl.myhyvesbookplus.tagram;
|
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.net.Uri;
|
||||||
import android.os.Bundle;
|
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.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
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;
|
||||||
|
|
||||||
|
import nl.myhyvesbookplus.tagram.controller.DownloadClass;
|
||||||
|
import nl.myhyvesbookplus.tagram.controller.ProfilePictureUploader;
|
||||||
|
|
||||||
|
import static android.app.Activity.RESULT_OK;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A simple {@link Fragment} subclass.
|
* Profilefragment which holds the personal info of the user.
|
||||||
* Activities that contain this fragment must implement the
|
* Makes use of ProfileAdapter in order to load in the items for ListView.
|
||||||
* {@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";
|
|
||||||
|
|
||||||
// TODO: Rename and change types of parameters
|
public class ProfileFragment extends Fragment implements View.OnClickListener {
|
||||||
private String mParam1;
|
static final int REQUEST_TAKE_PHOTO = 1;
|
||||||
private String mParam2;
|
ProgressDialog progressDialog;
|
||||||
|
|
||||||
private OnFragmentInteractionListener mListener;
|
/* 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;
|
||||||
|
|
||||||
public ProfileFragment() {
|
private ListView listView;
|
||||||
// Required empty public constructor
|
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
|
* Overridden onCreate which initializes a user and sets the default photoFile to null.
|
||||||
* this fragment using the provided parameters.
|
* @param savedInstanceState The standard return of the onCreate method.
|
||||||
*
|
|
||||||
* @param param1 Parameter 1.
|
|
||||||
* @param param2 Parameter 2.
|
|
||||||
* @return A new instance of fragment ProfileFragment.
|
|
||||||
*/
|
*/
|
||||||
// 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
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
if (getArguments() != null) {
|
user = FirebaseAuth.getInstance().getCurrentUser();
|
||||||
mParam1 = getArguments().getString(ARG_PARAM1);
|
photoFile = null;
|
||||||
mParam2 = getArguments().getString(ARG_PARAM2);
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
* Assigns all views and buttons for the header.
|
||||||
Bundle savedInstanceState) {
|
*/
|
||||||
// Inflate the layout for this fragment
|
protected void findHeaderViews() {
|
||||||
return inflater.inflate(R.layout.fragment_profile, container, false);
|
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);
|
||||||
// TODO: Rename method, update argument and hook method into UI event
|
changePwdButton = (Button) headerInflater.findViewById(R.id.change_psw_button);
|
||||||
public void onButtonPressed(Uri uri) {
|
bindOnClick();
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This interface must be implemented by activities that contain this
|
* Assign the ListView and add the header to it.
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
public interface OnFragmentInteractionListener {
|
protected void findTimelineViews() {
|
||||||
// TODO: Update argument type and name
|
listView = (ListView) timeLineInflater.findViewById(R.id.list);
|
||||||
void onFragmentInteraction(Uri uri);
|
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();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,279 @@
|
|||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class which creates views for the home-page timeline. This is done with a ListView.
|
||||||
|
*/
|
||||||
|
|
||||||
|
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 constructor */
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initiate a new view to be part of the ListView.
|
||||||
|
* @param position The position at which the view should start.
|
||||||
|
* @param convertView The viewconverter.
|
||||||
|
* @param parent The parent of the view.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public View getView(final int position, View convertView, ViewGroup parent) {
|
||||||
|
View rowView = mInflater.inflate(R.layout.list_item_timeline, parent, false);
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,108 +1,90 @@
|
|||||||
package nl.myhyvesbookplus.tagram;
|
package nl.myhyvesbookplus.tagram;
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.app.Fragment;
|
import android.app.Fragment;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.support.v4.widget.SwipeRefreshLayout;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
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 {
|
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
|
/* Some protected and private inits */
|
||||||
private String mParam1;
|
private ListView listView;
|
||||||
private String mParam2;
|
private DownloadClass downloadClass;
|
||||||
|
private ProgressBar progressBar;
|
||||||
|
|
||||||
private OnFragmentInteractionListener mListener;
|
/* Required empty public constructor */
|
||||||
|
public TimelineFragment() {}
|
||||||
public TimelineFragment() {
|
|
||||||
// Required empty public constructor
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use this factory method to create a new instance of
|
* Overridden onCreateView method which creates the ListView and contains a possible refresh
|
||||||
* this fragment using the provided parameters.
|
* functionality (swipe down page for result).
|
||||||
*
|
*
|
||||||
* @param param1 Parameter 1.
|
* https://www.survivingwithandroid.com/2014/05/android-swiperefreshlayout-tutorial-2.html
|
||||||
* @param param2 Parameter 2.
|
* Above reference was largely copied from.
|
||||||
* @return A new instance of fragment TimelineFragment.
|
* @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.
|
||||||
*/
|
*/
|
||||||
// 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
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||||
Bundle savedInstanceState) {
|
Bundle savedInstanceState) {
|
||||||
// Inflate the layout for this fragment
|
View timeLineInflater = inflater.inflate(R.layout.fragment_timeline, container, false);
|
||||||
return inflater.inflate(R.layout.fragment_timeline, container, false);
|
listView = (ListView) timeLineInflater.findViewById(R.id.list);
|
||||||
}
|
final SwipeRefreshLayout swipeView = (SwipeRefreshLayout) timeLineInflater.findViewById(R.id.swipe);
|
||||||
|
|
||||||
// TODO: Rename method, update argument and hook method into UI event
|
progressBar = (ProgressBar) timeLineInflater.findViewById(R.id.progressbar_timeline);
|
||||||
public void onButtonPressed(Uri uri) {
|
progressBar.setVisibility(View.VISIBLE);
|
||||||
if (mListener != null) {
|
|
||||||
mListener.onFragmentInteraction(uri);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
swipeView.setEnabled(false);
|
||||||
public void onAttach(Context context) {
|
downloadClass = new DownloadClass(getActivity());
|
||||||
super.onAttach(context);
|
downloadClass.getPostsFromServer();
|
||||||
if (context instanceof OnFragmentInteractionListener) {
|
|
||||||
mListener = (OnFragmentInteractionListener) context;
|
|
||||||
} else {
|
|
||||||
throw new RuntimeException(context.toString()
|
|
||||||
+ " must implement OnFragmentInteractionListener");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
swipeView.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
|
||||||
public void onDetach() {
|
@Override
|
||||||
super.onDetach();
|
public void onRefresh() {
|
||||||
mListener = null;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This interface must be implemented by activities that contain this
|
* Start display of the list; uses an adapter and listener in the main activity.
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
public interface OnFragmentInteractionListener {
|
public void startList() {
|
||||||
// TODO: Update argument type and name
|
TimeLineAdapter adapter = new TimeLineAdapter(getActivity(), downloadClass.getmList());
|
||||||
void onFragmentInteraction(Uri uri);
|
listView.setAdapter(adapter);
|
||||||
|
progressBar.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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 "";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 98 KiB |
@@ -5,5 +5,5 @@
|
|||||||
android:viewportWidth="24.0">
|
android:viewportWidth="24.0">
|
||||||
<path
|
<path
|
||||||
android:fillColor="#FF000000"
|
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>
|
</vector>
|
||||||
@@ -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>
|
||||||
@@ -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>
|
||||||
@@ -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>
|
||||||
@@ -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>
|
|
||||||
@@ -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>
|
||||||
@@ -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>
|
||||||
|
Before Width: | Height: | Size: 39 KiB |
|
After Width: | Height: | Size: 48 KiB |
|
After Width: | Height: | Size: 44 KiB |
@@ -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">-->
|
<?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>-->
|
<!--</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"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical"
|
|
||||||
android:paddingBottom="@dimen/activity_vertical_margin"
|
android:paddingBottom="@dimen/activity_vertical_margin"
|
||||||
android:paddingLeft="@dimen/activity_horizontal_margin"
|
android:paddingLeft="@dimen/activity_horizontal_margin"
|
||||||
android:paddingRight="@dimen/activity_horizontal_margin"
|
android:paddingRight="@dimen/activity_horizontal_margin"
|
||||||
android:paddingTop="@dimen/activity_vertical_margin"
|
android:paddingTop="@dimen/activity_vertical_margin"
|
||||||
tools:context=".LoginActivity">
|
tools:context=".LoginActivity">
|
||||||
|
|
||||||
<ImageView
|
<ScrollView
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="match_parent">
|
||||||
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" />
|
|
||||||
|
|
||||||
<EditText
|
<LinearLayout
|
||||||
android:id="@+id/email"
|
android:layout_width="match_parent"
|
||||||
android:layout_width="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:orientation="vertical">
|
||||||
android:inputType="textEmailAddress" />
|
|
||||||
|
|
||||||
<TextView
|
<ImageView
|
||||||
android:id="@+id/username_label"
|
android:layout_width="match_parent"
|
||||||
android:layout_width="match_parent"
|
android:layout_height="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:adjustViewBounds="true"
|
||||||
android:labelFor="@+id/username"
|
android:contentDescription="@string/logo_text"
|
||||||
android:text="@string/username"
|
android:cropToPadding="false"
|
||||||
android:visibility="gone" />
|
android:paddingEnd="@dimen/activity_horizontal_margin"
|
||||||
|
android:paddingStart="@dimen/activity_horizontal_margin"
|
||||||
|
android:src="@drawable/logo_new" />
|
||||||
|
|
||||||
<EditText
|
<TextView
|
||||||
android:id="@+id/username"
|
android:layout_width="match_parent"
|
||||||
android:layout_width="match_parent"
|
android:layout_height="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:labelFor="@+id/email"
|
||||||
android:inputType="text"
|
android:text="@string/email" />
|
||||||
android:visibility="gone" />
|
|
||||||
|
|
||||||
<TextView
|
<EditText
|
||||||
android:layout_width="match_parent"
|
android:id="@+id/email"
|
||||||
android:layout_height="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:labelFor="@+id/password"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/password" />
|
android:inputType="textEmailAddress" />
|
||||||
|
|
||||||
<EditText
|
<TextView
|
||||||
android:id="@+id/password"
|
android:id="@+id/username_label"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:inputType="textPassword" />
|
android:labelFor="@+id/username"
|
||||||
|
android:text="@string/username"
|
||||||
|
android:visibility="gone" />
|
||||||
|
|
||||||
<TextView
|
<EditText
|
||||||
android:id="@+id/confirm_password_label"
|
android:id="@+id/username"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/confirm_password"
|
android:inputType="text"
|
||||||
android:visibility="gone" />
|
android:visibility="gone" />
|
||||||
|
|
||||||
<EditText
|
<TextView
|
||||||
android:id="@+id/confirm_password_field"
|
android:layout_width="match_parent"
|
||||||
android:layout_width="match_parent"
|
android:layout_height="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:labelFor="@+id/password"
|
||||||
android:inputType="textPassword"
|
android:text="@string/password" />
|
||||||
android:visibility="gone" />
|
|
||||||
|
|
||||||
<Button
|
<EditText
|
||||||
android:id="@+id/login_button"
|
android:id="@+id/password"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginEnd="16dp"
|
android:inputType="textPassword" />
|
||||||
android:layout_marginStart="16dp"
|
|
||||||
android:onClick="logInOnClick"
|
|
||||||
android:text="@string/login_button" />
|
|
||||||
|
|
||||||
<Button
|
<TextView
|
||||||
android:id="@+id/go_to_register_button"
|
android:id="@+id/confirm_password_label"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginEnd="16dp"
|
android:text="@string/confirm_password"
|
||||||
android:layout_marginStart="16dp"
|
android:visibility="gone" />
|
||||||
android:onClick="goToRegisterOnClick"
|
|
||||||
android:text="@string/register" />
|
|
||||||
|
|
||||||
<Button
|
<EditText
|
||||||
android:id="@+id/register_button"
|
android:id="@+id/confirm_password_field"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginEnd="16dp"
|
android:inputType="textPassword"
|
||||||
android:layout_marginStart="16dp"
|
android:visibility="gone" />
|
||||||
android:onClick="registerOnClick"
|
|
||||||
android:text="@string/register"
|
|
||||||
android:visibility="gone" />
|
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/back_to_login_button"
|
android:id="@+id/login_button"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginEnd="16dp"
|
android:layout_marginEnd="16dp"
|
||||||
android:layout_marginStart="16dp"
|
android:layout_marginStart="16dp"
|
||||||
android:onClick="backToLoginOnClick"
|
android:text="@string/login_button" />
|
||||||
android:text="@string/back_to_login"
|
|
||||||
android:visibility="gone" />
|
|
||||||
|
|
||||||
</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>
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:padding="16dp">
|
android:padding="0dp">
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
|
|
||||||
<android.support.design.widget.BottomNavigationView
|
<android.support.design.widget.BottomNavigationView
|
||||||
|
|||||||
@@ -1,25 +1,133 @@
|
|||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<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"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
tools:context="nl.myhyvesbookplus.tagram.CameraFragment">
|
tools:context="nl.myhyvesbookplus.tagram.CameraFragment">
|
||||||
|
|
||||||
<LinearLayout
|
<RelativeLayout
|
||||||
|
android:id="@+id/camera_preview"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent" >
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<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_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
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_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:onClick="logOutOnClick"
|
android:visibility="gone"
|
||||||
android:text="LogOut" />
|
android:clickable="false"
|
||||||
</LinearLayout>
|
android:layout_margin="10dp"
|
||||||
<!-- TODO: Update blank fragment layout -->
|
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>
|
</FrameLayout>
|
||||||
|
|||||||
@@ -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>
|
|
||||||
@@ -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>
|
||||||
@@ -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>
|
||||||
@@ -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"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical"
|
||||||
tools:context="nl.myhyvesbookplus.tagram.TimelineFragment">
|
tools:context="nl.myhyvesbookplus.tagram.TimelineFragment">
|
||||||
|
|
||||||
<!-- TODO: Update blank fragment layout -->
|
<RelativeLayout
|
||||||
<TextView
|
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_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:text="@string/hello_blank_fragment" />
|
android:visibility="invisible" />
|
||||||
|
|
||||||
</FrameLayout>
|
</RelativeLayout>
|
||||||
@@ -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>
|
||||||
@@ -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>
|
||||||
@@ -8,12 +8,12 @@
|
|||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/navigation_camera"
|
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" />
|
android:title="@string/title_dashboard" />
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/navigation_profile"
|
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" />
|
android:title="@string/title_notifications" />
|
||||||
|
|
||||||
</menu>
|
</menu>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 4.6 KiB |
|
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 4.6 KiB |
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.7 KiB |
|
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.7 KiB |
|
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 6.9 KiB |
|
Before Width: | Height: | Size: 6.0 KiB After Width: | Height: | Size: 6.9 KiB |
|
Before Width: | Height: | Size: 7.5 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 9.8 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 19 KiB |
@@ -11,5 +11,28 @@
|
|||||||
<string name="title_home">Tijdlijn</string>
|
<string name="title_home">Tijdlijn</string>
|
||||||
<string name="title_notifications">Profiel</string>
|
<string name="title_notifications">Profiel</string>
|
||||||
<string name="username">Gebruikersnaam</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>
|
</resources>
|
||||||
@@ -2,5 +2,6 @@
|
|||||||
<resources>
|
<resources>
|
||||||
<color name="colorPrimary">#fbbf2d</color>
|
<color name="colorPrimary">#fbbf2d</color>
|
||||||
<color name="colorPrimaryDark">#ffa70f</color>
|
<color name="colorPrimaryDark">#ffa70f</color>
|
||||||
|
<!--<color name="colorAccent">#4bAfe5</color>-->
|
||||||
<color name="colorAccent">#4CAF50</color>
|
<color name="colorAccent">#4CAF50</color>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -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>
|
||||||
@@ -3,18 +3,35 @@
|
|||||||
<string name="title_home">Timeline</string>
|
<string name="title_home">Timeline</string>
|
||||||
<string name="title_dashboard">Camera</string>
|
<string name="title_dashboard">Camera</string>
|
||||||
<string name="title_notifications">Profile</string>
|
<string name="title_notifications">Profile</string>
|
||||||
|
|
||||||
<!-- TODO: Remove or change this placeholder text -->
|
|
||||||
<string name="username">Username</string>
|
<string name="username">Username</string>
|
||||||
<string name="password">Password</string>
|
<string name="password">Password</string>
|
||||||
<string name="confirm_password">Confirm 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="login_button">Login</string>
|
||||||
<string name="register">Register</string>
|
<string name="register">Register</string>
|
||||||
<string name="back_to_login">back to Login</string>
|
<string name="back_to_login">back to Login</string>
|
||||||
<string name="email">Email</string>
|
<string name="email">Email</string>
|
||||||
|
<string name="login_error">Please fill in email and password</string>
|
||||||
<!-- TODO: Remove or change this placeholder text -->
|
<string name="password_match_error">Passwords do not match</string>
|
||||||
<string name="hello_blank_fragment">Hello blank fragment</string>
|
<string name="register_error">Please fill in all the fields</string>
|
||||||
<string name="hello_camera">Hello Camera</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>
|
</resources>
|
||||||
|
|||||||
@@ -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
@@ -0,0 +1,2 @@
|
|||||||
|
logboek.pdf
|
||||||
|
|
||||||
98
logboek/logboek_felix_atsma.tex
Normal 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
@@ -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
|
||||||
115
notulen/notulen_0_1362017.tex
Normal 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 Marijn’s 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 d’r zin oan!”}
|
||||||
|
|
||||||
|
%-------------------------------------------------------------------------------
|
||||||
|
% INHOUD
|
||||||
|
%-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
\end{document}
|
||||||
110
notulen/notulen_1_2062017.tex
Normal 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}
|
||||||
113
notulen/notulen_2_2362017.tex
Normal 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 d’r zin oan!”}
|
||||||
|
|
||||||
|
%-------------------------------------------------------------------------------
|
||||||
|
% INHOUD
|
||||||
|
%-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
\end{document}
|
||||||
110
notulen/notulen_3_2662017.tex
Normal 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}
|
||||||